Recently Closed Tabs



  • What?
    This mod changes the trash icon and adds a button to quickly open the most recently closed tab or window.

    Demo

    vivaldi_oBxH5hW67M.png

    Installation
    You can learn how to install here

    Javascript:

    /*
     * Recently Closed Tabs
     * Written by Tam710562
     */
    
    window.gnoh = Object.assign(window.gnoh || {}, {
      createElement: function (element, attribute, parent, inner) {
        if (typeof element === 'undefined') {
          return false;
        }
        var el = document.createElement(element);
        if (!!attribute && typeof attribute === 'object') {
          Object.assign(el, attribute);
          if (typeof attribute.text !== 'undefined') {
            el.textContent = attribute.text;
          }
          if (typeof attribute.html !== 'undefined') {
            el.innerHTML = attribute.html;
          }
          if (typeof attribute.style === 'object') {
            for (var css in attribute.style) {
              el.style[css] = attribute.style[css];
            }
          }
          if (typeof attribute.events === 'object') {
            for (let key in attribute.events) {
              if (typeof attribute.events[key] === 'function') {
                el.addEventListener(key, attribute.events[key]);
              }
            }
          }
          for (var key in attribute) {
            if (key !== 'style' && key !== 'events' && key !== 'text' && key !== 'html') {
              if (typeof attribute[key] === 'object') {
                attribute[key] = JSON.stringify(attribute[key]);
              }
              el.setAttribute(key, attribute[key]);
            }
          }
        }
        if (!!inner) {
          if (!Array.isArray(inner)) {
            inner = [inner];
          }
          for (var k = 0; k < inner.length; k++) {
            if (inner[k].nodeName) {
              el.append(inner[k]);
            } else {
              el.append(this.createElementFromHTML(inner[k]));
            }
          }
        }
        if (typeof parent === 'string') {
          parent = document.querySelector(parent);
        }
        if (!!parent) {
          parent.append(el);
        }
        return el;
      },
      createElementFromHTML: function (html) {
        return this.createElement('template', {
          html: (html || '').trim()
        }).content;
      },
      override: function (obj, functionName, callback, conditon) {
        obj[functionName] = (function (_super) {
          return function () {
            var result;
            if (typeof conditon === 'function' && conditon.apply(this, arguments) || conditon === undefined || conditon === true) {
              result = _super.apply(this, arguments);
            }
            callback.apply(this, arguments);
            return result;
          };
        })(obj[functionName]);
      },
      timeOut: function (callback, conditon, timeout) {
        setTimeout(function wait() {
          var result;
          if (!conditon) {
            result = document.getElementById('browser');
          } else if (typeof conditon === 'string') {
            result = document.querySelector(conditon);
          } else if (typeof conditon === 'function') {
            result = conditon();
          } else {
            return;
          }
          if (result) {
            callback(result);
          } else {
            setTimeout(wait, timeout || 300);
          }
        }, timeout || 300);
      }
    });
    
    (function () {
      'use strict';
    
      const icons = {
        recentlyClosedTabs: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="width: 16px; height: 16px;"><path d="M12 8h27.711c6.739 0 12.157 5.548 11.997 12.286l-2.347 98.568C93.925 51.834 170.212 7.73 256.793 8.001 393.18 8.428 504.213 120.009 504 256.396 503.786 393.181 392.835 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.354-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.322 0 196-87.662 196-196 0-108.322-87.662-196-196-196-79.545 0-147.941 47.282-178.675 115.302l126.389-3.009c6.737-.16 12.286 5.257 12.286 11.997V212c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V20C0 13.373 5.373 8 12 8z"></path></svg>',
        dropDown: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" style="width: 8px; height: 8px;"><path d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"></path></svg>'
      };
    
      function recentlyClosedTabs(buttonToggleTrash) {
        const attributesRecentlyClosedTabs = {
          class: 'recently-closed-tabs',
          html: icons.recentlyClosedTabs,
          tabindex: -1,
          title: buttonToggleTrash.title,
          disabled: buttonToggleTrash.disabled,
          style: 'padding-left: 6px;',
          events: {
            click: function (event) {
              event.preventDefault();
              chrome.sessions.getRecentlyClosed(function (data) {
                if (data.length > 0) {
                  chrome.windows.getAll({}, function (info) {
                    const recentlyClosed = data.find(function (item) {
                      if (item.tab) {
                        return true;
                      }
                      const extDataWindow = JSON.parse(item.window.extData);
                      for (let i = 0; i < info.length; i++) {
                        if (info[i].extData && JSON.parse(info[i].extData).ext_id === extDataWindow.ext_id) {
                          return false;
                        }
                      }
                      return true;
                    });
                    
                    if (recentlyClosed) {
                      chrome.sessions.restore(recentlyClosed.sessionId);
                    }
                  });
                }
              });
            }
          }
        };
    
        const buttonRecentlyClosedTabs = gnoh.createElement('button', attributesRecentlyClosedTabs);
        buttonToggleTrash.before(buttonRecentlyClosedTabs);
        buttonToggleTrash.innerHTML = icons.dropDown;
        buttonToggleTrash.style = 'min-width: 0; padding-right: 6px;';
    
        gnoh.override(buttonToggleTrash, 'setAttribute', function (element) {
          buttonRecentlyClosedTabs.title = buttonToggleTrash.title;
          buttonRecentlyClosedTabs.disabled = buttonToggleTrash.disabled;
        });
      }
    
      gnoh.timeOut(function (buttonToggleTrash) {
        recentlyClosedTabs(buttonToggleTrash);
      }, '.button-toolbar.toggle-trash > button[title], .button-toolbar.toggle-trash[title] > button');
    })();
    

    Changelog

    13/09/2019

    • Create the first version..


  • I don't really get what's the difference compared to the normal trashcan



  • @iAN-CooG I simply prefer to restore the tab faster with just one click



  • @iAN-CooG If I understand it correctly, the big circle arrow is to just reopen last closed tab and the small arrow is to open the dropdown. Is it that, @tam710562?

    Edit: ah, a duplicate πŸ˜›



  • @potmeklecbohdan Yes, that's how it works πŸ™‚


  • Moderator

    @tam710562 said in Recently Closed Tabs:

    @iAN-CooG I simply prefer to restore the tab faster with just one click

    You can also use the middle button of the mouse, directly opens the last closed tab.



  • @Folgore101 exactly



  • @tam710562 Thanks for the mod. It’s also more convenient to use a click than a mouse or a command.



  • Is there anyway to increase the number of the closed tabs under the "Recently closed tabs" button?
    I still remember lots of closed tabs shown there in the old Opera 12...



  • @alexis It would be very difficult, but you can upvote this request πŸ˜‰



Looks like your connection to Vivaldi Forum was lost, please wait while we try to reconnect.