переделайте пожалуйста под UCF кнопку Reload user{Chrome, Content}.css
JSM'ка
var name = "UCF_userContentReloader", EXPORTED_SYMBOLS = [name + "Child"]; if (typeof Services != "object") var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); var find = function(sheet) { return sheet.href == this; } var getSheet = (doc, href) => InspectorUtils.getAllStyleSheets(doc).find(find, href); if (!ChromeUtils.domProcessChild.childID) { var noop = () => {}; ChromeUtils.import("resource:///modules/CustomizableUI.jsm").CustomizableUI.createWidget({ label: "Reload user{Chrome, Content}.css", tooltiptext: "L: Reload userChrome.css\nR: Reload userContent.css", id: "798278", localized: false, onCreated(btn) { btn._handleClick = this.click; btn.oncontextmenu = oncontextmenu; btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIpwAACKcBMsYCAwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMwSURBVEiJ5dbNb5RVFMfxz3mmrYgYE0IN4IaKb4n4UqOwMCYu2JCoQVDiwoUrQ4j0xao7ExITQxRoodEFK1cmRkSE8AeYYKpEFF0YY4SiUSMRQW0sLe0818U8nekwHe3U7vhtnnNOzj3f89znPvderjVFK8npaSWrPSjpElahQzhvyrF4y++t1GqbF7DHOvQLj6Ozrt2EDutYRHAasMK0vXgWWZO0SX/7DlJf6Skp3UWcFeVRV4zG235tCZx6rDPtKLqqAN4XPhROm3DJEiG3LA6aKkZ14jUSKaOd1Gsco6Qz8vRiDDvTFJz63S13AjdVAg7JvBxDzs2RfrE2MP9ijolZijvJXo/h8pmmb5z6LZf7qICWJQNxwP5mM1OnzNdy03V1U0oi2x77y+/Wp16t3CDWgvDKvKGIQZepfO+iWBIpKG9s7HGW0k7dKgsJjsSQffOF1or4srAuS04U9jOp14amYGGgiF2Re6llaEWnMSbPNyl5DtNFQzvnBKdd2oRNhXt4ZvW1rCwfkbInY9jHMeiscBiEJ9Lz2mfSaovgovXC8sI7siAoYsgnMy8JkmPYhhtdbwOV6a9NdVhT69qphYIblPl0FuO2WrimVVVrcu7dZkFqd75q525uBCelqj0tXzRwvSYbwWZ1doOVi4Yad0vVDj81gjPfV+2y9YsGLnlgFrj6p9TA405irPAemwmn/raNqc/D/wO9uXj+bMhXDeDihDledLYt9VmTektb5flxebYgcOpx+yzw0aic3vXgSqY9hdUuOUx6T+WWcX/LUELYh3ZMyqq1G8FxwCl8ULjdVFd6d6tgPQbMfLIwHIPONgVXWs1OFm3Mjt6Rdlg2X2bq0yfsLtzP/OHVq3PqzuPUm/Vj9xz9ZDrcg5F/Bb6gS8mbkq1F6EdlW+IdE03Baae1pEeJb1SuO0vrMvPsPvKRArDaChf8qWRal/BQccBsxnXFiBFTtjS7czW93qYdVurQJZW6SLeK+DaGyofSLh0uGUNHk6F/SfZI3ojh2k41b3DThnrdS+1/nAnjcxzR5mDsdeG/6szrXl2nJX4w4RFJJ3LhF7lzMey3lmtdU/oHaoj4Y/PDRWgAAAAASUVORK5CYII="); }, get click() { var {file, spec} = getURI("hrome"); var chromeSheet = getSheet(Services.wm.getMostRecentWindow(null).document, spec); delete this.click; return this.click = !chromeSheet ? noop : function() { var win = this.ownerGlobal; if (win.event?.detail < 2 && file.exists()) reload(chromeSheet), win.setTimeout(restyle, 50); } } }); var getURI = sub => { var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append(`userC${sub}.css`); return Services.io.newFileURI(file).QueryInterface(Ci.nsIFileURL); } var oncontextmenu = e => e.ctrlKey || e.shiftKey || e.detail != 1 || contextmenu(e); var contextmenu = e => { var {file, spec} = getURI("ontent"); var wb = Services.appShell.createWindowlessBrowser(); var contentSheet = getSheet(wb.document, spec); wb.close(); if (!contentSheet) return oncontextmenu = contextmenu = noop; ChromeUtils.registerProcessActor(name, {child: {moduleURI: __URI__}}); (contextmenu = async e => { if (!file.exists()) return; e.preventDefault(); var data = await reload(contentSheet, Object.create(null)); if (data) for(var p in data) { for(var dp of ChromeUtils.getAllDOMProcesses()) dp.remoteType && await dp.getActor(name).sendQuery(spec, data); restyle(); return; } })(e); } var restyle = () => { var subst = "u_css_reloader_restyle_substitution"; var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); rph.setSubstitution(subst, Services.io.newURI("data:text/css,:root{}")); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var args = [Services.io.newURI(`resource://${subst}/`), sss.USER_SHEET]; (restyle = () => { sss.loadAndRegisterSheet(...args); sss.unregisterSheet(...args); })(); } var reload = async (sheet, obj) => { try {var style = await (await fetch(sheet.href)).text();} catch {return obj;} InspectorUtils.parseStyleSheet(sheet, style); if (obj) obj[sheet.href] = style; for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); rule.type == rule.IMPORT_RULE && rule.styleSheet.href.startsWith("file:///") && await reload(rule.styleSheet, obj); } return obj; } } else var UCF_userContentReloaderChild = class extends JSProcessActorChild { receiveMessage(msg) { var {sheet} = this; if (!sheet) { var en = Services.ww.getWindowEnumerator(null); if (en.hasMoreElements()) sheet = this.sheet = getSheet(en.getNext().document, msg.name); } sheet && this.parse(sheet, msg.data); } parse(sheet, data) { var style = data[sheet.href]; if (!style) return; InspectorUtils.parseStyleSheet(sheet, style); for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); rule.type == rule.IMPORT_RULE && rule.styleSheet.href.startsWith("file:///") && this.parse(rule.styleSheet, data); } } }
1) Для ссылок это не работает, поэтому не понятно, что будет делать данный жест для ссылки.
2) я дополнил код, но при показе текст в строке статуса быстро исчезает - пример в строке 6 скрипта.
2) showInStatus() не для того, чтобы им что-то дополнять,
это, скорее, для показа самих жестов.
1) У меня не воспроизводится, ну, если страница загружена,
то есть, если ничего от загрузки не вмешается.
Но, затем вспомнил, что у лисы для Linux что-то странное творится
вокруг драга ссылок, проверил, и да, там вижу.
Вот, ничего лучше не придумал, как на старте отключить StatusPanel.update(),
а на финише вернуть, и mouseup послать в окно, чтобы не залипало обновлять.
Может сам что-нибудь разумнее подкумекаешь. А это в конце метода drag()
… //init || win.StatusPanel.panel.setAttribute("inactive", true); var sp = win.StatusPanel; if (init) { var upd = sp.update; (sp.update = () => {}).upd = upd; } else { win.windowUtils.sendMouseEventToWindow("mouseup", -1, -1, 0, 1, 0); win.setTimeout(() => sp.update = sp.update.upd, 350); sp.panel.setAttribute("inactive", true); }
Не проверите?
ссылка то появляется, кнопка не реагирует...Уточняю, если перед вкладкой пустая,тогда и не реагирует на закрытие нормальной...
Проверил. Не получилось воспроизвести.
Под «реагирует», надо полагать, подразумевается переход
кнопки из статуса "disabled" в обычный, то есть видимая реакция иконки.
Ставил перед «нормальной» и вкладку "about:blank",
и лисью дефолтную новую, и даже новую, заказанную WebExtensions.
Ну,пипец, fission.autostart.session = false //Заблокировали...
А почему ппц, и почему false?
Это чисто служебная настройка, предназначенная только
для чтения дочерними процессами. А само значение вычисляется
(и затем блокируется) в родительском процессе.
Вычисляется по многим факторам, но, скажем так: если ничего не помешает,
и переключить fission.autostart в true, то при следующем старте заблокируется уже в true.
Куда это ?
«Это» здесь ничем не поможет, там вообще нет статуса "disabled".
А ещё, «это», при каждом запуске, создаёт виджет с новым id, что приводит
не только к тому, что кнопку нельзя расположить в нужном месте,
но и к добавлению очередных новых записей в browser.uiCustomization.state,
и, через какое-то время, там порядочно этого мусора накопиться.
Отсутствует
JSM'ка
Большое спасибо!
Dumby, просветите пожалуйста ещё по такому вопросу.
У меня в СВ есть вот такие простенькие коды:
gBrowser.tabContainer.addEventListener("wheel", e => { if (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) { return; } e.stopPropagation(); e.preventDefault(); setTimeout(function() { gBrowser.tabContainer.advanceSelectedTab(e.deltaY > 0 ? 1 : -1, true); }, 25); }, true);
function closeTabEsc(e) { if (e.keyCode === 27 && window.fullScreen) { window.fullScreen = !window.fullScreen; } else if (e.keyCode === 27 && !window.fullScreen) { e.stopPropagation(); e.preventDefault(); setTimeout(function() { gBrowser.removeTab(gBrowser.selectedTab); }, 100); } } document.addEventListener("keydown", closeTabEsc, false); addDestructor(()=> document.removeEventListener("keydown", closeTabEsc, false));
addEventListener("dblclick", function(e) { if ( e.button == 0 && e.target.matches("tab :scope:not(.tab-close-button):not(.tab-icon-sound), tab") ) { e.preventDefault(); e.stopPropagation(); var vert = `javascript:(function(d,scrT){scrT=d.documentElement.scrollTop||d.body.scrollTop;if(scrT>window.innerHeight){localStorage['bmk_'+d.location.href]=scrT;scrollTo(0,0)}else{scrollTo(0,localStorage['bmk_'+d.location.href]||0)}})(document)`; gBrowser.loadURI(vert, { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() }); }; }, true, gBrowser.tabContainer);
if (WindowIsClosing()) { CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed); }
addEventListener('keydown', e => { if (e.shiftKey && e.code=="KeyZ") { e.preventDefault(); try { CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").collapsed) = !CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").collapsed) } catch(e) { } } });
scriptschrome: { // Для докум. окна браузера [ChromeOnly] load: [ // По событию "load"
то они в принципе работают. Но я не уверен, что это правильное решение.
Можно ли подключать эти коды таким способом или их надо как-то переделать под UCF?
И, если надо переделать под UCF, то как?
«The Truth Is Out There»
Отсутствует
Dumby - спасибо, теперь скрипт жестов мыши заработал отлично!
ещё может влиять расширение Link Status Redux, вывод в консоли: StatusPanel.update is not a function. В настройках этого расширения убрал отключение индикатора браузера.
Отредактировано Dobrov (14-02-2022 19:12:07)
Отсутствует
Можно ли подключать эти коды таким способом или их надо как-то переделать под UCF?
И, если надо переделать под UCF, то как?
Что-то слегка не связанные вещи.
Подключение — да, код кнопок исполняется в окне браузера,
так что — верно, «Для докум. окна браузера»,
и «По событию "load"» — ближе всего по моменту времени исполнения.
А вот что и как переделывать в самих кодах ...
Вроде уже упоминал, что меня нет однозначного мнения на этот счёт,
и узнать негде, с одной стороны, вроде принято удалять, а сдругой стороны,
браузер сам бы должен это прибирать, не знаю.
Если удаление тяжело дописывать, то, наверно, можно оставить как есть,
ну не съест же это всю память, в конце концов.
2. Вот здесь идёт вызов addDestructor(), которого нет (это от CB).
Должна образоваться ошибка, но поскольку это последняя строка, то всё работает.
Лучше убрать. Или заменить, если возвращаться к вышесказанному.
И, отвлекаясь на код, странная там какая-то конструкция проверки, избыточная,
и window.fullScreen = !window.fullScreen; выглядит как переключатель,
но таковым не является. Может лучше так, если без return (не проверял)
/* if (e.keyCode === 27 && window.fullScreen) { window.fullScreen = !window.fullScreen; } else if (e.keyCode === 27 && !window.fullScreen) { // ....... } */ if (e.keyCode == 27) { if (window.fullScreen) window.fullScreen = false; else { // ....... } }
3. А вот здесь ещё один кусок CB-специфики, посерьёзнее.
В кнопках addEventListener определен как функция, и используется так:
addEventListener("eventType", listener, captureFlag, eventTarget);
А вне CB, это будет интерпретировано как вызов метода window.addEventListener(),
то есть, листенер уйдёт в окно, и событие "dblclick" будет отслеживаться,
(и, соответственно, обрабатываться) по всему окну, а не только там, где вкладки,
а это нехорошо и не нужно.
Следует использовать addEventListener() как метод eventTarget,
то есть, такую конструкцию:
eventTarget.addEventListener("eventType", listener, captureFlag);
В данном случае, eventTarget — это gBrowser.tabContainer
4. и 5. Это нечто совсем уже кривое.
Ошибку «cannot assign to function call» я, пожалуй, вообще впервые увидел.
Может как-то так, если я правильно понял. Оба два
(async bar => { var stv = CustomizableUI.setToolbarVisibility.bind(null, bar.id); bar.collapsed || stv(); addEventListener("keydown", e => e.shiftKey && !e.repeat && e.code == "KeyZ" && !docShell.isCommandEnabled("cmd_insertText") && (e.preventDefault(), stv(bar.collapsed)) ); })(document.getElementById("PersonalToolbar"));
Отредактировано Dumby (15-02-2022 10:01:11)
Отсутствует
Что-то слегка не связанные вещи.
Подключение — да, код кнопок исполняется в окне браузера,
так что — верно, «Для докум. окна браузера»,
и «По событию "load"» — ближе всего по моменту времени исполнения.
А вот что и как переделывать в самих кодах ...
Dumby, огромное спасибо за развёрнутый ответ.
«The Truth Is Out There»
Отсутствует
Подскажите, как получить реальный ЮзерАгент, а не тот, что прописан в "general.useragent.override" ?
Иначе говоря, как получить значение опции по-умолчанию, то есть то значение, когда опция, например "general.useragent.override" сброшена?
Проблема в том, что если в "general.useragent.override" уже что-то прописано, то данный код вернёт пользовательское значение, а нужен ЮзерАгент по-умолчанию, который вшит в Firefox:
// вернёт строку из "general.useragent.override", а нужен реальный ЮзерАгент браузера: Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).userAgent
Отсутствует
Допустим, под «предыдущей посещенной вкладкой»,
подразумевается предыдущая (по времени)
активировавшаяся вкладка, не скрытая и не закрытая.
Следует понимать, что такой может не быть,
тогда переход пойдёт туда, куда перейдёт сам браузер.
Добавьте пожалуйста в этот скрипт (p798193) такое же поведение при ЛКМ по активной вкладке, если возможно. 78.
Спасибо.
Отредактировано Krtec (17-02-2022 21:22:48)
Отсутствует
ВВП
Через скрипты, контекст показывает, только я сменил
ивосстанавливает левой, меню средней, но иногда что то глючит, и если уже вкладку восстановил левой, то контекст не показывает по СКМ, тогда надо правой, а потом уже СКМ.
Отсутствует
Пользуюсь такой кнопкой для перевода:
/*Initialization Code*/ var lc = navigator.lastClick = {}; addEventListener("mouseup", e => { if (e.button) return; lc.X = e.screenX - mozInnerScreenX; lc.Y = e.screenY - mozInnerScreenY; }, false, gBrowser.tabpanels || 1); 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()}; // закрыть окно переводчика кликом мимо окна gBrowser.addEventListener("click", function c() { this.removeEventListener("click", c ); try { doc.getElementById(wId).closeWin() } catch(e) {}; }, true ); 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); this.parentNode.removeChild(this); }; 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); }; 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:20px;height:20px;padding:0;margin-top:1px;margin-right:0px;border:none;cursor:pointer;background-image:url("data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAACXBIWXMAAAAAAAAAAAHqZRakAAAEMklEQVQ4y6WUW2xUVRSG/305M51ppy0XgV60pUGgWkyggBIvITEpCYaIodGopSbElDRBQUPwyfiAJkQBTUFBohgUSUnEB1B8aCChCQQRgZpWiuXSDLRD6ZmWOXPO2Z1z2cuHQqnSGBLX49or317r3//aEuNCAgARUX/DurQEgBu1FZmE4EKOlfS+2mxWHPhiiiy6/Iu4UVuRkQBwbXOLDrUGAAjOR0nGj4evVJ5rmwUAZm1dj8QEIU8tr6fpTz1LdxOdu7edlK55S0VnlqKsoT7268rG4VToSWndMlVZQ/3ks9t2WPkF8ZF+PyR5Xg3EliyszMwggmAsngxyZyQAHCuptKavWJEAY/ddand1edmrFx+VACDnVuflR4vd+NIlhhYcqZ/bgvl7tsY6m99TpQuepvbLlw5KALBvmYp3d2d7L1zgi9sPl8x4cZnR8eU3braz05qaXxjcDAOSAGANDqqIFQzlky9OlFZnfSJMXlybV3A16USNiN8XeKMKtQYDi4546f0MTIw11/4TAGBE698PWfb6CVWbUMljJSUV8VnVPYnHaoz7TokwcORI9vlUb6G0mbG/qm6lJCKif9QQBOeIzV+YQKoXMqu15IOm8sIAs3Z+FD/ftFFNq1sqpWHAO37K95VjAIC0KQA3TRX4HgMQn79nawwAruxrVbF0WvmOw0YLNUikhxT8HP9r197s7OY1CQD4c9fX2UXFU72co0aJVhhCDqZVwby5sfLmNYlz23daC95dV7jidNs0s7auJ+c4cQCQWQoh0mnlHW/3Lr7UGAyf/s079snnN2OMUXUklssp1wcAmSF9VkwbWl1EBJU8weaU3ptcCEVdyWwUAOTe27ffzlwKKI/z2vtkBIUODxrG1gUATpbMrCCmNzIZeYIJEg/yWhSykIJcBxBsfaa/PzkGPDq9dEfwSPnaORs2GRN597+p9NylT7esPRqyXcsH+jaM2laIhYniKUJ1dPmaCEQETYRo+QzmXu8fbwDEHi5h6nqKOGOI3Nl6Pukhad9IPjnWoR1q+Lbj87SZo1BDVJbLivffid+FXDtwKEcAql5bFb2b6/7gY1ekBgMA8G0naof63pdj65A8x/ENc8ilUDN1c4CdWfaKU7zqhfjspsb8meNAnV99p65//4NbZER0cUFhCACe43BbhzQOqOE5TiBMU0kdMq41K3vj5aKypsb8f0tW8+bqmDGi/PS+VkuMeP4dYJ6tx3VoUYiccn1uDimuNRMUcua6cQDoadk9/Me2nZlAE3v8raZEzab1kyPEAjlsKeH4PgDklFtgUThuZNKBct1AjpgKIJZHxEY+/Ex1bd6e0gCqQAwA/C0tVseWlj4BRpMYJ8GdAACUdgObdHCvQ6ChTdud3TF3Xk2RETH4gznG10BXxveSTpjzuXx9DPjt8HASQCFuA+jD/4q/AYOlLA+pNh89AAAAAElFTkSuQmCC");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(); } var cnt = w.addEle1(text, 'display:block;border:1px solid #aaa;padding-bottom:3px;padding-left:3px;background-color:#fafcfe;color:#000;font:17px Times New Roman;width:260px;height:100px;overflow:auto;cursor:text;-moz-user-focus:normal;'); cnt.contentEditable="true"; cnt.context="contentAreaContextMenu"; 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(); 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'; }; 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 = 40*i+'px'; cnt.style.width = 130*i+'px'; } else{ for(var i = 3; i < 10; i++){ if(cnt.scrollHeight > cnt.offsetHeight || cnt.scrollWidth > cnt.offsetWidth){ cnt.style.height = 40*i+'px'; cnt.style.width = 130*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); 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); 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 />")); 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:blue;font:17px Arian;">Google Translate</a>', '_gt', window.navigator.lastClick); } } catch (x){LOG(x)}; }; xhr.send('q=' + encodeURIComponent(txt)); } else { var urlt = gBrowser.currentURI.spec; var url = "http://translate.google.com/translate?u="+encodeURIComponent(urlt)+"&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 menuId = "context-ext-google-translate"; var menuItem = document.getElementById(menuId); if (menuItem) { contextMenu.removeChild(menuItem.nextElementSibling); contextMenu.removeChild(menuItem.nextElementSibling); contextMenu.removeChild(menuItem); }; menuItem = document.createXULElement("menuitem"); menuItem.setAttribute("id", menuId); 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("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);
addEventListener('keydown', function (e){ if(e.shiftKey && !e.ctrlKey && e.altKey && e.keyCode == 84)ujs_google_translate('auto|ru'); }, false);
Вставил его в конец кода "своей" кнопки — переводчик не вызывается. Подскажите пожалуйста как таки прикрутить горячие клавиши. 78 ESR
В процессе ковыряния оказалось что при клике по кнопке переводчик тоже не вызывается, похоже она заточена только под контекстное меню (txt = gContextMenu.selectionInfo.fullText).
___
И ещё вопрос: кнопка Go plus² focus для поздних версий переделывалась? Не нашёл в теме. Хотелось бы иметь такую для 78 версии.
Отредактировано Krtec (19-02-2022 01:44:38)
Отсутствует
нужен ЮзерАгент по-умолчанию, который вшит в Firefox
Нет такого. Он просто вычисляется из составляющих.
значение, когда опция, например "general.useragent.override" сброшена
Ну так если настройка есть, то читаем и сбрасываем.
Теперь получаем UA.
Затем возвращаем настройку, если была.
Добавьте пожалуйста в этот скрипт (p798193) такое же поведение при ЛКМ по активной вкладке, если возможно. 78.
(async ucf => { await delayedStartupPromise; var set = new Set([gBrowser.selectedTab]); var bt = gBrowser._blurTab; gBrowser._blurTab = tab => tab.selected && blur(tab); var blur = (tab, click) => { set.delete(tab); var res; for(var t of set) t.hidden || (res = t); click && set.add(tab); res ? gBrowser.selectedTab = res : bt.call(gBrowser, tab); } var skip, arr = [ ["TabClose", e => set.delete(e.target)], ["TabSelect", e => set.add(e.target, set.delete(e.target))], ["mousedown", e => skip = e.button || !e.target.matches( "tab[selected] :scope:not(.tab-close-button):not(.tab-icon-sound), tab[selected]" ), true], ["click", e => skip || e.ctrKey || e.shiftKey || e.altKey || e.detail != 1 || blur(e.target.closest("tab"), true) ] ]; var id, tc = gBrowser.tabContainer; for(var args of arr) tc.addEventListener(...args); ucf.unloadlisteners.push(id = Symbol()); ucf[id] = {destructor() { set.clear(); for(var args of arr) tc.removeEventListener(...args); }}; })(ucf_custom_script_win);
Хочу чтобы чекер был снят всегда (с кэша)....Как ?
Как-то так
addEventListener("dialogopen", e => { var win = e.detail.dialog.frameContentWindow; if (win.location == "chrome://browser/content/preferences/dialogs/clearSiteData.xhtml") { var checkbox = win.document.getElementById("clearCache"); checkbox.checked = false; checkbox.disabled = true; } }, false, gBrowser.tabpanels);
Отсутствует
Dumby
Или саму xhtml'ку править, она небольшая, чекбокс найти легко.
Да,так и сделал. Не знаю почему, но как на кэш нажмешь так око меняется commonDialogWindow или commonDialog
Добавлено 19-02-2022 11:20:27
momo2000
tabbrowser-tab.js там контекст запилили . Можно рихтануть и кнопка заработает
Отредактировано ВВП (19-02-2022 11:20:27)
Отсутствует
как на кэш нажмешь так око меняется commonDialogWindow или commonDialog
Попробовал. Заменил checked на xhecked
(просто потому, что в текстовом редакторе правил, в смысле сам весь app omni.ja как один файл).
И чекер, при появлении диалога, снятый.
И нажатие на него не приводит ни к чему необычному.
Отсутствует
Отсутствует
значит зелененький 97 будет - вот только скажи сейчас, что в 7х64 работать не будет?
Отредактировано ALEX_45_ORP (19-02-2022 14:06:58)
Win 10х64
Отсутствует
Семера, значит комп старый. Без SSE , будет, но не так.
лэптоп НР, конечно без SSE, главное чтоб работала, хоть и помедленней, ок, спс.
Отредактировано ALEX_45_ORP (19-02-2022 18:54:19)
Win 10х64
Отсутствует
Dumby
Не могу толком вставить предупреждение на СКМ ...Отражается на другие клики.(UndoClose)
this.onclick = function(e) { if(e.target != this) return; if(e.button == 1 || e.button == 0 && (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey)) this.undoCloseTabsList.clearAllLists(); else if( e.button == 0 || e.button == 2 && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey && this.undoCloseTabsList.options.rightClickToUndoCloseTab ) { if( e.button == 0 && !this.undoCloseTabsList.options.useMenu || e.button == 2 && this.undoCloseTabsList.options.rightClickToUndoCloseTab ) { if(this.undoCloseTabsList.closedTabCount) this.undoCloseTabsList.undoCloseTab(); else this.undoCloseTabsList.drawUndoList() && this.undoCloseTabsList.showMenu(e); } // Allow use "command" section only from hotkey: e.preventDefault(); e.stopPropagation(); } };
Отсутствует
Krtec пишет...такое же поведение при ЛКМ по активной вкладке
скрытый текстВыделить кодКод:
(async ucf => { await delayedStartupPromise; var set = new Set([gBrowser.selectedTab]); var bt = gBrowser._blurTab; gBrowser._blurTab = tab => tab.selected && blur(tab); var blur = (tab, click) => { set.delete(tab); var res; for(var t of set) t.hidden || (res = t); click && set.add(tab); res ? gBrowser.selectedTab = res : bt.call(gBrowser, tab); } var skip, arr = [ ["TabClose", e => set.delete(e.target)], ["TabSelect", e => set.add(e.target, set.delete(e.target))], ["mousedown", e => skip = e.button || !e.target.matches( "tab[selected] :scope:not(.tab-close-button):not(.tab-icon-sound), tab[selected]" ), true], ["click", e => skip || e.ctrKey || e.shiftKey || e.altKey || e.detail != 1 || blur(e.target.closest("tab"), true) ] ]; var id, tc = gBrowser.tabContainer; for(var args of arr) tc.addEventListener(...args); ucf.unloadlisteners.push(id = Symbol()); ucf[id] = {destructor() { set.clear(); for(var args of arr) tc.removeEventListener(...args); }}; })(ucf_custom_script_win);
Так переключение зацикливается между двумя вкладками, хотелось бы по типу перемещения по истории вкладки назад при нажимании кнопки со стрелочкой — страница с которой переключаешся не становится предыдущей, а остаётся следующей по отношению к той, на которую переключился. Очень надеюсь что сие возможно и на вашу помощь.
Отсутствует
Dumby - напомню вопрос в теме UCF - просьба упростить код перехват кликов, убрать LongPress,
он даёт задержку при нажатии кнопок, т.е. убрать задержку, переделать на системные click, dblclick, wheel…
Сделал отладочный скрипт, в нём только кнопка Загрузки + сообщения в консоли и строке статуса:
(async (id) => { // для custom_script_win.js: дополнительные клики и подсказки кнопок © Dumby var dsym = Symbol(), j = (...args) => args.join("\n"), tooltips = { [dsym]: j(GetDynamicShortcutTooltipText("downloads-button"), `\nДвойной клик: открыть [Загрузки]` ), get "downloads-button"() { var hint = this[dsym]; try {var dw = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dw = Services.dirsvc.get("DfltDwnld", Ci.nsIFile);} //отличается от ⇧ if (dw) hint += "\n\n[Загрузки] — выбранная папка:\n" + dw.path; return hint; } }; /* end tooltips */ var listener = { // дополнительные клики кнопок и перехват существующих filter(sel) { return this.closest(sel); }, find(sel) { return data[sel][this] || data[sel][this + 1]; }, handleEvent(e) { if (this.skip || e.detail > 2) return; var trg = e.target; var sels = this.selectors.filter(this.filter, trg); var {length} = sels; if (!length) return; var dbl = e.detail == 2; var wh = e.type.startsWith("w"); var num = e.metaKey *64 + e.ctrlKey *32 + e.shiftKey *16 + e.altKey *8 + (wh ? 2 : e.button *128 + dbl *4); var obj = data[ length > 1 && sels.find(this.find, num) || sels[0] ]; // wheel if (wh) 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 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](trg); } delete this.selectors; return this.selectors = Object.keys(data); }, 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 onMouseenter = e => { var trg = e.target; var hint = tooltips[trg.id] || tooltips[(trg = trg.parentNode).id]; if (hint) trg.tooltipText = hint; } var keydown_win = e => { // нажатие клавиш log(e.keyCode); } window.addEventListener("keydown", keydown_win); var toolbars = ["nav-bar", "ucf-additional-vertical-bar"].map(i => document.getElementById(i)); var events = ["click", "mousedown", "wheel"]; // appMenu-protonMainView toolbars[0].addEventListener("mouseenter", onMouseenter, true); for(var bar of toolbars) for(var type of events) bar.addEventListener(type, listener, true); ucf_custom_script_win.unloadlisteners.push(id); ucf_custom_script_win[id] = {destructor() { window.removeEventListener("keydown", keydown_win); toolbars[0].removeEventListener("mouseenter", onMouseenter, true); for(var bar of toolbars) for(var type of events) bar.removeEventListener(type, listener, true); }} addDestructor = nextDestructor => { var {destructor} = ucf_custom_script_win[id]; ucf_custom_script_win[id].destructor = () => { try {destructor();} catch(ex) {Cu.reportError(ex);} nextDestructor(); } }; // end Hooks prefs.setBoolPref("browser.download.autohideButton", false); // не скрывать кнопку Загрузки var {prefs, dirsvc} = Services, log = msg => Services.console.logStringMessage("[HC] "+ msg), // отладка showInStatusPanel = (info, time = 5000, StatusPanel = window.StatusPanel) => { if (StatusPanel.update.tid) clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update; StatusPanel.update(); } } StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, time); StatusPanel._label = info; log("[HC] "+ info); }, data = { "#downloads-button": { mousedownTarget: true, // + отправить текст в консоль 2(trg, forward) { showInStatusPanel("DW Wheel " + (forward ? "forward" : "backward")); }, 4() { showInStatusPanel("DW Double Left Click"); Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError); }, 16(btn) { showInStatusPanel("Shift + ЛКМ"); }, 128() { showInStatusPanel("СКМ Click"); }, 256() { showInStatusPanel("ПКМ Click"); }, 260(btn) { showInStatusPanel("Double ПКМ Click"); }, 264(btn) { showInStatusPanel("Alt + ПКМ"); }, }, }; // end Clicks, HotKeys ================================================== })("hookClicks-and-tooltips-test"); // END hookClicks
Отсутствует
Не могу толком вставить предупреждение на СКМ ...Отражается на другие клики.
Можно, например, так
… //this.undoCloseTabsList.clearAllLists(); Services.prompt.confirm(null, null, "???") && this.undoCloseTabsList.clearAllLists();
хотелось бы по типу перемещения по истории
Как-то это поперёк концепции.
Сомневаюсь, что такое мне в голову поместится.
Ладно, если просто пощёкать подряд чтоб отмотать, то можно, но если активировать вкладку
не таким образом (кликом по активной), то сброс, возвращение к цепочке основного трекера.
(async ucf => { await delayedStartupPromise; var set = new Set([gBrowser.selectedTab]); var bt = gBrowser._blurTab; gBrowser._blurTab = tab => tab.selected && blur(tab,/* flipset ||*/ set); var blur = (tab, s) => { s.delete(tab); var res; for(var t of s) t.hidden || (res = t); res ? gBrowser.selectedTab = res : bt.call(gBrowser, tab); } var re = /\nblur@[^\n]+?\n(?:[^\n]+?\/)?arr<@/; var skip, flipset, arr = [ ["TabClose", e => { set.delete(e.target); flipset?.delete(e.target); }], ["TabSelect", e => { set.delete(e.target); set.add(e.target); if (flipset && !re.test(Components.stack.formattedStack)) flipset = null; }], ["mousedown", e => skip = e.button || !e.target.matches( "tab[selected] :scope:not(.tab-close-button):not(.tab-icon-sound), tab[selected]" ), true], ["click", e => skip || e.ctrKey || e.shiftKey || e.altKey || e.detail != 1 || blur(e.target.closest("tab"), flipset || (flipset = new Set(set))) ] ]; var id, tc = gBrowser.tabContainer; for(var args of arr) tc.addEventListener(...args); ucf.unloadlisteners.push(id = Symbol()); ucf[id] = {destructor() { set = flipset = null; for(var args of arr) tc.removeEventListener(...args); }}; })(ucf_custom_script_win);
просьба упростить код перехват кликов, убрать LongPress,
он даёт задержку при нажатии кнопок, т.е. убрать задержку, переделать на системные click, dblclick, wheel…
Задержку при нажатии кнопок даёт не LongPress, а необходимость поддержки dblclick.
Нужно ведь подождать, что двойной клик случится (или не случится), правда же?
Отредактировано Dumby (22-02-2022 16:59:04)
Отсутствует
Dumby
Можно, например, так
Класс ! А можно туда же еще код , типа, так второй на отмену один черт срабатывает
{ Services.prompt.confirm(null, null, "Удалить список вкладок и сесий ?") && this.undoCloseTabsList.clearAllLists(); SessionStore.canRestoreLastSession = false;}
Отсутствует