Полезная информация

Юристы зарабатывают огромные деньги и славу, оперируя хорошим знанием законов. Правила форума — простой путь к успешному общению.

№1670116-11-2022 18:39:25

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 295
UA: Firefox 101.0

Re: Custom Buttons

Dumby
Так я где то -moz-appearance: menuarrow !important; туда влепил...А "удаление всей истории" ? Так такая же проблема...

Отсутствует

 

№1670228-11-2022 02:05:50

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 342
UA: Firefox 102.0

Re: Custom Buttons

Dumby пишет

Если paxmod, то, наверно, это всё тот же пресловутый ограничительный
хардкод на загрузку модулей только по протоколам chrome: и resource:
(то есть file: и jar:file: идут лесом). Остальное не помню.
Хорошо, соберу что есть. Сам он, разумеется, лучше не стал. DOMi 7.0.10.

Dumby, не посмотрите DOM Inspector.
В [firefox] 107 перестал работать.


«The Truth Is Out There»

Отсутствует

 

№1670328-11-2022 02:22:05

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 1831
UA: Firefox 78.0

Re: Custom Buttons

unter_officer
Собирал себе какой-то.

Отсутствует

 

№1670428-11-2022 14:31:20

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 342
UA: Firefox 102.0

Re: Custom Buttons

Dumby, большое спасибо!


«The Truth Is Out There»

Отсутствует

 

№1670530-11-2022 22:00:30

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 295
UA: Firefox 107.0

Re: Custom Buttons

Dumby
gBrowser.removeAllTabsBut(gBrowser.selectedTab);
Нет другого варианта ?  Долго обьяснять, undoclose кнопка сдохла,рихтанул модули session И код этот тоже того...
И это placesCmd_undoRemove -воостановить закладку тоже пропало, куда рыть ? Комана работает, пункт не появляется...
Может кн. undo подрихтовать(document.popupNode), может это ? (this.parentNode.triggerNode), а то геммора много с SessionStore.jsm...

скрытый текст

Выделить код

Код:

// http://infocatcher.ucoz.net/js/cb/undoCloseTabs.js
// https://forum.mozilla-russia.org/viewtopic.php?id=56267
// https://github.com/Infocatcher/Custom_Buttons/tree/master/Undo_Close_Tabs

// Undo Close Tabs button for Custom Buttons
// (code for "initialization" section)

// (c) Infocatcher 2009-2015, 2017-2018
// version 0.3.3.1 - 2018-08-01

var options = {
    menuTemplate: [    
        "separator",            
        "separator",
        "closedTabs",
        "separator",
        "restoreClosedTabs",
        "clearClosedTabs",
        "separator", 
        "separator",
        "restoreLastSession",
        "separator"     
    ],
    showInTabContextMenu: false,
    /*
    menuTemplateTabContext: [ // like menuTemplate
        "closedTabs",
        "separator",
        "restoreClosedTabs",
        "clearClosedTabs"
    ],
    */
    windowItemTemplate: "(%count) %title",
    windowSelectedTabPrefix: "*",
    buttonTipTemplate: ["header", "title", "url", "closedAt"],
    itemTipTemplate: ["title", "url", "closedAt"],
    hideRestoreAllForSingleEntry: false,
    allowDeleteEntries: true,
    accesskeys: { // Empty string ("") to disable or string with possible values ("0123...", "abcd...")
        closedTabs: "",
        closedWindows: ""
    },
    accesskeyPostfix: " ", // <accesskey><postfix><label>
    openMenuOnMouseover: false,
    useMenu: false,
    rightClickToUndoCloseTab: false // Useful with "useMenu: true"
};

function _localize(sid) {
    var strings = {
        en: {
            restoreTab: "Восстановить последнюю вкладку \nИли сессию",

            restoreAllTabs: "Restore all tabs",
            restoreAllTabsAccesskey: "t",
            clearTabsHistory: "Clear history of closed tabs",
            clearTabsHistoryAccesskey: "b",

            restoreAllWindows: "Restore all windows",
            restoreAllWindowsAccesskey: "w",
            clearWindowsHistory: "Clear history of closed windows",
            clearWindowsHistoryAccesskey: "d",

            clearAllHistory: "Clear all history",
            clearAllHistoryAccesskey: "C",

            restoreLastSession: "Restore last session",
            restoreLastSessionAccesskey: "s",

            deleteUndoEntry: "Delete",

            tabContextMenu: "Recently Closed Tabs",
            tabContextMenuAccesskey: "y",

            itemTip: "%ago ago, %date",
            day: "d"
        },
        ru: {
            restoreTab: "Восстановить последнюю вкладку \nИли сессию",

            restoreAllTabs: "Восстановить все вкладки",
            restoreAllTabsAccesskey: "л",
            clearTabsHistory: "Очистить историю закрытых вкладок",
            clearTabsHistoryAccesskey: "д",

            restoreAllWindows: "Восстановить все окна",
            restoreAllWindowsAccesskey: "о",
            clearWindowsHistory: "Очистить историю закрытых окон",
            clearWindowsHistoryAccesskey: "н",

            clearAllHistory: "Очистить всю историю",
            clearAllHistoryAccesskey: "ч",

            restoreLastSession: "Восстановить последнюю сессию",
            restoreLastSessionAccesskey: "с",

            deleteUndoEntry: "Удалить",

            tabContextMenu: "Недавно закрытые вкладки",
            tabContextMenuAccesskey: "о",

            itemTip: "%ago назад, %date",
            day: "д"
        }
    };
    var locale = (function() {
        if("Services" in window && "locale" in Services) {
            var locales = Services.locale.requestedLocales // Firefox 64+
                || Services.locale.getRequestedLocales && Services.locale.getRequestedLocales();
            if(locales)
                return locales[0];
        }
        var prefs = "Services" in window && Services.prefs
            || Components.classes["@mozilla.org/preferences-service;1"]
                .getService(Components.interfaces.nsIPrefBranch);
        function pref(name, type) {
            return prefs.getPrefType(name) != prefs.PREF_INVALID ? prefs["get" + type + "Pref"](name) : undefined;
        }
        if(!pref("intl.locale.matchOS", "Bool")) { // Also see https://bugzilla.mozilla.org/show_bug.cgi?id=1414390
            var locale = pref("general.useragent.locale", "Char");
            if(locale && locale.substr(0, 9) != "chrome://")
                return locale;
        }
        return Components.classes["@mozilla.org/chrome/chrome-registry;1"]
            .getService(Components.interfaces.nsIXULChromeRegistry)
            .getSelectedLocale("global");
    })().match(/^[a-z]*/)[0];
    _localize = function(sid) {
        return strings[locale] && strings[locale][sid] || strings.en[sid] || sid;
    };
    return _localize.apply(this, arguments);
}

var JSON = "JSON" in window
    ? window.JSON
    : "nsIJSON" in Components.interfaces
        ? {
            parse: function(s) {
                return Components.classes["@mozilla.org/dom/json;1"]
                    .createInstance(Components.interfaces.nsIJSON)
                    .decode(s);
            }
        }
        : {
            parse: function(s) {
                return Components.utils.evalInSandbox("(" + s + ")", new Components.utils.Sandbox("about:blank"));
            }
        };

this.onclick = function(e) {
    if(e.target != this)
        return;
    if(e.button == 1 || e.button == 0 && (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey))

   {  
	if(Services.prompt.confirm(null, null, "     Удалить список вкладок и сессий ?")) {
		this.undoCloseTabsList.clearAllLists();
		SessionStore.canRestoreLastSession = false;
                document.querySelector(
    "#mainPopupSet > tooltip[onpopupshowing*=undoCloseTabsList]"
)?.undoCloseTabsList.updUI();

	}
}

    else if(
        e.button == 0
        || e.button == 2 && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey
            && this.undoCloseTabsList.options.rightClickToUndoCloseTab
    ) {
        if(
            e.button == 0 && !this.undoCloseTabsList.options.useMenu
            || e.button == 2 && this.undoCloseTabsList.options.rightClickToUndoCloseTab
        ) {
            if(this.undoCloseTabsList.closedTabCount)
                this.undoCloseTabsList.undoCloseTab();
            else
                this.undoCloseTabsList.drawUndoList() && this.undoCloseTabsList.showMenu(e);
        }
        // Allow use "command" section only from hotkey:
        e.preventDefault();
        e.stopPropagation();
    }
};
if(!this.hasOwnProperty("defaultContextId"))
    this.defaultContextId = this.getAttribute("context") || "custombuttons-contextpopup";
this.onmousedown = function(e) {
    if(e.target != this)
        return;
    if(this.undoCloseTabsList.options.useMenu) {
        if(e.button == 0)
            this.undoCloseTabsList.drawUndoList();
    }
    else if(e.button == 2) {
        var showCbMenu = e.ctrlKey || e.shiftKey || e.altKey || e.metaKey || !this.undoCloseTabsList.drawUndoList();
        this.setAttribute(
            "context",
            showCbMenu
                ? this.defaultContextId
                : this.undoCloseTabsList.mpId
        );
    }
};
this.onmouseover = function(e) {
    if(e.target != this)
        return;
    if(!this.disabled)
        this.undoCloseTabsList.updUI();
    this.undoCloseTabsList.options.useMenu && Array.prototype.some.call(
        this.parentNode.getElementsByTagName("*"),
        function(node) {
            if(
                node != this
                && node.namespaceURI == xulns
                // See https://github.com/Infocatcher/Custom_Buttons/issues/28
                //&& node.boxObject
                //&& node.boxObject instanceof Components.interfaces.nsIMenuBoxObject
                && "open" in node
                && node.open
                && node.getElementsByTagName("menupopup").length
                && this.undoCloseTabsList.drawUndoList()
            ) {
                node.open = false;
                this.open = true;
                return true;
            }
            return false;
        },
        this
    );
    if(
        this.undoCloseTabsList.options.openMenuOnMouseover
        && this.undoCloseTabsList.drawUndoList()
    )
        this.undoCloseTabsList.openMenu();
};

this.undoCloseTabsList = {
	button: this,
	options: options,
	mpId: this.id + "-context",
	cmId: this.id + "-contextSub",
	tcmId: this.id + "-tabContextMenu",
	tipId: this.id + "-tooltip",
	errPrefix: "[Custom Buttons :: Undo Close Tabs List]: ",
	get mp() {
		var btn = this.button;
		var mp = btn.getElementsByTagName("menupopup");
		mp = mp.length && mp[0];
		mp && mp.parentNode.removeChild(mp);
		mp = this.createElement("menupopup", {
			id: this.mpId,
			onclick: "this.parentNode.undoCloseTabsList.checkForMiddleClick(event);",
			onpopupshowing: "if(event.target == this) document.popupNode = this.parentNode;",
			onpopuphidden: "if(event.target == this) document.popupNode = null;"
		});
		if(this.cm)
			mp.setAttribute("context", this.cmId);
		var tb = btn.parentNode;
		if(
			this.options.useMenu
			&& tb.getAttribute("orient") == "vertical"
		) {
			// https://addons.mozilla.org/firefox/addon/vertical-toolbar/
			var isRight = tb.parentNode.getAttribute("placement") == "right";
			mp.setAttribute("position", isRight ? "start_before" : "end_before");
		}
		delete this.mp;
		return this.mp = btn.appendChild(mp);
	},
	get useCentextMenu() {
		delete this.useCentextMenu;
		return this.useCentextMenu = this.options.allowDeleteEntries
			&& ("forgetClosedTab" in this.ss || "forgetClosedWindow" in this.ss);
	},
	get cm() {
		delete this.cm;
		if(!this.useCentextMenu)
			return this.cm = null;
		var cm = document.getElementById(this.cmId);
		cm && cm.parentNode.removeChild(cm);
		cm = this.createElement("menupopup", {
			id: this.cmId,
			onpopupshowing: "return this.undoCloseTabsList.canDeleteUndoEntry(this.triggerNode || document.popupNode);"
		});
		var mi = this.createElement("menuitem", {
			oncommand: "this.parentNode.undoCloseTabsList.deleteUndoEntry(this.parentNode.triggerNode || document.popupNode);",
			label: _localize("deleteUndoEntry"),
			closemenu: "single"
		});
		cm.appendChild(mi);
		cm.undoCloseTabsList = this;
		return this.cm = document.getElementById("mainPopupSet").appendChild(cm);
	},
	get cbMenu() {
		var cbPopup = document.getElementById(this.button.defaultContextId);
		if(!cbPopup) {
			Components.utils.reportError(this.errPrefix + "cb menu not found");
			return this.cbMenu = null;
		}
		cbPopup = cbPopup.cloneNode(true);
		var id = "-" + this.button.id.match(/\d*$/)[0] + "-cloned";
		cbPopup.id += id;
		Array.prototype.slice.call(cbPopup.getElementsByAttribute("id", "*")).forEach(function(node) {
			node.id += id;
		});
		var menu = this.createElement("menu", {
			label: _localize("buttonMenu"),
			accesskey: _localize("buttonMenuAccesskey")
		});
		menu.appendChild(cbPopup);
		cbPopup.setAttribute(
			"onpopupshowing",
			'\
			var btn = document.popupNode = this.parentNode.parentNode.parentNode\n\
				.undoCloseTabsList.button;\n\
			custombutton.setContextMenuVisibility(btn);'
		);
		delete this.cbMenu;
		return this.cbMenu = menu;
	},
	get ss() {
		delete this.ss;
		return this.ss = "nsISessionStore" in Components.interfaces
			? (
				Components.classes["@mozilla.org/browser/sessionstore;1"]
				|| Components.classes["@mozilla.org/suite/sessionstore;1"]
			).getService(Components.interfaces.nsISessionStore)
			: SessionStore; // Firefox 61+ https://bugzilla.mozilla.org/show_bug.cgi?id=1450559
	},
	get appInfo() {
		delete this.appInfo;
		return this.appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
			.getService(Components.interfaces.nsIXULAppInfo);
	},
	get appVersion() {
		delete this.appVersion;
		return this.appVersion = parseFloat(this.appInfo.version);
	},
	get platformVersion() {
		delete this.platformVersion;
		return this.platformVersion = parseFloat(this.appInfo.platformVersion);
	},
	get appName() {
		delete this.appName;
		return this.appName = this.appInfo.name;
	},

	init: function() {
		window.addEventListener("TabClose",       this, false);
		window.addEventListener("SSTabRestoring", this, false);
		window.addEventListener("unload",         this, false);
		if(this.appName == "SeaMonkey") // No SSTab* events in SeaMonkey
			window.addEventListener("TabOpen", this, false);
		setTimeout(function(_this) {
			_this.mp.addEventListener("DOMMenuItemActive",   _this, false);
			_this.mp.addEventListener("DOMMenuItemInactive", _this, false);
			_this.initTooltip();
		}, 50, this);
		this.addPbExitObserver(true);
		this.updUIGlobal();
		if(this.options.showInTabContextMenu) setTimeout(function(_this) {
			_this.initTabContext();
		}, 100, this);
	},
	initTabContext: function() {
		var origMi = this.tabContextUndoClose;
		if(!origMi) {
			LOG("Can't find \"Undo Close Tab\" item in tab context menu");
			return;
		}
		var menu = document.getElementById(this.tcmId);
		menu && menu.parentNode.removeChild(menu); // For SeaMonkey
		menu = this.createElement("menu", {
			id: this.tcmId,
			label: _localize("tabContextMenu"),
			accesskey: _localize("tabContextMenuAccesskey"),
			tooltip: this.tipId,
			popupsinherittooltip: "true"
		});
		menu.undoCloseTabsList = this;
		menu.onclick = function(e) {
			if(e.target != this)
				return;
			if(e.button == 1 || e.button == 0 && (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey)) {
				if(this.undoCloseTabsList.closedTabCount) {
					this.undoCloseTabsList.undoCloseTab();
					closeMenus(this);
				}
			}
		};
		var origMp = this.mp;
		var mp = origMp.cloneNode(true);
		mp.id = this.button.id + "-tabContext";
		var _this = this;
		function drawUndoList() {
			var ok = false;
			var opts = _this.options;
			var origTemplate = opts.menuTemplate;
			opts.menuTemplate = opts.menuTemplateTabContext || origTemplate;
			_this.mp = mp;
			try {
				ok = _this.drawUndoList();
			}
			catch(e) {
				Components.utils.reportError(e);
			}
			opts.menuTemplate = origTemplate;
			_this.mp = origMp;
			return ok;
		}
		function updMenu() {
			if(drawUndoList())
				menu.removeAttribute("disabled");
			else
				menu.setAttribute("disabled", "true");
		}
		mp._updatePopup = function(e) {
			if(e.target != this)
				return;
			document.popupNode = _this.button;
			drawUndoList();
		};
		mp.setAttribute("onpopupshowing", "this._updatePopup(event);");
		mp.onclick = function(e) {
			_this.checkForMiddleClick(e, updMenu);
		};
		menu.appendChild(mp);
		addEventListener("popupshown", function(e) {
			if(e.target == e.currentTarget)
				setTimeout(updMenu, 0); // Pseudo async
		}, false, origMi.parentNode);
		addEventListener("DOMMenuItemActive",   this, false, mp);
		addEventListener("DOMMenuItemInactive", this, false, mp);
		origMi.parentNode.insertBefore(menu, origMi.nextSibling);
		origMi.setAttribute("hidden", "true");
	},
	initTooltip: function() {
		var tip = document.getElementById(this.tipId);
		tip && tip.parentNode.removeChild(tip);
		tip = this.tip = this.createElement("tooltip", {
			id: this.tipId,
			orient: "vertical",
			onpopupshowing: "return this.undoCloseTabsList.updTooltip(this, this.triggerNode || document.tooltipNode);",
			onpopuphiding: "this.cancelUpdateTimer();"
		});
		tip.undoCloseTabsList = this;
		tip._updateTimer = 0;
		tip.initUpdateTimer = function(fn, context) {
			if(this._updateTimer)
				clearInterval(this._updateTimer);
			this._updateTimer = setInterval(function() {
				fn.call(context);
			}, 1000);
		};
		tip.cancelUpdateTimer = function() {
			if(this._updateTimer) {
				clearInterval(this._updateTimer);
				this._updateTimer = 0;
			}
		};
		var btn = this.button;
		btn.removeAttribute("tooltiptext");
		btn.setAttribute("tooltip", this.tipId);
		btn.setAttribute("popupsinherittooltip", "true");
		document.getElementById("mainPopupSet").appendChild(tip);
		if(this.appVersion >= 61 && "getAnonymousElementByAttribute" in document) {
			var label = document.getAnonymousElementByAttribute(tip, "class", "tooltip-label");
			label && label.remove();
		}
	},
	_hasPbExitObserver: false,
	addPbExitObserver: function(add) {
		if(add == this._hasPbExitObserver || !("Services" in window))
			return;
		this._hasPbExitObserver = add;
		if(add)
			Services.obs.addObserver(this, "last-pb-context-exited", false);
		else
			Services.obs.removeObserver(this, "last-pb-context-exited");
	},
	destroy: function() {
		window.removeEventListener("TabClose",       this, false);
		window.removeEventListener("SSTabRestoring", this, false);
		window.removeEventListener("unload",         this, false);
		if(this.appName == "SeaMonkey")
			window.removeEventListener("TabOpen", this, false);
		this.mp.removeEventListener("DOMMenuItemActive",   this, false);
		this.mp.removeEventListener("DOMMenuItemInactive", this, false);
		this.addPbExitObserver(false);
		var menu = document.getElementById(this.tcmId);
		if(menu) {
			menu.parentNode.removeChild(menu);
			this.tabContextUndoClose.removeAttribute("hidden");
		}
		var tip = this.tip;
		tip && tip.parentNode && tip.parentNode.removeChild(tip);
	},
	handleEvent: function(e) {
		switch(e.type) {
			case "TabClose":
			case "SSTabRestoring":
			case "TabOpen":
				setTimeout(function(_this) {
					_this.updUI();
				}, 0, this);
			break;
			case "DOMMenuItemActive":
			case "DOMMenuItemInactive":
				if(!("XULBrowserWindow" in window))
					break;
				XULBrowserWindow.setOverLink(
					e.type == "DOMMenuItemActive"
						? (e.target.getAttribute("cb_urlDecoded") || "")
							.replace(/ \n/g, ", ")
						: "",
					null
				);
			break;
			case "unload":
				this.updUIGlobal();
				this.destroy();
		}
	},
	observe: function(subject, topic, data) {
		if(topic == "last-pb-context-exited") {
			setTimeout(function(_this) {
				_this.updUI();
			}, 25, this);
		}
	},

	createElement: function(name, attrs) {
		var node = document.createElementNS(xulns, name);
		if(attrs) for(var attrName in attrs) if(attrs.hasOwnProperty(attrName))
			node.setAttribute(attrName, attrs[attrName]);
		return node;
	},
	get tabContextUndoClose() {
		return document.getElementById("context_undoCloseTab")
			|| document.getElementById("tabContextUndoCloseTab") // Firefox 2.0
			|| document.getAnonymousElementByAttribute(gBrowser, "tbattr", "tabbrowser-undoclosetab"); // SeaMonkey
	},
	get closedWindowCount() {
		if(!("getClosedWindowCount" in this.ss)) {
			delete this.closedWindowCount;
			return this.closedWindowCount = 0;
		}
		this.__defineGetter__("closedWindowCount", function() {
			return this.ss.getClosedWindowCount();
		});
		return this.closedWindowCount;
	},
	get closedTabCount() {
		return this.ss.getClosedTabCount(window);
	},
	undoCloseTab: function(i) {
		if("undoCloseTab" in window) // Firefox 2.0+
			undoCloseTab(i);
		else // SeaMonkey
			gBrowser.undoCloseTab(i);
	},
	clearUndoTabsList: function() {
		var closedTabCount = this.closedTabCount;
		if(!closedTabCount)
			return;
		if("forgetClosedTab" in this.ss) // Gecko 1.9.2+
			while(closedTabCount--)
				this.ss.forgetClosedTab(window, 0);
		else {
			// Doesn't work in SeaMonkey
			const pName = "browser.sessionstore.max_tabs_undo";
			let val = cbu.getPrefs(pName);
			cbu.setPrefs(pName, 0);
			cbu.setPrefs(pName, val);
		}
		this.updUIGlobal();
	},
	clearUndoWindowsList: function() {
		var closedWindowCount = this.closedWindowCount;
		if(!closedWindowCount)
			return;
		if("forgetClosedWindow" in this.ss) // Gecko 1.9.2+
			while(closedWindowCount--)
				this.ss.forgetClosedWindow(0);
		else
			this.ss.setWindowState(window, '{"windows":[{}],"_closedWindows":[]}', false);
		this.updUIGlobal();
	},
	clearAllLists: function() {
		this.clearUndoTabsList();
		this.clearUndoWindowsList();
	},
	canDeleteUndoEntry: function(mi) {
		switch(mi.getAttribute("cb_type")) {
			case "tab":    return "forgetClosedTab"    in this.ss;
			case "window": return "forgetClosedWindow" in this.ss;
		}
		return false;
	},
	deleteUndoEntry: function(mi) {
		var i = +mi.getAttribute("cb_index");
		if(mi.getAttribute("cb_type") == "window") {
			this.ss.forgetClosedWindow(i);
			this.updUIGlobal();
		}
		else {
			this.ss.forgetClosedTab(window, i);
			this.updUI();
		}
		this.drawUndoList();
	},
	showMenu: function(e, isContext, mp) {
		var btn = this.button;
		document.popupNode = btn.ownerDocument.popupNode = btn;
		if(!mp)
			mp = this.mp;
		if("openPopupAtScreen" in mp)
			mp.openPopupAtScreen(e.screenX, e.screenY, isContext);
		else
			mp.showPopup(btn, e.screenX, e.screenY, isContext ? "context" : "popup", null, null);
	},
	openMenu: function() {
		var mp = this.mp;
		if("openPopup" in mp)
			mp.openPopup(this.button, "after_start");
		else
			mp.showPopup(this.button, -1, -1, "popup", "bottomleft", "topleft");
	},
	drawUndoList: function() {
        var mp = this.mp;

        var wc = this.closedWindowCount;
        var tc = this.closedTabCount;
        var ss = this.ss;
        var canRestoreLastSession = "restoreLastSession" in ss && ss.canRestoreLastSession
        if(!wc && !tc && !canRestoreLastSession) {
            mp.textContent = "";
            mp.hidePopup();
            return false;
        }

		this._undoWindowItems = wc && JSON.parse(ss.getClosedWindowData());
		this._undoTabItems    = tc && JSON.parse(ss.getClosedTabData(window));
		var df = document.createDocumentFragment();

		this.options.menuTemplate.forEach(function(sid, indx, arr) {
			switch(sid) {
				case "closedWindows":
					wc && this.addUndoWindowsList(df);
				break;
				case "restoreClosedWindows":
					wc > this.options.hideRestoreAllForSingleEntry
					&& df.appendChild(this.createElement("menuitem", {
						label: _localize("restoreAllWindows"),
						accesskey: _localize("restoreAllWindowsAccesskey"),
						oncommand: "for(var i = 0; i < " + this._undoWindowItems.length + "; ++i) undoCloseWindow();"
					}));
				break;
				case "clearClosedWindows":
					wc && df.appendChild(this.createElement("menuitem", {
						label: _localize("clearWindowsHistory"),
						accesskey: _localize("clearWindowsHistoryAccesskey"),
						oncommand: "this.parentNode.parentNode.undoCloseTabsList.clearUndoWindowsList();"
					}));
				break;
				case "closedTabs":
					tc && this.addUndoTabsList(df);
				break;
				case "restoreClosedTabs":
					tc > this.options.hideRestoreAllForSingleEntry
					&& df.appendChild(this.createElement("menuitem", {
						label: _localize("restoreAllTabs"),
						accesskey: _localize("restoreAllTabsAccesskey"),
						oncommand: "for(var i = 0; i < " + this._undoTabItems.length + "; ++i) this.parentNode.parentNode.undoCloseTabsList.undoCloseTab();"
					}));
				break;
				case "clearClosedTabs":
					tc && df.appendChild(this.createElement("menuitem", {
						label: _localize("clearTabsHistory"),
						accesskey: _localize("clearTabsHistoryAccesskey"),
						oncommand: "this.parentNode.parentNode.undoCloseTabsList.clearUndoTabsList();"
					}));
				break;
				case "clearAll":
					(
						wc && tc
						|| wc && arr.indexOf("clearClosedWindows") == -1
						|| tc && arr.indexOf("clearClosedTabs") == -1
					)
					&& df.appendChild(this.createElement("menuitem", {
						label: _localize("clearAllHistory"),
						accesskey: _localize("clearAllHistoryAccesskey"),
						oncommand: "this.parentNode.parentNode.undoCloseTabsList.clearAllLists();"
					}));
				break;
				case "restoreLastSession": // Gecko 2.0+
					canRestoreLastSession && df.appendChild(this.createElement("menuitem", {
						label: _localize("restoreLastSession"),
						accesskey: _localize("restoreLastSessionAccesskey"),
						oncommand: "this.parentNode.parentNode.undoCloseTabsList.ss.restoreLastSession();"
					}));
				break;
				case "buttonMenu":
					let cbMenu = this.cbMenu;
					if(cbMenu)
						df.appendChild(cbMenu);
				break;
				case "separator":
					if(df.hasChildNodes() && df.lastChild.localName != "menuseparator")
						df.appendChild(document.createElementNS(xulns, "menuseparator"));
				break;
				default:
					Components.utils.reportError(this.errPrefix + 'Invalid template entry: "' + sid + '"');
			}
		}, this);

		while(df.hasChildNodes() && df.lastChild.localName == "menuseparator")
			df.removeChild(df.lastChild);

		this._undoWindowItems = this._undoTabItems = null;

		mp.textContent = "";
		if(!df.hasChildNodes()) {
			mp.hidePopup();
			return false;
		}
		mp.appendChild(df);
		return true;
	},
	addUndoTabsList: function(undoPopup) {
        // Based on code from chrome://browser/content/browser.js
        // Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.3a1pre) Gecko/20090824 Minefield/3.7a1pre

        var keys = this.options.accesskeys.closedTabs;
        this._undoTabItems.forEach(function(undoItem, i) {
            var state = undoItem.state;
            var [key, keyPrefix] = this.getKey(keys, i);
            var title = undoItem.title;
            var url = state && state.entries && state.entries[state.index - 1].url || "";
            var mi = this.createElement("menuitem", {
                label: keyPrefix + title,
                accesskey: key,
                class: "menuitem-iconic bookmark-item menuitem-with-favicon",
                oncommand: "this.parentNode.parentNode.undoCloseTabsList.undoCloseTab(" + i + ");",
                cb_url: url,
                cb_urlDecoded: this.convertURI(url),
                cb_closedAt: undoItem.closedAt || 0,
                cb_index: i,
                cb_type: "tab"
            });
            if(
                state
                && "attributes" in state
                && "privateTab-isPrivate" in state.attributes
            ) // https://addons.mozilla.org/addon/private-tab/
                mi.setAttribute("privateTab-isPrivate", "true");
            if(this.cm)
                mi.setAttribute("context", this.cmId);
            var image = undoItem.image // Firefox
                || state && state.attributes && state.attributes.image // SeaMonkey
                || state && state.xultab
                    && /(?:^| )image=(\S+)/.test(state.xultab)
                    && decodeURI(RegExp.$1); // Only Firefox 2.0 ?
            if(image)
                mi.setAttribute("image", this.cachedIcon(image));
            if(i == 0)
                mi.setAttribute("key", "key_undoCloseTab");
            undoPopup.appendChild(mi);
        }, this);
    },
    getKey: function(keys, i) {
        var key = keys && keys.charAt(i % keys.length);
        var keyPrefix = keys && (key + this.options.accesskeyPostfix);
        return [key, keyPrefix];
    },
    checkForMiddleClick: function(e, upd) {
        var mi = e.target;
        if(
            "doCommand" in mi
            && e.button == 1
            && mi.parentNode == e.currentTarget
        ) {
            mi.doCommand();
            if(upd)
                upd();
            else
                this.drawUndoList();
        }
    },
    crop: function(s, crop) {
        if(crop == undefined)
            crop = 500;
        if(s.length <= crop)
            return s;
        var start = Math.round(crop*0.6);
        return s.substr(0, start) + "…" + s.substr(start - crop);
    },
    convertURI: function(uri, crop) {
        if(!uri || uri.indexOf("\n") != -1)
            return uri;
        try {
            uri = "losslessDecodeURI" in window
                ? losslessDecodeURI(makeURI(uri))
                : decodeURI(uri);
        }
        catch(e) {
            Components.utils.reportError(e);
        }
        return this.crop(uri, crop);
    },
    cachedIcon: function(src) {
        src = src.replace(/[&#]-moz-resolution=\d+,\d+$/, ""); // Firefox 22+
        if(
            !/^https?:/.test(src)
            // IDN, see https://bugzilla.mozilla.org/show_bug.cgi?id=311045
            || /^https?:\/\/[^.:\/]+\.[^a-z0-9-]+(?:\/|$)/.test(src)
            || this.appName == "SeaMonkey" && this.appVersion <= 2
            || this.appName == "Firefox"   && this.appVersion <= 3.5
        )
            return src;
        return "moz-anno:favicon:" + src; // https://bugzilla.mozilla.org/show_bug.cgi?id=467828
    },
    updUI: function() {
        var tabsCount = this.closedTabCount;
        var dis = !tabsCount 
        if(
            dis
            
            && this.options.menuTemplate.indexOf("restoreLastSession") != -1
            && "restoreLastSession" in this.ss && this.ss.canRestoreLastSession
        )
            dis = false;
        this.button.disabled = dis;
    },
    updTooltip: function(tip, tn) {
		var template, header, title, url, closedAt;
		if(tn == this.button) {
			template = this.options.buttonTipTemplate;
			header = _localize("restoreTab");
			let undoTabItems = JSON.parse(this.ss.getClosedTabData(window));
			if(undoTabItems.length) {
				let lastItem = undoTabItems[0];
				title = lastItem.title;
				url = lastItem.state && lastItem.state.entries
					&& lastItem.state.entries[lastItem.state.index - 1].url;
				closedAt = lastItem.closedAt || 0;
			}
		}
        else if(tn.hasAttribute("cb_index")) {
            template = this.options.itemTipTemplate;
            title = tn.getAttribute("label");
            url = tn.getAttribute("cb_url");
            closedAt = +tn.getAttribute("cb_closedAt");
        }
        else {
            return false;
        }

        var tipData = this.getTooltipData(template, header, title, url, closedAt);
        tip.textContent = "";
        tip.appendChild(tipData);
        if(closedAt && template.indexOf("closedAt") != -1) {
            tip.initUpdateTimer(function() {
                var tipData = this.getTooltipData(template, header, title, url, closedAt);
                if(tipData.textContent != tip.textContent) {
                    tip.textContent = "";
                    tip.appendChild(tipData);
                }
            }, this);
        }
        return tip.hasChildNodes();
    },
    getTooltipData: function(template, header, title, url, closedAt) {
        var df = document.createDocumentFragment();
        var hasHeader = header && template.indexOf("header") != -1;
        function item(key, val) {
            var lbl = document.createElementNS(xulns, "label");
            lbl.className = "cb-" + key;
            //lbl.setAttribute("value", val);
            lbl.textContent = val;
            lbl.setAttribute("maxwidth", "450"); // Trick to restore right border for long lines
            if(key == "closedAt" || hasHeader && key != "header")
                lbl.style.color = "grayText";
            return df.appendChild(lbl);
        }
        template.forEach(function(key) {
            switch(key) {
                case "header":
                    if(header)
                        item(key, header);
                break;
                case "title":
                    if(title && title != url)
                        item(key, title);
                break;
                case "url":
                    if(url)
                        item(key, this.convertURI(url));
                break;
                case "closedAt":
                    if(!closedAt)
                        break;
                    let dt = Math.round(Math.max(0, Date.now() - closedAt)/1000);
                    let days = Math.floor(dt/24/3600);
                    dt -= days*24*3600;
                    let d = new Date((dt + new Date(dt).getTimezoneOffset()*60)*1000);
                    let m = d.getMinutes();
                    let ts = d.getHours() + ":" + (m > 9 ? m : "0" + m);
                    if(days)
                        ts = days + _localize("day") + " " + ts;
                    let tsTip = _localize("itemTip")
                        .replace("%ago", ts)
                        .replace("%date", new Date(closedAt).toLocaleString());
                    item(key, tsTip);
            }
        }, this);
        return df;
    },
    get wm() {
        delete this.wm;
        return this.wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
            .getService(Components.interfaces.nsIWindowMediator);
    },
    updUIGlobal: function() {
        var isSeaMonkey = this.appName == "SeaMonkey";
        var ws = this.wm.getEnumerator(isSeaMonkey ? null : "navigator:browser");
        const id = this.button.id;
        while(ws.hasMoreElements()) {
            let win = ws.getNext();
            if(!isSeaMonkey || this.isBrowserWindow(win)) {
                let btn = win.document.getElementById(id);
                if(btn && "undoCloseTabsList" in btn) {
                    let ucl = btn.undoCloseTabsList;
                    ucl.ensureSessionsInitialized(ucl.updUI, ucl);
                }
            }
        }
    },
    isBrowserWindow: function(win) {
        var loc = window.location.href;
        return loc == "chrome://browser/content/browser.xul"
            || loc == "chrome://navigator/content/navigator.xul";
    },
    ensureSessionsInitialized: function(callback, context) {
        var _this = this;
        var stopTime = Date.now() + 3e3;
        (function ensureInitialized() {
            try {
                _this.ss.getClosedTabCount(window);
                callback.call(context);
                return;
            }
            catch(e) {
                if(Date.now() > stopTime) {
                    Components.utils.reportError(
                        _this.errPrefix
                        + "Can't initialize: nsISessionStore.getClosedTabCount() failed"
                    );
                    Components.utils.reportError(e);
                    return;
                }
            }
            setTimeout(ensureInitialized, 50);
        })();
    }
};

if(!this.undoCloseTabsList.options.useMenu && this.undoCloseTabsList.useCentextMenu) {
    this.oncontextmenu = function(e) {
        if(
            e.target != this
            || e.ctrlKey || e.shiftKey || e.altKey || e.metaKey
            || !this.undoCloseTabsList.mp.hasChildNodes()
        )
            return;
        e.preventDefault();
        this.undoCloseTabsList.showMenu(e); // Show menu without "context" flag
    };
}
if(this.undoCloseTabsList.options.rightClickToUndoCloseTab) {
    this.oncontextmenu = function(e) {
        if(e.target == this && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey)
            e.preventDefault();
    };
}

this.disabled = true;
setTimeout(function(_this) {
    _this.undoCloseTabsList.init();
}, 0, this);

//===================
// Styles
// Used icons from Undo Closed Tabs Button extension

// Styles can't override hardcoded icon
if( // Remove icon only if nsIStyleSheetService works on-the-fly (Firefox 3.0+)
    !Components.ID("{41d979dc-ea03-4235-86ff-1e3c090c5630}")
        .equals(Components.interfaces.nsIStyleSheetService)
) {
    let icon = this.icon
        || this.ownerDocument.getAnonymousElementByAttribute(this, "class", "toolbarbutton-icon");
    if(icon)
        icon.src = "";
    else
        this.image = "";
}

var cssStr = '\
    @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");\n\
    @-moz-document url("%windowURL%") {\n\
        %button% {\n\
            list-style-image: url("data:image/png;base64,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") !important;\n\
            -moz-image-region: rect(0, 24px, 24px, 0) !important;\n\
        }\n\
        %button%:hover {\n\
            -moz-image-region: rect(0, 48px, 24px, 24px) !important;\n\
        }\n\
        %button%[disabled="true"] {\n\
            -moz-image-region: rect(0, 72px, 24px, 48px) !important;\n\
        }\n\
        toolbar[iconsize="small"] %button% {\n\
            -moz-image-region: rect(24px, 16px, 40px, 0) !important;\n\
        }\n\
        toolbar[iconsize="small"] %button%:hover {\n\
            -moz-image-region: rect(24px, 32px, 40px, 16px) !important;\n\
        }\n\
        toolbar[iconsize="small"] %button%[disabled="true"] {\n\
            -moz-image-region: rect(24px, 48px, 40px, 32px) !important;\n\
        }\n\
    }'
    .replace(/%windowURL%/g, window.location.href)
    .replace(/%button%/g, "#" + this.id);
var cssURI = this.cssURI = Components.classes["@mozilla.org/network/io-service;1"]
    .getService(Components.interfaces.nsIIOService)
    .newURI("data:text/css," + encodeURIComponent(cssStr), null, null);
var sss = this.sss = Components.classes["@mozilla.org/content/style-sheet-service;1"]
    .getService(Components.interfaces.nsIStyleSheetService);
if(!sss.sheetRegistered(cssURI, sss.USER_SHEET))
    sss.loadAndRegisterSheet(cssURI, sss.USER_SHEET);


this.onDestroy = function(reason) {
    this.undoCloseTabsList.destroy();
    if(reason == "update" || reason == "delete") {
        let sss = this.sss;
        let cssURI = this.cssURI;
        if(sss.sheetRegistered(cssURI, sss.USER_SHEET))
            sss.unregisterSheet(cssURI, sss.USER_SHEET);
    }
};
if(this.undoCloseTabsList.options.useMenu) {
    this.type = "menu";
    this.orient = "horizontal";
}
setTimeout(() => this.undoCloseTabsList.updUI(), 250);
var style = custombutton.buttonGetHelp(self).replace(/id/g, _id);
var uri = makeURI('data:text/css,'+ encodeURIComponent(style));
var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
sss.loadAndRegisterSheet(uri, 0); 

addEventListener("contextmenu", e => !this.disabled || e.ctrlKey || e.shiftKey || e.preventDefault(), false, this);

Отредактировано ВВП (Вчера 17:07:39)

Отсутствует

 

Board footer

Powered by PunBB
Modified by Mozilla Russia
Copyright © 2004–2020 Mozilla Russia GitHub mark
Язык отображения форума: [Русский] [English]