желательно все прописать где "var run = ...", а "var path = ..." убрать
Да, действительно, так и надо было сделать,
а то получается перегон из пустого в порожнее.
/* var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(path); */ var file = Services.dirsvc.get("UChrm", Ci.nsIFile); ["user_chrome_files", "_", "opera-proxy.windows-386.exe"].forEach(file.append);
Отсутствует
Как переделать загрузчик AttributesInspector.js, чтобы вместо левой кнопки мыши код выполнялся при клике правой кнопкой ? Или колёсиком ?
(async (id) => CustomizableUI.createWidget({ label:id, id:id, localized: false, onCreated(btn) { btn.setAttribute("image","data:image/webp;base64,UklGRjwAAABXRUJQVlA4TC8AAAAvD8ADAAoGbSM5Ov6k774XCPFP/0/03/8JGPxzroIzuOW06Ih60Genn1S/gHe+BgA="); btn.onmouseenter = btn.onmouseleave = this.onmouse; btn.setAttribute("oncommand","handleCommand(this)"); btn.handleCommand = this.handleCommand; }, onmouse: e => e.target.focusedWindow = e.type.endsWith("r") && Services.wm.getMostRecentWindow(null), get handleCommand() { delete this.handleCommand; return this.handleCommand = btn => {(btn.handleCommand = new btn.ownerGlobal.Function(this.code).bind(btn))();} }, get code() { delete this.code; var s = Ff.c +"custom_scripts/AttributesInspector.js"; try { id = 'this.focusedWindow && this.focusedWindow.focus();\n' + Cu.readUTF8URI(Services.io.newURI(s)) } catch {} return this.code = id; } }))("AttributesInspector");
Отсутствует
Как переделать загрузчик AttributesInspector.js, чтобы вместо левой кнопки мыши код выполнялся при клике правой кнопкой ?
/* btn.setAttribute("oncommand","handleCommand(this)"); btn.handleCommand = this.handleCommand; */ btn.setAttribute("oncontextmenu", "return event.ctrlKey || (handleCommand(this), false)"); btn.handleCommand = this.handleCommand;
Или колёсиком ?
/* btn.setAttribute("oncommand","handleCommand(this)"); btn.handleCommand = this.handleCommand; */ btn.setAttribute("onauxclick", "if (event.button == 1) handleCommand(this)"); btn.handleCommand = this.handleCommand; ....... /* return this.code = id; */ return this.code = id.replace("canInspect: function(e) {\n", "$&\t\t\tif(e.button == 1 && e.target == context.button) return false;\n");
Отсутствует
Выложу здесь свой код google-translate.js. Ссылка на источник, ничего не удалял. Ненужное закомментировано, изменения прокомментированы и ссылки присутствуют.
// https://forum.mozilla-russia.org/viewtopic.php?pid=780231#p780231 (this.googletranslate = { init(that) { var lc = navigator.lastClick = {}, w = null, xhtmlns = 'http://www.w3.org/1999/xhtml'; var mouseUp = (e) => { if (e.button) return; lc.X = e.screenX - mozInnerScreenX; lc.Y = e.screenY - mozInnerScreenY; }; gBrowser.tabpanels.addEventListener('mouseup', mouseUp, false); this.destructor = () => { gBrowser.tabpanels.removeEventListener('mouseup', mouseUp, false); if (w) w.closeWin(); }; that.unloadlisteners.push("googletranslate"); var createWindow = function(text, status, title, id, pos, size) { var win = window, doc = win.document, wId = 'ujs_window'+(id || ''); w = doc.getElementById(wId); var keyDown = function(e) {if (!e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode == 27)doc.getElementById(wId).closeWin();}; var mouseDown = function() {doc.getElementById(wId).closeWin();}; if (w) w.closeWin(); w = doc.createElementNS(xhtmlns, 'div'); w.setAttribute('style', 'position:fixed;display:block;visibility:hidden;left:0;top:0;width:auto;height:auto;border:1px solid gray;padding:2px;margin:0;z-index:99999;overflow:hidden;cursor:move;'+(typeof w.style.borderRadius === 'string' ? 'background-color:#eaeaea;padding-top:0px;border-radius:4px;box-shadow:0 0 15px rgba(0,0,0,.4);' : 'background:-o-skin("Window Skin");')); w.id = wId; w.closeWin = function() { doc.removeEventListener('keydown', keyDown, false); gBrowser.tabpanels.removeEventListener('mousedown', mouseDown, false); this.parentNode.removeChild(this); w = null; }; w.addEle = function(str, style) { var ele = doc.createElementNS(xhtmlns, 'div'); ele.setAttribute('style', style); if (str) { ele.innerHTML = str; for (var el, all = ele.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)) { el.parentNode.removeChild(el); } else { for (var att = el.attributes, j = att.length; j--;) { if (/^on[a-z]+$/i.test(att[j].name))att[j].value = ''; } } } } return this.appendChild(ele); }; /* https://forum.mozilla-russia.org/viewtopic.php?pid=807299#p807299 w.addEle1 = function(str, style) { var ele = doc.createElementNS(xhtmlns, 'textarea'); ele.setAttribute('style', style); if (str) { ele.innerHTML = str; for (var el, all = ele.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)) { el.parentNode.removeChild(el); } else { for (var att = el.attributes, j = att.length; j--;) { if (/^on[a-z]+$/i.test(att[j].name))att[j].value = ''; } } } } return this.appendChild(ele); }; */ var img = doc.createElementNS(xhtmlns, 'div'); img.setAttribute('style', 'display:block;float:right;width:16px;height:16px;padding:0;margin-top:2px;margin-right:1px;border:none;cursor:pointer;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACQUlEQVR4Xm2SPUhbURTHfzfNJ4nU0Axx7CJCN2kQtIgVCtq6OdQuBUftWIQqFNsKDo6iHTqIqN3a0kklUKTS2AZrcOjioFtRjFWUfH+803cS9GHwB4dzcu75/+8L9xgaSEDbLXhaASzAyXAMn5/DHxwwjeJgKLRxd3Q0atxuLhGgWqmQmp9PJ7LZJ5Ow3WhQFweDG20LC1FfRwc3kUsm+T48fPIzl3s8VTdxxLt+/2FhdlZkc1MkmdR8Pba2ajlrz3z1+9OvIOaIfb7DwsSEyNKSyM6OSLksEo/rbw2ttadntV7Gnv3k86VfqskvmDzv7hZ580Zkelrk4kJqFIsii4satVrRs+rYmBQHBuRvS4u8g/fuCmDOz+HgAIWpKRgfh3AYhoZQ8Hqxjo4o9PdT3d1FcQEl8KoBnJ7C/j6KZkZGYG4OIhEUFed7erD29q69jGrd1qVBqcQVKgwEuMSEQhjtXRk4JvW/kM1i2WGMga4uzMoKBIOIfbNiolEC6+uU+/qQRALFA1QBlwVYxmBcLmhuxqytQSgEKu7t1dBavwKvbeINh/Has2IMqnXpem4bky6qWLdvZgaOj2FwEHNyoqG19vRMZ8jZs1+NOfsNcZS3EFvzeNL51laRe/dEYrFadsLpZeyZDx7P6QN4Btwx1OE1xO4HAquP2tsjAZ+Pm8gWi3xMpc6W8/kXPyAO/DM4oOsZa2pafdjZGXF7PAgOpXKZL4nE2XImcyUGMDSg63kbhgvgtYCq8+akIL4J3y7Fyn+DokZOnLlMyQAAAABJRU5ErkJggg==");background:-o-skin("Caption Close Button Skin");'); img.title = (win.navigator.language.indexOf('ru') == 0) ? '\u0417\u0430\u043A\u0440\u044B\u0442\u044C' : 'Close'; img.addEventListener('click', function() {this.parentNode.closeWin();}, false); w.appendChild(img); var title = w.addEle(title, 'display:table;color:#000;font:17px Times New Roman;width:auto;height:auto;padding:0;margin:0 2px;cursor:text;'); title.onclick = e => { e.preventDefault(); var url = e.target.href; // Здесь открываем url как хотим. var ctabpos = gBrowser.selectedTab._tPos +1; gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos); doc.getElementById(wId).closeWin(); }; /* https://forum.mozilla-russia.org/viewtopic.php?pid=807299#p807299 var cnt = w.addEle1(text, 'display:block;border:1px solid #aaa;padding-bottom:3px;padding-left:3px;background-color:#fafcfe;color:#000;font:16px Times New Roman;width:310px;height:160px;overflow:auto;cursor:text;-moz-user-focus:normal;-moz-user-select:text;'); cnt.contentEditable="true"; cnt.context="contentAreaContextMenu"; */ var cnt = doc.createElement("textarea"); cnt.style.cssText = ` color: #000; width: 310px; height: 160px; outline: none; padding-left: 3px; padding-bottom: 3px; border: 1px solid #aaa; background-color: #fafcfe; font: 17px Times New Roman; `; // if (text) cnt.value = text; --> if (text) cnt.value = text.trim(); if (text) cnt.value = text.trim(); w.append(cnt); w.addEle(status, 'display:table;font:12px Times New Roman;font-weight:bold;color:blue;width:auto;height:auto;padding-top:2px;margin:0 3px;cursor:pointer;'); w.addEventListener('mousedown', function(e) { if (e.target == w) { e.preventDefault(); /* https://forum.mozilla-russia.org/viewtopic.php?pid=807257#p807257 var grabX = e.clientX, grabY = e.clientY, origX = parseInt(w.style.left), origY = parseInt(w.style.top); var mouseMove = function(ev) { w.style.left = origX+ev.clientX-grabX+'px'; w.style.top = origY+ev.clientY-grabY+'px'; }; */ var st = w.style; var mouseMove = e => { st.top = parseInt(st.top) + e.movementY + "px"; st.left = parseInt(st.left) + e.movementX + "px"; } doc.addEventListener('mousemove', mouseMove, false); doc.addEventListener('mouseup', function() {doc.removeEventListener('mousemove', mouseMove, false);}, false); } }, false); doc.documentElement.appendChild(w); if (size) { cnt.style.height = size.height; cnt.style.width = size.width; } else { for (var i = 3; i < 10; i++) { if (cnt.scrollHeight > cnt.offsetHeight || cnt.scrollWidth > cnt.offsetWidth) { cnt.style.height = 80*i+'px'; cnt.style.width = 160*i+'px'; } else break; } } var docEle = (doc.compatMode == 'CSS1Compat' && win.postMessage) ? doc.documentElement : doc.body; var mX = docEle.clientWidth-w.offsetWidth, mY = docEle.clientHeight-w.offsetHeight; if (mX < 0) {cnt.style.width = parseInt(cnt.style.width)+mX+'px'; mX = 0;} if (mY < 0) {cnt.style.height = parseInt(cnt.style.height)+mY+'px'; mY =0;} var hW = parseInt(w.offsetWidth/2); w.style.left = (pos && pos.X < mX+hW ? (pos.X > hW ? pos.X-hW : 0) : mX)+'px'; w.style.top = (pos && pos.Y+10 < mY ? pos.Y+10 : mY)+'px'; w.style.visibility = 'visible'; doc.addEventListener('keydown', keyDown, false); gBrowser.tabpanels.addEventListener('mousedown', mouseDown, false); // https://forum.mozilla-russia.org/viewtopic.php?pid=807326#p807326 if (text) { var st = cnt.style; var div = cnt.editor.rootElement; var range = new Range(); range.selectNode(div.firstChild); var rect = range.getBoundingClientRect(); let w = Math.ceil(rect.width); if (cnt.scrollTopMax) { if (!matchMedia("(-moz-overlay-scrollbars)").matches) // ??? w += InspectorUtils.getChildrenForNode(div, true, false).at(-1).clientWidth; } else st.height = Math.max(50, Math.ceil(rect.height) + 1) + "px"; // к строке выше; изменить, если font-size > 22 https://forum.mozilla-russia.org/viewtopic.php?pid=807332#p807332 st.width = Math.max(200, w) + "px"; } return w; }; var getHash = function (txt) { TKK=eval('((function(){var a\x3d817046147;var b\x3d-335196159;return 410049+\x27.\x27+(a+b)})())'); function sM(a) { var b; if (null !== yr) b = yr; else { b = wr(String.fromCharCode(84)); var c = wr(String.fromCharCode(75)); b = [b(), b()]; b[1] = c(); b = (yr = window[b.join(c())] || "") || ""; } var d = wr(String.fromCharCode(116)), c = wr(String.fromCharCode(107)), d = [d(), d()]; d[1] = c(); c = "&" + d.join("") + "="; d = b.split("."); b = Number(d[0]) || 0; for (var e = [], f = 0, g = 0; g < a.length; g++) { var l = a.charCodeAt(g); 128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023), e[f++] = l >> 18 | 240, e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224, e[f++] = l >> 6 & 63 | 128), e[f++] = l & 63 | 128); } a = b; for (f = 0; f < e.length; f++) a += e[f], a = xr(a, "+-a^+6"); a = xr(a, "+-3^+b+-f"); a ^= Number(d[1]) || 0; 0 > a && (a = (a & 2147483647) + 2147483648); a %= 1E6; return c + (a.toString() + "." + (a ^ b)); } var yr = null; var wr = function(a) { return function() { return a; }; }, xr = function(a, b) { for (var c = 0; c < b.length - 2; c += 3) { var d = b.charAt(c + 2), d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d), d = "+" == b.charAt(c + 1) ? a >>> d : a << d; a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d; } return a; }; return sM(txt); }; var ujs_google_translate = function (dir) { var lng = window.navigator.language.slice(0, 2), txt = gContextMenu.selectionInfo.fullText, l = dir.split('|'); var encTxt = encodeURIComponent(txt); var winWait = function(lng) {createWindow('', (lng == 'ru' ? 'Подождите идет перевод' : 'Wait, is going Translating')+'\u2026', 'Google Translate', '_gt', window.navigator.lastClick);}; if (txt) { winWait(lng); var xhr = new XMLHttpRequest(); var url = 'https://translate.google.com/translate_a/single?client=gtx&sl=' + l[0] + '&tl=' + l[1] + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt); // для urlt изменил http --> https (14.10.2023); тестирую var urlt = "https://translate.google.com/translate_t?text=" + encTxt + "&sl=' + langFrom_google_text + '&tl=' + langTo_google_text +'&hl=' + lng + '&eotf=0&ujs=gtt"; xhr.open('POST', url, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8'); xhr.onreadystatechange = function() { try { if (xhr.readyState == 4 && xhr.status == 200) { // var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />")); var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "")); for (var i = 0, n; n = tmp[0][i]; i++) { if (n[0])result += n[0].toString(); }; status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + l[1].toUpperCase(); createWindow(result, status, '<a href="'+urlt.replace(/&/g,'&')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Google Translate</a>', '_gt', window.navigator.lastClick); } } catch(e) {}; }; xhr.send('q=' + encodeURIComponent(txt)); } else { var urlt = gBrowser.currentURI.spec; // Изменил строку ниже. Добавил параметр '&tl='+l[1] https://forum.mozilla-russia.org/viewtopic.php?pid=796999#p796999 & http --> https (14.10.2023) var url = "https://translate.google.com/translate?u=" + encodeURIComponent(urlt) + '&tl=' + l[1] + "&hl=" + lng + "&langpair=" + dir + "&tbb=1"; var ctabpos = gBrowser.selectedTab._tPos +1; gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos); }; }; var contextMenu = document.getElementById("contentAreaContextMenu"); var nextEleMenu = document.getElementById("context-inspect"); var menuItem = document.createXULElement("menuitem"); menuItem.setAttribute("id", "context-ru-google-translate"); menuItem.setAttribute("label", "Перевести на русский"); menuItem.setAttribute("class", "menuitem-iconic"); menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAABBUlEQVR4Ac2RMU4DMRREB2MqihQpAkUaqnAduuQw4Sx03CGcJYIiDYqQ0lCsZ77535ZFcgAkRuPvV7zd/dLiz3N1PFb8hmRckrfELZrF9ONQ1B6Yz0MyM7S0O6zGkVprh/3+Kw/JzkHSpRpJKZkpr9fYbOx0cjVsCbWG31oHBM9mtt0q73ZcrdLhAMlYQKkUI22aqsNo8HKZAMQhvVaKSHWj2Q2aPU3mJQFY7nuHyvYFduP83WF3AJRfcPNYnr/Lp1G1uK4m9sno1LaUbnX/htf8BNzoneUD5NhjvLCMhURQSQ93QCZwXYjFwg3I0NZKrvoknQPMIHkt/jRAQKMeG2yX89/mB4EJbKbZxIhFAAAAAElFTkSuQmCC"); menuItem.addEventListener("command", function() {ujs_google_translate('auto|ru');}, false); contextMenu.insertBefore(menuItem, nextEleMenu); menuItem = document.createXULElement("menuitem"); menuItem.setAttribute("id", "context-en-google-translate"); menuItem.setAttribute("label", "Перевести на английский"); menuItem.setAttribute("class", "menuitem-iconic"); menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAAB5UlEQVR4AWOgPZg0c9+Oq2+qpx9LaQaiw4mNB27efbs2uXFNQh2Q4Zm9zSNth23MhqjGnXMC86vnHmUS4udxv7OvOd2yPE7PTlfCTk9GVVEoyJA7WI8dyPA0k3U1l+jJMV7CeThpTZeoKDdDUsvBPSff/V+6/P/Bvf///2+bdvU/EKRm/k9IBNIlfZe+LFrzvbsbyJ636pKkyQyQhoUb7tZNvPpw3/0/TfX/ISAm5n94BIiRm/n/xYsLd946ei4vajoiqDuRAejQf//+o4PQ0P9+fmhiQGVnrr1kXJNYG2zEzXDxDsPv3wy/fkFJoOTPn39+/fr/69e/37//AUX+/mXRkO458wWHDba2f8wswCyQ3N+/f//8/fP7z5+TV18w2Mdt6plzPiptx5Wr7/+/ffMzOR6kysjkt74hWMPfp06O+2dulZCeFZKwnkE4m8E8bN3i9aCQ+dxY96GrK6bkGJD9R1v3l6Y20NVW9kt+/v//ZdbcFwkxTVPPMQimM8XEqkb7a/zoqLxkH9v4zVyI5+///wyMmtKMmhJAnbLqQjHxaw5r2orOmZN5uj470Zahat6BKS7JzpmLBHXm8GhM5lCdcP7ai1ZpixZxk9NXXjKIFzOIFjAI54oY1vXuue5qmscw+AAAW0tKxtPoicEAAAAASUVORK5CYII="); menuItem.addEventListener("command", function() {ujs_google_translate('auto|en');}, false); contextMenu.insertBefore(menuItem, nextEleMenu); contextMenu.insertBefore(document.createXULElement("menuseparator"), nextEleMenu); } }).init(this);
Отредактировано xrun1 (14-10-2023 11:48:48)
Отсутствует
Выложу здесь свой код google-translate.js.
Спасибо.
И у меня вопросик.
Возможно ли в этом скрипте использовать не Гугл, а другой переводчик?
Мне, например, больше нравиться DeepL.
«The Truth Is Out There»
Отсутствует
Возможно ли в этом скрипте использовать не Гугл, а другой переводчик?
Скрипт написал, примерно, в 2015-м году Алексей Рузанов aka Lex1. Остальные авторы его только модифицировали. Подробнее. Здесь есть сниппет для перевода Яндекса (сейчас не работает, проверил).
Всё это было давно, но, теоретически, возможно. Надо попробовать. В скрипте есть POST-запрос, надо смотреть, что передаётся гуглу или другому переводчику и получается в ответ. Это я так понимаю, теоретически...
var ujs_google_translate = function (dir) { var lng = window.navigator.language.slice(0, 2), txt = gContextMenu.selectionInfo.fullText, l = dir.split('|'); var encTxt = encodeURIComponent(txt); var winWait = function(lng) {createWindow('', (lng == 'ru' ? 'Подождите идет перевод' : 'Wait, is going Translating')+'\u2026', 'Google Translate', '_gt', window.navigator.lastClick);}; if (txt) { winWait(lng); var xhr = new XMLHttpRequest(); var url = 'https://translate.google.com/translate_a/single?client=gtx&sl=' + l[0] + '&tl=' + l[1] + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt); var urlt = "http://translate.google.com/translate_t?text=" + encTxt + "&sl=' + langFrom_google_text + '&tl=' + langTo_google_text +'&hl=' + lng + '&eotf=0&ujs=gtt"; xhr.open('POST', url, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8'); xhr.onreadystatechange = function() { try { if (xhr.readyState == 4 && xhr.status == 200) { // var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />")); var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "")); for (var i = 0, n; n = tmp[0][i]; i++) { if (n[0])result += n[0].toString(); }; status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + l[1].toUpperCase(); createWindow(result, status, '<a href="'+urlt.replace(/&/g,'&')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Google Translate</a>', '_gt', window.navigator.lastClick); } } catch(e) {}; }; xhr.send('q=' + encodeURIComponent(txt)); } else { var urlt = gBrowser.currentURI.spec; // Изменил строку ниже. Добавил параметр '&tl='+l[1] https://forum.mozilla-russia.org/viewtopic.php?pid=796999#p796999 var url = "http://translate.google.com/translate?u=" + encodeURIComponent(urlt) + '&tl=' + l[1] + "&hl=" + lng + "&langpair=" + dir + "&tbb=1"; var ctabpos = gBrowser.selectedTab._tPos +1; gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos); }; };
Отредактировано xrun1 (14-10-2023 11:50:50)
Отсутствует
Мне, например, больше нравиться DeepL.
На всякий случай просто к сведению. Расширение Simple Translate https://addons.mozilla.org/ru/firefox/a … translate/ добавляет два своих пункта в контекстном меню "перевести выделенное" и "перевести страницу" + плавающую кнопку.
Отсутствует
rubel
load: [ // По событию "load" { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar ... { path: "google-translate.js", ucfobj: true, },
Отсутствует
Не знаю, куда написать. Отвалилось расширение async_run_applications@vitaliy.ru.xpi. Правильнее сказать, работает, но добавить ничего не получается. Кто пользуется, проверьте, пожалуйста.
Отсутствует
Отвалилось расширение async_run_applications@vitaliy.ru.xpi.
там надо поправить в двух местах
//var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); //var {CustomizableUI} = ChromeUtils.import("resource:///modules/CustomizableUI.jsm"); //ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm"); var Services = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services; var CustomizableUI = globalThis.CustomizableUI || ChromeUtils.import("resource:///modules/CustomizableUI.jsm").CustomizableUI; Components.utils.importGlobalProperties(['IOUtils']);
// await OS.File.writeAtomic(this._storeFile.path, JSON.stringify(data), { tmpPath: this._storeFile.path + ".tmp" }).then(() => { await IOUtils.writeJSON(this._storeFile.path, data, { tmpPath: this._storeFile.path + ".tmp" }).then(() => {
Жизнь иногда такое выкидывает, что хочется подобрать...
Отсутствует
Dumby - Приветствую!
Вопрос по скрипту перехвата click, dblclick и долгое нажатие на кнопках панелей. (2021 года)
Убрал долгое нажатие и при одинарном клике стал срабатывать одинарный клик и следом двойной.
Просьба исправить ложное срабатывание DBLClick, которое происходит после одинарного клика.
Если пауза между кликами примерно как в скрипте 300 мс, в консоли видно срабатывание DBLClick. (и мышь не виновата!)
(async (id) =>{ // hookClicks TEST BUTTON var Mouse = { //meta*64 Ctrl*32 Шифт*16 Alt*8 (Wh ? 2 : But*128) long*4 dbl [id]: { 0(){ console.clear(); log('CLICK 0'); }, 1(){ log('DUBLE 0')}, 4(){ log('LONG 0')}, }}; CustomizableUI.createWidget({ id: id, label: id, tooltiptext: id, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn){ btn.style.setProperty("list-style-image","url(chrome://devtools/skin/images/settings.svg)"); } }); function log(s){console.log('■ '+ s +' '+ Math.random())} var Mus = {}; Object.keys(Mouse).forEach((k) =>{Mus["#"+ k] = Mus["."+ k] = Mouse[k]}); var listener = { // дополнительные клики кнопок и перехват существующих filter(sel) { return this.closest(sel); }, find(sel) { //условия запуска ? return Mus[sel][this] || Mus[sel][this + 1]; }, get selectors() { this.exec = (trg, obj, num) => { this.clickTID = null; obj[num](trg); } // this.onLongPress = (trg, obj, num) => { // this.mousedownTID = null; // this.longPress = true; // obj[num*4](trg); // } delete this.selectors; return this.selectors = Object.keys(Mus); }, handleEvent(e) { if (this.skip || e.detail > 2) return; if (e.type == "mouseenter") return; //update tooltips var trg = e.target; var sels = this.selectors.filter(this.filter, trg); var {length} = sels; if (!length) return; var dbl = e.detail == 2; var wheel = e.type.startsWith("w"); var num = e.metaKey*64 +e.ctrlKey*32 +e.shiftKey*16 +e.altKey*8 +(wheel ? 2 : e.button*128 +dbl); //long*4 var obj = Mus[ length > 1 && sels.find(this.find, num) || sels[0] ]; // wheel if (wheel) return obj[num]?.(trg, e.deltaY < 0); // mousedown if (e.type.startsWith("m")) { obj.mousedownTarget && this.stop(e); if (dbl) return; // this.longPress = false; //+ задержка при обычном клике // if (++num in obj) // this.mousedownTID = setTimeout(this.onLongPress, 640, trg, obj, num); if (e.button == 2) this.ctx = trg.getAttribute("context"), trg.setAttribute("context",""); return; } // click obj.mousedownTarget || this.stop(e); // if (this.longPress) return this.longPress = false; dbl ? this.clickTID &&= clearTimeout(this.clickTID) : this.mousedownTID &&= clearTimeout(this.mousedownTID); if (!obj[num]) { if (e.button == 1) return; if (e.button) { num = "context"; for(var p in this.a) this.a[p] = e[p]; } else num = "dispatch", this.mdt = obj.mousedownTarget; obj = this; } dbl ? obj[num](trg) : this.clickTID = setTimeout(this.exec, 300, trg, obj, num); }, get mdEvent() { delete this.mdEvent; return this.mdEvent = new MouseEvent("mousedown", {bubbles: true}); }, context(trg) { this.ctx ? trg.setAttribute("context", this.ctx) : trg.removeAttribute("context"); trg.dispatchEvent(new MouseEvent("contextmenu", this.a)); }, dispatch(trg) { this.skip = true; this.mdt ? trg.dispatchEvent(this.mdEvent) : trg.click(); this.skip = false; }, stop: e => { e.preventDefault(); e.stopImmediatePropagation(); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0} }; var events = ["click", "mousedown", "wheel", "mouseenter"]; var els = document.querySelectorAll("#navigator-toolbox,#ucf-additional-vertical-bar,#appMenu-popup,#widget-overflow-mainView"); for(var el of els) for(var type of events) el.addEventListener(type,listener,true); ucf_custom_script_win.unloadlisteners.push(id); ucf_custom_script_win[id] = {destructor(){ for(var el of els) for(var type of events) el.removeEventListener(type,listener,true); }}; })('ucf_hookClicks_test'); //клики-подсказки
Отсутствует
при одинарном клике стал срабатывать одинарный клик и следом двойной
Что-то не вижу такого.
Если пауза между кликами примерно как в скрипте 300 мс, в консоли видно срабатывание DBLClick
Да, согласен, 300 — это довольно погранично.
Второй клик, тогда, может быть расценен как двойной или как одинарный.
Если, зачем-то, есть желание лупить по клавише
как-то хитро, не быстро и не медленно, то чтобы всегда
было либо DUBLE, либо CLICK CLICK (то есть, чтобы не было CLICK DUBLE)
можно поднять таймаут до каких-нибудь 500.
Отсутствует
Да, согласен, 300 — это довольно погранично.
Второй клик, тогда, может быть расценен как двойной или как одинарный.
Чём больше задержка, тем позже срабатывает действие. То есть, после одинарного клика сначала пауза на время двойного клика, потом действие.
При использовании системных cliclk dblclick таких задержек нет.
Ложных срабатываний не было в скрипте с обычным кликом и долгим нажатием, а двойной клик даёт ложные сработки, специально под Windows проверял:
Dumby – может придумаешь способ назначить перехват кликов на всех кнопках панелей, используя системные onclick ondblclick ?
Это вообще возможно? Перехватывать onclick ondblclick клики всех кнопок указанных панелей вместо mousedown ?
так делается в скриптах с одной кнопкой, и клики определяет система, поэтому за одинарным не будет срабатывать двойной:
btn.linkedObject = this; for(var type of ["command", "contextmenu"]) // тут dblclick можно добавить… btn.setAttribute("on" + type, `linkedObject.${type}(event)`);
Отредактировано Dobrov (05-11-2023 03:31:31)
Отсутствует
Что ТУТ надо добавить/убавить чтобы окошко с переводом закрывалось только при нажатии на кнопку "закрыть ❌"?
Отсутствует
Dumby — твоя кнопка Быстрое переключение опций about:config содержала два контекстных меню.
Я оставил одно меню, — прошу убрать лишний код поддержки нескольких меню: popups, popupshowing… (может попроще код станет)
Актуальные версии скриптов: ucf_hookClicks.js, ucf_QuickToggle.js
/* Быстрое переключение опций about:config для окна [ChromeOnly] © Dumby 30 скрытых настроек. Ctrl+Click или Правый: сброс опции по-умолчанию клик по параметру с Shift или колёсиком блокирует авто-закрытие меню ⟳ Обновить страницу, ↯ Перезапуск браузера строки с pYellow = шрифт italic, цвет = ключ, пусто:Red refresh: false - reload current tab, true - reload skip cache restart: false - restart browser, true - restart with confirm */ (async (name, func) => { // mod by Dobrov, нужен ucf_hookClicks.js return CustomizableUI.createWidget(func()); //only UCF })(this.constructor.name, () => { var {prefs} = Services, db = prefs.getDefaultBranch(""), ua = glob.ua(true), //real ЮзерАгент I = [AppConstants.platform == "win" ? '#124' : '#e8e8e8', //текст под курсором, без Aero '#fff' "https://antizapret.prostovpn.org/proxy.pac", "user.pacfile", glob.pref(['browser.sessionstore.interval', 15e3]), parseInt(Services.appinfo.version),"general.useragent.override", "Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Android 12.0; Mobile; rv:109.0) Gecko/97.0 Firefox/97.0","Mozilla/5.0 ("], fonts = arr => arr.map(n => [(n == arr[arr.length-1] ? null : n), n]), //array с вложениями serif = fonts("Arial|Cantarell|DejaVu Sans|Roboto|PT Serif|Segoe UI|Ubuntu|Cambria|Fira Sans|Georgia|Noto Sans|Calibri|Times|системный".split('|')), sans = [["PT Sans","PT Sans"], ...serif] hints = new Map([ //опция отсутствует ? выполнить код и вернуть строку ["ucf.savedirs", `glob.crop(glob.dirsvcget(""),34)`], [I[5], `glob.ua()`]]), //текущий ЮзерАгент secondary = [{ // menu: [apref, lab, akey, hint, [undef, str], code] radio: [val, lab, str-val, add-hint, code] pref: ["dom.disable_open_during_load", "Всплывающие окна"], pDefGreen: 2, pYellow: true, values: [[true, "Блокировать"], [false, "Разрешить"]] },{ pref: ["javascript.enabled", "Выполнять скрипты Java",,"Поддержка интерактивных сайтов, рекламы\nтакже разрешает действия горячих клавиш"], pDefGreen: true, refresh: true, values: [[true, "Да"], [false, "Нет"]] },{ pref: ["browser.safebrowsing.downloads.remote.block_dangerous", "Опасные файлы, сайты",,"browser.safebrowsing.downloads.remote.block_dangerous_host"], pDefGreen: true, pYellow: false, values: [[true, "Запрет",,,`glob.pref('browser.safebrowsing.downloads.remote.block_dangerous_host',true)`], [false, "Открыть",,,`glob.pref('browser.safebrowsing.downloads.remote.block_dangerous_host',false)`]] },{ pref: ["ucf.savedirs", "Загрузки",,'Пути сохранения Страниц и Графики\nСинтаксис «_Html/subdir|_Pics/subdir»\nsubdir: пусто | 0 заголовок | 1 домен', ["", "всё в общей папке"]], pDefGreen: "_Сайты||_Фото|0", pYellow: "_Web|1|_Images|0", pGray: "", values: [ // сохранение Html/Pics. [Загрузки]/"_Html/subdir|_Pics/subdir" subdir: пусто | 0 заголовок | 1 домен ["", "всё в общую папку"], [`_Сайты||_Фото|0`, "_Сайты|_Фото/имя…"], [`_Web||_Photo|0`, "_Web|_Photo/имя"], [`_Web|1|_Pics|1`, "_Web/сайт|_Pics/…"], [`_Web|0|_Pics|`, "_Web/имя|_Pics"], [`_Web|1|_Images|0`, "_Web/сайт, _Images/имя"], //открыть опцию about:config: [`Сайт||Фото|`, "ввести свои пути",,"ключ в about:config",`glob.about_config("ucf.savedirs")`]] },null,{ pref: ["network.proxy.autoconfig_url", "Прокси (VPN)", "п", "network.proxy.type\n\nПереключение сетевых настроек"], pDefGreen: "localhost", pYellow: I[1], pGray: "", refresh: true, values: [ //фон кнопки Меню: серый, голубой, красный, жёлтый, зелёный ["localhost", "системный", "0",, `glob.pref('network.proxy.type', 0)`], ["127.0.0.1", "Tor или Opera", "1", "Необходим сервис tor или opera-proxy", `glob.pref('network.proxy.type', 1)`], [I[1], "АнтиЗапрет", "2", "Надёжный доступ на заблокированные сайты\n«Режим прокси» меняется на 2", `glob.pref('network.proxy.type', 2)`], // ["https://git.io/ac-anticensority-pac", "ac-anticensority", "3"], [glob.pref([I[2], "file:///etc/proxy.pac"]), "user .pac файл", "4", "about:config "+ I[2]], // нужен диалог выбора pac-файла [null, "сброшен",""]] },{ pref: ["network.proxy.type", "Режим прокси", "р"], pDefGreen: 5, pYellow: 2, pGray: 1, refresh: true, values: [ [5, "системный", "5"], [0, "Без прокси", "0", "по-умолчанию"], [2, "Автонастройка", "2", "about:config "+ I[2]], [1, "Ручная настройка", "1", "Используется network.proxy.autoconfig_url"], [4, "Автоопределение", "4"] ] },{ pref: ["network.trr.mode", "DNS поверх HttpS",, "Шифрование DNS-трафика для\nзащиты персональных данных"], pDefGreen: 0, pYellow: 2, pGray: 5, refresh: true, values: [ [0, "по-умолчанию", "0"], [1, "автоматически", "1", "используется DNS или DoH, в зависимости от того, что быстрее"], [2, "DoH, затем DNS", "2"], [3, "только DoH", "3"], [4, "DNS и DoH", "4"], [5, "отключить DoH", "5"] ] },{ pref: ["network.cookie.cookieBehavior", "Получать куки",, "Персональные настройки посещённых сайтов"], pDefGreen: 3, pYellow: 0, pGray: 4, values: [[0, "со всех сайтов"], [3, "посещённые сайты"], [4, "кроме трекеров"], [1, "кроме сторонних"], [2, "никогда"]] },null,{ pref: ["browser.display.use_document_fonts", "Загружать шрифты страниц"], pDefGreen: 1, pGray: 0, refresh: true, values: [[1, "Да"], [0, "Нет"]] },{ pref: ["font.name.sans-serif.x-cyrillic", "Шрифт без засечек ",,"Также влияет на всплывающие подсказки\nСистемный: загрузка шрифтов документа"], pDefGreen: "", pYellow: "Roboto", pGray: "Arial", values: sans },{ pref: ["font.name.serif.x-cyrillic", "Шрифт с засечками"], pDefGreen: "", pYellow: "Arial", values: serif },{ pref: ["gfx.webrender.force-disabled", "Ускорять отрисовку страниц", ,"gfx.webrender.compositor.force-enabled\ngfx.webrender.all\n\nАппаратная отрисовка страниц видеокартой.\nотключите при разных проблемах с графикой"], pDefGreen: false, pYellow: true, pGray: undefined, restart: true, values: [ [true, "Нет",,,`[["gfx.webrender.compositor.force-enabled", false], ["gfx.webrender.all", false]].map((a) =>{glob.pref(...a)})`], [false, "Да",,,`[["gfx.webrender.compositor.force-enabled", true], ["gfx.webrender.all", true]].map((a) =>{glob.pref(...a)})`]] },null,{ pref: ["media.autoplay.default", "Авто-play аудио/видео"], pDefGreen: 0, pYellow: 2, pGray: 5, refresh: true, values: [ [0, "Разрешить", "0"], [2, "Спрашивать", "2"], [1, "Запретить", "1"], [5, "Блокировать", "5"]] },{ pref: ["dom.storage.enabled", "Локальное хранилище",, "Сохранение персональных данных, по\nкоторым вас можно идентифицировать"], pDefGreen: false, pYellow: true, values: [[true, "Разрешить"], [false, "Запретить"]] },{ pref: ["privacy.resistFingerprinting", "Изоляция Firstparty-Fingerprint", ,"privacy.firstparty.isolate\n\nЗащита данных пользователя также\nзапрещает запоминать размер окна"], pDefGreen: false, values: [[true, "Да", , "Защита от слежки",`glob.pref('privacy.firstparty.isolate', true)`], [false, "Нет", , "Защита от слежки",`glob.pref('privacy.firstparty.isolate', false)`]] },(()=>{ if (I[4] > 114) return { //опции зависят от версии FF pref: ["browser.translations.enable", "Встроенный перевод сайтов"], pDefGreen: true, pGray: false, refresh: true, values: [[true, "Да"], [false, "Откл",,,`glob.toStatus("Перевод отключен для новых вкладок")`]] }; else return { pref: ["media.peerconnection.enabled", "WebRTC ваш реальный IP"], pDefGreen: false, values: [[true, "Выдать"], [false, "Скрыть"]] } })(),null,{ pref: ["network.http.sendRefererHeader", "Referer: для чего"], pDefGreen: 2, pYellow: 1, values: [[0, "Ни для чего", "0"], [1, "Только ссылки", "1"], [2, "Ссылки, графика", "2"]] },{ pref: ["browser.cache.disk.capacity", "Кэш браузера",,"\ncache.memory.max_entry_size:\nДиск и память: 5120\nтолько Память: -1"], pDefGreen: 1048576, pYellow: 0, pGray: 256e3, values: [ [256e3, "По-умолчанию"], [1048576, "Диск и Память",,,`[["browser.cache.memory.enable", true], ["browser.cache.disk.enable", true], ["browser.cache.memory.max_entry_size", 5120]].map((a) =>{glob.pref(...a)})`], [0, "только Память",,,`[["browser.cache.memory.enable", true], ["browser.cache.disk.enable", false], ["browser.cache.memory.max_entry_size", -1]].map((a) =>{glob.pref(...a)})`], [2097152, "только Диск",,,`[["browser.cache.memory.enable", false], ["browser.cache.disk.enable", true]].map((a) =>{glob.pref(...a)})`]] },{ pref: ["browser.sessionstore.interval", "Резервирование сессий",,"Браузер резервирует сессии на\nслучай сбоя, снижая ресурс SSD"], pDefGreen: 3e5, pYellow: I[3], pGray: 15e3, values: [ [I[3], `${I[3]/60e3 + " мин"}`], [15e3, "15 сек"], [6e4, "1 мин"], [3e5, "5 мин"], [9e5, "15 мин"], [18e5, "30 мин"]] },{ pref: [I[5], "User Agent",,"Тип гаджета меняет вид сайта", [ua, "встроенный"]], pDefGreen: ua, pYellow: I[8] + I[6], pGray: I[8] + I[7], refresh: true, values: [ [ua, "По-умолчанию"], [I[8] + I[6], "Chrome 118 Win10"], [I[8] + I[7], "Firefox 97 Android 12"], [I[8] + "Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)", "MSIE 6.0 Windows"], ["Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12 Version/12.16", "Opera12 W8"], [I[8] + "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"], [I[8] + "PlayStation 4 3.11) AppleWebKit/537.73 (KHTML, like Gecko)", "Playstation 4"], ["Windows NT 10.0; Win64; x64; Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edge/44.18363.8131", "Edge 44 Xbox One"], [I[8] + "compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; SAMSUNG; GT-I8350)", "Windows Phone"], [I[8] + "Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.143 YaBrowser/22.5.0.1916 Yowser/2.5 Safari/537.36", "Yandex OSX"], [I[8] + "compatible; Googlebot/2.1; +http://www.google.com/bot.html)", "GoogleBot"]] }]; return { id: "ToggleButton", label: "Журнал, Меню опций", localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, icon: "data:image/webp;base64,UklGRkYCAABXRUJQVlA4WAoAAAAQAAAAFwAAFwAAQUxQSJcAAAANcGJr25S8mH4SNGxAgsguPCZ0BcMOiDSNRpvVaCTa3AI2qm2e2ofz7OuwgIiYgMzb4kVjGvegnQFAwXgFVnvcOmtnMJtutAa3Vo4mhRMDpWq8AjfU+yQoYf1/oTkTIdUrknKswNQ5yAdDzqgr4CYbsJWQfEyEU5QNEl2eKFM2AAIbjmSIMjwXPGyEdj6Bdn4mj9KO63sAAFZQOCCIAQAAdAgAnQEqGAAYAD6dRppKgoCqgAE4lsAKwgisgG27uzPePSvBIu/Pr0HJqW+AfoAIHl2DrAnRo/G3JBpTx8yE7L6LFQyD+yUNvuRYAAD+7mwmpaoBcsJ1hVKsMI2ucqid8qndm+WEvH4l4il6lA8FPscgnrRHrnSjjyNcfUV21+TkfqOWKou2UvVsZSl1z+jKs760Vij5XCWF9Uo6TZAhKfrJpeILyQYwq2Ee/g1uyEH/dJMI/91DsVpI6i2vV/Jqpd4/KniJtTm1woLvaotA2ikt3eeBaqlHf8WPe++lSWS7fETjgvzzbflp0Rj+v23kbb9e/VjUcPaD83shRuwzEo6CAO/AGxE+Zwbvv9NDsQT6T+S4CCDOFTuMRVv9/0E4P+uK+Vc3bMfQQD05gY/fes+ZX6ZHkvFdMn7zX8LMVvI59p7F806HPD2lBjs4lWWhQ5ckJDNflZL49370shr3/Q9uMJN9i/NVCu4OT7K3+4+/RkAMnjuY09u+3i4y4CldQG789iIAAAA=", defGreen: "data:image/webp;base64,UklGRgoBAABXRUJQVlA4TP0AAAAvD8ADEI9hpG2kwpf60h8+nBQkbSSp/tW9hIMPFw5E0kaSKuP9q3kJDx8ePDjQSCQp2z8RkhhIHBVAEdD9J4JYEkEUJSiDD0EIEcFgBSIspCAcbdlyRzfeYpwnDotGYFHIfXe6pdToDwUE2bZNRzds24qTx9b8h+chHET0fwLiX3vNO6jyh5aWbwMaqX3Ttu/j0VDG+5ZB9nQ2nYwBUGepB8vqYH9v+qrpnsESzDcnh9i3DZ4oB3cfPD0+kmSTuyCucHH+8dXwLphnt5+6vgQlz3KwrB90f3drUFqXYE/zJz9KsufsQbatX741WnxtabN4hjds8X2veQdVxr8CAA==", Gray: "data:image/webp;base64,UklGRsgAAABXRUJQVlA4TLsAAAAvD8ADEFW4rbVtaVj67ViCCWhDSugiHSSVle7uMoJnhO973wgztW2IIZo4RvFEMdqu2rZtGJfNqWfYX0SisXgaGvkBFK5k4EEDTtS7Q31XN3ei94VeQuI61k6unuRaB86CMExsYWnFt+imhRgmCMMWJmYWliTRJgrYIAzfJfUMSCK7hDdji3VQkkTjE9hMrsCmNheZy9gzEqlhndwlMoJ5NSqr+KCIfPuDUm+Uoz7+FEmkmIjg/Pcf/6EBAA==", Red: "data:image/webp;base64,UklGRhwBAABXRUJQVlA4TBABAAAvD8ADEL+hNJKkaOTJkycJn7CQJ5GjeXIgE4ZY/5Qq+HyMRJJyEvkR6K+IQwQk8qSRSFJWfgwkMZD0b0IC1KZtwDhl9h1Afx+SIEmAIEmChO+PwVWRpOsj2EgllBRDKy1EiJmhs5ztdaTnOAkEFBjQIGAdDiPJNq37bdu2nX9uDOGevQcR/SeQtNn+Aovh/vL2eF1FYR/cz9tNJKgHvf+4jseiYn59JAC38yqV8N57SDibw3OXzaQlyWKE3dPhtSzkshkiAttSHa4VLRXzqkqhogJIvVEjLbNWScIVeC3araaGoOqxeDk89z3rdphZzMITuF3mA/SJCFA2B9xPs9FkbKTsP8JcDtMhB7nQ747/CA==", Yellow: "data:image/webp;base64,UklGRv4AAABXRUJQVlA4TPEAAAAvD8ADEFeBppGkTMdJQAKSkI0MSsoTgAhDkW1sG3VEF0EER06Mtm1jWBi4/68cNBJJykpiIHFUQNK/CQlIOO+Lr4fmLsUtio7rgkBiUAjszusVxAQkHiEB8xAnXoQwz5sOM4QYHEaSbVrnWf8/21b+GX6GsBvRfwJBCHHADPlLlGQhM0Qfif18v7HTj9/3mI7z4onp8Wrkj+t2ANg4+pEgdYZ5WTdwmQcnFWRF2w8zAPZtkQnCik3bAWhZMRRQAVDVrEoFCAWZoamkApKakQlSV4f2BnBTQRSYxgcGkQDx0zLfWM+PYwLPNml7iH//+A8AAA==", onCreated(btn) { btn.setAttribute("image", this.icon); var doc = btn.ownerDocument; btn.domParent = null; btn.popups = new btn.ownerGlobal.Array(); this.createPopup(doc, btn, "secondary", secondary); btn.linkedObject = this; for(var type of ["contextmenu", "command"]) // "mousedown" "auxclick" события btn.setAttribute("on" + type, `linkedObject.${type}(event)`); this.addSheet(btn); }, addSheet(btn) { //текст под курсором var cb = Array.isArray(btn._destructors); var id = cb ? btn.id : "ToggleButton"; var css = `#${id} menu[_moz-menuactive] { color: ${I[0]} !important; }`; var args = [ "data:text/css;charset=utf-8," + encodeURIComponent(css), Ci.nsIDOMWindowUtils.USER_SHEET ]; if (cb) var destructor = function() { this.removeSheetUsingURIString(...args); } var add = b => b.ownerGlobal.windowUtils.loadSheetUsingURIString(...args); (this.addSheet = !cb ? add : btn => { add(btn); btn._destructors.push({destructor, context: btn.ownerGlobal.windowUtils}); })(btn); }, createPopup(doc, btn, name, data) { var popup = doc.createXULElement("menupopup"); var prop = name + "Popup"; btn.popups.push(btn[prop] = popup); popup.id = this.id + "-" + prop; for (var type of ["popupshowing", "click"]) popup.setAttribute("on" + type, `parentNode.linkedObject.${type}(event)`); for(var obj of data) popup.append(this.createElement(doc, obj)); btn.append(popup); }, map: {b: "Bool", n: "Int", s: "String"}, createElement(doc, obj) { // pref if (!obj) return doc.createXULElement("menuseparator"); var pref = doc.ownerGlobal.Object.create(null), node, img, bool; for(var [key, val] of Object.entries(obj)) { if (key == "pref") { var [apref, lab, akey, hint, undef, code] = val; // строка меню pref.pref = apref; pref.lab = lab || apref; if (hint) { if (RegExp(/\p{L}/,'u').test(hint[0]) && (hint[0] === hint[0].toUpperCase())) hint = '\n'+ hint; pref.hint = hint; } if (undef) pref.undef = undef; //если не массив: undef || undef == "" if (code) pref.code = code; } else if (key == "image") img = val, pref.img = true; else if (key != "values") pref[key] = val; else pref.hasVals = true; } var type = prefs.getPrefType(pref.pref); var str = this.map[type == prefs.PREF_INVALID ? obj.values ? (typeof obj.values[0][0])[0] : "b" : type == prefs.PREF_BOOL ? "b" : type == prefs.PREF_INT ? "n" : "s" ]; pref.get = prefs[`get${str}Pref`]; var map, set = prefs[`set${str}Pref`]; if (pref.hasVals) { for(var [val, , , , code] of obj.values) code && (map || (map = new Map())).set(val, code); if (map) pref.set = (key, val) => { set(key, val); map.has(val) && eval(map.get(val)); // выполнить код } } if (!map) pref.set = set; node = doc.createXULElement("menu"); node.className = "menu-iconic"; img && node.setAttribute("image", img); akey && node.setAttribute("accesskey", akey); (node.pref = pref).vals = doc.ownerGlobal.Object.create(null); this.createRadios(doc, str.startsWith("B") && !pref.hasVals ? [[true, "true"], [false, "false"]] : obj.values, node.appendChild(doc.createXULElement("menupopup")) ); if ("pDefGreen" in obj) pref.noAlt = !("pYellow" in obj); return node; }, regexpRefresh: /^(?:view-source:)?(?:https?|ftp)/, upd(node) { var {pref} = node, def = false, user = false, val; // если опция не найдена if (prefs.getPrefType(pref.pref) != prefs.PREF_INVALID) { try { val = pref.defVal = db[pref.get.name](pref.pref); def = true; // опция по-умолчанию получена } catch {def = false} user = prefs.prefHasUserValue(pref.pref); if (user) try {val = pref.get(pref.pref, undefined);} catch {} } if (val == pref.val && def == pref.def && user == pref.user) return; pref.val = val; pref.def = def; pref.user = user; var exists = def || user; if (!exists && pref.undef) // опция не найдена ? вернуть default-значение val = pref.undef[0]; var hint = eval(hints.get(pref.pref)); if (!hint) hint = val != undefined ? val : "Эта опция не указана"; if (hint === "") hint = "[ пустая строка ]"; hint += "\n" + pref.pref; if (pref.hint) hint += "\n" + pref.hint; node.tooltipText = hint; //+ текст var img, alt = "pYellow" in pref && val == pref.pYellow, pro = "pGray" in pref && val == pref.pGray; if (alt) img = this.Yellow; if (pro) img = this.Gray; if ("pDefGreen" in pref) if (val == pref.pDefGreen) node.style.removeProperty("color"), img = this.defGreen; else { node.style.setProperty("color", "#702020", "important"); if (!alt && !pro) img = this.Red; } node.setAttribute("image", img || this.Gray); // серый значок, если нет pDefGreen user ? node.style.setProperty("font-style", "italic", "important") : node.style.removeProperty("font-style"); var {lab} = pref; if (exists && pref.hasVals) { if (val in pref.vals) var sfx = pref.vals[val] || val; else var sfx = user ? "другое" : "стандарт"; lab += ` ${"restart" in pref ? "↯-" : "refresh" in pref ? "-⟳" : "—"} ${sfx}`; } lab = exists ? lab : '['+ lab + `${"restart" in pref ? " ↯" : "refresh" in pref ? " ⟳" : ""}` +']'+ `${pref.undef ? " - "+ pref.undef[1] : ""}`; node.setAttribute("label", lab); // имя = [имя] если преф не существует }, createRadios(doc, vals, popup) { for(var arr of vals) { var [val, lab, key, hint] = arr; var menuitem = doc.createXULElement("menuitem"); with (menuitem) setAttribute("type","radio"), setAttribute("closemenu","none"), setAttribute("label", popup.parentNode.pref.vals[val] = lab), key && setAttribute("accesskey", key); var tip = menuitem.val = val === "" ? "[ пустая строка ]" : val; if (hint) tip += "\n" + hint; menuitem.tooltipText = `${tip != undefined ? tip + "\n\n" : ""}клик с Shift блокирует авто-закрытие`; popup.append(menuitem); } }, openPopup(popup) { var btn = popup.parentNode; if (btn.domParent != btn.parentNode) { btn.domParent = btn.parentNode; if (btn.matches(".widget-overflow-list > :scope")) var pos = "after_start"; else var win = btn.ownerGlobal, {width, height, top, bottom, left, right} = btn.closest("toolbar").getBoundingClientRect(), pos = width > height ? `${win.innerHeight - bottom > top ? "after" : "before"}_start` : `${win.innerWidth - right > left ? "end" : "start"}_before`; for(var p of btn.popups) p.setAttribute("position", pos); } popup.openPopup(btn); }, maybeRestart(node, conf) { if (conf && !Services.prompt.confirm(null, this.label, "Перезапустить браузер?")) return; var cancel = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); Services.obs.notifyObservers(cancel, "quit-application-requested", "restart"); return cancel.data ? Services.prompt.alert(null, this.label, "Запрос на выход отменён.") : this.restart(); }, async restart() { var meth = Services.appinfo.inSafeMode ? "restartInSafeMode" : "quit"; Services.startup[meth](Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart); }, maybeRe(node, fe) { var {pref} = node; if ("restart" in pref) { if (this.maybeRestart(node, pref.restart)) return; } else this.popupshowing(fe, node.parentNode); if ("refresh" in pref) { var win = node.ownerGlobal; if (this.regexpRefresh.test(win.gBrowser.currentURI.spec)) pref.refresh ? win.BrowserReloadSkipCache() : win.BrowserReload();} }, maybeClosePopup(e, trg) { (e.shiftKey || e.button == 1) || trg.parentNode.hidePopup(); }, popupshowing(e, trg = e.target) { if (trg.state == "closed") return; if (trg.id) { for(var node of trg.children) { if (node.nodeName.endsWith("r")) continue; this.upd(node); !e && node.open && this.popupshowing(null, node.querySelector("menupopup")); } return; } var {pref} = trg.closest("menu"), findChecked = true; var findDef = "defVal" in pref; var checked = trg.querySelector("[checked]"); if (checked) { if (checked.val == pref.val) { if (findDef) findChecked = false; else return; } else checked.removeAttribute("checked"); } if (findDef) { var def = trg.querySelector("menuitem:not([style*=font-style]"); if (def) if (def.val == pref.defVal) { if (findChecked) findDef = false; else return; } else def.style.setProperty("font-style", "italic", "important"); } for(var node of trg.children) if ("val" in node) { if (!pref.val && pref.val != "" && pref.undef) pref.val = pref.undef[0]; // опции нет ? вернуть по-умолчанию if (findChecked && node.val == pref.val) { node.setAttribute("checked", true); if (findDef) findChecked = false; else break; } if (findDef && node.val == pref.defVal) { node.style.removeProperty("font-style"); if (findChecked) findDef = false; else break;} } }, click(e, trg = e.target) { //строки меню if (e.button) return; var {pref} = trg; if (!pref) return; }, command(e, trg = e.target) { // LMB на кнопке var newVal = trg.val, menu = trg.closest("menu"); if (!menu) return; this.maybeClosePopup(e, menu); if (newVal != menu.pref.val) menu.pref.set(menu.pref.pref, newVal), this.maybeRe(menu, true); menu.pref.code && eval(menu.pref.code); //run }, contextmenu(e, trg = e.target) { if ("pref" in trg) { this.maybeClosePopup(e, trg); if (trg.pref.user) prefs.clearUserPref(trg.pref.pref), this.maybeRe(trg); var code = trg.pref.code; code && eval(code); //run } e.preventDefault(); } }; });
Отсутствует
В скрипт ucf_hookClicks.js добавил меню команд пользователя, которое открывается по клику колёсиком на кнопке QuickToggle about:config или на любой другой кнопке, например:
trg = document.getElementById("unified-extensions-button");
document.getElementById("QuickToggle").menupopup.openPopup(trg, "before_start");
Теперь в одном скрипте есть меню пользователя, перехват нажатий клавиш, событий мыши, подсказки кнопок, меню настроек.
Все опции в начале скрипта можно править «под себя», например добавить команды аналогично кнопке Save+
Нужно убрать из CustomStylesScripts.jsm скрипт ucf_QuickToggle.js, так как эти коды сведены в один ucf_hookClicks_new.js
Отредактировано Dobrov (21-11-2023 06:25:24)
Отсутствует
Dumby посмотрите пожалуйста код кнопки в ней тусклая иконка если svg.context-properties.content.enabled стоит в false
//Очистить историю try { ((img, preventClearThumbs) => { CustomizableUI.createWidget({ id: "bt-clear-history", label: "Очистить историю", tooltiptext: "Очистить историю", defaultArea: CustomizableUI.AREA_NAVBAR, onCreated: function(bt) { bt.image = img; }, onCommand: function(event) { var win = event.target.ownerDocument.defaultView; var itemsToClear = [ "history", "sessions", "formdata", "cache", "downloads", "offlineApps", "pluginData" ]; var range = win.Sanitizer.getClearRange(0); win.Sanitizer.sanitize(itemsToClear, { ignoreTimespan: !range, range, }).then(() => { var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); alertsService.showAlertNotification(img, "История Очищена!", "", false); win.setTimeout(()=> alertsService.closeAlert(), 2000); }); } }); })("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M5.5.7c1.1 0 1.1 1.6 0 1.6S4.4.7 5.5.7zm8.3.5L9.5 5.5s-1.24.1-2.68.12C5.18 7.15 4.12 7.66.822 8.01v1.2C3.35 13.3 4.97 15.2 9.21 15.2h1.09c1.4-1.7 2-2.9 2.5-4.9V9.21c-.5-1.19-1.6-2.41-1.6-2.41l4.1-4.1zm-10.3 2c1.7 0 1.7 2.6 0 2.6s-1.7-2.6 0-2.6z'/></svg>", null); } catch(e) {}
Отредактировано egorsemenov06 (28-11-2023 09:38:42)
Отсутствует
Помню был скрипт для смены User-Agent для определенного сайта. Подскажите рабочий для 115 код или ссылку на код.
Отсутствует