Dobrov
Не все пользуются версией с CustomStylesScripts.jsm и прочими scriptsbackground: [ // В фоне [System Principal]. Мне эта версия UCF непонятна, лично я на старой остался.
Отредактировано xrun1 (15-07-2022 04:27:15)
Отсутствует
Не все пользуются версией с CustomStylesScripts.jsm. Мне эта версия UCF непонятна, лично я на старой остался.
Дополнил шапку, добавил custom_script.js - скрипты добавлять здесь: (async () => { ["ucf_SessionManager.js"]. Процитирую скрипт из шапки:
// Этот скрипт можно использовать для создания кнопок с помощью CustomizableUI.createWidget (async (scripts) => { // подключить внешние скрипты [['ucf_QuickToggle.js'], ['UCFTitleChangedChild.jsm', 'registerUCFTitleChanged'], ['Test.jsm']] .forEach(function(js) { try { if (/\.jsm$/i.test(js[0])) { // [скрипт js или jsm, инициализация] var obj = ChromeUtils.import(scripts + js[0]); js[1] && obj[js[1]](); } else Services.scriptloader.loadSubScript(scripts + js[0]); } catch(ex) {Cu.reportError(ex);} }); })('chrome://user_chrome_files/content/custom_scripts/'); /* вариант с отдельными скриптами: (async () => { var loadscript = (name, funcName) => { try { var {href, pathname} = new URL(`chrome://user_chrome_files/content/custom_scripts/${name}`); if (/\.jsm$/i.test(pathname)) { var obj = ChromeUtils.import(href); funcName && obj[funcName](); } else Services.scriptloader.loadSubScript(href); } catch(ex) {Cu.reportError(ex);} } loadscript("ucf_aom-button.js"); loadscript("UCFTitleChangedChild.jsm", "registerUCFTitleChanged"); })(); */
Скачал этот профиль, посмотрел, почитал - слишком много разных фишек, многие мне ни о чем не говорят, другие мне просто не нужны.
Какие фишки непонятны? Описание есть в спойлере шапки и встроенной справке (спойлер "Полный список▼").
Сообщите, какие конкретно скрипты непонятны и я дополню описание..
Ещё можно убрать ненужные скрипты из CustomStylesScripts.jsm и CustomStylesScriptsChild.jsm, оставив базовый ucf_hookClicks.js и нужный вам ucf_SessionManager.js. Впрочем дополнительные скрипты требуют значительно меньше памяти, чем дополнения.
Отредактировано Dobrov (15-07-2022 05:37:18)
Отсутствует
ez7pac
xrun1
Этот скрипт... вроде работает в версии UCF 2021-6-5 -> https://forum.mozilla-russia.org/viewto … 17#p797517, код под первым спойлером.
Add, добавить в user_chrome_files/custom_scripts/custom_script.js
Отредактировано kokoss (15-07-2022 20:02:14)
Win7
Отсутствует
Сообщите, какие конкретно скрипты непонятны и я дополню описание..
Да не то, чтобы непонятны, просто я мельком пробежался, сильно не вникал. Я ставлю обычно только то, что мне нужно и полезно на данный момент. Ставить пак, пусть и хороший, "шоб було" , ради одной фишки - не мое. Вот сейчас из всего списка меня заинтересовал только менеджер сессий. А перебирать пак, удаляя ненужное мне - это косяки, глюки, нервотрепка и т.п. Элементарно не хватит знаний.
Этот скрипт... вроде работает в версии UCF 2021-6-5 -> https://forum.mozilla-russia.org/viewto … 17#p797517, код под первым спойлером.
Спасибо. Но код - это хорошо, но еще бы знать куда его впихнуть и не накосячить при этом...
Я в принцип работы UCF не въезжаю вообще. userChrome, userContent - еще так, с пятое на десятое, и то нужно носом ткнуть - "вот этот код добавить вот сюда и не забудь вот эту запятую поставить". А UCF - это уже другой уровень.
Отсутствует
Add, добавить в user_chrome_files/custom_scripts/custom_script.js
Только сейчас увидел ответ. И снова спасибо! Добавил, кнопка появилась, работает менеджер. Я извиняюсь, конечно, но возникли пара вопросов.
1. Работает только ручное сохранение или можно выставить в авто? Если можно, то как включить и как настроить периодичность?
2. Где хранятся сессии?
Отсутствует
1. Работает только ручное сохранение или можно выставить в авто? Если можно, то как включить и как настроить периодичность?
2. Где хранятся сессии?
Сесии храняться в «Профиль Firefox//chrome/simple_session_manager.json»
С авто-сохранением и таймером для него надо обращаться к Dumby, он этот скрипт делал.
Отсутствует
Уважаемые гуру, подскажите, пожалуйста. Есть вот такой скрипт, прекрасно работает на 78. А на 101 не грузится меню с подключёнными стилями (остальное работает). Это реально поправить?
Отсутствует
Есть вот такой скрипт
Пробуй, проверял на 103, в консоли ошибок нет...
// ==UserScript== // @name UserCSSLoader // @description Stylish みたいなもの // @namespace http://d.hatena.ne.jp/Griever/ // @author Griever // @include main // @license MIT License // @compatibility Firefox 4 // @charset UTF-8 // @version 0.0.4改 // @startup UCL.init(); // @note 0.0.4 Remove E4X // @note CSSEntry クラスを作った // @note スタイルのテスト機能を作り直した // @note ファイルが削除された場合 rebuild 時に CSS を解除しメニューを消すようにした // @note uc で読み込まれた .uc.css の再読み込みに仮対応 // ==/UserScript== /****** 使い方 ****** chrome フォルダに CSS フォルダが作成されるのでそこに .css をぶち込むだけ。 ファイル名が "xul-" で始まる物、".as.css" で終わる物は AGENT_SHEET で、それ以外は USER_SHEET で読み込む。 ファイルの内容はチェックしないので @namespace 忘れに注意。 メニューバーに CSS メニューが追加される メニューを左クリックすると ON/OFF 中クリックするとメニューを閉じずに ON/OFF 右クリックするとエディタで開く エディタは "view_source.editor.path" に指定されているものを使う フォルダは "UserCSSLoader.FOLDER" にパスを入れれば変更可能 **** 説明終わり ****/ (function(){ let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; if (!window.Services) Cu.import("resource://gre/modules/Services.jsm"); // 起動時に他の窓がある(2窓目の)場合は抜ける let list = Services.wm.getEnumerator("navigator:browser"); while(list.hasMoreElements()){ if(list.getNext() != window) return; } if (window.UCL) { window.UCL.destroy(); delete window.UCL; } const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; window.UCL = { IN_TOOLMENU: false, // true: ツールメニュー内、 false:メインメニューのヘルプの前 USE_UC: "UC" in window, AGENT_SHEET: Ci.nsIStyleSheetService.AGENT_SHEET, USER_SHEET : Ci.nsIStyleSheetService.USER_SHEET, readCSS : {}, get disabled_list() { let obj = []; try { obj = decodeURIComponent(this.prefs.getCharPref("disabled_list")).split("|"); } catch(e) {} delete this.disabled_list; return this.disabled_list = obj; }, get prefs() { delete this.prefs; return this.prefs = Services.prefs.getBranch("UserCSSLoader.") }, get styleSheetServices(){ delete this.styleSheetServices; return this.styleSheetServices = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); }, get FOLDER() { let aFolder; try { // UserCSSLoader.FOLDER があればそれを使う let folderPath = this.prefs.getCharPref("FOLDER"); aFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile) aFolder.initWithPath(folderPath); } catch (e) { aFolder = Services.dirsvc.get("UChrm", Ci.nsIFile); aFolder.appendRelativePath("CSS"); } if (!aFolder.exists() || !aFolder.isDirectory()) { aFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0664); } delete this.FOLDER; return this.FOLDER = aFolder; }, getFocusedWindow: function() { let win = document.commandDispatcher.focusedWindow; if (!win || win == window) win = content; return win; }, init: function() { const cssmenu = $C("menu", { id: "usercssloader-menu", label: "CSS", accesskey: "C" }); const menupopup = $C("menupopup", { id: "usercssloader-menupopup" }); cssmenu.appendChild(menupopup); let menu = $C("menu", { label: "メニュ━━━(゚∀゚)━━━!!", accesskey: "C" }); menupopup.appendChild(menu); let mp = $C("menupopup", { id: "usercssloader-submenupopup" }); menu.appendChild(mp); mp.appendChild($C("menuitem", { label: "Rebuld", accesskey: "R", acceltext: "Alt + R", oncommand: "UCL.rebuild();" })); mp.appendChild($C("menuseparator")); mp.appendChild($C("menuitem", { label: "新規作成", accesskey: "N", oncommand: "UCL.create();" })); mp.appendChild($C("menuitem", { label: "CSS フォルダを開く", accesskey: "O", oncommand: "UCL.openFolder();" })); mp.appendChild($C("menuitem", { label: "userChrome.css を編集", // hidden: true, oncommand: "UCL.editUserCSS(\'userChrome.css\');" })); mp.appendChild($C("menuitem", { label: "userContent.css を編集", // hidden: true, oncommand: "UCL.editUserCSS(\'userContent.css\');" })); mp.appendChild($C("menuseparator")); mp.appendChild($C("menuitem", { label: "スタイルのテスト (Chrome)", id: "usercssloader-test-chrome", hidden: true, accesskey: "C", oncommand: "UCL.styleTest(window);" })); mp.appendChild($C("menuitem", { label: "スタイルのテスト (Webページ)", id: "usercssloader-test-content", hidden: true, accesskey: "W", oncommand: "UCL.styleTest();" })); mp.appendChild($C("menuitem", { label: "userstyles.org でスタイルを検索", accesskey: "S", oncommand: "UCL.searchStyle();" })); menu = $C("menu", { label: ".uc.css", accesskey: "U", hidden: !UCL.USE_UC }); menupopup.appendChild(menu); mp = $C("menupopup", { id: "usercssloader-ucmenupopup" }); menu.appendChild(mp); mp.appendChild($C("menuitem", { label: "Rebuild(.uc.js)", oncommand: "UCL.UCrebuild();" })); mp.appendChild($C("menuseparator", { id: "usercssloader-ucsepalator" })); if (this.IN_TOOLMENU) { $('menu_ToolsPopup').insertBefore(cssmenu, $('menu_preferences')); } else { $('main-menubar').insertBefore(cssmenu, $('helpMenu')); } $("mainKeyset").appendChild($C("key", { id: "usercssloader-rebuild-key", oncommand: "UCL.rebuild();", key: "R", modifiers: "alt", })); this.rebuild(); this.initialized = true; if (UCL.USE_UC) { setTimeout(function() { UCL.UCcreateMenuitem(); }, 1000); } window.addEventListener("unload", this, false); }, uninit: function() { const dis = []; for (let x of Object.keys(this.readCSS)) { if (!this.readCSS[x].enabled) dis.push(x); } this.prefs.setCharPref("disabled_list", encodeURIComponent(dis.join("|"))); window.removeEventListener("unload", this, false); }, destroy: function() { var i = document.getElementById("usercssloader-menu"); if (i) i.parentNode.removeChild(i); var i = document.getElementById("usercssloader-rebuild-key"); if (i) i.parentNode.removeChild(i); this.uninit(); }, handleEvent: function(event) { switch(event.type){ case "unload": this.uninit(); break; } }, rebuild: function() { let ext = /\.css$/i; let not = /\.uc\.css/i; let files = this.FOLDER.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator); while (files.hasMoreElements()) { let file = files.getNext().QueryInterface(Ci.nsIFile); if (!ext.test(file.leafName) || not.test(file.leafName)) continue; let CSS = this.loadCSS(file); CSS.flag = true; } for (let leafName of Object.keys(this.readCSS)) { const CSS = this.readCSS[leafName]; if (!CSS.flag) { CSS.enabled = false; delete this.readCSS[leafName]; } delete CSS.flag; this.rebuildMenu(leafName); } if (this.initialized) { if (typeof(StatusPanel) !== "undefined") StatusPanel._label = "Rebuild しました"; else XULBrowserWindow.statusTextField.label = "Rebuild しました"; } }, loadCSS: function(aFile) { var CSS = this.readCSS[aFile.leafName]; if (!CSS) { CSS = this.readCSS[aFile.leafName] = new CSSEntry(aFile); if (this.disabled_list.indexOf(CSS.leafName) === -1) { CSS.enabled = true; } } else if (CSS.enabled) { CSS.enabled = true; } return CSS; }, rebuildMenu: function(aLeafName) { var CSS = this.readCSS[aLeafName]; var menuitem = document.getElementById("usercssloader-" + aLeafName); if (!CSS) { if (menuitem) menuitem.parentNode.removeChild(menuitem); return; } if (!menuitem) { menuitem = $C("menuitem", { label : aLeafName, id : "usercssloader-" + aLeafName, class : "usercssloader-item " + (CSS.SHEET == this.AGENT_SHEET? "AGENT_SHEET" : "USER_SHEET"), type : "checkbox", autocheck : "false", oncommand : "UCL.toggle('"+ aLeafName +"');", onclick : "UCL.itemClick(event);" }); document.getElementById("usercssloader-menupopup").appendChild(menuitem); } menuitem.setAttribute("checked", CSS.enabled); }, toggle: function(aLeafName) { var CSS = this.readCSS[aLeafName]; if (!CSS) return; CSS.enabled = !CSS.enabled; this.rebuildMenu(aLeafName); }, itemClick: function(event) { if (event.button == 0) return; event.preventDefault(); event.stopPropagation(); let label = event.currentTarget.getAttribute("label"); if (event.button == 1) { this.toggle(label); } else if (event.button == 2) { closeMenus(event.target); this.edit(this.getFileFromLeafName(label)); } }, getFileFromLeafName: function(aLeafName) { let f = this.FOLDER.clone(); f.QueryInterface(Ci.nsIFile); // use appendRelativePath f.appendRelativePath(aLeafName); return f; }, styleTest: function(aWindow) { aWindow || (aWindow = this.getFocusedWindow()); new CSSTester(aWindow, function(tester){ if (tester.saved) UCL.rebuild(); }); }, searchStyle: function() { let word; try { word = gBrowser.currentURI.host; } catch { word = gBrowser.currentURI.spec; } let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); openLinkIn("https://userstyles.org/styles/search/" + word, "tab", { private: false, inBackground: false, relatedToCurrent: true, triggeringPrincipal: systemPrincipal, }); }, openFolder: function() { this.FOLDER.launch(); }, editUserCSS: function(aLeafName) { let file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.appendRelativePath(aLeafName); this.edit(file); }, edit: function(aFile) { var editor = Services.prefs.getCharPref("view_source.editor.path"); if (!editor) return alert("エディタのパスが未設定です。\n view_source.editor.path を設定してください"); try { var UI = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); UI.charset = window.navigator.platform.toLowerCase().indexOf("win") >= 0? "Shift_JIS": "UTF-8"; var path = UI.ConvertFromUnicode(aFile.path); var app = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); app.initWithPath(editor); var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); process.init(app); process.run(false, [path], 1); } catch (e) {} }, create: function(aLeafName) { if (!aLeafName) aLeafName = prompt("ファイル名を入力してください", dateFormat(new Date(), "%Y_%m%d_%H%M%S")); if (aLeafName) aLeafName = aLeafName.replace(/\s+/g, " ").replace(/[\\/:*?\"<>|]/g, ""); if (!aLeafName || !/\S/.test(aLeafName)) return; if (!/\.css$/.test(aLeafName)) aLeafName += ".css"; let file = this.getFileFromLeafName(aLeafName); this.edit(file); }, UCrebuild: function() { let re = /^file:.*\.uc\.css(?:\?\d+)?$/i; let query = "?" + new Date().getTime(); Array.prototype.slice(document.styleSheets).forEach(function(css){ if (!re.test(css.href)) return; if (css.ownerNode) { css.ownerNode.parentNode.removeChild(css.ownerNode); } let pi = document.createProcessingInstruction('xml-stylesheet','type="text/css" href="'+ css.href.replace(/\?.*/, '') + query +'"'); document.insertBefore(pi, document.documentElement); }); UCL.UCcreateMenuitem(); }, UCcreateMenuitem: function() { let sep = $("usercssloader-ucsepalator"); let popup = sep.parentNode; if (sep.nextSibling) { let range = document.createRange(); range.setStartAfter(sep); range.setEndAfter(popup.lastChild); range.deleteContents(); range.detach(); } let re = /^file:.*\.uc\.css(?:\?\d+)?$/i; Array.prototype.slice(document.styleSheets).forEach(function(css) { if (!re.test(css.href)) return; let fileURL = decodeURIComponent(css.href).split("?")[0]; let aLeafName = fileURL.split("/").pop(); let m = $C("menuitem", { label : aLeafName, tooltiptext : fileURL, id : "usercssloader-" + aLeafName, type : "checkbox", autocheck : "false", checked : "true", oncommand : "this.setAttribute('checked', !(this.css.disabled = !this.css.disabled));", onclick : "UCL.UCItemClick(event);" }); m.css = css; popup.appendChild(m); }); }, UCItemClick: function(event) { if (event.button == 0) return; event.preventDefault(); event.stopPropagation(); if (event.button == 1) { event.target.doCommand(); } else if (event.button == 2) { closeMenus(event.target); let fileURL = event.currentTarget.getAttribute("tooltiptext"); let file = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getFileFromURLSpec(fileURL); this.edit(file); } }, }; function CSSEntry(aFile) { this.path = aFile.path; this.leafName = aFile.leafName; this.lastModifiedTime = 1; this.SHEET = /^xul-|\.as\.css$/i.test(this.leafName) ? Ci.nsIStyleSheetService.AGENT_SHEET: Ci.nsIStyleSheetService.USER_SHEET; } CSSEntry.prototype = { sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService), _enabled: false, get enabled() { return this._enabled; }, set enabled(isEnable) { var aFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile) aFile.initWithPath(this.path); var isExists = aFile.exists(); // ファイルが存在したら true var lastModifiedTime = isExists ? aFile.lastModifiedTime : 0; var isForced = this.lastModifiedTime != lastModifiedTime; // ファイルに変更があれば true var fileURL; try { fileURL = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromFile(aFile); } catch { fileURL = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromActualFile(aFile); } var uri = Services.io.newURI(fileURL, null, null); if (this.sss.sheetRegistered(uri, this.SHEET)) { // すでにこのファイルが読み込まれている場合 if (!isEnable || !isExists) { this.sss.unregisterSheet(uri, this.SHEET); } else if (isForced) { // 解除後に登録し直す this.sss.unregisterSheet(uri, this.SHEET); this.sss.loadAndRegisterSheet(uri, this.SHEET); } } else { // このファイルは読み込まれていない if (isEnable && isExists) { this.sss.loadAndRegisterSheet(uri, this.SHEET); } } if (this.lastModifiedTime !== 1 && isEnable && isForced) { log(this.leafName + " の更新を確認しました。"); } this.lastModifiedTime = lastModifiedTime; return this._enabled = isEnable; }, }; function CSSTester(aWindow, aCallback) { this.win = aWindow || window; this.doc = this.win.document; this.callback = aCallback; this.init(); } CSSTester.prototype = { sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService), preview_code: "", saved: false, init: function() { this.dialog = openDialog( "data:text/html;charset=utf8,"+encodeURIComponent('<!DOCTYPE HTML><html lang="ja"><head><title>CSSTester</title></head><body></body></html>'), "", "width=550,height=400,dialog=no"); this.dialog.addEventListener("load", this, false); }, destroy: function() { this.preview_end(); this.dialog.removeEventListener("unload", this, false); this.previewButton.removeEventListener("click", this, false); this.saveButton.removeEventListener("click", this, false); this.closeButton.removeEventListener("click", this, false); }, handleEvent: function(event) { switch(event.type) { case "click": if (event.button != 0) return; if (this.previewButton == event.currentTarget) { this.preview(); } else if (this.saveButton == event.currentTarget) { this.save(); } else if (this.closeButton == event.currentTarget) { this.dialog.close(); } break; case "load": var doc = this.dialog.document; doc.body.innerHTML = '\ <style type="text/css">\ :not(input):not(select) { padding: 0px; margin: 0px; }\ table { border-spacing: 0px; }\ body, html, #main, #textarea { width: 100%; height: 100%; }\ #textarea { font-family: monospace; }\ </style>\ <table id="main">\ <tr height="100%">\ <td colspan="4"><textarea id="textarea"></textarea></td>\ </tr>\ <tr height="40">\ <td><input type="button" value="Preview" /></td>\ <td><input type="button" value="Save" /></td>\ <td width="80%"><span class="log"></span></td>\ <td><input type="button" value="Close" /></td>\ </tr>\ </table>\ '; this.textbox = doc.querySelector("textarea"); this.previewButton = doc.querySelector('input[value="Preview"]'); this.saveButton = doc.querySelector('input[value="Save"]'); this.closeButton = doc.querySelector('input[value="Close"]'); this.logField = doc.querySelector('.log'); var code = "@namespace url(" + this.doc.documentElement.namespaceURI + ");\n"; code += this.win.location.protocol.indexOf("http") === 0? "@-moz-document domain(" + this.win.location.host + ") {\n\n\n\n}": "@-moz-document url(" + this.win.location.href + ") {\n\n\n\n}"; this.textbox.value = code; this.dialog.addEventListener("unload", this, false); this.previewButton.addEventListener("click", this, false); this.saveButton.addEventListener("click", this, false); this.closeButton.addEventListener("click", this, false); this.textbox.focus(); let p = this.textbox.value.length - 3; this.textbox.setSelectionRange(p, p); break; case "unload": this.destroy(); this.callback(this); break; } }, preview: function() { var code = this.textbox.value; if (!code || !/\:/.test(code)) return; code = "data:text/css;charset=utf-8," + encodeURIComponent(this.textbox.value); if (code == this.preview_code) return; this.preview_end(); var uri = Services.io.newURI(code, null, null); this.sss.loadAndRegisterSheet(uri, Ci.nsIStyleSheetService.AGENT_SHEET); this.preview_code = code; this.log("Preview"); }, preview_end: function() { if (this.preview_code) { let uri = Services.io.newURI(this.preview_code, null, null); this.sss.unregisterSheet(uri, Ci.nsIStyleSheetService.AGENT_SHEET); this.preview_code = ""; } }, save: function() { var data = this.textbox.value; if (!data) return; var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(window, "", Ci.nsIFilePicker.modeSave); fp.appendFilter("CSS Files","*.css"); fp.defaultExtension = "css"; if (window.UCL) fp.displayDirectory = UCL.FOLDER; var res = fp.show(); if (res != fp.returnOK && res != fp.returnReplace) return; var suConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); suConverter.charset = "UTF-8"; data = suConverter.ConvertFromUnicode(data); var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); foStream.init(fp.file, 0x02 | 0x08 | 0x20, 0664, 0); foStream.write(data, data.length); foStream.close(); this.saved = true; }, log: function() { this.logField.textContent = dateFormat(new Date(), "%H:%M:%S") + ": " + $A(arguments); } }; UCL.init(); function $(id) { return document.getElementById(id); } function $A(arr) { return Array.prototype.slice(arr); } function $C(name, attr) { const el = document.createElementNS(XULNS, name); if (attr) Object.keys(attr).forEach(function(n) { el.setAttribute(n, attr[n]) }); return el; } function dateFormat(date, format) { format = format.replace("%Y", ("000" + date.getFullYear()).substr(-4)); format = format.replace("%m", ("0" + (date.getMonth()+1)).substr(-2)); format = format.replace("%d", ("0" + date.getDay()).substr(-2)); format = format.replace("%H", ("0" + date.getHours()).substr(-2)); format = format.replace("%M", ("0" + date.getMinutes()).substr(-2)); format = format.replace("%S", ("0" + date.getSeconds()).substr(-2)); return format; } function log() { Application.console.log(Array.prototype.slice(arguments)); } })();
Жизнь иногда такое выкидывает, что хочется подобрать...
Отсутствует
Farby
Меню появилось, но стили не отключаются и не обновляются. Проверял на чистой 102 ESR.
UPD Скрипт заработал! Правда, запускается он каким-то извращённым способом: во-первых, ему нужен пустой (ну или запиканный звёздочками) userChrome.css. В принципе, он его и так игнорит, но ни в 78, ни в доквантумных версиях наличие записей там ему не мешало. А во-вторых, после редактирования userChrome.css обновить надо через кнопку Reload user{Chrome, Content}.css. Тогда он видит изменения и потом уже начинает нормально работать.
Спасибо, что починили, очень уж удобный скрипт, приходилось держать вместо него три кнопки, которые не охватывали полностью его функций
Отредактировано kazarin (24-07-2022 15:22:42)
Отсутствует
посмотрите пожалуйста кнопку Save.В ней не работает функция "Сохранить значок веб-сайта"
Опять изменили аргументы в internalSave()
/* if (typeof window.saveImageURL != "function") var saveImageURL = internalSave.length == 15 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, a7, a5, null, priv, prin); */ if (typeof window.saveImageURL != "function") var saveImageURL = internalSave.length == 16 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : internalSave.length == 15 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, a7, a5, null, priv, prin);
Отсутствует
Заметил, что если включить стили в настройках расширения - перестают работать клавиши вызова боковой панели (ctrl+B, ctrl+H). Это можно как-то починить? (на всякий случай выложил папку https://disk.yandex.ru/d/SCyAqLNnyxbTRw)
upd: виновник этого безобразия - auto_hide_sidebar.css
Отредактировано Northtech (29-01-2023 00:20:59)
Отсутствует
не работает функция "Сохранить выделеный текст как txt фаил"
А, saveURL() тоже
… //var splice = saveURL.length == 10; var {length} = saveURL, splice = length > 9, l11 = length == 11; … //splice && args.splice(5, 0, null); splice && args.splice(5, 0, null) && l11 && args.splice(1, 0, null);
Отредактировано Dumby (02-08-2022 11:25:53)
Отсутствует
о проверке версий:
например AppConstants.MOZ_APP_VERSION больше 102 -> выполняем один код, меньше -> другой прежний.
Это наверное поможет, если Опять изменили аргументы в internalSave()
Отредактировано Dobrov (02-08-2022 11:30:13)
Отсутствует
Тогда скажи на какой версии Firefox эта правка
сломала обратную совместимость, попробую посмотреть.
Не знаю, если новая правка работает на всех Firefox, начиная с 90, тогда ладно.
Я откатился на FF97, когда страницы стали непонятно тормозить и долго загружаться на FF102.
Отсутствует
addDestructor is not defined
Это значило бы, что надо загрузчик смотреть, если бы дело было в этом.
Но дело в другом (см. также).
Пока, можно добавить в код одну строку про "lazy".
… let g = Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {}); if("lazy" in g) g = g.lazy;
Отредактировано Dumby (04-08-2022 09:47:22)
Отсутствует
Dobrov, уважаемый, можно вопрос по вашей кнопке Quick toggle for about:config preferences (Dobrov mod)?
window.SetDownloadDir = function (path, path_old) { path = window.convertFromUnicode("UTF-8", path); path_old = window.convertFromUnicode("UTF-8", path_old) || ''; if ( path != path_old ) { cbu.setPrefs("browser.download.folderList", 2); cbu.setPrefs("browser.download.useDownloadDir", true); cbu.setPrefs("browser.download.dir", path); } return path; }; window.PathToDownloadDir = function (change) { // null возврат папки загрузки true тоже + открыть папку загрузки 2 изменить папку загрузки - обзор. возврат папки загрузки раньше диалога выбора // try { var path = Services.prefs.getComplexValue("browser.download.dir", Ci.nsISupportsString).data } try { var path = Services.downloads.userDownloadsDirectory.path } catch(e) { path = Services.downloads.defaultDownloadsDirectory.path }; if ( change == true ) { var file = Services.dirsvc.get('ProfD', Ci.nsIFile); file.initWithPath(path); file.launch(); } if (typeof change == 'string') path = window.SetDownloadDir(change, path); // изменить путь загрузок if (change == 2) { var fp = window.makeFilePicker(); fp.init(window, "Выберите папку для загрузок!", 2); fp.open(re=> { if ( re == fp.returnOK ) return window.SetDownloadDir(fp.file.path, path) }); } return path; }; window.PathToDownloadFolder = function (change) { // Получить\Открыть (change=false)\Изменить путь к папке загрузки (change=true или текст) try { var path = Services.downloads.userDownloadsDirectory.path } catch(e) { path = Services.downloads.defaultDownloadsDirectory.path }; if ( change == false ) { var file = Services.dirsvc.get('ProfD', Ci.nsIFile); file.initWithPath(path); file.launch(); } if ( !change ) return path; // arg == undefined || arg == false var fp = window.makeFilePicker(); fp.init(window, "Выберите папку для загрузок!", 2); fp.open(re=> { if ( re != fp.returnOK ) return; cbu.setPrefs("browser.download.folderList", 2); cbu.setPrefs("browser.download.useDownloadDir", true); cbu.setPrefs("browser.download.dir", window.convertFromUnicode("UTF-8", fp.file.path)); }) }; window.Title = function (type) { // заголовок (без обрезки, если type не указан), домен (type <0) var title = (content.document.title || gBrowser.mCurrentTab.label); var host = (/about:/.test(gURLBar.value)) ? // ReaderView или страница about:… decodeURIComponent(gURLBar.value).replace(/^.*url=/,'').replace(/^https?:\/\//,'').replace(/\/.*/,'') : gBrowser.currentURI.host; if (/^file:\/\//.test(gBrowser.currentURI.spec)) host = ''; // открыт локальный файл if ( !type ) return title; // заголовок if ( type > 0 ) return title.replace(/[:\\\/<>?*|"]+/g,' ').replace(/\s+/g,' ').replace(/ /g,' ').substr(0, type).trim(); // ограничить длину имени if ( type < 0 ) return host.replace(/^www\./,'').replace(/^ru\./,'').replace(/^m\./,'').replace(/^forum\./,'').replace(/^club\.dns/,'dns'); }; // Быстрое переключение параметров about:config от 24.07.2016 [FIX Dobrov] // Изменить иконку при несоответствие любого параметра пользовательскому предпочтению (см. ниже) // Иконка меняется только при изменении параметров через меню кнопки, либо после его открытия. var s='CB.hasNotUserChoice', str = ' Быстрые настройки'; // str = 'profile: '+ OS.Constants.Path.profileDir; str = str +'\n Правый клик: опции браузера'; str = str +'\n Держать: открыть about:config'; str = str +'\n\n Proxy(VPN): …порт: '+ cbu.getPrefs("network.proxy.http_port"); str = str +'\n '+ cbu.getPrefs("network.proxy.http"); this.tooltipText = str; // str = str +'\n'+ OS.Constants.Path.libxul; // str = str +'\n'+ OS.Constants.Path.homeDir; // str = str +'\n'+ OS.Constants.Path.desktopDir; // str = str +'\n'+ OS.Constants.Path.winAppDataDir; // undefined // str = str +'\n'+ OS.Constants.Path.winLocalAppDataDir; // undefined // str = str +'\n'+ OS.Constants.Path.winStartMenuProgsDir; // undefined // str = str +'\n'+ OS.Constants.Path.winStartMenuProgsDir; // undefined // str = str +'\n'+ OS.Constants.Path.macUserLibDir; // undefined // str = str +'\n'+ OS.Constants.Path.macLocalApplicationsDir; // undefined function toggleImage(){ custombuttons.getPrefs(s) ? self.style.cssText = '' : self.style.cssText = 'filter: grayscale(100%)'; }; toggleImage();Services.prefs.addObserver(s,toggleImage,false);addDestructor(()=>Services.prefs.removeObserver(s,toggleImage)); var menuPopup = self.appendChild(document.createXULElement("menupopup")); menuPopup.id='quick-aboutconfig-menupopup'; // для стиля в userChrome.css var menuContext = self.appendChild(document.createXULElement("menupopup")); // для действия Сохранить как… Web-страница будет в кодировке Win1251. на FF ниже 60 в GIT не видно выпадающего списка версий var useragent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:78.0) Gecko/20100101 Firefox/78.0"; //,,,Firefox 78/MacOSX|||\ var useragent_name = "Firefox 78/MacOSX"; [ {nodeName:"menu", name:"Прокси (VPN)", pref:"network.proxy.type", refresh:"", image:"chrome://browser/skin/privatebrowsing-mask.png", userChoice:2, strValues:"0,,,отключен,,,0|||2,,,Автонастройка,,,2|||4,,,…для текущей сети,,,4|||5,,,Системный,,,5"}, {nodeName:"menu", name:"URL автонастройки", pref:"network.proxy.autoconfig_url", refresh:"", userChoice:"https://antizapret.prostovpn.org/proxy.pac", strValues:"https://antizapret.prostovpn.org/proxy.pac,,,АнтиЗапрет,,,1|||file:///etc/proxy.pac,,,.pac файл,,,2|||https://git.io/ac-anticensority-pac,,,ac-anticensority,,,3|||127.0.0.1,,,Отключен,,,0"}, //https://rebrand.ly/ac-anticensority {nodeName:"checkbox", name:"режим 'Без прокси' при выходе", pref:"CB.Proxy.reset", userChoice:"false"}, {nodeName:"menuseparator"}, {nodeName:"menu", name:"Загружать шрифты Web", pref:"browser.display.use_document_fonts", strValues:"0,,,Выкл,,,|||1,,,Вкл,,,"}, {nodeName:"checkbox", name:"Выполнять скрипты Java", pref:"javascript.enabled", key:'j', userChoice:"true"}, {nodeName:"checkbox", name:"Сообщить о загрузке страницы", pref:"dom.enable_performance", userChoice:"false"}, {nodeName:"menuseparator"}, {nodeName:"checkbox", name:"автопроигрывание мультимедиа", pref:"media.autoplay.enabled", key:'m', userChoice:"true"}, {nodeName:"menuseparator"}, {nodeName:"menu", name:"User Agent", pref:"general.useragent.override", key:'u', refresh:"", userChoice: useragent, strValues: "\ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:100.0.1) Gecko/20100101 Firefox/101.0.1.0,,,Firefox 101.0.1/MacOSX|||\ Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727),,,MSIE 6.0/Windows|||\ Mozilla/5.0 (Linux; Android 7.0; PLUS Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36,,,Chrome61/Android7|||\ Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30,,,Safari 6/MacOSX|||\ Mozilla/5.0 (Linux; Android 5.1.1; SM-G928X Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Mobile Safari/537.36,,,Samsung Galaxy S6|||\ Mozilla/5.0 (PlayStation 4 3.11) AppleWebKit/537.73 (KHTML, like Gecko),,,Playstation 4|||\ Xbox (Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586,,,Xbox One (mobile)|||\ Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586,,,Microsoft Lumia 950|||\ Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; SAMSUNG; GT-I8350),,,Windows Phone|||\ Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html),,,GoogleBot|||\ ,,,Пустое значение"}, // Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots),,,YandexBot|||\ // Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm),,,BingBot|||\ // Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp),,,YahooBot|||\ // Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html),,,BaiduspiderBot|||\ // ia_archiver (+http://www.alexa.com/site/help/webmasters; crawler@alexa.com),,,AlexaCrawlerBot|||\ // DuckDuck bot/1.0; (+http://duckduckgo.com/duckduckbot.html),,,DuckDuckBot|||\ ].forEach( (m)=> { CreateMenu(m, menuPopup); // какое меню создавать }); [ {nodeName:"menu", name:"Куки", pref:"network.cookie.cookieBehavior", refresh:"", userChoice:"0", strValues:"0,,,Разрешить все сайты,,,|||2,,,Запретить все сайты,,,|||3,,,Сторонние посещённые сайты,,,|||1,,,Не принимать со сторонних сайтов,,,"}, {nodeName:"menu", name:"Загружать графику", pref:"permissions.default.image", refresh:"", userChoice:1, strValues:"1,,,Да|||3,,,Site only|||2,,,Нет"}, // 1,2,3; 1 разрешить изображения, 2 отключить; 3 изображения с основного веб-сайта, блокировать со сторонних (third-party) серверов {nodeName:"menu", name:"Анимация изображений", pref:"image.animation_mode", key:'i', refresh:"", userChoice:"normal", strValues:"normal,,,вкл.,,,|||none,,,выкл.,,,"}, {nodeName:"checkbox", name:"OnLine видео 'dom.workers'", pref:"dom.workers.enabled", key:'w', userChoice:"true"}, {nodeName:"menuseparator"}, {nodeName:"checkbox", name:"Откл. дискового кэша", pref:"browser.cache.disk.enable", userChoice:"false"}, {nodeName:"checkbox", name:"Откл. кэша в оперативной памяти", pref:"browser.cache.memory.enable", userChoice:"false"}, {nodeName:"checkbox", name:"Локальное хранилище indexedDB", pref:"dom.indexedDB.enabled", key:'d', userChoice:"true"}, {nodeName:"checkbox", name:"Откл. локального хранилища", pref:"dom.storage.enabled", key:'s'}, {nodeName:"menuseparator"}, // {nodeName:"menu", name:"Back-story-cash [Tessssttt]", pref:"browser.sessionhistory.max_total_viewers", strValues:"0,,,0"}, // {nodeName:"menuseparator"}, {nodeName:"menu", name:"useragent.locale", pref:"general.useragent.locale", key:'l', restart:"", strValues:"en-US,,,English,,,e|||ru-RU,,,Рус (ru-RU),,,r|||ru,,,русский (ru),,,"}, {nodeName:"menu", name:"language", pref:"intl.accept_languages", strValues:"en-US, en;q=0.5,,,en-US, en;q=0.5,,,e|||en-US, en, ru-RU, ru,,,en-US, en, ru-RU, ru,,,r"}, {nodeName:"menu", name:"document_color_use", pref:"browser.display.document_color_use", key:'c', userChoice:"0", strValues:"0,,,Auto,,,0|||1,,,Always,,,1|||2,,,Never,,,2"}, {nodeName:"menuseparator"}, {nodeName:"checkbox", name:"В качестве реферера корень сайта", pref:"network.http.referer.spoofSource", userChoice:"true"}, {nodeName:"menu", name:"Вкл/Выкл Referer", pref:"network.http.sendRefererHeader", userChoice:"2", strValues:"0,,,0|||2,,,2"}, {nodeName:"menu", name:"referer.trimmingPolicy", pref:"network.http.referer.trimmingPolicy", strValues:"0,,,0|||2,,,2"}, {nodeName:"menuseparator"}, {nodeName:"checkbox", pref:"media.mediasource.enabled", userChoice:"true"}, {nodeName:"checkbox", pref:"media.peerconnection.enabled"}, //WebRTC false=off! {nodeName:"checkbox", name:"Многопоточность вкладок (CPU)", pref:"browser.tabs.remote.autostart", restart:"", userChoice:"false"}, //about:support=Multiprocess Windows|forum.ru-board.com/topic.cgi?forum=5&topic=49695&start=0&limit=1&m=9#1 {nodeName:"menuseparator"}, // {nodeName:"checkbox", name:"On/Off useragentS", pref:"general.useragent.site_specific_overrides"}, // useragent +",,,"+ useragent_name +"|||\ ].forEach( (m)=> { CreateMenu(m, menuContext); // контекстное меню }); function CreateMenu(m, menuNew) { if (m.nodeName==="checkbox" || m.nodeName==="radio") var mItem = document.createXULElement('menuitem') // для checkbox, radio else var mItem = document.createXULElement(m.nodeName); var addCommand=''; // создать элементы меню if ("refresh" in m) addCommand = ' BrowserReload();'; if ("restart" in m) addCommand = ' if (custombuttons.confirmBox(null, "Restart?", "Yes", "Cancel")) Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart);'; if ("image" in m) mItem.setAttribute('image', m.image); if ("name" in m) mItem.setAttribute('name', m.name); if ("pref" in m) { mItem.setAttribute('closemenu', 'none'); mItem.setAttribute('oncontextmenu', 'event.preventDefault();custombuttons.clearPrefs("'+m.pref+'");'+ addCommand); } if ("key" in m) mItem.setAttribute('accesskey', m.key); // тип radio не добавлен !!! if (m.nodeName==="checkbox") { mItem.setAttribute('type', 'checkbox'); mItem.setAttribute('oncommand','custombuttons.setPrefs("'+m.pref+'",!custombuttons.getPrefs("'+m.pref+'"));if (event.shiftKey && event.keyCode==event.DOM_VK_RETURN){event.preventDefault();custombuttons.clearPrefs("'+m.pref+'")};'+addCommand); } // if (m.nodeName==="radio") { // if ("name" in m) mItem.setAttribute('label', m.name); // mItem.setAttribute('type', 'radio'); // mItem.setAttribute('oncommand','custombuttons.setPrefs("'+m.pref+'",!custombuttons.getPrefs("'+m.pref+'"));'+addCommand); // } if (m.nodeName === "menu") { mItem.setAttribute('class', 'menu-iconic'); var subMenu = mItem.appendChild(document.createXULElement("menupopup")); for (var value of m.strValues.split('|||')) { var submItem = document.createXULElement("menuitem"); var smVal = value.split(',,,')[0]; var smValConv = convertFromUnicode("UTF-8", smVal); var smName = value.split(',,,')[1]; var key = value.split(',,,')[2]; key && submItem.setAttribute('accesskey', key); submItem.setAttribute('type', 'radio'); submItem.setAttribute('label', smName); submItem.setAttribute('tooltiptext', smVal); submItem.setAttribute('closemenu', 'none'); submItem.setAttribute('oncommand', 'try{custombuttons.setPrefs("'+ m.pref +'","'+ smValConv.replace(/\\/g,'\\\\')+'")}catch(e){Services.prefs.setIntPref("'+ m.pref +'","'+ smValConv +'")};'+ addCommand); subMenu.appendChild(submItem); } } menuNew.appendChild(mItem); // Листенеры отслеживания переключения параметров и устанавка соответствующих названий и чекбоксов для пунктов меню при открытии меню и кликах for (var type of ['command', 'popupshowing', 'contextmenu']) { addEventListener(type, (e)=> { setTimeout(()=> { if ("pref" in m) { var val, def; def = Services.prefs.prefHasUserValue(m.pref); try { val = Services.prefs.getComplexValue(m.pref, Ci.nsISupportsString).data; } catch(e) { if (Services.prefs.getPrefType(m.pref) == 64) val = custombuttons.getPrefs(m.pref).toString(); else val = custombuttons.getPrefs(m.pref); } def ? mItem.style.setProperty('font-weight', 'bold', 'important') : mItem.style.removeProperty('font-weight'); } if (m.nodeName === 'checkbox') { mItem.setAttribute('checked', val); mItem.label = ( mItem.hasAttribute('name') ? mItem.getAttribute('name') : m.pref ); if ("userChoice" in m) { // отображение значения +' - "'+val+'"'; try {var usrChc = (val.toString() === m.userChoice)} catch(e) {usrChc = false}; mItem.setAttribute('user-choice', usrChc); usrChc ? mItem.style.removeProperty('color') : mItem.style.setProperty('color', 'orangered', 'important'); } } if (subMenu) { for (var smitem of subMenu.getElementsByTagName('menuitem')) { var smval = smitem.getAttribute('tooltiptext'); smitem.setAttribute('checked', (val === smval) ? true : false); } } if (m.nodeName === "menu") { var vname; try { vname = subMenu.getElementsByAttribute('checked', 'true')[0].getAttribute('label'); } catch(e) { if (!Services.prefs.prefHasUserValue(m.pref)) vname = 'Default'; else vname = 'Other'; } mItem.setAttribute('label', ( mItem.hasAttribute('name') ? mItem.getAttribute('name') : m.pref ) +' - "'+ vname +'"'); mItem.setAttribute('tooltiptext', val || 'This preferences has null value or does not exist.'); if ("userChoice" in m) { var smUsrChc = (val === m.userChoice.toString()); mItem.setAttribute('user-choice', smUsrChc); smUsrChc ? mItem.style.removeProperty('color') : mItem.style.setProperty('color', 'orangered', 'important'); } } if ("userChoice" in m) { var hasNotUserChoice = menuNew.getElementsByAttribute('user-choice', 'false')[0]; custombuttons.setPrefs(s, hasNotUserChoice ? true : false); } }, 0) }, false, menuNew) } }; // End CreateMenu // Конвертировать текст в юникод ............. function convertFromUnicode(charset,str) {var converter=Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); converter.charset=charset;str=converter.ConvertFromUnicode(str);return str+converter.Finish();}; var switchOffProxy = { // Переключать на режим 'Без прокси' при закрытии браузера если это разрешено в 'about:config' observe: function(subject, topic, data) { if ( data == "shutdown" && cbu.getPrefs("CB.Proxy.reset") ) cbu.setPrefs("network.proxy.type",0); } }; Services.obs.addObserver(switchOffProxy, "quit-application", false); // nodeName: checkbox - для логических(boolean) параметров, menu - для целых(integer) и строковых(string). menuseparator - для разделителя. // pref - параметр about:config. // Параметры имеющие значения отличные от дефолтных - выделены жирным стилем текста. // restart (задавать с пустым значением. т.е., restart: "") - перезапуск браузера (с подтверждением в диалоговом окне) после изменения параметра. // key - задает accesskey - клавиши для быстрой навигации по меню. // userChoice - задает предпочитаемое значение и если текущее значение с ним не совпадает, пункт меню/название меню помечаются красным цветом. // Также можно установить предупреждающую иконку для таких пунктов. См. стиль в посте ккнопки. А также меняется иконка самой кнопки (см. выше). // strValues - значения и отображаемое в меню название значения. Задавать для целых(integer) и строковых(string) параметров. // Задается в виде: значение,,,название,,,accesskey|||значение2,,,название2,,,accesskey2|||значение3,,,название3 и т.д. (accesskey - задается опционально) // Полное значение отображается в подсказках, при наведении на название подменю/пункт подменю. // Для логических(boolean) - отображается сразу после самого параметра (значение true - также ставит галочку для него). // ЛКМ по пунктам меню - переключает значения для логических(boolean) параметров, // любая кнопка по пунктам в субменю - задает это значение для целых(integer) и строковых(string) параметров. // Клавиатура: Enter - переключение параметра. // Alt + M - открыть меню кнопки. (Сочетание можно сменить на свое. См. в конце кода) // ПКМ по пунктам меню и названию субменю - сбрасывает значение параметра в дефолтное (сейчас перехватывается кликом по кнопке). // Спецклавиша вызова контекстного меню / Shift+Enter - сброс в дефолтное значение (убрал это действие). // Настройка функций кликов мыши для кнопки, учитывая долгое нажатие var longPress = false; // долгое нажатие function handleEvent(event) { switch(event.type) { case"mouseover": // можно обновлять tooltip кнопки 0 // this.setAttribute('Popup.state', menuPopup.state); // состояние меню: открыто/скрыто // this.setAttribute('menuContext.state', menuContext.state); // состояние меню: открыто/скрыто break; case"mousedown": self.timer = setTimeout(()=> { // удержание if ( event.target.localName == "menuitem" ) return; longPress = true; // блокировка обычных кликов if ( event.button == 0 ) { // ЛКм Long window.switch_tab_url('about:config'); } else if ( event.button == 2 ) { // ПКм Long // setPathToDownloadFolder(); window.switch_tab_url('about:preferences#content'); } else if ( event.button == 1 ) { // СКм Long 0 } }, 500 ); break; case"mouseup": // отжатие кнопки clearTimeout(self.timer); // сброс таймера долгих нажатий if ( longPress ) { longPress = false } // выполнялась команда долгих нажатий, сброс флага и выход else if ( event.button == 0 ) { // ЛКм if ( /open|showing/.test(this.getAttribute('Popup.state')) || /open|showing/.test(this.getAttribute('menuContext.state')) ) {// показать/скрыть меню, замена функции this._handleClick menuPopup.hidePopup(); menuContext.hidePopup() } else menuPopup.openPopup(this,'after_start'); if ( !/open|showing/.test(this.getAttribute('menuContext.state')) ) // показать/скрыть меню, замена функции this._handleClick this.setAttribute('Popup.state', menuPopup.state); // видимость Popup. выполнить также на "mouseover" ( или один раз глобально в конце handleEvent) this.setAttribute('menuContext.state', menuContext.state); // видимость Popup. выполнить также на "mouseover" ( или один раз глобально в конце handleEvent) } else if ( event.button == 2 && !event.altKey && !event.metaKey) { // ПКм if ( event.ctrlKey && event.shiftKey ) { // +Ctrl +Shift var host = gURLBar.inputField; var str = 'host ' + host + "\n" + decodeURIComponent(gBrowser.currentURI.spec) + "\n" + '+1 '+ window.Title(33) + "\n" + '=0 '+ window.Title(0) + "\n" + '-1 '+ decodeURIComponent(window.Title(-1)) + "\n"; // URLBarInput.value + '/n'; // gURLBar.mInputField; // window.show_tooltip(0, '', str, 5000); } if ( event.ctrlKey) { // +Ctrl // window.SavSnapshot(); var info = custombuttons.cbService.readFromClipboard(); // info = document.getElementById('tabbrowser-tabs').clientWidth; // info = gBrowser.tabs.clientWidth; window.statusTextField(info); } else if ( event.shiftKey) { // +Shift window.PathToDownloadFolder("/home"); } else { // window.switch_tab_url('about:config'); if (/open|showing/.test(this.getAttribute('menuContext.state'))) // показать/скрыть меню, замена функции this._handleClick menuContext.hidePopup() else menuContext.openPopup(this,'after_start'); this.setAttribute('menuContext.state', menuContext.state); // видимость Popup. выполнить также на "mouseover" ( или один раз глобально в конце handleEvent) } event.preventDefault(); event.stopPropagation(); } else if ( event.button == 1 ) { // СКм custombuttons.editButton(this); // Редактировать кнопку… } break; case"DOMMouseScroll": // ролик мыши над кнопкой event.detail > 0 ? FullZoom.reduce() : FullZoom.enlarge(); break; case"contextmenu": // ПКм+Alt или Meta откроет контекстное меню menuContext.hidePopup(); if(!event.altKey && !event.metaKey) event.preventDefault(); // event.stopPropagation(); // break; } // команды при выполнении любых событий }; // var this_event = ["mousedown", "mouseup", "mouseover", "contextmenu", "draggesture", "DOMMouseScroll"] var this_event = ["mousedown", "mouseup", "mouseover", "draggesture", "DOMMouseScroll"] .forEach((type)=> this.addEventListener(type, handleEvent, false)); // Горячие клавиши: действия. коды: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Constants_for_keyCode_value addEventListener("keyup", (e)=>{ if (e.altKey && !e.shiftKey && !e.ctrlKey && e.keyCode==77){ // сочетание клавиш Alt+M e.preventDefault();e.stopPropagation(); menuPopup.showPopup(this,-1,-1,"popup","bottomleft","topleft"); } }, false,window); // Блокировать контекстное меню при клике ПКМ, +Ctrl, +Shift this.oncontextmenu = function(e) { if(e.button == 2 && !e.altKey && !e.metaKey) { e.preventDefault(); e.stopPropagation(); } }; // Листенер позволяющий сброс параметров с субменю по Shift + Enter // За код спасибо Dumby // addEventListener("popupshown", { // handleEvent: function(e) { // this[e.type](e); // }, // popupshown: function(e) { // if (e.target != menuPopup) return; // menuPopup.addEventListener("popuphidden", this, false); // window.addEventListener("keydown", this, true); // }, // popuphidden: function(e) { // if (e.target != menuPopup) return; // menuPopup.removeEventListener("popuphidden", this, false); // window.removeEventListener("keydown", this, true); // }, // popupshowing: function(e) { // e.target.parentNode.removeEventListener("popupshowing", this, false); // e.preventDefault(); // }, // get old() { // delete this.old; // this.e = new MouseEvent("contextmenu", {}); // return this.old = parseInt(Services.appinfo.platformVersion) < 25; // }, // get prop() { // delete this.prop; // if ("key" in KeyboardEvent.prototype) this.prop = "key", this.val = "Enter"; // else this.prop = "keyCode", this.val = KeyboardEvent.DOM_VK_RETURN; // return this.prop; // }, // keydown: function(e) { // if (!e.shiftKey || e.ctrlKey || e.altKey || e[this.prop] != this.val) return; // var target = menuPopup.querySelector("menu[_moz-menuactive]:not([open])"); // if (!target) return; // this.old ? target.addEventListener("popupshowing", this, false) : e.stopPropagation(); // target.dispatchEvent(this.e); // menuPopup.dispatchEvent(this.e); // } // }, false, menuPopup); // pref:"network.proxy.autoconfig_url", refresh:"", userChoice:"https://antizapret.prostovpn.org/proxy.pac", strValues:"https://antizapret.prostovpn.org/proxy.pac,,,АнтиЗапрет,,,1|||file:///etc/proxy.pac,,,.pac файл,,,2|||https://git.io/ac-anticensority-pac,,,ac-anticensority,,,3"}, //https://rebrand.ly/ac-anticensority // {nodeName:"checkbox", pref:"xpinstall.signatures.required"}, //Check is compatibility // {nodeName:"checkbox", pref:"browser.bookmarks.autoExportHTML"}, //BookmarksHtml [false=places.sqlite] // {nodeName: "menu", pref: "CB.TEST", key: 't', userChoice: "C:\\Downloads\\TEST1", strValues: "C:\\Downloads\\TEST1,,,TEST1,,,1|||C:\\Downloads\\TEST2,,,TEST2,,,2"}, // var mPrefs = "network.proxy.autoconfig_url"; // }, 100); // window.statusTextField(gBrowser.docShell.charset +' '+ m.value +'_'+ decodeURIComponent(window.hostname())); // tmp = (self.image == imgFlashToPlayer || self.image == imgFlashMinimize || self.image == imgFlashMaximize); // if(m.value.substring(0,9)=='videotopl') // self.image = tmp ? imgFlashToPlayer : imgHTML5ToPlayer; // Menu_n_TooltipTxts.forEach((m) => { // // window.show_tooltip(0, '', m, 5000); // var mItem = document.createXULElement("menuitem"); // if("radio" in m) { // // 0 // // l = l + ( cbu.getPrefs(mPrefs) == m.value ) + '\n'; // mItem.setAttribute('checked', cbu.getPrefs(mPrefs) == m.value); // } // // menuContext.appendChild(mItem); // }); // mItem.getAttribute('name') // mItem.setAttribute("type", "radio"); // mItem.setAttribute('label', ( mItem.hasAttribute('name') ? mItem.getAttribute('name') : m.pref ) +' - "'+ vname +'"'); // mItem.setAttribute('tooltiptext', val || 'This preferences has null value or does not exist.'); // {nodeName:"checkbox", name:"Загружать графику", radio:"", pref:"permissions.default.image", refresh:"", userChoice:1, strValues:"1,,,On"}, // {nodeName:"checkbox", name:"не Загружать графику", radio:"", pref:"permissions.default.image", refresh:"", strValues:"2,,,Off"},
Отсутствует
kazarin - Антизапрет переодически не работает на некоторых сайтах - флибуста и прочие.
Для Антизапрета нужно установить два пункта меню: 1) Прокси - Антизапрет 2) Режим прокси - Автонастройка.
С виду код вроде рабочий, но советую обновить кнопку. Приведённый код сильно устарел - актуальный от апреля 2022 (требуется 2 скрипта: ucf_QuickToggle.js + глобальный ucf_hookClicks.js).
в моём профиле (в шапке темы) переключение прокси делается проще: долгий клик по Замку или кнопке Quick toggle.
Отсутствует
Dobrov
Спасибо за ответ!
Поторопился я писать, сегодня уже всё грузится - наверно, на стороне форума были косяки.
Код рабочий и работает отлично, пользуюсь им уже давно и он очень нравится мне в том виде, что есть)) Посмотрел новую версию, это вообще совсем другой скрипт, с другими функциями, он её не заменит.
Отсутствует
egorsemenov06
Тяп-ляп — папка long_left_click
Загружать из неё в сандбокс скрипт startup.js
Например
… scriptsbackground: [ // В фоне [System Principal] … { path: "long_left_click/startup.js" },
data:application/x-zip-compressed;base64,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
Отсутствует
Тяп-ляп — папка long_left_click
Загружать из неё в сандбокс скрипт startup.js
Например
скрытый текстНастройки — about:llc
скрытый текст
Интересный вариант, запихнуть расширение в UCF
Отредактировано kokoss (27-08-2022 19:29:21)
Win7
Отсутствует
в этот скрипт можно добавить стиль что бы иконкии были все на одном уровне
В скрипт? Это принципиально?
Просто может лучше добавить в стиль для менюшек первой строкой:
#ID menuitem,
где ID — id кнопки Save.
Отсутствует