Dumby спасибо.
Кнопка управлением масштабом. работает на и 61 и 63
/*Initialization Code*/ // Кнопка для управления масштабом страницы в адресной строке, от 27.11.2017. .......................... (()=> { // Удалить из адресной строки FF51 стандартную кнопку масштаба .... var but = document.getElementById('urlbar-zoom-button'); if (but) but.style.display = "none"; // Создать в адресной строке кнопку масштаба .... var zoomButton = document.createElement("label"); var urlbarIcons = document.getElementById("urlbar-icons") || document.getElementById("page-action-buttons"); // FF57 urlbarIcons.insertBefore(zoomButton, urlbarIcons.lastChild); // перед последней кнопкой адресной строки addDestructor(()=> zoomButton.remove()); updateZoomButton(); zoomButton.id = "zoomButton"; zoomButton.setAttribute("context", "event.stopPropagation()"); zoomButton.style.cssText = "-moz-appearance: none; border: 0; margin-right: -1px;"; // Css стиль для кнопки масштаба zoomButton.tooltipText = "Л: Менять масштаб страницы или только текста\n Жирный - только текст\nС: Единый масштаб для всех страниц - Красный цвет\nП: Сбросить масштаб на 100% \nКолесиком: менять масштаб"; // Показывать текущий масштаб страницы на кнопке и изменять цвет и шрифт отображения масштаба .... function updateZoomButton(e) { zoomButton.value = Math.round(ZoomManager.zoom*100) + "%"; setTimeout(()=> { zoomButton.style.fontWeight = ZoomManager.useFullZoom ? '' : 'bold'; zoomButton.style.color = cbu.getPrefs("CB.zoom.allEvenly") ? "red" : ""; }, 5); // запомнить текущий масштаб в 'about:config' if ( e == undefined ) { try { window.clearTimeout(zoomButton.prefTimeout) } catch(e) {}; zoomButton.prefTimeout = window.setTimeout(()=> { cbu.setPrefs("CB.zoom.Percent", ZoomManager.zoom.toFixed(2) ) }, 250); } }; // Отслеживать клики на кнопке масштаба .... addEventListener("click", e=> { if ( e.button == 0 ) ZoomManager.toggleZoom(); // переключить режим изминения масштаба if ( e.button == 1 ) { // единый масштаб для всех страниц cbu.isPref("CB.zoom.allEvenly", false); cbu.setPrefs("CB.zoom.allEvenly", !cbu.getPrefs("CB.zoom.allEvenly") ); cbu.setPrefs("CB.zoom.Percent", ZoomManager.zoom.toFixed(2) ); } if ( e.button == 2 ) FullZoom.reset(); // сбросить масштаб updateZoomButton(); }, false, zoomButton); // Менять масштаб колесиком мыши на кнопке масштаба .... addEventListener("DOMMouseScroll", e=> { e.detail > 0 ? FullZoom.reduce() : FullZoom.enlarge(); }, false, zoomButton); // Следим за изменением масштаба и запускаем обновление кнопки .... var hidden = Object.getOwnPropertyDescriptor(XULElement.prototype, "hidden"); Object.defineProperty(but, "hidden", { configurable: true, enumerable: true, get: hidden.get.bind(but), set: val => { Components.stack.formattedStack.includes("LocationChange") || setTimeout(updateZoomButton, 50); return hidden.set.call(but, val); } }); addDestructor(() => delete but.hidden); // Устанавливать единый масштаб для всех страниц если это разрешено в 'about:config' .... addEventListener("TabAttrModified", e=> { if ( e.target.linkedBrowser.currentURI.spec !== gBrowser.currentURI.spec ) return; if ( cbu.getPrefs("CB.zoom.allEvenly") && content.location.protocol.startsWith("http") ) { var value = cbu.getPrefs("CB.zoom.Percent"); if ( ZoomManager.zoom.toFixed(2) == value ) return; setTimeout(()=> { gBrowser.markupDocumentViewer[ZoomManager.useFullZoom ? 'fullZoom' : 'textZoom'] = value; updateZoomButton(e); }, 0); } else updateZoomButton(e); }, true, gBrowser.tabContainer); })();
Отсутствует
Dumby еще несколько маленьких вопросов по 63
не работает вот такой код, ссылается в консоли на nsPIPlacesDatabase
function inf211(){ with(Components.classes["@mozilla.org/browser/nav-history-service;1"] .getService(Components.interfaces.nsPIPlacesDatabase) .DBConnection.mozIStorageConnection .createStatement('SELECT count(fk) FROM moz_bookmarks') ) { step(); bkmcnt=getInt32(0); finalize(); } alert("Общее количество закладок="+bkmcnt) }
// Сохранить как PNG страницу или части страницы ............. WebScreenShot = { capture: function(win, x, y, width, height) { //const xhtmlns = 'http://www.w3.org/1999/xhtml'; var canvas = document.createElementNS(xhtmlns, 'canvas'); canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); ((i = 17)=> { try { ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white") } catch(e) { canvas.height = canvas.width*i; arguments.callee(--i) }; })(); var url = makeURI(canvas.toDataURL("image/png")); var fp = window.makeFilePicker(); fp.init(window, "Сохранить как…", fp.modeSave); fp.appendFilter("", "*.png"); // fp.defaultString = getTabLabel() + " " + (new Date().toLocaleFormat("%d.%m.%Y. %H:%M:%S")) + ".png"; fp.defaultString = getTabLabel() + ".png"; fp.open(res => { if (res == fp.returnCancel || !fp.file) return; var save = window.makeWebBrowserPersist().saveURI; save.length < 8 ? save(url, null, null, null, null, fp.file, null) : save(url, null, null, null, null, null, fp.file, null); }); }, 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); }, 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); // удалить стиль когда подсказка закрывается }, ""); } };
и вот еще говорит не функция:
var p = document.createElement("tooltip");
var tooltip = gBrowser.appendChild(p);
Отредактировано Andrey_Krropotkin (23-12-2018 18:26:12)
Отсутствует
ссылается в консоли на nsPIPlacesDatabase
Его втащили в nsINavHistoryService. Вот так, вроде, алертится
var statement = PlacesUtils.history.DBConnection .createStatement("SELECT count(fk) FROM moz_bookmarks"); statement.executeStep(); var bkmcnt = statement.getInt32(0); statement.finalize(); alert("Общее количество закладок=" + bkmcnt);
код ссылается на нехватку аргументов
Вау, и здесь сунули свой triggering principal .
Читаем idl'ку. У меня вот так записывает
var file = Services.dirsvc.get("TmpD", Ci.nsIFile); file.append("bla.txt"); makeWebBrowserPersist().saveURI( makeURI("data:text/plain,blabla"), document.nodePrincipal, null, null, null, null, null, file, null ); setTimeout(file.reveal, 500);
показывает на ошибку в этой строке
var editor = ta.QueryInterface(Components.interfaces.nsIDOMNSEditableElement)
Не квериинтерфейсь того, чего нет.
и вот еще говорит не функция:
var p = document.createElement("tooltip");
var tooltip = gBrowser.appendChild(p);
Правильно говорит, gBrowser не Node уже давно.
Отсутствует
Dumby
Могли бы Вы, если не сложно, добавить в кнопку Autocopy работающую в 63+, функцию замены выделенного текста вставляемым по СКМ? Это было весомым её преимуществом перед остальными автокопирами. И сделать отдельной кнопкой функцию сохранения изображений без запроса по двойному ПКМ на них? Или починить "старую" версию, если так проще, к сожалению, bunda1 давно не отвечает в личке, надеюсь, он ещё вернётся на форум.
Вот этих функций очень не хватает:
3. Даёт возможность средней кнопкой мыши вставлять текст из буфера обмена с заменой выделенного текста в текстовые полях и поисковых формах на страницах и также в адресной строке и строке поиска браузера и поисковых формах браузера которые открываются как страница, например поисковой форме в about:config и также редакторе в Custom Buttons. Эту возможность надо включать в настройках кнопки.
4. Даёт возможность копировать адрес страницы если кликнуть правой клавишей мыши на значке идентификации сайта в строке адреса, при этом значок идентификации сайта мигает красным или открыть без запроса информацию о странице Разрешения если кликнуть левой клавишей мыши.
6. Даёт возможность без запроса сохранять изображения на странице в папке загрузки двойным правым кликом мыши, если эта возможность включена в настройках кнопки.
/*Initialization Code*/ this.closest("toolbarpaletteitem") || (script => { var id = `CB${_id.slice(20)}:Autocopy`, pid = id + "Parent"; var nsvoStr = `Components.utils.import("resource://gre/modules/Services.jsm", {})`; var nsvo = eval(nsvoStr), {Services} = nsvo, parent = nsvo[pid]; if (!parent) { var cid = id + "Child", u = code => "data:," + encodeURIComponent(code); var pref = "CB.Autocopy.settings", topic = "quit-application-granted"; var PREF_ENABLED = 1, PREF_BLINK = 2, PREF_RESET = 4; (parent = nsvo[pid] = { init() { this.readSettings(); if (!this[PREF_ENABLED]) return; this.initChild(); if (this[PREF_RESET]) this.setObserver(true); }, destroy(reason) { var ud = reason[5] == "e"; if (ud || !this.obsAdded) this.saveSettings(); delete nsvo[pid]; if (reason == "delete") Services.prefs.clearUserPref(pref); if (!this[PREF_ENABLED]) return; this.destroyChild(); if (ud && this[PREF_RESET]) this.setObserver(false); }, get processURL() { delete this.processURL; this.frameURL = u(`${nsvoStr}["${cid}"].init(this);`); return this.processURL = u(script.replace(/%ID%/g, cid) .replace("%NSVO%", nsvoStr).replace("%BLINK%", this[PREF_BLINK]) ); }, get frameURLDestroy() { delete this.frameURLDestroy; this.processURLDestroy = u(`${nsvoStr}["${cid}"].forget();`); return this.frameURLDestroy = u(`${nsvoStr}["${cid}"].destroy(this);`); }, initChild() { Services.ppmm.loadProcessScript(this.processURL, true); Services.mm.loadFrameScript(this.frameURL, true); }, destroyChild() { Services.mm.removeDelayedFrameScript(this.frameURL); Services.mm.loadFrameScript(this.frameURLDestroy, false); Services.ppmm.removeDelayedProcessScript(this.processURL); Services.ppmm.loadProcessScript(this.processURLDestroy, false); }, readSettings() { this.prefVal = Services.prefs.getIntPref(pref, 3); for(var setting of [PREF_ENABLED, PREF_BLINK, PREF_RESET]) this[setting] = Boolean(this.prefVal & setting); }, saveSettings() { var settings = 0; for(var setting of [PREF_ENABLED, PREF_BLINK, PREF_RESET]) if (this[setting]) settings += setting; if (this.prefVal != settings) Services.prefs.setIntPref(pref, settings); }, btns: new Set(), register(btn) { this.btns.add(btn); btn._handleClick = this.click; btn.oncontextmenu = this.context; this.setImg(btn, this[PREF_ENABLED]); }, unregister(btn, reason) { this.btns.delete(btn); if (!this.btns.size) this.destroy(reason); }, setImg(btn, state) { btn.ownerDocument.getAnonymousElementByAttribute( btn, "class", "toolbarbutton-icon" ).src = state ? "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgMBAAQIAAcEBwAIBAcACAQHAAgEBwAIBAcACAQHAAgEBwAIBAcACAMEAQEAAAAAAAAAAAAAAAACAwADAAAAABUnAB9cqgC3a7wB4Gq5Ad1qugHearoB3mq6Ad5qugHearoB3mi4AN1qugHgYrMAxR43AC8AAAAAAAEAAAECAAQAAAQAV6AAprP9Vv/W/qn80/+f/9T/ov/U/6L/1P+i/9T/ov/U/6L/1/+n/9X+pfy3/WL/Y7QAvwEAAQAAAAAAFSgAH1ehAKlyzwD1htgf/YzcJ/2K2yP9i9sk/YvbJf2L2yX9i9sm/YnaIv2b4kP92/21/Nf+qv9quwHdBQkACAAAAQBeqwCzr/tR/8X0j/u+8X//vvJ//77ygP++8oD/vvKA/77yf/+98n7/wvSH/4zcKv+e4kv93v+0/2i5AN0DBwAIBQkACGu8AdzV/af/4v/B/d//u//h/7//4f+//+H/v//h/7//4f+//9/+u//n/8n/w/GK/4zaK/3g/7r/aroC3gMHAAgEBwAIarkC3dX/pf/g/sD93v67/9/+vv/g/r//4P6//+D+v//f/r7/3f66/+T/xv/B8Yb/j9st/eT/w/9qugPeAwcACAQHAAhqugLe2v+w/+j/z/3l/8r/5//N/+f/zv/n/87/5//O/+f/zf/l/sj/7P/W/8Xyj/+Q2y/96f/N/2q6A94DBwAIBAcACGq6At7f/7n/7v/c/ev/1v/t/9n/7f/a/+3/2v/t/9r/7f/Z/+r+1f/y/+P/yPKW/5DbMf3s/9X/aroE3gMHAAgEBwAIaroC3uP/wf/z/+j98P/h//L/5P/z/+X/8//l//P/5f/y/+T/8P7g//j/7v/L8p3/kdsy/fD/3P9rugTeAwcACAQHAAhqugLe5v/J//j/8v31/+r/9v/t//f/7v/3/+//9//u//b/7f/0/un//f/4/87yo/+R2zL98f/f/2q5Bd0DBwAIBAcACGq6At7p/8///P/6/fj/8f/6//T/+v/1//r/9f/6//X/+v/0//f+8P//////0fGo/5PbNf30/+f/a7wE3AQJAAgEBwAIabkC3er/0f/+//79+v/0//v/9//8//j//P/4//z/+P/7//f/+f70///////T8qz/i9go+8P9ef9dqwCzAAACAAUJAAhquwHd7f7a//////z+//39/////f////3////9/////f////39/vz9/////dzzvv5v0AD1VqECqRUnAB8AAAAAAQACAGK0AL/J/Yf/8v7k/O3/1//u/9n/7v/Z/+7/2f/u/9n/7v/Z/+3/1//x/eP8vfxu/1WgAKYAAAUAAQIABAABAAAAAAAAHjcALmGzAMVquwLgarkC3Wq6At5qugLearoC3mq6At5qugLearkC3Wu8AeBbqgC3FScAHwAAAAACAwADAAAAAAAAAAAAAAAAAwQCAQQIAAgEBwAIBAcACAQHAAgEBwAIBAcACAQHAAgEBwAIBAgABwMDAgAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" : "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgEDAAQACAcEAAcIBAAHCAQABwgEAAcIBAAHCAQABwgEAAcIBAAHCAMBBAEAAAAAAAAAAAAAAAACAAMDAAAAABUAJx9cAKq3awG84GoBud1qAbreagG63moBut5qAbreagG63mgAuN1qAbrgYgCzxR4ANy8AAAAAAAABAAEAAgQABAAAVwCgprNW/f/Wqf7805///9Si///Uov//1KL//9Si///Uov//16f//9Wl/vy3Yv3/YwC0vwEBAAAAAAAAFQAoH1cAoalyAM/1hh/Y/Ywn3P2KI9v9iyTb/Ysl2/2LJdv9iybb/Yki2v2bQ+L927X9/Neq/v9qAbvdBQAJCAABAABeAKuzr1H7/8WP9Pu+f/H/vn/y/76A8v++gPL/voDy/75/8v+9fvL/wof0/4wq3P+eS+L93rT//2gAud0DAAcIBQAJCGsBvNzVp/3/4sH//d+7///hv///4b///+G////hv///4b///9+7/v/nyf//w4rx/4wr2v3guv//agK63gMABwgEAAcIagK53dWl///gwP793rv+/9++/v/gv/7/4L/+/+C//v/fvv7/3br+/+TG///BhvH/jy3b/eTD//9qA7reAwAHCAQABwhqArre2rD//+jP//3lyv//583//+fO///nzv//587//+fN///lyP7/7Nb//8WP8v+QL9v96c3//2oDut4DAAcIBAAHCGoCut7fuf//7tz//evW///t2f//7dr//+3a///t2v//7dn//+rV/v/y4///yJby/5Ax2/3s1f//agS63gMABwgEAAcIagK63uPB///z6P/98OH///Lk///z5f//8+X///Pl///y5P//8OD+//ju///LnfL/kTLb/fDc//9rBLreAwAHCAQABwhqArre5sn///jy//316v//9u3///fu///37///9+7///bt///06f7//fj//86j8v+RMtv98d///2oFud0DAAcIBAAHCGoCut7pz////Pr//fjx///69P//+vX///r1///69f//+vT///fw/v//////0ajx/5M12/305///awS83AQACQgEAAcIaQK53erR///+/v/9+vT///v3///8+P///Pj///z4///79///+fT+///////TrPL/iyjY+8N5/f9dAKuzAAIAAAUACQhqAbvd7dr+//////z+/f/9/////f////3////9/////f////39/P79/////dy+8/5vAND1VgKhqRUAJx8AAAAAAQIAAGIAtL/Jh/3/8uT+/O3X///u2f//7tn//+7Z///u2f//7tn//+3X///x4/38vW78/1UAoKYABQAAAQACBAAAAQAAAAAAHgA3LmEAs8VqArvgagK53WoCut5qArreagK63moCut5qArreagK53WsBvOBbAKq3FQAnHwAAAAACAAMDAAAAAAAAAAAAAAAAAwIEAQQACAgEAAcIBAAHCAQABwgEAAcIBAAHCAQABwgEAAcIBAAIBwMCAwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }, click() { var newState = parent[PREF_ENABLED] = !parent[PREF_ENABLED]; for(var btn of parent.btns) parent.setImg(btn, newState); newState ? parent.initChild() : parent.destroyChild(); if (parent[PREF_RESET]) parent.setObserver(newState); }, context(e) { if (e.ctrlKey || e.shiftKey) return; if (e.detail > 1) return parent.popup.hidePopup(); if (!this.contains(parent.popup)) this.appendChild(parent.popup); e.preventDefault(); parent.popup.openPopup(this, "after_start"); }, get popup() { var win = Services.wm.getMostRecentWindow("navigator:browser"); var doc = win.document, popup = doc.createElement("menupopup"); popup.setAttribute("onclick", "event.stopPropagation();"); popup.setAttribute("oncommand", "handleCommand(event.target);"); for(var [lab, pref] of win.Object.entries({ "Выделенный текст мигает при автокопировании": PREF_BLINK, "Выключать автокопирование при выходе из браузера": PREF_RESET })) { var menuitem = popup.appendChild(doc.createElement("menuitem")); menuitem.setAttribute("label", lab); menuitem.setAttribute("type", "checkbox"); if (this[menuitem.pref = pref]) menuitem.setAttribute("checked", true); } popup.handleCommand = menuitem => { var newState = this[menuitem.pref] = menuitem.hasAttribute("checked"); if (!this[PREF_ENABLED]) return; if (menuitem.pref == PREF_BLINK) Services.ppmm.broadcastAsyncMessage(cid + ":FromParent", {blink: newState}); else if (menuitem.pref == PREF_RESET) this.setObserver(newState); } delete this.popup; return this.popup = popup; }, obsAdded: false, setObserver(set) {this.obsAdded = set ? Services.obs.addObserver(this, topic, false) : Services.obs.removeObserver(this, topic); }, observe() { Services.obs.removeObserver(this, topic); this[PREF_ENABLED] = false; this.saveSettings(); } }).init(); } parent.register(this); addDestructor(reason => parent.unregister(this, reason), parent); })(`(nsvo => (nsvo["%ID%"] = { x: -1, y: -1, d: false, handleEvent(e) {e.button || this[e.type](e);}, mousedown(e) {this.x = e.screenX; this.y = e.screenY, this.down = true;}, mouseup(e) { var {down} = this; this.down = false; if (!down) return; if (e.screenX == this.x && e.screenY == this.y && (e.detail == 1 || e.target.matches( "textarea[disabled],input[disabled],button,select,summary" ))) return; var name = e.originalTarget.nodeName; if (/^(?:(?:xul:)?(?:slider|scrollbarbutton)|resizer)$/.test(name)) return; this.x = this.y = -1; var win = this.getFocusedWin(e.target.ownerGlobal); var sel = win.getSelection(); if (sel.toString()) { (win.docShell || win.document.docShell).doCommand("cmd_copy", null, win); this.blinkEnabled && this.blink(win, e.detail > 1); } }, blinkEnabled: %BLINK%, blink(win, pause) { if (pause) return win.setTimeout(() => this.blink(win), 100); var sc = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShell) .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsISelectionDisplay) .QueryInterface(Components.interfaces.nsISelectionController); sc.setDisplaySelection(sc.SELECTION_OFF); sc.repaintSelection(sc.SELECTION_NORMAL); win.setTimeout(() => { sc.setDisplaySelection(sc.SELECTION_ON); sc.repaintSelection(sc.SELECTION_NORMAL); }, 150); }, getFocusedWin(win) { var focusedWin = {}; var elm = Services.focus.getFocusedElementForWindow(win.top, true, focusedWin); return focusedWin.value; }, get cm() { delete this.cm; return this.cm = Components.classes["@mozilla.org/embedcomp/command-manager;1"] .getService(Components.interfaces.nsICommandManager); }, count: 0, init(cfmm) { this.count += 1; cfmm.addEventListener("mousedown", this); cfmm.addEventListener("mouseup", this); cfmm.addEventListener("unload", this); if (this.count == 1) this.cpmm.addMessageListener("%ID%:FromParent", this); }, destroy(cfmm) { this.count -= 1; cfmm.removeEventListener("mousedown", this); cfmm.removeEventListener("mouseup", this); cfmm.removeEventListener("unload", this); if (!this.count) this.cpmm.removeMessageListener("%ID%:FromParent", this); }, receiveMessage(msg) { if ("blink" in msg.data) this.blinkEnabled = msg.data.blink; }, unload(e) {this.destroy(e.target);}, forget: () => delete nsvo["%ID%"] }).cpmm = this)(%NSVO%);`);
// Настройка функций кликов мыши для кнопки ................. this.onclick =e=> { if ( e.button == 0 ) cbu.setPrefs("CB.Autocopy", !cbu.getPrefs("CB.Autocopy")); if ( e.button == 2 ) { e.preventDefault(); menuPopup.showPopup(this, -1, -1, "popup", "bottomleft", "topleft"); } }; this.oncontextmenu = e => e.detail == 2 && !menuPopup.hidePopup() || e.ctrlKey || !!menuPopup.openPopup(this, "after_start"); // Создать меню ................. var array = [ { label: 'Выделять текст с пробелом справа', value: 'layout.word_select.eat_space_to_next_word' }, { label: 'Выделенный текст мигает при автокопировании', value: 'CB.Autocopy.selectingTextBlink' }, { label: 'Дополнительные возможности для адресной строки', value: 'CB.Autocopy.addToAddressBar'}, { label: 'Выключать автокопирование при выходе из браузера', value: 'CB.Autocopy.reset' }, { separator: ''}, { label: 'Двойной правый клик мыши копирует выделенный текст', value: 'CB.Autocopy.copyWithDoubleClick' }, { label: 'Двойной правый клик мыши сохраняет изображение без запроса', value: 'CB.Autocopy.saveWithDoubleClick' }, { label: 'Средним кликом вставлятъ текст с заменой выделенного текста', value: 'middlemouse.paste' }, ]; var menuPopup = self.appendChild(document.createElement("menupopup")); array.forEach(m=> { if ( "separator" in m ) { menuPopup.appendChild(document.createElement("menuseparator")); return }; var mItem = menuPopup.appendChild(document.createElement("menuitem")); mItem.setAttribute("label", m.label); mItem.setAttribute('type', 'checkbox'); mItem.setAttribute('checked', cbu.getPrefs(m.value)); mItem.onclick =e=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value)); }); menuPopup.setAttribute("onclick", "event.stopPropagation()"); // Блокировка двойной инициализации обработчиков для SeaMonkey ............... if ( this.hasAttribute("initialized") ) return; // Установить нужную иконку кнопки при старте браузера или при изменениях настроек в 'about:config' ................. const s = "CB.Autocopy"; function toggleImage() { document.getAnonymousNodes(self)[1].src = cbu.getPrefs(s) ? "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgMBAAQIAAcEBwAIBAcACAQHAAgEBwAIBAcACAQHAAgEBwAIBAcACAMEAQEAAAAAAAAAAAAAAAACAwADAAAAABUnAB9cqgC3a7wB4Gq5Ad1qugHearoB3mq6Ad5qugHearoB3mi4AN1qugHgYrMAxR43AC8AAAAAAAEAAAECAAQAAAQAV6AAprP9Vv/W/qn80/+f/9T/ov/U/6L/1P+i/9T/ov/U/6L/1/+n/9X+pfy3/WL/Y7QAvwEAAQAAAAAAFSgAH1ehAKlyzwD1htgf/YzcJ/2K2yP9i9sk/YvbJf2L2yX9i9sm/YnaIv2b4kP92/21/Nf+qv9quwHdBQkACAAAAQBeqwCzr/tR/8X0j/u+8X//vvJ//77ygP++8oD/vvKA/77yf/+98n7/wvSH/4zcKv+e4kv93v+0/2i5AN0DBwAIBQkACGu8AdzV/af/4v/B/d//u//h/7//4f+//+H/v//h/7//4f+//9/+u//n/8n/w/GK/4zaK/3g/7r/aroC3gMHAAgEBwAIarkC3dX/pf/g/sD93v67/9/+vv/g/r//4P6//+D+v//f/r7/3f66/+T/xv/B8Yb/j9st/eT/w/9qugPeAwcACAQHAAhqugLe2v+w/+j/z/3l/8r/5//N/+f/zv/n/87/5//O/+f/zf/l/sj/7P/W/8Xyj/+Q2y/96f/N/2q6A94DBwAIBAcACGq6At7f/7n/7v/c/ev/1v/t/9n/7f/a/+3/2v/t/9r/7f/Z/+r+1f/y/+P/yPKW/5DbMf3s/9X/aroE3gMHAAgEBwAIaroC3uP/wf/z/+j98P/h//L/5P/z/+X/8//l//P/5f/y/+T/8P7g//j/7v/L8p3/kdsy/fD/3P9rugTeAwcACAQHAAhqugLe5v/J//j/8v31/+r/9v/t//f/7v/3/+//9//u//b/7f/0/un//f/4/87yo/+R2zL98f/f/2q5Bd0DBwAIBAcACGq6At7p/8///P/6/fj/8f/6//T/+v/1//r/9f/6//X/+v/0//f+8P//////0fGo/5PbNf30/+f/a7wE3AQJAAgEBwAIabkC3er/0f/+//79+v/0//v/9//8//j//P/4//z/+P/7//f/+f70///////T8qz/i9go+8P9ef9dqwCzAAACAAUJAAhquwHd7f7a//////z+//39/////f////3////9/////f////39/vz9/////dzzvv5v0AD1VqECqRUnAB8AAAAAAQACAGK0AL/J/Yf/8v7k/O3/1//u/9n/7v/Z/+7/2f/u/9n/7v/Z/+3/1//x/eP8vfxu/1WgAKYAAAUAAQIABAABAAAAAAAAHjcALmGzAMVquwLgarkC3Wq6At5qugLearoC3mq6At5qugLearkC3Wu8AeBbqgC3FScAHwAAAAACAwADAAAAAAAAAAAAAAAAAwQCAQQIAAgEBwAIBAcACAQHAAgEBwAIBAcACAQHAAgEBwAIBAgABwMDAgAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" : "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgEDAAQACAcEAAcIBAAHCAQABwgEAAcIBAAHCAQABwgEAAcIBAAHCAMBBAEAAAAAAAAAAAAAAAACAAMDAAAAABUAJx9cAKq3awG84GoBud1qAbreagG63moBut5qAbreagG63mgAuN1qAbrgYgCzxR4ANy8AAAAAAAABAAEAAgQABAAAVwCgprNW/f/Wqf7805///9Si///Uov//1KL//9Si///Uov//16f//9Wl/vy3Yv3/YwC0vwEBAAAAAAAAFQAoH1cAoalyAM/1hh/Y/Ywn3P2KI9v9iyTb/Ysl2/2LJdv9iybb/Yki2v2bQ+L927X9/Neq/v9qAbvdBQAJCAABAABeAKuzr1H7/8WP9Pu+f/H/vn/y/76A8v++gPL/voDy/75/8v+9fvL/wof0/4wq3P+eS+L93rT//2gAud0DAAcIBQAJCGsBvNzVp/3/4sH//d+7///hv///4b///+G////hv///4b///9+7/v/nyf//w4rx/4wr2v3guv//agK63gMABwgEAAcIagK53dWl///gwP793rv+/9++/v/gv/7/4L/+/+C//v/fvv7/3br+/+TG///BhvH/jy3b/eTD//9qA7reAwAHCAQABwhqArre2rD//+jP//3lyv//583//+fO///nzv//587//+fN///lyP7/7Nb//8WP8v+QL9v96c3//2oDut4DAAcIBAAHCGoCut7fuf//7tz//evW///t2f//7dr//+3a///t2v//7dn//+rV/v/y4///yJby/5Ax2/3s1f//agS63gMABwgEAAcIagK63uPB///z6P/98OH///Lk///z5f//8+X///Pl///y5P//8OD+//ju///LnfL/kTLb/fDc//9rBLreAwAHCAQABwhqArre5sn///jy//316v//9u3///fu///37///9+7///bt///06f7//fj//86j8v+RMtv98d///2oFud0DAAcIBAAHCGoCut7pz////Pr//fjx///69P//+vX///r1///69f//+vT///fw/v//////0ajx/5M12/305///awS83AQACQgEAAcIaQK53erR///+/v/9+vT///v3///8+P///Pj///z4///79///+fT+///////TrPL/iyjY+8N5/f9dAKuzAAIAAAUACQhqAbvd7dr+//////z+/f/9/////f////3////9/////f////39/P79/////dy+8/5vAND1VgKhqRUAJx8AAAAAAQIAAGIAtL/Jh/3/8uT+/O3X///u2f//7tn//+7Z///u2f//7tn//+3X///x4/38vW78/1UAoKYABQAAAQACBAAAAQAAAAAAHgA3LmEAs8VqArvgagK53WoCut5qArreagK63moCut5qArreagK53WsBvOBbAKq3FQAnHwAAAAACAAMDAAAAAAAAAAAAAAAAAwIEAQQACAgEAAcIBAAHCAQABwgEAAcIBAAHCAQABwgEAAcIBAAIBwMCAwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }; toggleImage(); Services.prefs.addObserver(s, toggleImage, false); addDestructor(()=> Services.prefs.removeObserver(s, toggleImage)); // Выключать кнопку при закрытии браузера если это разрешено в 'about:config' ................. var toggleButton = { observe:(subject, topic, data)=> { cbu.getPrefs("CB.Autocopy.reset") && data == "shutdown" && cbu.setPrefs("CB.Autocopy", false); } }; Services.obs.addObserver(toggleButton, "quit-application", false); // Функции автоматически копирует выделенный текст на странице, если это разрешено в 'about:config' ............... function autocopy(e) { if ( e.button || !cbu.getPrefs("CB.Autocopy") || document.commandDispatcher.focusedWindow.getSelection().isCollapsed ) return; goDoCommand('cmd_copy'); // выделенный текст мигает .... if ( !cbu.getPrefs("CB.Autocopy.selectingTextBlink") ) return; document.activeElement.blur(); setTimeout(()=> window.content.focus(), 300); }; addEventListener('mouseup', autocopy, false, gBrowser); // Cредней кнопкой мыши вставить текст из буфера обмена в текстовые поля с заменой выделенного текста ............... function middleMousePaste(e, doc = this.document || document) { if ( e.button !== 1 || !cbu.getPrefs('middlemouse.paste') || !/input|password|textarea|textbox|searchbar|findbar|cbeditor/.test(e.target.localName) ) return; e.preventDefault(); e.stopPropagation(); // вставить текст .... var cmd = "cmd_insertText"; var commandDispatcher = doc.commandDispatcher; var controller = commandDispatcher.getControllerForCommand(cmd); var controller = controller.QueryInterface(Ci.nsICommandController); var params = Cc["@mozilla.org/embedcomp/command-params;1"].createInstance(Ci.nsICommandParams); params.setStringValue("state_data", gClipboard.read()); controller.doCommandWithParams(cmd, params); }; addEventListener("click", middleMousePaste, true, document.documentElement); // Дополнительные возможности для значка идентификации сайта в строке адреса ............... addEventListener("click", e=> { if ( e.button == 1 || !/page-proxy-favicon|page-proxy-button/.test(e.target.id) || !cbu.getPrefs("CB.Autocopy.addToAddressBar") ) return; e.preventDefault(); e.stopPropagation(); e.target.setAttribute("context", "event.stopPropagation()"); // ЛКМ без запроса открывает информацию о странице в вкладке 'Разрешения' .... if ( e.button == 0 ) BrowserPageInfo(content.document, (gURLBar.value.startsWith("http") ? "permTab" : "generalTab")); // ПКМ копирует текущий адрес .... if ( e.button !== 2 ) return; gClipboard.write(content.location); // значок идентификации сайта мигает красным .... var id = (Services.appinfo.name == "SeaMonkey") ? "page-proxy-deck" : "identity-box"; document.getElementById(id).style.background = "red"; setTimeout(()=> document.getElementById(id).style.background = "", 300); }, true, gURLBar); // Дополнительные возможности для двойного клика мыши ............... function handleDblClick(e) { var node = e.target; var editor = node.editor; // Сохранить изображение в папку загрузки .... if ( e.button == 2 && cbu.getPrefs("CB.Autocopy.saveWithDoubleClick") && node.localName == 'img' ) { var run = cbu.getPrefs("browser.download.folderList"); var use = cbu.getPrefs("browser.download.useDownloadDir"); cbu.setPrefs("browser.download.folderList", 2); cbu.setPrefs("browser.download.useDownloadDir", true); function save() { var func = eval( gContextMenu.saveMedia.toSource() .replace(/(false,\s+)false,/, "$1true,") .replace(/^s/, "0,function s") ); (save =()=> func.call(gContextMenu))(); } /Pale Moon|SeaMonkey/.test(Services.appinfo.name) ? saveImageURL(gContextMenu.imageURL, 0, 0, 0, 1, null, content.document) : save(); setTimeout(()=> document.getElementById("contentAreaContextMenu").hidePopup(), 20); cbu.setPrefs("browser.download.folderList", run); cbu.setPrefs("browser.download.useDownloadDir", use); }; // скопировать выделенный текст .... if ( e.button == 2 && cbu.getPrefs("CB.Autocopy.copyWithDoubleClick") && !/findbar|tabbrowser/.test(node.localName) ) { e.preventDefault(); editor ? editor.copy() : goDoCommand("cmd_copy"); try { var box = (node.textbox || node).inputField.parentNode; var popup = box.ownerDocument.getAnonymousElementByAttribute(box, "anonid", "input-box-contextmenu"); setTimeout(()=> popup.hidePopup(), 50); } catch(e) { setTimeout(()=> document.getElementById("contentAreaContextMenu").hidePopup(), 50) }; } }; addEventListener("dblclick", handleDblClick, false, gBrowser); // Наблюдатель следит за открытием новых окон ............... function observer(subject) { subject.addEventListener("load", e=> { var doc = e.target; var view = doc.defaultView; // добавлять обработчики клика для редакторов CB кнопок .... if ( /custombuttons/.test(doc.URL) ) { view.addEventListener("dblclick", handleDblClick, false); view.addEventListener("click", middleMousePaste.bind(view), true); }; // добавлять обработчики клика для 'Информацию о странице' и 'Библиотеки' .... if ( /pageInfo.xul|places.xul/.test(doc.URL) ) { view.addEventListener("dblclick", function close() { this.close() }, true); view.addEventListener("unload", e=> { view.removeEventListener(e.type, arguments.callee, false); view.removeEventListener("dblclick", close, true); }, false); }; }); }; Services.ww.registerNotification(observer); addDestructor(()=> Services.ww.unregisterNotification(observer)); // Подсказка для кнопки ................................ this.tooltipText = "Autocopy \nЛ: Переключить автоматическое копирование \nП: Меню \nДП: CB меню";
Отсутствует
Dumby спасибо.
По редактору понял. Поменял var editor = ta.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor на var editor = ta.editor и все получилось.
Реанимировал еще одну кнопку для 63 Save+
// Save, от 07.03.2017. ............. self.label = "Save"; self._handleClick =()=> menuPopup.openPopup(this, "after_start"); self.image = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="; var pref = "CB.Shortcuts.pathToSaveShortcuts"; //var faviconFolder = "C:\\Users\\vieva\\Desktop\\"; // папка для сохранения иконок для ярлыков и ярлыков сайтов var folderpath="C:\\Users\\vieva\\Desktop"; var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); // Создать меню для кнопки ............. var array = [ { label: "Сохранить значок веб-сайта", func: "saveFavicon()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACPVBMVEX09ff////C3L+Uq8+Vq8+Uqs+Zr9CZrtCZr9Gfu+ear8+mt9JRf8ORxl3t8vfF06+Twojs8/d9otl8o9s+aquZrs/X9KLp8Pft8fZhisf//+DBzN2hveihv+pii8hti9pgicl6oNlojs1zncNsi836/P2duebx8/eYyWqBp+Gn0IKBvlKHsm9qmaVuk8zt7/FEbauEv1Tp7/JdhL9oi9Pl8e2LwlmdsdD7/P76+/3H7ofo8+peh8eHwFaSteZ0pkp2gl7q8/Ohy5OApt2by2eZuOqbuOWaezWuvtd7nN2HvWxul9Ty9feQxV5ljcqBp+JEcLCVtOOo0nR7odx5n9suX6Z1mtBzmtSXyGPv9PewzfOzx+O6zu/s8fd9o95Xfrthi8lYhMN5oNnw9ffw9Pjw9Pf8/f6ewO/m8O9zmdE6aapsjdyUwouPxWPDzd6XteOSs9B5nNVpnpqHt7h/s6F6n9d7ntSTttGHwVh4qp+Ev1HH7ox6qk5wj+Hm8e3t9fOm0IKAtqOBpNrx+P9ljcyhs9FpkM2hv+/u8/fF0eOLu4N+vFKgzX3p9OSFqN13qExekIl4n9j7/P3x9PhxmNDm8e9Vg8Zfkozr8veq0YTX9qL//92AtamOwnHFz96Fot1diMh+pd13ntmatu+YyW/3+/+Tqs5UgcShzJNbhsdTf8GHs7bo8PaXtuqMr+Ty8/SZt+SUqs7r7Ox3ndb9/f7t8feZyXGYyWWCpNbz9PRuiteNtNDn7/V4ntjx8fGo3JqNAAAAv3RSTlP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AEVuhDkAAAD+SURBVBhXY5jHzcUMAqxAICq9bx8D96adDFAgaGQOFOBaH7h7zoqZDTlFyptncAAFWBjyi52CXCI0unRLxcECPhsatbbzmlXMnS60hg0kkOxW0uNrq93tNaFpD1ggUm21QK532ZQdSm1hmXKdDCwdnOWVOi1RjNGMQCCrwMDMJ8NZ4LAynVGPkXFp8zpJBubYmn579wXtqhZb0iwn9a1iWLaViYmJ3891obOwYtLEvcYMGyWAAkwJdv6accEhi8LjGVr11SenpC5f61g3NcO0vjCAIc+DjZ2dnWexddWSbYa9nlkM+8BgWsxsK7FZ1VLzRaACNokmtdnyu1QMQgF7Rlh4zWWTAwAAAABJRU5ErkJggg=="}, { label: "Запомнить значок веб-сайта как base64", func: "copyFaviconData()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAI2bv/9RVpf/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAACIkvD/Jia6/ywpq/8AAAAAAAAAAAAAAAAAAAD/AAAA/wbwAf90qpv/Ymic/1RWqP9OUKr/W2Ch/2dumf9YYKT/Ly/B/xQP3/8MB9P/JCGb/wAAAAAAAAAAAAAAAAAAAP8G8AH/U5ea/ycr8f8VIP3/HiP4/ywo8v8sIvb/LCL2/ywi9v8KBOj/BQDe/wQAtv8tK4P/AAAAAAAAAAAAAAD/BvAB/3Sqm/9iaJz/Tim3/0UuuP9GPrT/R0ex/zk8uf8gIMz/FRDe/xEMzv8jIJz/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8AAAD/SqOR/yImvP8sLKj/AAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/BvAB/3Sqm/9KW5r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAABvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAG8AH/AAAAAAAAAP8G8AH/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BvAB/wbwAf8AAAAAAAAA/wAAAP8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAG8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOesQQBjrEGAAaxBwACsQcABrEHDg6xBwAesQcAPrEHAD6xBw8+sQcPprEHD8axBwAGsQQABrEGAAaxB//+sQQ=="}, { separator: ''}, { label: "Сохранить ярлык страницы как…", func: "saveShortcuts()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADzqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP8E/yT/BP8k/5XLDv/zqgD/86oA//I1///yNf//86oA//OqAP/zqgD/86oA//OqAP+Vyw7/lcsO/wT/JP8E/yT/BP8k/5XLDv+Vyw7/86oA//OqAP/yNf//8jX///OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//02AP/9NgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/9NgD//TYA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA/wA31v8AN9b/86oA//9If///SH//86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP8AN9b/ADfW//OqAP//SH///0h///OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/5XLDv+Vyw7/86oA//OqAP/zqgD/86oA/0CA//9AgP//86oA/07+9f9O/vX/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP9AgP//QID///OqAP9O/vX/Tv71//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ=="}, { separator: ''}, { 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="}, { label: "Сохранить видимую часть страницы как PNG", func: "WebScreenShot.capturePage()", image: false}, { 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="}, { 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="}, { separator: ''}, { label: "Сохранить выделенный текст как txt файл", func: "saveSelectionToTxt()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAQE6AAAAZAAAAGgAAAJmAAACZgAAAGYAAABmAAAAZgAAAGYAAABmAAAAZgAAAGYAAABlAAAAaQABAmYAAQEjAAAAADlVkOdVcKHxVXKi8kdklPJLZpfyU3Cg8lJvn/JRbZ7yUW+g8lFun/JRbp/yUG6e8lVyofFVdKjzLkV45wAAAFABAQEAaIzF/3y34v9wsuL/cJe0/0lpgv9bjLP/dLLh/2+v3v9sq9v/cK3d/3Gv3v9sqtv/b7Df/4G77P9VcqT2AAAAVAMDAQBnir/+ZqfU/pDB4/7a3uD+j46N/kxYXv6To6/+1er4/tXp+P7J3/D+1ej4/svg8v6Gut/9aqzd/lhxnvAAAABSAwIBAGaIvv9pptX/ocfj//f4/P/P0tX/g4CA/1xZWf+Woqr/2uz8/9Hl+f/W5fT/2Of3/5fC4v5tq93/Vm+e8QAAAFIDAgEAaYm+/3mw2/+iyeX/9Pn8/+z0+//IzNL/d3h5/0tMTv+Mkpn/xdvs/9Hp/f/O4PL/msXk/nmz4/9XcJ/xAAAAUgMDAQBti7//k7/h/6fL5v/v9fn/4u73/9Dk9P+8wMT/YGpx/zJJWv94iJf/ztzo/9Pp/P+ZwuD+gLfk/1dwnvEAAABSAwMBAHOPwf+myub/sNHp//j7/P/6/P3/8fr///r39P+sxdP/IXWq/xJJcv+NjZD/0+Lu/6TN7f6Ft+L/WXGf8QAAAFIDAwEAd5LD/7PR6/+ZxOP/0ePx/97r9f/Y5/L/3e32/8Tc7f9gseT/CHK3/zBYdv+HiY7/lL/f/pLE7/9bcJ3xAAAAUgMDAQB4k8P/xNvx/5/F5f+kyOX/qMrn/6TH5f+kyOX/sM/q/5e51P9Mm83/GHm3/xxIav9fdYf+pMvs/1x1pfIAAABTAwMBAHmSxf/O4/T/y9/y/8Hb9P/C3PX/wNv0/7vW7/+93ff/utDm/42fsf9Gjbn/EXS2/ytSbv6Fj5r/WnGc8gAAAFICAwEBepPE/tHk9f/S5PX/vMjV/7fCzP+3w8//uMPP/7XBzP+6ytf/qa+4/3h/hv9Ghaz/JoO+/jNXdP82PVnyAAAAVgACAgCBmcb/2+r3/dHh8fyPkpX/kI6N/5yam/+dnJ3/paWk/6enpf+sr6//mpSR/3Bubf9SjbD8H4C+/QsrSvcCAAB/AAAAA3yVx//j8///3u/7/52gpf6pqKf+uLm5/rq7u/7Ly8v+ycnI/paWlf6LjY/+np2f/Xh+g/5gnL7/MX+y/xcgJ80BAgNNN1OUs6W84fDA1O73mJyj/ainpv+2trb/t7e4/8fHyP/Fxsb/kZGQ/4eGhP+vucT/j6G+/W53k/NlkbnwNoOv/AgiNb8CCBsQDRo/YwsaO3B0d33arKyp9q2trfWvr6/2u7u79ru7vPawr7H1sbCt9nJ2gOQIGD6bFCFEYB0qPE1Bf6SpEz9cggAAAAMCAQEBAQAAADIyMmlDQ0ONQUFBhUFBQYVCQkGFQkJBhUhISIRNTU2OKysrZAEAAAUBAQAAAgEAAAkEAAEDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}, { separator: ''}, { label: "Запомнить изображение как base64, в контекстном меню", value: "CB.Save.WebScreenShotOnImage"}, { label: "Сохранить выделенный текст в файл, в контекстном меню", value: "CB.Save.SelectionToFile" }, { label: "Открыть выделенный текст в внешнем редакторе, в контекстном меню", value: "CB.Save.TextToEditor"}, ]; 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 ("value" in m) { mItem.setAttribute('type', 'checkbox'); mItem.setAttribute('checked', cbu.getPrefs(m.value) ); mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value)); } if ("func" in m) mItem.addEventListener("command", ()=> eval(m.func.toString())); }); menuPopup.setAttribute("onclick", "event.stopPropagation()"); function aDate() { var t=new Date(); var y=1900+t.getYear(); var min=t.getMinutes(); if (min<10){min="0"+min}; var h=t.getHours(); var m=t.getMonth();switch(m){case 0: m="января";break;case 1: m="февраля";break;case 2: m="марта";break;case 3: m="апреля";break;case 4: m="мая";break;case 5: m="июня";break;case 6: m="июля";break;case 7: m="августа";break;case 8: m="сентября";break;case 9: m="октября";break;case 10: m="ноября";break;default: m="декабря";} var d=t.getDate(); //var curdate=y+"г."+" "+d+" "+m+" "+h+":"+min; var curdate=d+" "+m+" "+y+" "+"г"; var myfilename=curdate; return myfilename; } // Сохранить как PNG страницу или части страницы ............. WebScreenShot = { capture: function(win, x, y, width, height) { //const xhtmlns = 'http://www.w3.org/1999/xhtml'; var canvas = document.createElementNS(xhtmlns, 'canvas'); canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); ((i = 17)=> { try { ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white") } catch(e) { canvas.height = canvas.width*i; arguments.callee(--i) }; })(); var url = makeURI(canvas.toDataURL("image/png")); var fp = window.makeFilePicker(); fp.init(window, "Сохранить как…", fp.modeSave); fp.appendFilter("", "*.png"); // fp.defaultString = getTabLabel() + " " + (new Date().toLocaleFormat("%d.%m.%Y. %H:%M:%S")) + ".png"; fp.defaultString = getTabLabel() + ".png"; fp.open(res => { if (res == fp.returnCancel || !fp.file) return; // var save = window.makeWebBrowserPersist().saveURI; // save.length < 8 // ? save(url, null, null, null, null, fp.file, null) // : save(url, null, null, null, null, null, fp.file, null); makeWebBrowserPersist().saveURI( makeURI(canvas.toDataURL("image/png")), document.nodePrincipal, null, null, null, null, null, fp.file, null ); }); }, 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); }, 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(); this.capture.apply(this, this.getPosition()); 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)); }, }; 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(); } }); }; // Сохранить ярлык страницы в указанную папку .............. function saveShortcuts() { var urllink = content.document.location; var file = Components.classes["@mozilla.org/file/local;1"]. createInstance(Components.interfaces.nsIFile); file.initWithPath(folderpath); if( !file.exists() || !file.isDirectory() ) { file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0x1B6);} var savetodir=folderpath+"\\"; var urllink=gBrowser.currentURI.spec; var out=getTabLabel(); var filename=savetodir+out+'.url'; var data="[InternetShortcut]\r\nURL="+urllink+"\r\n"; saveToFile(data, filename); // подсказка var notification = 'Сохранил в: ' + folderpath; var image = gBrowser.selectedBrowser.mIconURL; alertsService.showAlertNotification(image, filename, notification); }; // Сохранить иконку текущего сайта с диалогом сохранения ............. function saveFavicon() { saveImageURL(gBrowser.selectedTab.image, "save", null, false, false, null, content.document) }; // Скопировать иконку текущего сайта как base64 код ............. function copyFaviconData() { var img = new Image(); img.src = gBrowser.selectedTab.image; WebScreenShot.onImage(img); }; // Сохранить выделенный текст или весь текст на странице как txt файл ............. function saveSelectionToTxt() { var sel = getSelect(); !sel && document.getElementById("cmd_selectAll").doCommand(); // создать название файла из заголовка страницы и текущего времени и сохранить текст .... var fileTitle = getTabLabel() + ' ' + aDate().replace(/:/g, "."); saveURL("data:text/plain," + encodeURIComponent(content.location + ("\r\n\r\n" + sel)), fileTitle + ".txt", null, false, false, null, content.document); !sel && goDoCommand("cmd_selectNone"); }; // Добавляем в контекстного меню страницы новые пункты ............. ((contextMenu, el)=> { // в контекстного меню изображений .... var baseItem = contextMenu.appendChild(document.createElement("menuitem")); baseItem.id = "content-baseItem"; baseItem.setAttribute("label", "Запомнить изображение как base64"); baseItem.onclick =()=> WebScreenShot.onImage(gContextMenu.target); // в контекстного меню выделенного текста .... var saveItem = contextMenu.insertBefore(document.createElement("menuitem"), el); saveItem.id = "content-saveItem"; saveItem.setAttribute("label", "Сохранить выделенный текст в файл"); saveItem.onclick =()=> saveSelectionToFile(); var editorItem = contextMenu.insertBefore(document.createElement("menuitem"), el); editorItem.id = "content-editorItem"; editorItem.setAttribute("label", "Открыть выделенный текст в внешнем редакторе"); editorItem.onclick =()=> textToEditor(); // устанавливаем где и при каких настройках показывать новые пункты .... addEventListener('popupshowing', e=> { if (e.target != e.currentTarget) return; var sel = gContextMenu.isTextSelected; saveItem.hidden = !sel || !cbu.getPrefs("CB.Save.SelectionToFile"); editorItem.hidden = !sel || !cbu.getPrefs("CB.Save.TextToEditor"); baseItem.hidden = !gContextMenu.onImage || !cbu.getPrefs("CB.Save.WebScreenShotOnImage"); }, false, contextMenu); // удалять новые пункти при изминениях .... addDestructor(()=> { baseItem.remove(); saveItem.remove(); editorItem.remove(); }); })(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open")); // Сохранить выделенный текст в файл на рабочем столе ............. function saveSelectionToFile() { // создать текст для записи var url = content.document.location; if (/\.рф/.test(url.host)) url = convertFromUnicode("UTF-8", url); var time = aDate().replace(/:/g, "."); var text = convertFromUnicode("UTF-8", getSelect()); var title = convertFromUnicode("UTF-8", getTabLabel()); var text = "..............................................................\n" + title + " - " + time + "\n" + url + "\n\n" + text + "\n\n\n"; var text = text.replace(/\u000A/g, "\u000D\u000A").replace(/\u000D\u000D\u000A/g, "\u000D\u000A"); // путь к файлу и название файла var file = Services.dirsvc.get("Desk", Ci.nsIFile); file.append("Save - " + (aDate().replace(/:/g, ".")) + ".txt"); // создать файл с текстом или добавлять текст в файл var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); file.exists() ? foStream.init(file, 0x02 | 0x10, 0664, 0) : foStream.init(file, 0x02|0x08|0x20, 0666, 0); foStream.write(text, text.length); foStream.close(); // всплывающая подсказка дает возможность открыть файл если кликнуть на подсказке var notification = 'Сохранил выделенный текст в файл на рабочий стол'; var image = gBrowser.selectedTab.image || self.image; alertsService.showAlertNotification(image, notification, "Кликни чтобы открыть файл", true, "", (s, t)=> { if (t == 'alertclickcallback') file.launch(); }, ""); }; // Создать текстовой файл с выделенным текстом в папке профиля и открыть в редакторе ............. function textToEditor() { var text = convertFromUnicode("UTF-8", getSelect()); var file = Services.dirsvc.get('ProfD', Ci.nsIFile); file.append("TextToEditor.txt"); custombuttonsUtils.writeFile(file.path, text); file.launch(); }; // Конвертировать текст в юникод ............. function convertFromUnicode(charset, str) { // var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); converter.charset = charset; str = converter.ConvertFromUnicode(str); return str + converter.Finish(); }; // Получить название домена с заглавным первым символом и без приставок( типа .ru и .com ) .............. function getSiteName() { try { var domain = content.document.domain.split('.') } catch(e) { return "" }; domain = (domain.length == 2) ? domain[0] : domain[1] return domain[0].toUpperCase() + domain.slice(1).split('.')[0] + " "; }; // Получить название вкладки без не сохраняемых символов и лишних пробелов .............. function getTabLabel() { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); }; // Получить выделенный текст из страницы или 'false' .............. function getSelect() { var el = document.commandDispatcher.focusedElement; try { return el.value.substring(el.selectionStart, el.selectionEnd) } catch(e) {}; var sel = gBrowser.contentDocument.defaultView.getSelection(); return (sel == '') ? false : sel.toString().replace(/^\s+|\s+$/g,"").replace(/\u000A/g, "\u000D\u000A").replace(/\u000D\u000D\u000A/g, "\u000D\u000A"); };
Отредактировано Andrey_Krropotkin (23-12-2018 22:36:19)
Отсутствует
Andrey_Krropotkin
Посмотрите пожалуйста еще кнопку Сохранить с траницу в PNG / PDF
// Настройка функций кликов мыши для кнопки ........ this.onclick = function(e) { if ( e.button == 0 ) savePageInPNG(); // ЛКМ if ( e.button == 1 ) gShowPopup(this); // СКМ if ( e.button == 2 && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey ) { // ПКМ e.preventDefault(); savePageToPDF(); } }; // Сохраняет страницу как PDF файл через сервис 'pdfmyurl.com' function savePageToPDF() { // разрешить страницу для расширения NoScript .... if ( "noscriptUtil" in window ) { var autoReload = custombuttons.getPrefs("noscript.autoReload"); if ( autoReload ) custombuttons.setPrefs("noscript.autoReload", false); noscriptOverlay.allowPage(); if ( autoReload ) setTimeout(function() { custombuttons.setPrefs("noscript.autoReload", true) }, 10) } // сохранить если это веб страница .... var loc = content.location; if (loc.protocol.slice(0, 4) == "http") loadURI("http://pdfmyurl.com?url=" + loc); }; // Сохранить всю страницу как PNG ........ function savePageInPNG() { var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); canvas.width = Math.min(content.innerWidth + content.scrollMaxX, 32766); canvas.height = Math.min(content.innerHeight + content.scrollMaxY, 32766); var context = canvas.getContext("2d"); context.drawWindow(content, 0, 0, canvas.width, canvas.height, "white"); var uri = makeURI(canvas.toDataURL("image/png")); var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker); fp.init(window, "Save Screenshot As", fp.modeSave); fp.appendFilter("", "*.png"); fp.appendFilters(fp.filterImages | fp.filterAll); fp.defaultExtension = "png"; fp.defaultString = content.document.title + ".png"; if (fp.show() == fp.returnCancel || !fp.file) return; Cc['@mozilla.org/embedding/browser/nsWebBrowserPersist;1'] .createInstance(Ci.nsIWebBrowserPersist) .saveURI(uri, null, null, null, null, fp.file, null); }; // Подсказка для кнопки ........ this.tooltipText = "L = Сохранить страницу как PNG-изображение \nM = Контекстное меню \nR = Сохранить страницу как PDF файл";
Отсутствует
Garalf на 63
// Настройка функций кликов мыши для кнопки ........ this.onclick = function(e) { if ( e.button == 0 ) savePageInPNG(); // ЛКМ if ( e.button == 1 ) gShowPopup(this); // СКМ if ( e.button == 2 && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey ) { // ПКМ e.preventDefault(); savePageToPDF(); } }; // Сохраняет страницу как PDF файл через сервис 'pdfmyurl.com' function savePageToPDF() { // разрешить страницу для расширения NoScript .... //if ( "noscriptUtil" in window ) { // var autoReload = custombuttons.getPrefs("noscript.autoReload"); // if ( autoReload ) custombuttons.setPrefs("noscript.autoReload", false); // noscriptOverlay.allowPage(); // if ( autoReload ) setTimeout(function() { custombuttons.setPrefs("noscript.autoReload", true) }, 10) // } // сохранить если это веб страница .... //var loc = content.location; var loc = content.document.location; if (loc.protocol.slice(0, 4) == "http") // loadURI("http://pdfmyurl.com?url=" + loc); var vert = "http://pdfmyurl.com?url=" + loc; getBrowser (). loadURI(vert, document.nodePrincipal); }; // Сохранить всю страницу как PNG ........ function savePageInPNG() { var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); canvas.width = Math.min(content.innerWidth + content.scrollMaxX, 32766); canvas.height = Math.min(content.innerHeight + content.scrollMaxY, 32766); var context = canvas.getContext("2d"); context.drawWindow(content, 0, 0, canvas.width, canvas.height, "white"); var uri = makeURI(canvas.toDataURL("image/png")); var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker); var fp = window.makeFilePicker(); fp.init(window, "Сохранить как…", fp.modeSave); fp.appendFilter("", "*.png"); fp.defaultString = content.document.title + ".png"; fp.open(res => { if (res == fp.returnCancel || !fp.file) return; makeWebBrowserPersist().saveURI( makeURI(canvas.toDataURL("image/png")), document.nodePrincipal, null, null, null, null, null, fp.file, null); }); }; // Подсказка для кнопки ........ this.tooltipText = "L = Сохранить страницу как PNG-изображение \nM = Контекстное меню \nR = Сохранить страницу как PDF файл";
Отредактировано Andrey_Krropotkin (24-12-2018 11:24:10)
Отсутствует
Garalf У меня работает так
/*Initialization Code*/ /*Дополнительные пункты в контекстном меню кнопки*/ const topicURL = "http://forum.mozilla-russia.org/viewforum.php?id=34" const cbNamespace = "http://xsms.nm.ru/custombuttons/"; const nsIFilePicker = Ci.nsIFilePicker; const nsIFile = Ci.nsIFile; function $(aId) { return document.getElementById(aId); }; var date = new Date(); var time1 = date.toLocaleString('ru', {year: 'numeric'}); var time2 = date.toLocaleString('ru', {month: 'long', day: 'numeric'}); var time = time1 + "г" + " " + time2; ///////////////////////////////////////////////////////////////////////////// /////////////////////////////// Context menus /////////////////////////////// ///////////////////////////////////////////////////////////////////////////// function addMenuItem(aNewIDs, aNodeIDs, aLabel, aIcon, aCommand) { for (var i = 0; i < aNewIDs.length; i++) { // Remove previously created menuitems if any if ($(aNewIDs[i])) $(aNewIDs[i]).parentNode.removeChild($(aNewIDs[i])); let mi = e4xConv_parseXULFromString( '<menuitem xmlns="' + e4xConv_encodeHTML(xulns, true) + '"\n\ id="' + e4xConv_encodeHTML(aNewIDs[i], true) + '" class="menuitem-iconic"\n\ image="' + e4xConv_encodeHTML(aIcon, true) + '" label="' + e4xConv_encodeHTML(aLabel, true) + '"\n\ oncommand="' + e4xConv_encodeHTML(aCommand, true) + '"/>'); if (i == 0) mi.setAttribute("observes", "custombuttons-contextbroadcaster-primary"); if ($(aNodeIDs[i])) { if ($(aNodeIDs[i]).nextSibling) { $(aNodeIDs[i]).parentNode.insertBefore(mi, $(aNodeIDs[i]).nextSibling); } else { $(aNodeIDs[i]).parentNode.appendChild(mi); } } } }; var saveImg1 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAnUlEQVQ4jc3RPQ4BURTF8Z+PgrAPtUJnIxZgBZagkolVqDWWIliARCFR6GSq0Twyw2SemcpJTnPzzv/edy//ohOymj7mARl6NRoOQ6YAiGmNFAm6TQBpePdAJwYYYIF+rpaE8CoGaGEbarsw7qfaVYCl4rY3mOOGaQwwU326O8Zhyi/AJPwxdv8rRmWAyw/hl89lgCZ+69AgvPcXegKfOWlGgoA/rgAAAABJRU5ErkJggg=="; var saveImg2 = "data:application/file;base64,AAABAAEAEBACAAEAAQCwAAAAFgAAACgAAAAQAAAAIAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAADbAAADpcAAA//AAANVwAAD/8AAAKsAAAD/AAAP//AAAP8AAAD/AAAD/8AAAwDAAAP/wAAA/wAAAP8AAA"; var saveImg3 = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQf//rEH4j6xB8IesQeHDrEHD4axBh/CsQYf4rEGH8KxBw+GsQeHDrEHwh6xB+I+sQf//rEH//6xB//+sQQ=="; var saveImg4 = "data:application/file;base64,AAABAAEAEBACAAEAAQCwAAAAFgAAACgAAAAQAAAAIAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAA/wAAAP8AAA"; var saveImg5 = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU1FQr1FRT7BRUU+wUVFPsFFRT7BRUU+wUVFPsFFRT7BRUU+wUVFPsFFRT7BRUU+wU1FQrwAAAAAAAAAAAAAAAHd0cpz//////////////////////////////////////////////////////////3d0cpwAAAAAAAAAAAAAAAB4d3Sc/////+Dg4P/g4OD/4ODg/+Dg4P/g4OD/4ODg/+Dg4P/g4OD/4ODg//////94d3ScAAAAAAAAAAAAAAAAenh3nP/////i4uL/4uLi/5yiz/9HYcT/PWrR/1qQ3P+nuNr/4uLi/+Li4v//////enh3nAAAAAAAAAAAAAAAAH18eJz/////5OTk/2FluP8IJ6r/D1TU/wli4v8FZeb/D3He/4y+5f/k5OT/+/v7/318eJwAAAAAAAAAAAAAAACBfXyc/////5Wc0v8JKq//E2Pd/yFTrv9EKTn/LjVZ/xaF2/8OdNP/zNnm//z8/P+BfXycAAAAAAAAAAAAAAAAhIGBnP////89Xc7/Dk7N/wpQ0/8zVp//TGCK/4U2Cf9DW2b/Eqj7/5C+5//8/Pz/hIGBnAAAAAAAAAAAAAAAAIaEgZz/////Kmnf/wlFzf8gPZ7/uXcl/8OAK/+UTBL/b1Az/zfG9f9srdX/+fn5/4aEgZwAAAAAAAAAAAAAAACJhoac/////0iN6P8HQtH/EVzd/2mCqf/dqkz/0pY6/6FnKv9Nvt7/kMfs//X19f+JhoacAAAAAAAAAAAAAAAAiomJnP////+Mr+r/FFnU/xVRyv+LorL/8Oqh//nXbP+5omH/Urvf/8bj7v/s7Oz/iomJnAAAAAAAAAAAAAAAAI6Kipz/////2+n3/5aSm/+hcEn/4uXC////2P/25KD/rqSD/7HR5//o6Oj/4eHh/46KipwAAAAAAAAAAAAAAACPjo6c//////j4+P/4+Pj/3s/F/9i/n//p27n/5NG0/+7r6f/r6+v/3t7e/9LS0v+Pjo6cAAAAAAAAAAAAAAAAk4+PnP/////6+vr/+vr6//r6+v/6+vr/+vr6//j4+P/19fX/r66t/62sq/ObmprrkI2NpgAAAAAAAAAAAAAAAJOTk5z//////Pz8//z8/P/8/Pz/+/v7//r6+v/4+Pj/9fX1/66trfHs7Ozrp6emp4aGhhMAAAAAAAAAAAAAAACWlpOc/////////////////v7+//39/f/6+vr/9/f3//Pz8/+bmprrp6enp3NzcxYAAAAAAAAAAAAAAAAAAAAAmJiWnJiYlpyYmJacmJiWnJeTk52SkZGemJiWnJeTk52SkZGej4+LpIaGhhMAAAAAAAAAAAAAAAAAAAAAgAMAAIADAACAAwAAgAMAAIADAACAAwAAgAMAAIADAACAAwAAgAMAAIADAACAAwAAgAMAAIADAACABwAAgA8AAA=="; var saveImg6 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABKklEQVR42mNkQAMNDAxCQMoTiB2BWAEq/ACI9wPxdqD8O2T1jGiao4HUEgb8IAaobimGAUDBGiDVzEAcqAWqb4EbQKTNWF3CCPXzW5ho/f//YDqHkZFhCpQNA7lAMV4gzY4QEmZEtx1mgCtQ8W4o2xLIPg5lJwDZUghDYkAGzAEyktENMAQqPA9l6wDZEkB6D6Yhc0EG7AGynfEZYAxkawHpxVC+A5CvC6RFGBj2Em2AIZCeg8Q3BtLSUAMIegGkwQBIz8U0YC7OQEQ2wAjIPoekGRQTUC/E4IxGkMKzaNEI8jso4chDbGdgA0UjekJ6A8S3gRikFWQyKOF/higGR50UFLPBEhLM9AZoUv4F1cAA1QTi/2SAJFkQnxdCoyZlJEPIz0xIhpCUnQFx83abgfUZOQAAAABJRU5ErkJggg=="; var saveImg7 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAASUlEQVR42mNkoBAw0s6ABob/aHxGkg1I8zEGM2dtOTskDED3MxCgGIBpASOGATANhACyi6hrAGVeoDgQB6UB2PxMvAFEAooNAAC7izYR2pQ0nAAAAABJRU5ErkJggg=="; var saveImg8 = "data:application/file;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///8A////AESqAABHpgAASKAAAEukAQxMpQMYR6MAAEepAQ9MpgOLRKgACUenAABHpgAARKoAAP///wD///8A////AP///wBEqgAARaIAAFS2FVBj0jS3Y9AzyVG0EUROrwt8TKcDs0ikAANInwAAR6YAAESqAAD///8A////AP///wD///8ARKQAAVvJKJtj0jX/SaAJ/0abCv9UtSH/U7QX8lW5IMddwyfQW8Iii0mqBQ1DqQAA////AP///wD///8A////AEWlAAFYwB6YXsYc5F7GFt9bwA+vVbgWvU6rAKBRrgf0RZgA/02oDP9ezCzJR6UBA////wD///8A////AP///wBFrAAASKIAADiGNQAeYIIpF1iJHVa4GKEve0tFLHl1Pla7J51exRnUWL8VjEetAAP///8A////AP///wD///8AC0WuAAk/tAAANdpIAFD6/wA+7f8gd6jqBlPX+QBE9PIGS8uDLnZLADqNJwAzjDMA////AP///wD///8A////AAAw0QAALc0AAEPdegBI4f8AK8P/ADHX/wAwzf8AL8b/AEno/gAz2zYALtEQAC3VAP///wD///8A////AP///wAAMssAADjSMwBA2pIATen/ADG9/wBe1v8ATcz/ADHK/wBN5/4ASeH/AEvl6wA10DP///8A////AP///wD///8AADnTSQBO5/8ANc7/ADnR/xC+9/8C0f//AMj//wCP8P8ALcX/ACrC/wBE3f8ASeOf////AP///wD///8A////AABI4Z4ARN3/ACvG/wJAxP8Z5v//AMT//wDE//8Axv7/AETM/wA51P8AUervADjSPP///wD///8A////AP///wAAOdRiAFry+QBS6/QATOP/H+P8/xDe//8J1///E9H4/wFE2f8AReC6ADTOEwAyywD///8A////AP///wD///8AADDNAAAyzCcARN7WACvG/wVfzf8d0vf/HM30/whf0/8AI7n/ADzV+AA40kUAMswA////AP///wD///8A////AAAwywAAPNdTAEfg/wAsw/8AOdb/ADLP/wAswv8AReP/AC7H/wA40f8AR+GfADDKAP///wD///8A////AP///wAAMswAADfRQgBY8f8AT+j/AE7o7AA+1/8AK8T/AE7o/wBN5f8AVe7/AD/ZbAAwywD///8A////AP///wD///8AADPMAAAyywAANM4vADjSUQA0zikAU+z3AEff/wBJ4sMAN9EtADjROQAyywAAM8wA////AP///wD///8A////AAAzzAAAM8wAADHLAAAwywAAMcsAAD/YXQBK4pYAN9AxAC/KAAAwygAAM8wAADPMAP///wD///8A+R8AAPAfAADABwAAwAMAAPgDAADwHwAA8AcAAOADAADAAwAAwAMAAMAHAADgBwAA4AcAAOAHAADwDwAA/j8AAA=="; var saveImg9 = "data:application/file;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAD///8BAAAAFwAAAGkAAABzAAAAdQAAAHUAAAB1AAAAdQAAAHUAAAB1AAAAdQAAAHUAAAB1AAAAdQAAADkAAAAP////AQAAAIdgZmj/YWlt/2FobP9haGz/YGhr/2Boa/9fZ2v/X2dr/15mav9dZWn/XGRo/0ZNUP8AAACdAAAAFf///wEAAACr2tzc/9ve4P/a3t//1dnZ/7S2tf+foJz/m5ya/6apqP/O0tP/09fZ/9DV1v+hqq//AAAAuQAAABX///8BAAAAq+3u7//e4eL/ub29/2hnXv9oVUX/U0As/zgxGf83Lx3/YWBX/7a5uv/S1tj/o6yx/wAAALkAAAAV////AQAAAKv29/f/19na/1dUQf9jXDv/dmtJ/4FoSP9VQiL/V0Ek/008Iv9HQTP/yc3P/6Wus/8AAAC5AAAAFf///wEAAACr+Pj4/5uamP9tY0L/g31b/6GLa/+McVH/eFY5/4xwUv9yXkD/RTki/4uMiv+nsLT/AAAAuQAAABX///8BAAAAq/n6+v+FfXL/waSM/8qznf/DrZP/ooFi/7WfhP+qh2//blk9/1A+Iv9aWlH/pK2x/wAAALkAAAAV////AQAAAKv6+/v/d3Rr/9zCsP/RxbH/z8Wu/9fJt//Qvab/qItv/5iOb/9tYUH/VVJK/6Wtsf8AAAC5AAAAFf///wEAAACr+/z8/4mHff+3pI//3NK//+HXxf/m3Mz/5trJ/9rMuf+bgWT/d14//2hnYP+osbX/AAAAuQAAABX///8BAAAAq/z9/f/FxL7/j4l+//Xw5f/29ez/8/Dl/+DMuv/VuaP/poZn/2dFKv+srav/oamt/wAAALkAAAAV////AQAAAKv+/v7/+/z8/5iZjf+5uqr/6+PW/+3i1P/kzL3/vZR+/4NhSf+Qh3z/z9HS/4qQkv8AAAC1AAAAFf///wEAAACr/v7+//7+/v/u7u3/tbiv/5WSgP+DfGj/e25Z/29gTv+sppz/vr6+/5aYmP90eHr/AAAApwAAABP///8BAAAAq/////////////////7+/v/9/f3//f39//v8/P/5+fn/1dXV/2pqav9TU1P/QUFB/wEBAYkAAAAJ////AQAAAKv7+/v//////////////////v7+//7+/v/+/v7/+vr6/9fY2P/V1tb/7Ozs/4KCgv8EBAQrAAAAA////wEAAACFlJSU/6ioqP+qqqr/qqqq/6qqqv+qqqr/qKio/6anp/2kpaX9o6Oj/4qKitUZGRk9////Af///wH///8BAAAAFQAAAFUAAABVAAAAVQAAAFUAAABVAAAAVQAAAFUAAABTBAQEUx8fH1dfX18z////Af///wH///8BAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//w=="; var loadImg = "data:image/x-icon;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAD///8B////Af///wH///8B////AQAAAB+yg2l71ZRt+daTa//Wk2v/1pNr/9aTa//Wk2v/v4NlywYEAycAAAAX////Af///wH///8B////Af///wHdo4M53Zx3/+Sgef/innb/4p52/+Kedv/lo3r/5aR6/+mqgfvPj27N////Af///wH///8B////Af///wH///8B4KSD8+mmff/opH3/56N6/+Whef/no3r/66qB/8KBXf/Fg1//0Y5s78+Pbqn///8B////Af///wH///8B////AeGlg//trIX/7ayE/+6thP/urIX/9bWL/8eFYf/GhF//yYZh/9SPa/nkn3j/////Af///wH///8B////Af///wHkn3j/76+G/+6uh//vrob/76+G//W3jP/GhF//y4di/9ONZ//XkWr/5J94/////wH///8B////Af///wH///8B5J94/++wif/wsIj/8LGJ//CxiP/0toz/y4di/8+KZf/vroP/766D/+SfeP////8B////Af///wH///8B////AeSfeP/xs4v/8bOL//Cziv/ws4v/87WL/9CNa+3QjWvt3p96/96fev/en3r/////Af///wH///8B////Af///wHkn3j/8rWN//K2jf/ytY3/8rWN//O2jvfdo4Lj0I5sJdCObCXQjmwl0I5sJf///wH///8B////Af///wH///8B5J94//O3j//zuI//87iP//O4j//zuZDx3aOD7////wH///8B////Af///wHdo4M/5J94/+SfeP/kn3j/5J94/++2j//zupH/9LqR//O6kv/0upL/87qR/+SfeP/kn3j/5J94/+SfeP////8B////Af///wHkoXr/9cCY//W8k//0vJT/9L2T//S8lP/0vZT/9LyU//S8lP/1vJT/9cCY/+Shev////8B////Af///wH///8B9b+WC+SjfP/2yqP/9b+W//a/lf/2v5X/9b6V//W+lv/1vpX/9sqj/+SjfP////8B////Af///wH///8B////Af///wH2wZgX5aZ+//fTrP/2wJj/9sCY//bAmP/2wZj/99Os/+Smf/////8B////Af///wH///8B////Af///wH///8B////Af///wHkqYH/99ax//fCmv/3wpn/99aw/+Sogf////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AeWrhP/317L/99ey/+WrhP////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B5a2F/+Wthf////8B////Af///wH///8B////Af///wH///8BAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//w=="; var moveToMenu = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABKElEQVR42o3TMUvDQBQH8P+7tLlEwaW4ugl+iU6CCA4i0tbdqavgZ/ErCE79DsVBkYpKLR2kuApOatG297zLJWkqXnIPwrsk937cveQIJXHZBZt8cgFyzaEqYGuTvl7feM2FVAIHR8Bj341UAu1T4PPdjXgBJgzyPKDFy4SDIkJZo1yRASZ+FDB5Itzfct7YBGjuBBBh6oT6ed2OazGjsV3wQ2Cu64bXUKM7FgZJgPaufinTSVFhrDPFheVIe01nwLgfq9HNVCRAaw8Q6USWS4B05mgVIH2/qG+ABh+46im7heP9EELOLRDZpVqAQev8ZwUS/DBLivMtlDWxc7Ycs6yBhyov9vqMGcBBDB5/rxT7/Qfntjn/FXsDrmIvoHUonMVegMllx/kXlvSRMQ0GPE4AAAAASUVORK5CYII="; var removeFromToolbar = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACMElEQVR42p3Sz2/SUBwA8G9pgQJd6QYZQQkOjUFdXMCLMn9B4l3myRgXhydPZgcTY2KyLfGiF/wT9GTmhfIXjMQ4NP5YD5qZTGdVdEx+9FVKSwttrTV4QD3AN3mH9837fr7v+/Kww1e4ic2HiSYMRGxufcHjxs87nQ5GN0zodnXQNLVomvCAL6ZR/xxmAS9VsX1umz1pJ/dfKGeD4+58OERNYQQO7Y4BWs8E3XCAqvRAEkWkdpTcNptm+4DpMVUOtboZl4tY2reXWmTGvbDTVKFnALicTrvYsFqbpgEOBw6tpgiigOb4Yoa1gTMzY1B+XUexKM1gLid8a3QgQHtBklQQBJm3RuAxDBiPl0z4aMq+eu1rFYmiFLOBowd8QJEEiLIBlbpV7PdArdZCApJX3j9O3e/Pe/Di0zTpJgvB8CSjSG1o7O7mbCA04QIHjoGsGuAfI6FRk0D8ISe3VlPc4OPGL61nab+/QDE0VD9/+T1CKOCCtqoDQRBAe0n4yH/nZUVLVtjTCP4R8cvPN8LRSKL6qVKygUjIC0rXAAMw6+EI6GkmoGaDM0DP8KuzfyHx+WfLe6KRpdpOlbMB+E9oWof78OhEcjB/5OqLbHAyUEB1oYTBCDFz7VWaYZg11BTYkYBj17lFyu3Lo5aYGwk4fuNNHgd8QVHk2EjA7K3NDVM3iuV708tDA2dXtqb0rr5mrWT57jQaGjh1+13eKio+uXOo9Gs/NJC6+TZhdf7zQ38Ceg0HgF1MCP0AAAAASUVORK5CYII="; var iconADD = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACDUlEQVR42nWT30sUURTHz91Zd9FkVBRrX0oScTMI8weSIYSU/QMFbb5oGAn+AQo9B/UH9BAF+lIr+OLrSETQQ4GhEVRrUFkP/SLRNcvUnXv8nrmz7XVcB86cy7nn+5kz556ryHrueKxIYcFkPMmbxXHgzA6NDyguatQewBzHkKMMQDnWPgDsIwYh8/hATP8HQCRJEFIc5iA1DpljZIGogJU/9WXp39DR1pj99QBwe45dZb6UhCXE2Hx6m4xtQZQ/8SDni+DdSNopVYtysUiFpVbDqp4vPL4uCWc6zt+H+wvbAOBrCBCRFgh0AtIA6BboBVADc6eeZLMCGOq/kkF8Hcs8AO8tgDwav5M0AI/bw87Xw9dml+bvSUamtfsGYmuIrQDwKgIoQirkF3pR9uCbz28vx+tTMWo6VRdsL79eLax80yePtc3MTlwYKwMIT8HTvYufFkc+bq4NOjWN9Kf6cIVsHNr4sePnf9LxytqH06Od1w6oICGA9uZGOnvEpb7tgkrefLl8UXZvdTV5CYe3vv9Wzy6dVnfL9KAKfkcALeihaSKT+yj3Imji1XRPBvFyTTSn4LHMi5Y5SCnrGFc3c5MCqKtMD5c5RnsOisfILlmD1NxA5yThwy96GhkkRtlxrP3oIO0d5ZKXfSSbUYaJ1/tGef9lovAyUeQyAaKCO4nLpPRBABWJlwCWt6vYBccZ9A793wmLAAAAAElFTkSuQmCC"; var customBtn = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAjVJREFUeNqcUkuIUmEUPl4fML6bBsFRacRF2EaCcRO48bFLEIJcBIJLxb2b2UWLkIEgQQjauVFaKmgYuclUTMUHKoaKE4GPxnxh5r3ezh0QHJFmmA/OPZfDfx7fdw7AfojQ7qGx4QawdgMymeyRyWR6IZVKucFg8N10Ov0Ot4VGozmNRCLx5XL5F/HHbrefYZh7m1yWWq0+TafTn2kEdqXr9TrtcDje3JR4xRHH1QYCgXOz2Wzs9/sQj8dBIpEATtGrVqu9yWSywmdLNGq3AAeNsFgsz202mxk7QzKZBK1WCzqdjtHjKUmSx41Go4L+slQqpYvF4keKoibXpnA6nWfY+VehUKBSqRTJ0Oh2u3Qul6MHgwE9Ho9pLMD4H16v95zD4RxuU6BbrdYlPh5g8tfFYvET9XiIiRylUsnQgPl8DtgVhsOheL1eS6LRaGy1Wg02FAA5VmKxWB1/yUQioWOxWHKXy2XEYsDQEggEgKJCJpOBcrnMbOliW4MNSOaDCbVKpVISCoVGHBnQQygUgnK1AkeH9z+Ew+HX2xoQezZDjUaj3ygDiMViaLfbV8kK+TGw2WysJzzafry3QK1W+9Lr9RpIDbLZLEhE4vedTsdvMBieuN3ulwRBPLh2B7uYzWYXzWZzjBoc5PP5MJ70K1xfEsVc4cpNeDcnuLFvzM3978gILpcrRy/w+XybGE+v1z/z+/2frFarG9d5AHeBSqUyeDyetwqF4jHcFXw+/4TH44n+CTAA3Ccog288LRAAAAAASUVORK5CYII="; var saveAll = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACOElEQVR42mNkwAJ+7xf7//3tKwZeIUELRqf3JxnwAEZkzrtlwnv/MzE6/WfkWCwS/iTu7RLO/wzMPAwc/z4Lc0f/eIfTgP/7BM0PXDY5ofB9N8M/EB8k+BcoyQw1mEWd4SurLIO97lkUFzX9b/oPNmBznc7/////MbAzfIdoBoI/P77Abfnzn4XhH9A0kOLA7icQV88HKn0EdcH6Ss3/yM76/f0jg2vTXYZ/f39j9fdUgQkMdTp1DNFXoiEGrCzFNMCj6SrD/79/MDQzsbAzCEfyMTBwADkbGBjBBiwrRDXgF9AAz6ZLWF1QIlHCsFRnKdj2pYxLIQYsytPAMMC75SLYBVMkpzDkPM+By0lFSTEwCDAwvJ79eouoqKgv2IB5WWgGfPvI4N95kUEyQQwcJVXbq8CGeEp6MlzUuQi2fcKbCQgDZqWhG/CJIaDrLIPMf0kGBjeggAoDw5YNWxh8rHwYGMQZGB5PfszAysq6RUJCAmLAtCR1DAMCu08zzJSZxtDm0cbA8AQoyAxJGyDbWx+2MrCwsGyRkZGBGDApDpsBx8FhME95HkObfhtYM4MqA8OdnjtgNSAXyMvLQwzoi8JmwGF4NGoc12Bg6IHYXnuzFm6AsrIyxIAJ+UHXfj27oomIhc9AA/ajpAOdPToMV1yuwPnMzMxbNDU14QaEAqnGH28fqYGywt/fP5i8q5czYUtIMABygY6ODsSAJUuWOKMrUFHT2PPvzy90YZhX/79//36dt7d3KACPfPJHOU7GxAAAAABJRU5ErkJggg=="; let cIDs = ["custombuttons-contextpopup-exportXML", "custombuttons-contextpopup-exportXML-sub"]; let bIDs = ["custombuttons-contextpopup-bookmarkButton", "custombuttons-contextpopup-bookmarkButton-sub"]; addMenuItem(cIDs, bIDs, "Сохранить код кнопки в XML файл", saveImg9, "document.getElementById('" + this.id + "').saveXML(('triggerNode' in this.parentNode) " + "? this.parentNode.triggerNode.URI " + ": document.popupNode.URI);", "X"); let xIDs = ["custombuttons-contextpopup-importnewbutton", "custombuttons-contextpopup-importnewbutton-sub"]; let aIDs = ["custombuttons-contextpopup-addnewbutton", "custombuttons-contextpopup-addnewbutton-sub"]; addMenuItem(xIDs, aIDs, "Добавить кнопку из XML файла\u2026", loadImg, "document.getElementById('" + this.id + "').checkDocumentForCBXML(content.document);"); let fIDs = ["custombuttons-contextpopup-copyImageURI", "custombuttons-contextpopup-copyImageURI-sub"]; let b2IDs = ["custombuttons-contextpopup-copyURI", "custombuttons-contextpopup-copyURI-sub"]; addMenuItem(fIDs, b2IDs, "Копировать изображение кнопки в формате base64", saveImg1, "document.getElementById('" + this.id + "').copyImageURI();"); let f1IDs = ["custombuttons-contextpopup-saveButtonImage", "custombuttons-contextpopup-saveButtonImage-sub"]; addMenuItem(f1IDs, cIDs, "Сохранить изображение кнопки", saveImg8, "document.getElementById('" + this.id + "').saveImageURI();"); let f2IDs = ["custombuttons-contextpopup-copyButtonsCodeText", "custombuttons-contextpopup-copyButtonsCodeText-sub"]; addMenuItem(f2IDs, b2IDs, "Копировать код кнопки как текст", saveImg2, "document.getElementById('" + this.id + "').copyButtonsCodeText();"); let f3IDs = ["custombuttons-contextpopup-copyAsHTML", "custombuttons-contextpopup-copyAsHTML-sub"]; addMenuItem(f3IDs, b2IDs, "Копировать код кнопки как HTML ссылку", saveImg3, "document.getElementById('" + this.id + "').copyToHTMLCode();"); let f4Ds = ["custombuttons-contextpopup-copyToBBCode", "custombuttons-contextpopup-copyToBBCode-sub"]; addMenuItem(f4Ds, b2IDs, "Копировать код кнопки как BBcode сылку", saveImg4, "document.getElementById('" + this.id + "').copyToBBCode();"); let f5Ds = ["custombuttons-contextpopup-saveAsHTML", "custombuttons-contextpopup-saveAsHTML-sub"]; addMenuItem(f5Ds, bIDs, "Сохранить код кнопки в HTML файл", saveImg5, "document.getElementById('" + this.id + "').saveToHTMLCode();"); let f8Ds = ["custombuttons-contextpopup-saveAsHTMLAll", "custombuttons-contextpopup-AsHTMLAll-sub"]; addMenuItem(f8Ds, f5Ds, "Сохранить все кнопки в HTML файл", saveAll, "document.getElementById('" + this.id + "').saveToHTMLALLCode()"); let f6Ds = ["custombuttons-contextpopup-getButtonId", "custombuttons-contextpopup-getButtonId-sub"]; let b1IDs = ["custombuttons-contextpopup-remove", "custombuttons-contextpopup-remove-sub"]; addMenuItem(f6Ds, b1IDs, "Показать Id кнопки", saveImg6, "document.getElementById('" + this.id + "').idMIonclick(content.document);"); let f7Ds = ["custombuttons-contextpopup-addNextButton", "custombuttons-contextpopup-addNextButton-sub"]; var addMI = document.getElementById('custombuttons-contextpopup-addnewbutton'); addMI.setAttribute('image', iconADD); var addMI1 = document.getElementById('custombuttons-contextpopup-addnewbutton-sub'); addMI1.setAttribute('image', iconADD); var addMI2 = document.getElementById('custombuttons-contextpopup-move-moveToPanel'); addMI2.setAttribute('image', moveToMenu); var addMI3 = document.getElementById('custombuttons-contextpopup-move-removeFromToolbar'); addMI3.setAttribute('image', removeFromToolbar); var addMI4 = document.getElementById('custombuttons-contextpopup-customize'); addMI4.setAttribute('image', customBtn); 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(); } }); }; function readFile(aFile) { var data = ""; var fstream = Cc["@mozilla.org/network/file-input-stream;1"]. createInstance(Ci.nsIFileInputStream); fstream.init(aFile, -1, 0, 0); var charset = "UTF-8"; const replacementChar = Ci.nsIConverterInputStream .DEFAULT_REPLACEMENT_CHARACTER; var is = Cc["@mozilla.org/intl/converter-input-stream;1"]. createInstance(Ci.nsIConverterInputStream); is.init(fstream, charset, 1024, replacementChar); var str = {}; while (is.readString(4096, str) != 0) { data += str.value; } is.close(); return data; }; function stringToDOM(aString) { var parser = new DOMParser(); var dom = parser.parseFromString(aString, "text/xml"); if (dom.documentElement.nodeName == "parsererror") { return null; } else { return dom; } }; function importXMLtoButton(aStrXMLData) { loadURI("custombutton://" + escape(aStrXMLData)); }; function getCBOverlay() { var dirsvc = Cc["@mozilla.org/file/directory_service;1"]. getService(Ci.nsIProperties); var file = dirsvc.get("ProfD", Ci.nsIFile); file.append("custombuttons"); file.append("buttonsoverlay.xul"); return file; }; this.checkDocumentForCBXML = function checkDocumentForCBXML(aDocument) { if (((aDocument.contentType == "text/xml") || (aDocument.contentType == "application/xml"))&& (aDocument.documentElement.localName == "custombutton")) { var serializer = new XMLSerializer(); var xml = serializer.serializeToString(aDocument); importXMLtoButton(xml); } else { this.loadXML(); } }; this.loadXML = function loadXML() { var fp = window.makeFilePicker(); fp.init(window, "Установить кнопку из XML файла", nsIFilePicker.modeOpen); fp.appendFilters(fp.filterXML); fp.appendFilter("Все файлы", "*.*"); fp.displayDirectory = FileUtils.File( getPathToHtmlFileFolder() ); fp.open(re=> { if ( re == fp.returnOK ) gBrowser.selectedTab = gBrowser.addTab(fp.file.path); }) var xmlData = readFile(fp.file); var xmlDOM = stringToDOM(xmlData).documentElement; if (!xmlDOM) { custombuttons.alertBox("Импорт не удался", "Это не XML файл!"); return; } if ((xmlDOM.localName == "custombutton") && ((xmlDOM.getAttribute("xmlns:cb") == cbNamespace) || (xmlDOM.getAttribute("xmlns") == cbNamespace))) { importXMLtoButton(xmlData); } else { custombuttons.alertBox("Импорт не удался", "XML файл не содержит кнопок!"); } } this.copyImageURI = function copyImageURI() { var btn = document.popupNode; if (!btn) return; cbu.gClipboard.write(btn.image); var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService); as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "Изображение кнопки скопировано в буфер", false, "", null); } this.copyToHTMLCode = function copyToHTMLCode() { var btn = document.popupNode; if (!btn) return; var code = "<p><div id=\"install\" style=\"background: transparent -moz-linear-gradient(center top , rgb(224, 102, 255) 30%, rgb(125, 38, 205) 55%); text-shadow: 0pt -1px 0pt rgb(122, 55, 139); border: 1px outset rgb(85, 26, 139); border-radius: 1em; padding: 0; width: 240px; text-align: center;\"><a href=\"" + btn.URI + "\" style=\"display: block; padding: 1em; color: #ffffff; text-decoration: none;\" title=\"Click here to install " + btn.name + "\" rel=\"nofollow\"><img src=\"" + btn.image + "\" alt=\"" + btn.name + "\" style=\"vertical-align: middle; float: left;\"/>" + btn.name + "</a></div></p>"; cbu.gClipboard.write(code); var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService); as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "HTML кнопки скопирован в буфер", false, "", null); } this.copyToBBCode = function copyToBBCode() { var btn = document.popupNode; if (!btn) return; var code = "[url=" + btn.URI + "][B]" + btn.name + "[/B][/url]"; cbu.gClipboard.write(code); //.toXMLString()); var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService); as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "BBCode кнопки скопирован в буфер", false, "", null); } this.saveImageURI = function saveImageURI() { var btn = document.popupNode, br = gBrowser; if (!btn) return; if(btn.image != "") { var tab = br.mCurrentTab; br.selectedTab = br.addTab(btn.image); setTimeout( function() { window.content.document.title = btn.name; saveImageURL(gBrowser.mCurrentTab.image, "save", null, false, false, null, content.document) //saveDocument(window.content.document); br.removeCurrentTab(); br.selectedTab = tab; }, 200); } else custombuttons.alertBox("Эта кнопка не имееет изображения!"); } this.copyButtonsCodeText = function copyButtonsCodeText() { var btn = document.popupNode; if (!btn) return; var code = ((btn.cbCommand == "") || (btn.Command == "/*CODE*/")) ? "" : ("\n/*CODE*/\n" + btn.cbCommand + "\n"); var init = ((btn.cbInitCode == "") || (btn.cbInitCode == "/*Initialization Code*/")) ? "" : ("\n/*Initialization Code*/\n" + btn.cbInitCode); cbu.gClipboard.write(code + init); //custombuttons.alertSlide(btn.name, "Код скопирван в буфер"); var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService); as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "Код скопирван в буфер", false, "", null); } this.createNextButton = function(aButton) { custombuttons.cloneButton(aButton, true); window.setTimeout(function(){ if(!aButton.nextSibling.hasAttribute('initialized')) { custombuttons.editButton(aButton.nextSibling); } }) } this.saveXML = function saveXML(aStrURI) { var cbURI = (aStrURI != undefined) ? aStrURI : readFromClipboard(); if (!cbURI || !/^custombutton\:\/\//.test(cbURI)) { custombuttons.uChelpButton(this); return; } var cbXML = cbURI.replace(/^custombutton\:\/\//, ""); var decodeXML = unescape(cbXML); var btnName = decodeXML.match(/\<name\/?.+/).toString(); var name = "untitled"; if (!/\<name\/\>/.test(btnName)) { name = btnName.replace(/\<\/?\w+\>/g, "").toString(); } var image = decodeXML.match(/\<image\/?.+/).toString(); var icon = ""; if (!/\<\image.*\[\].*\>$/.test(image)) { icon = image.match(/[^\[\]]+/g)[2].toString() .replace(/custombuttons\-stdicon\-\d/, "").toString(); } function htmlEntities(str) { return str.replace(/&/g, "&").replace(/</g, "<") .replace(/>/g, ">").replace(/"/g, """); } var xmlTemplate = "custombuttons/\"\n\ xmlns:html=\"http://www.w3.org/1999/xhtml\">\n\ <html:head>\n\ <html:title><![CDATA[" + name + "]]></html:title>\n\ <html:link rel=\"shortcut icon\" href=\"" + icon + "\"/>\n\ <html:style type=\"text/css\"><![CDATA[\n\ body { font-size: medium; margin: 0; }\n\ body, code:before, help:before, initcode:before {\n\ font-family: \"Verdana\", sans-serif;\n\ }\n\ #wrapper { position: fixed; top: 1em; right: 1em; text-align: center; }\n\ p { font-size: small; text-align: center; }\n\ #button {\n\ background-color: rgb(85, 168, 2);\n\ background-image: linear-gradient(to bottom, rgb(147, 200, 94),\ rgb(85, 168, 2));\n\ background-image: -moz-linear-gradient(top, rgb(147, 200, 94),\ rgb(85, 168, 2));\n\ background-image: -o-linear-gradient(top, rgb(147, 200, 94),\ rgb(85, 168, 2));\n\ background-image: -webkit-linear-gradient(top, rgb(147, 200, 94),\ rgb(85, 168, 2));\n\ border: 1px solid rgb(58, 116, 4);\n\ border-radius: .5em;\n\ -moz-border-radius: .5em;\n\ -webkit-border-radius: .5em;\n\ padding: 0;\n\ margin-bottom: 1em;\n\ box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\ -moz-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\ -o-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\ -webkit-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\ }\n\ #button a {\n\ color: #000;\n\ text-shadow: -1pt -1px 0pt rgba(255, 255, 255, .5);\n\ padding: 1em;\n\ text-decoration: none;\n\ }\n\ :-moz-any-link:focus {\n\ color: white;\n\ outline-color: transparent;\n\ text-decoration: none;\n\ }\n\ #button a, code, code:before, initcode, initcode:before, help, help:before {\ \n display: block;\n\ }\n\ #credits { position: fixed; bottom: 1em; right: 1em; font-size: small; }\n\ custombutton { background-color: rgb(171, 171, 171); margin: 1em; }\n\ date, image, mode, accelkey { display: none; }\n\ name { font-weight: bold; font-size: x-large; }\n\ code:before, help:before, initcode:before {\n\ font-weight: bold;\n\ font-size: large;\n\ margin: 0 0 1em;\n\ padding: .5em;\n\ }\n\ code:before { content: \"Код\"; }\n\ help:before { content: \"Справка\"; }\n\ initcode:before { content: \"Инициализация\"; }\n\ code, initcode, help {\n\ background-color: rgb(255, 255, 255);\n\ border: 1px inset rgb(170, 170, 170);\n\ font: medium monospace;\n\ margin: 1em 1em 2em 0;\n\ padding: 1em;\n\ text-align: left;\n\ width: 840px;\n\ white-space: pre-wrap;\n\ word-wrap: break-word;\n\ }\n\ .clear { clear: both; }\n\ ]]></html:style>\n\ </html:head>\n\ <html:body>\n\ <html:div id=\"wrapper\">\n\ <html:div id=\"button\">\n\ <html:a href=\"" + cbURI + "\" rel=\"nofollow\" title=\"Установить " + htmlEntities(name, "ENT_COMPAT") +"\">\n\ <![CDATA[Установить кнопку]]>\n\ </html:a>\n\ </html:div>\n\ <html:div id=\"credits\">\n\ <html:a href=\"" + topicURL +"\">\n\ <![CDATA[Другие кнопки]]><html:br/>\ <![CDATA[на форуме Mozilla Россия]]>\n\ </html:a>\n\ </html:div>\n\ </html:div>\n\ </html:body>"; decodeXML = decodeXML.replace(/custombuttons\/\"\>/, xmlTemplate); name += ".xml"; saveToFile(decodeXML, name); var btn = document.popupNode; var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService); as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "сохранена в XML файл", false, "", null); } var mrw = mostRecentWindow('navigator:browser'); var css = '@-moz-document url("chrome://browser/content/browser.xul"){' + this.Help + '}'; var uri = makeURI('data:text/css,' + encodeURIComponent(css)); var sss = Components.classes['@mozilla.org/content/style-sheet-service;1'].getService(Components.interfaces.nsIStyleSheetService); if (!sss.sheetRegistered(uri, sss.USER_SHEET)) sss.loadAndRegisterSheet(uri, sss.USER_SHEET); this.idMIonclick = function idMIonclick() { var btn = document.popupNode.id; var box = custombuttons.confirmBox("Копировать в буфер", btn, "Да", "Нет"); if (box) { custombuttons.cbService.writeToClipboard(btn); custombuttons.alertSlide(btn, "Скопирована в буфер"); } } function mostRecentWindow(windowType) { return Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow(windowType); } this.saveToHTMLALLCode = function saveToHTMLALLCode() { var visibleCBbuttons = [...document.querySelectorAll('[cb-mode]')]; var paletteCBbuttons = [...custombuttons.palette.querySelectorAll('[cb-mode]')]; var allCBbuttons = visibleCBbuttons.concat(paletteCBbuttons); var array = []; allCBbuttons.forEach(but=> { var uri = but.URI ? but.URI : getPaleteButtonsURI(but); var name = but.getAttribute("label") || "Без названия"; var image = but.getAttribute("image") || "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACNFBMVEXDRgDweQDnbwC0NgDCRQC7PQDtpTu+QQD78q3PUwDCRAD//8vbYQDLTgDocAD0iQX1jQbGSgD7iAD4gwDVaw7vdwDyegD+igDweQDlawDyhAXveADmZwDzmBbtcwDwkhHveADmhBTkgxbweADkfRH+igD7hADXZQX0gADyjA/tfgvveQDiawDQVADRXgfnbwD1jAb9iQD9z0PVZAbxpinykRHtdgD5mRbERQDDRgDOYArCRAD9iQD3ewDxegD3dwDFRgDAQAD+hgD4fQDucgDtgQftfwTISQDCRQDvdgD5lxb1kRb2qh7wnynkagD766LDRQDDRwDDRQDspjbtpzbuqDbvqzv//8DUZAbCRQD//83pjhvveQbvggW+QQDfcxLlmUb//8veYADMTwDHSADVVwC8PgDwixb78q3oZgDUWADRVADCRQD9iQDERwDBQQDYVQC+PgC0NgDbYQDWWgDUWADSVQDFSAC+QAC7PAC0NgD+wRL+/kD+/zb+7i3+8Cv+/DX+wBL/+DD/rwz+qgz+rwz/tAz+sQzfbAT+3iP/+jD//Dz1jwP+nwf5iwf7pBz2tRr4lwb/ogfsdQT+2R7/9ET+2iT8yyLmgBL5iQL2egLokhP7zzT60zv1zUr0gAL1ewP50yn9+UL++EXooyngaAH41EPzowzyySj+xxzlhhHvvyruwjXxvTnUag3+zxrwigP+swz86U/ZXwD75lHqegD6xzb//kn+uhPTXAG3OAD/+UC2vFeJAAAAe3RSTlMAAAAAAAAAAAAAAAAAAAAAAAAAAACfnwAIaelpAAA2+wD7UQAAa3oArKzRzMysnwgAvPQA/gAAw3prw0oALr16vS4AACnF6bspAAAA/mIAADQAAAAAAI8AAEwA0vv7kd2yAuuvr+vKABL23U+8Sk/d9vUDIIAQAAAQgCAfvupHAAABB0lEQVR4Xi3IU3fDABgA0C+u26FdZ9u2bdu2vZSzbds2/tyac3IfLxjpGyA6MimqY6gHTNgiiNwkwRM1E7EhTrYyTfMzzsh0ZEPiH+D6+u5mV1jEhpe5haVCYW1T4suEvUOkk7PLpVJ5WFnl7hEUDN5LPvsHJ6cazdn13f3DYxu0B35+/Y2qVSr17NzGeUgohIVHLK/PMDa39qKieRATGxd/9cS4uU1MwnmQktqY/qGlaVr7/ZOVDTmQm5df8PwyNj4xOTVdjOM4kCRZOr+wWFa+srpWQVEU8PnV2zu7NbV19UfHDQRBAIfTdNHc0soVdnR2dfdgGAgEvW99/QNc4eDQ8O8Ihv0D77NPgbVLZ6kAAAAASUVORK5CYII="; array.push("<img src=" + image + "> <a href=" + uri + ">" + name +"</a><br>\n"); }); var before = "<html>\n<head>\n<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>\n</head>\n<body>\n"; var after = "\n</body>\n</html>"; var text = before + array.join("") + after; name = "CB buttons " + time + ".html" saveToFile(text, name); var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService) alertsService.showAlertNotification(saveImg5, "Экспорт в HTML", "Экспортировал все CB кнопки как HTML"); setTimeout(()=> alertsService.closeAlert(), 4000); }; this.saveToHTMLCode = function saveToHTMLCode() { var btn = document.popupNode; var xml = '<html xmlns="' + e4xConv_encodeHTML(xhtmlns, true) + '">\n\ <head>\n\ <meta http-equiv=\'Content-Type\' content=\'text/html; charset=utf-8\'/>\n\ <title>' + e4xConv_encodeHTML(btn.name + ' for Custom Buttons') + '</title>\n\ <link rel=\'icon\' type=\'image/vnd.microsoft.icon\' href="' + e4xConv_encodeHTML(btn.image, true) + '"/>\n\ <style type="text/css">\n\ .button a{\n\ background-color: rgb(85, 168, 2);\n\ background-image: linear-gradient(to bottom, rgb(147, 200, 94), rgb(85, 168, 2));\n\ background-image: -moz-linear-gradient(top, rgb(147, 200, 94), rgb(85, 168, 2));\n\ border: 1px solid rgb(58, 116, 4);\n\ border-radius: .5em;\n\ -webkit-border-radius: .5em;\n\ padding: 0;\n\ margin-bottom: 1em;\n\ box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\ -o-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\ -webkit-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\ color: #000;\n\ text-shadow: -1pt -1px 0pt rgba(255, 255, 255, .5);\n\ padding: 0.5em;\n\ text-decoration: none;\n\ }\n\ pre { border: 1px inset rgb(170, 170, 170); \n\ background-color: rgb(255, 255, 255);}\n\ body { background-color: rgb(245, 245, 220);} \n\ </style> \n\ </head>\n\ <body>\n\ <section id=\'install\'><h1>' + e4xConv_encodeHTML(btn.name) + '</h1>\n\ </section>\n\ <div class="button"><a href="' + e4xConv_encodeHTML(btn.URI, true) + '">Установить кнопку</a></div>\n\ <section id=\'init\'><h2>Инициализация</h2><pre>' + e4xConv_encodeHTML(btn.cbInitCode) + '</pre></section>\n\ <section id=\'code\'><h2>Код</h2><pre>' + e4xConv_encodeHTML(btn.cbCommand) + '</pre></section>\n\ <section id=\'help\'><h2>Справка</h2><pre>' + e4xConv_encodeHTML(btn.Help) + '</pre></section>\n\ </body>\n\ </html>'; var html = '<!DOCTYPE html>\n' + xml; var name = btn.name + ".HTML"; saveToFile(html, name); var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService); as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "сохранена в HTML файл", false, "", null); } function e4xConv_parseXULFromString(xul) { xul = xul.replace(/>\s+</g, "><"); return new DOMParser().parseFromString(xul, "application/xml").documentElement; } function e4xConv_encodeHTML(s, isAttr) { s = String(s) .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """); if(isAttr) { s = s .replace(/\t/g, "	") .replace(/\n/g, "
") .replace(/\r/g, "
"); } return s; }; function getPaleteButtonsURI(but) { var doc = document.implementation.createDocument("", "", null); doc.async = false; doc.load("chrome://custombuttons/content/nbftemplate.xml"); ["help,Help", "name,label", "image,image", "mode,cb-mode", "initcode,cb-init", "accelkey,cb-accelkey", "code,cb-oncommand"] .forEach(str=> { var arr = str.split(','); var value = but.getAttribute(arr[1]), name = arr[0]; custombutton.buttonSetText(doc, name, value, true); }); var ser = new XMLSerializer(); return "custombutton://" + escape(ser.serializeToString(doc)); };
Отредактировано Andrey_Krropotkin (24-12-2018 14:29:43)
Отсутствует
Dumby подскажи пожалуйста 61 работало а на 63 нет - конструкции примерно такого типа. Окно загружается, все кнопки в окне работают, но сам документ в окне нет и везде ссылается на dialog.document.getElementById("listbox").selectAll();.
Может опять triggering principal или listbox поломали?
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 += '<listbox id="listbox" flex="1" style=" background: #FFF; border: 1px solid #999; border-radius: 8px 8px 8px 8px; box-shadow: 3px 3px 3px #444; padding-top: 4px;">'; data += '<listcols>'; data += '<listcol/>'; data += '<listcol flex="1"/>'; data += '</listcols>'; data += '</listbox>'; 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("listitem"); var cell = document.createElement("listcell"); 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+ } .... .... .... 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=780,height=410,alwaysRaised"; dialog = window.openDialog(url, "", feature);
Отредактировано Andrey_Krropotkin (24-12-2018 15:12:40)
Отсутствует
добавить в кнопку Autocopy работающую в 63+, функцию замены выделенного текста вставляемым по СКМ
Ну, если настройка middlemouse.paste выключена,
то можно попробовать заменить handleEvent.
//handleEvent(e) {e.button || this[e.type](e);}, handleEvent(e) { if (e.button != 1) return e.button || this[e.type](e); var ed = e.type[5] == "d" && !e.ctrlKey && e.target.editor; if ( ed && ed instanceof Ci.nsIEditor && ed.canPaste(ed.selectionController.SELECTION_NORMAL) ) e.preventDefault(), ed.paste(ed.selectionController.SELECTION_NORMAL); },
сделать отдельной кнопкой функцию сохранения изображений без запроса по двойному ПКМ на них
Так в «OLD Autocopy» ядро для этого, вроде, вполне рабочее.
Если страница превентит контекстое меню, то придётся кликать с зажатым Shift.
addEventListener("contextmenu", { handleEvent(e) { if (e.detail != 2 || !gContextMenu || !gContextMenu.onImage) return; var pl = "browser.download.folderList"; var pu = "browser.download.useDownloadDir"; var cl = Services.prefs.getIntPref(pl), sl = cl == 2; var cu = Services.prefs.getBoolPref(pu); sl || Services.prefs.setIntPref(pl, 2); cu || Services.prefs.setBoolPref(pu, true); try { this.save(); e.preventDefault(); this.hide(); } finally { sl || Services.prefs.setIntPref(pl, cl); cu || Services.prefs.setBoolPref(pu, cu); } }, get hide() { delete this.hide; var popup = document.getElementById("contentAreaContextMenu"); return this.hide = popup.hidePopup.bind(popup); }, get save() { var func = eval(gContextMenu.saveMedia.toSource() .replace(/(false,\s+)false,/, "$1true,") .replace(/^s/, "0,function s") ); delete this.save; return this.save = () => func.call(gContextMenu); } }, false, gBrowser.tabpanels || gBrowser.mPanelContainer || 1);
или listbox поломали?
Отредактировано Dumby (24-12-2018 17:47:13)
Отсутствует
Dumby наверно последний вопрос по 63 Пытаюсь набросать кнопку - открыть ссылку в сайдбаре, что не получается. С menuitem и toolbarbutton понятно, а вот с browser не понятно. Как его явно объявить? Не могли Вы простеькую набросать кнопочку?
Теперь по 64 - не работает
- var refNode = document.getAnonymousElementByAttribute(gFindBar, 'anonid', 'highlight'); пишет не найден, чем можно заменить?
- у кнопки search-go-button убрали anoid. Если раньше было var btn = document.getAnonymousElementByAttribute(bar, "anonid", "search-go-button");
btn.setAttribute("hidden", "false");, то как теперь сделать стрелку всегда видимой?
PS. Не критично (очень редко пользуюсь) - в кнопке консоль браузера (в вашей последней) в командной строке не видно контекстного меню.
Отредактировано Andrey_Krropotkin (25-12-2018 12:08:18)
Отсутствует
Dumby
Всё работает, но, к сожалению без middlemouse.paste очень некомфортно, обретая одно удобство теряется другое, а с ним двоит. Если будет время и вообще возможно с этим справиться, прошу Вас помочь. Сохранение по 2ПКМ работает отлично, спасибо большое!
Отсутствует
Подскажите, использую автоматическую настройку прокси. Но иногда глючит, тогда меняю адрес на другой. Возможно это сделать с помощью кнопки. К примеру нажал и выбираешь какой использовать, или автоматом поменялись.
FF ESR52
Отсутствует
вопрос по 63 Пытаюсь набросать кнопку - открыть ссылку в сайдбаре, что не получается. С menuitem и toolbarbutton понятно, а вот с browser не понятно. Как его явно объявить? Не могли Вы простеькую набросать кнопочку?
Side View что ли пишешь ? А кнопочку набросать,
ну могу попробовать простенькую, в смысле неполноценную.
(id => { var label = "CB Sidebar Loader"; var url = "chrome://browser/content/webext-panels.xul?" + id; var icon = "chrome://devtools/skin/images/dock-side-left.svg"; var defaultURL = "data:text/html;charset=utf-8,<center><h1>Заглушка</h1></center>"; var currentURL; var e = (name, attrs, node, append) => { var elm = document.createElement(name); for(var a in attrs) elm.setAttribute(a, attrs[a]); append ? node.append(elm) : node.before(elm); return elm; } var menuitem = e("menuitem", { label, type: "checkbox", id: "menu_CBSidebarLoader", oncommand: `SidebarUI.toggle("${id}");`, }, document.getElementById("viewSidebarMenu"), true); var btn = e("toolbarbutton", { label, type: "checkbox", oncommand: "handleCommand();", id: "sidebar-switcher-CBSidebarLoader", class: "subviewbutton subviewbutton-iconic" }, document.querySelector('toolbarbutton[id^="sidebar-switcher-"] + toolbarseparator')); SidebarUI.sidebars.set(id, { url, title: label, buttonId: btn.id, menuId: menuitem.id, }); var css = `\ #${btn.id} > .toolbarbutton-icon, #sidebar-box[sidebarcommand="${id}"] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon { width: 16px; height: 16px; opacity: 0.8; fill: currentColor; -moz-context-properties: fill; list-style-image: url(${icon}); }`; var str = "data:text/css," + encodeURIComponent(css), type = windowUtils.USER_SHEET; windowUtils.loadSheetUsingURIString(str, type); addDestructor(() => { btn.remove(); menuitem.remove(); SidebarUI.sidebars.delete(id); windowUtils.removeSheetUsingURIString(str, type); }); var isActive = () => SidebarUI.isOpen && SidebarUI.currentID == id; if (isActive()) { SidebarUI.selectMenuItem(id); var doc = SidebarUI.browser.contentDocument; if (doc.readyState != "complete") return; var br = doc.getElementById("webext-panels-browser"); if (br) currentURL = br.currentURI.spec; } btn.handleCommand = () => { if (!btn.hasAttribute("checked")) { SidebarUI._switcherPanel.hidePopup(); btn.setAttribute("checked", true); } loadURL(gBrowser.currentURI.spec); } this.onclick = e => { if (!e.button) loadURL(gBrowser.currentURI.spec); else if (e.button == 1) SidebarUI.toggle(id); } addEventListener("load", e => e.target.documentURI == url && load(currentURL || defaultURL) , true, SidebarUI.browser); var loadURL = url => { currentURL = url; isActive() ? load(url) : SidebarUI.show(id); } var principal = {triggeringPrincipal: document.nodePrincipal}; var config = {browserStyle: false, extension: {remote: false}}; var load = async url => { var win = SidebarUI.browser.contentWindow; var br = win.document.getElementById("webext-panels-browser"); if (br) { if (br.currentURI.spec === url) return; br.parentNode.remove(); } var br = await win.getBrowser(config); win.onunload = () => currentURL = br.currentURI.spec; br.loadURI(url, principal); } })("viewCBSidebarLoader");
без middlemouse.paste очень некомфортно
То есть, если что-то выделено, тогда клик СКМ (в любом месте текстового поля)
должен вставлять с заменой выделенного. А если выделенного текста нет,
тогда не делать ничего, а вставится так, ну как это сделает сам middlemouse.paste
Если всё верно, тогда пропробуй, на замену, новый handleEvent
handleEvent(e) { if (e.type[0] == "m") return e.button || this[e.type](e); else if (e.button != 1) return; var ed = e.target.editor; if ( ed && ed instanceof Ci.nsIEditor && !ed.selection.isCollapsed && ed.canPaste(ed.selectionController.SELECTION_NORMAL) ) e.preventDefault(), ed.paste(ed.selectionController.SELECTION_NORMAL); },
init(cfmm) { this.count += 1; cfmm.addEventListener("click", this, true); cfmm.addEventListener("mousedown", this); cfmm.addEventListener("mouseup", this); cfmm.addEventListener("unload", this); if (this.count == 1) this.cpmm.addMessageListener("%ID%:FromParent", this); }, destroy(cfmm) { this.count -= 1; cfmm.removeEventListener("click", this, true); cfmm.removeEventListener("mousedown", this); cfmm.removeEventListener("mouseup", this); cfmm.removeEventListener("unload", this); if (!this.count) this.cpmm.removeMessageListener("%ID%:FromParent", this); },
Отсутствует
Dumby
Спасибо огромнейшее, всё работает! Впечатляет, насколько Вы разбираетесь в кодинге. А может можно парой строчек добавить и авто-замену выделенного по СКМ в поисковой (Ctrl+F) и адресной строке, т.е. в том, что вставляет middlemouse.paste? В оригинальной Autocopy от bunda1, правда, была проблема, в связи с тем, что выделяемый текст ещё и копировался, приходилось сначала выделять старый поиск, удалять, копировать нужное и вставлять, а это забывалось.
Вы где-нибудь выкладываете свои кнопки?
/*Initialization Code*/ this.closest("toolbarpaletteitem") || (script => { var id = `CB${_id.slice(20)}:Autocopy`, pid = id + "Parent"; var nsvoStr = `Components.utils.import("resource://gre/modules/Services.jsm", {})`; var nsvo = eval(nsvoStr), {Services} = nsvo, parent = nsvo[pid]; if (!parent) { var cid = id + "Child", u = code => "data:," + encodeURIComponent(code); var pref = "CB.Autocopy.settings", topic = "quit-application-granted"; var PREF_ENABLED = 1, PREF_BLINK = 2, PREF_RESET = 4; (parent = nsvo[pid] = { init() { this.readSettings(); if (!this[PREF_ENABLED]) return; this.initChild(); if (this[PREF_RESET]) this.setObserver(true); }, destroy(reason) { var ud = reason[5] == "e"; if (ud || !this.obsAdded) this.saveSettings(); delete nsvo[pid]; if (reason == "delete") Services.prefs.clearUserPref(pref); if (!this[PREF_ENABLED]) return; this.destroyChild(); if (ud && this[PREF_RESET]) this.setObserver(false); }, get processURL() { delete this.processURL; this.frameURL = u(`${nsvoStr}["${cid}"].init(this);`); return this.processURL = u(script.replace(/%ID%/g, cid) .replace("%NSVO%", nsvoStr).replace("%BLINK%", this[PREF_BLINK]) ); }, get frameURLDestroy() { delete this.frameURLDestroy; this.processURLDestroy = u(`${nsvoStr}["${cid}"].forget();`); return this.frameURLDestroy = u(`${nsvoStr}["${cid}"].destroy(this);`); }, initChild() { Services.ppmm.loadProcessScript(this.processURL, true); Services.mm.loadFrameScript(this.frameURL, true); }, destroyChild() { Services.mm.removeDelayedFrameScript(this.frameURL); Services.mm.loadFrameScript(this.frameURLDestroy, false); Services.ppmm.removeDelayedProcessScript(this.processURL); Services.ppmm.loadProcessScript(this.processURLDestroy, false); }, readSettings() { this.prefVal = Services.prefs.getIntPref(pref, 3); for(var setting of [PREF_ENABLED, PREF_BLINK, PREF_RESET]) this[setting] = Boolean(this.prefVal & setting); }, saveSettings() { var settings = 0; for(var setting of [PREF_ENABLED, PREF_BLINK, PREF_RESET]) if (this[setting]) settings += setting; if (this.prefVal != settings) Services.prefs.setIntPref(pref, settings); }, btns: new Set(), register(btn) { this.btns.add(btn); btn._handleClick = this.click; btn.oncontextmenu = this.context; this.setImg(btn, this[PREF_ENABLED]); }, unregister(btn, reason) { this.btns.delete(btn); if (!this.btns.size) this.destroy(reason); }, setImg(btn, state) { btn.ownerDocument.getAnonymousElementByAttribute( btn, "class", "toolbarbutton-icon" ).src = state ? "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgMBAAQIAAcEBwAIBAcACAQHAAgEBwAIBAcACAQHAAgEBwAIBAcACAMEAQEAAAAAAAAAAAAAAAACAwADAAAAABUnAB9cqgC3a7wB4Gq5Ad1qugHearoB3mq6Ad5qugHearoB3mi4AN1qugHgYrMAxR43AC8AAAAAAAEAAAECAAQAAAQAV6AAprP9Vv/W/qn80/+f/9T/ov/U/6L/1P+i/9T/ov/U/6L/1/+n/9X+pfy3/WL/Y7QAvwEAAQAAAAAAFSgAH1ehAKlyzwD1htgf/YzcJ/2K2yP9i9sk/YvbJf2L2yX9i9sm/YnaIv2b4kP92/21/Nf+qv9quwHdBQkACAAAAQBeqwCzr/tR/8X0j/u+8X//vvJ//77ygP++8oD/vvKA/77yf/+98n7/wvSH/4zcKv+e4kv93v+0/2i5AN0DBwAIBQkACGu8AdzV/af/4v/B/d//u//h/7//4f+//+H/v//h/7//4f+//9/+u//n/8n/w/GK/4zaK/3g/7r/aroC3gMHAAgEBwAIarkC3dX/pf/g/sD93v67/9/+vv/g/r//4P6//+D+v//f/r7/3f66/+T/xv/B8Yb/j9st/eT/w/9qugPeAwcACAQHAAhqugLe2v+w/+j/z/3l/8r/5//N/+f/zv/n/87/5//O/+f/zf/l/sj/7P/W/8Xyj/+Q2y/96f/N/2q6A94DBwAIBAcACGq6At7f/7n/7v/c/ev/1v/t/9n/7f/a/+3/2v/t/9r/7f/Z/+r+1f/y/+P/yPKW/5DbMf3s/9X/aroE3gMHAAgEBwAIaroC3uP/wf/z/+j98P/h//L/5P/z/+X/8//l//P/5f/y/+T/8P7g//j/7v/L8p3/kdsy/fD/3P9rugTeAwcACAQHAAhqugLe5v/J//j/8v31/+r/9v/t//f/7v/3/+//9//u//b/7f/0/un//f/4/87yo/+R2zL98f/f/2q5Bd0DBwAIBAcACGq6At7p/8///P/6/fj/8f/6//T/+v/1//r/9f/6//X/+v/0//f+8P//////0fGo/5PbNf30/+f/a7wE3AQJAAgEBwAIabkC3er/0f/+//79+v/0//v/9//8//j//P/4//z/+P/7//f/+f70///////T8qz/i9go+8P9ef9dqwCzAAACAAUJAAhquwHd7f7a//////z+//39/////f////3////9/////f////39/vz9/////dzzvv5v0AD1VqECqRUnAB8AAAAAAQACAGK0AL/J/Yf/8v7k/O3/1//u/9n/7v/Z/+7/2f/u/9n/7v/Z/+3/1//x/eP8vfxu/1WgAKYAAAUAAQIABAABAAAAAAAAHjcALmGzAMVquwLgarkC3Wq6At5qugLearoC3mq6At5qugLearkC3Wu8AeBbqgC3FScAHwAAAAACAwADAAAAAAAAAAAAAAAAAwQCAQQIAAgEBwAIBAcACAQHAAgEBwAIBAcACAQHAAgEBwAIBAgABwMDAgAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" : "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgEDAAQACAcEAAcIBAAHCAQABwgEAAcIBAAHCAQABwgEAAcIBAAHCAMBBAEAAAAAAAAAAAAAAAACAAMDAAAAABUAJx9cAKq3awG84GoBud1qAbreagG63moBut5qAbreagG63mgAuN1qAbrgYgCzxR4ANy8AAAAAAAABAAEAAgQABAAAVwCgprNW/f/Wqf7805///9Si///Uov//1KL//9Si///Uov//16f//9Wl/vy3Yv3/YwC0vwEBAAAAAAAAFQAoH1cAoalyAM/1hh/Y/Ywn3P2KI9v9iyTb/Ysl2/2LJdv9iybb/Yki2v2bQ+L927X9/Neq/v9qAbvdBQAJCAABAABeAKuzr1H7/8WP9Pu+f/H/vn/y/76A8v++gPL/voDy/75/8v+9fvL/wof0/4wq3P+eS+L93rT//2gAud0DAAcIBQAJCGsBvNzVp/3/4sH//d+7///hv///4b///+G////hv///4b///9+7/v/nyf//w4rx/4wr2v3guv//agK63gMABwgEAAcIagK53dWl///gwP793rv+/9++/v/gv/7/4L/+/+C//v/fvv7/3br+/+TG///BhvH/jy3b/eTD//9qA7reAwAHCAQABwhqArre2rD//+jP//3lyv//583//+fO///nzv//587//+fN///lyP7/7Nb//8WP8v+QL9v96c3//2oDut4DAAcIBAAHCGoCut7fuf//7tz//evW///t2f//7dr//+3a///t2v//7dn//+rV/v/y4///yJby/5Ax2/3s1f//agS63gMABwgEAAcIagK63uPB///z6P/98OH///Lk///z5f//8+X///Pl///y5P//8OD+//ju///LnfL/kTLb/fDc//9rBLreAwAHCAQABwhqArre5sn///jy//316v//9u3///fu///37///9+7///bt///06f7//fj//86j8v+RMtv98d///2oFud0DAAcIBAAHCGoCut7pz////Pr//fjx///69P//+vX///r1///69f//+vT///fw/v//////0ajx/5M12/305///awS83AQACQgEAAcIaQK53erR///+/v/9+vT///v3///8+P///Pj///z4///79///+fT+///////TrPL/iyjY+8N5/f9dAKuzAAIAAAUACQhqAbvd7dr+//////z+/f/9/////f////3////9/////f////39/P79/////dy+8/5vAND1VgKhqRUAJx8AAAAAAQIAAGIAtL/Jh/3/8uT+/O3X///u2f//7tn//+7Z///u2f//7tn//+3X///x4/38vW78/1UAoKYABQAAAQACBAAAAQAAAAAAHgA3LmEAs8VqArvgagK53WoCut5qArreagK63moCut5qArreagK53WsBvOBbAKq3FQAnHwAAAAACAAMDAAAAAAAAAAAAAAAAAwIEAQQACAgEAAcIBAAHCAQABwgEAAcIBAAHCAQABwgEAAcIBAAIBwMCAwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }, click() { var newState = parent[PREF_ENABLED] = !parent[PREF_ENABLED]; for(var btn of parent.btns) parent.setImg(btn, newState); newState ? parent.initChild() : parent.destroyChild(); if (parent[PREF_RESET]) parent.setObserver(newState); }, context(e) { if (e.ctrlKey || e.shiftKey) return; if (e.detail > 1) return parent.popup.hidePopup(); if (!this.contains(parent.popup)) this.appendChild(parent.popup); e.preventDefault(); parent.popup.openPopup(this, "after_start"); }, get popup() { var win = Services.wm.getMostRecentWindow("navigator:browser"); var doc = win.document, popup = doc.createElement("menupopup"); popup.setAttribute("onclick", "event.stopPropagation();"); popup.setAttribute("oncommand", "handleCommand(event.target);"); for(var [lab, pref] of win.Object.entries({ "Выделенный текст мигает при автокопировании": PREF_BLINK, "Выключать автокопирование при выходе из браузера": PREF_RESET })) { var menuitem = popup.appendChild(doc.createElement("menuitem")); menuitem.setAttribute("label", lab); menuitem.setAttribute("type", "checkbox"); if (this[menuitem.pref = pref]) menuitem.setAttribute("checked", true); } popup.handleCommand = menuitem => { var newState = this[menuitem.pref] = menuitem.hasAttribute("checked"); if (!this[PREF_ENABLED]) return; if (menuitem.pref == PREF_BLINK) Services.ppmm.broadcastAsyncMessage(cid + ":FromParent", {blink: newState}); else if (menuitem.pref == PREF_RESET) this.setObserver(newState); } delete this.popup; return this.popup = popup; }, obsAdded: false, setObserver(set) {this.obsAdded = set ? Services.obs.addObserver(this, topic, false) : Services.obs.removeObserver(this, topic); }, observe() { Services.obs.removeObserver(this, topic); this[PREF_ENABLED] = false; this.saveSettings(); } }).init(); } parent.register(this); addDestructor(reason => parent.unregister(this, reason), parent); })(`(nsvo => (nsvo["%ID%"] = { x: -1, y: -1, d: false, handleEvent(e) { if (e.type[0] == "m") return e.button || this[e.type](e); else if (e.button != 1) return; var ed = e.target.editor; if ( ed && ed instanceof Ci.nsIEditor && !ed.selection.isCollapsed && ed.canPaste(ed.selectionController.SELECTION_NORMAL) ) e.preventDefault(), ed.paste(ed.selectionController.SELECTION_NORMAL); }, mousedown(e) {this.x = e.screenX; this.y = e.screenY, this.down = true;}, mouseup(e) { var {down} = this; this.down = false; if (!down) return; if (e.screenX == this.x && e.screenY == this.y && (e.detail == 1 || e.target.matches( "textarea[disabled],input[disabled],button,select,summary" ))) return; var name = e.originalTarget.nodeName; if (/^(?:(?:xul:)?(?:slider|scrollbarbutton)|resizer)$/.test(name)) return; this.x = this.y = -1; var win = this.getFocusedWin(e.target.ownerGlobal); var sel = win.getSelection(); if (sel.toString()) { (win.docShell || win.document.docShell).doCommand("cmd_copy", null, win); this.blinkEnabled && this.blink(win, e.detail > 1); } }, blinkEnabled: %BLINK%, blink(win, pause) { if (pause) return win.setTimeout(() => this.blink(win), 100); var sc = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShell) .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsISelectionDisplay) .QueryInterface(Components.interfaces.nsISelectionController); sc.setDisplaySelection(sc.SELECTION_OFF); sc.repaintSelection(sc.SELECTION_NORMAL); win.setTimeout(() => { sc.setDisplaySelection(sc.SELECTION_ON); sc.repaintSelection(sc.SELECTION_NORMAL); }, 150); }, getFocusedWin(win) { var focusedWin = {}; var elm = Services.focus.getFocusedElementForWindow(win.top, true, focusedWin); return focusedWin.value; }, get cm() { delete this.cm; return this.cm = Components.classes["@mozilla.org/embedcomp/command-manager;1"] .getService(Components.interfaces.nsICommandManager); }, count: 0, init(cfmm) { this.count += 1; cfmm.addEventListener("click", this, true); cfmm.addEventListener("mousedown", this); cfmm.addEventListener("mouseup", this); cfmm.addEventListener("unload", this); if (this.count == 1) this.cpmm.addMessageListener("%ID%:FromParent", this); }, destroy(cfmm) { this.count -= 1; cfmm.removeEventListener("click", this, true); cfmm.removeEventListener("mousedown", this); cfmm.removeEventListener("mouseup", this); cfmm.removeEventListener("unload", this); if (!this.count) this.cpmm.removeMessageListener("%ID%:FromParent", this); }, receiveMessage(msg) { if ("blink" in msg.data) this.blinkEnabled = msg.data.blink; }, unload(e) {this.destroy(e.target);}, forget: () => delete nsvo["%ID%"] }).cpmm = this)(%NSVO%);`);
Отсутствует
Теперь по 64 - не работает
- var refNode = document.getAnonymousElementByAttribute(gFindBar, 'anonid', 'highlight'); пишет не найден, чем можно заменить?
- у кнопки search-go-button убрали anoid. Если раньше было var btn = document.getAnonymousElementByAttribute(bar, "anonid", "search-go-button");
btn.setAttribute("hidden", "false");, то как теперь сделать стрелку всегда видимой?
в командной строке не видно контекстного меню
Для Firefox 64+, если приемлимо, что в linkset'е останется link,
можно просто добавить куда-нибудь в середину init()
"insertFTLIfNeeded" in MozXULElement && MozXULElement .insertFTLIfNeeded("toolkit/main-window/editmenu.ftl");
А может можно парой строчек добавить и авто-замену выделенного по СКМ в поисковой (Ctrl+F) и адресной строке, т.е. в том, что вставляет middlemouse.paste?
Нет, нельзя. Действие происходит там, где ни адресной ни поисковой строки нет.
Нужен listener в окне браузера, а так всё то же самое.
addEventListener("click", e => { if (e.button != 1) return; var ed = e.target.editor; if ( ed && ed instanceof Ci.nsIEditor && !ed.selection.isCollapsed && ed.canPaste(ed.selectionController.SELECTION_NORMAL) ) e.preventDefault(), ed.paste(ed.selectionController.SELECTION_NORMAL); }, true);
Отсутствует
Dumby
Я же говорю, волшебник. Спасибо большое! Так Вы нигде не выкладываете кнопки?
/*Initialization Code*/ this.closest("toolbarpaletteitem") || (script => { var id = `CB${_id.slice(20)}:Autocopy`, pid = id + "Parent"; var nsvoStr = `Components.utils.import("resource://gre/modules/Services.jsm", {})`; var nsvo = eval(nsvoStr), {Services} = nsvo, parent = nsvo[pid]; if (!parent) { var cid = id + "Child", u = code => "data:," + encodeURIComponent(code); var pref = "CB.Autocopy.settings", topic = "quit-application-granted"; var PREF_ENABLED = 1, PREF_BLINK = 2, PREF_RESET = 4; (parent = nsvo[pid] = { init() { this.readSettings(); if (!this[PREF_ENABLED]) return; this.initChild(); if (this[PREF_RESET]) this.setObserver(true); }, destroy(reason) { var ud = reason[5] == "e"; if (ud || !this.obsAdded) this.saveSettings(); delete nsvo[pid]; if (reason == "delete") Services.prefs.clearUserPref(pref); if (!this[PREF_ENABLED]) return; this.destroyChild(); if (ud && this[PREF_RESET]) this.setObserver(false); }, get processURL() { delete this.processURL; this.frameURL = u(`${nsvoStr}["${cid}"].init(this);`); return this.processURL = u(script.replace(/%ID%/g, cid) .replace("%NSVO%", nsvoStr).replace("%BLINK%", this[PREF_BLINK]) ); }, get frameURLDestroy() { delete this.frameURLDestroy; this.processURLDestroy = u(`${nsvoStr}["${cid}"].forget();`); return this.frameURLDestroy = u(`${nsvoStr}["${cid}"].destroy(this);`); }, initChild() { Services.ppmm.loadProcessScript(this.processURL, true); Services.mm.loadFrameScript(this.frameURL, true); }, destroyChild() { Services.mm.removeDelayedFrameScript(this.frameURL); Services.mm.loadFrameScript(this.frameURLDestroy, false); Services.ppmm.removeDelayedProcessScript(this.processURL); Services.ppmm.loadProcessScript(this.processURLDestroy, false); }, readSettings() { this.prefVal = Services.prefs.getIntPref(pref, 3); for(var setting of [PREF_ENABLED, PREF_BLINK, PREF_RESET]) this[setting] = Boolean(this.prefVal & setting); }, saveSettings() { var settings = 0; for(var setting of [PREF_ENABLED, PREF_BLINK, PREF_RESET]) if (this[setting]) settings += setting; if (this.prefVal != settings) Services.prefs.setIntPref(pref, settings); }, btns: new Set(), register(btn) { this.btns.add(btn); btn._handleClick = this.click; btn.oncontextmenu = this.context; this.setImg(btn, this[PREF_ENABLED]); }, unregister(btn, reason) { this.btns.delete(btn); if (!this.btns.size) this.destroy(reason); }, setImg(btn, state) { btn.ownerDocument.getAnonymousElementByAttribute( btn, "class", "toolbarbutton-icon" ).src = state ? "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgMBAAQIAAcEBwAIBAcACAQHAAgEBwAIBAcACAQHAAgEBwAIBAcACAMEAQEAAAAAAAAAAAAAAAACAwADAAAAABUnAB9cqgC3a7wB4Gq5Ad1qugHearoB3mq6Ad5qugHearoB3mi4AN1qugHgYrMAxR43AC8AAAAAAAEAAAECAAQAAAQAV6AAprP9Vv/W/qn80/+f/9T/ov/U/6L/1P+i/9T/ov/U/6L/1/+n/9X+pfy3/WL/Y7QAvwEAAQAAAAAAFSgAH1ehAKlyzwD1htgf/YzcJ/2K2yP9i9sk/YvbJf2L2yX9i9sm/YnaIv2b4kP92/21/Nf+qv9quwHdBQkACAAAAQBeqwCzr/tR/8X0j/u+8X//vvJ//77ygP++8oD/vvKA/77yf/+98n7/wvSH/4zcKv+e4kv93v+0/2i5AN0DBwAIBQkACGu8AdzV/af/4v/B/d//u//h/7//4f+//+H/v//h/7//4f+//9/+u//n/8n/w/GK/4zaK/3g/7r/aroC3gMHAAgEBwAIarkC3dX/pf/g/sD93v67/9/+vv/g/r//4P6//+D+v//f/r7/3f66/+T/xv/B8Yb/j9st/eT/w/9qugPeAwcACAQHAAhqugLe2v+w/+j/z/3l/8r/5//N/+f/zv/n/87/5//O/+f/zf/l/sj/7P/W/8Xyj/+Q2y/96f/N/2q6A94DBwAIBAcACGq6At7f/7n/7v/c/ev/1v/t/9n/7f/a/+3/2v/t/9r/7f/Z/+r+1f/y/+P/yPKW/5DbMf3s/9X/aroE3gMHAAgEBwAIaroC3uP/wf/z/+j98P/h//L/5P/z/+X/8//l//P/5f/y/+T/8P7g//j/7v/L8p3/kdsy/fD/3P9rugTeAwcACAQHAAhqugLe5v/J//j/8v31/+r/9v/t//f/7v/3/+//9//u//b/7f/0/un//f/4/87yo/+R2zL98f/f/2q5Bd0DBwAIBAcACGq6At7p/8///P/6/fj/8f/6//T/+v/1//r/9f/6//X/+v/0//f+8P//////0fGo/5PbNf30/+f/a7wE3AQJAAgEBwAIabkC3er/0f/+//79+v/0//v/9//8//j//P/4//z/+P/7//f/+f70///////T8qz/i9go+8P9ef9dqwCzAAACAAUJAAhquwHd7f7a//////z+//39/////f////3////9/////f////39/vz9/////dzzvv5v0AD1VqECqRUnAB8AAAAAAQACAGK0AL/J/Yf/8v7k/O3/1//u/9n/7v/Z/+7/2f/u/9n/7v/Z/+3/1//x/eP8vfxu/1WgAKYAAAUAAQIABAABAAAAAAAAHjcALmGzAMVquwLgarkC3Wq6At5qugLearoC3mq6At5qugLearkC3Wu8AeBbqgC3FScAHwAAAAACAwADAAAAAAAAAAAAAAAAAwQCAQQIAAgEBwAIBAcACAQHAAgEBwAIBAcACAQHAAgEBwAIBAgABwMDAgAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" : "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgEDAAQACAcEAAcIBAAHCAQABwgEAAcIBAAHCAQABwgEAAcIBAAHCAMBBAEAAAAAAAAAAAAAAAACAAMDAAAAABUAJx9cAKq3awG84GoBud1qAbreagG63moBut5qAbreagG63mgAuN1qAbrgYgCzxR4ANy8AAAAAAAABAAEAAgQABAAAVwCgprNW/f/Wqf7805///9Si///Uov//1KL//9Si///Uov//16f//9Wl/vy3Yv3/YwC0vwEBAAAAAAAAFQAoH1cAoalyAM/1hh/Y/Ywn3P2KI9v9iyTb/Ysl2/2LJdv9iybb/Yki2v2bQ+L927X9/Neq/v9qAbvdBQAJCAABAABeAKuzr1H7/8WP9Pu+f/H/vn/y/76A8v++gPL/voDy/75/8v+9fvL/wof0/4wq3P+eS+L93rT//2gAud0DAAcIBQAJCGsBvNzVp/3/4sH//d+7///hv///4b///+G////hv///4b///9+7/v/nyf//w4rx/4wr2v3guv//agK63gMABwgEAAcIagK53dWl///gwP793rv+/9++/v/gv/7/4L/+/+C//v/fvv7/3br+/+TG///BhvH/jy3b/eTD//9qA7reAwAHCAQABwhqArre2rD//+jP//3lyv//583//+fO///nzv//587//+fN///lyP7/7Nb//8WP8v+QL9v96c3//2oDut4DAAcIBAAHCGoCut7fuf//7tz//evW///t2f//7dr//+3a///t2v//7dn//+rV/v/y4///yJby/5Ax2/3s1f//agS63gMABwgEAAcIagK63uPB///z6P/98OH///Lk///z5f//8+X///Pl///y5P//8OD+//ju///LnfL/kTLb/fDc//9rBLreAwAHCAQABwhqArre5sn///jy//316v//9u3///fu///37///9+7///bt///06f7//fj//86j8v+RMtv98d///2oFud0DAAcIBAAHCGoCut7pz////Pr//fjx///69P//+vX///r1///69f//+vT///fw/v//////0ajx/5M12/305///awS83AQACQgEAAcIaQK53erR///+/v/9+vT///v3///8+P///Pj///z4///79///+fT+///////TrPL/iyjY+8N5/f9dAKuzAAIAAAUACQhqAbvd7dr+//////z+/f/9/////f////3////9/////f////39/P79/////dy+8/5vAND1VgKhqRUAJx8AAAAAAQIAAGIAtL/Jh/3/8uT+/O3X///u2f//7tn//+7Z///u2f//7tn//+3X///x4/38vW78/1UAoKYABQAAAQACBAAAAQAAAAAAHgA3LmEAs8VqArvgagK53WoCut5qArreagK63moCut5qArreagK53WsBvOBbAKq3FQAnHwAAAAACAAMDAAAAAAAAAAAAAAAAAwIEAQQACAgEAAcIBAAHCAQABwgEAAcIBAAHCAQABwgEAAcIBAAIBwMCAwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }, click() { var newState = parent[PREF_ENABLED] = !parent[PREF_ENABLED]; for(var btn of parent.btns) parent.setImg(btn, newState); newState ? parent.initChild() : parent.destroyChild(); if (parent[PREF_RESET]) parent.setObserver(newState); }, context(e) { if (e.ctrlKey || e.shiftKey) return; if (e.detail > 1) return parent.popup.hidePopup(); if (!this.contains(parent.popup)) this.appendChild(parent.popup); e.preventDefault(); parent.popup.openPopup(this, "after_start"); }, get popup() { var win = Services.wm.getMostRecentWindow("navigator:browser"); var doc = win.document, popup = doc.createElement("menupopup"); popup.setAttribute("onclick", "event.stopPropagation();"); popup.setAttribute("oncommand", "handleCommand(event.target);"); for(var [lab, pref] of win.Object.entries({ "Выделенный текст мигает при автокопировании": PREF_BLINK, "Выключать автокопирование при выходе из браузера": PREF_RESET })) { var menuitem = popup.appendChild(doc.createElement("menuitem")); menuitem.setAttribute("label", lab); menuitem.setAttribute("type", "checkbox"); if (this[menuitem.pref = pref]) menuitem.setAttribute("checked", true); } popup.handleCommand = menuitem => { var newState = this[menuitem.pref] = menuitem.hasAttribute("checked"); if (!this[PREF_ENABLED]) return; if (menuitem.pref == PREF_BLINK) Services.ppmm.broadcastAsyncMessage(cid + ":FromParent", {blink: newState}); else if (menuitem.pref == PREF_RESET) this.setObserver(newState); } delete this.popup; return this.popup = popup; }, obsAdded: false, setObserver(set) {this.obsAdded = set ? Services.obs.addObserver(this, topic, false) : Services.obs.removeObserver(this, topic); }, observe() { Services.obs.removeObserver(this, topic); this[PREF_ENABLED] = false; this.saveSettings(); } }).init(); } parent.register(this); addDestructor(reason => parent.unregister(this, reason), parent); })(`(nsvo => (nsvo["%ID%"] = { x: -1, y: -1, d: false, handleEvent(e) { if (e.type[0] == "m") return e.button || this[e.type](e); else if (e.button != 1) return; var ed = e.target.editor; if ( ed && ed instanceof Ci.nsIEditor && !ed.selection.isCollapsed && ed.canPaste(ed.selectionController.SELECTION_NORMAL) ) e.preventDefault(), ed.paste(ed.selectionController.SELECTION_NORMAL); }, mousedown(e) {this.x = e.screenX; this.y = e.screenY, this.down = true;}, mouseup(e) { var {down} = this; this.down = false; if (!down) return; if (e.screenX == this.x && e.screenY == this.y && (e.detail == 1 || e.target.matches( "textarea[disabled],input[disabled],button,select,summary" ))) return; var name = e.originalTarget.nodeName; if (/^(?:(?:xul:)?(?:slider|scrollbarbutton)|resizer)$/.test(name)) return; this.x = this.y = -1; var win = this.getFocusedWin(e.target.ownerGlobal); var sel = win.getSelection(); if (sel.toString()) { (win.docShell || win.document.docShell).doCommand("cmd_copy", null, win); this.blinkEnabled && this.blink(win, e.detail > 1); } }, blinkEnabled: %BLINK%, blink(win, pause) { if (pause) return win.setTimeout(() => this.blink(win), 100); var sc = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShell) .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsISelectionDisplay) .QueryInterface(Components.interfaces.nsISelectionController); sc.setDisplaySelection(sc.SELECTION_OFF); sc.repaintSelection(sc.SELECTION_NORMAL); win.setTimeout(() => { sc.setDisplaySelection(sc.SELECTION_ON); sc.repaintSelection(sc.SELECTION_NORMAL); }, 150); }, getFocusedWin(win) { var focusedWin = {}; var elm = Services.focus.getFocusedElementForWindow(win.top, true, focusedWin); return focusedWin.value; }, get cm() { delete this.cm; return this.cm = Components.classes["@mozilla.org/embedcomp/command-manager;1"] .getService(Components.interfaces.nsICommandManager); }, count: 0, init(cfmm) { this.count += 1; cfmm.addEventListener("click", this, true); cfmm.addEventListener("mousedown", this); cfmm.addEventListener("mouseup", this); cfmm.addEventListener("unload", this); if (this.count == 1) this.cpmm.addMessageListener("%ID%:FromParent", this); }, destroy(cfmm) { this.count -= 1; cfmm.removeEventListener("click", this, true); cfmm.removeEventListener("mousedown", this); cfmm.removeEventListener("mouseup", this); cfmm.removeEventListener("unload", this); if (!this.count) this.cpmm.removeMessageListener("%ID%:FromParent", this); }, receiveMessage(msg) { if ("blink" in msg.data) this.blinkEnabled = msg.data.blink; }, unload(e) {this.destroy(e.target);}, forget: () => delete nsvo["%ID%"] }).cpmm = this)(%NSVO%);`); addEventListener("click", e => { if (e.button != 1) return; var ed = e.target.editor; if ( ed && ed instanceof Ci.nsIEditor && !ed.selection.isCollapsed && ed.canPaste(ed.selectionController.SELECTION_NORMAL) ) e.preventDefault(), ed.paste(ed.selectionController.SELECTION_NORMAL); }, true);
Отсутствует
Dumby спасибо, теперь все свои кнопки до актуальных поднял. А может случится чудо и Вы еще Dom inspector c колен подымите, а то неудобно одной только кнопкой пользоваться там где штатный не может.
Отсутствует
Andrey_Krropotkin
Если не сложно, выложите их в теме Готовые кнопки для Custom Buttons, а то столько полезного размазано по форуму и даже не знаешь, что такое есть.
Отсутствует
Karn они в основном сделаны для моих предпочтений. Вообще то я не автор кнопок, я только исправлял и делал под себя, поэтому я там выложить не могу. Для меня это будут лишние заботы, так как от версии к версии много изменений и лучше я здесь буду отвечать на вопросы и выкладывать.
Отсутствует
Infocatcher если Вы еще не ушли с Firefox, можете подправить свои кнопки для 64 Edit_Custom_Button_in_Tab и Check for Addons Updates? Первая вообще не хочет работать, вторая работает только при открытой вкладке "Дополнения"
Отсутствует