Dumby
Не фига не понял,какой сплойер ? где первый ,где второй...Да не увидел сам jsm измененный...Но этот старый - точнее показывает !!!
var EXPORTED_SYMBOLS = ["UCFMemIndReporterChild"]; var ai = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime); var prop = ai.processType == ai.PROCESS_TYPE_DEFAULT ? "resident" : "residentUnique"; var pid = ai.processID; var mrm = Cc["@mozilla.org/memory-reporter-manager;1"].getService(Ci.nsIMemoryReporterManager); class UCFMemIndReporterChild extends JSProcessActorChild {receiveMessage() {return [pid, mrm[prop]];}}
Отредактировано ВВП (11-11-2021 23:43:39)
Отсутствует
Не фига не понял,какой сплойер ? где первый ,где второй...Да не увидел сам jsm измененный...
Но этот старый - точнее показывает !!!
Тогда не трогай, оставь как есть.
Отсутствует
Может вопрос не по теме. Есть кнопка
var iconProxy = 'data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAQAAAAAIAA4GQAAnFmkAHQ5fAAQAKAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAEBAQECAgICAgICAgICAgMBAQEAAAQBJBFQOLQ+nX38ecev/mu6of8gfFvtAyUXewAAAAsAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEBAAAAAAMLUza7PKd//3S7oP2849X9zuvh/mW4mf4XiV7/AB4QZwAAAAAAAAAAAQEBAQAAAAAZGhgTKSwnLyYqJDErKCUnID8vXgaAUP9BlnH8b7ea/ojHrv+q2sf/a7CT+zGWbf8PakXGAAIAAAEBAQMHBwcbAAAAD2BiXn76/ff/4ebg/Onm4f+DtZ7/A31L/j2Wb/+Fwaj/ls23/7rh0v9+vaT+M5du/xKGWO0DIxIdAAAAAAEBAQEAAAABBgYFEaSmorbP08z239vX/4OwnP4ail3/RJlz/5HHsP/T7+X/ms64/3K2mP40k2r/D3tM7AUiExwhIx8meXt1mXt+eKJ3eXSce353n6esouDMysf/o7eq/kOdeP92uZv/vuPT/9Hs4P/C4tT/eLWa+juWbv8bcEq7AAYBAF1gWn7//////f39/P//////////////////////////lcKx/3i9pf/K7OD/2O/l/7ndzf6Fw6n/VK+I/AsxHj8AAAAAXF5bf+Ln2P+AnU/4fZ1N+4WiV/yKp13+jKlh/5CsZf+GpFj/Zpxh/4C5nf+i0L7+k8ex/1udf+UTOCZFAAAAAAEBAQJfYF5/3uXR/16IIPxciiH/Z5Iv/26YOP9ymz3/cpw+/3OcPf9wlzb/YI80/1mKNPu707X/YmZjiAAAAAAEBAQGAAAAAF9gXoDg5tT/cJU6/HGaPf9/pE3/hqtX/4uvXf+NsF7/iKxZ/4KoU/9+o0r/cpY6+9zjyf9ubm2JAAAAAAMEAwQAAAAAX2BegODm1P94nEX8e6JJ/4quXP+Vt2n/nb1z/6LBef+jwXz/ob96/527d/+NrGP71+HG/2praogAAAAABAQDBAAAAABfYF2A4ObU/4WlVvyPsmP/osB7/7HMj/+81J3/wdik/8DXo/+60pz/tc6X/6G6ffvY4sf/amtqiAAAAAAEBAMEAAAAAF9gXn/e5dL/n7l7/LLMk//B16X/zuG2/9jpwv/b68b/2enE/9Pkvv/Q4bv/uMud+9jhyP9qa2mHAAAAAAQEAwQAAAAAX2Bef97k0v+gt335sceT/LrNnfzC1Kj8ydmx/MzatfzK2bP8xtav/MbVr/ywwpL41+HH/2tsaokAAAAABAQDBAAAAABZW1Z3+fz1/+Dm1Pzj6db/5u3b/+nv3v/r8eD/6vDe/+ft2//k69j/4efT/9ngzPv7//b/ZGdhfwAAAAADBAMEAAAAABcZFRpZW1Z6YGFfgWBiYIBhYmGAYmJhgGJjYoBiY2KAYmJhgGFiYYBgYWCAX2BegF1fWoAbHRkeAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
// Настройка функций кликов мыши для кнопки ...................
this.onclick =e=> {
// действие при клике ЛКМ ....
if ( e.button == 0 )openMenuPopup();
// действие при клике СКМ ....
if ( e.button == 1 )
cbu.getPrefs("CB.Proxy.connectionsInTab") ? openConnectionsInTab() : openConnections();
};
// Подсказка для кнопки ...................
this.onmouseover )=> {
var arr = ["Без прокси", "Ручная настройка", "Автоматическая через URL", "", "Автоматическая настройка", "Системная настройка"];
var str = arr.map((m, i)=> (cbu.getPrefs("network.proxy.type") == i ? "●" : " ") + m).filter(m=> /\S/.test(m)).join("\n");
this.tooltipText = "Proxy +\n"
+ "\n" + str
+ "\n\nЛ: Mеню кнопки \nС: Открыть настройки прокси"
+ "\n\nТекущие настройки прокси:"
+ "\nIP: " + cbu.getPrefs("network.proxy.http")
+ "\nПорт: " + cbu.getPrefs("network.proxy.http_port")
};
// Создать меню для кнопки ...................
function openMenuPopup() {
var array = [
{ label: "Без прокси", value: 0, radio: ''},
{ label: "Ручная настройка сервиса прокси:", value: 1, radio: ''},
{ label: "URL автоматической настройки сервиса прокси", value: 2, radio: ''},
{ label: "Автоматически определять настройки прокси для этой сети", value: 4, radio: ''},
{ label: "Использовать системные настройки прокси", value: 5, radio: ''},
{ separator: ''},
{ label: "Добавление прокси в контекстом меню", value: 'CB.Proxy.inContextMenu', checkbox: ''},
{ label: "Открывать настройки прокси как вкладку", value: 'CB.Proxy.connectionsInTab', checkbox: ''},
{ label: "Переключать на режим 'Без прокси' при закрытии браузера ", value: 'CB.Proxy.reset', checkbox: ''}
];
var menuPopup = self.appendChild( document.createXULElement("menupopup") );
menuPopup.setAttribute("onclick", "event.stopPropagation()");
menuPopup.textContent = "";
array.forEach(m=> {
if ( "separator" in m ) { menuPopup.appendChild( document.createXULElement("menuseparator") ); return };
var mItem = menuPopup.appendChild(document.createXULElement("menuitem"))
mItem.setAttribute("label", m.label);
if ( "radio" in m ) {
mItem.setAttribute('type', 'radio');
mItem.setAttribute('checked', cbu.getPrefs("network.proxy.type") == m.value);
mItem.onclick )=> cbu.setPrefs("network.proxy.type", m.value);
}
if ( "checkbox" in m ) {
mItem.setAttribute('type', 'checkbox');
mItem.setAttribute('checked', cbu.getPrefs(m.value) );
mItem.onclick )=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value));
}
});
menuPopup.openPopup(self, "after_start");
};
var listenClick = win => {
var args = ["click", win.close.bind(win), true];
var unload = () => gBrowser.removeEventListener(...args);
gBrowser.addEventListener(...args);
win.addEventListener("unload", unload, {once: true});
}
var version = parseInt(Services.appinfo.platformVersion);
var url = `chrome://browser/content/preferences/dialogs/connection.x${version >= 72 ? "htm" : "u"}l`;
var fox73 = version >= 73, noop = () => {};
if (fox73) var grid = win => {
var url = "data:text/css;charset=utf-8," + encodeURIComponent(`
#proxy-grid, #dnsOverHttps-grid {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
}
#proxy-grid > .thin {
grid-column-end: 3;
height: 20px;
}
#dnsOverHttps-grid.custom-container-hidden #networkCustomDnsOverHttpsInput,
#dnsOverHttps-grid.custom-container-hidden #networkCustomDnsOverHttpsInputLabelContainer {
display: none;
}
`);
(grid = win => win.windowUtils.loadSheetUsingURIString(url, win.windowUtils.AUTHOR_SHEET))(win);
}
var winOpen = win => win.addEventListener("readystatechange", winReady, {once: true, capture: true});
var winReady = e => {
var win = e.target.ownerGlobal, cw = win.isChromeWindow;
if (cw || (win.location == url && !win.docShell.name)) winPatch(win, cw);
}
var winPatch = (win, cw) => {
win.opener = {gSubDialog: {_dialogs: [{
_frame: {get contentDocument() {
cw && listenClick(win);
delete this.contentDocument;
return this.contentDocument = win.document;
}},
resizeVertically: cw ? () => win.sizeToContent() : noop
}]}};
fox73 && grid(win);
}
addEventListener("MozBeforeInitialXULLayout", winReady, false, gBrowser.tabpanels || 1);
for(var {contentWindow: win} of gBrowser.browsers)
win && win.location == url && !win.opener && winPatch(win);
// Функция открывает настройки прокси в окне ...................
function openConnections() {
var win = [...Services.wm.getEnumerator(null)].find(w => w.location == url);
win ? win.focus() : winOpen(openDialog(url, "Proxy", "centerscreen"));
}
// Функция открывает настройки прокси в вкладке ...................
function openConnectionsInTab() {
var connections = gBrowser.getBrowserForTab(
gBrowser.selectedTab = gBrowser.addTrustedTab(url)
);
// oбработчик ждет пока откроется прокси, удаляет себя и добавляет атрибут
connections.addEventListener("pageshow",
e => e.target.documentElement.setAttribute("type", "prefwindow")
, {once: true});
}
// Установливать нужную иконку кнопки при старте баузера или при изменениях в 'about:config' ...................
var s = "network.proxy.type";
function toggleImage() {
var icon = self.icon || self.ownerDocument.getAnonymousElementByAttribute(self, "class", "toolbarbutton-icon");
switch( cbu.getPrefs(s) ) {
case 0: icon.src = self.image; break;
case 1: icon.src = iconProxy; break;
case 2: icon.src = iconProxy; break;
case 4: icon.src = iconProxy; break;
case 5: icon.src = iconProxy; break;
default:icon.src = self.image;
}
};
toggleImage();
Services.prefs.addObserver(s, toggleImage, false);
addDestructor(()=> Services.prefs.removeObserver(s, toggleImage));
// Переключать на режим 'Без прокси' при закрытии браузера если это разрешено в 'about:config' ...................
var switchOffProxy = {
observe: function(subject, topic, data) {
if ( data == "shutdown" && cbu.getPrefs("CB.Proxy.reset") ) cbu.setPrefs("network.proxy.type", 0);
}
};
Services.obs.addObserver(switchOffProxy, "quit-application", false);
// Создаем меню для добавление прокси в контекстном меню выделенного текста на странице ...................
var contextMenu = document.getElementById("contentAreaContextMenu");
var menuitem = document.createElementNS(xulns,"menuitem");
menuitem.setAttribute("label", "Добавить прокси");
menuitem.setAttribute("class", "menuitem-iconic");
menuitem.setAttribute("image", self.image);
menuitem.onclick )=> addNewProxy(menuitem);
contextMenu.appendChild(menuitem); // как последний пункт меню
addDestructor(() => menuitem.remove());
addEventListener("popupshowing", () => {
menuitem.hidden = !cbu.getPrefs("CB.Proxy.inContextMenu") || !gContextMenu.isContentSelected; // !gContextMenu.isTextSelected;
}, false, contextMenu);
// добавление прокси ...................
function addNewProxy(menuitem) {
var sel = gBrowser.contentDocument
? gBrowser.contentDocument.defaultView.getSelection().toString() // Pale Moon
: gContextMenu.selectionInfo.fullText; // Firefox
sel = sel.replace(/^\s+|\s+$/g, ""); // удалить пробелы, слева и справа от строки
sel = sel.replace(/\s+/g, ":"); // заменить пробелы внутри строки
// если только порт ...
if (sel.length < 6 && isFinite(sel)) {
var lab = 'порт';
cbu.setPrefs("network.proxy.http_port", +sel);
}
// если только адрес ...
if (sel.length > 5 && !/.test(sel) && sel.split(".").length == 4) {
var lab = 'адрес';
cbu.setPrefs("network.proxy.http", convertFromUnicode("UTF-8", sel));
}
// если адрес и порт ...
if (sel.length > 5 && /.test(sel) && sel.split(":").length == 2 && sel.split(".").length == 4) {
var lab = 'адрес и порт';
var arr = sel.split(":"), IP = arr[0], port = arr[1];
cbu.setPrefs("network.proxy.http_port", +port);
cbu.setPrefs("network.proxy.http", convertFromUnicode("UTF-8", IP));
}
// всплывающая подсказка рядом с выделенным текстом ...
var mainPopupSet = document.getElementById('mainPopupSet');
var tooltip = mainPopupSet.appendChild(document.createElementNS(xulns,"tooltip"));
tooltip.style.cssText = "color: red !important; font-weight: bold !important; font-size: 14px !important; -moz-box-orient: horizontal; text-align: center;";
var image = tooltip.appendChild(document.createElementNS(xulns, "image"));
image.setAttribute("src", self.image);
var label = tooltip.appendChild(document.createElementNS(xulns, "label"));
label.setAttribute("value", "Установлен " + lab + " прокси: " + sel);
tooltip.openPopup(menuitem.parentNode, "before_start");
setTimeout(() => mainPopupSet.removeChild(tooltip), 3000);
};
// Конвертировать текст в юникод .............
function convertFromUnicode(charset, str) {
var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = charset;
str = converter.ConvertFromUnicode(str);
return str + converter.Finish();
}
На форуме
Как программно сделать скриншот сайта и сохранить его в определённую папку. Лиса 56.0.2. Заранее благодарю!
За давностью не помню кто выкладывал кнопку.
Попробуйте, может подойдёт.
/*Initialization Code*/ // Сохранить как PNG .......... self.label = "Сохранить как PNG"; self._handleClick =()=> menuPopup.showPopup(this, -1, -1, "popup", "bottomleft", "topleft"); self.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGwSURBVHjarJPPaxNBGIafmd1km23saqtRaLB6kFYl2ELpRayCVL20RvCmJwk9ePNWvPsXtCA9eNCDeO0hLemPo96LYAuKkRhtsBViEtI0rrt+GyFQ1oMkfjAf883M+8w7w4zyfZ9uwsxms10RzCBNTd3sSLy2lvsDCCKzWMCKGHgotOTAlpamJPm+jCmFL00bmmbD5WlmsKXTdBltB3bcxowaLWJwsTpi4bvNVu1JMmVn5cmcqTB6/DAg3hcjGpUFskjZjlgFKdmvVIiISKlfUhlyQMVPywgDjvX1YCjpOBZ2fZ+9+TuUpxcZuz7Ebl7ArkfM0dgDcOAFCvfwHTi9URJJi2RCqEuPmRxPUXn9imodLo1D6orGjMHW6govZqfDDkYviDXBlZ4vsFsrk8vXqZRWeDY8hz55lvvpGU7sFEn0RhhTtTBg/tETCvlNdj68papsUoND3Lh6iyPOOYrvv/JufYNrqcssbW8zkjwdBnz7/JKL50/x4F4at9GgsFckX/2IefQHZyb6mbl9l2LpE8ff1PnufWkD/t87yC1v/pvi4V8AwZvuNFS33/m3AAMAhEeAiqLmty4AAAAASUVORK5CYII="; var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); // Создать меню для кнопки ..... var array = [ { label: "Сохранить всю страницу как PNG", func: "WebScreenShot.captureAll()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}, { separator: ''}, { label: "Сохранить видимую часть страницы как PNG", func: "WebScreenShot.capturePage()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}, { separator: ''}, { label: "Сохранить выбранный элемент страницы как PNG", func: "WebScreenShotByClick.init()", image: "data:image/x-icon;base64,AAABAAEAIBkAAAEAIAAMDQAAFgAAACgAAAAgAAAAMgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29fT/2tra/8jIyP/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8jIyP/a2tr/9vX0/+zs7P/ak0b/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/9qTRv/s7Oz/7Ozs/+J9Dv/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+/6SdmP/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/+vn4//z7+v/6+fj/4n0O/+zs7P/s7Oz/4n0O//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/aFtT//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//j39v/ifQ7/7Ozs/+zs7P/ifQ7/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P9oW1P/7+zq/+/s6v/v7Or/8O3r//Dt6//w7ev/8O3r//Dt6//w7ev/8O3r/+/s6v/w7ev/9fTy/+J9Dv/s7Oz/7Ozs/+J9Dv/49/b/+Pf2//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4/2hbU//q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/y8O//4n0O/+zs7P/s7Oz/4n0O//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/aFtT/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe//Dt6//ifQ7/7Ozs/+zs7P/ifQ7/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P9oW1P/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/7uro/+J9Dv/s7Oz/7Ozs/+J9Dv/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx/2hbU//x7+3/8vDv//Hv7f/x7+3/8e/t//Lw7//x7+3/8e/t//Lw7//x7+3/8vDv//Hv7f/29fT/4n0O/+zs7P/s7Oz/4n0O//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//aFtT/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/8vGwf/ifQ7/7Ozs/+zs7P/ifQ7/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f9nWlL/aFtT/2hbU/9nWlL/Z1pS/2hbU/9oW1P/Z1pS/2daUv9oW1P/aFtT/2hbU/9nWlL/pJyX/+J9Dv/s7Oz/7Ozs/+J9Dv/w7ev/8O3r//Dt6//w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Hv7f/w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Dt6//w7ev/4n0O/+zs7P/s7Oz/4n0O/+/s6v/v7Or/7uro/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/u6uj/7+zq/+/s6v/ifQ7/7Ozs/+zs7P/ifQ7/7uro/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7Ojm/+J9Dv/s7Oz/7Ozs/+J9Dv/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/4n0O/+zs7P/s7Oz/4n0O/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/ifQ7/7Ozs/+zs7P/ifQ7/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+J9Dv/s7Oz/7Ozs/+J9Dv/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/4n0O/+zs7P/s7Oz/4n0O/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/ifQ7/7Ozs/+zs7P/ifQ7/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+J9Dv/s7Oz/7Ozs/+J9Dv/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/k39z/4n0O/+zs7P/s7Oz/4n0O/+Lc2f/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/ifQ7/7Ozs/+zs7P/ifQ7/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+J9Dv/s7Oz/9fTy/+J9Dv/8+/r/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/4n0O//X08v/8+/r/6KFU/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ooVT//Pv6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}, { separator: ''}, { label: "Сохранить выбранную область страницы как PNG", func: "WebScreenShotByClipping.init()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAADDn2Hfz5pE/8eVQP7IlkH/yJZB/8iWQf/IlUH/yJVA/8iVQP/IlED/yJQ//8iUP//IlD//yJM+/8iTPv/Hkj3/nI1w//bDbP//8OH//+zW///s1///69b//+rV///p1P//59L//+XQ///izf//38n//9vG///ZxP//1b///dG////Prf/KlkX/88N4/v37///99Pj//fT6//vy9v/68fT/+u/y//rt8P/66u3/+ufq//rl6P/64eT/+93h//3a3//71d7//9LK/86XR//0xHb//vv////18///9fT///f5///4////9f7///P8///v+f//7Pb//+nz///m8f//4eb//9vZ//3Y2v//1Mb/zphH//TGd//+/////Pj1///7///Q58r/m9aV/6TZnv+i15r/otWY/6LTlv+j0pb/mc6M/9DXuf//3+P//Nnc///Wyf/OmUf/9MZ3//7////8+/j//////53WnP+Y5pn/rvGv/6PvpP+e7p//me6b/5nvm/95533/mM+L///j7f/629z//9jL/86ZR//0xnf//v////z9+v//////qtup/8Xzxf/a/tn/z/vO/8n7yf/D+sL/xPvD/6Hzo/+j05b//+Tu//re3///2cz/zplI//XGeP/+/////P36//////+n26f/uvC6/9T71P/K+Mr/xvjG/8D3wP+/+L//nfCf/6LTlf//5u//+t/g///cz//OmUj/9MZ3//7////8/fr//////6rcqv/G9MX/3//f/9n92f/V/NX/0PzQ/9H+0P+s9a7/pdSY///o8f/64OL//9zP/86aSP/0xnf//v////z9+f//////ndid/5TjlP+v7q//qeyp/6jsqf+k7KX/p+6n/4Tlh/+Z0Y7//+r0//rh4v//3tH/zppI//TGd//+/////v77///////Y8Nj/p9+n/6/jr/+t4a3/rd2p/67bpv+u2ab/p9Wc/9jgx///6Oz//OPl///e0f/Omkj/9MV1//7//////fr///78///+/f///////////////////P////j////0+///8fn//+vu///m4v/94+P//97P/86ZSP/zx3v//v/////+/f///////f////v////7////+/////v+///7+///+/f///vz/P/98Pr//+33//3p9///5OL/zppL//a1Sv/0xoL/9cR7//XEfP/1xHz/9cR8//XEfP/1xH3/9cR8//XCev/1wXr/9b94//W9d//1u3X/87l0//y6bP/Llj7/+pMA/vWBAP/1gwD/9YMA//WDAP/1gwD/9YMA//WDAP/1gwD/9YQA//WEAP/1hAD/9YQA//WEAP/zhAH//okA/8qLIv3xpzP/4ptV/+OdU//jnVP/451T/+OdU//jnVP/451T/+OdU//jnVL/451S/+OdUv/jnVL/451S/+GdVf/qnUf/2aRJ/9q0c9/8yn7/98V5/vjGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6/vrIe/+jj2y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}, ]; var menuPopup = self.appendChild(document.createElement("menupopup")); array.forEach((m,i)=> { if ("separator" in m) { menuPopup.appendChild(document.createElement("menuseparator")); return }; var mItem = menuPopup.appendChild(document.createElement("menuitem")); mItem.setAttribute("label", m.label); mItem.setAttribute("class", "menuitem-iconic"); if ("image" in m) mItem.setAttribute("image", m.image || array[i-1].image); if ("func" in m) mItem.addEventListener("command", ()=> eval(m.func.toString())); }); menuPopup.setAttribute("onclick", "event.stopPropagation()"); // Сохранить как PNG страницу или части страницы ..... WebScreenShot = { capture: function(win, x, y, width, height) { var canvas = document.createElementNS(xhtmlns, 'canvas'); canvas.style.display = 'inline'; canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); ctx.clearRect(0, 0, width, height); ctx.save(); try { ctx.scale(1.0, 1.0); } catch(e) { alertsService.showAlertNotification("chrome://global/skin/icons/error-16.png", "Слишком большая страница, не могу сохранить всё", "Кликни чтобы сохранить сколько можно", true, "", (s, t)=> { if ( t == 'alertclickcallback' ) WebScreenShot.capture(content, 0, 0, width, width*17); }, ""); return; } ctx.drawWindow(win, x, y, width, height, "rgb(255,255,255)"); ctx.restore(); var url = canvas.toDataURL("image/png"); var url = Services.io.newURI(url, null, null); var fp = window.makeFilePicker(); fp.init(window, "Сохранить как…", fp.modeSave); fp.appendFilters(fp.filterImages); fp.defaultExtension = "png"; var fileName = getTabLabel(); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '').replace(/\s+/g, '_').slice(0, 100).replace(/^\s+|\s+$/g, ''); var fileDate = (function () { var d = new Date(), z = function(n){return (n < 10 ? '0' : '') + n}; return '[' + z(d.getFullYear()) + '_' + z(d.getMonth()+1) + '_' + z(d.getDate()) + '÷' + z(d.getHours()) + '_' + z(d.getMinutes()) + '_' + z(d.getSeconds()) + ']'; })(); fp.defaultString = fileName + "_" + fileDate + ".png"; if (fp.show() == fp.returnCancel || !fp.file) return; var wbp = window.makeWebBrowserPersist(); parseInt(Services.appinfo.version) < 36 ? wbp.saveURI(url, null, null, null, null, fp.file, null) : wbp.saveURI(url, null, null, null, null, null, fp.file, null); // если FF36+ canvas.remove(); }, captureAll: function() { var win = content; WebScreenShot.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY); }, capturePage: function() { var win = content, doc = win.document, body = doc.body, html = doc.documentElement; var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft; var scrY = (body.scrollTop || html.scrollTop) - html.clientTop; WebScreenShot.capture(win, scrX, scrY, win.innerWidth, win.innerHeight); }, // Запомнить изображение на странице как base64 ..... onImage: function(image) { var canvas = document.createElementNS(xhtmlns, 'canvas'); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight; var ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); var base64 = canvas.toDataURL(); gClipboard.write(base64); // стиль для изображение на сплывающей подсказке ..... var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); // всплывающая подсказка ..... alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { if (t == 'alertfinished') sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается }, ""); } }; // Сохранить выбранную область страницы как PNG ..... WebScreenShotByClipping = { capture: WebScreenShot.capture, handleEvent: function(e) { if (e.button) return false; e.preventDefault(); e.stopPropagation(); switch(e.type){ case 'mousedown': this.downX = e.pageX; this.downY = e.pageY; this.bs.left = this.downX + 'px'; this.bs.top = this.downY + 'px'; this.body.appendChild(this.box); this.flag = true; break; case 'mousemove': if (!this.flag) return; this.moveX = e.pageX; this.moveY = e.pageY; if (this.downX > this.moveX) this.bs.left = this.moveX + 'px'; if (this.downY > this.moveY) this.bs.top = this.moveY + 'px'; this.bs.width = Math.abs(this.moveX - this.downX) + 'px'; this.bs.height = Math.abs(this.moveY - this.downY) + 'px'; break; case 'mouseup': this.uninit(); break; } }, init: function() { this.win = document.commandDispatcher.focusedWindow; if (this.win == window) this.win = content; this.doc = this.win.document; this.body = this.doc.body; if (!this.body instanceof HTMLBodyElement){ alertsService.showAlertNotification(self.image, self.label, "Не удается захватить!"); return false; } this.flag = null; this.box = this.doc.createElement('div'); this.bs = this.box.style; this.bs.border = '#0f0 dashed 2px'; this.bs.position = 'absolute'; this.bs.zIndex = '2147483647'; this.defaultCursor = getComputedStyle(this.body, '').cursor; this.body.style.cursor = 'crosshair'; ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit: function() { var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)]; this.body.style.cursor = this.defaultCursor; this.body.removeChild(this.box); this.capture.apply(this, pos); ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true)); }, }; // Сохранить фрейм на странице как PNG ..... WebScreenShotByClick = { capture: WebScreenShot.capture, getPosition: function() { var html = this.doc.documentElement; var body = this.doc.body; var rect = this.target.getBoundingClientRect(); return [ this.win ,Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft ,Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop ,parseInt(rect.width) ,parseInt(rect.height) ]; }, highlight: function() { this.orgStyle = this.target.hasAttribute('style') ? this.target.style.cssText : false; this.target.style.cssText += 'outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;'; }, lowlight: function(e) { if (this.orgStyle) this.target.style.cssText = this.orgStyle; else this.target.removeAttribute('style'); }, handleEvent: function(e) { switch(e.type){ case 'click': if (e.button) return; e.preventDefault(); e.stopPropagation(); this.lowlight(); var pos = this.getPosition(); this.capture.apply(this, pos); this.uninit(); break; case 'mouseover': if (this.target) this.lowlight(); this.target = e.target; this.highlight(); break; } }, init: function() { this.win = content; this.doc = content.document; ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit: function() { this.target = false; ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true)); }, }; // Получить название вкладки без не сохраняемых символов и лишних пробелов ..... function getTabLabel() { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); };
«The Truth Is Out There»
Отсутствует
Andrey_Krropotkin, здравствуйте.
В этом виновата ваша кнопка. Сейчас её проверил, на 4pda, с "proxy.pac" не пускает, просит капчу.
И еще заметил глюк, не дает скачать торрент, если это - magnet-ссылка.
Если хотите как временное решение, пока не исправят вашу кнопку, воспользуйтесь этой, попроще.
custombutton://%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0D%0A%3Ccustombutton%20xmlns%3Acb%3D%22http%3A//xsms.nm.ru/custombuttons/%22%3E%0A%20%20%3Cname%3E%u0423%u043F%u0440%u0430%u0432%u043B%u0435%u043D%u0438%u0435%20%u043D%u0430%u0441%u0442%u0440%u043E%u0439%u043A%u0430%u043C%u0438%20%u043F%u0440%u043E%u043A%u0441%u0438%3C/name%3E%0A%20%20%3Cimage%3E%3C%21%5BCDATA%5Bdata%3Aimage/png%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA0ElEQVR4nLWRMU4DQQxFn1cUqagoOAZSuhQ5BAflANAFKV2kHIMSpUmxtj9FAsxm5FVSxNKMRp7v5+8Z4z/EbWEAD21ms3ndY+eb896GEAjW67eX39wEEDHGavW4tL72BBBst4ddm+sA0gHNDBMxRgnwGDNigRlcupBOy+OYNcBdmd+YWQ3wVAmI8BiGr8ZBSxGZEPFcjxDuev94+jRADH8mBBgpAUqfOJu2uC2Kv+qBmoNXlKqg09scvSkoNcNMh2vOHeCah5xoLgGV8H6P+AMlwWDGRU9JUgAAAABJRU5ErkJggg%3D%3D%5D%5D%3E%3C/image%3E%0A%20%20%3Cmode%3E0%3C/mode%3E%0A%20%20%3Cinitcode%3E%3C%21%5BCDATA%5Bthis._handleClick%20%3D%28%29%3D%3E%20%7B%0A%20%20%20%20cbu.setPrefs%28s%2C%20cbu.getPrefs%28s%29%20%3D%3D%202%20%3F%205%20%3A%202%29%3B%0A%7D%3B%0A%0Avar%20s%20%3D%20%22network.proxy.type%22%3B%0Afunction%20toggleImage%28%29%20%7B%0A%20%20%20%20var%20%7Bicon%7D%20%3D%20self%3B%0A%20%20%20%20switch%28%20cbu.getPrefs%28s%29%20%29%20%7B%0A%20%20%20%20%20%20%20%20case%205%3A%20icon.src%20%3D%20%22data%3Aimage/png%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA5UlEQVR4nLWSMU4DMRBFv60gsWlTcow0cBHgYlwlucBK0FDScwKKpIni+fNTeFdrJ3iVIPGlke3xzJP97YBJwm0KALAoM6+b7RfCsPOLBGC12x/eXp7XY64C3HXd4eHpcX3ROWgHYP/+8VnmYrlITi5JmAQD6pDQuePoZNlTncBS0pHEvXu+ZMiXkQZ7JFgyNQGJdDfLjWOMAAmSkEifBfyQGRDjZKYEAZA7Eq0NoFHffd/n40dM7yFIPrIqlS/2p38wJxVjEz73Z66qD3N0lCY0FM/W4cb5BeAaI6uac0Cr8P9MPAG8Q3OjXdF9sAAAAABJRU5ErkJggg%3D%3D%22%3B%20break%3B%0A%20%20%20%20%20%20%20%20case%201%3A%20icon.src%20%3D%20%22data%3Aimage/png%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAyUlEQVR4nLWROw7CQAxExwEJpFDlGkh0FJyHc+U0FAjRIXGRfKr1hyLksxt2lRRMtbLs5/EsYZRhnQgAttPK9X59d3WKzBgAQ3kpj33FAzhhOZzzU2q+fbavackDsLBWWiUNqJimAKImQxpEHclsjCeTjcQB7KzRBgTyXRgGaM65F3bgQLTWetgc/oupYSf7+AlOWYtb8QAIHaO3Yd9TAAf2sKHRNYpFPQNOElhOiQ3M+ilFRxjCD2WJDUveM8CSIL2eEBBr/F+IHyKXWDEkGup0AAAAAElFTkSuQmCC%22%3B%20break%3B%0A%20%20%20%20%20%20%20%20case%202%3A%20icon.src%20%3D%20%22data%3Aimage/png%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA0ElEQVR4nLWRMU4DQQxFn1cUqagoOAZSuhQ5BAflANAFKV2kHIMSpUmxtj9FAsxm5FVSxNKMRp7v5+8Z4z/EbWEAD21ms3ndY+eb896GEAjW67eX39wEEDHGavW4tL72BBBst4ddm+sA0gHNDBMxRgnwGDNigRlcupBOy+OYNcBdmd+YWQ3wVAmI8BiGr8ZBSxGZEPFcjxDuev94+jRADH8mBBgpAUqfOJu2uC2Kv+qBmoNXlKqg09scvSkoNcNMh2vOHeCah5xoLgGV8H6P+AMlwWDGRU9JUgAAAABJRU5ErkJggg%3D%3D%22%3B%20break%3B%0A%20%20%20%20%20%20%20%20default%3A%20icon.src%20%3D%20self.image%3B%0A%20%20%20%20%7D%0A%7D%0AtoggleImage%28%29%3B%0AServices.prefs.addObserver%28s%2C%20toggleImage%2C%20false%29%3B%0AaddDestructor%28%28%29%20%3D%3E%20Services.prefs.removeObserver%28s%2C%20toggleImage%29%29%3B%0A%0A%0Avar%20toggleButton%20%3D%20%7B%0A%20%20%20%20observe%28s%2C%20t%2C%20data%29%20%7B%0A%20%20%20%20%20%20%20%20cbu.getPrefs%28%22CB.Proxy.reset%22%29%20%26%26%20data%20%3D%3D%20%22shutdown%22%20%26%26%20cbu.setPrefs%28%22network.proxy.type%22%2C%205%29%3B%0A%20%20%20%20%7D%0A%7D%3B%5D%5D%3E%3C/initcode%3E%0A%20%20%3Ccode%3E%3C%21%5BCDATA%5Bthis.onclick%20%3D%20this.oncontextmenu%20%3D%20e%20%3D%3E%20%7B%0A%20%20%20%20switch%20%28e.button%29%20%7B%0A%20%20%20%20%20%20%20%20case%200%3A%20cbu.setPrefs%28s%2C%20cbu.getPrefs%28s%29%20%21%3D%202%20%3F%202%20%3A%200%29%3B%20break%0A%20%20%20%20%20%20%20%20case%201%3A%20cbu.getPrefs%28s%29%20%21%3D%205%20%26%26%20cbu.setPrefs%28s%2C%205%29%3B%20break%3B%0A%20%20%20%20%20%20%20%20case%202%3A%0A%20%20%20%20%20%20%20%20if%20%28e.shiftKey%20%7C%7C%20e.ctrlKey%20%7C%7C%20e.altKey%20%7C%7C%20e.metaKey%29%20return%3B%0A%20%20%20%20%20%20%20%20e.preventDefault%28%29%3B%20e.stopPropagation%28%29%3B%0A%20%20%20%20%20%20%20%20const%20url%20%3D%20%22about%3Apreferences%23advanced%22%2C%0A%20%20%20%20%20%20%20%20tab%20%3D%20gBrowser.selectedTab%20%3D%20gBrowser.addTab%28url%29%2C%0A%20%20%20%20%20%20%20%20br%20%3D%20tab.linkedBrowser%2C%0A%20%20%20%20%20%20%20%20onPageShow%20%3D%20e%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20const%20win%20%3D%20e.target.defaultView%2C%20%7Btop%7D%20%3D%20win%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%28top.location.href%20%3D%3D%20url%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20br.removeEventListener%28%22pageshow%22%2C%20onPageShow%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20gSubDialog%20%3D%20top.gSubDialog%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20gSubDialog.open%28%22chrome%3A//browser/content/preferences/dialogs/connection.xhtml%22%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%20%20%20%20br.addEventListener%28%22pageshow%22%2C%20onPageShow%29%3B%0A%20%20%20%20%20%20%20%20break%3B%0A%20%20%20%20%7D%0A%7D%3B%5D%5D%3E%3C/code%3E%0A%20%20%3Caccelkey%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/accelkey%3E%0A%20%20%3Chelp%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/help%3E%0A%20%20%3Cattributes/%3E%0A%3C/custombutton%3E
Отсутствует
Пострел
Почему 1 и 2 ? Пример (автомедиа)
custombutton://%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0D%0A%3Ccustombutton%20xmlns%3Acb%3D%22http%3A//xsms.nm.ru/custombuttons/%22%3E%0A%20%20%3Cname%3EStopautoplay%3C/name%3E%0A%20%20%3Cimage%3E%3C%21%5BCDATA%5Bdata%3Aimage/svg+xml%3Bbase64%2CPCEtLSBUaGlzIFNvdXJjZSBDb2RlIEZvcm0gaXMgc3ViamVjdCB0byB0aGUgdGVybXMgb2YgdGhlIE1vemlsbGEgUHVibGljCiAgIC0gTGljZW5zZSwgdi4gMi4wLiBJZiBhIGNvcHkgb2YgdGhlIE1QTCB3YXMgbm90IGRpc3RyaWJ1dGVkIHdpdGggdGhpcwogICAtIGZpbGUsIFlvdSBjYW4gb2J0YWluIG9uZSBhdCBodHRwOi8vbW96aWxsYS5vcmcvTVBMLzIuMC8uIC0tPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTYgMTYiIGZpbGw9IiNGRjAwMDAiIGZpbGwtb3BhY2l0eT0iMSI+CiAgPHBhdGggZD0iTTE0Ljk0NCA0LjA1NmwtMS40NzggMS40NzhhNS45ODkgNS45ODkgMCAwIDEtNy45MyA3LjkzbC0xLjQ4NSAxLjQ4NUE3Ljk4MSA3Ljk4MSAwIDAgMCAxNC45NDQgNC4wNTZ6Ii8+CiAgPHBhdGggZD0iTTExLjk3NCA3LjAyNmwtNC42MDggNC42MDggNC44LTIuNzcxYTEgMSAwIDAgMCAwLTEuNzI2eiIvPgogIDxwYXRoIGQ9Ik0xNC43MDcgMS4yOTNhMSAxIDAgMCAwLTEuNDE0IDBsLS40LjRBNy44IDcuOCAwIDAgMCAxMC45OC41NzRhMSAxIDAgMCAwLS43NDYgMS44NTYgNS43NjcgNS43NjcgMCAwIDEgMS4yMzQuNjg4TDkuMTc1IDUuNDExIDYuNDk0IDMuODYzQTEgMSAwIDAgMCA1IDQuNzI2djQuODZsLTEuODg1IDEuODg1QTUuOTE5IDUuOTE5IDAgMCAxIDMgNC43MjFWNmEuNS41IDAgMCAwIDEgMFYyLjVhLjUuNSAwIDAgMC0uNS0uNWgtM2EuNS41IDAgMCAwIDAgMWgxLjI2MmE3Ljk2MyA3Ljk2MyAwIDAgMC0uMDc0IDkuOWwtLjM5NS4zOTVhMSAxIDAgMSAwIDEuNDE0IDEuNDE0bDEyLTEyYTEgMSAwIDAgMCAwLTEuNDE2eiIvPgo8L3N2Zz4K%5D%5D%3E%3C/image%3E%0A%20%20%3Cmode%3E0%3C/mode%3E%0A%20%20%3Cinitcode%3E%3C%21%5BCDATA%5B%28ps%20%3D%3E%20%7B%0A%0A%0A%20%20%20%20var%20s%20%3D%20%22media.autoplay.default%22%3B%0A%20%0A%20%20%20%20this._handleClick%20%3D%20%28%29%20%3D%3E%20ps.setIntPref%28s%2C%20ps.getIntPref%28s%2C%205%29%20%3F%200%20%3A%205%29%3B%0A%0A%20%20%20%20var%20toggleImage%20%3D%20val%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20this.icon.src%20%3D%20%28val%20%3D%20ps.getIntPref%28s%2C%205%29%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%3F%20this.image%0A%20%20%20%20%20%20%20%20%20%20%20%20%3A%20%22data%3Aimage/svg+xml%3Bcharset%3Dutf-8%3Bbase64%2CPCEtLSBUaGlzIFNvdXJjZSBDb2RlIEZvcm0gaXMgc3ViamVjdCB0byB0aGUgdGVybXMgb2YgdGhlIE1vemlsbGEgUHVibGljCiAgIC0gTGljZW5zZSwgdi4gMi4wLiBJZiBhIGNvcHkgb2YgdGhlIE1QTCB3YXMgbm90IGRpc3RyaWJ1dGVkIHdpdGggdGhpcwogICAtIGZpbGUsIFlvdSBjYW4gb2J0YWluIG9uZSBhdCBodHRwOi8vbW96aWxsYS5vcmcvTVBMLzIuMC8uIC0tPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjE5IiBoZWlnaHQ9IjE5IiB2aWV3Qm94PSIwIC0xIDE3IDE5IiBmaWxsPSJ5ZWxsb3ciIGZpbGwtb3BhY2l0eT0iY29udGV4dC1maWxsLW9wYWNpdHkiPgogIDxwYXRoIGQ9Ik0xMC45OC41NzRhMSAxIDAgMCAwLS43NDYgMS44NTZBNi4wMzQgNi4wMzQgMCAxIDEgMyA0LjcyMVY2YS41LjUgMCAwIDAgMSAwVjIuNWEuNS41IDAgMCAwLS41LS41aC0zYS41LjUgMCAwIDAgMCAxaDEuMjYyQTggOCAwIDEgMCAxMC45OC41NzR6Ii8+CiAgPHBhdGggZD0iTTYuNDk0IDEyLjEzN2w1LjY3Mi0zLjI3NGExIDEgMCAwIDAgMC0xLjcyNkw2LjQ5NCAzLjg2M0ExIDEgMCAwIDAgNSA0LjcyNnY2LjU0OGExIDEgMCAwIDAgMS40OTQuODYzeiIvPgo8L3N2Zz4K%22%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20this.tooltipText%20%3D%20val%20%3F%20%27Stop%20AutoMedia%27%20%3A%20%27Play%20AutoMedia%27%3B%20%0A%20%20%20%20%20%20%0A%20%20%20%20%7D%0A%20%20%20%20toggleImage%28%29%3B%0A%20%20%20%20ps.addObserver%28s%2C%20toggleImage%2C%20false%29%3B%0A%20%20%20%20addDestructor%28%28%29%20%3D%3E%20ps.removeObserver%28s%2C%20toggleImage%29%29%3B%0A%7D%29%28Services.prefs%29%3B%0A%0Athis.oncontextmenu%20%3De%3D%3E%20%7B%20e.button%20%26%26%20%21e.ctrlKey%20%26%26%20e.preventDefault%28%29%20%7D%3B%0Athis.onclick%20%3D%20e%20%3D%3E%20e.button%20%21%3D%201%20%7C%7C%20gShowPopup%28this%29%3B%20%0A%0A%0A%5D%5D%3E%3C/initcode%3E%0A%20%20%3Ccode%3E%3C%21%5BCDATA%5B/*CODE*/%5D%5D%3E%3C/code%3E%0A%20%20%3Caccelkey%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/accelkey%3E%0A%20%20%3Chelp%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/help%3E%0A%20%20%3Cattributes/%3E%0A%3C/custombutton%3E
Отсутствует
Пострел спасибо работает
Добавлено 14-11-2021 23:42:50
Dumby можешь объяснить этот казус, вот кнопка и мое сообщение, вот Пострел в своем посте дал временное решение В чем прикол, вроде кнопка, по моему твоя, вообще не влияет на то как браузер использует прокси, там только форма и порядок выбора действий и от адреса не зависит, или я в чем то ошибаюсь. будь добр разъясни.
Отредактировано Andrey_Krropotkin (14-11-2021 23:42:50)
На форуме
Andrey_Krropotkin
network.proxy.type - 0 ....Это по умолчанию Прописать можно в greprefs.js
И сама кнопка
custombutton://%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0D%0A%3Ccustombutton%20xmlns%3Acb%3D%22http%3A//xsms.nm.ru/custombuttons/%22%3E%0A%20%20%3Cname%3EProxy%3C/name%3E%0A%20%20%3Cimage%3E%3C%21%5BCDATA%5Bdata%3Aimage/png%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACFUlEQVR42mO0DwpKaG9vL2VmZmb8+/fvPwY84P///2DMwcHBcuHChZcp4eE5jJeePn2hIyUl/uDTJwZuLi4GFhYWBmZsmqH073//GD5+/MigIijIEJmTM4Px1Z8/H86dP8/vbmrKQBIAuiS1omIp46u/fz9cunSJ39nQkCT934AGZBUXL2F8+///h/MXLpBswMvfvxnKy8uXMH4GGnDg+HF+Hysr8gwAOuXDvhMn+L0tLUky4On37wzV1dUQAw6fPcvvZmJCkgEPP39mqK+vX8L4E2QAGWFw9/17hubm5iWMv4AGnL55k99KQ4MkA+68e8fQ0dGxlPHxt28vZDg5xUGCf4H4JxD/AOI/f/8y/AMmmt/AwAJhYCplYGRkZPjz5w9YnJeXFxSICxhN3N3zSkpK8kH6371791UOCHR0dIR+/frFAMIgDaDk++rVq78XL158BBT7xMPDw/f69evvrXV1pYxAjSDMA8R8wWlphfn5+SlAM/iB6R1sI0jz169fwfjs2bN3m5qaWu+fObMO6uAvjDA/uUdFle1YurQTxP4KxL+AmAnkFSAGuoxBREiIQRAU+l++fFHg5QXF+RUGqO0QICRkt2z58mU+bm7SXFADfkGl2ICYBYjfAsMCmHNPTaqvDwFyH6MaAAFyMvr6Eebm5hbq6uqyQL9yAQPs/5s3bz4D/X//8OHDh/68fLkWqO41TAMAPUoMne+Z1jQAAAAASUVORK5CYII%3D%5D%5D%3E%3C/image%3E%0A%20%20%3Cmode%3E0%3C/mode%3E%0A%20%20%3Cinitcode%3E%3C%21%5BCDATA%5B%0A%20%28ps%20%3D%3E%20%7B%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%0A%20%20%20this._handleClick%20%3D%20%28%29%20%3D%3E%20%7B%0A%09%09var%20direct%20%3D%20ps.getIntPref%28s%29%20%3D%3D%200%3B%0A%09%09var%20msg%20%3D%20%60%u041F%u0440%u043E%u043A%u0441%u0438%20%u0441%u0435%u0440%u0432%u0435%u0440%u044B%20%3A%20%u0412%24%7Bdirect%20%3F%20%22%22%20%3A%20%22%u044B%22%7D%u043A%u043B%u044E%u0447%u0438%u0442%u044C%20%3F%60%3B%0A%0A%09%09if%20%28%21Services.prompt.confirm%28null%2C%20%22%u0412%u041D%u0418%u041C%u0410%u041D%u0418%u0415%20%21%22%2C%20msg%29%29%20return%3B%0A%0A%09%09ps.setIntPref%28s%2C%20direct%20%3F%202%20%3A%200%29%3B%0A%09%09var%20method%20%3D%20%60%24%7Bdirect%20%3F%20%22en%22%20%3A%20%22dis%22%7Dable%60%3B%0A%09%09AddonManager.getAddonByID%28%22%7Bacf99872-d701-4863-adc2-cdda1163aa34%7D%22%29%0A%09%09%09.then%28addon%20%3D%3E%20addon%5Bmethod%5D%28%29%2C%20Cu.reportError%29%3B%0A%09%7D%0A%20%20%20%20%20var%20s%20%3D%20%22network.proxy.type%22%3B%0A%20%0A%20%20%20%20var%20toggleImage%20%3D%20val%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20this.icon.src%20%3D%20%28val%20%3D%20ps.getIntPref%28s%2C%202%29%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%3F%20this.image%0A%20%20%20%20%20%20%20%20%20%20%20%20%3A%20%22data%3Aimage/png%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACFklEQVR42mO0DwpKaG9vL2VmZmb8+/fvPwY84P///2DMwcHBcuHChZcp4eE5jJeePn2hIyUl/uDTJwZuLi4GFhYWBmZsmqH073//GD5+/MigIijIEJmTM4Px1Z8/H86dP8/vYWrKQAoAuSS1omIp46u/fz9cunSJ38XQkCQDvgINyCouXsL49v//D+cvXCDZgBe/fzOUl5cvYfwMNODA8eP8vlZW5BnwDWjAvhMn+H0sLUky4Mn37wzV1dUQAw6fPcvvbmJCkgEPPn9mqK+vX8L4E2QAGWFw5/17hubm5iWMv4AGnL55k99aQ4MkA26/e8fQ0dGxlPHxt28vZDg5xUGCf4H4JxD/AOI/f/8y/AMmmt/AwAJhYCplYGRkZPjz5w9YnJeXFxSICxhN3N3zSkpK8kH6371791UOCHR0dIR+/frFAMIgDaBE8+rVq78XL158BBT7xMPDw/f69evvrXV1pYxAjSDMA8R8wWlphfn5+SlAM/iB6R1sI0jz169fwfjs2bN3m5qaWu+fObMO6uAvjDA/uUdFle1YurQTxP4KxL+AmAnkFSAGuoxBREiIQRDIfvjlyxcFXl5QnF9hgNoOAUJCdsuWL1/m4+YmzQU14BdUig2IWYD4LTAsgDn31KT6+hAg9zGqARAgJ6OvH2Fubm6hrq4uC/QrFzDA/r958+Yz0P/3Dx8+fOjPy5drgepewzQAAJP3DZ3PnU32AAAAAElFTkSuQmCC%22%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20this.tooltipText%20%3D%20val%20%3F%20%27%u0410%u0432%u0442%u043E%u043F%u0440%u043E%u043A%u0441%u0438%27%20%3A%20%27%u0411%u0435%u0437%20%u043F%u0440%u043E%u043A%u0441%u0438%27%3B%0A%0A%0A%0A%20%20%20%20%20%20%20%20BrowserReload%28%29%3B%0A%20%0A%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%7D%0A%20%20%20%20toggleImage%28%29%3B%0A%20%20%20%20ps.addObserver%28s%2C%20toggleImage%2C%20false%29%3B%0A%20%20%20%20addDestructor%28%28%29%20%3D%3E%20ps.removeObserver%28s%2C%20toggleImage%29%29%3B%0A%7D%29%28Services.prefs%29%3B%0Athis.onclick%20%3D%20e%20%3D%3E%20e.button%20%21%3D%201%20%7C%7C%20gShowPopup%28this%29%3B%20%0Athis.oncontextmenu%20%3De%3D%3E%20%7B%20e.button%20%26%26%20%21e.ctrlKey%20%26%26%20e.preventDefault%28%29%20%7D%3B%0A%0A%5D%5D%3E%3C/initcode%3E%0A%20%20%3Ccode%3E%3C%21%5BCDATA%5B/*CODE*/%0A%5D%5D%3E%3C/code%3E%0A%20%20%3Caccelkey%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/accelkey%3E%0A%20%20%3Chelp%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/help%3E%0A%20%20%3Cattributes/%3E%0A%3C/custombutton%3E
Отсутствует
Dumby можешь объяснить этот казус
Нет, не могу, мне это проверить негде.
Но могу поделиться неким предположением.
А если перед переключением на pac настройка ни разу не побывала
в значении autodetect или в значении system, то есть переключалась
только на direct (0) или manual (1), или только между ними, то PAC-файл перезагружен не будет.
Ну, кроме самого первого переключения на pac (после старта браузера).
У Пострел'а в коде жёстко прописано переключение system <—> pac (5 <—> 2),
а ты своей кнопкой, возможно, переключался direct <—> pac (0 <—> 2), отсюда и различие.
Проверить можешь просто: попробуй своей кнопкой переключаться только между
«Использовать системные настройки прокси» <—> «URL автоматической настройки сервиса прокси»,
если всё в порядке, значит оно.
И, наверно, не лишним будет открыть адрес PAC-файла во вкладке и почитать комментарии в начале,
про «once a minute», особенно.
Отсутствует
Совсем разные вещи. У RV pageAction, а у VDH browserAction.
Такой способ обновления подсказок сложен, нужно подстраиваться под каждую кнопку! Я ожидал простой код обновления подсказок любых кнопок панели.
Сделал mouseenter для панелей page-action-buttons и nav-bar-customization-target. Подсказка обновляется при наведении:
var rv_btn = document.getElementById(`pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_`); if ((e.target == rv_btn) && (!/Режим/.test(rv_btn.tooltipText))) // Reader View rv_btn.tooltipText = rv_help;
Отсутствует
Сделал mouseenter
Так если mouseenter устраивает, то что ты мне голову морочишь.
И раз «ожидал простой код», то можно ещё проще
var tooltips = { "pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_": "RV Tooltip", "_b9db16a4-6edc-47ec-a1f4-b86292ed211d_-browser-action": "VDH Tooltip", }; ....... var trg = e.target, ttt = tooltips[trg.id]; if (ttt) trg.tooltipText = ttt;
для панелей page-action-buttons и nav-bar-customization-target
page-action-buttons то зачем?
Это дочерний элемент того же nav-bar-customization-target.
Отсутствует
Так если mouseenter устраивает, то что ты мне голову морочишь.
И не думал! Цель - улучшить демо-профиль, где многие скрипты уже включены. mouseenter не устраивает цитата в теме UCF: у меня перестал обрабатываться долгий клик в скрипте ToggleAboutConfig, когда добавил addEventListener("mouseenter" для nav-bar-customization-target в скрипт ucf_hookClicks. Ещё back/forward-button при "mouseenter" открывают меню, а не переходят вперёд/назад.
Я просил код, который может добавлять дополнительные клики на уже существующие кнопки тулбара, что позволит проще расширять их возможности, используя один скрипт.
Пробовал изменить твой код перехвата кликов, но не разобрался! Нужно, чтобы работало примерно так:
Изменение яркости скролом над "identity-box" вместо ★, перехват событий указанных id кнопок в начале кода, разбор как в твоём коде кликов:
512: saveSelectionToTxt, // СКМ Click (сохранить .txt) цифра содержит сумму событий: id кнопки, клавиша мыши, управляющие клавиши, дубль-клик, единица для scroll+ равно (num+1), scroll- результат: отрицательное число -(num+1). И добавить LongPress по возможности…
(async (id, func) => { // для custom_script_win.js: дополнительные клики и подсказки кнопок await window.delayedStartupPromise; var nav = document.getElementById("nav-bar-customization-target"), // кнопки панели btn = document.getElementById("downloads-button"), // 0 Загрузки pui = document.getElementById("PanelUI-menu-button"), // 1 меню fav = document.getElementById("star-button"), // 2 vdh = "_b9db16a4-6edc-47ec-a1f4-b86292ed211d_-browser-action", // 3 Video DownloadHelper rv = "pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_"; // 4 Reader View if (!btn) return; btn_help =` Двойной клик: ⬇︎ открыть [Загрузки] …на картинке: ⧉ найти Похожие\n Правый клик (Alt+S): Сохранить в единый html всё / выделенное …дважды Картинки вкл/выкл\n Ролик: Сохранить как файл .txt Колёсико на рисунке: ➜ Сохранить`, sgs_help = `\nAlt⇧S ⌨ нажатие SingleSave`, PanelUI_help = `Клик мыши: меню Firefox ${Services.appinfo.platformVersion} …+ Shift ⚑ Краткая справка …+ Alt Персонализация Клик дважды ⊠ закрыть браузер \n Правый клик ⇲ Свернуть …+ дважды ⤾ Вернуть вкладку …+ Alt Диспетчер задач …+ Shift Адаптивный дизайн\n Колёсико: Развернуть | окно …+ Alt Полный экран …+ дважды Обновить без кэша`, rv_help = `Reader View ${Services.appinfo.OS == "Darwin" ? "⌥⌘M" : "Ctrl+⇧+M"}\n Клик мыши Режим для чтения Колёсико Адаптивный дизайн`, vdh_help = `Video DownloadHelper\nСкачивание проигрываемого видео`; var addDestructor = nextDestructor => { var {destructor} = ucf[id]; ucf[id].destructor = () => { try {destructor();} catch(ex) {Cu.reportError(ex);} nextDestructor(); } }, switchToTab = (but, url) => { // открыть вкладку | закрыть, если открыта for(var tab of but.ownerGlobal.gBrowser.tabs) if ( tab.linkedBrowser.currentURI.spec == url ) {but.ownerGlobal.gBrowser.removeTab(tab); return;}; // закрыть but.ownerGlobal.switchToTabHavingURI(url, true, {relatedToCurrent: true, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); }, showInStatusPanel = (info, time = 5000) => { var win = Services.wm.getMostRecentWindow("navigator:browser"); StatusPanel = win.StatusPanel; if (StatusPanel.update.tid) clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update; StatusPanel.update(); } } StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, time); StatusPanel._label = info; }, Title = (max, title) => { // получить заголовок. без обрезки: max не указан, домен: max <0, + дата: max=0 if (!title) var title = document.title || gBrowser.selectedTab.label; if (max == undefined) return title; // заголовок как есть или ограничить длину, убрать служебные символы title = title.replace(/[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim(); if ( max > 0 ) return title.slice(0, max); if ( max == 0) return title.slice(0, 100) +"_"+ new Date().toLocaleDateString('ru', {day: 'numeric', month: 'numeric', year: '2-digit'}) +'-'+ new Date().toLocaleTimeString().replace(/:/g, "։"); var host = decodeURIComponent(gURLBar.value); // max < 0 if (!/^file:\/\//.test(host)) host = host.replace(/^.*url=|https?:\/\/|www\.|\/.*/g,''); return host.replace(/^ru\.|^m\.|forum\./,'').replace(/^club\.dns/,'dns'); }, saveSelectionToTxt = async () => { // сохранить страницу или выделенный текст как файл .txt var splice = saveURL.length == 10; var msgName = id + ":Save:GetSelection"; var receiver = msg => { var args = ["data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\n\n" + msg.data), Title(0) + '.txt', null, false, true, null, window.document]; splice && args.splice(5, 0, null); saveURL(...args); showInStatusPanel("√ текст сохранён: "+ Title(0).slice(0, 60)); } messageManager.addMessageListener(msgName, receiver); addDestructor(() => messageManager.removeMessageListener(msgName, receiver)); var func = fm => { var res, fed, win = {}, fe = fm.getFocusedElementForWindow(content, true, win); var sel = (win = win.value).getSelection(); if (sel.isCollapsed) { var ed = fe && fe.editor; if (ed && ed instanceof Ci.nsIEditor) sel = ed.selection, fed = fe; } if (sel.isCollapsed) fed && fed.blur(), docShell.doCommand("cmd_selectAll"), res = win.getSelection().toString(), docShell.doCommand("cmd_selectNone"), fed && fed.focus(); res = res || sel.toString(); /\S/.test(res) && sendAsyncMessage("saveSelectionToTxt", res); } var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})`.replace("saveSelectionToTxt", msgName)) + '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));'; (saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, save = async () => { // SingleHtml by Лекс, правка: Dumby, Dobrov var msgName = id + "ucfDwnldsBtnSaveSnapshotToHTML"; if (typeof IOUtils != "object") { // Firefox 78 ESR var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); var PathUtils = {join: (...args) => OS.Path.join(...args)}; var IOUtils = {writeUTF8: (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt))}; } var write = IOUtils.writeUTF8 ? "writeUTF8" : "writeAtomicUTF8"; var msgListener = async msg => { var [fileContent, fileName] = msg.data, dir; // fileName: выделенный текст или null try {dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} var arr = prefs.getStringPref("ucf_save.dirs","_Web||_Images|0").split('|').slice(0,2); //subdir: title|host arr[1] = (arr[1] == "0") ? Title(100) : (arr[1] == "1") ? Title(-1) : ""; // имя вкладки или домен arr.forEach(dir.append); // ucf_save.dirs = "_Web||_Pics|1" HTML сохранится в папку [Загрузки]/_Web/label dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); // создать, если не существует… var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(dir.path); if (!fileName) fileName = Title(100); // убрать служебные символы dir.append(Title(0, fileName) +'.html'); await IOUtils[write](dir.path, fileContent) && showInStatusPanel("√ страница записана: " + fileName.slice(0, 60)); var d = await Downloads.createDownload({ source: "about:blank", target: FileUtils.File(dir.path)}); // Fake download (await Downloads.getList(Downloads.ALL)).add(d); d.refresh(d.succeeded = true); // кнопка Загрузки мигает } messageManager.addMessageListener(msgName, msgListener); addDestructor(() => messageManager.removeMessageListener(msgName, msgListener)); var svc = 'globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services'; var url = "data:;charset=utf8," + encodeURIComponent(`(${func})(${svc});`.replace("%MSG_NAME%", msgName)); (save = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, tid, allowMousedown, listener = { // доп.события для 15 кнопок handleEvent(e) { if (e.detail > 2) return; var btn = e.target; var dbl = e.detail == 2; var num = e.button *512 + e.metaKey *256 + e.ctrlKey *128 + e.shiftKey *64 + e.altKey *32 + dbl *16 + (btn == document.getElementById(rv) && 4) + (btn == vdh && 3) + (btn == fav && 2) + (btn == pui && 1); if (!this[num]) { if (e.button == 1) return; if (e.button) { num = "context"; for(var p in this.a) this.a[p] = e[p]; } else num = "mousedown"; } if (dbl) tid &&= clearTimeout(tid), this[num](btn); else tid = setTimeout(this.exec, 300, num, btn, this); }, exec(num, btn, self) { tid = null; self[num](btn); }, mousedown(e) { allowMousedown = true; e.dispatchEvent(new MouseEvent("mousedown", {})); allowMousedown = false; }, context(e) { e.removeAttribute("context"); e.dispatchEvent(new MouseEvent("contextmenu", this.a)); e.toggleAttribute("context"); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0}, /*** ======= Downloads Clicks ======= ***/ 512: saveSelectionToTxt, // СКМ Click (сохранить .txt) 16() { // Double Left Click - Обзор папки «Загрузки» Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError) // Обзор папки «Загрузки» }, 1024: save, // ПКМ Click (Single HTML) 1040(btn) { // Double Right Click var pref = "permissions.default.image"; var one = prefs.getIntPref(pref) == 1; prefs.setIntPref(pref, one ? 2 : 1); btn.style.filter = one ? "hue-rotate(180deg) brightness(95%)" : ""; BrowserReload(); }, /*** ======= PanelUI-menu Clicks ======= 100*pui 32*e.button 8*e.ctrlKey 4*e.shiftKey 2*e.altKey dbl btn ***/ 33() { gCustomizeMode.enter(); // ЛКМ + Alt Персонализация }, 65() { // Shift + ЛКМ var help_ucf = ['chrome://user_chrome_files/content/help.html', 'http://forum.puppyrus.org/index.php?topic=22762']; var newURI = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).convertChromeURL(Services.io.newURI(help_ucf[0])); // .spec = file:/// (newURI.QueryInterface(Ci.nsIFileURL).file.exists()) ? switchToTab(pui, help_ucf[0]) : switchToTab(pui, help_ucf[1]); }, 545: BrowserFullScreen, // Alt + СКМ 513() { // СКМ windowState != STATE_MAXIMIZED ? maximize() : restore(); }, 529: BrowserReloadSkipCache, // СКМ Double 1025() { // ПКМ minimize(); }, 1057(pui) { // Alt + ПКМ switchToTab(pui, 'about:performance'); }, 1089(pui) { // Shift + ПКМ pui.ownerDocument.getElementById("key_responsiveDesignMode").doCommand(); // запуск пункта меню с HotKey if (gBrowser.selectedBrowser.browsingContext.inRDMPane) BrowserReload(); }, 1153(pui) { // Shift + Alt + ПКМ var obj = ChromeUtils.import("resource://devtools/shared/Loader.jsm").require("devtools/client/menus").menuitems.find(menuitem => menuitem.id == "menu_devtools_remotedebugging"); (this[138] = target => obj.oncommand({target}))(pui); // запуск пункта меню, у которого нет HotKey }, 17: BrowserTryToCloseWindow, // Double Left Click 1041(pui) { // ПКМ Double Right Click pui.ownerGlobal.undoCloseTab(); }, }, // end listener keydown_win = e => { // нажатие клавиш if (e.keyCode == 83 && e.altKey) e.shiftKey // Alt+S [+Shift] ? singlesave ? singlesave.click() : save() : save(); // имитировать клик по кнопке, используя её ID if (e.keyCode == 68 && e.altKey){ // Alt+D отладка - запуск внешнего JS // e.target.ownerDocument.getElementById("key_browserConsole").doCommand(); eval(Cu.readUTF8URI(Services.io.newURI("chrome://user_chrome_files/content/custom_scripts/User.js"))); console.log("END User.js " + Math.random()); } }, str_cut = (s, cut = 33) => { // сократить/разбить длинную строку return s.substring(0,cut) + `${s.length > cut - 1 ? `…\n…${s.substring(s.length -cut + 2, s.length)}`: ""}`; }, {prefs, dirsvc} = Services, linux = /macos|linux/.test(AppConstants.platform), singlesave; prefs.setBoolPref("browser.download.autohideButton", false); // не скрывать кнопку Загрузки var hint_upd = function(e, text, find) { // обновить подсказку var tooltips = { "downloads-button": [btn_help, 1], "PanelUI-menu-button": [PanelUI_help], "pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_": [rv_help], "_b9db16a4-6edc-47ec-a1f4-b86292ed211d_-browser-action": [vdh_help], }, trg = e.target, hint = tooltips[trg.id][0], dw; if (tooltips[trg.id][1] == 1) { // здесь надо упростить hint = GetDynamicShortcutTooltipText(trg.id) + hint; if (document.getElementById('_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action') && !/SingleSave/.test(hint)) hint = hint + sgs_help; if (!/выбранная/.test(hint)) try {dw = prefs.getComplexValue("browser.download.dir",Ci.nsIFile)} catch {dw = dirsvc.get("DfltDwnld", Ci.nsIFile)}; hint = hint + `${dw ? "\n\n[Загрузки] — выбранная папка:\n"+ str_cut(dw.path, 33) : ""}`; } if (trg.tooltipText != hint) trg.tooltipText = hint; } var mouseenter = function(e) { this.parentNode.addEventListener("mousedown", stop, true); this.addEventListener("mouseleave", mouseleave, {once: true}); hint_upd(e); } var mouseleave = function(e) { this.parentNode.removeEventListener("mousedown", stop, true); } var stop = e => { e.button || allowMousedown || e.stopImmediatePropagation(); } var btns = [btn, pui]; for(var b of btns) { b.toggleAttribute("context"), b.addEventListener("click", listener, true), b.addEventListener("mouseenter", mouseenter); } var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win; ucf[id] = {destructor() { for(var b of btns) { b.removeEventListener("click", listener, true); b.removeEventListener("mouseenter", mouseenter); if (b.matches(":hover")) b.removeEventListener("mouseleave", mouseleave), b.parentNode.removeEventListener("mousedown", stop, true); } }}; ucf.unloadlisteners.push(id); var boxLst = e => { // console.log('@: '+ e.button); if (e.button == 1 && e.target.id == `pageAction-urlbar-_${rv}_`) { // Reader View Button e.stopImmediatePropagation(), document.getElementById("key_responsiveDesignMode").doCommand(); // Адаптивный дизайн if (gBrowser.selectedBrowser.browsingContext.inRDMPane) BrowserReload(); } } nav.addEventListener("auxclick", boxLst, true); nav.addEventListener("mouseenter", mouseenter, true); window.addEventListener("keydown", keydown_win); addDestructor(() => { nav.removeEventListener("auxclick", boxLst, true); nav.removeEventListener("mouseenter", mouseenter, true); window.removeEventListener("keydown", keydown_win); }); })("downloads-button-click-listener", ({io, focus}) => { // SingleHTML не сохраняет svg графику var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec;} catch {} }, getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r;} catch(e) {} } }, encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else img = obj; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }, toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }, mainWin = {}; focus.getFocusedElementForWindow(content, true, mainWin); mainWin = mainWin.value; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild), meta = doc.createElement('meta'), sheets = doc.styleSheets, title = doc.getElementsByTagName('title')[0]; meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var selText = selWin ? win.getSelection().toString().slice(0, 200) : undefined; sendAsyncMessage("%MSG_NAME%", [doctype + sel.innerHTML +'\n<a href='+ (loc.protocol != 'data:' ? loc.href : 'data:uri') +'><small><blockquote>источник: '+ new Date().toLocaleString("ru") +'</blockquote></small></a>', selText]); // выделенный текст }); // END hookClicks
Отредактировано Dobrov (22-11-2021 01:40:08)
Отсутствует
Не могу запустить две 94 . Или профиль один работает... Может в INI что то новое надо ?
У меня нормально запускаются. Каждая со своим профилем.
«в INI» ничего нового не добавлял. Проверил на Win 7 и 10.
перестал обрабатываться долгий клик в скрипте ToggleAboutConfig, когда добавил
Не, это ты совсем что-то левое добавил.
Лучше отдельный фрагмент сделать,
только для тултипов, и со своим mouseenter-обработчиком.
Вот, правда в CB набирал, но, думаю, понятно.
var str_cut = s => s; var dsym = Symbol(); var j = arr => arr.join("\n"); var tooltips = { "PanelUI-menu-button": j([ `Клик мыши: меню Firefox ${Services.appinfo.platformVersion}`, "…+ Shift ⚑ Краткая справка", "…+ Alt Персонализация", "Клик дважды ⊠ закрыть браузер\n", "Правый клик ⇲ Свернуть", "…+ дважды ⤾ Вернуть вкладку", "…+ Alt Диспетчер задач", "…+ Shift Адаптивный дизайн\n", "Колёсико: Развернуть | окно", "…+ Alt Полный экран", "…+ дважды Обновить без кэша" ]), "pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_": j([ `Reader View ${Services.appinfo.OS == "Darwin" ? "⌥⌘M" : "Ctrl+⇧+M"}\n`, "Клик мыши Режим для чтения", "Колёсико Адаптивный дизайн" ]), "_b9db16a4-6edc-47ec-a1f4-b86292ed211d_-browser-action": j([ "Video DownloadHelper", "Скачивание проигрываемого видео" ]), [dsym]: j([ GetDynamicShortcutTooltipText("downloads-button"), "\nДвойной клик: ⬇︎ открыть [Загрузки]", "…на картинке: ⧉ найти Похожие\n", "Правый клик (Alt+S): Сохранить", " в единый html всё / выделенное", "…дважды Картинки вкл/выкл\n", "Ролик: Сохранить как файл .txt", "Колёсико на рисунке: ➜ Сохранить" ]), get "downloads-button"() { var hint = this[dsym]; if (document.getElementById("_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action")) hint += "\nAlt⇧S ⌨ нажатие SingleSave"; try {var dw = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dw = Services.dirsvc.get("DfltDwnld", Ci.nsIFile);} if (dw) hint += "\n\n[Загрузки] — выбранная папка:\n" + str_cut(dw.path, 33); return hint; }, }; addEventListener("mouseenter", e => { var hint = tooltips[e.target.id]; if (hint) e.target.tooltipText = hint; }, true, document.getElementById("nav-bar") || 1);
Отредактировано Dumby (22-11-2021 21:23:31)
Отсутствует
Dumby
Да, косяк здесь был...Все норм. теперь.
[General]
StartWithLastProfile=1
[Profile0]
Name=default
IsRelative=1
Path=../../../
Default=1
Вопрос: Как рихтануть Attributes Inspector , чтобы наводил cursor:default ? А то кнопки pointer... Неудобно.
Отредактировано ВВП (23-11-2021 11:30:17)
Отсутствует
Здравствуйте, для Firefox 91.0.2 устанавливаю версию custom_buttons-0.0.7.0.0.19, далее кнопку Undo Close Tabs 0.3.3.2 (2020-03-14), но кнопка не появляется в панели инструментов. Также нет нигде элемента меню Добавить кнопку. В Firefox 94.0.2 также ничего не работает. В Firefox 75 все работало без проблем. Подскажите пожалуйста, решение этой проблемы.
Код кнопки
custombutton://%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0D%0A%3Ccustombutton%20xmlns%3Acb%3D%22http%3A//xsms.nm.ru/custombuttons/%22%3E%0A%20%20%3Cname%3EUndo%20Close%20Tab%3C/name%3E%0A%20%20%3Cimage%3E%3C%21%5BCDATA%5Bdata%3Aimage/png%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABZVBMVEX////w8PD09PTx8fHw8PCPkIvv7++LjIfw8PDu7u6ZmZXv7+/29vbw8PD///+Txdt8lJ2RkY2Sk4+bzeJcnLsbcp6LjIcwf6bg4N/m//+XyuDf7/+LvNGmr68ufqbg4N9OhaLm8PJvrstCjrPg4N9Rk7Q8hqfk8PRoqMc5h60vgKk9ia/f4N7w8PDi7/ZgpMOLtMny9fYmeaIqfaff4N6hpKLv7+/h8PVwqcTB1N3L3ebv7+9trMqLjIeOj4rf39719vbM7PaMt81hpMPL7fmbnJeoqaXr6+tin774+/vF2t+lq6qKlI+hop38/Pz7+/v5+fn9/f29vruLjIeqq6f7+/v5+fnGxsSLjId5rcfg8vw4ibN8ud3n8vgacZ2extrA5//4+/wacp4yha8ZcZ18wuyIxuthrNc5irdvt+KRzvO62ep+w+7N6PeY1/+U1v+h2/9am7sbcp4keaXm8/ovgq07jLe+yJo8AAAAWXRSTlMAES5KZr+CMJ7X7Lr4ZwHdD4f0yftxJtP6Cj4Q/EIe9HPg/tXy/kvL/fr++fGfuf3Bzv787+6DptCRyLvRDs/u+P3O+TSw5Or8ovXiHqKWW0aBpyVHNSZMDw1FfDAAAACvSURBVHhehchTcwRBAIXRXmewtG3btm0jtn9/elPZmpqnnKd7P0DgADK5glyUQpH4b0pYkJo730t1PADxBSiKhlVvT4v11myBgSHD8Vz+cP388rr7rGlg0CIIojccrx5v7u4fjDCYMAxLWm1f33bHcuWEwXUBuT3eS58/cBuEIcQ8iURj8cT7RwqkM1n6LzabXtgUS6BcqdLO6o1mC7Q7XepZrz8YgtGYQphMZ+BfP976HHRDoNUhAAAAAElFTkSuQmCC%5D%5D%3E%3C/image%3E%0A%20%20%3Cmode%3E0%3C/mode%3E%0A%20%20%3Cinitcode%3E%3C%21%5BCDATA%5B//%20http%3A//infocatcher.ucoz.net/js/cb/undoCloseTabs.js%0A//%20https%3A//forum.mozilla-russia.org/viewtopic.php%3Fid%3D56267%0A//%20https%3A//github.com/Infocatcher/Custom_Buttons/tree/master/Undo_Close_Tabs%0A%0A//%20Undo%20Close%20Tabs%20button%20for%20Custom%20Buttons%0A//%20%28code%20for%20%22initialization%22%20section%29%0A%0A//%20%28c%29%20Infocatcher%202009-2015%2C%202017-2020%0A//%20version%200.3.3.2%20-%202020-03-14%0A%0Avar%20options%20%3D%20%7B%0A%09menuTemplate%3A%20%5B%0A%09%09%22closedWindows%22%2C%0A%09%09%22separator%22%2C%0A%09%09%22restoreClosedWindows%22%2C%0A%09%09%22clearClosedWindows%22%2C%0A%09%09%22separator%22%2C%0A%09%09%22closedTabs%22%2C%0A%09%09%22separator%22%2C%0A%09%09%22restoreClosedTabs%22%2C%0A%09%09%22clearClosedTabs%22%2C%0A%09%09%22separator%22%2C%0A%09%09%22clearAll%22%2C%0A%09%09%22separator%22%2C%0A%09%09%22restoreLastSession%22%2C%0A%09%09%22separator%22%2C%0A%09%09%22buttonMenu%22%0A%09%5D%2C%0A%09showInTabContextMenu%3A%20false%2C%0A%09/*%0A%09menuTemplateTabContext%3A%20%5B%20//%20like%20menuTemplate%0A%09%09%22closedTabs%22%2C%0A%09%09%22separator%22%2C%0A%09%09%22restoreClosedTabs%22%2C%0A%09%09%22clearClosedTabs%22%0A%09%5D%2C%0A%09*/%0A%09windowItemTemplate%3A%20%22%28%25count%29%20%25title%22%2C%0A%09windowSelectedTabPrefix%3A%20%22*%22%2C%0A%09buttonTipTemplate%3A%20%5B%22header%22%2C%20%22title%22%2C%20%22url%22%2C%20%22closedAt%22%5D%2C%0A%09itemTipTemplate%3A%20%5B%22title%22%2C%20%22url%22%2C%20%22closedAt%22%5D%2C%0A%09hideRestoreAllForSingleEntry%3A%20false%2C%0A%09allowDeleteEntries%3A%20true%2C%0A%09accesskeys%3A%20%7B%20//%20Empty%20string%20%28%22%22%29%20to%20disable%20or%20string%20with%20possible%20values%20%28%220123...%22%2C%20%22abcd...%22%29%0A%09%09closedTabs%3A%20%22%22%2C%0A%09%09closedWindows%3A%20%22%22%0A%09%7D%2C%0A%09accesskeySeparator%3A%20%22%20%22%2C%20//%20%3Caccesskey%3E%3Cseparator%3E%3Clabel%3E%0A%09openMenuOnMouseover%3A%20false%2C%0A%09useMenu%3A%20false%2C%0A%09rightClickToUndoCloseTab%3A%20false%20//%20Useful%20with%20%22useMenu%3A%20true%22%0A%7D%3B%0A%0Afunction%20_localize%28sid%29%20%7B%0A%09var%20strings%20%3D%20%7B%0A%09%09en%3A%20%7B%0A%09%09%09restoreTab%3A%20%22Restore%20the%20most%20recently%20closed%20tab%22%2C%0A%0A%09%09%09restoreAllTabs%3A%20%22Restore%20all%20tabs%22%2C%0A%09%09%09restoreAllTabsAccesskey%3A%20%22t%22%2C%0A%09%09%09clearTabsHistory%3A%20%22Clear%20history%20of%20closed%20tabs%22%2C%0A%09%09%09clearTabsHistoryAccesskey%3A%20%22b%22%2C%0A%0A%09%09%09restoreAllWindows%3A%20%22Restore%20all%20windows%22%2C%0A%09%09%09restoreAllWindowsAccesskey%3A%20%22w%22%2C%0A%09%09%09clearWindowsHistory%3A%20%22Clear%20history%20of%20closed%20windows%22%2C%0A%09%09%09clearWindowsHistoryAccesskey%3A%20%22d%22%2C%0A%0A%09%09%09clearAllHistory%3A%20%22Clear%20all%20history%22%2C%0A%09%09%09clearAllHistoryAccesskey%3A%20%22C%22%2C%0A%0A%09%09%09restoreLastSession%3A%20%22Restore%20last%20session%22%2C%0A%09%09%09restoreLastSessionAccesskey%3A%20%22s%22%2C%0A%0A%09%09%09deleteUndoEntry%3A%20%22Delete%22%2C%0A%0A%09%09%09buttonMenu%3A%20%22Button%20menu%22%2C%0A%09%09%09buttonMenuAccesskey%3A%20%22m%22%2C%0A%0A%09%09%09tabContextMenu%3A%20%22Recently%20Closed%20Tabs%22%2C%0A%09%09%09tabContextMenuAccesskey%3A%20%22y%22%2C%0A%0A%09%09%09itemTip%3A%20%22%25ago%20ago%2C%20%25date%22%2C%0A%09%09%09day%3A%20%22d%22%0A%09%09%7D%2C%0A%09%09ru%3A%20%7B%0A%09%09%09restoreTab%3A%20%22%u0412%u043E%u0441%u0441%u0442%u0430%u043D%u043E%u0432%u0438%u0442%u044C%20%u043F%u043E%u0441%u043B%u0435%u0434%u043D%u044E%u044E%20%u0437%u0430%u043A%u0440%u044B%u0442%u0443%u044E%20%u0432%u043A%u043B%u0430%u0434%u043A%u0443%22%2C%0A%0A%09%09%09restoreAllTabs%3A%20%22%u0412%u043E%u0441%u0441%u0442%u0430%u043D%u043E%u0432%u0438%u0442%u044C%20%u0432%u0441%u0435%20%u0432%u043A%u043B%u0430%u0434%u043A%u0438%22%2C%0A%09%09%09restoreAllTabsAccesskey%3A%20%22%u043B%22%2C%0A%09%09%09clearTabsHistory%3A%20%22%u041E%u0447%u0438%u0441%u0442%u0438%u0442%u044C%20%u0438%u0441%u0442%u043E%u0440%u0438%u044E%20%u0437%u0430%u043A%u0440%u044B%u0442%u044B%u0445%20%u0432%u043A%u043B%u0430%u0434%u043E%u043A%22%2C%0A%09%09%09clearTabsHistoryAccesskey%3A%20%22%u0434%22%2C%0A%0A%09%09%09restoreAllWindows%3A%20%22%u0412%u043E%u0441%u0441%u0442%u0430%u043D%u043E%u0432%u0438%u0442%u044C%20%u0432%u0441%u0435%20%u043E%u043A%u043D%u0430%22%2C%0A%09%09%09restoreAllWindowsAccesskey%3A%20%22%u043E%22%2C%0A%09%09%09clearWindowsHistory%3A%20%22%u041E%u0447%u0438%u0441%u0442%u0438%u0442%u044C%20%u0438%u0441%u0442%u043E%u0440%u0438%u044E%20%u0437%u0430%u043A%u0440%u044B%u0442%u044B%u0445%20%u043E%u043A%u043E%u043D%22%2C%0A%09%09%09clearWindowsHistoryAccesskey%3A%20%22%u043D%22%2C%0A%0A%09%09%09clearAllHistory%3A%20%22%u041E%u0447%u0438%u0441%u0442%u0438%u0442%u044C%20%u0432%u0441%u044E%20%u0438%u0441%u0442%u043E%u0440%u0438%u044E%22%2C%0A%09%09%09clearAllHistoryAccesskey%3A%20%22%u0447%22%2C%0A%0A%09%09%09restoreLastSession%3A%20%22%u0412%u043E%u0441%u0441%u0442%u0430%u043D%u043E%u0432%u0438%u0442%u044C%20%u043F%u043E%u0441%u043B%u0435%u0434%u043D%u044E%u044E%20%u0441%u0435%u0441%u0441%u0438%u044E%22%2C%0A%09%09%09restoreLastSessionAccesskey%3A%20%22%u0441%22%2C%0A%0A%09%09%09deleteUndoEntry%3A%20%22%u0423%u0434%u0430%u043B%u0438%u0442%u044C%22%2C%0A%0A%09%09%09buttonMenu%3A%20%22%u041C%u0435%u043D%u044E%20%u043A%u043D%u043E%u043F%u043A%u0438%22%2C%0A%09%09%09buttonMenuAccesskey%3A%20%22%u041C%22%2C%0A%0A%09%09%09tabContextMenu%3A%20%22%u041D%u0435%u0434%u0430%u0432%u043D%u043E%20%u0437%u0430%u043A%u0440%u044B%u0442%u044B%u0435%20%u0432%u043A%u043B%u0430%u0434%u043A%u0438%22%2C%0A%09%09%09tabContextMenuAccesskey%3A%20%22%u043E%22%2C%0A%0A%09%09%09itemTip%3A%20%22%25ago%20%u043D%u0430%u0437%u0430%u0434%2C%20%25date%22%2C%0A%09%09%09day%3A%20%22%u0434%22%0A%09%09%7D%0A%09%7D%3B%0A%09var%20locale%20%3D%20%28function%28%29%20%7B%0A%09%09if%28%22Services%22%20in%20window%20%26%26%20%22locale%22%20in%20Services%29%20%7B%0A%09%09%09var%20locales%20%3D%20Services.locale.requestedLocales%20//%20Firefox%2064+%0A%09%09%09%09%7C%7C%20Services.locale.getRequestedLocales%20%26%26%20Services.locale.getRequestedLocales%28%29%3B%0A%09%09%09if%28locales%29%0A%09%09%09%09return%20locales%5B0%5D%3B%0A%09%09%7D%0A%09%09var%20prefs%20%3D%20%22Services%22%20in%20window%20%26%26%20Services.prefs%0A%09%09%09%7C%7C%20Components.classes%5B%22@mozilla.org/preferences-service%3B1%22%5D%0A%09%09%09%09.getService%28Components.interfaces.nsIPrefBranch%29%3B%0A%09%09function%20pref%28name%2C%20type%29%20%7B%0A%09%09%09return%20prefs.getPrefType%28name%29%20%21%3D%20prefs.PREF_INVALID%20%3F%20prefs%5B%22get%22%20+%20type%20+%20%22Pref%22%5D%28name%29%20%3A%20undefined%3B%0A%09%09%7D%0A%09%09if%28%21pref%28%22intl.locale.matchOS%22%2C%20%22Bool%22%29%29%20%7B%20//%20Also%20see%20https%3A//bugzilla.mozilla.org/show_bug.cgi%3Fid%3D1414390%0A%09%09%09var%20locale%20%3D%20pref%28%22general.useragent.locale%22%2C%20%22Char%22%29%3B%0A%09%09%09if%28locale%20%26%26%20locale.substr%280%2C%209%29%20%21%3D%20%22chrome%3A//%22%29%0A%09%09%09%09return%20locale%3B%0A%09%09%7D%0A%09%09return%20Components.classes%5B%22@mozilla.org/chrome/chrome-registry%3B1%22%5D%0A%09%09%09.getService%28Components.interfaces.nsIXULChromeRegistry%29%0A%09%09%09.getSelectedLocale%28%22global%22%29%3B%0A%09%7D%29%28%29.match%28/%5E%5Ba-z%5D*/%29%5B0%5D%3B%0A%09_localize%20%3D%20function%28sid%29%20%7B%0A%09%09return%20strings%5Blocale%5D%20%26%26%20strings%5Blocale%5D%5Bsid%5D%20%7C%7C%20strings.en%5Bsid%5D%20%7C%7C%20sid%3B%0A%09%7D%3B%0A%09return%20_localize.apply%28this%2C%20arguments%29%3B%0A%7D%0A%0Avar%20JSON%20%3D%20%22JSON%22%20in%20window%0A%09%3F%20window.JSON%0A%09%3A%20%22nsIJSON%22%20in%20Components.interfaces%0A%09%09%3F%20%7B%0A%09%09%09parse%3A%20function%28s%29%20%7B%0A%09%09%09%09return%20Components.classes%5B%22@mozilla.org/dom/json%3B1%22%5D%0A%09%09%09%09%09.createInstance%28Components.interfaces.nsIJSON%29%0A%09%09%09%09%09.decode%28s%29%3B%0A%09%09%09%7D%0A%09%09%7D%0A%09%09%3A%20%7B%0A%09%09%09parse%3A%20function%28s%29%20%7B%0A%09%09%09%09return%20Components.utils.evalInSandbox%28%22%28%22%20+%20s%20+%20%22%29%22%2C%20new%20Components.utils.Sandbox%28%22about%3Ablank%22%29%29%3B%0A%09%09%09%7D%0A%09%09%7D%3B%0A%0Athis.onclick%20%3D%20function%28e%29%20%7B%0A%09if%28e.target%20%21%3D%20this%29%0A%09%09return%3B%0A%09if%28e.button%20%3D%3D%201%20%7C%7C%20e.button%20%3D%3D%200%20%26%26%20%28e.ctrlKey%20%7C%7C%20e.shiftKey%20%7C%7C%20e.altKey%20%7C%7C%20e.metaKey%29%29%0A%09%09this.undoCloseTabsList.clearAllLists%28%29%3B%0A%09else%20if%28%0A%09%09e.button%20%3D%3D%200%0A%09%09%7C%7C%20e.button%20%3D%3D%202%20%26%26%20%21e.ctrlKey%20%26%26%20%21e.shiftKey%20%26%26%20%21e.altKey%20%26%26%20%21e.metaKey%0A%09%09%09%26%26%20this.undoCloseTabsList.options.rightClickToUndoCloseTab%0A%09%29%20%7B%0A%09%09if%28%0A%09%09%09e.button%20%3D%3D%200%20%26%26%20%21this.undoCloseTabsList.options.useMenu%0A%09%09%09%7C%7C%20e.button%20%3D%3D%202%20%26%26%20this.undoCloseTabsList.options.rightClickToUndoCloseTab%0A%09%09%29%20%7B%0A%09%09%09if%28this.undoCloseTabsList.closedTabCount%29%0A%09%09%09%09this.undoCloseTabsList.undoCloseTab%28%29%3B%0A%09%09%09else%0A%09%09%09%09this.undoCloseTabsList.drawUndoList%28%29%20%26%26%20this.undoCloseTabsList.showMenu%28e%29%3B%0A%09%09%7D%0A%09%09//%20Allow%20use%20%22command%22%20section%20only%20from%20hotkey%3A%0A%09%09e.preventDefault%28%29%3B%0A%09%09e.stopPropagation%28%29%3B%0A%09%7D%0A%7D%3B%0Aif%28%21this.hasOwnProperty%28%22defaultContextId%22%29%29%0A%09this.defaultContextId%20%3D%20this.getAttribute%28%22context%22%29%20%7C%7C%20%22custombuttons-contextpopup%22%3B%0Athis.onmousedown%20%3D%20function%28e%29%20%7B%0A%09if%28e.target%20%21%3D%20this%29%0A%09%09return%3B%0A%09if%28this.undoCloseTabsList.options.useMenu%29%20%7B%0A%09%09if%28e.button%20%3D%3D%200%29%0A%09%09%09this.undoCloseTabsList.drawUndoList%28%29%3B%0A%09%7D%0A%09else%20if%28e.button%20%3D%3D%202%29%20%7B%0A%09%09var%20showCbMenu%20%3D%20e.ctrlKey%20%7C%7C%20e.shiftKey%20%7C%7C%20e.altKey%20%7C%7C%20e.metaKey%20%7C%7C%20%21this.undoCloseTabsList.drawUndoList%28%29%3B%0A%09%09this.setAttribute%28%0A%09%09%09%22context%22%2C%0A%09%09%09showCbMenu%0A%09%09%09%09%3F%20this.defaultContextId%0A%09%09%09%09%3A%20this.undoCloseTabsList.mpId%0A%09%09%29%3B%0A%09%7D%0A%7D%3B%0Athis.onmouseover%20%3D%20function%28e%29%20%7B%0A%09if%28e.target%20%21%3D%20this%29%0A%09%09return%3B%0A%09if%28%21this.disabled%29%0A%09%09this.undoCloseTabsList.updUI%28%29%3B%0A%09this.undoCloseTabsList.options.useMenu%20%26%26%20Array.prototype.some.call%28%0A%09%09this.parentNode.getElementsByTagName%28%22*%22%29%2C%0A%09%09function%28node%29%20%7B%0A%09%09%09if%28%0A%09%09%09%09node%20%21%3D%20this%0A%09%09%09%09%26%26%20node.namespaceURI%20%3D%3D%20xulns%0A%09%09%09%09//%20See%20https%3A//github.com/Infocatcher/Custom_Buttons/issues/28%0A%09%09%09%09//%26%26%20node.boxObject%0A%09%09%09%09//%26%26%20node.boxObject%20instanceof%20Components.interfaces.nsIMenuBoxObject%0A%09%09%09%09%26%26%20%22open%22%20in%20node%0A%09%09%09%09%26%26%20node.open%0A%09%09%09%09%26%26%20node.getElementsByTagName%28%22menupopup%22%29.length%0A%09%09%09%09%26%26%20this.undoCloseTabsList.drawUndoList%28%29%0A%09%09%09%29%20%7B%0A%09%09%09%09node.open%20%3D%20false%3B%0A%09%09%09%09this.open%20%3D%20true%3B%0A%09%09%09%09return%20true%3B%0A%09%09%09%7D%0A%09%09%09return%20false%3B%0A%09%09%7D%2C%0A%09%09this%0A%09%29%3B%0A%09if%28%0A%09%09this.undoCloseTabsList.options.openMenuOnMouseover%0A%09%09%26%26%20this.undoCloseTabsList.drawUndoList%28%29%0A%09%29%0A%09%09this.undoCloseTabsList.openMenu%28%29%3B%0A%7D%3B%0A%0Athis.undoCloseTabsList%20%3D%20%7B%0A%09button%3A%20this%2C%0A%09options%3A%20options%2C%0A%09mpId%3A%20this.id%20+%20%22-context%22%2C%0A%09cmId%3A%20this.id%20+%20%22-contextSub%22%2C%0A%09tcmId%3A%20this.id%20+%20%22-tabContextMenu%22%2C%0A%09tipId%3A%20this.id%20+%20%22-tooltip%22%2C%0A%09errPrefix%3A%20%22%5BCustom%20Buttons%20%3A%3A%20Undo%20Close%20Tabs%20List%5D%3A%20%22%2C%0A%09get%20mp%28%29%20%7B%0A%09%09var%20btn%20%3D%20this.button%3B%0A%09%09var%20mp%20%3D%20btn.getElementsByTagName%28%22menupopup%22%29%3B%0A%09%09mp%20%3D%20mp.length%20%26%26%20mp%5B0%5D%3B%0A%09%09mp%20%26%26%20mp.parentNode.removeChild%28mp%29%3B%0A%09%09mp%20%3D%20this.createElement%28%22menupopup%22%2C%20%7B%0A%09%09%09id%3A%20this.mpId%2C%0A%09%09%09onclick%3A%20%22this.parentNode.undoCloseTabsList.checkForMiddleClick%28event%29%3B%22%2C%0A%09%09%09onpopupshowing%3A%20%22if%28event.target%20%3D%3D%20this%29%20document.popupNode%20%3D%20this.parentNode%3B%22%2C%0A%09%09%09onpopuphidden%3A%20%22if%28event.target%20%3D%3D%20this%29%20document.popupNode%20%3D%20null%3B%22%0A%09%09%7D%29%3B%0A%09%09if%28this.cm%29%0A%09%09%09mp.setAttribute%28%22context%22%2C%20this.cmId%29%3B%0A%09%09var%20tb%20%3D%20btn.parentNode%3B%0A%09%09if%28%0A%09%09%09this.options.useMenu%0A%09%09%09%26%26%20tb.getAttribute%28%22orient%22%29%20%3D%3D%20%22vertical%22%0A%09%09%29%20%7B%0A%09%09%09//%20https%3A//addons.mozilla.org/firefox/addon/vertical-toolbar/%0A%09%09%09var%20isRight%20%3D%20tb.parentNode.getAttribute%28%22placement%22%29%20%3D%3D%20%22right%22%3B%0A%09%09%09mp.setAttribute%28%22position%22%2C%20isRight%20%3F%20%22start_before%22%20%3A%20%22end_before%22%29%3B%0A%09%09%7D%0A%09%09delete%20this.mp%3B%0A%09%09return%20this.mp%20%3D%20btn.appendChild%28mp%29%3B%0A%09%7D%2C%0A%09get%20useCentextMenu%28%29%20%7B%0A%09%09delete%20this.useCentextMenu%3B%0A%09%09return%20this.useCentextMenu%20%3D%20this.options.allowDeleteEntries%0A%09%09%09%26%26%20%28%22forgetClosedTab%22%20in%20this.ss%20%7C%7C%20%22forgetClosedWindow%22%20in%20this.ss%29%3B%0A%09%7D%2C%0A%09get%20cm%28%29%20%7B%0A%09%09delete%20this.cm%3B%0A%09%09if%28%21this.useCentextMenu%29%0A%09%09%09return%20this.cm%20%3D%20null%3B%0A%09%09var%20cm%20%3D%20document.getElementById%28this.cmId%29%3B%0A%09%09cm%20%26%26%20cm.parentNode.removeChild%28cm%29%3B%0A%09%09cm%20%3D%20this.createElement%28%22menupopup%22%2C%20%7B%0A%09%09%09id%3A%20this.cmId%2C%0A%09%09%09onpopupshowing%3A%20%22return%20this.undoCloseTabsList.canDeleteUndoEntry%28this.triggerNode%20%7C%7C%20document.popupNode%29%3B%22%0A%09%09%7D%29%3B%0A%09%09var%20mi%20%3D%20this.createElement%28%22menuitem%22%2C%20%7B%0A%09%09%09oncommand%3A%20%22this.parentNode.undoCloseTabsList.deleteUndoEntry%28this.parentNode.triggerNode%20%7C%7C%20document.popupNode%29%3B%22%2C%0A%09%09%09label%3A%20_localize%28%22deleteUndoEntry%22%29%2C%0A%09%09%09closemenu%3A%20%22single%22%0A%09%09%7D%29%3B%0A%09%09cm.appendChild%28mi%29%3B%0A%09%09cm.undoCloseTabsList%20%3D%20this%3B%0A%09%09return%20this.cm%20%3D%20document.getElementById%28%22mainPopupSet%22%29.appendChild%28cm%29%3B%0A%09%7D%2C%0A%09get%20cbMenu%28%29%20%7B%0A%09%09var%20cbPopup%20%3D%20document.getElementById%28this.button.defaultContextId%29%3B%0A%09%09if%28%21cbPopup%29%20%7B%0A%09%09%09Components.utils.reportError%28this.errPrefix%20+%20%22cb%20menu%20not%20found%22%29%3B%0A%09%09%09return%20this.cbMenu%20%3D%20null%3B%0A%09%09%7D%0A%09%09cbPopup%20%3D%20cbPopup.cloneNode%28true%29%3B%0A%09%09var%20id%20%3D%20%22-%22%20+%20this.button.id.match%28/%5Cd*%24/%29%5B0%5D%20+%20%22-cloned%22%3B%0A%09%09cbPopup.id%20+%3D%20id%3B%0A%09%09Array.prototype.slice.call%28cbPopup.getElementsByAttribute%28%22id%22%2C%20%22*%22%29%29.forEach%28function%28node%29%20%7B%0A%09%09%09node.id%20+%3D%20id%3B%0A%09%09%7D%29%3B%0A%09%09var%20menu%20%3D%20this.createElement%28%22menu%22%2C%20%7B%0A%09%09%09label%3A%20_localize%28%22buttonMenu%22%29%2C%0A%09%09%09accesskey%3A%20_localize%28%22buttonMenuAccesskey%22%29%0A%09%09%7D%29%3B%0A%09%09menu.appendChild%28cbPopup%29%3B%0A%09%09cbPopup.setAttribute%28%0A%09%09%09%22onpopupshowing%22%2C%0A%09%09%09%27%5C%0A%09%09%09var%20btn%20%3D%20document.popupNode%20%3D%20this.parentNode.parentNode.parentNode%5Cn%5C%0A%09%09%09%09.undoCloseTabsList.button%3B%5Cn%5C%0A%09%09%09custombutton.setContextMenuVisibility%28btn%29%3B%27%0A%09%09%29%3B%0A%09%09delete%20this.cbMenu%3B%0A%09%09return%20this.cbMenu%20%3D%20menu%3B%0A%09%7D%2C%0A%09get%20ss%28%29%20%7B%0A%09%09delete%20this.ss%3B%0A%09%09return%20this.ss%20%3D%20%22nsISessionStore%22%20in%20Components.interfaces%0A%09%09%09%3F%20%28%0A%09%09%09%09Components.classes%5B%22@mozilla.org/browser/sessionstore%3B1%22%5D%0A%09%09%09%09%7C%7C%20Components.classes%5B%22@mozilla.org/suite/sessionstore%3B1%22%5D%0A%09%09%09%29.getService%28Components.interfaces.nsISessionStore%29%0A%09%09%09%3A%20SessionStore%3B%20//%20Firefox%2061+%20https%3A//bugzilla.mozilla.org/show_bug.cgi%3Fid%3D1450559%0A%09%7D%2C%0A%09get%20appInfo%28%29%20%7B%0A%09%09delete%20this.appInfo%3B%0A%09%09return%20this.appInfo%20%3D%20Components.classes%5B%22@mozilla.org/xre/app-info%3B1%22%5D%0A%09%09%09.getService%28Components.interfaces.nsIXULAppInfo%29%3B%0A%09%7D%2C%0A%09get%20appVersion%28%29%20%7B%0A%09%09delete%20this.appVersion%3B%0A%09%09return%20this.appVersion%20%3D%20parseFloat%28this.appInfo.version%29%3B%0A%09%7D%2C%0A%09get%20appName%28%29%20%7B%0A%09%09delete%20this.appName%3B%0A%09%09return%20this.appName%20%3D%20this.appInfo.name%3B%0A%09%7D%2C%0A%0A%09init%3A%20function%28%29%20%7B%0A%09%09window.addEventListener%28%22TabClose%22%2C%20%20%20%20%20%20%20this%2C%20false%29%3B%0A%09%09window.addEventListener%28%22SSTabRestoring%22%2C%20this%2C%20false%29%3B%0A%09%09window.addEventListener%28%22unload%22%2C%20%20%20%20%20%20%20%20%20this%2C%20false%29%3B%0A%09%09if%28this.appName%20%3D%3D%20%22SeaMonkey%22%29%20//%20No%20SSTab*%20events%20in%20SeaMonkey%0A%09%09%09window.addEventListener%28%22TabOpen%22%2C%20this%2C%20false%29%3B%0A%09%09setTimeout%28function%28_this%29%20%7B%0A%09%09%09_this.mp.addEventListener%28%22DOMMenuItemActive%22%2C%20%20%20_this%2C%20false%29%3B%0A%09%09%09_this.mp.addEventListener%28%22DOMMenuItemInactive%22%2C%20_this%2C%20false%29%3B%0A%09%09%09_this.initTooltip%28%29%3B%0A%09%09%7D%2C%2050%2C%20this%29%3B%0A%09%09this.addPbExitObserver%28true%29%3B%0A%09%09this.updUIGlobal%28%29%3B%0A%09%09if%28this.options.showInTabContextMenu%29%20setTimeout%28function%28_this%29%20%7B%0A%09%09%09_this.initTabContext%28%29%3B%0A%09%09%7D%2C%20100%2C%20this%29%3B%0A%09%7D%2C%0A%09initTabContext%3A%20function%28%29%20%7B%0A%09%09var%20origMi%20%3D%20this.tabContextUndoClose%3B%0A%09%09if%28%21origMi%29%20%7B%0A%09%09%09LOG%28%22Can%27t%20find%20%5C%22Undo%20Close%20Tab%5C%22%20item%20in%20tab%20context%20menu%22%29%3B%0A%09%09%09return%3B%0A%09%09%7D%0A%09%09var%20menu%20%3D%20document.getElementById%28this.tcmId%29%3B%0A%09%09menu%20%26%26%20menu.parentNode.removeChild%28menu%29%3B%20//%20For%20SeaMonkey%0A%09%09menu%20%3D%20this.createElement%28%22menu%22%2C%20%7B%0A%09%09%09id%3A%20this.tcmId%2C%0A%09%09%09label%3A%20_localize%28%22tabContextMenu%22%29%2C%0A%09%09%09accesskey%3A%20_localize%28%22tabContextMenuAccesskey%22%29%2C%0A%09%09%09tooltip%3A%20this.tipId%2C%0A%09%09%09popupsinherittooltip%3A%20%22true%22%0A%09%09%7D%29%3B%0A%09%09menu.undoCloseTabsList%20%3D%20this%3B%0A%09%09menu.onclick%20%3D%20function%28e%29%20%7B%0A%09%09%09if%28e.target%20%21%3D%20this%29%0A%09%09%09%09return%3B%0A%09%09%09if%28e.button%20%3D%3D%201%20%7C%7C%20e.button%20%3D%3D%200%20%26%26%20%28e.ctrlKey%20%7C%7C%20e.shiftKey%20%7C%7C%20e.altKey%20%7C%7C%20e.metaKey%29%29%20%7B%0A%09%09%09%09if%28this.undoCloseTabsList.closedTabCount%29%20%7B%0A%09%09%09%09%09this.undoCloseTabsList.undoCloseTab%28%29%3B%0A%09%09%09%09%09closeMenus%28this%29%3B%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%3B%0A%09%09var%20origMp%20%3D%20this.mp%3B%0A%09%09var%20mp%20%3D%20origMp.cloneNode%28true%29%3B%0A%09%09mp.id%20%3D%20this.button.id%20+%20%22-tabContext%22%3B%0A%09%09var%20_this%20%3D%20this%3B%0A%09%09function%20drawUndoList%28%29%20%7B%0A%09%09%09var%20ok%20%3D%20false%3B%0A%09%09%09var%20opts%20%3D%20_this.options%3B%0A%09%09%09var%20origTemplate%20%3D%20opts.menuTemplate%3B%0A%09%09%09opts.menuTemplate%20%3D%20opts.menuTemplateTabContext%20%7C%7C%20origTemplate%3B%0A%09%09%09_this.mp%20%3D%20mp%3B%0A%09%09%09try%20%7B%0A%09%09%09%09ok%20%3D%20_this.drawUndoList%28%29%3B%0A%09%09%09%7D%0A%09%09%09catch%28e%29%20%7B%0A%09%09%09%09Components.utils.reportError%28e%29%3B%0A%09%09%09%7D%0A%09%09%09opts.menuTemplate%20%3D%20origTemplate%3B%0A%09%09%09_this.mp%20%3D%20origMp%3B%0A%09%09%09return%20ok%3B%0A%09%09%7D%0A%09%09function%20updMenu%28%29%20%7B%0A%09%09%09if%28drawUndoList%28%29%29%0A%09%09%09%09menu.removeAttribute%28%22disabled%22%29%3B%0A%09%09%09else%0A%09%09%09%09menu.setAttribute%28%22disabled%22%2C%20%22true%22%29%3B%0A%09%09%7D%0A%09%09mp._updatePopup%20%3D%20function%28e%29%20%7B%0A%09%09%09if%28e.target%20%21%3D%20this%29%0A%09%09%09%09return%3B%0A%09%09%09document.popupNode%20%3D%20_this.button%3B%0A%09%09%09drawUndoList%28%29%3B%0A%09%09%7D%3B%0A%09%09mp.setAttribute%28%22onpopupshowing%22%2C%20%22this._updatePopup%28event%29%3B%22%29%3B%0A%09%09mp.onclick%20%3D%20function%28e%29%20%7B%0A%09%09%09_this.checkForMiddleClick%28e%2C%20updMenu%29%3B%0A%09%09%7D%3B%0A%09%09menu.appendChild%28mp%29%3B%0A%09%09addEventListener%28%22popupshown%22%2C%20function%28e%29%20%7B%0A%09%09%09if%28e.target%20%3D%3D%20e.currentTarget%29%0A%09%09%09%09setTimeout%28updMenu%2C%200%29%3B%20//%20Pseudo%20async%0A%09%09%7D%2C%20false%2C%20origMi.parentNode%29%3B%0A%09%09addEventListener%28%22DOMMenuItemActive%22%2C%20%20%20this%2C%20false%2C%20mp%29%3B%0A%09%09addEventListener%28%22DOMMenuItemInactive%22%2C%20this%2C%20false%2C%20mp%29%3B%0A%09%09origMi.parentNode.insertBefore%28menu%2C%20origMi.nextSibling%29%3B%0A%09%09origMi.setAttribute%28%22hidden%22%2C%20%22true%22%29%3B%0A%09%7D%2C%0A%09initTooltip%3A%20function%28%29%20%7B%0A%09%09var%20tip%20%3D%20document.getElementById%28this.tipId%29%3B%0A%09%09tip%20%26%26%20tip.parentNode.removeChild%28tip%29%3B%0A%09%09tip%20%3D%20this.tip%20%3D%20this.createElement%28%22tooltip%22%2C%20%7B%0A%09%09%09id%3A%20this.tipId%2C%0A%09%09%09orient%3A%20%22vertical%22%2C%0A%09%09%09onpopupshowing%3A%20%22return%20this.undoCloseTabsList.updTooltip%28this%2C%20document.tooltipNode%29%3B%22%2C%0A%09%09%09onpopuphiding%3A%20%22this.cancelUpdateTimer%28%29%3B%22%0A%09%09%7D%29%3B%0A%09%09tip.undoCloseTabsList%20%3D%20this%3B%0A%09%09tip._updateTimer%20%3D%200%3B%0A%09%09tip.initUpdateTimer%20%3D%20function%28fn%2C%20context%29%20%7B%0A%09%09%09if%28this._updateTimer%29%0A%09%09%09%09clearInterval%28this._updateTimer%29%3B%0A%09%09%09this._updateTimer%20%3D%20setInterval%28function%28%29%20%7B%0A%09%09%09%09fn.call%28context%29%3B%0A%09%09%09%7D%2C%201000%29%3B%0A%09%09%7D%3B%0A%09%09tip.cancelUpdateTimer%20%3D%20function%28%29%20%7B%0A%09%09%09if%28this._updateTimer%29%20%7B%0A%09%09%09%09clearInterval%28this._updateTimer%29%3B%0A%09%09%09%09this._updateTimer%20%3D%200%3B%0A%09%09%09%7D%0A%09%09%7D%3B%0A%09%09var%20btn%20%3D%20this.button%3B%0A%09%09btn.removeAttribute%28%22tooltiptext%22%29%3B%0A%09%09btn.setAttribute%28%22tooltip%22%2C%20this.tipId%29%3B%0A%09%09btn.setAttribute%28%22popupsinherittooltip%22%2C%20%22true%22%29%3B%0A%09%09document.getElementById%28%22mainPopupSet%22%29.appendChild%28tip%29%3B%0A%09%09if%28this.appVersion%20%3E%3D%2061%20%26%26%20%22getAnonymousElementByAttribute%22%20in%20document%29%20%7B%0A%09%09%09var%20label%20%3D%20document.getAnonymousElementByAttribute%28tip%2C%20%22class%22%2C%20%22tooltip-label%22%29%3B%0A%09%09%09label%20%26%26%20label.remove%28%29%3B%0A%09%09%7D%0A%09%7D%2C%0A%09_hasPbExitObserver%3A%20false%2C%0A%09addPbExitObserver%3A%20function%28add%29%20%7B%0A%09%09if%28add%20%3D%3D%20this._hasPbExitObserver%20%7C%7C%20%21%28%22Services%22%20in%20window%29%29%0A%09%09%09return%3B%0A%09%09this._hasPbExitObserver%20%3D%20add%3B%0A%09%09if%28add%29%0A%09%09%09Services.obs.addObserver%28this%2C%20%22last-pb-context-exited%22%2C%20false%29%3B%0A%09%09else%0A%09%09%09Services.obs.removeObserver%28this%2C%20%22last-pb-context-exited%22%29%3B%0A%09%7D%2C%0A%09destroy%3A%20function%28%29%20%7B%0A%09%09window.removeEventListener%28%22TabClose%22%2C%20%20%20%20%20%20%20this%2C%20false%29%3B%0A%09%09window.removeEventListener%28%22SSTabRestoring%22%2C%20this%2C%20false%29%3B%0A%09%09window.removeEventListener%28%22unload%22%2C%20%20%20%20%20%20%20%20%20this%2C%20false%29%3B%0A%09%09if%28this.appName%20%3D%3D%20%22SeaMonkey%22%29%0A%09%09%09window.removeEventListener%28%22TabOpen%22%2C%20this%2C%20false%29%3B%0A%09%09this.mp.removeEventListener%28%22DOMMenuItemActive%22%2C%20%20%20this%2C%20false%29%3B%0A%09%09this.mp.removeEventListener%28%22DOMMenuItemInactive%22%2C%20this%2C%20false%29%3B%0A%09%09this.addPbExitObserver%28false%29%3B%0A%09%09var%20menu%20%3D%20document.getElementById%28this.tcmId%29%3B%0A%09%09if%28menu%29%20%7B%0A%09%09%09menu.parentNode.removeChild%28menu%29%3B%0A%09%09%09this.tabContextUndoClose.removeAttribute%28%22hidden%22%29%3B%0A%09%09%7D%0A%09%09var%20tip%20%3D%20this.tip%3B%0A%09%09tip%20%26%26%20tip.parentNode%20%26%26%20tip.parentNode.removeChild%28tip%29%3B%0A%09%7D%2C%0A%09handleEvent%3A%20function%28e%29%20%7B%0A%09%09switch%28e.type%29%20%7B%0A%09%09%09case%20%22TabClose%22%3A%0A%09%09%09case%20%22SSTabRestoring%22%3A%0A%09%09%09case%20%22TabOpen%22%3A%0A%09%09%09%09setTimeout%28function%28_this%29%20%7B%0A%09%09%09%09%09_this.updUI%28%29%3B%0A%09%09%09%09%7D%2C%200%2C%20this%29%3B%0A%09%09%09break%3B%0A%09%09%09case%20%22DOMMenuItemActive%22%3A%0A%09%09%09case%20%22DOMMenuItemInactive%22%3A%0A%09%09%09%09if%28%21%28%22XULBrowserWindow%22%20in%20window%29%29%0A%09%09%09%09%09break%3B%0A%09%09%09%09XULBrowserWindow.setOverLink%28%0A%09%09%09%09%09e.type%20%3D%3D%20%22DOMMenuItemActive%22%0A%09%09%09%09%09%09%3F%20%28e.target.getAttribute%28%22cb_urlDecoded%22%29%20%7C%7C%20%22%22%29%0A%09%09%09%09%09%09%09.replace%28/%20%5Cn/g%2C%20%22%2C%20%22%29%0A%09%09%09%09%09%09%3A%20%22%22%2C%0A%09%09%09%09%09null%0A%09%09%09%09%29%3B%0A%09%09%09break%3B%0A%09%09%09case%20%22unload%22%3A%0A%09%09%09%09this.updUIGlobal%28%29%3B%0A%09%09%09%09this.destroy%28%29%3B%0A%09%09%7D%0A%09%7D%2C%0A%09observe%3A%20function%28subject%2C%20topic%2C%20data%29%20%7B%0A%09%09if%28topic%20%3D%3D%20%22last-pb-context-exited%22%29%20%7B%0A%09%09%09setTimeout%28function%28_this%29%20%7B%0A%09%09%09%09_this.updUI%28%29%3B%0A%09%09%09%7D%2C%2025%2C%20this%29%3B%0A%09%09%7D%0A%09%7D%2C%0A%0A%09createElement%3A%20function%28name%2C%20attrs%29%20%7B%0A%09%09var%20node%20%3D%20document.createElementNS%28xulns%2C%20name%29%3B%0A%09%09if%28attrs%29%20for%28var%20attrName%20in%20attrs%29%20if%28attrs.hasOwnProperty%28attrName%29%29%0A%09%09%09node.setAttribute%28attrName%2C%20attrs%5BattrName%5D%29%3B%0A%09%09return%20node%3B%0A%09%7D%2C%0A%09get%20tabContextUndoClose%28%29%20%7B%0A%09%09return%20document.getElementById%28%22context_undoCloseTab%22%29%0A%09%09%09%7C%7C%20document.getElementById%28%22tabContextUndoCloseTab%22%29%20//%20Firefox%202.0%0A%09%09%09%7C%7C%20document.getAnonymousElementByAttribute%28gBrowser%2C%20%22tbattr%22%2C%20%22tabbrowser-undoclosetab%22%29%3B%20//%20SeaMonkey%0A%09%7D%2C%0A%09get%20closedWindowCount%28%29%20%7B%0A%09%09if%28%21%28%22getClosedWindowCount%22%20in%20this.ss%29%29%20%7B%0A%09%09%09delete%20this.closedWindowCount%3B%0A%09%09%09return%20this.closedWindowCount%20%3D%200%3B%0A%09%09%7D%0A%09%09this.__defineGetter__%28%22closedWindowCount%22%2C%20function%28%29%20%7B%0A%09%09%09return%20this.ss.getClosedWindowCount%28%29%3B%0A%09%09%7D%29%3B%0A%09%09return%20this.closedWindowCount%3B%0A%09%7D%2C%0A%09get%20closedTabCount%28%29%20%7B%0A%09%09return%20this.ss.getClosedTabCount%28window%29%3B%0A%09%7D%2C%0A%09undoCloseTab%3A%20function%28i%29%20%7B%0A%09%09if%28%22undoCloseTab%22%20in%20window%29%20//%20Firefox%202.0+%0A%09%09%09undoCloseTab%28i%29%3B%0A%09%09else%20//%20SeaMonkey%0A%09%09%09gBrowser.undoCloseTab%28i%29%3B%0A%09%7D%2C%0A%09clearUndoTabsList%3A%20function%28%29%20%7B%0A%09%09var%20closedTabCount%20%3D%20this.closedTabCount%3B%0A%09%09if%28%21closedTabCount%29%0A%09%09%09return%3B%0A%09%09if%28%22forgetClosedTab%22%20in%20this.ss%29%20//%20Gecko%201.9.2+%0A%09%09%09while%28closedTabCount--%29%0A%09%09%09%09this.ss.forgetClosedTab%28window%2C%200%29%3B%0A%09%09else%20%7B%0A%09%09%09//%20Doesn%27t%20work%20in%20SeaMonkey%0A%09%09%09const%20pName%20%3D%20%22browser.sessionstore.max_tabs_undo%22%3B%0A%09%09%09let%20val%20%3D%20cbu.getPrefs%28pName%29%3B%0A%09%09%09cbu.setPrefs%28pName%2C%200%29%3B%0A%09%09%09cbu.setPrefs%28pName%2C%20val%29%3B%0A%09%09%7D%0A%09%09this.updUIGlobal%28%29%3B%0A%09%7D%2C%0A%09clearUndoWindowsList%3A%20function%28%29%20%7B%0A%09%09var%20closedWindowCount%20%3D%20this.closedWindowCount%3B%0A%09%09if%28%21closedWindowCount%29%0A%09%09%09return%3B%0A%09%09if%28%22forgetClosedWindow%22%20in%20this.ss%29%20//%20Gecko%201.9.2+%0A%09%09%09while%28closedWindowCount--%29%0A%09%09%09%09this.ss.forgetClosedWindow%280%29%3B%0A%09%09else%0A%09%09%09this.ss.setWindowState%28window%2C%20%27%7B%22windows%22%3A%5B%7B%7D%5D%2C%22_closedWindows%22%3A%5B%5D%7D%27%2C%20false%29%3B%0A%09%09this.updUIGlobal%28%29%3B%0A%09%7D%2C%0A%09clearAllLists%3A%20function%28%29%20%7B%0A%09%09this.clearUndoTabsList%28%29%3B%0A%09%09this.clearUndoWindowsList%28%29%3B%0A%09%7D%2C%0A%09canDeleteUndoEntry%3A%20function%28mi%29%20%7B%0A%09%09switch%28mi.getAttribute%28%22cb_type%22%29%29%20%7B%0A%09%09%09case%20%22tab%22%3A%20%20%20%20return%20%22forgetClosedTab%22%20%20%20%20in%20this.ss%3B%0A%09%09%09case%20%22window%22%3A%20return%20%22forgetClosedWindow%22%20in%20this.ss%3B%0A%09%09%7D%0A%09%09return%20false%3B%0A%09%7D%2C%0A%09deleteUndoEntry%3A%20function%28mi%29%20%7B%0A%09%09var%20i%20%3D%20+mi.getAttribute%28%22cb_index%22%29%3B%0A%09%09if%28mi.getAttribute%28%22cb_type%22%29%20%3D%3D%20%22window%22%29%20%7B%0A%09%09%09this.ss.forgetClosedWindow%28i%29%3B%0A%09%09%09this.updUIGlobal%28%29%3B%0A%09%09%7D%0A%09%09else%20%7B%0A%09%09%09this.ss.forgetClosedTab%28window%2C%20i%29%3B%0A%09%09%09this.updUI%28%29%3B%0A%09%09%7D%0A%09%09this.drawUndoList%28%29%3B%0A%09%7D%2C%0A%09showMenu%3A%20function%28e%2C%20isContext%2C%20mp%29%20%7B%0A%09%09var%20btn%20%3D%20this.button%3B%0A%09%09document.popupNode%20%3D%20btn.ownerDocument.popupNode%20%3D%20btn%3B%0A%09%09if%28%21mp%29%0A%09%09%09mp%20%3D%20this.mp%3B%0A%09%09if%28%22openPopupAtScreen%22%20in%20mp%29%0A%09%09%09mp.openPopupAtScreen%28e.screenX%2C%20e.screenY%2C%20isContext%29%3B%0A%09%09else%0A%09%09%09mp.showPopup%28btn%2C%20e.screenX%2C%20e.screenY%2C%20isContext%20%3F%20%22context%22%20%3A%20%22popup%22%2C%20null%2C%20null%29%3B%0A%09%7D%2C%0A%09openMenu%3A%20function%28%29%20%7B%0A%09%09var%20mp%20%3D%20this.mp%3B%0A%09%09if%28%22openPopup%22%20in%20mp%29%0A%09%09%09mp.openPopup%28this.button%2C%20%22after_start%22%29%3B%0A%09%09else%0A%09%09%09mp.showPopup%28this.button%2C%20-1%2C%20-1%2C%20%22popup%22%2C%20%22bottomleft%22%2C%20%22topleft%22%29%3B%0A%09%7D%2C%0A%09drawUndoList%3A%20function%28%29%20%7B%0A%09%09var%20mp%20%3D%20this.mp%3B%0A%0A%09%09var%20wc%20%3D%20this.closedWindowCount%3B%0A%09%09var%20tc%20%3D%20this.closedTabCount%3B%0A%09%09var%20ss%20%3D%20this.ss%3B%0A%09%09var%20canRestoreLastSession%20%3D%20%22restoreLastSession%22%20in%20ss%20%26%26%20ss.canRestoreLastSession%0A%09%09if%28%21wc%20%26%26%20%21tc%20%26%26%20%21canRestoreLastSession%29%20%7B%0A%09%09%09mp.textContent%20%3D%20%22%22%3B%0A%09%09%09mp.hidePopup%28%29%3B%0A%09%09%09return%20false%3B%0A%09%09%7D%0A%0A%09%09this._undoWindowItems%20%3D%20wc%20%26%26%20JSON.parse%28ss.getClosedWindowData%28%29%29%3B%0A%09%09this._undoTabItems%20%20%20%20%3D%20tc%20%26%26%20JSON.parse%28ss.getClosedTabData%28window%29%29%3B%0A%09%09var%20df%20%3D%20document.createDocumentFragment%28%29%3B%0A%0A%09%09this.options.menuTemplate.forEach%28function%28sid%2C%20indx%2C%20arr%29%20%7B%0A%09%09%09switch%28sid%29%20%7B%0A%09%09%09%09case%20%22closedWindows%22%3A%0A%09%09%09%09%09wc%20%26%26%20this.addUndoWindowsList%28df%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22restoreClosedWindows%22%3A%0A%09%09%09%09%09wc%20%3E%20this.options.hideRestoreAllForSingleEntry%0A%09%09%09%09%09%26%26%20df.appendChild%28this.createElement%28%22menuitem%22%2C%20%7B%0A%09%09%09%09%09%09label%3A%20_localize%28%22restoreAllWindows%22%29%2C%0A%09%09%09%09%09%09accesskey%3A%20_localize%28%22restoreAllWindowsAccesskey%22%29%2C%0A%09%09%09%09%09%09oncommand%3A%20%22for%28var%20i%20%3D%200%3B%20i%20%3C%20%22%20+%20this._undoWindowItems.length%20+%20%22%3B%20++i%29%20undoCloseWindow%28%29%3B%22%0A%09%09%09%09%09%7D%29%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22clearClosedWindows%22%3A%0A%09%09%09%09%09wc%20%26%26%20df.appendChild%28this.createElement%28%22menuitem%22%2C%20%7B%0A%09%09%09%09%09%09label%3A%20_localize%28%22clearWindowsHistory%22%29%2C%0A%09%09%09%09%09%09accesskey%3A%20_localize%28%22clearWindowsHistoryAccesskey%22%29%2C%0A%09%09%09%09%09%09oncommand%3A%20%22this.parentNode.parentNode.undoCloseTabsList.clearUndoWindowsList%28%29%3B%22%0A%09%09%09%09%09%7D%29%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22closedTabs%22%3A%0A%09%09%09%09%09tc%20%26%26%20this.addUndoTabsList%28df%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22restoreClosedTabs%22%3A%0A%09%09%09%09%09tc%20%3E%20this.options.hideRestoreAllForSingleEntry%0A%09%09%09%09%09%26%26%20df.appendChild%28this.createElement%28%22menuitem%22%2C%20%7B%0A%09%09%09%09%09%09label%3A%20_localize%28%22restoreAllTabs%22%29%2C%0A%09%09%09%09%09%09accesskey%3A%20_localize%28%22restoreAllTabsAccesskey%22%29%2C%0A%09%09%09%09%09%09oncommand%3A%20%22for%28var%20i%20%3D%200%3B%20i%20%3C%20%22%20+%20this._undoTabItems.length%20+%20%22%3B%20++i%29%20this.parentNode.parentNode.undoCloseTabsList.undoCloseTab%28%29%3B%22%0A%09%09%09%09%09%7D%29%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22clearClosedTabs%22%3A%0A%09%09%09%09%09tc%20%26%26%20df.appendChild%28this.createElement%28%22menuitem%22%2C%20%7B%0A%09%09%09%09%09%09label%3A%20_localize%28%22clearTabsHistory%22%29%2C%0A%09%09%09%09%09%09accesskey%3A%20_localize%28%22clearTabsHistoryAccesskey%22%29%2C%0A%09%09%09%09%09%09oncommand%3A%20%22this.parentNode.parentNode.undoCloseTabsList.clearUndoTabsList%28%29%3B%22%0A%09%09%09%09%09%7D%29%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22clearAll%22%3A%0A%09%09%09%09%09%28%0A%09%09%09%09%09%09wc%20%26%26%20tc%0A%09%09%09%09%09%09%7C%7C%20wc%20%26%26%20arr.indexOf%28%22clearClosedWindows%22%29%20%3D%3D%20-1%0A%09%09%09%09%09%09%7C%7C%20tc%20%26%26%20arr.indexOf%28%22clearClosedTabs%22%29%20%3D%3D%20-1%0A%09%09%09%09%09%29%0A%09%09%09%09%09%26%26%20df.appendChild%28this.createElement%28%22menuitem%22%2C%20%7B%0A%09%09%09%09%09%09label%3A%20_localize%28%22clearAllHistory%22%29%2C%0A%09%09%09%09%09%09accesskey%3A%20_localize%28%22clearAllHistoryAccesskey%22%29%2C%0A%09%09%09%09%09%09oncommand%3A%20%22this.parentNode.parentNode.undoCloseTabsList.clearAllLists%28%29%3B%22%0A%09%09%09%09%09%7D%29%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22restoreLastSession%22%3A%20//%20Gecko%202.0+%0A%09%09%09%09%09canRestoreLastSession%20%26%26%20df.appendChild%28this.createElement%28%22menuitem%22%2C%20%7B%0A%09%09%09%09%09%09label%3A%20_localize%28%22restoreLastSession%22%29%2C%0A%09%09%09%09%09%09accesskey%3A%20_localize%28%22restoreLastSessionAccesskey%22%29%2C%0A%09%09%09%09%09%09oncommand%3A%20%22this.parentNode.parentNode.undoCloseTabsList.ss.restoreLastSession%28%29%3B%22%0A%09%09%09%09%09%7D%29%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22buttonMenu%22%3A%0A%09%09%09%09%09let%20cbMenu%20%3D%20this.cbMenu%3B%0A%09%09%09%09%09if%28cbMenu%29%0A%09%09%09%09%09%09df.appendChild%28cbMenu%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22separator%22%3A%0A%09%09%09%09%09if%28df.hasChildNodes%28%29%20%26%26%20df.lastChild.localName%20%21%3D%20%22menuseparator%22%29%0A%09%09%09%09%09%09df.appendChild%28document.createElementNS%28xulns%2C%20%22menuseparator%22%29%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09default%3A%0A%09%09%09%09%09Components.utils.reportError%28this.errPrefix%20+%20%27Invalid%20template%20entry%3A%20%22%27%20+%20sid%20+%20%27%22%27%29%3B%0A%09%09%09%7D%0A%09%09%7D%2C%20this%29%3B%0A%0A%09%09while%28df.hasChildNodes%28%29%20%26%26%20df.lastChild.localName%20%3D%3D%20%22menuseparator%22%29%0A%09%09%09df.removeChild%28df.lastChild%29%3B%0A%0A%09%09this._undoWindowItems%20%3D%20this._undoTabItems%20%3D%20null%3B%0A%0A%09%09mp.textContent%20%3D%20%22%22%3B%0A%09%09if%28%21df.hasChildNodes%28%29%29%20%7B%0A%09%09%09mp.hidePopup%28%29%3B%0A%09%09%09return%20false%3B%0A%09%09%7D%0A%09%09mp.appendChild%28df%29%3B%0A%09%09return%20true%3B%0A%09%7D%2C%0A%09addUndoWindowsList%3A%20function%28undoPopup%29%20%7B%0A%09%09//%20Based%20on%20code%20from%20chrome%3A//browser/content/browser.js%0A%09%09//%20Mozilla/5.0%20%28Windows%3B%20U%3B%20Windows%20NT%205.1%3B%20en-US%3B%20rv%3A1.9.3a1pre%29%20Gecko/20090824%20Minefield/3.7a1pre%0A%0A%09%09var%20keys%20%3D%20this.options.accesskeys.closedWindows%3B%0A%09%09this._undoWindowItems.forEach%28function%28undoItem%2C%20i%29%20%7B%0A%09%09%09var%20tabs%20%3D%20undoItem.tabs%3B%0A%09%09%09var%20%5Bkey%2C%20keyPrefix%5D%20%3D%20this.getKey%28keys%2C%20i%29%3B%0A%09%09%09var%20title%20%3D%20undoItem.title%3B%0A%09%09%09var%20selectedTab%20%3D%20tabs%5BundoItem.selected%20-%201%5D%3B%0A%09%09%09var%20urls%20%3D%20%5B%5D%3B%0A%09%09%09tabs.forEach%28function%28tab%29%20%7B%0A%09%09%09%09if%28%21tab.entries%20%7C%7C%20%21tab.entries.length%29%20//%20Can%20be%20%5B%5D%20for%20about%3Ablank%0A%09%09%09%09%09return%3B%0A%09%09%09%09var%20url%20%3D%20this.convertURI%28tab.entries%5Btab.index%20-%201%5D.url%2C%20120%29%3B%0A%09%09%09%09var%20selectedPrefix%20%3D%20tab%20%3D%3D%20selectedTab%20%26%26%20tabs.length%20%3E%201%0A%09%09%09%09%09%3F%20this.options.windowSelectedTabPrefix%0A%09%09%09%09%09%3A%20%22%22%3B%0A%09%09%09%09urls.push%28selectedPrefix%20+%20url%29%3B%0A%09%09%09%7D%2C%20this%29%3B%0A%09%09%09var%20url%20%3D%20urls.join%28%22%20%5Cn%22%29%3B%0A%09%09%09var%20mi%20%3D%20this.createElement%28%22menuitem%22%2C%20%7B%0A%09%09%09%09label%3A%20keyPrefix%20+%20this.options.windowItemTemplate%0A%09%09%09%09%09.replace%28%22%25title%22%2C%20title%29%0A%09%09%09%09%09.replace%28%22%25count%22%2C%20tabs.length%29%2C%0A%09%09%09%09accesskey%3A%20key%2C%0A%09%09%09%09%22class%22%3A%20%22menuitem-iconic%20bookmark-item%20menuitem-with-favicon%22%2C%0A%09%09%09%09oncommand%3A%20%22undoCloseWindow%28%22%20+%20i%20+%20%22%29%3B%22%2C%0A%09%09%09%09cb_url%3A%20url%2C%0A%09%09%09%09cb_urlDecoded%3A%20this.convertURI%28url%29%2C%0A%09%09%09%09cb_closedAt%3A%20undoItem.closedAt%20%7C%7C%200%2C%0A%09%09%09%09cb_index%3A%20i%2C%0A%09%09%09%09cb_type%3A%20%22window%22%0A%09%09%09%7D%29%3B%0A%09%09%09if%28this.cm%29%0A%09%09%09%09mi.setAttribute%28%22context%22%2C%20this.cmId%29%3B%0A%09%09%09var%20icon%20%3D%20selectedTab.image%20%7C%7C%20selectedTab.attributes%20%26%26%20selectedTab.attributes.image%3B%0A%09%09%09if%28icon%29%0A%09%09%09%09mi.setAttribute%28%22image%22%2C%20this.cachedIcon%28icon%29%29%3B%0A%09%09%09if%28i%20%3D%3D%200%29%0A%09%09%09%09mi.setAttribute%28%22key%22%2C%20%22key_undoCloseWindow%22%29%3B%0A%09%09%09undoPopup.appendChild%28mi%29%3B%0A%09%09%7D%2C%20this%29%3B%0A%09%7D%2C%0A%09addUndoTabsList%3A%20function%28undoPopup%29%20%7B%0A%09%09//%20Based%20on%20code%20from%20chrome%3A//browser/content/browser.js%0A%09%09//%20Mozilla/5.0%20%28Windows%3B%20U%3B%20Windows%20NT%205.1%3B%20en-US%3B%20rv%3A1.9.3a1pre%29%20Gecko/20090824%20Minefield/3.7a1pre%0A%0A%09%09var%20keys%20%3D%20this.options.accesskeys.closedTabs%3B%0A%09%09this._undoTabItems.forEach%28function%28undoItem%2C%20i%29%20%7B%0A%09%09%09var%20state%20%3D%20undoItem.state%3B%0A%09%09%09var%20%5Bkey%2C%20keyPrefix%5D%20%3D%20this.getKey%28keys%2C%20i%29%3B%0A%09%09%09var%20title%20%3D%20undoItem.title%3B%0A%09%09%09var%20url%20%3D%20state%20%26%26%20state.entries%20%26%26%20state.entries%5Bstate.index%20-%201%5D.url%20%7C%7C%20%22%22%3B%0A%09%09%09var%20mi%20%3D%20this.createElement%28%22menuitem%22%2C%20%7B%0A%09%09%09%09label%3A%20keyPrefix%20+%20title%2C%0A%09%09%09%09accesskey%3A%20key%2C%0A%09%09%09%09class%3A%20%22menuitem-iconic%20bookmark-item%20menuitem-with-favicon%22%2C%0A%09%09%09%09oncommand%3A%20%22this.parentNode.parentNode.undoCloseTabsList.undoCloseTab%28%22%20+%20i%20+%20%22%29%3B%22%2C%0A%09%09%09%09cb_url%3A%20url%2C%0A%09%09%09%09cb_urlDecoded%3A%20this.convertURI%28url%29%2C%0A%09%09%09%09cb_closedAt%3A%20undoItem.closedAt%20%7C%7C%200%2C%0A%09%09%09%09cb_index%3A%20i%2C%0A%09%09%09%09cb_type%3A%20%22tab%22%0A%09%09%09%7D%29%3B%0A%09%09%09if%28%0A%09%09%09%09state%0A%09%09%09%09%26%26%20%22attributes%22%20in%20state%0A%09%09%09%09%26%26%20%22privateTab-isPrivate%22%20in%20state.attributes%0A%09%09%09%29%20//%20https%3A//addons.mozilla.org/addon/private-tab/%0A%09%09%09%09mi.setAttribute%28%22privateTab-isPrivate%22%2C%20%22true%22%29%3B%0A%09%09%09if%28this.cm%29%0A%09%09%09%09mi.setAttribute%28%22context%22%2C%20this.cmId%29%3B%0A%09%09%09var%20image%20%3D%20undoItem.image%20//%20Firefox%0A%09%09%09%09%7C%7C%20state%20%26%26%20state.attributes%20%26%26%20state.attributes.image%20//%20SeaMonkey%0A%09%09%09%09%7C%7C%20state%20%26%26%20state.xultab%0A%09%09%09%09%09%26%26%20/%28%3F%3A%5E%7C%20%29image%3D%28%5CS+%29/.test%28state.xultab%29%0A%09%09%09%09%09%26%26%20decodeURI%28RegExp.%241%29%3B%20//%20Only%20Firefox%202.0%20%3F%0A%09%09%09if%28image%29%0A%09%09%09%09mi.setAttribute%28%22image%22%2C%20this.cachedIcon%28image%29%29%3B%0A%09%09%09if%28i%20%3D%3D%200%29%0A%09%09%09%09mi.setAttribute%28%22key%22%2C%20%22key_undoCloseTab%22%29%3B%0A%09%09%09undoPopup.appendChild%28mi%29%3B%0A%09%09%7D%2C%20this%29%3B%0A%09%7D%2C%0A%09getKey%3A%20function%28keys%2C%20i%29%20%7B%0A%09%09var%20key%20%3D%20keys%20%26%26%20keys.charAt%28i%20%25%20keys.length%29%3B%0A%09%09var%20keyPrefix%20%3D%20keys%20%26%26%20%28key%20+%20this.options.accesskeySeparator%29%3B%0A%09%09return%20%5Bkey%2C%20keyPrefix%5D%3B%0A%09%7D%2C%0A%09checkForMiddleClick%3A%20function%28e%2C%20upd%29%20%7B%0A%09%09var%20mi%20%3D%20e.target%3B%0A%09%09if%28%0A%09%09%09%22doCommand%22%20in%20mi%0A%09%09%09%26%26%20e.button%20%3D%3D%201%0A%09%09%09%26%26%20mi.parentNode%20%3D%3D%20e.currentTarget%0A%09%09%29%20%7B%0A%09%09%09mi.doCommand%28%29%3B%0A%09%09%09if%28upd%29%0A%09%09%09%09upd%28%29%3B%0A%09%09%09else%0A%09%09%09%09this.drawUndoList%28%29%3B%0A%09%09%7D%0A%09%7D%2C%0A%09crop%3A%20function%28s%2C%20crop%29%20%7B%0A%09%09if%28crop%20%3D%3D%20undefined%29%0A%09%09%09crop%20%3D%20500%3B%0A%09%09if%28s.length%20%3C%3D%20crop%29%0A%09%09%09return%20s%3B%0A%09%09var%20start%20%3D%20Math.round%28crop*0.6%29%3B%0A%09%09return%20s.substr%280%2C%20start%29%20+%20%22%u2026%22%20+%20s.substr%28start%20-%20crop%29%3B%0A%09%7D%2C%0A%09convertURI%3A%20function%28uri%2C%20crop%29%20%7B%0A%09%09if%28%21uri%20%7C%7C%20uri.indexOf%28%22%5Cn%22%29%20%21%3D%20-1%29%0A%09%09%09return%20uri%3B%0A%09%09uri%20%3D%20this.losslessDecodeURI%28uri%29%3B%0A%09%09return%20this.crop%28uri%2C%20crop%29%3B%0A%09%7D%2C%0A%09losslessDecodeURI%3A%20function%28uri%29%20%7B%0A%09%09if%28uri%29%20try%20%7B%0A%09%09%09return%20this._losslessDecodeURI%28uri%29%3B%0A%09%09%7D%0A%09%09catch%28e%29%20%7B%0A%09%09%09Components.utils.reportError%28e%29%3B%0A%09%09%7D%0A%09%09return%20uri%3B%0A%09%7D%2C%0A%09get%20_losslessDecodeURI%28%29%20%7B%0A%09%09var%20ldu%3B%0A%09%09if%28%22losslessDecodeURI%22%20in%20window%29%0A%09%09%09ldu%20%3D%20losslessDecodeURI%3B%0A%09%09else%20if%28%22UrlbarInput%22%20in%20window%29%20//%20Firefox%2075+%0A%09%09%09ldu%20%3D%20Components.utils.import%28%22resource%3A///modules/UrlbarInput.jsm%22%2C%20%7B%7D%29.losslessDecodeURI%3B%0A%09%09delete%20this._losslessDecodeURI%3B%0A%09%09return%20this._losslessDecodeURI%20%3D%20ldu%0A%09%09%09%3F%20function%28uri%29%20%7B%0A%09%09%09%09return%20ldu%28makeURI%28uri%29%29%3B%0A%09%09%09%7D%0A%09%09%09%3A%20decodeURI%3B%0A%09%7D%2C%0A%09cachedIcon%3A%20function%28src%29%20%7B%0A%09%09src%20%3D%20src.replace%28/%5B%26%23%5D-moz-resolution%3D%5Cd+%2C%5Cd+%24/%2C%20%22%22%29%3B%20//%20Firefox%2022+%0A%09%09if%28%0A%09%09%09%21/%5Ehttps%3F%3A/.test%28src%29%0A%09%09%09//%20IDN%2C%20see%20https%3A//bugzilla.mozilla.org/show_bug.cgi%3Fid%3D311045%0A%09%09%09%7C%7C%20/%5Ehttps%3F%3A%5C/%5C/%5B%5E.%3A%5C/%5D+%5C.%5B%5Ea-z0-9-%5D+%28%3F%3A%5C/%7C%24%29/.test%28src%29%0A%09%09%09%7C%7C%20this.appName%20%3D%3D%20%22SeaMonkey%22%20%26%26%20this.appVersion%20%3C%3D%202%0A%09%09%09%7C%7C%20this.appName%20%3D%3D%20%22Firefox%22%20%20%20%26%26%20this.appVersion%20%3C%3D%203.5%0A%09%09%29%0A%09%09%09return%20src%3B%0A%09%09return%20%22moz-anno%3Afavicon%3A%22%20+%20src%3B%20//%20https%3A//bugzilla.mozilla.org/show_bug.cgi%3Fid%3D467828%0A%09%7D%2C%0A%09updUI%3A%20function%28%29%20%7B%0A%09%09var%20tabsCount%20%3D%20this.closedTabCount%3B%0A%09%09var%20dis%20%3D%20%21tabsCount%20%26%26%20%21this.closedWindowCount%3B%0A%09%09if%28%0A%09%09%09dis%0A%09%09%09%26%26%20this.options.useMenu%0A%09%09%09%26%26%20this.options.menuTemplate.indexOf%28%22restoreLastSession%22%29%20%21%3D%20-1%0A%09%09%09%26%26%20%22restoreLastSession%22%20in%20this.ss%20%26%26%20this.ss.canRestoreLastSession%0A%09%09%29%0A%09%09%09dis%20%3D%20false%3B%0A%09%09this.button.disabled%20%3D%20dis%3B%0A%09%7D%2C%0A%09updTooltip%3A%20function%28tip%2C%20tn%29%20%7B%0A%09%09var%20template%2C%20header%2C%20title%2C%20url%2C%20closedAt%3B%0A%09%09if%28tn%20%3D%3D%20this.button%29%20%7B%0A%09%09%09template%20%3D%20this.options.buttonTipTemplate%3B%0A%09%09%09header%20%3D%20_localize%28%22restoreTab%22%29%3B%0A%09%09%09let%20undoTabItems%20%3D%20JSON.parse%28this.ss.getClosedTabData%28window%29%29%3B%0A%09%09%09if%28undoTabItems.length%29%20%7B%0A%09%09%09%09let%20lastItem%20%3D%20undoTabItems%5B0%5D%3B%0A%09%09%09%09title%20%3D%20lastItem.title%3B%0A%09%09%09%09url%20%3D%20lastItem.state%20%26%26%20lastItem.state.entries%0A%09%09%09%09%09%26%26%20lastItem.state.entries%5BlastItem.state.index%20-%201%5D.url%3B%0A%09%09%09%09closedAt%20%3D%20lastItem.closedAt%20%7C%7C%200%3B%0A%09%09%09%7D%0A%09%09%7D%0A%09%09else%20if%28tn.hasAttribute%28%22cb_index%22%29%29%20%7B%0A%09%09%09template%20%3D%20this.options.itemTipTemplate%3B%0A%09%09%09title%20%3D%20tn.getAttribute%28%22label%22%29%3B%0A%09%09%09url%20%3D%20tn.getAttribute%28%22cb_url%22%29%3B%0A%09%09%09closedAt%20%3D%20+tn.getAttribute%28%22cb_closedAt%22%29%3B%0A%09%09%7D%0A%09%09else%20%7B%0A%09%09%09return%20false%3B%0A%09%09%7D%0A%0A%09%09var%20tipData%20%3D%20this.getTooltipData%28template%2C%20header%2C%20title%2C%20url%2C%20closedAt%29%3B%0A%09%09tip.textContent%20%3D%20%22%22%3B%0A%09%09tip.appendChild%28tipData%29%3B%0A%09%09if%28closedAt%20%26%26%20template.indexOf%28%22closedAt%22%29%20%21%3D%20-1%29%20%7B%0A%09%09%09tip.initUpdateTimer%28function%28%29%20%7B%0A%09%09%09%09var%20tipData%20%3D%20this.getTooltipData%28template%2C%20header%2C%20title%2C%20url%2C%20closedAt%29%3B%0A%09%09%09%09if%28tipData.textContent%20%21%3D%20tip.textContent%29%20%7B%0A%09%09%09%09%09tip.textContent%20%3D%20%22%22%3B%0A%09%09%09%09%09tip.appendChild%28tipData%29%3B%0A%09%09%09%09%7D%0A%09%09%09%7D%2C%20this%29%3B%0A%09%09%7D%0A%09%09return%20tip.hasChildNodes%28%29%3B%0A%09%7D%2C%0A%09getTooltipData%3A%20function%28template%2C%20header%2C%20title%2C%20url%2C%20closedAt%29%20%7B%0A%09%09var%20df%20%3D%20document.createDocumentFragment%28%29%3B%0A%09%09var%20hasHeader%20%3D%20header%20%26%26%20template.indexOf%28%22header%22%29%20%21%3D%20-1%3B%0A%09%09function%20item%28key%2C%20val%29%20%7B%0A%09%09%09var%20lbl%20%3D%20document.createElementNS%28xulns%2C%20%22label%22%29%3B%0A%09%09%09lbl.className%20%3D%20%22cb-%22%20+%20key%20+%20%22%20tooltip-label%22%3B%0A%09%09%09lbl.textContent%20%3D%20val%3B%0A%09%09%09lbl.setAttribute%28%22maxwidth%22%2C%20%22450%22%29%3B%20//%20Trick%20to%20restore%20right%20border%20for%20long%20lines%0A%09%09%09if%28key%20%3D%3D%20%22closedAt%22%20%7C%7C%20hasHeader%20%26%26%20key%20%21%3D%20%22header%22%29%0A%09%09%09%09lbl.style.color%20%3D%20%22grayText%22%3B%0A%09%09%09return%20df.appendChild%28lbl%29%3B%0A%09%09%7D%0A%09%09template.forEach%28function%28key%29%20%7B%0A%09%09%09switch%28key%29%20%7B%0A%09%09%09%09case%20%22header%22%3A%0A%09%09%09%09%09if%28header%29%0A%09%09%09%09%09%09item%28key%2C%20header%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22title%22%3A%0A%09%09%09%09%09if%28title%20%26%26%20title%20%21%3D%20url%29%0A%09%09%09%09%09%09item%28key%2C%20title%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22url%22%3A%0A%09%09%09%09%09if%28url%29%0A%09%09%09%09%09%09item%28key%2C%20this.convertURI%28url%29%29%3B%0A%09%09%09%09break%3B%0A%09%09%09%09case%20%22closedAt%22%3A%0A%09%09%09%09%09if%28%21closedAt%29%0A%09%09%09%09%09%09break%3B%0A%09%09%09%09%09let%20dt%20%3D%20Math.round%28Math.max%280%2C%20Date.now%28%29%20-%20closedAt%29/1000%29%3B%0A%09%09%09%09%09let%20days%20%3D%20Math.floor%28dt/24/3600%29%3B%0A%09%09%09%09%09dt%20-%3D%20days*24*3600%3B%0A%09%09%09%09%09let%20d%20%3D%20new%20Date%28%28dt%20+%20new%20Date%28dt%29.getTimezoneOffset%28%29*60%29*1000%29%3B%0A%09%09%09%09%09let%20m%20%3D%20d.getMinutes%28%29%3B%0A%09%09%09%09%09let%20ts%20%3D%20d.getHours%28%29%20+%20%22%3A%22%20+%20%28m%20%3E%209%20%3F%20m%20%3A%20%220%22%20+%20m%29%3B%0A%09%09%09%09%09if%28days%29%0A%09%09%09%09%09%09ts%20%3D%20days%20+%20_localize%28%22day%22%29%20+%20%22%20%22%20+%20ts%3B%0A%09%09%09%09%09let%20tsTip%20%3D%20_localize%28%22itemTip%22%29%0A%09%09%09%09%09%09.replace%28%22%25ago%22%2C%20ts%29%0A%09%09%09%09%09%09.replace%28%22%25date%22%2C%20new%20Date%28closedAt%29.toLocaleString%28%29%29%3B%0A%09%09%09%09%09item%28key%2C%20tsTip%29%3B%0A%09%09%09%7D%0A%09%09%7D%2C%20this%29%3B%0A%09%09return%20df%3B%0A%09%7D%2C%0A%09get%20wm%28%29%20%7B%0A%09%09delete%20this.wm%3B%0A%09%09return%20this.wm%20%3D%20Components.classes%5B%22@mozilla.org/appshell/window-mediator%3B1%22%5D%0A%09%09%09.getService%28Components.interfaces.nsIWindowMediator%29%3B%0A%09%7D%2C%0A%09updUIGlobal%3A%20function%28%29%20%7B%0A%09%09var%20isSeaMonkey%20%3D%20this.appName%20%3D%3D%20%22SeaMonkey%22%3B%0A%09%09var%20ws%20%3D%20this.wm.getEnumerator%28isSeaMonkey%20%3F%20null%20%3A%20%22navigator%3Abrowser%22%29%3B%0A%09%09const%20id%20%3D%20this.button.id%3B%0A%09%09while%28ws.hasMoreElements%28%29%29%20%7B%0A%09%09%09let%20win%20%3D%20ws.getNext%28%29%3B%0A%09%09%09if%28isSeaMonkey%20%26%26%20%21this.isBrowserWindow%28win%29%29%0A%09%09%09%09continue%3B%0A%09%09%09let%20btn%20%3D%20win.document.getElementById%28id%29%3B%0A%09%09%09if%28btn%20%26%26%20%22undoCloseTabsList%22%20in%20btn%29%20%7B%0A%09%09%09%09let%20ucl%20%3D%20btn.undoCloseTabsList%3B%0A%09%09%09%09ucl.ensureSessionsInitialized%28ucl.updUI%2C%20ucl%29%3B%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%2C%0A%09isBrowserWindow%3A%20function%28win%29%20%7B%0A%09%09var%20loc%20%3D%20window.location.href%3B%0A%09%09return%20loc%20%3D%3D%20%22chrome%3A//browser/content/browser.xul%22%0A%09%09%09%7C%7C%20loc%20%3D%3D%20%22chrome%3A//navigator/content/navigator.xul%22%3B%0A%09%7D%2C%0A%09ensureSessionsInitialized%3A%20function%28callback%2C%20context%29%20%7B%0A%09%09var%20_this%20%3D%20this%3B%0A%09%09var%20stopTime%20%3D%20Date.now%28%29%20+%203e3%3B%0A%09%09%28function%20ensureInitialized%28%29%20%7B%0A%09%09%09try%20%7B%0A%09%09%09%09_this.ss.getClosedTabCount%28window%29%3B%0A%09%09%09%09callback.call%28context%29%3B%0A%09%09%09%09return%3B%0A%09%09%09%7D%0A%09%09%09catch%28e%29%20%7B%0A%09%09%09%09if%28Date.now%28%29%20%3E%20stopTime%29%20%7B%0A%09%09%09%09%09Components.utils.reportError%28%0A%09%09%09%09%09%09_this.errPrefix%0A%09%09%09%09%09%09+%20%22Can%27t%20initialize%3A%20nsISessionStore.getClosedTabCount%28%29%20failed%22%0A%09%09%09%09%09%29%3B%0A%09%09%09%09%09Components.utils.reportError%28e%29%3B%0A%09%09%09%09%09return%3B%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%09setTimeout%28ensureInitialized%2C%2050%29%3B%0A%09%09%7D%29%28%29%3B%0A%09%7D%0A%7D%3B%0A%0Aif%28%21this.undoCloseTabsList.options.useMenu%20%26%26%20this.undoCloseTabsList.useCentextMenu%29%20%7B%0A%09this.oncontextmenu%20%3D%20function%28e%29%20%7B%0A%09%09if%28%0A%09%09%09e.target%20%21%3D%20this%0A%09%09%09%7C%7C%20e.ctrlKey%20%7C%7C%20e.shiftKey%20%7C%7C%20e.altKey%20%7C%7C%20e.metaKey%0A%09%09%09%7C%7C%20%21this.undoCloseTabsList.mp.hasChildNodes%28%29%0A%09%09%29%0A%09%09%09return%3B%0A%09%09e.preventDefault%28%29%3B%0A%09%09this.undoCloseTabsList.showMenu%28e%29%3B%20//%20Show%20menu%20without%20%22context%22%20flag%0A%09%7D%3B%0A%7D%0Aif%28this.undoCloseTabsList.options.rightClickToUndoCloseTab%29%20%7B%0A%09this.oncontextmenu%20%3D%20function%28e%29%20%7B%0A%09%09if%28e.target%20%3D%3D%20this%20%26%26%20%21e.ctrlKey%20%26%26%20%21e.shiftKey%20%26%26%20%21e.altKey%20%26%26%20%21e.metaKey%29%0A%09%09%09e.preventDefault%28%29%3B%0A%09%7D%3B%0A%7D%0A%0Athis.disabled%20%3D%20true%3B%0AsetTimeout%28function%28_this%29%20%7B%0A%09_this.undoCloseTabsList.init%28%29%3B%0A%7D%2C%200%2C%20this%29%3B%0A%0A//%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%0A//%20Styles%0A//%20Used%20icons%20from%20Undo%20Closed%20Tabs%20Button%20extension%0A%0A//%20Styles%20can%27t%20override%20hardcoded%20icon%0Aif%28%20//%20Remove%20icon%20only%20if%20nsIStyleSheetService%20works%20on-the-fly%20%28Firefox%203.0+%29%0A%09%21Components.ID%28%22%7B41d979dc-ea03-4235-86ff-1e3c090c5630%7D%22%29%0A%09%09.equals%28Components.interfaces.nsIStyleSheetService%29%0A%29%20%7B%0A%09let%20icon%20%3D%20this.icon%0A%09%09%7C%7C%20this.ownerDocument.getAnonymousElementByAttribute%28this%2C%20%22class%22%2C%20%22toolbarbutton-icon%22%29%3B%0A%09if%28icon%29%0A%09%09icon.src%20%3D%20%22%22%3B%0A%09else%0A%09%09this.image%20%3D%20%22%22%3B%0A%7D%0A%0Avar%20cssStr%20%3D%20%27%5C%0A%09@namespace%20url%28%22http%3A//www.mozilla.org/keymaster/gatekeeper/there.is.only.xul%22%29%3B%5Cn%5C%0A%09@-moz-document%20url%28%22%25windowURL%25%22%29%20%7B%5Cn%5C%0A%09%09%25button%25%20%7B%5Cn%5C%0A%09%09%09list-style-image%3A%20url%28%22data%3Aimage/png%3Bbase64%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%22%29%20%21important%3B%5Cn%5C%0A%09%09%09-moz-image-region%3A%20rect%280%2C%2024px%2C%2024px%2C%200%29%20%21important%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%09%25button%25%3Ahover%20%7B%5Cn%5C%0A%09%09%09-moz-image-region%3A%20rect%280%2C%2048px%2C%2024px%2C%2024px%29%20%21important%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%09%25button%25%5Bdisabled%3D%22true%22%5D%20%7B%5Cn%5C%0A%09%09%09-moz-image-region%3A%20rect%280%2C%2072px%2C%2024px%2C%2048px%29%20%21important%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%09toolbar%5Biconsize%3D%22small%22%5D%20%25button%25%20%7B%5Cn%5C%0A%09%09%09-moz-image-region%3A%20rect%2824px%2C%2016px%2C%2040px%2C%200%29%20%21important%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%09toolbar%5Biconsize%3D%22small%22%5D%20%25button%25%3Ahover%20%7B%5Cn%5C%0A%09%09%09-moz-image-region%3A%20rect%2824px%2C%2032px%2C%2040px%2C%2016px%29%20%21important%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%09toolbar%5Biconsize%3D%22small%22%5D%20%25button%25%5Bdisabled%3D%22true%22%5D%20%7B%5Cn%5C%0A%09%09%09-moz-image-region%3A%20rect%2824px%2C%2048px%2C%2040px%2C%2032px%29%20%21important%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%7D%27%0A%09.replace%28/%25windowURL%25/g%2C%20window.location.href%29%0A%09.replace%28/%25button%25/g%2C%20%22%23%22%20+%20this.id%29%3B%0Avar%20cssURI%20%3D%20this.cssURI%20%3D%20Components.classes%5B%22@mozilla.org/network/io-service%3B1%22%5D%0A%09.getService%28Components.interfaces.nsIIOService%29%0A%09.newURI%28%22data%3Atext/css%2C%22%20+%20encodeURIComponent%28cssStr%29%2C%20null%2C%20null%29%3B%0Avar%20sss%20%3D%20this.sss%20%3D%20Components.classes%5B%22@mozilla.org/content/style-sheet-service%3B1%22%5D%0A%09.getService%28Components.interfaces.nsIStyleSheetService%29%3B%0Aif%28%21sss.sheetRegistered%28cssURI%2C%20sss.USER_SHEET%29%29%0A%09sss.loadAndRegisterSheet%28cssURI%2C%20sss.USER_SHEET%29%3B%0A%0A%0Athis.onDestroy%20%3D%20function%28reason%29%20%7B%0A%09this.undoCloseTabsList.destroy%28%29%3B%0A%09if%28reason%20%3D%3D%20%22destructor%22%29%20//%20May%20happens%20before%20%22unload%22%0A%09%09this.undoCloseTabsList.updUIGlobal%28%29%3B%0A%09if%28reason%20%3D%3D%20%22update%22%20%7C%7C%20reason%20%3D%3D%20%22delete%22%29%20%7B%0A%09%09let%20sss%20%3D%20this.sss%3B%0A%09%09let%20cssURI%20%3D%20this.cssURI%3B%0A%09%09if%28sss.sheetRegistered%28cssURI%2C%20sss.USER_SHEET%29%29%0A%09%09%09sss.unregisterSheet%28cssURI%2C%20sss.USER_SHEET%29%3B%0A%09%7D%0A%7D%3B%0Aif%28this.undoCloseTabsList.options.useMenu%29%20%7B%0A%09this.type%20%3D%20%22menu%22%3B%0A%09this.orient%20%3D%20%22horizontal%22%3B%0A%7D%5D%5D%3E%3C/initcode%3E%0A%20%20%3Ccode%3E%3C%21%5BCDATA%5Bif%28%21event.target%29%20//%20Button%27s%20hotkey%20pressed%0A%09this.undoCloseTabsList.drawUndoList%28%29%20%26%26%20this.undoCloseTabsList.openMenu%28%29%3B%5D%5D%3E%3C/code%3E%0A%20%20%3Caccelkey%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/accelkey%3E%0A%20%20%3Chelp%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/help%3E%0A%20%20%3Cattributes/%3E%0A%3C/custombutton%3E
Отсутствует
Letterman
у меня работает. та же версия ФФ и та же кнопка, за исключением небольшого косяка - при наведении курсора на кнопку появляется пустой тултип, но для меня это не критично.
сама кнопка
в секцию "код"
/*CODE*/ if(!event.target) // Button's hotkey pressed this.undoCloseTabsList.drawUndoList() && this.undoCloseTabsList.openMenu();
/*Initialization Code*/ // 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-2020 // version 0.3.3.2 - 2020-03-14 var options = { menuTemplate: [ "closedWindows", "separator", "restoreClosedWindows", "clearClosedWindows", "separator", "closedTabs", "separator", "restoreClosedTabs", "clearClosedTabs", "separator", "clearAll", "separator", "restoreLastSession", "separator", "buttonMenu" ], 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: "" }, accesskeySeparator: " ", // <accesskey><separator><label> openMenuOnMouseover: false, useMenu: false, rightClickToUndoCloseTab: false // Useful with "useMenu: true" }; function _localize(sid) { var strings = { en: { restoreTab: "Restore the most recently closed tab", 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", buttonMenu: "Button menu", buttonMenuAccesskey: "m", tabContextMenu: "Recently Closed Tabs", tabContextMenuAccesskey: "y", itemTip: "%ago ago, %date", day: "d" }, ru: { restoreTab: "Восстановить последнюю закрытую вкладку", restoreAllTabs: "Восстановить все вкладки", restoreAllTabsAccesskey: "л", clearTabsHistory: "Очистить историю закрытых вкладок", clearTabsHistoryAccesskey: "д", restoreAllWindows: "Восстановить все окна", restoreAllWindowsAccesskey: "о", clearWindowsHistory: "Очистить историю закрытых окон", clearWindowsHistoryAccesskey: "н", clearAllHistory: "Очистить всю историю", clearAllHistoryAccesskey: "ч", restoreLastSession: "Восстановить последнюю сессию", restoreLastSessionAccesskey: "с", deleteUndoEntry: "Удалить", buttonMenu: "Меню кнопки", buttonMenuAccesskey: "М", 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)) this.undoCloseTabsList.clearAllLists(); 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 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, 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; }, addUndoWindowsList: 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.closedWindows; this._undoWindowItems.forEach(function(undoItem, i) { var tabs = undoItem.tabs; var [key, keyPrefix] = this.getKey(keys, i); var title = undoItem.title; var selectedTab = tabs[undoItem.selected - 1]; var urls = []; tabs.forEach(function(tab) { if(!tab.entries || !tab.entries.length) // Can be [] for about:blank return; var url = this.convertURI(tab.entries[tab.index - 1].url, 120); var selectedPrefix = tab == selectedTab && tabs.length > 1 ? this.options.windowSelectedTabPrefix : ""; urls.push(selectedPrefix + url); }, this); var url = urls.join(" \n"); var mi = this.createElement("menuitem", { label: keyPrefix + this.options.windowItemTemplate .replace("%title", title) .replace("%count", tabs.length), accesskey: key, "class": "menuitem-iconic bookmark-item menuitem-with-favicon", oncommand: "undoCloseWindow(" + i + ");", cb_url: url, cb_urlDecoded: this.convertURI(url), cb_closedAt: undoItem.closedAt || 0, cb_index: i, cb_type: "window" }); if(this.cm) mi.setAttribute("context", this.cmId); var icon = selectedTab.image || selectedTab.attributes && selectedTab.attributes.image; if(icon) mi.setAttribute("image", this.cachedIcon(icon)); if(i == 0) mi.setAttribute("key", "key_undoCloseWindow"); undoPopup.appendChild(mi); }, this); }, 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.accesskeySeparator); 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; uri = this.losslessDecodeURI(uri); return this.crop(uri, crop); }, losslessDecodeURI: function(uri) { if(uri) try { return this._losslessDecodeURI(uri); } catch(e) { Components.utils.reportError(e); } return uri; }, get _losslessDecodeURI() { var ldu; if("losslessDecodeURI" in window) ldu = losslessDecodeURI; else if("UrlbarInput" in window) // Firefox 75+ ldu = Components.utils.import("resource:///modules/UrlbarInput.jsm", {}).losslessDecodeURI; delete this._losslessDecodeURI; return this._losslessDecodeURI = ldu ? function(uri) { return ldu(makeURI(uri)); } : decodeURI; }, 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 && !this.closedWindowCount; if( dis && this.options.useMenu && 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 + " tooltip-label"; 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)) continue; 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 == "destructor") // May happens before "unload" this.undoCloseTabsList.updUIGlobal(); 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"; }
Отсутствует
нет нигде элемента меню Добавить кнопку
Пункт «Добавить новую кнопку…» должен быть
в меню «Вид» главного меню [Файл Правка Вид Журнал ...],
и в контекстном меню тулбаров, таком,
как, например, появляющимся при клике ПКМ по кнопке гамбургера [Ξ].
Ещё есть одноимённая кнопка в разделе «Custom Buttons» на странице about:addons
Если этого всего нет, то, скорее всего, установка CB просто не произошла,
типа как поставить paxmod на недолеченный релиз или бету,
в аддон-менеджере будет, но не более того, просто бесполезный manifest.json
для Firefox 91.0.2 устанавливаю версию custom_buttons-0.0.7.0.0.19
Вот засада, в 0.0.7.0.0.19 не работают клонированные CB-меню
(используется в кнопке Undo Close Tabs).
А в последней версии работают, но она не совместима с Firefox 91.
Оказии пока не случилось, а из-за одной строчки собирать
новую версию не хотелось, но, пожалуй, следует. Чтобы была совместимая.
Custom Buttons 0.0.7.0.0.22. paxmod и bootstrap в zip-папке.
есть более свежая версия 0.3.3.3
Кстати, под угрозой.
В Firefox 95 SessionStore.getClosed{Tab, Window}Data()
будет всегда возвращать собственно сам объект,
а не его JSON.stringify() представление, как это было до этого по умолчанию.
Вариант фикса
var JSON = "JSON" in window //? window.JSON ? { parse: function(arg) { return typeof arg == "string" ? (JSON = window.JSON).parse(arg) : (this.parse = function(obj) { return obj; }) && arg; } }
Отредактировано Dumby (24-11-2021 17:13:39)
Отсутствует
как поставить paxmod на недолеченный релиз или бету
Не, это я что-то не не то загнул.
Например, если править AppConstants.jsm в omni.ja,
выключить xpinstall.signatures.required
и не влючить extensions.experiments.enabled, то да,
но такое совсем маловероятно. Тогда не понятно в чём дело.
Вопрос: Как рихтануть Attributes Inspector , чтобы наводил cursor:default ? А то кнопки pointer... Неудобно.
Попробуй — поиск в коде: outline-offset
следующей строкой добавить: cursor: default !important;\n\
Отредактировано Dumby (24-11-2021 18:15:35)
Отсутствует
sonyas75, Dumby
Спасибо, в моем случае все решилось банальным запуском чистого профиля.
Dumby, не получилось скачать ваш Custom Buttons 0.0.7.0.0.22. paxmod, Eset чего-то на него ругается. Подскажите, куда вставить ваш вариант фикса Undo Close Tabs?
kokoss, спасибо за свежий вариант.
Отсутствует
Подскажите, куда вставить ваш вариант фикса Undo Close Tabs?
Там же написано, фикс для 95!
не получилось скачать ваш Custom Buttons 0.0.7.0.0.22. paxmod, Eset чего-то на него ругается.
А отключить Eset на время скачивания файла не вариант?!
Win7
Отсутствует