nbuh пишет: Скажите пожалуйста, а как установить иконку кнопки, если она дана в виде кода, а не рисунка?
изъясняйтесь внятнее что есть и что хотите получить.
если есть чтото типа data:image/png;base64,.... то просто вставляете этот код в поле изображение в окне редактирования кнопки
либо ищете в коде кнопки подобные куски и заменяете своими (все что в кавычках)
если вам надо получитть такой код из картинки то в окне редактироания там где изображение выберите файл и нажмите >>base64 и в строке вместо адреса появится этот код
я помню те времена когда обновления программ убирали проблемы и исправляли баги, а не добавляли их.
toxID:05AB9B827D896AACEE7FF4573A02FB8F025F46ADC856B98F65BC1BA9BD21A81DC98BA9C36CE3
Отсутствует
Есть вот такой код:
/*Initialization Code*/ // Открыть вкладку "Исходный код страницы" справа от текущей. .......... this.onclick = function(event) { if(event.button == 0) { var orgTab = gBrowser.selectedTab; var newTab = gBrowser.addTab ("view-source:" + content.location.href); gBrowser.moveTabTo(newTab, orgTab._tPos+1); setTimeout(function() { gBrowser.selectedTab = newTab, 500 }); } }
«The Truth Is Out There»
Отсутствует
unter_officer может что-то из этого подойдет с заменой "view-source:", context-inspect, view-inspect, inspect...
Отсутствует
func4ptch4
Попробовал. Не работает.
«The Truth Is Out There»
Отсутствует
rubel Только сейчас заметил ваше сообщение - Save snapshot to html
У меня на 64 работает так -
// Добавить новый пункт "Сохранить страницу или выбранное как HTML" в главном меню ..................................................... (function() { // блокировать дублирование пункта при открытии настройки панелей if ( document.getElementById("SaveHTML") ) return; function SaveHTML(event) { var saveToFile = function (fileContent, fileName) { var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); uc.charset = 'utf-8'; fileContent = uc.ConvertFromUnicode(fileContent); var nsIFilePicker = Components.interfaces.nsIFilePicker; var fp = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker); fp.init(window, '', fp.modeSave); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); fp.open(function (rv) { if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) { var stream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream); stream.init(fp.file, 0x02|0x20|0x08, 0666, 0); stream.write(fileContent, fileContent.length); stream.close(); } }); }; var resolveURL = function (url, base) { try { var ioService = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService); var baseURI = ioService.newURI(base, null, null); var absURI = ioService.newURI(url, null, baseURI); return absURI.spec; } catch (e) {} }; var 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) {} } }; var 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; }; var 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'; } }; var mainWin = document.commandDispatcher.focusedWindow.top == content ? document.commandDispatcher.focusedWindow : content 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); var meta = doc.createElement('meta'); meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); var title = doc.getElementsByTagName('title')[0]; 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); }; var sheets = doc.styleSheets; 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 fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, ''); fileName += (function () { var d = new Date(), z = function(n){return '_' + (n < 10 ? '0' : '') + n}; return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds()); })(); if(!/\.html?$/.test(fileName))fileName += '.html'; saveToFile(doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->', fileName); } var menuItem = document.createElement("toolbarbutton"); menuItem.id = "SaveHTML"; menuItem.setAttribute("label", "Сохранить страницу или выбранное как HTML"); menuItem.setAttribute("class", "subviewbutton subviewbutton-iconic"); menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACzElEQVQ4jV2STW8bZRDHf/Psrr11nZhgVKcKaSmUiArRKBRVIMgH4BKJ7xAp5MSFiA+Rc28ckBAoipC4koJQLyAaVFChIlQllDRWmjRev8Qvu14/+wwHx6ZlpNFcZn7zn79GVJW1tbXc6urqijHGqKoAPF3TgcVaq8owXJbphx99fOOnWzcHoqqsr68/t7y83BARVBXnHHraXo3a3HoUU8gFAHRTS2Bg/7C2Zx7vXPIBwjA0p3BU9Zns9i3vvVrhr6MWzlpee+EsRqAbHc3+/Pee7wPkcrkx4P+g0IMvb/5Iv5/iXEaWZQS+By578MaVy9YH8H3fE5FnANZajqMmgcAnH7yN73mICMYMd21sbLy7srKiPkA+n3/qBLhzv8p+EuOfTUjShPbODvOVWa5fnRsvKBaLAcAIMFbw+bc/EBVn8At7SPcQ60LSiVm++P0fGu0e7y++yalvHoABCILAiAj7hzU+vfcVT6zPVGmR3x4/xJoLSH6BVu4cN777nnQwQETI5XL/AYwxRkS4ff8BEk6Q2pBfq3dxUuHMmWt0kgFGStTDY/7YrTLybQwYPU2cpgzsCd1OgmSzWHeOR7VjWicxaT9lxn+HfjoYmWnGHgAiIsydf5HKnUXiThehQDG4Tr3e5KR7hN8XilnGKxfOoyrDgZECwIgIb125xIxxTGVdgjRG4pR2+zbG/sIkD7l2cYJyaYLMOZxzjBV4nueLCI1GnaWFab65t4OXt4gUuFqYJ8gGuPYBCxdLHNciys9PkaapjAHGGM8YQ7lcZv71OaYmC/xZPaJHTN4cUgpDXrr8MtOVaUqTRXzfY3t7u7O0tDR82a2trfkkSTSOY+31etrpdLTZbGoURRpFkdbrTY3qTW00mhrHse7u7t4tl8uhqg4VxHHcPDg4+ExVHeBU1YmIU1WnisucZtamLszn01ar9WRzc/PrWq2WAPwLJ7l2ULfXOAMAAAAASUVORK5CYII="); menuItem.addEventListener("command", SaveHTML, false); var it = document.getElementById("appMenu-print-button"); it.parentNode.insertBefore(menuItem, it); })();
Отсутствует
У меня на 64 работает так -
Попробовал. Не работает, ваш код вставлял и во вкладку Код и в Инициализацию. Нигде нет этого пункта: . Извиняюсь, нашел в кнопочке справа. А я искал в меню Инструменты. Спасибо Вам За эту чудесную кнопку!
"Сохранить страницу или выбранное как HTML" в главном меню
Отредактировано rubel (17-01-2019 08:01:08)
Отсутствует
Подправил под 64 - Добавление на вкладке дополнения в меню расширений дополнительных пунктов
//Добавление на вкладке дополнения в меню расширений дополнительных пунктов (function(){ var iconURL = ""; if (window.AM_Helper) { window.AM_Helper.uninit(); delete window.AM_Helper; } Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/AddonManager.jsm"); window.AM_Helper = { init: function() { document.addEventListener("DOMContentLoaded", this, false); this.platformVersion = parseFloat(Services.appinfo.platformVersion); }, uninit: function() { document.removeEventListener("DOMContentLoaded", this, false); }, handleEvent: function(event){ switch(event.type){ case "DOMContentLoaded": var doc = event.target; var win = doc.defaultView; if (["about:addons","chrome://mozapps/content/extensions/extensions.xul"].indexOf(doc.URL) == -1) return; this.addPopupMenu(doc); win.AM_Helper = AM_Helper; this.win = win; var observer = new MutationObserver(function(e) { e = e[e.length-1]; if(e.attributeName == "loading") { var doc = e.target.ownerDocument; } }); observer.observe(doc.getElementById("detail-view"), {attributes: true}); break; case "popupshowing": this.getAddon(this.win.document.popupNode.value, this.setItemsAttributes, event); break; } }, //Создаем меню addPopupMenu: function(doc) { var mainicon2="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAwAAAP8AAAD/AAAA/wAAAPAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAAAAAAD/AAAA/wAAAP8AAADwAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAA/wAAAP8AAAD/AAAA8AAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAAAAAP8AAAD/AAAA/wAAAPAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAAAAAAD/AAAA/wAAAP8AAADwAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAA8wAAAP8AAAD/AAAA8AAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAAAAAPAAAAD/AAAA/wAAAPAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAAAAAAAHsAAAD/AAAAkAAAAAAAAADwAAAA/wAAAP8AAADwAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAAAAAIQAAAD/AAAAjQAAAAAAAAB1AAAA/wAAAP8AAAD/AAAA8AAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAIoAAAD/AAAAigAAAAAAAABpAAAAAAAAAAAAAAB7AAAA/wAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAigAAAAAAAAB7AAAA8AAAAAAAAACEAAAA/wAAAIcAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAhwAAAAAAAACBAAAA/wAAAPAAAACKAAAA/wAAAIcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEAAAA/wAAAP8AAAD/AAAA/wAAAIcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIQAAAAAAAAAAAAAAAAAAAAAAB8AAAAfAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAxAAAAIgAAAAWAAAAJEAAAEDAAD+BwAA+A8AAA=="; var ins = doc.getElementById("menuitem_uninstallItem"); if (!ins) return; ins = ins.nextSibling; var popup = ins.parentNode; var menuitem = $C("menuseparator", { id: "AM-separator-1" }); popup.insertBefore(menuitem, ins); menuitem = $C("menuitem", { id: "AM-browse-dir", label: "Папка установки", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.browseDir);" }); popup.insertBefore(menuitem, ins); menuitem = $C("menuitem", { id: "AM-browse-Folder", label: "Файл установки", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.Folder);" }); popup.insertBefore(menuitem, ins); menuitem = $C("menuitem", { id: "AM-open-url", label: "Страница на AMO", tooltiptext: null, oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.goAMO);" }); popup.insertBefore(menuitem, ins); menuitem = $C("menuitem", { id: "AM-browse-support", label: "Страница поддержки", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.support);" }); popup.insertBefore(menuitem, ins); menuitem = $C("menuitem", { id: "AM-browse-goHome", label: "Домашняя страница", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.goHome);" }); popup.insertBefore(menuitem, ins); var menu = $C("menu", { id: "AM-menu", class: "menu-iconic", image: mainicon2, label: "Копировать", }); popup.insertBefore(menu, ins); var menuPopup = $C("menupopup", { id: "AM-menupopup", }); menu.appendChild(menuPopup); menuitem = $C("menuitem", { id: "AM-copy-name", label: "Копировать имя", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyName);" }); menuPopup.appendChild(menuitem); menuitem = $C("menuitem", { id: "AM-copy-version", label: "Копировать версию", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyVersion);" }); menuPopup.appendChild(menuitem); menuitem = $C("menuitem", { id: "AM-copy-NameVersion", label: "Копировать имя и версию", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyNameVersion);" }); menuPopup.appendChild(menuitem); menuitem = $C("menuitem", { id: "AM-copy-id", label: "Копировать id", oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyID);" }); menuPopup.appendChild(menuitem); popup.addEventListener("popupshowing", this, true); }, //Указываем где и когда показывать элементы меню setItemsAttributes: function(aAddon, event) { var popup = event.target; var doc = popup.ownerDocument; var isExtension = (aAddon.type == "extension"), isTheme = (aAddon.type == "theme"), isPlugin = (aAddon.type == "plugin"), isService = (aAddon.type == "service"), isCustomButton = (aAddon.type == "custombuttons"), menuitem ; menuitem = doc.getElementById("AM-browse-dir"); menuitem.hidden = isService || isTheme || isCustomButton; menuitem = doc.getElementById("AM-browse-Folder"); menuitem.hidden = isService || isTheme || isCustomButton || isPlugin; menuitem = doc.getElementById("AM-copy-name"); menuitem.tooltipText = aAddon.name; menuitem = doc.getElementById("AM-copy-version"); menuitem.tooltipText = aAddon.version; menuitem.hidden = isCustomButton || isTheme; menuitem = doc.getElementById("AM-copy-NameVersion"); menuitem.tooltipText = aAddon.name + " " + aAddon.version; menuitem.hidden = isCustomButton || isTheme; menuitem = doc.getElementById("AM-copy-id"); menuitem.tooltipText = "ID: " + aAddon.id; menuitem = doc.getElementById("AM-open-url"); var amoURL = aAddon.reviewURL ? aAddon.reviewURL.replace(/\/reviews\//, "/") : null; menuitem.tooltipText = amoURL; menuitem.hidden = !amoURL || /addons.mozilla.org/.test(aAddon.homepageURL); menuitem = doc.getElementById("AM-browse-support"); menuitem.tooltipText = aAddon.supportURL; menuitem.hidden = !aAddon.supportURL; menuitem = doc.getElementById("AM-browse-goHome"); menuitem.tooltipText = aAddon.homepageURL; menuitem.hidden = !aAddon.homepageURL; }, getPopupNode: function (aNode) { var doc = aNode.ownerDocument; return "triggerNode" in aNode.parentNode ? aNode.parentNode.triggerNode : doc.popupNode; }, getAddon: function (aId, aCallback, aEvent) { var self = this; if (this.win.gDetailView._addon) { aCallback.apply(this, [this.win.gDetailView._addon, aEvent]); return; } (self.platformVersion < 61.0? new Promise((resolve, reject) => AddonManager.getAllAddons(addons => resolve(addons))): AddonManager.getAllAddons() ).then(addons => { for (var i = 0; i < addons.length; i++) { if (addons[i].id == aId) { aCallback.apply(self, [addons[i], aEvent]); return; } } }); }, //Открыть папку установки browseDir: function (aAddon) { switch (aAddon.type) { case "plugin": var pathes = aAddon.pluginFullpath; for (var i = 0; i < pathes.length; i++) { this.revealPath(pathes[i]); } return; case "userchromejs": var file = aAddon._script.file; if (file.exists()) file.reveal(); return; } // addon var gecko = parseInt(Services.appinfo.platformVersion); var nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", (gecko >= 14) ? "nsIFile" : "nsILocalFile", "initWithPath"); var dir = Services.dirsvc.get("ProfD", Ci.nsIFile); dir.append("extensions"); dir.append(aAddon.id); var fileOrDir = dir.path + (dir.exists() ? "" : ".xpi"); try { (new nsLocalFile(fileOrDir)).reveal(); } catch (ex) { var addonDir = /.xpi$/.test(fileOrDir) ? dir.parent : dir; try { if (addonDir.exists()) { addonDir.launch(); } } catch (ex) { var uri = Services.io.newFileURI(addonDir); var protSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"]. getService(Ci.nsIExternalProtocolService); protSvc.loadUrl(uri); } } }, //Копировать имя copyName: function (aAddon) { this.copyToClipboard(aAddon.name); }, //Копировать ID copyID: function (aAddon) { this.copyToClipboard("ID: " + aAddon.id); }, //Копировать версию copyVersion: function (aAddon) { this.copyToClipboard(aAddon.version); }, //Копировать имя и версию copyNameVersion: function (aAddon) { this.copyToClipboard(aAddon.name + " " + aAddon.version); }, //Открыть файл установки Folder: function (aAddon) { var gecko = parseInt(Services.appinfo.platformVersion); var nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", (gecko >= 14) ? "nsIFile" : "nsILocalFile", "initWithPath"); var dir = Services.dirsvc.get("ProfD", Ci.nsIFile); dir.append('extensions'); dir.append(aAddon.id); if ( dir.exists() ) dir.launch(); var file = Components.classes['@mozilla.org/file/directory_service;1'] .getService(Components.interfaces.nsIProperties) .get('ProfD', Components.interfaces.nsIFile); file.append('extensions'); file.append( aAddon.id + '.xpi' ) if ( file.exists() ) file.launch(); return; }, //Страница на АМО goAMO: function (aAddon) { var sourceTracker = "/?src=external-Add-ons_Manager_Context_Menu-extension"; if (aAddon.reviewURL) { var amoURL = aAddon.reviewURL.replace(/\/reviews\//, "/") .replace(/\/(firefox|seamonkey|thunderbird|android)/, "") .replace(/\/\?src\=api/, sourceTracker); } if (/personas.mozilla.org$/.test(aAddon.id)) { amoURL = "https://addons.mozilla.org/addon/" + aAddon.id.match(/\d+/) + sourceTracker; } openURL(amoURL); }, //Домашняя страница goHome: function (aAddon) { var url = aAddon.homepageURL; if (!url) { if (aAddon.reviewURL) { url = aAddon.reviewURL.replace(/\/reviews\/.*$/, "/"); } else { url = "https://addons.mozilla.org/search/?q=" + encodeURIComponent(aAddon.name); } } openURL(url); }, //Страница поддержки support: function(aAddon) { openURL(aAddon.supportURL); }, //Вспомогательные функции get getPath() { var url = this.win.gViewController.viewObjects.detail._addon; if (!url) return false; return url.pluginFullpath || false; }, revealPath: function(path){ var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile); file.initWithPath(path); if(file.exists()) file.reveal(); }, copyToClipboard: function (aString) { Cc["@mozilla.org/widget/clipboardhelper;1"]. getService(Ci.nsIClipboardHelper).copyString(aString); } }; AM_Helper.init(); function $C(name, attr) { var el = document.createElement(name); if (attr) Object.keys(attr).forEach(function(n){ el.setAttribute(n, attr[n])}); return el; } })();
Отсутствует
«Merge Date»
Описание исходной концепции (Firefox 63+) здесь.
В коде для конфигурационного файла заменён запускатор,
поскольку рассылка использовавшегося топика прекращена (#l4.31).
// try {(jsval => { var data = { MOZ_REQUIRE_SIGNING: false, MOZ_ALLOW_LEGACY_EXTENSIONS: true, get MOZ_UNSIGNED_SCOPES() { return 31; // AddonManager.SCOPE_ALL } }; var o = Cu.getGlobalForObject(jsval).Object, {freeze} = o; o.freeze = obj => { if (Components.stack.caller.filename != "resource://gre/modules/AppConstants.jsm") return freeze(obj); for(let key in data) o.defineProperty(obj, key, o.getOwnPropertyDescriptor(data, key)); return (o.freeze = freeze)(obj); } lockPref("extensions.legacy.enabled", true); lockPref("xpinstall.signatures.required", false); lockPref("extensions.langpacks.signatures.required", false); Cu.import("resource://gre/modules/addons/XPIInstall.jsm", {}) .shouldVerifySignedState = addon => !addon.id; })(Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}));} catch(ex) {Cu.reportError(ex);} // try {({ ids: [ "custombuttons@xsms.org", ], init(xrt) { if (xrt.inSafeMode) return; Cu.import("resource://gre/modules/addons/XPIProvider.jsm", this); var load = async file => { var rootURI = this.XPIInternal.getURIForResourceInFile(file, ""); Cu.import(rootURI.resolve("startup.jsm"), {}).start(rootURI); } var proto = this.XPIInternal.BootstrapScope.prototype; var func = proto._beforeCallBootstrapMethod; proto._beforeCallBootstrapMethod = () => { proto._beforeCallBootstrapMethod = func; for(var addon of this.XPIInternal.XPIStates.enabledAddons()) this.ids.includes(addon.id) && !addon.loader && load(addon.file); } } }).init(Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime));} catch(ex) {Cu.reportError(ex);}
из Firefox 65 вырезали аддон-менеджерские коды
обслуживавшие bootstrapped extensions
Затейник xiaoxiaoflood продемонстрировал,
что, на данный момент, это можно вернуть назад.
Но идея подгрузки через config.js многочисленного файла́ из профиля
показалась немного запутанной, а bootstrapLoader.xpi, который лежит
среди опекаемых расширений, тоже слегка не понравился,
да и вообще xpi, как таковой, пока не слишком хорошо подходит для таких дел.
Однако, взял из него код, чуть-чуть изменил, дополнил про providesUpdatesSecurely,
собрал адресом в одну строку, и записал как scriptloader'ом в sandbox.
Получилсь компактно, и не нужно ничего ни устанавливать,
ни создавать никаких файлов, а просто добавить код в config.js
Private Tab 0.2.3pre прямо из-под make.bat установился без проблем.
Соответственно, и Custom Buttons без paxmod-оболочки, если что.
custom_buttons-0.0.7.0.0.2-fx-bootstrap.xpi
bootstrap-loader.js
// try { Cu.createDocumentEncoder && Cc["@mozilla.org/moz/jssubscript-loader;1"] .getService(Ci.mozIJSSubScriptLoader).loadSubScript(String.raw` data:,var {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");%0Avar {AddonManager} = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");%0A%0AXPCOMUtils.defineLazyModuleGetters(this, {%0A%09Services: "resource://gre/modules/Services.jsm",%0A%09ConsoleAPI: "resource://gre/modules/Console.jsm",%0A%09Blocklist: "resource://gre/modules/Blocklist.jsm",%0A%09AddonInternal: "resource://gre/modules/addons/XPIDatabase.jsm",%0A%09RDFDataSource: "resource://gre/modules/addons/RDFDataSource.jsm"%0A});%0AXPCOMUtils.defineLazyGetter(this, "BOOTSTRAP_REASONS", () =>%0A%09ChromeUtils.import("resource://gre/modules/addons/XPIProvider.jsm", {})%0A%09%09.XPIProvider.BOOTSTRAP_REASONS%0A);%0AXPCOMUtils.defineLazyGetter(this, "logger", () =>%0A%09ChromeUtils.import("resource://gre/modules/Log.jsm", {})%0A%09%09.Log.repository.getLogger("addons.bootstrap")%0A);%0A%0A%0A// RDFManifestConverter.jsm%0Aconst RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest";%0A%0Afunction EM_R(aProperty) {%0A%09return %60http://www.mozilla.org/2004/em-rdf%23%24{aProperty}%60;%0A}%0Afunction getValue(literal) {%0A%09return literal && literal.getValue();%0A}%0Afunction getProperty(resource, property) {%0A%09return getValue(resource.getProperty(EM_R(property)));%0A}%0A%0Aclass Manifest {%0A%09constructor(ds) {%0A%09%09this.ds = ds;%0A%09}%0A%09static loadFromString(text) {%0A%09%09return new this(RDFDataSource.loadFromString(text));%0A%09}%0A%09static loadFromBuffer(buffer) {%0A%09%09return new this(RDFDataSource.loadFromBuffer(buffer));%0A%09}%0A%09static async loadFromFile(uri) {%0A%09%09return new this(await RDFDataSource.loadFromFile(uri));%0A%09}%0A}%0A%0Aclass InstallRDF extends Manifest {%0A%09_readProps(source, obj, props) {%0A%09%09for (let prop of props) {%0A%09%09%09let val = getProperty(source, prop);%0A%09%09%09if (val != null) {%0A%09%09%09%09obj[prop] = val;%0A%09%09%09}%0A%09%09}%0A%09}%0A%09_readArrayProp(source, obj, prop, target, decode = getValue) {%0A%09%09let result = Array.from(%0A%09%09%09source.getObjects(EM_R(prop)), target => decode(target)%0A%09%09);%0A%09%09if (result.length) {%0A%09%09%09obj[target] = result;%0A%09%09}%0A%09}%0A%09_readArrayProps(source, obj, props, decode = getValue) {%0A%09%09for (let [prop, target] of Object.entries(props)) {%0A%09%09%09this._readArrayProp(source, obj, prop, target, decode);%0A%09%09}%0A%09}%0A%09_readLocaleStrings(source, obj) {%0A%09%09this._readProps(source, obj, ["name", "description", "creator", "homepageURL"]);%0A%09%09this._readArrayProps(source, obj, {%0A%09%09%09locale: "locales",%0A%09%09%09developer: "developers",%0A%09%09%09translator: "translators",%0A%09%09%09contributor: "contributors",%0A%09%09});%0A%09}%0A%09decode() {%0A%09%09let root = this.ds.getResource(RDFURI_INSTALL_MANIFEST_ROOT);%0A%09%09let result = {};%0A%0A%09%09let props = [%0A%09%09%09"id", "version", "type", "updateURL", "optionsURL",%0A%09%09%09"optionsType", "aboutURL", "iconURL",%0A%09%09%09"bootstrap", "unpack", "strictCompatibility"%0A%09%09];%0A%09%09this._readProps(root, result, props);%0A%0A%09%09let decodeTargetApplication = source => {%0A%09%09%09let app = {maxVersion: "*"};%0A%09%09%09this._readProps(source, app, ["id", "minVersion"]);%0A%09%09%09return app;%0A%09%09};%0A%0A%09%09let decodeLocale = source => {%0A%09%09%09let localized = {};%0A%09%09%09this._readLocaleStrings(source, localized);%0A%09%09%09return localized;%0A%09%09};%0A%0A%09%09this._readLocaleStrings(root, result);%0A%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"targetPlatform": "targetPlatforms"}%0A%09%09);%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"targetApplication": "targetApplications"}, decodeTargetApplication%0A%09%09);%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"localized": "localized"}, decodeLocale%0A%09%09);%0A%09%09this._readArrayProps(%0A%09%09%09root, result, {"dependency": "dependencies"}, source => getProperty(source, "id")%0A%09%09);%0A%09%09return result;%0A%09}%0A}%0A// fim RDFManifestConverter.jsm%0A%0A%0A// BootstrapLoader.jsm%0A/**%0A * Valid IDs fit this pattern.%0A */%0Avar gIDTest = /^(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)$/i;%0A%0A// Properties that exist in the install manifest%0Aconst PROP_METADATA%09= [%0A%09"id", "version", "type", "internalName", "updateURL",%0A%09"optionsURL", "optionsType", "aboutURL", "iconURL"%0A];%0Aconst PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];%0Aconst PROP_LOCALE_MULTI%09= ["developers", "translators", "contributors"];%0A%0A// Map new string type identifiers to old style nsIUpdateItem types.%0A// Retired values:%0A// 32 = multipackage xpi file%0A// 8 = locale%0A// 256 = apiextension%0A// 128 = experiment%0A// theme = 4%0Aconst TYPES = {%0A%09extension: 2,%0A%09dictionary: 64,%0A};%0A%0Aconst COMPATIBLE_BY_DEFAULT_TYPES = {%0A%09extension: true,%0A%09dictionary: true,%0A};%0A%0Aconst hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);%0A%0Afunction isXPI(filename) {%0A%09let ext = filename.slice(-4).toLowerCase();%0A%09return ext === ".xpi" || ext === ".zip";%0A}%0A%0A/**%0A * Gets an nsIURI for a file within another file, either a directory or an XPI%0A * file. If aFile is a directory then this will return a file: URI, if it is an%0A * XPI file then it will return a jar: URI.%0A *%0A * @param {nsIFile} aFile%0A *%09%09The file containing the resources, must be either a directory or an XPI file%0A *%0A * @param {string} aPath%0A *%09%09The path to find the resource at, "/" separated. If aPath is empty%0A *%09%09then the uri to the root of the contained files will be returned%0A *%0A * @returns {nsIURI}%0A *%09%09An nsIURI pointing at the resource%0A */%0Afunction getURIForResourceInFile(aFile, aPath) {%0A%09if (!isXPI(aFile.leafName)) {%0A%09%09let resource = aFile.clone();%0A%09%09if (aPath)%0A%09%09%09aPath.split("/").forEach(part => resource.append(part));%0A%0A%09%09return Services.io.newFileURI(resource);%0A%09}%0A%09return buildJarURI(aFile, aPath);%0A}%0A%0A/**%0A * Creates a jar: URI for a file inside a ZIP file.%0A *%0A * @param {nsIFile} aJarfile%0A *%09%09The ZIP file as an nsIFile%0A *%0A * @param {string} aPath%0A *%09%09The path inside the ZIP file%0A *%0A * @returns {nsIURI}%0A *%09%09An nsIURI for the file%0A */%0Afunction buildJarURI(aJarfile, aPath) {%0A%09let uri = Services.io.newFileURI(aJarfile);%0A%09uri = "jar:" + uri.spec + "!/" + aPath;%0A%09return Services.io.newURI(uri);%0A}%0A%0Avar BootstrapLoader = {%0A%09name: "bootstrap",%0A%09manifestFile: "install.rdf",%0A%09async loadManifest(pkg) {%0A%09%09/**%0A%09%09 * Reads locale properties from either the main install manifest root%0A%09%09 * or an em:localized section in the install manifest.%0A%09%09 *%0A%09%09 * @param {Object} aSource%0A%09%09 *%09%09The resource to read the properties from.%0A%09%09 *%0A%09%09 * @param {boolean} isDefault%0A%09%09 *%09%09True if the locale is to be read from the main install manifest root%0A%09%09 *%0A%09%09 * @param {string[]} aSeenLocales%0A%09%09 *%09%09An array of locale names already seen for this install manifest.%0A%09%09 *%09%09Any locale names seen as a part of this function will be added to this array%0A%09%09 *%0A%09%09 * @returns {Object}%0A%09%09 *%09%09An object containing the locale properties%0A%09%09 */%0A%09%09function readLocale(aSource, isDefault, aSeenLocales) {%0A%09%09%09let locale = {};%0A%09%09%09if (!isDefault) {%0A%09%09%09%09locale.locales = [];%0A%09%09%09%09for (let localeName of aSource.locales || []) {%0A%09%09%09%09%09if (!localeName) {%0A%09%09%09%09%09%09logger.warn("Ignoring empty locale in localized properties");%0A%09%09%09%09%09%09continue;%0A%09%09%09%09%09}%0A%09%09%09%09%09if (aSeenLocales.includes(localeName)) {%0A%09%09%09%09%09%09logger.warn("Ignoring duplicate locale in localized properties");%0A%09%09%09%09%09%09continue;%0A%09%09%09%09%09}%0A%09%09%09%09%09aSeenLocales.push(localeName);%0A%09%09%09%09%09locale.locales.push(localeName);%0A%09%09%09%09}%0A%0A%09%09%09%09if (locale.locales.length == 0) {%0A%09%09%09%09%09logger.warn("Ignoring localized properties with no listed locales");%0A%09%09%09%09%09return null;%0A%09%09%09%09}%0A%09%09%09}%0A%09%09%09for (let prop of [...PROP_LOCALE_SINGLE, ...PROP_LOCALE_MULTI]) {%0A%09%09%09%09if (hasOwnProperty(aSource, prop)) {%0A%09%09%09%09%09locale[prop] = aSource[prop];%0A%09%09%09%09}%0A%09%09%09}%0A%09%09%09return locale;%0A%09%09}%0A%0A%09%09let manifestData = await pkg.readString("install.rdf");%0A%09%09let manifest = InstallRDF.loadFromString(manifestData).decode();%0A%0A%09%09let addon = new AddonInternal();%0A%09%09for (let prop of PROP_METADATA) {%0A%09%09%09if (hasOwnProperty(manifest, prop)) {%0A%09%09%09%09addon[prop] = manifest[prop];%0A%09%09%09}%0A%09%09}%0A%09%09if (!addon.type) {%0A%09%09%09addon.type = "extension";%0A%09%09} else {%0A%09%09%09let type = addon.type;%0A%09%09%09addon.type = null;%0A%09%09%09for (let name in TYPES) {%0A%09%09%09%09if (TYPES[name] == type) {%0A%09%09%09%09%09addon.type = name;%0A%09%09%09%09%09break;%0A%09%09%09%09}%0A%09%09%09}%0A%09%09}%0A%09%09if (!(addon.type in TYPES))%0A%09%09%09throw new Error("Install manifest specifies unknown type: " + addon.type);%0A%0A%09%09if (!addon.id)%0A%09%09%09throw new Error("No ID in install manifest");%0A%09%09if (!gIDTest.test(addon.id))%0A%09%09%09throw new Error("Illegal add-on ID " + addon.id);%0A%09%09if (!addon.version)%0A%09%09%09throw new Error("No version in install manifest");%0A%0A%09%09addon.strictCompatibility =%0A%09%09%09!(addon.type in COMPATIBLE_BY_DEFAULT_TYPES) ||%0A%09%09%09"strictCompatibility" in manifest && manifest.strictCompatibility == "true";%0A%0A%09%09// Only read these properties for extensions.%0A%09%09if (addon.type == "extension") {%0A%09%09%09if (manifest.bootstrap != "true") {%0A%09%09%09%09throw new Error("Non-restartless extensions no longer supported");%0A%09%09%09}%0A%09%09%09if (%0A%09%09%09%09addon.optionsType &&%0A%09%09%09%09addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE_BROWSER &&%0A%09%09%09%09addon.optionsType != AddonManager.OPTIONS_TYPE_TAB%0A%09%09%09) {%0A%09%09%09%09throw new Error("Install manifest specifies unknown optionsType: " + addon.optionsType);%0A%09%09%09}%0A%09%09} else {%0A%09%09%09// Convert legacy dictionaries into a format the WebExtension%0A%09%09%09// dictionary loader can process.%0A%09%09%09if (addon.type === "dictionary") {%0A%09%09%09%09addon.loader = null;%0A%09%09%09%09let dictionaries = {};%0A%09%09%09%09await pkg.iterFiles(({path}) => {%0A%09%09%09%09%09let match = /^dictionaries\/([^\/]+)\.dic$/.exec(path);%0A%09%09%09%09%09if (match) {%0A%09%09%09%09%09%09let lang = match[1].replace(/_/g, "-");%0A%09%09%09%09%09%09dictionaries[lang] = match[0];%0A%09%09%09%09%09}%0A%09%09%09%09});%0A%09%09%09%09addon.startupData = {dictionaries};%0A%09%09%09}%0A%0A%09%09%09// Only extensions are allowed to provide an optionsURL, optionsType,%0A%09%09%09// optionsBrowserStyle, or aboutURL. For all other types they are silently ignored%0A%09%09%09addon.aboutURL = null;%0A%09%09%09addon.optionsBrowserStyle = null;%0A%09%09%09addon.optionsType = null;%0A%09%09%09addon.optionsURL = null;%0A%09%09}%0A%0A%09%09addon.defaultLocale = readLocale(manifest, true);%0A%09%09let defaultLocaleEntries = Object.entries(addon.defaultLocale);%0A%0A%09%09let seenLocales = [];%0A%09%09addon.locales = [];%0A%09%09for (let localeData of manifest.localized || []) {%0A%09%09%09let locale = readLocale(localeData, false, seenLocales);%0A%09%09%09if (locale) {%0A%09%09%09%09for(let [key, val] of defaultLocaleEntries)%0A%09%09%09%09%09key in locale || Reflect.set(locale, key, val);%0A%09%09%09%09addon.locales.push(locale);%0A%09%09%09}%0A%09%09}%0A%0A%09%09addon.dependencies = Object.freeze(%0A%09%09%09"dependencies" in manifest ? Array.from(new Set(manifest.dependencies)) : []%0A%09%09);%0A%0A%09%09let seenApplications = [];%0A%09%09addon.targetApplications = [];%0A%09%09for (let targetApp of manifest.targetApplications || []) {%0A%09%09%09if (!targetApp.id || !targetApp.minVersion || !targetApp.maxVersion) {%0A%09%09%09%09logger.warn("Ignoring invalid targetApplication entry in install manifest");%0A%09%09%09%09continue;%0A%09%09%09}%0A%09%09%09if (seenApplications.includes(targetApp.id)) {%0A%09%09%09%09logger.warn(%0A%09%09%09%09%09"Ignoring duplicate targetApplication entry for " + targetApp.id + " in install manifest"%0A%09%09%09%09);%0A%09%09%09%09continue;%0A%09%09%09}%0A%09%09%09seenApplications.push(targetApp.id);%0A%09%09%09addon.targetApplications.push(targetApp);%0A%09%09}%0A%0A%09%09// Note that we don't need to check for duplicate targetPlatform entries since%0A%09%09// the RDF service coalesces them for us.%0A%09%09addon.targetPlatforms = [];%0A%09%09for (let targetPlatform of manifest.targetPlatforms || []) {%0A%09%09%09let platform = {%0A%09%09%09%09os: null,%0A%09%09%09%09abi: null,%0A%09%09%09};%0A%0A%09%09%09let pos = targetPlatform.indexOf("_");%0A%09%09%09if (pos != -1) {%0A%09%09%09%09platform.os = targetPlatform.substring(0, pos);%0A%09%09%09%09platform.abi = targetPlatform.substring(pos + 1);%0A%09%09%09} else {%0A%09%09%09%09platform.os = targetPlatform;%0A%09%09%09}%0A%09%09%09addon.targetPlatforms.push(platform);%0A%09%09}%0A%0A%09%09addon.userDisabled = false;%0A%09%09addon.softDisabled = addon.blocklistState == Blocklist.STATE_SOFTBLOCKED;%0A%09%09addon.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;%0A%0A%09%09addon.userPermissions = null;%0A%0A%09%09addon.icons = {};%0A%09%09if (await pkg.hasResource("icon.png")) {%0A%09%09%09addon.icons[32] = "icon.png";%0A%09%09%09addon.icons[48] = "icon.png";%0A%09%09}%0A%0A%09%09if (await pkg.hasResource("icon64.png")) {%0A%09%09%09addon.icons[64] = "icon64.png";%0A%09%09}%0A%0A%09%09return addon;%0A%09},%0A%0A%09loadScope(addon, file) {%0A%09%09let uri = getURIForResourceInFile(file, "bootstrap.js").spec;%0A%09%09let principal = Services.scriptSecurityManager.getSystemPrincipal();%0A%0A%09%09let sandbox = new Cu.Sandbox(principal, {%0A%09%09%09sandboxName: uri,%0A%09%09%09addonId: addon.id,%0A%09%09%09wantGlobalProperties: ["ChromeUtils"],%0A%09%09%09metadata: { addonID: addon.id, URI: uri },%0A%09%09});%0A%0A%09%09try {%0A%09%09%09Object.assign(sandbox, BOOTSTRAP_REASONS);%0A%0A%09%09%09XPCOMUtils.defineLazyGetter(%0A%09%09%09%09sandbox, "console", () => new ConsoleAPI({ consoleID: %60addon/%24{addon.id}%60 })%0A%09%09%09);%0A%09%09%09Services.scriptloader.loadSubScript(uri, sandbox);%0A%0A%09%09} catch (e) {%0A%09%09%09logger.warn(%60Error loading bootstrap.js for %24{addon.id}%60, e);%0A%09%09}%0A%0A%09%09function findMethod(name) {%0A%09%09%09if (sandbox.name) {%0A%09%09%09%09return sandbox.name;%0A%09%09%09}%0A%09%09%09try {%0A%09%09%09%09let method = Cu.evalInSandbox(name, sandbox);%0A%09%09%09%09return method;%0A%09%09%09} catch (err) { }%0A%0A%09%09%09return () => {%0A%09%09%09%09logger.warn(%60Add-on %24{addon.id} is missing bootstrap method %24{name}%60);%0A%09%09%09};%0A%09%09}%0A%0A%09%09let install = findMethod("install");%0A%09%09let uninstall = findMethod("uninstall");%0A%09%09let startup = findMethod("startup");%0A%09%09let shutdown = findMethod("shutdown");%0A%0A%09%09return {%0A%09%09%09install: (...args) => install(...args),%0A%09%09%09uninstall: (...args) => uninstall(...args),%0A%0A%09%09%09startup(...args) {%0A%09%09%09%09if (addon.type == "extension") {%0A%09%09%09%09%09logger.debug(%60Registering manifest for %24{file.path}\n%60);%0A%09%09%09%09%09Components.manager.addBootstrappedManifestLocation(file);%0A%09%09%09%09}%0A%09%09%09%09return startup(...args);%0A%09%09%09},%0A%0A%09%09%09shutdown(data, reason) {%0A%09%09%09%09try {%0A%09%09%09%09%09return shutdown(data, reason);%0A%09%09%09%09} catch (err) {%0A%09%09%09%09%09throw err;%0A%09%09%09%09} finally {%0A%09%09%09%09%09if (reason != BOOTSTRAP_REASONS.APP_SHUTDOWN) {%0A%09%09%09%09%09%09logger.debug(%60Removing manifest for %24{file.path}\n%60);%0A%09%09%09%09%09%09Components.manager.removeBootstrappedManifestLocation(file);%0A%09%09%09%09%09}%0A%09%09%09%09}%0A%09%09%09},%0A%09%09};%0A%09},%0A};%0A// fim BootstrapLoader.jsm%0A%0A%0AAddonManager.addExternalExtensionLoader(BootstrapLoader);%0AObject.defineProperty(%0A%09AddonInternal.prototype,%0A%09"providesUpdatesSecurely",%0A%09{enumerable: true, value: true}%0A);%0A `.trim(), new Cu.Sandbox(Cu.getObjectPrincipal(this), {wantGlobalProperties: ["ChromeUtils"]})); } catch(ex) {Cu.reportError(ex);}
Отредактировано Dumby (20-02-2019 17:56:44)
Отсутствует
Firefox 63+
Firefox 65
Приветствую. Можно попросить объяснить в двух словах бестолковому — эти метóды годятся для 65 или нет?
И что куда (присоединяясь в ковпросу Garalf).
В конец запутался я в этих версиях. Мало того что кнопки не работают ещё и стили перепиливать придётся.
Спасибо заранее, уж простите, в конец запутался я в версиях
Отсутствует
А куда поместить bootstrap-loader.js? Дописать в config.js?
Да, всё верно, bootstrap-loader.js задуман
как предназначеный быть добавленным в config.js
эти метóды годятся для 65 или нет?
Да, я надеюсь, что обе эти метóды годятся для Firefox 65.
И не будет работать на 62, 61, 60, 59, и.т.д.
Можно, конечно, было бы попробовать расширить диапазон,
но не вижу большого смысла, да и всё равно дальше 60 не сдвинуть.
Firefox 65 — это имеется в виду рубеж, когда нужно
предпринимать какие-то дополнительные действия,
поскольку bootstrap-расширения перестанут работать не потому,
что неподписаны или легаси, а просто потому, что некоторые необходимые
служебные коды высланы из Firefox куда-то в Thunderbird'ьи края.
Иначе говоря, с точки зрения Firefox 65, попытка установить
такое расширение будет воспринята так, как будто какой-то лопух
пытается поставить аддон вообще без инсталляционного манифеста.
Таким образом, чтобы установить
на вылеченный Firefox 65 bootstrap-расширение, нужно:
либо оформить его как paxmod, и тут для некоторых (зависит от расширения)
весьма желателен какой-нибудь запускатор, ну просто чтобы
стартовало побыстрее, а не тогда, когда запустится само,
либо веруть лису во вменяемое состояние, подключив обратно
выпиленные из неё коды, типа сделать так, как если бы ничего
и не случилось вовсе. Тогда нужен какой-нибудь bootstrap-лоадер.
Отсутствует
Доброго дня всем.
Сможет кто нибудь переделать Clipboard? Чтоб контекстное меню открывалось не при нажатии на кнопку а был пункт в контекстном меню страницы как в стареньком расширении Clipple
Нужно для Palemoon 27 и 28 версий.
Отредактировано Rag (29-01-2019 15:59:17)
Отсутствует
Да, я надеюсь, что обе эти метóды годятся для Firefox 65.
Огромное спасибо, уважаемый! Объяснение более чем доходчивое.
Да я и сам виноват — ухитрился вставить код bootstrap-loader.js так, что Firefox вообще запускаться перестал.
Да ещё и custombuttons@xsms.org.xpi обозвал как custombuttons@xsms.org.xpi.xpi
Начудил, в общем... Буду Ctrl-C Ctrl-V осваивать...
без CB - это уже другой браузер
Отсутствует
Затейник xiaoxiaoflood продемонстрировал,
Без этого куска config.js отвалились расширения WinSizeNPosition и Video Speed Controller, а после добавления кода в начало config.js они снова подхватились.
Отсутствует
Чем он круче 64? Если смысл его ломать? Кнопки падают? Заманали они своими шарадами ...Теперь еще и панели...
Unread - непрочитанная вкладка - опять ломать? Если нет новой скорости или еще какой-то фишки, то на ... он нужен?
MP4 декодер когда? Никогда ! А это главная фича хрома....От уроды.
Отредактировано drage2 (30-01-2019 12:44:08)
Отсутствует
Dumby не подскажите?
1. В 65 убрали файл chrome://global/content/platformHTMLBindings.xml из которого можно было вывести команды. Сейчас в 65 такое возможно или нет?
var tagNames = ["command", "broadcaster", "key", "menuitem"]; var collection = new Object(); for (var i = 0; i < tagNames.length; i++) { collection[tagNames[i]] = document.getElementsByTagName(tagNames[i]); } var out = new Array(); var xai = Components.classes["@mozilla.org/xre/app-info;1"]. getService(Components.interfaces.nsIXULAppInfo); out.push(xai.name + " " + xai.version); out.push(document.documentElement.getAttribute("windowtype")); var menuitems = document.getElementsByTagName("menuitem"); for (var i in collection) { var count = 0; out.push("_____ ^ " + i + " " + Array(72 - i.length).join("_")); for (var j = 0; j < collection[i].length; j++) { var id = collection[i][j].getAttribute("id"); var oncommand = collection[i][j].getAttribute("oncommand"); var label = collection[i][j].getAttribute("label"); var tooltiptext = collection[i][j].getAttribute("tooltiptext"); var text = label || tooltiptext; if (id && oncommand) { count++; var tagNames = ["command", "key", "observes"]; for (var m = 0; m < tagNames.length; m++) { if (!text) { for (var n = 0; n < menuitems.length; n++) { if (menuitems[n].getAttribute(tagNames[m]) == id) { text = menuitems[n].getAttribute("label"); break; } } } } id = text ? id + " \u25ba " + text : id; oncommand = oncommand.search(/\x29$/) > -1 ? oncommand + ";" : oncommand; oncommand = oncommand.replace(/\s\s+/g, " "); out.push(id + "\n" + oncommand); } } out.push(i + " count " + count); } out.push("_____ ^ handler " + Array(65).join("_")); var request = new XMLHttpRequest(); request.open("GET", "chrome://global/content/platformHTMLBindings.xml", false); request.send(null); var els = request.responseXML.getElementsByTagName("handler"); var cmd = new Array(); var count = 0; for (var i = 0; i < els.length; i++) { var command = els[i].getAttribute("command"); var controller = document.commandDispatcher.getControllerForCommand(command); var element = document.getElementById(command); var label = element && element.getAttribute("label"); var tooltiptext = element && element.getAttribute("tooltiptext"); var text = label || tooltiptext; if (command && (controller || element) && cmd.indexOf(command) == -1) { count++; var tagNames = ["command", "key", "observes"]; for (var m = 0; m < tagNames.length; m++) { if (!text) { for (var n = 0; n < menuitems.length; n++) { if (menuitems[n].getAttribute(tagNames[m]) == command) { text = menuitems[n].getAttribute("label"); break; } } } } cmd.push(command); var id = text ? command + " \u25ba " + text : command; var oncommand = "goDoCommand('" + command + "');"; out.push(id + "\n" + oncommand); } } out.push("handler count " + count); for (var i = 0; i < out.length; i++) { var suc = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]. createInstance(Components.interfaces.nsIScriptableUnicodeConverter); suc.charset = "UTF-8"; out[i] = suc.ConvertFromUnicode(out[i]); out[i] = out[i].replace(/&/g, "&"); out[i] = out[i].replace(/>/g, ">"); out[i] = out[i].replace(/</g, "<"); out[i] = out[i].replace(/"/g, """); out[i] = out[i].replace(/'/g, "'"); } var data = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">'; data += "<html><head><title>" + out[1] + "</title>"; data += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'; data += "</head><body><pre>" + out.join("\n\n") + "</pre></body></html>"; if (xai.name == "Firefox" || xai.name == "SeaMonkey") { gBrowser.selectedTab = gBrowser.addTab("data:text/html;charset=utf-8;base64," + btoa(data), { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() }); } if (xai.name == "Thunderbird") { openContentTab("data:text/html;charset=utf-8;base64," + btoa(data)); }
function readFromClipboard() { var string; try { var clipboard = Cc["@mozilla.org/widget/clipboard;1"]. getService(Ci.nsIClipboard); var trans = Cc["@mozilla.org/widget/transferable;1"]. createInstance(Ci.nsITransferable); trans.addDataFlavor("text/unicode"); if (clipboard.supportsSelectionClipboard()) { clipboard.getData(trans, clipboard.kSelectionClipboard); } else { clipboard.getData(trans, clipboard.kGlobalClipboard); } var data = {}; var dataLen = {}; trans.getTransferData("text/unicode", data, dataLen); if (data) { data = data.value.QueryInterface(Ci.nsISupportsString); string = data.data.substring(0, dataLen.value / 2); } } catch (ex) { } return string; }
Отредактировано Andrey_Krropotkin (31-01-2019 10:26:48)
Отсутствует
В 65 убрали файл chrome://global/content/platformHTMLBindings.xml из которого можно было вывести команды. Сейчас в 65 такое возможно или нет?
Bug 1419091 - Figure out an alternative to the key handling defined with XBL in the platformHTMLBindings.xml files
То есть их зашили в C++. Так что, вряд ли.
Нет, ну можешь попробовать по сети за командами слазать,
типа как-то так (не проверял)
(async () => { var url = `${ AppConstants.SOURCE_REVISION_URL.replace("rev", "raw-file") }/dom/xbl/builtin/${ {win: "win", linux: "unix", macosx: "mac"}[AppConstants.platform] || "unix" }/ShortcutKeyDefinitions.cpp`; var text = await (await fetch(url)).text(); var commands = text.match(/cmd_[^"]+/g); alert(commands.join("\n")); })();
Перестал на на 65 работать вот такой код работы с Clipboard, вроде на 65 с Clipboard ничего не меняли
С Clipboard, может, и не меняли, а вот с nsITransferable меняли.
Bug 1493292 - Remove aDataLen parameters from nsITransferable
Значит, наверно, так
//string = data.data.substring(0, dataLen.value / 2); string = trans.getTransferData.length == 2 ? data.data : data.data.substring(0, dataLen.value / 2);
Отсутствует
Dumby пишет:
типа как-то так (не проверял)
нормально все показывает.
А с richlistbox, listcol и richlistitem то же что изменили?
У меня есть код на 64 работал, на 65 перестал, т.е функции все отрабатываются, кнопки все работают, но в полях ничего не видно, словно текст стал белым.
/*CODE*/ var btn = this, br = gBrowser; var img2 = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAABwWjpocFs8zHFbPP9xWzz/cVs8/3FbPP9xWzz/cVs8/3FbPP9xWzz/cVs8/3FbPP9xWzz/cVs8/3BbPMxwWjpodWBB4bWwqv/o6Oj/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+rq6v+1sKr/dWBB4XtlR//f39//6Ojo/8e7q/+0oIf/po1t/6aNbf+mjW3/po1t/6aNbf+mjW3/po1t/+rq6v/s7Oz/39/f/3tlR/+Ba07/29vb/+fn5//f39//3Nzc/9nZ2f/Z2dn/2dnZ/9nZ2f/Z2dn/2dnZ/9nZ2f/l5eX/5+fn/9vb2/+Ba07/h3FV/9bW1v/k5OT/5OTk/+Dg4P+bhGb/k3hX/5N4WP+TeFf/m4Rm/+Dg4P+WfF3/rp2H/+Dg4P/U1NT/h3FV/454XP/Z2dn/5+fn/+Pj4//j4+P/ysK3/8nCtv/Jwrb/xr2w/8e9sP/d29j/2NjY/5d9Xv+vnon/1dXV/454XP+UgGP/3Nzc/+rq6v/m5ub/lHlY/5d8XP+dhmf/lXpa/5R5WP+dhmf/uqyb/+bm5v+UeVj/r56I/9jY2P+UgGP/m4dr/97e3v/t7e3/6enp/93d3f/d3d3/3t7e/yOC5P+AsOD/3t7e/+Pj4/+lkHX/rp6J/+Li4v/c3Nz/m4dr/6KNc//h4eH/8PDw//Dw8P/w8PD/7Ozs/zKK6f/h4eH/C3To/+zs7P/s7Oz/4+Pj/+bm5v/u7u7/4eHh/6KNc/+olHr/5OTk//Pz8//z8/P/8/Pz//Dw8P8Seen/8PDw/xJ56f8Seen/8PDw//Dw8P/z8/P/8/Pz/+Tk5P+olHr/r5uC/+fn5//29vb/9vb2//b29v/z8/P/lL3o/xl96f/n5+f/grTo/yWE6v/z8/P/9vb2//b29v/n5+f/r5uC/7Whif/p6en/+fn5//n5+f/5+fn/+fn5//Dw8P+JuOr/JYXr/+/v7/+60ev/9fX1//n5+f/5+fn/6enp/7Whif+6p5D/7Ozs//v7+//7+/v/+/v7//v7+//6+vr/8/Pz/4y77f83juz/9fX1//v7+//7+/v/+/v7/+zs7P+6p5D/v6yW/+3t7f/8/Pz//f39//39/f/9/f3//f39//z8/P/09PT/xNnw//r6+v/9/f3//f39//z8/P/t7e3/v6yW/8Owm8ze2tX/9fX1//f39//39/f/9/f3//f39//39/f/9/f3//T09P/39/f/9/f3//f39//19fX/3trV/8Owm8zGsp9oyLWezMi1n//ItZ//yLWf/8i1n//ItZ//yLWf/8i1n//ItZ//yLWf/8i1n//ItZ//yLWf/8i1nszGsp9oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="; var img1 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmlJREFUeNpsU0toU0EUPfPysx/tTxuDH9SCWhUDooIbd7oRUUTMouqi2iIoCO6lceHWhegy4EJFinWjrlQUpVm0IIoFpVDEIthm0dpikpf3ZuZ6Z94nrXhhMjM3c8895977BBHB2PznK8WPtDgyWH5q77cPH8PpdXuhpQT4ifR9u5sfJb1bmw6VivahATDrxcRZ2njfoaMv+2j7mLDn93MPiNRMvGbL18L9IpF8h9/TN+EYkMffSiOXJ5+hkD+PdqcLpICWHOHc2CC+LEyA/K+cKQMnlQHJX8wqYG3MAJy88Wa4OLDvEqAEOpJd0LxHIMdHBziowSwVlF8D6QaicK01krw/JynwcKoEwZczewroTvZirlKJs5CqQ5CG8pb57FnJUA0LYCXMX5fibd+p8LWDDemcPZbzQyjvH+Ki1TlIciElA7ghwLKV4kRZstt2sANWRjYTAGzuP2hXZFpJ/GsxgGJ0ox1aoFWsDXyyxqCs26+ydmagFN/rRjymJ1898bzGzmQE0HCZpmk5A0RFIv8Pn0WYPsiu6t/Rsj6PauVTwffTSzGAGZhUG2F06hEc9ibS7OPMNp6ErYFlKavo7MkhmTqCxZ/jwzGA9Hx82H2BZSw1NTN9Gx8ycHkajU/7M+jInsDC7DiaEmo1bNl1AMr9ASFgqVu9MCTIzoGUimXVAnnaN0PdBBDCCYbEtMk6wkpQwIG0sn0PQIUF4GsTwLSIFKNqF6DVrQq+IWVrQDxAYQC/1SsYOI4pOxKZrfifiUSbDUisif7XlpGIPufXd/uvdvZm760M0no1FZcnrzUdjw7au3vu/BVgAFLXeuTxhTXVAAAAAElFTkSuQmCC"; var trigger, trigger1, dialog, drives, count; var icon1 = "data:image/png;base64,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"; var icon2 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACa0lEQVR42oWTXUhTYRjH/+/50H1mZ/kRs5WstTKCcsFiTIVYUETUneAupEAqwSuD2obJokS78WawLrppu+uiSymCwFr2ceEcQoWM/MjK2odzNfd1ds7pbKCo2Py/HHh5nuf9v7/znOcQrKvP0sY1NPgMXJOdpiiRgCQAIsqZ2qxY4BZXlmdyyfR1+Kc+YpPIxu72mYtWm328y3IOGqpWzpCNgoV8AoHpF8XU1+/OnOvls50NZOked30622ZrtXBGoqBYSPLKCEWE5qbzodDEg+L9N8PYJrI9oAt0xy+1ddaf0BhQhIDX32YwEZp4wt99dQ07iGiGL3hMzS23GImUqQWVsYkz6wyMSdWIoiTg7coslheW0sKffOlHfDm46hof2GJwyO+MOh1XTJxCAwZU5SmKJZQksVKQD06hmoje1zVrs9nMsZ+/0cDppMONBqKU3z/B/0V07Rfs4wX09PTseDgYDILU3HP0quu0/alYclS9V9t92ma9rFGpEUnNI5ZJYTBytGJQLt6s9RiBy27B6GS4Eh3q9NWdaunnlRSy2SzAUvCGj1Un2BIZ7PDjYF0f9inl8WHAsCwG3xt3IXC390KSwhUKT/sjGPbchF4LSlkLDa3AQEi/C8GIY46oaiRpNbcENXsEzVo9WBpE/qw1NAP3jLk6ARk7/5k9vr+1lC1ALPCQaYD51HNk+AhoAi/jcFcloIc6MqL1gFqi5HbwAhCXmxdNXsXDd4FykdfrlaoSUHccomivJ2AZ+UIKdLYE/kvsqZRcu4GxD+l1g//3wNMZhYo2leeYVH4OApEX0ijwJzEyuVg2qDaJ/wCoeQGVklbGmAAAAABJRU5ErkJggg=="; var icon3 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAB3RJTUUH1wcREBAg9OD7NAAAAAlwSFlzAAAewQAAHsEBw2lUUwAAAARnQU1BAACxjwv8YQUAAAH6SURBVHjaxVNBaxNBFP4mGRNp06bSaGu9qXhRLOSQX6Dg0d48SMWC4Mmbv8AfYA7Sgp6UgteCF29CKahBsKKWglgam4rRxGxiks3u7Mz6zZIlSVHRk7N8vLcz7/vemzczwP8eorSCgtLJJeXpUGtMBQHgK5RptxbuYJUx5o8CL5bx+OzCkyuZ2cLIwtPihbVW9a1GiCyFQyusFD4S2zfv4x5DtI2TAphOZk8zbXFE4NKt5ctInDmY8OLd6zNrtI+IlhURG0Xs55dezZXXF9Gq7CA9NQvNbAH19W/wo+6gWXeaN1aQkybEXLv2Bb36Z+SvfUAynYLgB9Y+GLEv6Sl4HTdcvX0yy4kZqdkit1nFWC4Pme4ydvMXxNiOwwTfIVP5OCBlK0Cv8Y4C5xnXYM+bB0ixTwjWHwpUdzbh+ijZSWlYQefrcxwrLJJcIZxRAWM33qP1KTCOwJ9ErbyLno8trvqRgOrsITV5ik6pT2IXvbZdINmjVr8CmYMx09h7/8wKMBtUtIWgu4/DE8e5lxob4pLsDkhhvxJrjYfE2Am065/Et1ZUQRAJTBxJIDQJZrgKZDiRwYA03AlxCF1Ho92oYGM7ElCS5/qmVjXzLx+cg71tMex5D/8Pw+ng4etd2GYpER0ucJRI26v9l2/Ivg82CI2YIP+BPCyifwI91AzKs/qQkQAAAABJRU5ErkJggg=="; var icon4 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC5UlEQVR4AWIgFvxfaXzz/0tNC5wKbgpHCINoS9V+NW2TpVNlnPfc5Q0CsEkOwHItURRd3bfHeBh927Zt27Zt27Zt2/6xbdvJWFcnj8Xsqo1C42Ccw/mLnfNeeH2R5PcRWbG/J7+vcbC8GE3QAwPQP3L1DsnwlAcOWOv+waVg5F4dMdbu2Un8GlwX0nHO3vazHDoOGC07b/aHBEb8CLVj6MXw1HmvLVzvAJm89V7S/9B9ZdGV68gD11wtXLZcuNuW/kN2FckfIFI4usOPFn/5/iITEqcC6J+514St8oGpQIFNkovYIzORXNtinFqMtSOLwFJ8u+BQ8GaC73fQQ/lh3OSGnwDokGlc2GrVN7KUB6EOht0O+jyg3mHM2oegFTw1+UpmLbfBng6uB56L0SktY7IPGaPdcy3toZSA6WHQ46PQnlw//gH8lAtWis2//JvZh+9Btr0AZmPwBJHYZUZgNQEAXE8zc0GafrVdeWHFqdTDFqgKEKPhtXHmH0/z567nQ6YOwY1QEmyzzmLfO1LRZbF4sMw8FUJ8xZ+lrRhd3gwU4AtuE6RappavcdPun4LTBBtwLWVsLzSy6YYPdf0AKa9B3FR5eLtP2d8fQm7tEuGsx3V97qXvzDXZev3hEADyAAUQ3zXAwIqdOLTjEhJ2HQlAOZ9g69XmsrCU5LVhR7F0oZAsTOS+8z+CAlADxAWKX2vgg0K9zS3bCTw7gCobwhXNp/225+5PjqfvoAxru/34+pzn2CM1HfJAHSh7QrlxJQAdu/DIuNazpbje3iKbbS1y4PoiZ2dFboqJPKFFXkXk3Q6+38O3EP/JUAlAAwB3L6qs8cPyWoa6HYXFHVwQg/lxmJPoyGFYoiEPrFAdNL5fCJ4BoIDeX5hkuHD/2i0zb8vGFutIsAbpOrQ1oMWGmEPNMYgEh8WilUPVy8UVrAp9Q9dtOCNzwtPFdfee4G6yXVO23kLslbNU/v3cSvHRZVOdcnT1ADucXxaSvokQAAAAAElFTkSuQmCC"; function jarLoaded(e) { var val = gURLBar.value; if(val.search(/(file|jar):/) == 0 && val.search(/\.(ja|jar|xpi|zip)$/i) > -1) loadURI("jar:" + val + "!/"); } function jarClicked(e) { if(e.button == 0) { var tabUrl = gURLBar.value; if(tabUrl.search(/(file|jar):/) == 0 && tabUrl.search(/\/$/) > -1 || tabUrl.search(/view-source:/) == 0) { var node = e.target.href; if(node && node.search(/\.(exe|dll|sqlite|sqlite-shm|sqlite-wal)$/i) == -1) { if(tabUrl.search(/view-source:/) == 0 && node.search(/view-source:/) == 0 || node.search(/\.(ja|jar|xpi|zip)$/i) > -1) { e.preventDefault(); e.stopPropagation(); br.selectedTab = br.addTab(node); } else if(node.search(/\/$/) == -1) { e.preventDefault(); e.stopPropagation(); br.selectedTab = br.addTab("view-source:" + un(node)); }}}}} function intf(drives, count) { var data = '<?xml version="1.0"?>'; data += '<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>'; data += '<window title="' + btn.label + '" onload="self.load()" xmlns="' + xulns + '">'; data += '<keyset>'; data += '<key keycode="VK_ESCAPE" oncommand="close()"/>'; data += '</keyset>'; data += '<vbox flex="1">'; data += '<richlistbox id="listbox" flex="1" >'; data += '<listcols>'; data += '<listcol/>'; data += '<listcol flex="1" />'; data += '</listcols>'; data += '</richlistbox>'; data += '<hbox>'; data += '<button image="' + icon2 + '" label=" Add-on" oncommand="self.addon(event)" tooltiptext="Ctrl+ = Без закрытия диалога"/>'; data += '<button image="' + img2 + '" label=" 1 omni.ja" oncommand="self.omni(event)" tooltiptext="Ctrl+ = Без закрытия диалога"/>'; data += '<button image="' + img2 + '" label=" 2 omni.ja" oncommand="self.omni1(event)" tooltiptext="Ctrl+ = Без закрытия диалога"/>'; data += '<button image="' + icon4 + '" label=" Firefox" oncommand="self.folder(event,' + "'GreD'" + ')" tooltiptext="Ctrl+ = Без закрытия диалога"/>'; data += '<button image="' + icon3 + '" label=" Профиль" oncommand="self.folder(event,' + "'ProfD'" + ')" tooltiptext="Ctrl+ = Без закрытия диалога"/>'; data += '<button label="Закрыть" oncommand="self.close()"/>'; data += '</hbox>'; data += '<hbox>'; for(i = 0; i < count; i++) data += '<button image="' + icon1 + '" label=" ' + drives[i] + '" oncommand="self.mydrives(event,' + "'" + drives[i] + "'" + ')" tooltiptext="Ctrl+ = Без закрытия диалога"/>'; data += '</hbox>'; data += '</vbox>'; data += '</window>'; return data.replace(/self/g, "opener.document.getElementById("" + self.id + "")"); } this.load = function() { if(!("AddonManager" in window)) Components.utils.import("resource://gre/modules/AddonManager.jsm"); if(!("Services" in window)) Components.utils.import("resource://gre/modules/Services.jsm"); var then, promise = AddonManager.getAddonsByTypes(["extension"], then = function(addons) { var list = new Array(); addons.forEach( function(addon) { list.push(addon); }); var options = { addonTypes: ["extension"] }; function key(addon) { return options.addonTypes.indexOf(["extension"]) + "\n" + addon.name.toLowerCase(); } list.sort( function(a, b){ var ka = key(a); var kb = key(b); return ka == kb ? 0 : ka < kb ? -1 : 1; }); for(var i = 0; i < list.length; i++) { var item = document.createElement("richlistitem"); var cell = document.createElement("treecol"); cell.setAttribute("label", list[i].name); item.appendChild(cell); dialog.document.getElementById("listbox").appendChild(item); dialog.document.getElementById("listbox").focus(); dialog.document.getElementById("listbox").selectAll(); } }); promise && typeof promise.then == "function" && promise.then(then, Components.utils.reportError); // Firefox 61+ } this.addon = function(e) { if(!("AddonManager" in window)) Components.utils.import("resource://gre/modules/AddonManager.jsm"); if(!("Services" in window)) Components.utils.import("resource://gre/modules/Services.jsm"); var name = dialog.document.getElementById("listbox").selectedItem.firstChild.getAttribute("label"); //AddonManager.getAddonsByTypes(["extension"], function(addons) { var then, promise = AddonManager.getAddonsByTypes(["extension"], then = function(addons) { addons.forEach( function(addon) { if(addon.name == name) { var uri = addon.getResourceURI(); var file = uri.QueryInterface(Ci.nsIFileURL).file; if(file.isDirectory()) br.selectedTab = br.addTab(uri.spec); else br.selectedTab = br.addTrustedTab("jar:" + uri.spec + "!/"); }});}); if(!e.ctrlKey) dialog.close(); promise && typeof promise.then == "function" && promise.then(then, Components.utils.reportError); // Firefox 61+ } this.omni1 = function(e) { //var file = Services.dirsvc.get("GreD", Ci.nsIFile); var profileDir = Components.classes["@mozilla.org/file/directory_service;1"] .getService(Components.interfaces.nsIProperties) .get("GreD", Components.interfaces.nsIFile) .path; var file = profileDir + "\\browser\\omni.ja"; var vert="jar:" + "file:///" + file + "!/"; br.selectedTab = br.addTrustedTab(vert); if(!e.ctrlKey) dialog.close(); } this.omni = function(e) { var file = Services.dirsvc.get("GreD", Ci.nsIFile); file.append("omni.ja"); var uri = Services.io.newFileURI(file); br.selectedTab = br.addTrustedTab("jar:" + uri.spec + "!/"); if(!e.ctrlKey) dialog.close(); } this.folder = function(e, shortcut) { var uri = Services.io.newFileURI(Services.dirsvc.get(shortcut, Ci.nsIFile)); br.selectedTab = br.addTrustedTab(uri.spec); if(!e.ctrlKey) dialog.close(); } this.mydrives = function(e, letter) { br.selectedTab = br.addTrustedTab("file:///" + letter + "/"); if(!e.ctrlKey) dialog.close(); } this.close = function() { dialog.close(); } Cu.import("resource://gre/modules/FileUtils.jsm"); var root = new FileUtils.File("\\\\."); var drivesEnum = root.directoryEntries; drives = []; while (drivesEnum.hasMoreElements()) { drives.push(drivesEnum.getNext().QueryInterface(Ci.nsIFile).path); } count = drives.length; var url = "data:application/vnd.mozilla.xul+xml;text/plain," + encodeURIComponent(intf(drives, count)); var feature = "chrome,centerscreen,width=580,height=410,alwaysRaised"; dialog = window.openDialog(url, "", feature); //dialog = window.openDialog(url, document.nodePrincipal, "", feature); this.onDestroy = function(reason) { if(reason == "update" || reason == "delete") { br.removeEventListener("click", jarClicked, false); br.tabContainer.removeEventListener("TabSelect", jarLoaded, false); if(reason == "delete") try { this.PS.clearUserPref(unzp); } catch (e) {} }}
Отредактировано Andrey_Krropotkin (31-01-2019 14:32:58)
Отсутствует
А с richlistbox, listcol и richlistitem то же что изменили?
А причём здесь они? Проблемы с отображением у treecol'ов,
которым в richlistbox'е делать нечего, даже хотя бы исходя из названия.
И вообще как-то наворочено, может будь проще
/* for(var i = 0; i < list.length; i++) { var item = document.createElement("richlistitem"); var cell = document.createElement("treecol"); cell.setAttribute("label", list[i].name); item.appendChild(cell); dialog.document.getElementById("listbox").appendChild(item); dialog.document.getElementById("listbox").focus(); dialog.document.getElementById("listbox").selectAll(); } */ var box = dialog.document.getElementById("listbox"); for(var addon of list) box.appendItem(addon.name, "").addon = addon; box.focus(); }); promise && typeof promise.then == "function" && promise.then(then, Components.utils.reportError); // Firefox 61+ } this.addon = e => { var item = dialog.document.querySelector("richlistitem[selected]"); var uri = item.addon.getResourceURI(); var file = uri.QueryInterface(Ci.nsIFileURL).file; uri = file.isDirectory() ? uri.spec : "jar:" + uri.spec + "!/"; if (!e.ctrlKey) { dialog.close(); dialog = null; } br.selectedTab = br.addTrustedTab(uri); } /* this.addon = function(e) { if(!("AddonManager" in window)) Components.utils.import("resource://gre/modules/AddonManager.jsm"); if(!("Services" in window)) Components.utils.import("resource://gre/modules/Services.jsm"); var name = dialog.document.getElementById("listbox").selectedItem.firstChild.getAttribute("label"); //AddonManager.getAddonsByTypes(["extension"], function(addons) { var then, promise = AddonManager.getAddonsByTypes(["extension"], then = function(addons) { addons.forEach( function(addon) { if(addon.name == name) { var uri = addon.getResourceURI(); var file = uri.QueryInterface(Ci.nsIFileURL).file; if(file.isDirectory()) br.selectedTab = br.addTab(uri.spec); else br.selectedTab = br.addTrustedTab("jar:" + uri.spec + "!/"); }});}); if(!e.ctrlKey) dialog.close(); promise && typeof promise.then == "function" && promise.then(then, Components.utils.reportError); // Firefox 61+ } */
Отредактировано Dumby (31-01-2019 19:16:11)
Отсутствует
Dumby спасибо да действительно так лучше, а еще также спасибо за DOM Inspector
Отсутствует
Как сделать динамическую ширину вкладок (табов) из кода [CB] или userChrome.css?
Есть ли работающий код? Расширение TabMix у меня НЕ установлено (оно мне не нужно).
Дано: панель вкладок сверху, она может быть в одну/несколько строк. Браузер: Basilisk 2018.12.18.
Надо: ширину табов к примеру от 350 до 50 пикселей, ширина уменьшается в зависимости от количества открытых вкладок.
При переполнении табов появляется следующая строка панели вкладок - это уже решено и работает в CSS-стиле.
Я сделал код [CB], но проявляется эффект: при открытии последней вкладки мелькает вторая строка панели вкладок, затем ширина табов уменьшается и 2 строка пропадает.
function TabCollapsed() { try { window.clearTimeout(TabCollapsed.timeout) } catch(e) {}; TabCollapsed.timeout = window.setTimeout(()=> { var tabbrowser = document.getElementById('tabbrowser-tabs'); var Tabs = gBrowser.tabs.length; const maxTabs = 16, maxTabWidth = 320; Tabs = Math.min(Tabs, maxTabs); // возвращает минимальное число из группы чисел document.getElementById("TabsToolbar").collapsed = (Tabs == 1); if ( Tabs == 1 ) return; var tabWidth = Math.min(( tabbrowser.clientWidth - (48 + maxTabs) ) / Tabs, maxTabWidth); // вычислить ширину вкладки custombuttons.setPrefs('browser.tabs.tabMaxWidth', tabWidth); custombuttons.setPrefs('browser.tabs.tabMinWidth', tabWidth); }, 50); }; addEventListener("TabOpen", function() {TabCollapsed(true)}, false, gBrowser.tabContainer); addEventListener("TabClose", function() {TabCollapsed(false)}, false, gBrowser.tabContainer); setTimeout(function() TabCollapsed(false), 1000); // старт браузера
Отсутствует
Вопрос у вас в Clipboard такой код? я там немного добавил BBCode(вроде он вообще не пашет), в самом Clipboard попап есть но не копируется.
Если будет время займусь может смогу с моим скудным знанием что-то сделать.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Блок инициализации глоб. переменных и функций // срок существования - один сеанс браузера //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // bbBBCodeStat=true // разрешить/включить BBCode window.arycb_BBCodeClipboardStrings = this.clipboardStrings = []; // Массив буфера обмена // //******************************************************** //--------Общие функции для вставки BBCode---------------- //********************************************************* //++++++++++++++++++BEGIN DEF++++++++++++++++++++++++++++++ //-------------------------------------------------------- // Функция lb_BBCodePrim // [bbCode]выделенный[/bbCode] // по умолчанию от ЛКМ) lb_BBCodePrim = function (open,close){ var theBox = document.commandDispatcher.focusedElement; var startPos = theBox.selectionStart; var endPos = theBox.selectionEnd; var oPosition = theBox.scrollTop; var oHeight = theBox.scrollHeight; var text=theBox.value.substring(0,startPos); text +=open+theBox.value.substring(startPos, endPos)+close; text +=theBox.value.substring(endPos, theBox.value.length); theBox.value = text; var nHeight = theBox.scrollHeight - oHeight; theBox.scrollTop = oPosition + nHeight; }; //--------------------------------------------------------- // Функция mb_BBCodePrim // Резерв // по умолчанию от CКМ mb_BBCodePrim = function (open,close) {}; // ------------------------------------------------------- // Функция rb_BBCodePrim // [bbCode]параметр PASTE по умолчанию из буфер обмена[/bbCode] // по умолчанию от ПКМ rb_BBCodePrim = function (open,close,paste){ if (paste == undefined) { open +=close;} //буфер обмена пуст else { open +=paste+close;} var theBox = document.commandDispatcher.focusedElement; var startPos = theBox.selectionStart; var endPos = theBox.selectionEnd; var selectionLen = endPos - startPos var oPosition = theBox.scrollTop; var oHeight = theBox.scrollHeight; var text=theBox.value.substring(0,startPos); var nHeight = theBox.scrollHeight - oHeight; text +=open; text +=theBox.value.substring(endPos, theBox.value.length); theBox.value = text; theBox.selectionStart = endPos + open.length; theBox.selectionEnd = endPos + open.length - selectionLen; theBox.scrollTop = oPosition + nHeight; }; // ------------------------------------------------------- // Функция fHLD_Get_ListClipboardPrim // получить список сохранёного буфера обмена // fnHLD_Get_ListClipboardPrim = function (){ var cs = arycb_BBCodeClipboardStrings; return (cs.slice(0)); }; //++++++++++++++++++END DEF+++++++++++++++++++++++++++++++++++ //Список сохранёного буфера обмена //Не вызываем это, обработка по таймеру или по событию ЛКМ //-----Обработчики буфера обмена this.MAX_ENTRIES = 5; //Максимальное число записей 5 this.CHECK_INTERVAL = 1000; //Время опроса буфера 1000 миллисекунд this.type = "menu"; this.orient = "horizontal"; this._menupopup = this.appendChild(document.createElement("menupopup")); this._menupopup.setAttribute("oncommand", "this.parentNode.handleCommand(event.target);"); this.checkClipboard = function() { var clipStr = readFromClipboard(); if(clipStr && this.clipboardStrings.indexOf(clipStr) == -1) this.storeString(clipStr); }; this.storeString = function(str) { var cs = this.clipboardStrings; cs.push(str); while(cs.length > this.MAX_ENTRIES) cs.shift(); var mi = document.createElement("menuitem"); mi.setAttribute("label", str); this._menupopup.appendChild(mi); while(this._menupopup.childNodes.length > this.MAX_ENTRIES) this._menupopup.removeChild(this._menupopup.firstChild); }; this.handleCommand = function(mi) { var indx = Array.indexOf(mi.parentNode.childNodes, mi); if(indx != -1) this.insertText(this.clipboardStrings[indx]); }; this.insertText = function(str) { var cmd = "cmd_insertText"; var controller = document.commandDispatcher.getControllerForCommand(cmd); if(controller && controller.isCommandEnabled(cmd)) { controller = controller.QueryInterface(Ci.nsICommandController); var params = Cc["@mozilla.org/embedcomp/command-params;1"] .createInstance(Ci.nsICommandParams); params.setStringValue("state_data", str); controller.doCommandWithParams(cmd, params); } }; setInterval(function(button) { button.checkClipboard(); }, this.CHECK_INTERVAL, this); this.setAttribute("onpopupshowing", "this.checkClipboard();");
Отредактировано func4ptch4 (03-02-2019 21:35:28)
Отсутствует
Dumby
Привет! Такая проблема : добавить ссылку в закладки , в 61 еще работает, т.е. favicon появляется . В 64 уже нет,только дефолтная.
Где поганка зарыта? Какое JS ковырять? или JSM ? Заманали они своими шарадами...
Отредактировано drage2 (04-02-2019 22:24:22)
Отсутствует