>Форум Mozilla Россия http://forum.mozilla-russia.org/index.php >Сustom Buttons http://forum.mozilla-russia.org/viewforum.php?id=34 >[CB]Toggle Restartless Add-ons http://forum.mozilla-russia.org/viewtopic.php?id=57948 |
Infocatcher > 02-02-2013 23:45:23 |
Toggle Restartless Add-ons 0.1.2.2 (2016-04-10) Управление: Скриншот: Установить: Выделить код Код:custombutton://%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0D%0A%3Ccustombutton%20xmlns%3Acb%3D%22http%3A//xsms.nm.ru/custombuttons/%22%3E%0A%20%20%3Cname%3EToggle%20Restartless%20Add-ons%3C/name%3E%0A%20%20%3Cimage%3E%3C%21%5BCDATA%5Bchrome%3A//mozapps/skin/extensions/extensionGeneric-16.png%5D%5D%3E%3C/image%3E%0A%20%20%3Cmode%3E0%3C/mode%3E%0A%20%20%3Cinitcode%3E%3C%21%5BCDATA%5B//%20http%3A//infocatcher.ucoz.net/js/cb/toggleRestartlessAddons.js%0A//%20https%3A//forum.mozilla-russia.org/viewtopic.php%3Fid%3D57948%0A//%20https%3A//github.com/Infocatcher/Custom_Buttons/tree/master/Toggle_Restartless_Add-ons%0A%0A//%20Toggle%20Restartless%20Add-ons%20button%20for%20Custom%20Buttons%0A//%20%28code%20for%20%22initialization%22%20section%29%0A//%20Also%20the%20code%20can%20be%20used%20from%20main%20window%20context%20%28as%20Mouse%20Gestures%20code%2C%20for%20example%29%0A%0A//%20Also%20you%20can%20check%20for%20add-ons%20updates%20using%20right-click%3A%0A//%20copy%20all%20code%20from%0A//%20https%3A//github.com/Infocatcher/Custom_Buttons/blob/master/Check_for_Addons_Updates/checkForAddonsUpdates.js%0A//%20after%20%22//%3D%3D%20Check%20for%20Addons%20Updates%20begin%22%0A%0A//%20%28c%29%20Infocatcher%202013-2016%0A//%20version%200.1.2.2%20-%202016-04-10%0A%0Avar%20options%20%3D%20%7B%0A%09addonTypes%3A%20%5B%22extension%22%2C%20%22plugin%22%5D%2C%0A%09//%20Possible%20values%3A%20%22extension%22%2C%20%22plugin%22%0A%09//%20From%20extensions%3A%20%22userstyle%22%20%28Stylish%29%2C%20%22greasemonkey-user-script%22%20%28Greasemonkey%29%2C%20%22userscript%22%20%28Scriptish%29%0A%09//%20%28swap%20to%20reorder%20in%20the%20menu%29%0A%09showVersions%3A%200%2C%0A%09//%200%20-%20don%27t%20show%20versions%0A%09//%201%20-%20show%20after%20name%3A%20%22Addon%20Name%201.2%22%0A%09//%202%20-%20show%20as%20%22acceltext%22%20%28in%20place%20for%20hotkey%20text%29%0A%09sort%3A%20%7B%0A%09%09enabled%3A%20%20%20%20%200%2C%0A%09%09clickToPlay%3A%200%2C%0A%09%09disabled%3A%20%20%20%200%0A%09%09//%20Sort%20order%3A%0A%09%09//%200%2C%200%2C%200%20-%20sort%20add-ons%20of%20each%20type%20alphabetically%0A%09%09//%200%2C%200%2C%201%20-%20show%20enabled%20add-ons%20%28of%20each%20type%29%20first%0A%09%09//%200%2C%201%2C%202%20-%20enabled%20add-ons%2C%20then%20click-to-play%20and%20then%20disabled%0A%09%7D%2C%0A%09closeMenu%3A%20true%2C%0A%09//%20Close%20menu%20after%20left-click%20%28use%20Shift+click%20to%20invert%20this%20behavior%29%0A%09closeMenuClickToPlay%3A%20-1%0A%09//%20Special%20handling%20for%20click%20to%20play%20plugins%3A%0A%09//%20-1%20-%20invert%20Shift+click%20behavior%0A%09//%200%20%20-%20do%20nothing%20special%20%28and%20use%20%22closeMenu%22%20option%29%0A%09//%201%20%20-%20always%20don%27t%20close%20menu%0A%7D%3B%0A%0Avar%20mp%20%3D%20document.createElement%28%22menupopup%22%29%3B%0Amp.setAttribute%28%22onpopupshowing%22%2C%20%22this.updateMenu%28%29%3B%22%29%3B%0Amp.setAttribute%28%22oncommand%22%2C%20%22this.handleEvent%28event%29%3B%22%29%3B%0Amp.setAttribute%28%22onmousedown%22%2C%20%22if%28event.button%20%3D%3D%200%29%20this.handleEvent%28event%29%3B%22%29%3B%0Amp.setAttribute%28%22onclick%22%2C%20%22if%28event.button%20%3E%200%29%20this.handleEvent%28event%29%3B%22%29%3B%0Amp.setAttribute%28%22oncontextmenu%22%2C%20%22return%20false%3B%22%29%3B%0Amp.setAttribute%28%22onpopuphidden%22%2C%20%22this.destroyMenu%28%29%3B%22%29%3B%0A%0Avar%20tb%20%3D%20this.parentNode%3B%0Aif%28tb%20%26%26%20tb.getAttribute%28%22orient%22%29%20%3D%3D%20%22vertical%22%29%20%7B%0A%09//%20https%3A//addons.mozilla.org/firefox/addon/vertical-toolbar/%0A%09var%20isRight%20%3D%20tb.parentNode.getAttribute%28%22placement%22%29%20%3D%3D%20%22right%22%3B%0A%09mp.setAttribute%28%22position%22%2C%20isRight%20%3F%20%22start_before%22%20%3A%20%22end_before%22%29%3B%0A%7D%0A%0Avar%20cleanupTimer%20%3D%200%3B%0Amp.updateMenu%20%3D%20function%28%29%20%7B%0A%09clearTimeout%28cleanupTimer%29%3B%0A%09addStyle%28%29%3B%0A%09getRestartlessAddons%28options.addonTypes%2C%20function%28addons%29%20%7B%0A%09%09var%20df%20%3D%20document.createDocumentFragment%28%29%3B%0A%09%09var%20prevType%3B%0A%09%09function%20sortPosition%28addon%29%20%7B%0A%09%09%09if%28%22STATE_ASK_TO_ACTIVATE%22%20in%20AddonManager%20%26%26%20addon.userDisabled%20%3D%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%29%0A%09%09%09%09return%20options.sort.clickToPlay%3B%0A%09%09%09if%28addon.isActive%29%0A%09%09%09%09return%20options.sort.enabled%3B%0A%09%09%09return%20options.sort.disabled%3B%0A%09%09%7D%0A%09%09function%20key%28addon%29%20%7B%0A%09%09%09return%20options.addonTypes.indexOf%28addon.type%29%0A%09%09%09%09+%20%22%5Cn%22%20+%20sortPosition%28addon%29%0A%09%09%09%09+%20%22%5Cn%22%20+%20addon.name.toLowerCase%28%29%3B%0A%09%09%7D%0A%09%09addons.sort%28function%28a%2C%20b%29%20%7B%0A%09%09%09var%20ka%20%3D%20key%28a%29%3B%0A%09%09%09var%20kb%20%3D%20key%28b%29%3B%0A%09%09%09return%20ka%20%3D%3D%20kb%20%3F%200%20%3A%20ka%20%3C%20kb%20%3F%20-1%20%3A%201%3B%0A%09%09%7D%29.forEach%28function%28addon%29%20%7B%0A%09%09%09var%20type%20%3D%20addon.type%3B%0A%09%09%09if%28prevType%20%26%26%20type%20%21%3D%20prevType%29%0A%09%09%09%09df.appendChild%28document.createElement%28%22menuseparator%22%29%29%3B%0A%09%09%09prevType%20%3D%20type%3B%0A%09%09%09var%20icon%20%3D%20addon.iconURL%20%7C%7C%20addon.icon64URL%0A%09%09%09%09%7C%7C%20type%20%3D%3D%20%22plugin%22%20%20%20%20%26%26%20%22chrome%3A//mozapps/skin/plugins/pluginGeneric-16.png%22%0A%09%09%09%09%7C%7C%20type%20%3D%3D%20%22extension%22%20%26%26%20%22chrome%3A//mozapps/skin/extensions/extensionGeneric-16.png%22%0A%09%09%09%09%7C%7C%20%22%22%3B%0A%09%09%09var%20mi%20%3D%20document.createElement%28%22menuitem%22%29%3B%0A%09%09%09mi.className%20%3D%20%22menuitem-iconic%22%3B%0A%09%09%09var%20label%20%3D%20addon.name%3B%0A%09%09%09if%28options.showVersions%20%3D%3D%201%29%0A%09%09%09%09label%20+%3D%20%22%20%22%20+%20addon.version%3B%0A%09%09%09else%20if%28options.showVersions%20%3D%3D%202%29%0A%09%09%09%09mi.setAttribute%28%22acceltext%22%2C%20addon.version%29%3B%0A%09%09%09mi.setAttribute%28%22label%22%2C%20label%29%3B%0A%09%09%09mi.setAttribute%28%22image%22%2C%20icon%29%3B%0A%09%09%09var%20desc%20%3D%20addon.description%3B%0A%09%09%09desc%20%26%26%20mi.setAttribute%28%22tooltiptext%22%2C%20desc%29%3B%0A%09%09%09setDisabled%28mi%2C%20addon.userDisabled%29%3B%0A%09%09%09mi._cbAddon%20%3D%20addon%3B%0A%09%09%09df.appendChild%28mi%29%3B%0A%09%09%7D%29%3B%0A%09%09mp.textContent%20%3D%20%22%22%3B%0A%09%09mp.appendChild%28df%29%3B%0A%09%7D%29%3B%0A%7D%3B%0Amp.handleEvent%20%3D%20function%28e%29%20%7B%0A%09var%20mi%20%3D%20e.target%3B%0A%09if%28%21%28%22_cbAddon%22%20in%20mi%29%29%0A%09%09return%3B%0A%09var%20addon%20%3D%20mi._cbAddon%3B%0A%09if%28e.type%20%3D%3D%20%22mousedown%22%29%20%7B%0A%09%09var%20stayOpen%20%3D%20options.closeMenu%20%3F%20e.shiftKey%20%3A%20%21e.shiftKey%3B%0A%09%09if%28options.closeMenuClickToPlay%20%26%26%20isAskToActivateAddon%28addon%29%29%0A%09%09%09stayOpen%20%3D%20options.closeMenuClickToPlay%20%3D%3D%20-1%20%3F%20%21stayOpen%20%3A%20true%3B%0A%09%09mi.setAttribute%28%22closemenu%22%2C%20stayOpen%20%3F%20%22none%22%20%3A%20%22auto%22%29%3B%0A%09%09return%3B%0A%09%7D%0A%09var%20hasMdf%20%3D%20hasModifier%28e%29%3B%0A%09if%28e.type%20%3D%3D%20%22command%22%20%26%26%20%28%21hasMdf%20%7C%7C%20e.shiftKey%29%29%20%7B%0A%09%09let%20newDis%20%3D%20setNewDisabled%28addon%29%3B%0A%09%09setDisabled%28mi%2C%20newDis%29%3B%0A%09%7D%0A%09else%20if%28e.type%20%3D%3D%20%22command%22%20%26%26%20hasMdf%20%7C%7C%20e.type%20%3D%3D%20%22click%22%20%26%26%20e.button%20%3D%3D%201%29%20%7B%0A%09%09openAddonPage%28addon%29%3B%0A%09%09closeMenus%28mi%29%3B%0A%09%7D%0A%09else%20if%28e.type%20%3D%3D%20%22click%22%20%26%26%20e.button%20%3D%3D%202%29%20%7B%0A%09%09if%28openAddonOptions%28addon%29%29%0A%09%09%09closeMenus%28mi%29%3B%0A%09%7D%0A%7D%3B%0Amp.destroyMenu%20%3D%20function%28%29%20%7B%0A%09removeStyle%28%29%3B%0A%09clearTimeout%28cleanupTimer%29%3B%0A%09cleanupTimer%20%3D%20setTimeout%28function%28%29%20%7B%0A%09%09mp.textContent%20%3D%20%22%22%3B%0A%09%7D%2C%205000%29%3B%0A%7D%3B%0Afunction%20isAskToActivateAddon%28addon%29%20%7B%0A%09return%20addon.type%20%3D%3D%20%22plugin%22%0A%09%09%26%26%20%22STATE_ASK_TO_ACTIVATE%22%20in%20AddonManager%0A%09%09%26%26%20Services.prefs.getBoolPref%28%22plugins.click_to_play%22%29%3B%0A%7D%0Afunction%20setNewDisabled%28addon%29%20%7B%0A%09var%20newDis%20%3D%20getNewDisabled%28addon%29%3B%0A%09var%20oldDis%20%3D%20addon.userDisabled%3B%0A%09addon.userDisabled%20%3D%20newDis%3B%0A%09var%20realDis%20%3D%20addon.userDisabled%3B%0A%09if%28realDis%20%21%3D%20newDis%29%20%7B%20//%20We%20can%27t%20enable%20vulnerable%20plugins%0A%09%09var%20err%20%3D%20%22Can%27t%20set%20addon.userDisabled%20to%20%22%20+%20newDis%20+%20%22%2C%20real%20value%3A%20%22%20+%20realDis%3B%0A%09%09if%28newDis%29%20%7B%0A%09%09%09LOG%28err%20+%20%22%5CnSTATE_ASK_TO_ACTIVATE%20not%20supported%3F%22%29%3B%0A%09%09%09newDis%20%3D%20false%3B%0A%09%09%7D%0A%09%09else%20%7B%0A%09%09%09LOG%28err%20+%20%22%5CnVulnerable%20plugin%3F%22%29%3B%0A%09%09%09if%28oldDis%20%3D%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%29%0A%09%09%09%09newDis%20%3D%20true%3B%0A%09%09%09else%0A%09%09%09%09newDis%20%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%3B%0A%09%09%7D%0A%09%09addon.userDisabled%20%3D%20newDis%3B%0A%09%7D%0A%09return%20addon.userDisabled%3B%0A%7D%0Afunction%20getNewDisabled%28addon%29%20%7B%0A%09//%20disabled%20-%3E%20STATE_ASK_TO_ACTIVATE%20-%3E%20enabled%20-%3E%20...%0A%09var%20curDis%20%3D%20addon.userDisabled%3B%0A%09var%20newDis%3B%0A%09if%28%22STATE_ASK_TO_ACTIVATE%22%20in%20AddonManager%20%26%26%20curDis%20%3D%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%29%0A%09%09newDis%20%3D%20false%3B%0A%09else%20if%28%21curDis%29%0A%09%09newDis%20%3D%20true%3B%0A%09else%20%7B%0A%09%09if%28isAskToActivateAddon%28addon%29%29%0A%09%09%09newDis%20%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%3B%0A%09%09else%0A%09%09%09newDis%20%3D%20false%3B%0A%09%7D%0A%09return%20newDis%3B%0A%7D%0Afunction%20setDisabled%28mi%2C%20disabled%29%20%7B%0A%09var%20askToActivate%20%3D%20%22STATE_ASK_TO_ACTIVATE%22%20in%20AddonManager%20%26%26%20disabled%20%3D%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%3B%0A%09var%20cl%20%3D%20mi.classList%3B%0A%09cl.toggle%28%22toggleRestartlessAddons-askToActivate%22%2C%20askToActivate%29%3B%0A%09cl.toggle%28%22toggleRestartlessAddons-disabled%22%2C%20disabled%20%26%26%20%21askToActivate%29%3B%0A%7D%0A%0Aif%28%0A%09this%20instanceof%20XULElement%20//%20Custom%20Buttons%0A%09%26%26%20typeof%20event%20%3D%3D%20%22object%22%0A%09%26%26%20%21%28%22type%22%20in%20event%29%20%26%26%20typeof%20_phase%20%3D%3D%20%22string%22%20%26%26%20_phase%20%3D%3D%20%22init%22%20//%20Initialization%0A%29%20%7B%0A%09this.type%20%3D%20%22menu%22%3B%0A%09this.orient%20%3D%20%22horizontal%22%3B%0A%09this.appendChild%28mp%29%3B%0A%0A%09this.onmouseover%20%3D%20function%28e%29%20%7B%0A%09%09if%28e.target%20%21%3D%20this%29%0A%09%09%09return%3B%0A%09%09Array.some%28%0A%09%09%09this.parentNode.getElementsByTagName%28%22*%22%29%2C%0A%09%09%09function%28node%29%20%7B%0A%09%09%09%09if%28%0A%09%09%09%09%09node%20%21%3D%20this%0A%09%09%09%09%09%26%26%20node.namespaceURI%20%3D%3D%20xulns%0A%09%09%09%09%09%26%26%20node.boxObject%0A%09%09%09%09%09//%20See%20https%3A//github.com/Infocatcher/Custom_Buttons/issues/28%0A%09%09%09%09%09//%26%26%20node.boxObject%20instanceof%20Components.interfaces.nsIMenuBoxObject%0A%09%09%09%09%09%26%26%20%22open%22%20in%20node%0A%09%09%09%09%09%26%26%20node.open%0A%09%09%09%09%09%26%26%20node.getElementsByTagName%28%22menupopup%22%29.length%0A%09%09%09%09%29%20%7B%0A%09%09%09%09%09node.open%20%3D%20false%3B%0A%09%09%09%09%09this.open%20%3D%20true%3B%0A%09%09%09%09%09return%20true%3B%0A%09%09%09%09%7D%0A%09%09%09%09return%20false%3B%0A%09%09%09%7D%2C%0A%09%09%09this%0A%09%09%29%3B%0A%09%7D%3B%0A%09this.onmousedown%20%3D%20function%28e%29%20%7B%0A%09%09if%28e.target%20%3D%3D%20this%20%26%26%20e.button%20%3D%3D%200%20%26%26%20hasModifier%28e%29%29%0A%09%09%09e.preventDefault%28%29%3B%0A%09%7D%3B%0A%09this.oncontextmenu%20%3D%20function%28e%29%20%7B%0A%09%09if%28e.target%20%3D%3D%20this%20%26%26%20%21hasModifier%28e%29%20%26%26%20hasUpdater%28%29%29%0A%09%09%09e.preventDefault%28%29%3B%0A%09%7D%3B%0A%09this.onclick%20%3D%20function%28e%29%20%7B%0A%09%09if%28e.target%20%21%3D%20this%29%0A%09%09%09return%3B%0A%09%09if%28e.button%20%3D%3D%200%20%26%26%20hasModifier%28e%29%20%7C%7C%20e.button%20%3D%3D%201%29%0A%09%09%09openAddonsManager%28%29%3B%0A%09%09else%20if%28e.button%20%3D%3D%202%20%26%26%20%21hasModifier%28e%29%20%26%26%20hasUpdater%28%29%29%0A%09%09%09checkForAddonsUpdates.call%28this%29%3B%0A%09%7D%3B%0A%7D%0Aelse%20%7B%20//%20Mouse%20gestures%20or%20something%20other...%0A%09let%20e%3B%0A%09if%28typeof%20event%20%3D%3D%20%22object%22%20%26%26%20event%20instanceof%20Event%20%26%26%20%22screenX%22%20in%20event%29%20//%20FireGestures%0A%09%09e%20%3D%20event%3B%0A%09else%20if%28this%20%3D%3D%20window%20%26%26%20%22mgGestureState%22%20in%20window%20%26%26%20%22endEvent%22%20in%20mgGestureState%29%20//%20Mouse%20Gestures%20Redox%0A%09%09e%20%3D%20mgGestureState.endEvent%3B%0A%09else%20%7B%0A%09%09let%20anchor%20%3D%20this%20instanceof%20XULElement%20%26%26%20this%0A%09%09%09%7C%7C%20window.gBrowser%20%26%26%20gBrowser.selectedBrowser%0A%09%09%09%7C%7C%20document.documentElement%3B%0A%09%09if%28%22boxObject%22%20in%20anchor%29%20%7B%0A%09%09%09let%20bo%20%3D%20anchor.boxObject%3B%0A%09%09%09e%20%3D%20%7B%0A%09%09%09%09screenX%3A%20bo.screenX%2C%0A%09%09%09%09screenY%3A%20bo.screenY%0A%09%09%09%7D%3B%0A%09%09%09if%28this%20instanceof%20XULElement%29%0A%09%09%09%09e.screenY%20+%3D%20bo.height%3B%0A%09%09%7D%0A%09%7D%0A%09if%28%21e%20%7C%7C%20%21%28%22screenX%22%20in%20e%29%29%0A%09%09throw%20new%20Error%28%22%5BToggle%20Restartless%20Add-ons%5D%3A%20Can%27t%20get%20event%20object%22%29%3B%0A%09document.documentElement.appendChild%28mp%29%3B%0A%09mp.addEventListener%28%22popuphidden%22%2C%20function%20destroy%28e%29%20%7B%0A%09%09mp.removeEventListener%28e.type%2C%20destroy%2C%20false%29%3B%0A%09%09setTimeout%28function%28%29%20%7B%0A%09%09%09mp.destroyMenu%28%29%3B%0A%09%09%09mp.parentNode.removeChild%28mp%29%3B%0A%09%09%7D%2C%200%29%3B%0A%09%7D%2C%20false%29%3B%0A%09mp.openPopupAtScreen%28e.screenX%2C%20e.screenY%29%3B%0A%7D%0A%0Afunction%20getRestartlessAddons%28addonTypes%2C%20callback%2C%20context%29%20%7B%0A%09if%28%21%28%22AddonManager%22%20in%20window%29%29%0A%09%09Components.utils.import%28%22resource%3A//gre/modules/AddonManager.jsm%22%29%3B%0A%09AddonManager.getAddonsByTypes%28addonTypes%2C%20function%28addons%29%20%7B%0A%09%09var%20restartless%20%3D%20addons.filter%28function%28addon%29%20%7B%0A%09%09%09var%20ops%20%3D%20addon.operationsRequiringRestart%3B%0A%09%09%09return%20%21addon.appDisabled%0A%09%09%09%09%26%26%20%21%28ops%20%26%20AddonManager.OP_NEEDS_RESTART_ENABLE%20%7C%7C%20ops%20%26%20AddonManager.OP_NEEDS_RESTART_DISABLE%29%3B%0A%09%09%7D%29%3B%0A%09%09callback.call%28context%2C%20restartless%29%3B%0A%09%7D%29%3B%0A%7D%0Afunction%20openAddonOptions%28addon%29%20%7B%0A%09//%20Based%20on%20code%20from%20chrome%3A//mozapps/content/extensions/extensions.js%0A%09//%20Firefox%2021.0a1%20%282013-01-27%29%0A%09Components.utils.import%28%22resource%3A//gre/modules/Services.jsm%22%29%3B%0A%09var%20optionsURL%20%3D%20addon.optionsURL%3B%0A%09if%28%21addon.isActive%20%7C%7C%20%21optionsURL%29%0A%09%09return%20false%3B%0A%09if%28addon.type%20%3D%3D%20%22plugin%22%29%20//%20No%20options%20for%20now%21%0A%09%09return%20false%3B%0A%09if%28addon.optionsType%20%3D%3D%20AddonManager.OPTIONS_TYPE_INLINE%29%0A%09%09openAddonPage%28addon%2C%20true%29%3B%0A%09else%20if%28addon.optionsType%20%3D%3D%20AddonManager.OPTIONS_TYPE_TAB%20%26%26%20%22switchToTabHavingURI%22%20in%20window%29%0A%09%09switchToTabHavingURI%28optionsURL%2C%20true%29%3B%0A%09else%20%7B%0A%09%09let%20windows%20%3D%20Services.wm.getEnumerator%28null%29%3B%0A%09%09while%28windows.hasMoreElements%28%29%29%20%7B%0A%09%09%09let%20win%20%3D%20windows.getNext%28%29%3B%0A%09%09%09if%28win.document.documentURI%20%3D%3D%20optionsURL%29%20%7B%0A%09%09%09%09win.focus%28%29%3B%0A%09%09%09%09return%20true%3B%0A%09%09%09%7D%0A%09%09%7D%0A%09%09//%20Note%3A%20original%20code%20checks%20browser.preferences.instantApply%20and%20may%20open%20modal%20windows%0A%09%09window.openDialog%28optionsURL%2C%20%22%22%2C%20%22chrome%2Ctitlebar%2Ctoolbar%2Ccenterscreen%2Cdialog%3Dno%22%29%3B%0A%09%7D%0A%09return%20true%3B%0A%7D%0Afunction%20openAddonsManager%28view%29%20%7B%0A%09var%20openAddonsMgr%20%3D%20window.BrowserOpenAddonsMgr%20//%20Firefox%0A%09%09%7C%7C%20window.openAddonsMgr%20//%20Thunderbird%0A%09%09%7C%7C%20window.toEM%3B%20//%20SeaMonkey%0A%09openAddonsMgr%28view%29%3B%0A%7D%0Afunction%20openAddonPage%28addon%2C%20scrollToPreferences%29%20%7B%0A%09scrollToPreferences%20%3D%20scrollToPreferences%20%26%26%20parseFloat%28Services.appinfo.platformVersion%29%20%3E%3D%2012%0A%09%09%3F%20%22/preferences%22%0A%09%09%3A%20%22%22%3B%0A%09openAddonsManager%28%22addons%3A//detail/%22%20+%20encodeURIComponent%28addon.id%29%20+%20scrollToPreferences%29%3B%0A%7D%0A%0Afunction%20hasModifier%28e%29%20%7B%0A%09return%20e.ctrlKey%20%7C%7C%20e.shiftKey%20%7C%7C%20e.altKey%20%7C%7C%20e.metaKey%3B%0A%7D%0A%0Afunction%20addStyle%28%29%20%7B%0A%09if%28addStyle.hasOwnProperty%28%22_style%22%29%29%0A%09%09return%3B%0A%09var%20style%20%3D%20%27%5C%0A%09%09.toggleRestartlessAddons-disabled%20%3E%20.menu-iconic-left%20%7B%5Cn%5C%0A%09%09%09opacity%3A%200.4%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%09.toggleRestartlessAddons-disabled%20%3E%20.menu-iconic-text%2C%5Cn%5C%0A%09%09.toggleRestartlessAddons-disabled%20%3E%20.menu-accel-container%20%7B%5Cn%5C%0A%09%09%09opacity%3A%200.5%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%09.toggleRestartlessAddons-askToActivate%20%7B%5Cn%5C%0A%09%09%09color%3A%20-moz-nativehyperlinktext%3B%5Cn%5C%0A%09%09%7D%27%3B%0A%09addStyle._style%20%3D%20document.insertBefore%28%0A%09%09document.createProcessingInstruction%28%0A%09%09%09%22xml-stylesheet%22%2C%0A%09%09%09%27href%3D%22%27%20+%20%22data%3Atext/css%2C%22%0A%09%09%09%09+%20encodeURIComponent%28style%29%20+%20%27%22%20type%3D%22text/css%22%27%0A%09%09%29%2C%0A%09%09document.documentElement%0A%09%29%3B%0A%7D%0Afunction%20removeStyle%28%29%20%7B%0A%09if%28%21addStyle.hasOwnProperty%28%22_style%22%29%29%0A%09%09return%3B%0A%09var%20s%20%3D%20addStyle._style%3B%0A%09s.parentNode.removeChild%28s%29%3B%0A%09delete%20addStyle._style%3B%0A%7D%0Afunction%20closeMenus%28node%29%20%7B%0A%09//%20Based%20on%20function%20closeMenus%20from%20chrome%3A//browser/content/utilityOverlay.js%0A%09for%28%3B%20node%20%26%26%20%22tagName%22%20in%20node%3B%20node%20%3D%20node.parentNode%29%20%7B%0A%09%09if%28%0A%09%09%09node.namespaceURI%20%3D%3D%20%22http%3A//www.mozilla.org/keymaster/gatekeeper/there.is.only.xul%22%0A%09%09%09%26%26%20%28node.localName%20%3D%3D%20%22menupopup%22%20%7C%7C%20node.localName%20%3D%3D%20%22popup%22%29%0A%09%09%29%0A%09%09%09node.hidePopup%28%29%3B%0A%09%7D%0A%7D%0A%0Afunction%20hasUpdater%28%29%20%7B%0A%09var%20has%20%3D%20checkForAddonsUpdates.toString%28%29.indexOf%28%22Services.jsm%22%29%20%21%3D%20-1%3B%0A%09hasUpdater%20%3D%20function%28%29%20%7B%0A%09%09return%20has%3B%0A%09%7D%3B%0A%09return%20has%3B%0A%7D%0Afunction%20checkForAddonsUpdates%28%29%20%7B%0A//%3D%3D%20Check%20for%20Addons%20Updates%20begin%0A%0A//%3D%3D%20Check%20for%20Addons%20Updates%20end%0A%7D%5D%5D%3E%3C/initcode%3E%0A%20%20%3Ccode%3E%3C%21%5BCDATA%5Bif%28%21event.target%29%20//%20Button%27s%20hotkey%20pressed%0A%09this.open%20%3D%20true%3B%5D%5D%3E%3C/code%3E%0A%20%20%3Caccelkey%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/accelkey%3E%0A%20%20%3Chelp%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/help%3E%0A%20%20%3Cattributes/%3E%0A%3C/custombutton%3E
Также код можно использовать из других расширений, позволяющих выполнять произвольный код в контексте главного окна приложения, например, из Mouse Gestures. |
Infocatcher > 03-02-2013 00:18:23 |
Тестовая версия, будьте осторожны! |
iDev.Pi > 03-02-2013 21:18:25 |
feature requests: |
Infocatcher > 04-02-2013 00:43:34 |
iDev.Pi пишет
Это можно. iDev.Pi пишет
Мне как-то не очень нравится заменять контекстное меню действием. |
iDev.Pi > 04-02-2013 01:12:13 |
Infocatcher пишет
А я вот наоборот, хочу поменьше кнопок на панели иметь Infocatcher пишет
Это можно обойти так: 04-02-2013 01:16:36 |
Infocatcher > 04-02-2013 01:16:58 |
Infocatcher пишет
И синхронизировать изменения тоже не очень-то удобно. И забыть можно. iDev.Pi пишет
А из меню и так можно открыть управление дополнениями, только для конкретного дополнения, но там уже всего один клик до обычного управления пополнениями. |
Infocatcher > 04-02-2013 02:15:04 |
iDev.Pi пишет
Я про это думал. По-моему, так искать проще, когда по алфавиту. |
Infocatcher > 16-02-2013 21:45:27 |
Toggle Restartless Add-ons 0.1.1 (2013-02-04) |
Infocatcher > 02-10-2013 22:15:56 |
Toggle Restartless Add-ons 0.1.2 (2013-10-02) |
Infocatcher > 21-02-2014 01:14:34 |
Toggle Restartless Add-ons 0.1.2.1 (2014-02-21) |
difabor > 21-02-2014 09:55:44 |
1. Есть ли возможность вызова настроек для аддонов, у которых есть настройки? |
Infocatcher > 21-02-2014 11:29:33 |
difabor пишет
Из описания:
difabor пишет
На данный момент – только правкой исходного кода. Например, так (надо заменить соответствующую функцию в коде): Выделить код Код:function getRestartlessAddons(addonTypes, callback, context) { if(!("AddonManager" in window)) Components.utils.import("resource://gre/modules/AddonManager.jsm"); var excludeIds = [ "{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}", // Adblock Plus "elemhidehelper@adblockplus.org" ]; var excludeNames = [ "Shockwave Flash" ]; AddonManager.getAddonsByTypes(addonTypes, function(addons) { var restartless = addons.filter(function(addon) { var ops = addon.operationsRequiringRestart; return !addon.appDisabled && excludeIds.indexOf(addon.id) == -1 && excludeNames.indexOf(addon.name) == -1 && !(ops & AddonManager.OP_NEEDS_RESTART_ENABLE || ops & AddonManager.OP_NEEDS_RESTART_DISABLE); }); callback.call(context, restartless); }); } difabor пишет
Extension Options Menu? |
difabor > 21-02-2014 12:38:09 |
1. Спасибо за разъяснение и извините, что сам не разобрался с описанием. |
Xant1k > 20-01-2016 14:24:55 |
del |
Infocatcher > 20-01-2016 14:58:00 |
Xant1k Если очень хочется, можно закомментировать в коде проверку: Выделить код Код:function getRestartlessAddons(addonTypes, callback, context) { if(!("AddonManager" in window)) Components.utils.import("resource://gre/modules/AddonManager.jsm"); AddonManager.getAddonsByTypes(addonTypes, function(addons) { var restartless = addons.filter(function(addon) { var ops = addon.operationsRequiringRestart; return !addon.appDisabled //&& !(ops & AddonManager.OP_NEEDS_RESTART_ENABLE || ops & AddonManager.OP_NEEDS_RESTART_DISABLE); }); callback.call(context, restartless); }); } |
oleg.sgh > 20-01-2016 16:27:43 |
Можно исключить из меню все плагины? Их названия вытягивают меню на 2\3 экрана...да и не особо нужно. |
Infocatcher > 20-01-2016 20:13:12 |
oleg.sgh |
oleg.sgh > 20-01-2016 20:25:31 |
Infocatcher |
difabor > 20-01-2016 23:14:27 |
Уважаемый Infocatcher, Выделить код Код:// Создать двухсекционное меню ...................... var popup = addElement("menupopup", { position: "after_start", oncontextmenu: "return false", style: "-moz-appearance: none; border: 1px solid" }, self); var mainBox = addElement("hbox", {}, popup); var leftBox = addElement("vbox", {style: "background-color: rgb(255,255,0);"}, mainBox); // Левое меню var rightBox = addElement("vbox", { // Правое меню style: "background-color: rgb(255,0,0); box-shadow: 1px 0px 2px rgb(204, 214, 234) inset;" // стиль правого меню 241, 245, 251 }, mainBox); Можно задать счётчик менюитемов и каждый менюитем с №М%К равным 0 помещать в первую колонку, №М%К равным 1 помещать во вторую колонку, и т.д. Выделить код Код:function getRestartlessAddons(addonTypes, callback, context) { if(!("AddonManager" in window)) Components.utils.import("resource://gre/modules/AddonManager.jsm"); var excludeIds = [ "{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}", // Adblock Plus "elemhidehelper@adblockplus.org" ]; var excludeNames = [ "Shockwave Flash" ]; AddonManager.getAddonsByTypes(addonTypes, function(addons) { var restartless = addons.filter(function(addon) { var ops = addon.operationsRequiringRestart; return !addon.appDisabled && excludeIds.indexOf(addon.id) == -1 && excludeNames.indexOf(addon.name) == -1 && !(ops & AddonManager.OP_NEEDS_RESTART_ENABLE || ops & AddonManager.OP_NEEDS_RESTART_DISABLE); }); callback.call(context, restartless); }); } В принципе, если в about:config хранить список таких исключений, то их можно исключать по такому списку. |
Xant1k > 21-01-2016 15:26:15 |
del |
Infocatcher > 22-01-2016 10:04:36 |
difabor пишет
Можно, что-то такое будет: Выделить код Код:<hbox> <vbox> <menuitem label="1" /> <menuitem label="2" /> </vbox> <vbox> <menuitem label="3" /> <menuitem label="4" /> </vbox> <vbox>...</vbox> ... </hbox> Только, скорее всего, не будет работать навигация по меню с клавиатуры. difabor пишет
Это просто, надо искать в коде создание пунктов меню, по "menuitem" находится одно такое место. Выделить код Код:mp.updateMenu = function() { ... getRestartlessAddons(options.addonTypes, function(addons) { // Получение списка дополнений // Создание "буфера" для небольшого увеличения производительности // https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment var df = document.createDocumentFragment(); ... // Тут можно объявить какие-нибудь счетчики addons.sort(function(a, b) { // Сортировка списка дополнений var ka = key(a); var kb = key(b); return ka == kb ? 0 : ka < kb ? -1 : 1; }).forEach(function(addon) { // Перебор всех элементов списка ... var mi = document.createElement("menuitem"); // Создается новый пункт меню ... df.appendChild(mi); // Созданный пункт меню добавляется в "буфер" }); mp.textContent = ""; // Очистка меню mp.appendChild(df); // Меню заполняется содержимым "буфера" difabor пишет
Можно, что-то такое: Выделить код Код:var excludeIds = getRestartlessAddons._excludeIds || ( getRestartlessAddons._excludeIds = Services.prefs.getCharPref("extensions.custombuttons.button.toggleRestartlessAddons.excludeIds") .split("|") ); var excludeNames = getRestartlessAddons._excludeNames || ( getRestartlessAddons._excludeNames = Services.prefs.getCharPref("extensions.custombuttons.button.toggleRestartlessAddons.excludeNames") .split("|") ); Только Services.prefs.getCharPref() не понимает юникод и выпадет с ошибкой, если настройка не существует. (на остальное попозже отвечу) |
Infocatcher > 27-01-2016 11:16:29 |
difabor пишет
Это все реализуемо, просто тогда уж интуитивнее сделать контекстное меню. difabor пишет
Ну, если есть желание писать свой велосипед для жестов... difabor пишет
Тут на самом деле сложнее всего сделать интерфейс настроек. Вот упрощенный пример с вложенным меню. Только там если скрыть все дополнения одного типа, неправильно выведет разделитель. Выделить код Код:--- toggleRestartlessAddons.js +++ toggleRestartlessAddons_submenu.js @@ -42,7 +42,7 @@ }; var mp = document.createElement("menupopup"); -mp.setAttribute("onpopupshowing", "this.updateMenu();"); +mp.setAttribute("onpopupshowing", "if(event.target == this) this.updateMenu();"); mp.setAttribute("oncommand", "this.handleEvent(event);"); mp.setAttribute("onmousedown", "if(event.button == 0) this.handleEvent(event);"); mp.setAttribute("onclick", "if(event.button > 0) this.handleEvent(event);"); @@ -75,6 +75,20 @@ + "\n" + sortPosition(addon) + "\n" + addon.name.toLowerCase(); } + var collapseNames = [ + "Adblock Plus" + ]; + var menu; + function more(mi) { + menu = document.createElement("menu"); + menu.setAttribute("label", "More…"); + var mp = document.createElement("menupopup"); + menu.appendChild(mp); + more = function(mi) { + mp.appendChild(mi); + }; + more(mi); + } addons.sort(function(a, b) { var ka = key(a); var kb = key(b); @@ -101,8 +115,13 @@ desc && mi.setAttribute("tooltiptext", desc); setDisabled(mi, addon.userDisabled); mi._cbAddon = addon; - df.appendChild(mi); + if(collapseNames.indexOf(addon.name) != -1) + more(mi); + else + df.appendChild(mi); }); + if(menu) + df.appendChild(menu); mp.textContent = ""; mp.appendChild(df); }); difabor пишет
Я не вполне уверен, что получится найти такое количество полезных расширений, чтобы эти все доработки оказались оправданы. |
difabor > 27-01-2016 21:57:04 |
Infocatcher пишет
Спасибо большое! Буду "переваривать". Выделить код Код:--- toggleRestartlessAddons.js +++ toggleRestartlessAddons_submenu.js @@ -42,7 +42,7 @@ ... и т.д. 2.Я совсем не понял нотацию в приведённом Вами коде: Infocatcher пишет
Где этот код писать? |
Infocatcher > 28-01-2016 00:07:28 |
difabor пишет
Это diff, да. difabor пишет
Это не совсем код, это результат (можно наглядно увидеть в DOM Inspector'е). label="1" и прочее – просто для примера, это название пункта меню. |
difabor > 28-01-2016 01:48:11 |
Спасибо! Понял Извините за тупость! Выделить код Код:function addStyle() { if(addStyle.hasOwnProperty("_style")) return; var style = '\ .toggleRestartlessAddons-disabled > .menu-iconic-left {\n\ opacity: 0.4;\n\ }\n\ .toggleRestartlessAddons-disabled > .menu-iconic-text,\n\ .toggleRestartlessAddons-disabled > .menu-accel-container {\n\ opacity: 0.5;\n\ }\n\ .toggleRestartlessAddons-askToActivate {\n\ color: -moz-nativehyperlinktext;\n\ }'; addStyle._style = document.insertBefore( document.createProcessingInstruction( "xml-stylesheet", 'href="' + "data:text/css," + encodeURIComponent(style) + '" type="text/css"' ), document.documentElement ); } |
Infocatcher > 28-01-2016 16:48:45 |
difabor пишет
Надо внести правки в Выделить код Код:function sortPosition(addon) { if("STATE_ASK_TO_ACTIVATE" in AddonManager && addon.userDisabled == AddonManager.STATE_ASK_TO_ACTIVATE) return options.sort.clickToPlay; if(addon.isActive) return options.sort.enabled; return options.sort.disabled; } function key(addon) { return options.addonTypes.indexOf(addon.type) + "\n" + sortPosition(addon) + "\n" + addon.name.toLowerCase(); } addons.sort(function(a, b) { // Вот тут собственно сортировка, остальное – вспомогательные функции var ka = key(a); var kb = key(b); return ka == kb ? 0 : ka < kb ? -1 : 1; }) Только там специальные штуки, чтобы работал настроечный объект и группировка по типам. Выделить код Код:function sortPosition(addon) { if("STATE_ASK_TO_ACTIVATE" in AddonManager && addon.userDisabled == AddonManager.STATE_ASK_TO_ACTIVATE) return options.sort.clickToPlay; if(addon.isActive) return options.sort.enabled; return options.sort.disabled; } на что-нибудь вроде Выделить код Код:function sortPosition(addon) { var time = new Date(addon.updateDate).getTime() || 0; return "0".repeat(13 - String(time).length) + time; } difabor пишет
Не совсем. Потом можно и туда, но сначала нужно добавить какие-нибудь отличительные признаки, за которые можно стилями цепляться. В простейшем случае надо к уже имеющемуся дописать Выделить код Код:mi.setAttribute("label", label); mi.setAttribute("image", icon); // Для дополнительной подсветки if(addon.optionsURL) mi.style.fontWeight = "bold"; var ops = addon.operationsRequiringRestart; if(!(ops & AddonManager.OP_NEEDS_RESTART_ENABLE || ops & AddonManager.OP_NEEDS_RESTART_DISABLE)) mi.style.fontStyle = "italic"; |
difabor > 28-01-2016 17:19:59 |
Спасибо большое! |
Infocatcher > 29-01-2016 12:55:19 |
difabor пишет
Там все проще сделано: список обновляется при каждом открытии (пересоздается заново). Выделить код Код:mp.setAttribute("onpopupshowing", "this.updateMenu();"); ... mp.updateMenu = function() { ... }; Все равно отслеживать что-то пока меню закрыто нет смысла (да и вредно для производительности. |
difabor > 30-01-2016 00:29:24 |
Infocatcher пишет
Спасибо! |
Infocatcher > 30-01-2016 22:03:48 |
difabor , как и при построении меню. |
difabor > 31-01-2016 03:23:21 |
Infocatcher пишет
Информация насчёт наличия настроек пропадает и в about:addons и это имхо правильно - нельзя вызывать настройки отключённого аддона и не надо даже провоцировать на это. Infocatcher пишет
В данном конкретном случае имхо нет такой необходимости, но знать как в эту же функцию перенести дополнительный код для раскрашивания и передать в нее ссылку на addon было бы очень желательно. |
Infocatcher > 31-01-2016 17:15:49 |
difabor пишет
Примерно так (там в двух местах вызывается setDisabled() + лучше переименовать для соответствия): -> -> И саму функцию: -> Выделить код Код:function highlightFeatures(mi, addon, disabled) { // Для дополнительной подсветки if(addon.optionsURL) mi.style.fontWeight = "bold"; var ops = addon.operationsRequiringRestart; if(!(ops & AddonManager.OP_NEEDS_RESTART_ENABLE || ops & AddonManager.OP_NEEDS_RESTART_DISABLE)) mi.style.fontStyle = "italic"; ... |
Mishania > 31-01-2016 18:57:26 |
Столько интересного понаписали, а готовую кнопку выкладывать будете? |
difabor > 01-02-2016 02:34:32 |
Mishania пишет
Так ведь эта кнопка Infocatcherа выложена и прекрасно работает. 01-02-2016 02:38:26 Infocatcher пишет
Огромнейшее спасибо! |
difabor > 04-02-2016 12:27:12 |
Уважаемый Infocatcher, |
Infocatcher > 05-02-2016 20:07:29 |
difabor пишет
Эээ... о каком быстром поиске речь? Там ничего такого не реализовано. Впрочем, я еще вот такую штуку делал для фильтрации: |
difabor > 06-02-2016 00:57:28 |
Infocatcher пишет
Спасибо! |
difabor > 06-02-2016 07:54:05 |
А как можно менять фон самого меню (не менюитема, а меню в целом)? Я имею в виду цвет фона? |
Infocatcher > 06-02-2016 15:57:52 |
difabor пишет
Тут два варианта: или в userChrome.css, или в код кнопки. Выделить код Код:toolbarbutton[id^="custombuttons-button"][label="Search"] > menupopup { -moz-appearance: none; background-color: rgba(0,255,0,0.8); } Это для menupopup внутри CB-кнопки с названием «Search». Но здесь надо вручную номер вписывать: button99. А если в коде, то надо найти место, где создается menupopup, в данном случае это Выделить код Код:var mp = document.createElement("menupopup"); // Добавить для раскраски: mp.style.cssText = "-moz-appearance: none; background-color: rgba(0,255,0,0.8);"; |
difabor > 07-02-2016 10:39:58 |
Infocatcher пишет
Огромное спасибо! |
difabor > 14-02-2016 17:02:04 |
Уважаемый Infocatcher, |
Infocatcher > 05-03-2016 23:17:55 |
Ох, помню, что читал, но забыл ответить. Это из-за chrome://browser/skin/browser.css Обесцвечивается вот так (в userChrome.css): |
difabor > 05-03-2016 23:55:01 |
Спасибо большое! |
Infocatcher > 06-03-2016 23:14:58 |
difabor Вместо #tools-menu (меню Инструменты) можно задавать штуки типа menu[label="Инструменты"] для определения по названию. А во-вторых, можно получить ссылку на сам этот узел, в котором находится текст сочетания клавиш, и перекрасить только его: Выделить код Код:var mi = document.getElementById("menu_openDownloads"); // Для примера пункт Инструменты – Загрузки var accel = document.getAnonymousElementByAttribute(mi, "class", "menu-accel"); // У пунктов с иконками тут будет "menu-iconic-accel" accel.style.color = "green"; |
difabor > 06-03-2016 23:23:47 |
Большое спасибо! |
voqabuhe > 30-03-2016 16:40:51 |
Infocatcher |
Infocatcher > 30-03-2016 19:55:59 |
voqabuhe пишет
Или Shift+клик, или поменять там в самом начале: Выделить код Код:var options = { ... closeMenu: true, // Close menu after left-click (use Shift+click to invert this behavior) |
voqabuhe > 30-03-2016 23:39:54 |
Infocatcher |
Infocatcher > 31-03-2016 00:39:20 |
voqabuhe |
voqabuhe > 31-03-2016 01:05:29 |
Infocatcher |
Infocatcher > 31-03-2016 01:10:32 |
voqabuhe |
voqabuhe > 31-03-2016 01:21:48 |
Infocatcher 31-03-2016 01:25:29 Infocatcher пишет
У меня 48.0a1 (2016-03-30) |
Infocatcher > 31-03-2016 01:39:17 |
Хм, наверное, дело в этом исправлении, которое пока попало только в разрабатываемую версию. |
voqabuhe > 31-03-2016 01:46:40 |
Infocatcher пишет
У меня версия version 0.1.2.1 - 2014-02-21 |
Infocatcher > 31-03-2016 11:29:13 |
Там заголовок старый, это видно по логам. |
voqabuhe > 31-03-2016 13:07:41 |
Infocatcher |
Infocatcher > 31-03-2016 13:26:45 |
voqabuhe |
voqabuhe > 31-03-2016 13:45:46 |
Infocatcher |
momo2000 > 18-02-2018 11:40:15 |
Блин, не показывает устаревшие расширения( |
Infocatcher > 18-02-2018 22:22:04 |
momo2000 пишет
Эмм, показывает: Вероятно, речь о расширениях, требующих перезапуска, но их не должно показывать в соответствии с названием кнопки. Выделить код Код:function getRestartlessAddons(addonTypes, callback, context) { … AddonManager.getAddonsByTypes(addonTypes, function(addons) { var restartless = addons.filter(function(addon) { var ops = addon.operationsRequiringRestart; return !addon.appDisabled // закомментировать проверку && !(ops & AddonManager.OP_NEEDS_RESTART_ENABLE || ops & AddonManager.OP_NEEDS_RESTART_DISABLE) … |
momo2000 > 19-02-2018 08:30:19 |
Infocatcher Дык надо пункт перезагрузки в конец вставить и тогда будет практически полный аналог Extension Options Menu, его даже с AMO удалили, видать как супер пупер устаревшее) |
momo2000 > 21-02-2018 16:09:42 |
Infocatcher или другой мастер Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart); иконка Выделить код Код:data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAD///8A/Pz8A/v7+gX7+/oF+fn4B////wB7d3JQDgYA8A4GAPB7d3JQ////APv7+gX8/PsD//7/AP///wD///8A////AP///wD///8A/v7+Af///wDx8fAFIRoU2BEJAP8RCQD/IRoU2PLx8AX///8A/Pz8Af7+/gL///8A////AP///wCalpFfgHx1jYiEfoCUkYt26unnDh4YFdgLAwD/DAQA/xoUEN38/PwAfXl0Wnp2cF////8A/v7+A////wD///8Aw8G9LwwJBuoAAAD/Ew8P7/f4+AeIhIBHHBUK4hsUCOKOi4dH1NTSCQUBAOkAAAD/iYV/U////wD8/PwD////AMrKxxUaEwfhDwcA/yMcFOvy8fAQ////APDv7gjw7+4H////APf39wBlYFx/CQIA/w0FAOjBv70Z////AP///wBbV1V/AAAA/zIsI8E6NTC+5+foGf///wD+/v4C////Afz8/AP///8B8fHxADYxKq0AAAD/aGRidv///wD19fUANC0lxAAAAP+ppqJE5eTjD+3t7A////8A/v7+Af7+/gH///8A+/v6BP///wCjoZxGAgAA/ykkHMDv7+8A7u3uDSghGOcFAAD8wsG+Hv///wD8/PwB////AP///wD///8A////APz8/AH///8Aw8G+GwQAAPwqIhji7+7uCu7t7gwoIRjlBQAA+sPBvhn///8A/Pz8Av///wD///8A////AP///wD8/PwB////AMPBvhkFAAD6JyAY5u7t7gz19fUANC0lxAAAAP+koZxF////APr6+gT///8A////AP///wD///8A+vr6BP///wCkoZxFAAAA/zMtJcP19fUA////AF1YVn0AAAD/NjEprfHx8QD///8E+vr6BPz8/AH8/PwB+vr6BP///wTx8fEANjEprQAAAP9dWFZ8////AP///wDBv70bCwQA6wkBAP9lYFx69vb1AP///wH+/v4A/v7+AP///wH29vUAZWBcegkBAP8LBADrwb+9Gv///wD8/PwD////AHl1cFgAAAD/CQIA/zUuJq6ppqE/x8XCF8fFwheppqE/NS4mrgkCAP8AAAD/eHVwV////wD8/PwD////AP7+/gP///8Ae3dwVgoDAO8BAAD/AgAA/wQAAPoEAAD6AgAA/wEAAP8KAwDvendwVv///wD+/v4D////AP///wD///8A/fz8A////wDDwL8aYFpTfjQtIsYoIRbmKCEW5jQtIsZgWlN+w8C/Gv///wD9/PwD////AP///wD///8A////AP7+/wD8/PwD////Af///wDz8vIB7u3sC+7t7Avz8vIB////AP///wH8/PwD/v7/AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== И можно ли у плагинов сделать режим "Всегда включать" и "Никогда не включать", а не "Всегда включать" и "Включать по запросу"? |
Dumby > 26-04-2018 18:01:01 |
Infocatcher скрытый текст Выделить код Код:if(addon.hidden) { _log("Let's try set addon.userDisabled using raw hack"); let g = Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {}); if("XPIDatabase" in g && "updateAddonDisabledState" in g.XPIDatabase) { // Firefox 61+ let rawAddon = g.XPIDatabase.syncGetAddon(function(rawAddon) { return rawAddon.id == addon.id }); g.XPIDatabase.updateAddonDisabledState(rawAddon, newDis); } else { // See "set userDisabled(val)" if("eval" in g) { |
Infocatcher > 18-05-2018 12:58:46 |
Dumby пишет
Совсем заработался, сообщение видел, даже запомнил, что было второе исправление... вспомнил только когда попытался применить кнопку. |
Dumby > 28-05-2018 12:37:23 |
Infocatcher скрытый текст Выделить код Код:function setNewDisabled(addon) { var newDis = getNewDisabled(addon); var oldDis = addon.userDisabled; try { if(addon.hidden && !addon.__lookupSetter__("userDisabled")) // Firefox 62+ throw 0; addon.userDisabled = newDis; } catch(e) { // Error: Cannot disable hidden add-on firefox@getpocket.com |
Infocatcher > 28-05-2018 13:43:43 |
Dumby пишет
О! А я уже успел вот так поразвлекаться: |
Infocatcher > 28-05-2018 15:55:00 |
А вот и источник проблемы: |
Dumby > 30-05-2018 08:23:37 |
Infocatcher Надо будет в addons4.js в CustombuttonsButton.prototype Наблюдение: если кнопка расположена на панели вкладок, |
Infocatcher > 31-05-2018 20:49:01 |
Dumby пишет
Не придумалось, как сбросить цвет... перекрасил: https://github.com/Infocatcher/Custom_B … 5ab04fdd31 |
Dumby > 21-06-2018 19:15:23 |
Infocatcher Выделить код Код://let rawAddon = g.XPIDatabase.syncGetAddon(function(rawAddon) { let rawAddon = Array.from(g.XPIDatabase.addonDB.values()).find(function(rawAddon) { |
Infocatcher > 22-06-2018 23:17:37 |
Dumby Выделить код Код:getDependentAddons(aAddon) { return Array.from(XPIDatabase.getAddons()) .filter(addon => addon.dependencies.includes(aAddon.id)); }, resource://gre/modules/addons/XPIDatabase.jsm Выделить код Код:/** * Synchronously gets all add-ons in the database. * This is only called from the preference observer for the default * compatibility version preference, so we can return an empty list if * we haven't loaded the database yet. * * @returns {Array<AddonInternal>} */ getAddons() { if (!this.addonDB) { return []; } return _filterDB(this.addonDB, aAddon => true); }, Выделить код Код:var g = Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {}); Array.isArray(g.XPIDatabase.getAddons()); // true И к чему тогда Array.from()? о_О Шаловливые клоуны… © |
momo2000 > 09-07-2019 11:58:02 |
Всё работает, но с 68 показывает ещё и поисковые плагины, даже при addonTypes: ["extension"] |
Infocatcher > 10-07-2019 21:11:37 |
momo2000 пишет
Это к разработчикам Firefox, к сожалению: у встроенных поисковых плагинов теперь type = "extension": |
Infocatcher > 17-09-2019 21:27:51 |
Распорка для скрытия поисковых плагинов: https://github.com/Infocatcher/Custom_B … 941d074ed6 |
kokoss > 27-09-2019 19:18:06 |
Infocatcher |
Andrey_Krropotkin > 27-09-2019 19:33:30 |
kokoss а в чем проблема? Он и так работает в 69 без отключения многопроцессорного режима. |
kokoss > 27-09-2019 20:01:12 |
Andrey_Krropotkin |
Andrey_Krropotkin > 27-09-2019 20:50:40 |
kokoss брал у Infocatcher здесь скрытый текст Выделить код Код:// http://infocatcher.ucoz.net/js/cb/toggleRestartlessAddons.js // https://forum.mozilla-russia.org/viewtopic.php?id=57948 // https://github.com/Infocatcher/Custom_Buttons/tree/master/Toggle_Restartless_Add-ons // Toggle Restartless Add-ons button for Custom Buttons // (code for "initialization" section) // Also the code can be used from main window context (as Mouse Gestures code, for example) // Also you can check for add-ons updates using right-click: // copy all code from // https://github.com/Infocatcher/Custom_Buttons/blob/master/Check_for_Addons_Updates/checkForAddonsUpdates.js // after "//== Check for Addons Updates begin" // See "var style = " to modify styles for specific add-ons // (c) Infocatcher 2013-2017 // version 0.1.3pre3 - 2017-10-23 var options = { addonTypes: ["extension"], // Possible values: "extension", "plugin" // From extensions: "userstyle" (Stylish), "greasemonkey-user-script" (Greasemonkey), "userscript" (Scriptish) // (swap to reorder in the menu) showVersions: 1, // 0 - don't show versions // 1 - show after name: "Addon Name 1.2" // 2 - show as "acceltext" (in place for hotkey text) showHidden: 0, // 0 - don't show hidden add-ons // -1 - show only enabled hidden add-ons (e.g. to track new items) // 1 - show all hidden add-ons sort: { enabled: 0, clickToPlay: 0, disabled: 0 // Sort order: // 0, 0, 0 - sort add-ons of each type alphabetically // 0, 0, 1 - show enabled add-ons (of each type) first // 0, 1, 2 - enabled add-ons, then click-to-play and then disabled }, closeMenu: false, // Close menu after left-click closeMenuClickToPlay: false // Close menu after left-click, for click to play plugins // Use Shift+click to invert closeMenu* behavior }; var mp = document.createXULElement("menupopup"); mp.setAttribute("onpopupshowing", "this.updateMenu();"); mp.setAttribute("oncommand", "this.handleEvent(event);"); mp.setAttribute("onmousedown", "if(event.button == 0) this.handleEvent(event);"); mp.setAttribute("onclick", "if(event.button > 0) this.handleEvent(event);"); mp.setAttribute("oncontextmenu", "return false;"); mp.setAttribute("onpopuphidden", "this.destroyMenu();"); var tb = this.parentNode; if(tb && tb.getAttribute("orient") == "vertical") { // https://addons.mozilla.org/firefox/addon/vertical-toolbar/ var isRight = tb.parentNode.getAttribute("placement") == "right"; mp.setAttribute("position", isRight ? "start_before" : "end_before"); } var cleanupTimer = 0; mp.updateMenu = function() { clearTimeout(cleanupTimer); addStyle(); getRestartlessAddons(options.addonTypes, function(addons) { var df = document.createDocumentFragment(); var prevType; function sortPosition(addon) { if("STATE_ASK_TO_ACTIVATE" in AddonManager && addon.userDisabled == AddonManager.STATE_ASK_TO_ACTIVATE) return options.sort.clickToPlay; if(addon.isActive) return options.sort.enabled; return options.sort.disabled; } function key(addon) { return options.addonTypes.indexOf(addon.type) + "\n" + sortPosition(addon) + "\n" + addon.name.toLowerCase(); } addons.sort(function(a, b) { var ka = key(a); var kb = key(b); return ka == kb ? 0 : ka < kb ? -1 : 1; }).forEach(function(addon) { var type = addon.type; if(prevType && type != prevType) df.appendChild(document.createXULElement("menuseparator")); prevType = type; var icon = addon.iconURL || addon.icon64URL; var mi = document.createXULElement("menuitem"); mi.className = "menuitem-iconic"; var label = addon.name; if(options.showVersions == 1) label += " " + addon.version; else if(options.showVersions == 2) mi.setAttribute("acceltext", addon.version); mi.setAttribute("label", label); mi.setAttribute("image", icon || mp.icons[type] || ""); if(!icon && mp.icons.useSVG) mi.style.fill = "#15c"; var tip = addon.description || ""; var delay = "delayedStartupAddons" in Services && Services.delayedStartupAddons[addon.id] || null; var isDelayed = delay !== null; mi.classList.toggle("toggleRestartlessAddons-isDelayed", isDelayed); if(isDelayed) tip = "[Delayed Startup: " + delay.toLocaleString() + "]" + (tip ? "\n" + tip : ""); tip && mi.setAttribute("tooltiptext", tip); mi.classList.toggle("toggleRestartlessAddons-isHidden", addon.hidden || false); setDisabled(mi, addon.userDisabled); mi._cbAddon = addon; df.appendChild(mi); }); mp.textContent = ""; mp.appendChild(df); }); }; mp.handleEvent = function(e) { var mi = e.target; if(!("_cbAddon" in mi)) return; var addon = mi._cbAddon; if(e.type == "mousedown") { var closeMenu = isAskToActivateAddon(addon) ? options.closeMenuClickToPlay : options.closeMenu; if(e.shiftKey) closeMenu = !closeMenu; mi.setAttribute("closemenu", closeMenu ? "auto" : "none"); return; } var hasMdf = hasModifier(e); if(e.type == "command" && (!hasMdf || e.shiftKey)) { let newDis = setNewDisabled(addon); setDisabled(mi, newDis); } else if(e.type == "command" && hasMdf || e.type == "click" && e.button == 1) { openAddonPage(addon); closeMenus(mi); } else if(e.type == "click" && e.button == 2) { if(openAddonOptions(addon)) closeMenus(mi); } }; mp.destroyMenu = function() { removeStyle(); clearTimeout(cleanupTimer); cleanupTimer = setTimeout(function() { mp.textContent = ""; }, 5000); }; mp.icons = { get useSVG() { delete this.useSVG; return this.useSVG = Services.appinfo.name == "Firefox" && parseFloat(Services.appinfo.version) >= 57; }, get plugin() { delete this.plugin; return this.plugin = this.useSVG ? "chrome://mozapps/skin/plugins/pluginGeneric.svg" : "chrome://mozapps/skin/plugins/pluginGeneric-16.png"; }, get extension() { delete this.extension; return this.extension = this.useSVG ? "chrome://mozapps/skin/extensions/extensionGeneric-16.svg" : "chrome://mozapps/skin/extensions/extensionGeneric-16.png"; } }; function isAskToActivateAddon(addon) { return addon.type == "plugin" && "STATE_ASK_TO_ACTIVATE" in AddonManager && Services.prefs.getBoolPref("plugins.click_to_play"); } function setNewDisabled(addon) { var newDis = getNewDisabled(addon); var oldDis = addon.userDisabled; try { addon.userDisabled = newDis; } catch(e) { // Error: Cannot disable hidden add-on firefox@getpocket.com _log("Can't set addon.userDisabled to " + newDis + ", error:\n" + e); if(addon.hidden) setNewDisabledRaw(addon, newDis); } var realDis = addon.userDisabled; if(realDis != newDis && addon.type == "extension") { // Firefox 62+? Weird things happens setNewDisabledRaw(addon, newDis); realDis = addon.userDisabled; } if(realDis != newDis) { // We can't enable vulnerable plugins let err = "Can't set addon.userDisabled to " + newDis + ", real value: " + realDis; if(newDis) { _log(err + "\nSTATE_ASK_TO_ACTIVATE not supported?"); newDis = false; } else { _log(err + "\nVulnerable plugin?"); if(oldDis == AddonManager.STATE_ASK_TO_ACTIVATE) newDis = true; else newDis = AddonManager.STATE_ASK_TO_ACTIVATE; } addon.userDisabled = newDis; } return addon.userDisabled; } function getNewDisabled(addon) { // disabled -> STATE_ASK_TO_ACTIVATE -> enabled -> ... var curDis = addon.userDisabled; var newDis; if("STATE_ASK_TO_ACTIVATE" in AddonManager && curDis == AddonManager.STATE_ASK_TO_ACTIVATE) newDis = false; else if(!curDis) newDis = true; else { if(isAskToActivateAddon(addon)) newDis = AddonManager.STATE_ASK_TO_ACTIVATE; else newDis = false; } return newDis; } function setNewDisabledRaw(addon, newDis) { _log("Let's try set addon.userDisabled using raw hack"); let g = Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {}); if("XPIDatabase" in g && "updateAddonDisabledState" in g.XPIDatabase) { // Firefox 61+ let rawAddon = g.XPIDatabase.getAddons().find(function(rawAddon) { return rawAddon.id == addon.id; }); g.XPIDatabase.updateAddonDisabledState(rawAddon, newDis); } else if("eval" in g) { // See "set userDisabled(val)" let addonFor = g.eval("addonFor"); let rawAddon = addonFor(addon); //rawAddon.userDisabled = newDis; g.XPIProvider.updateAddonDisabledState(rawAddon, newDis); } else { // Firefox 57+? See https://forum.mozilla-russia.org/viewtopic.php?pid=745272#p745272 updateAddonDisabledState(addon, newDis); } } function updateAddonDisabledState(addon, newDis) { var nsvo = Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {}); var key = "_cbToggleRestartlessAddonsData"; var url = URL.createObjectURL(new Blob([ "XPIProvider.updateAddonDisabledState(addonFor(this." + key + "[0]), this." + key + "[1]); delete this." + key + ";" ])); addDestructor(function() { URL.revokeObjectURL(url); }); (updateAddonDisabledState = function(addon, newDis) { nsvo[key] = [addon, newDis]; Services.scriptloader.loadSubScript(url, nsvo); })(addon, newDis); } function setDisabled(mi, disabled) { var askToActivate = "STATE_ASK_TO_ACTIVATE" in AddonManager && disabled == AddonManager.STATE_ASK_TO_ACTIVATE; var cl = mi.classList; cl.toggle("toggleRestartlessAddons-askToActivate", askToActivate); cl.toggle("toggleRestartlessAddons-disabled", disabled && !askToActivate); } if( this instanceof XULElement // Custom Buttons && typeof event == "object" && !("type" in event) && typeof _phase == "string" && _phase == "init" // Initialization ) { this.type = "menu"; this.orient = "horizontal"; this.appendChild(mp); this.onmouseover = function(e) { if(e.target != this) return; Array.prototype.some.call( this.parentNode.getElementsByTagName("*"), function(node) { if( node != this && node.namespaceURI == xulns && node.boxObject // See https://github.com/Infocatcher/Custom_Buttons/issues/28 //&& node.boxObject instanceof Components.interfaces.nsIMenuBoxObject && "open" in node && node.open && node.getElementsByTagName("menupopup").length ) { node.open = false; this.open = true; return true; } return false; }, this ); }; this.onmousedown = function(e) { if(e.target == this && e.button == 0 && hasModifier(e)) e.preventDefault(); }; this.oncontextmenu = function(e) { if(e.target == this && !hasModifier(e) && hasUpdater()) e.preventDefault(); }; this.onclick = function(e) { if(e.target != this) return; if(e.button == 0 && hasModifier(e) || e.button == 1) openAddonsManager(); else if(e.button == 2 && !hasModifier(e) && hasUpdater()) checkForAddonsUpdates.call(this); }; } else { // Mouse gestures or something other... let e; if(typeof event == "object" && event instanceof Event && "screenX" in event) // FireGestures e = event; else if( this instanceof Components.interfaces.nsIDOMChromeWindow && "mgGestureState" in window && "endEvent" in mgGestureState // Mouse Gestures Redox ) e = mgGestureState.endEvent; else { let anchor = this instanceof XULElement && this || window.gBrowser && gBrowser.selectedBrowser || document.documentElement; if("boxObject" in anchor) { let bo = anchor.boxObject; e = { screenX: bo.screenX, screenY: bo.screenY }; if(this instanceof XULElement) e.screenY += bo.height; } } if(!e || !("screenX" in e)) throw new Error("[Toggle Restartless Add-ons]: Can't get event object"); document.documentElement.appendChild(mp); mp.addEventListener("popuphidden", function destroy(e) { mp.removeEventListener(e.type, destroy, false); setTimeout(function() { mp.destroyMenu(); mp.parentNode.removeChild(mp); }, 0); }, false); mp.openPopupAtScreen(e.screenX, e.screenY); } function getRestartlessAddons(addonTypes, callback, context) { if(!("AddonManager" in window)) Components.utils.import("resource://gre/modules/AddonManager.jsm"); if(!("Services" in window)) Components.utils.import("resource://gre/modules/Services.jsm"); var then, promise = AddonManager.getAddonsByTypes(addonTypes, then = function(addons) { var restartless = addons.filter(function(addon) { var ops = addon.operationsRequiringRestart; return !addon.appDisabled && !(ops & AddonManager.OP_NEEDS_RESTART_ENABLE || ops & AddonManager.OP_NEEDS_RESTART_DISABLE) && ( !addon.hidden || options.showHidden > 0 || options.showHidden == -1 && !addon.userDisabled ); }); callback.call(context, restartless); }); promise && typeof promise.then == "function" && promise.then(then, Components.utils.reportError); // Firefox 61+ } function openAddonOptions(addon) { // Based on code from chrome://mozapps/content/extensions/extensions.js // Firefox 21.0a1 (2013-01-27) var optionsURL = addon.optionsURL; if(!addon.isActive || !optionsURL) return false; if(addon.type == "plugin") // No options for now! return false; if( addon.optionsType == AddonManager.OPTIONS_TYPE_INLINE || addon.optionsType == (AddonManager.OPTIONS_TYPE_INLINE_INFO || NaN) || addon.optionsType == (AddonManager.OPTIONS_TYPE_INLINE_BROWSER || NaN) ) openAddonPage(addon, true); else if(addon.optionsType == AddonManager.OPTIONS_TYPE_TAB && "switchToTabHavingURI" in window) switchToTabHavingURI(optionsURL, true); else { let windows = Services.wm.getEnumerator(null); while(windows.hasMoreElements()) { let win = windows.getNext(); if(win.document.documentURI == optionsURL) { win.focus(); return true; } } // Note: original code checks browser.preferences.instantApply and may open modal windows window.openDialog(optionsURL, "", "chrome,titlebar,toolbar,centerscreen,dialog=no"); } return true; } function openAddonsManager(view) { var openAddonsMgr = window.BrowserOpenAddonsMgr // Firefox || window.openAddonsMgr // Thunderbird || window.toEM; // SeaMonkey openAddonsMgr(view); } function openAddonPage(addon, scrollToPreferences) { var platformVersion = parseFloat( Services.appinfo.name == "Pale Moon" ? Services.appinfo.version : Services.appinfo.platformVersion ); scrollToPreferences = scrollToPreferences && platformVersion >= 12 ? "/preferences" : ""; openAddonsManager("addons://detail/" + encodeURIComponent(addon.id) + scrollToPreferences); } function hasModifier(e) { return e.ctrlKey || e.shiftKey || e.altKey || e.metaKey; } function addStyle() { if(addStyle.hasOwnProperty("_style")) return; var style = '\ .toggleRestartlessAddons-isDelayed > .menu-iconic-text {\n\ opacity: 0.75;\n\ color: #070;\n\ }\n\ .toggleRestartlessAddons-isHidden > .menu-iconic-text {\n\ color: #609;\n\ }\n\ .toggleRestartlessAddons-disabled > .menu-iconic-left {\n\ opacity: 0.4;\n\ }\n\ .toggleRestartlessAddons-disabled > .menu-iconic-text,\n\ .toggleRestartlessAddons-disabled > .menu-accel-container {\n\ opacity: 0.5;\n\ }\n\ .toggleRestartlessAddons-askToActivate {\n\ color: -moz-nativehyperlinktext;\n\ }'; addStyle._style = document.insertBefore( document.createProcessingInstruction( "xml-stylesheet", 'href="' + "data:text/css," + encodeURIComponent(style) + '" type="text/css"' ), document.documentElement ); } function removeStyle() { if(!addStyle.hasOwnProperty("_style")) return; var s = addStyle._style; s.parentNode.removeChild(s); delete addStyle._style; } function closeMenus(node) { // Based on function closeMenus from chrome://browser/content/utilityOverlay.js for(; node && "tagName" in node; node = node.parentNode) { if( node.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" && (node.localName == "menupopup" || node.localName == "popup") ) node.hidePopup(); } } function _log(s) { if(typeof LOG == "function") // Custom Buttons LOG(s); else // Or something else Services.console.logStringMessage("Toggle Restartless Add-ons: " + s); } function hasUpdater() { var has = checkForAddonsUpdates.toString().indexOf("about:addons") != -1; hasUpdater = function() { return has; }; return has; } function checkForAddonsUpdates() { // http://infocatcher.ucoz.net/js/cb/checkForAddonsUpdates.js // https://forum.mozilla-russia.org/viewtopic.php?id=57958 // https://github.com/Infocatcher/Custom_Buttons/tree/master/Check_for_Addons_Updates // Check for Addons Updates button for Custom Buttons // (code for "code" section) // (c) Infocatcher 2012-2014 // version 0.1.5 - 2014-10-13 // Button just open hidden tab with about:addons and trigger built-in "Check for Updates" function. // And show tab, if found updates. (function() { var btn = this instanceof XULElement ? this : { // Launched not from custom button image: "", // Base64-encoded icon (if empty, will be used "imgLoading") label: "Check for Addons Updates", tooltipText: "" }; if("_cb_disabled" in btn) return; btn._cb_disabled = true; if(!("Services" in window)) Components.utils.import("resource://gre/modules/Services.jsm"); var app = Services.appinfo.name; var ADDONS_URL = "about:addons"; var progressIcon = new ProgressIcon(btn); var image = btn.image || progressIcon.imgLoading; var tip = btn.tooltipText; btn.tooltipText = "Open " + ADDONS_URL + "…"; var tab, browser, gBrowser; var tbTabInfo, tbTab; var trgWindow = Services.wm.getMostRecentWindow("navigator:browser") || app == "Thunderbird" && Services.wm.getMostRecentWindow("mail:3pane") || window; var trgDocument = trgWindow.document; var tabmail = trgDocument.getElementById("tabmail"); if(tabmail && app == "Thunderbird") { // Note: SeaMonkey doesn't support content tabs in mail window let addonsWin; let receivePong = function(subject, topic, data) { addonsWin = subject; }; Services.obs.addObserver(receivePong, "EM-pong", false); Services.obs.notifyObservers(null, "EM-ping", ""); Services.obs.removeObserver(receivePong, "EM-pong"); if(addonsWin) { let rootWindow = addonsWin .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShellTreeItem) .rootTreeItem .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindow); tabmail = rootWindow.document.getElementById("tabmail"); tbTabInfo = tabmail.getBrowserForDocument(addonsWin); tbTab = tab = tbTabInfo.tabNode; processAddonsTab(addonsWin); } else { Services.obs.addObserver(function observer(subject, topic, data) { Services.obs.removeObserver(observer, topic); if(subject.document.readyState == "complete") processAddonsTab(subject); else { subject.addEventListener("load", function onLoad(e) { subject.removeEventListener(e.type, onLoad, false); processAddonsTab(subject); }, false); } }, "EM-loaded", false); // See openAddonsMgr() -> openContentTab() tbTabInfo = tabmail.openTab("contentTab", { contentPage: ADDONS_URL, clickHandler: "specialTabs.siteClickHandler(event, /addons\.mozilla\.org/);", background: true }); tbTab = tab = tbTabInfo.tabNode; tbTab.collapsed = true; // Note: dontSelectHiddenTab() not implemented } } else if("gBrowser" in trgWindow && trgWindow.gBrowser.tabs) { let isPending = false; let ws = Services.wm.getEnumerator("navigator:browser"); windowsLoop: while(ws.hasMoreElements()) { let w = ws.getNext(); let tabs = w.gBrowser.tabs; for(let i = 0, l = tabs.length; i < l; ++i) { let t = tabs[i]; if( !t.closing && t.linkedBrowser && t.linkedBrowser.currentURI.spec == ADDONS_URL ) { tab = t; break windowsLoop; } } } gBrowser = trgWindow.gBrowser; if(!tab) { tab = gBrowser.addTab(ADDONS_URL, { triggeringPrincipal: "Services" in window // Firefox 63+ && Services.scriptSecurityManager && Services.scriptSecurityManager.getSystemPrincipal() }); tab.collapsed = true; tab.closing = true; // See "visibleTabs" getter in chrome://browser/content/tabbrowser.xml trgWindow.addEventListener("TabSelect", dontSelectHiddenTab, false); } else if( tab.getAttribute("pending") == "true" // Gecko >= 9.0 || tab.linkedBrowser.contentDocument.readyState == "uninitialized" // || tab.linkedBrowser.__SS_restoreState == 1 ) isPending = true; browser = tab.linkedBrowser; if(isPending || browser.webProgress.isLoadingDocument) { browser.addEventListener("load", processAddonsTab, true); if(isPending) { if(parseFloat(Services.appinfo.platformVersion) >= 41) { // Workaround to correctly restore pending tab // See https://github.com/Infocatcher/Custom_Buttons/issues/39 let selTab = gBrowser.selectedTab; gBrowser.selectedTab = tab; gBrowser.selectedTab = selTab; } else { browser.reload(); } } } else { processAddonsTab(); } } else { progressIcon.restore(); btn.tooltipText = tip; delete btn._cb_disabled; Services.prompt.alert(window, btn.label, "Error: Can't find supported window!"); return; } function processAddonsTab(e) { var doc; if(e && e instanceof Components.interfaces.nsIDOMWindow) { doc = e.document; } else if(e) { doc = e.target; if(doc.location != ADDONS_URL) return; browser.removeEventListener(e.type, processAddonsTab, true); } else { doc = browser.contentDocument; } progressIcon.loading(); var inProgress = $("updates-progress"); btn.tooltipText = inProgress.getAttribute("value"); var origIcon = tab.image; tab.image = image; var updEnabledPref = "extensions.update.enabled"; var updEnabled = Services.prefs.getBoolPref(updEnabledPref); if(!updEnabled) Services.prefs.setBoolPref(updEnabledPref, true); var notFound = $("updates-noneFound"); var updated = $("updates-installed"); // Avoid getting false results from the past update check (may not be required for "noneFound") notFound.hidden = updated.hidden = true; $("cmd_findAllUpdates").doCommand(); var waitTimer = setInterval(function() { if(!doc.defaultView || doc.defaultView.closed) { stopWait(); notify("Tab with add-ons manager was closed!"); return; } if(!inProgress.hidden) return; var autoUpdate = $("utils-autoUpdateDefault"); var autoUpdateChecked = autoUpdate.getAttribute("checked") == "true"; var found = $("updates-manualUpdatesFound-btn"); if( autoUpdateChecked ? notFound.hidden && updated.hidden : notFound.hidden && found.hidden ) // Too early? return; stopWait(); if(!tbTab) tab.closing = false; function removeTab() { if(!tab.collapsed) return; if(tbTab) tabmail.closeTab(tbTabInfo, true /*aNoUndo*/); else { gBrowser.removeTab(tab); (function forgetClosedTab(isSecondTry) { var ss = "nsISessionStore" in Components.interfaces ? ( Components.classes["@mozilla.org/browser/sessionstore;1"] || Components.classes["@mozilla.org/suite/sessionstore;1"] ).getService(Components.interfaces.nsISessionStore) : SessionStore; // Firefox 61+ https://bugzilla.mozilla.org/show_bug.cgi?id=1450559 if(!("forgetClosedTab" in ss)) return; var closedTabs = JSON.parse(ss.getClosedTabData(window)); for(let i = 0, l = closedTabs.length; i < l; ++i) { let closedTab = closedTabs[i]; let state = closedTab.state; if(state.entries[state.index - 1].url == ADDONS_URL) { ss.forgetClosedTab(window, i); return; } } if(!isSecondTry) // May be needed in SeaMonkey setTimeout(forgetClosedTab, 0, true); })(); } } if(!updEnabled) Services.prefs.setBoolPref(updEnabledPref, false); if(!notFound.hidden) { removeTab(); notify(notFound.getAttribute("value")); return; } if(autoUpdateChecked) { removeTab(); notify(updated.getAttribute("value")); return; } tab.collapsed = false; $("categories").selectedItem = $("category-availableUpdates"); var tabWin = tab.ownerDocument.defaultView; if(tbTab) tabmail.switchToTab(tbTabInfo); else tabWin.gBrowser.selectedTab = tab; setTimeout(function() { tabWin.focus(); doc.defaultView.focus(); $("addon-list").focus(); }, 0); }, 50); function $(id) { return doc.getElementById(id); } function stopWait() { clearInterval(waitTimer); progressIcon.restore(); btn.tooltipText = tip; if(tab.image == image) tab.image = origIcon; trgWindow.removeEventListener("TabSelect", dontSelectHiddenTab, false); setTimeout(function() { delete btn._cb_disabled; }, 500); } function notify(msg) { Components.classes["@mozilla.org/alerts-service;1"] .getService(Components.interfaces.nsIAlertsService) .showAlertNotification( Services.appinfo.name == "Firefox" && parseFloat(Services.appinfo.version) >= 57 ? "chrome://mozapps/skin/extensions/extensionGeneric.svg" : "chrome://mozapps/skin/extensions/extensionGeneric.png", btn.label, msg, false, "", null ); } } function dontSelectHiddenTab(e) { // <tab /><tab collapsed="true" /> // Close first tab: collapsed tab becomes selected var trgTab = e.originalTarget || e.target; if(trgTab != tab) return; if(/\n(?:BrowserOpenAddonsMgr|toEM)@chrome:\/\//.test(new Error().stack)) { // User open Add-ons Manager, show tab trgWindow.removeEventListener("TabSelect", dontSelectHiddenTab, false); setTimeout(function() { // Hidden tab can't be selected, so select it manually... tab.collapsed = tab.closing = false; gBrowser.selectedTab = tab; }, 0); } function done(t) { if(!t.hidden && !t.closing) { e.preventDefault(); e.stopPropagation(); return gBrowser.selectedTab = t; } return false; } for(var t = tab.nextSibling; t; t = t.nextSibling) if(done(t)) return; for(var t = tab.previousSibling; t; t = t.previousSibling) if(done(t)) return; } function ProgressIcon(btn) { if(!(btn instanceof XULElement)) { this.loading = this.restore = function() {}; return; } var app = Services.appinfo.name; var pv = parseFloat(Services.appinfo.platformVersion); if(app == "SeaMonkey") this.imgConnecting = this.imgLoading = "chrome://communicator/skin/icons/loading.gif"; else if(app == "Thunderbird") { this.imgConnecting = "chrome://messenger/skin/icons/connecting.png"; this.imgLoading = "chrome://messenger/skin/icons/loading.png"; } else { this.imgConnecting = "chrome://browser/skin/tabbrowser/connecting.png"; this.imgLoading = app == "Firefox" && pv >= 48 ? "chrome://global/skin/icons/loading.png" : "chrome://browser/skin/tabbrowser/loading.png"; } var useAnimation = app == "Firefox" && pv >= 32; var btnIcon = btn.ownerDocument.getAnonymousElementByAttribute(btn, "class", "toolbarbutton-icon") || btn.getElementsByClassName("toolbarbutton-icon")[0]; var origIcon = btnIcon.src; btnIcon.src = this.imgConnecting; if(useAnimation) { let cs = btnIcon.ownerDocument.defaultView.getComputedStyle(btnIcon, null); let s = btnIcon.style; s.margin = [cs.marginTop, cs.marginRight, cs.marginBottom, cs.marginLeft].join(" "); s.padding = [cs.paddingTop, cs.paddingRight, cs.paddingBottom, cs.paddingLeft].join(" "); s.width = cs.width; s.height = cs.height; s.boxShadow = "none"; s.borderColor = s.background = "transparent"; btnIcon.setAttribute("fadein", "true"); btnIcon.setAttribute("busy", "true"); btnIcon.classList.add("tab-throbber"); btnIcon._restore = function() { delete btnIcon._restore; btnIcon.removeAttribute("busy"); btnIcon.removeAttribute("progress"); setTimeout(function() { btnIcon.classList.remove("tab-throbber"); btnIcon.removeAttribute("style"); btnIcon.removeAttribute("fadein"); }, 0); }; } this.loading = function() { btnIcon.src = this.imgLoading; if(useAnimation) btnIcon.setAttribute("progress", "true"); }; this.restore = function() { btnIcon.src = origIcon; if(useAnimation) btnIcon._restore(); }; } }).call(this); //== Check for Addons Updates end } this.tooltipText = "Переключатель джетпаков" + "\n\nУправление:\nЛКМ – открыть меню" + "\nПКМ – проверить обновления" + "\nСКМ – открыть страницу дополнений" + "\nShift+ПКМ – меню кнопки" + "\n\nВ меню: \nЛКМ – включить/выключить дополнение" + "\nShift+ЛКМ – включить/выключить дополнение без закрытия меню" + "\nСКМ – открыть страницу дополнения в управлении дополнениями" + "\nПКМ – открыть настройки дополнения (если есть)"; секция /*CODE*/ скрытый текст |
kokoss > 27-09-2019 21:26:52 |
Andrey_Krropotkin |
Andrey_Krropotkin > 27-09-2019 21:36:49 |
kokoss это не ко мне, это не мой код, я в него не вникал. |
Infocatcher > 27-09-2019 21:53:20 |
kokoss пишет
В начале кода есть настройки, sort: { … disabled: 1 } переместит отключенные в конец списка: Выделить код Код:var options = { … sort: { enabled: 0, clickToPlay: 0, disabled: 0 // Sort order: // 0, 0, 0 - sort add-ons of each type alphabetically // 0, 0, 1 - show enabled add-ons (of each type) first // 0, 1, 2 - enabled add-ons, then click-to-play and then disabled }, |
kokoss > 27-09-2019 22:36:11 |
Infocatcher |
voqabuhe > 24-01-2020 22:46:05 |
Infocatcher |
Infocatcher > 24-01-2020 22:55:07 |
Есть тестовая: Но у тестовых обновлены только непосредственно исходник (toggleRestartlessAddons.js) и установочная страница (toggleRestartlessAddons.html, которую можно скачать отдельно и открыть или скопировать custombutton:// ссылку). |
voqabuhe > 25-01-2020 03:50:48 |
Infocatcher |
Dumby > 23-02-2020 15:02:18 |
Infocatcher В Firefox 74 для метода XPIDatabase.updateAddonDisabledState() скрытый текст Выделить код Код://g.XPIDatabase.updateAddonDisabledState(rawAddon, newDis); g.XPIDatabase.updateAddonDisabledState( rawAddon, g.XPIDatabase.updateAddonDisabledState.length == 1 // Firefox 74+ ? {userDisabled: newDis} : newDis ); |
Infocatcher > 26-02-2020 19:53:09 |
Dumby пишет
Вот ведь… Заодно обнаружил, что в Firefox 74.0b7 подозрительно себя ведет Firefox Screenshots: как бы выключается, но восстанавливается после перезапуска. А в консоли Кондуит и Швамбрания… sendRemoveListener on closed conduit screenshots@mozilla.org.33 ConduitsChild.jsm:108 _send resource://gre/modules/ConduitsChild.jsm:108 _send self-hosted:977 removeListener resource://gre/modules/ExtensionChild.jsm:1138 removeListener resource://gre/modules/ExtensionChild.jsm:1361 onClicked chrome://browser/content/child/ext-menus.js:282 removeListener resource://gre/modules/ExtensionCommon.jsm:2544 revoke resource://gre/modules/ExtensionCommon.jsm:2566 close resource://gre/modules/ExtensionCommon.jsm:2571 unload resource://gre/modules/ExtensionCommon.jsm:910 unload resource://gre/modules/ExtensionPageChild.jsm:261 unload resource://gre/modules/ExtensionPageChild.jsm:310 destroyExtensionContext resource://gre/modules/ExtensionPageChild.jsm:494 observe resource://gre/modules/ExtensionPageChild.jsm:407 |
Infocatcher > 27-02-2020 21:14:09 |
Infocatcher пишет
Пришлось еще и extensions.screenshots.disabled переключать. |
voqabuhe > 27-02-2020 22:23:14 |
Infocatcher пишет
Нефига опять не пойму откуда её ставить то? |
Infocatcher > 28-02-2020 20:14:11 |
voqabuhe пишет
В общем случае – по инструкции. скрытый текст Откроется измененный файл: https://github.com/Infocatcher/Custom_B … sAddons.js И вот постоянная ссылка на версию с исправлением: https://raw.githubusercontent.com/Infoc … sAddons.js |
voqabuhe > 28-02-2020 20:42:32 |
Infocatcher |
momo2000 > 29-02-2020 08:37:39 |
voqabuhe |
Dumby > 17-04-2020 08:06:57 |
Infocatcher |
Infocatcher > 17-04-2020 21:40:49 |
Dumby пишет
Вот ведь иконисты… |
Infocatcher > 22-04-2020 21:22:18 |
egorsemenov06 пишет
https://github.com/VitaliyVstyle/Vitali … _files.zip ? Судя по описанию, надо в user_chrome_files/custom_scripts/custom_script.js вписать вот такое: Выделить код Код:(function () { // Toggle Restartless Add-ons button // Custom Buttons-like environment var event = {}; var _phase = "init"; var id = "__cb_toggleRestartlessAddons"; CustomizableUI.createWidget({ id: id, type: "custom", defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(doc) { var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var btn = doc.createElementNS(XUL_NS, "toolbarbutton"); var attrs = { id: id, class: "toolbarbutton-1 chromeclass-toolbar-additional", label: "Toggle Restartless Add-ons", tooltiptext: "Toggle Restartless Add-ons", style: 'list-style-image: url("chrome://branding/content/icon16.png");', // Set icon here __proto__: null }; for(var p in attrs) btn.setAttribute(p, attrs[p]); doc.defaultView.setTimeout(function() { toggleRestartlessAddons.call(btn); }, 0); return btn; } }); function toggleRestartlessAddons() { // Code from https://github.com/Infocatcher/Custom_Buttons/blob/master/Toggle_Restartless_Add-ons/toggleRestartlessAddons.js } })(); Вместо chrome://branding/content/icon16.png надо вписать длинный data:image… иконки. Из консоли ошибок работает. Наверное, и из user_chrome_files запустится. |
voqabuhe > 22-04-2020 22:53:16 |
egorsemenov06 |
voqabuhe > 22-04-2020 23:56:21 |
egorsemenov06 23-04-2020 00:04:37 |
voqabuhe > 23-04-2020 00:08:49 |
egorsemenov06 |
_zt > 23-04-2020 22:34:06 |
Секция на замену: скрытый текст Выделить код Код:style: ` @namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul); .restartless label:after { content:"☑"; } .enabling label:after { content:"☑" !important; } .disabling label:after { content:"☐" !important; } .uninstalling label:after { content: '!' !important; } .noOptions label { font-style: italic; color: silver; } .disabled label { color: gray; font-style: italic; } .disabled label:after { content:"☐" !important; } `, скрытый текст Выделить код Код:style: ` @namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul); .restartless label:after { content:"☑"; } .enabling label:after { content:"☑" !important; } .disabling label:after { content:"☐" !important; } .uninstalling label:after { content: '!' !important; } .noOptions label { font-style: italic; color: gray } .disabled label { color: orange; font-style: italic; } .disabled label:after { content:"☐" !important; } `, скрытый текст Выделить код Код:style: ` @namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul); .restartless label:after { font-size: 18px; content:"☑"; } .enabling label:after { content:"☑" !important; } .disabling label:after { content:"☐" !important; } .uninstalling label:after { content: '!' !important; } .noOptions label { color: gray; } .disabled label { color: orange; font-style: italic; } .disabled label:after { content:"☐" !important; } `, Ну и это можно: Выделить код Код:mi.setAttribute('tooltiptext', addon.description + '\nID : ' + addon.id + '\n\nЛКМ : Настройки\nПКМ : Откл. / Включить\nСКМ : Домашняя страница\nCtrl + ЛКМ : Открыть архив\nCtrl + ПКМ : Деинсталлировать\nCtrl + СКМ : Копировать ID'); Размер удален, так как все равно не работает. В общей теме есть замена, но она не реальный, а распакованный размер показывает. |
Infocatcher > 24-04-2020 23:18:29 |
egorsemenov06 пишет
Поставил. Вот так, вроде, работает (по-прежнему надо дописать код инициализации и задать иконку): Выделить код Код:(function () { // Toggle Restartless Add-ons button // Custom Buttons-like environment var event = {}; var _phase = "init"; var window, document, XULElement, setTimeout, clearTimeout; var AddonManager; var id = "__cb_toggleRestartlessAddons"; CustomizableUI.createWidget({ id: id, type: "custom", defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(doc) { var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var btn = doc.createElementNS(XUL_NS, "toolbarbutton"); var attrs = { id: id, class: "toolbarbutton-1 chromeclass-toolbar-additional", label: "Toggle Restartless Add-ons", tooltiptext: "Toggle Restartless Add-ons", style: 'list-style-image: url("chrome://branding/content/icon16.png");', // Set icon here __proto__: null }; for(var p in attrs) btn.setAttribute(p, attrs[p]); var win = doc.defaultView; win.setTimeout(function() { window = win; document = win.document; XULElement = win.XULElement; setTimeout = win.setTimeout; clearTimeout = win.clearTimeout; AddonManager = win.AddonManager; toggleRestartlessAddons.call(btn); }, 0); return btn; } }); function toggleRestartlessAddons() { // Code from https://github.com/Infocatcher/Custom_Buttons/blob/master/Toggle_Restartless_Add-ons/toggleRestartlessAddons.js } })(); 24-04-2020 23:21:03 24-04-2020 23:35:04 Выделить код Код:(function () { // Toggle Restartless Add-ons button var id = "__cb_toggleRestartlessAddons"; CustomizableUI.createWidget({ id: id, type: "custom", defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(doc) { var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var btn = doc.createElementNS(XUL_NS, "toolbarbutton"); var attrs = { id: id, class: "toolbarbutton-1 chromeclass-toolbar-additional", label: "Toggle Restartless Add-ons", tooltiptext: "Toggle Restartless Add-ons", style: 'list-style-image: url("chrome://branding/content/icon16.png");', // Set icon here __proto__: null }; for(var p in attrs) btn.setAttribute(p, attrs[p]); var win = doc.defaultView; win.setTimeout(function() { new win.Function( "(" + toggleRestartlessAddons.toString() .replace("{", '{\n\tvar event = {}, _phase = "init";') + ").call(document.getElementById('" + id + "'));" )(); }, 0); return btn; } }); function toggleRestartlessAddons() { // Code from https://github.com/Infocatcher/Custom_Buttons/blob/master/Toggle_Restartless_Add-ons/toggleRestartlessAddons.js } })(); |
JKT > 14-07-2020 01:27:53 |
|
kokoss > 14-07-2020 14:02:12 |
Add, или такой вариант для -> user_chrome_files/custom_script.js: https://forum.mozilla-russia.org/viewto … 12#p780412 |
Garalf > 29-07-2020 12:54:14 |
У меня в 79 перестало работать обновление расширений по правому клику, просто крутится кольцо... |
voqabuhe > 29-07-2020 14:50:39 |
Garalf |
Garalf > 29-07-2020 21:13:41 |
voqabuhe |
voqabuhe > 29-07-2020 23:43:51 |
Garalf |
Garalf > 30-07-2020 10:47:35 |
Разобрался. Все работает! |
KOMMEHTATOP > 02-10-2020 10:37:36 |
Mozilla Firefox 78.3.1esr Toggle Restartless Add-ons скрытый текст Выделить код Код:custombutton://%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0D%0A%3Ccustombutton%20xmlns%3Acb%3D%22http%3A//xsms.nm.ru/custombuttons/%22%3E%0A%20%20%3Cname%3E%u0410%u0432%u0442%u043E%u043C%u0430%u0442%u0438%u0447%u0435%u0441%u043A%u0438%20%u043F%u0435%u0440%u0435%u0437%u0430%u0433%u0440%u0443%u0436%u0430%u0442%u044C%20%u0432%u043A%u043B%u0430%u0434%u043A%u0443%3C/name%3E%0A%20%20%3Cimage%3E%3C%21%5BCDATA%5Bhttps%3A//raw.githubusercontent.com/Infocatcher/Custom_Buttons/master/Toggle_Restartless_Add-ons/icon.png%5D%5D%3E%3C/image%3E%0A%20%20%3Cmode%3E0%3C/mode%3E%0A%20%20%3Cinitcode%3E%3C%21%5BCDATA%5B//%20http%3A//infocatcher.ucoz.net/js/cb/toggleRestartlessAddons.js%0A//%20https%3A//forum.mozilla-russia.org/viewtopic.php%3Fid%3D57948%0A//%20https%3A//github.com/Infocatcher/Custom_Buttons/tree/master/Toggle_Restartless_Add-ons%0A%0A//%20Toggle%20Restartless%20Add-ons%20button%20for%20Custom%20Buttons%0A//%20%28code%20for%20%22initialization%22%20section%29%0A//%20Also%20the%20code%20can%20be%20used%20from%20main%20window%20context%20%28as%20Mouse%20Gestures%20code%2C%20for%20example%29%0A%0A//%20Also%20you%20can%20check%20for%20add-ons%20updates%20using%20right-click%3A%0A//%20copy%20all%20code%20from%0A//%20https%3A//github.com/Infocatcher/Custom_Buttons/blob/master/Check_for_Addons_Updates/checkForAddonsUpdates.js%0A//%20after%20%22//%3D%3D%20Check%20for%20Addons%20Updates%20begin%22%0A%0A//%20See%20%22var%20style%20%3D%20%22%20to%20modify%20styles%20for%20specific%20add-ons%0A%0A//%20%28c%29%20Infocatcher%202013-2019%0A//%20version%200.1.3pre4%20-%202020-01-01%0A%0Avar%20options%20%3D%20%7B%0A%09addonTypes%3A%20%5B%22extension%22%2C%20%22plugin%22%5D%2C%0A%09//%20Possible%20values%3A%20%22extension%22%2C%20%22plugin%22%0A%09//%20From%20extensions%3A%20%22userstyle%22%20%28Stylish%29%2C%20%22greasemonkey-user-script%22%20%28Greasemonkey%29%2C%20%22userscript%22%20%28Scriptish%29%0A%09//%20%28swap%20to%20reorder%20in%20the%20menu%29%0A%09showVersions%3A%200%2C%0A%09//%200%20-%20don%27t%20show%20versions%0A%09//%201%20-%20show%20after%20name%3A%20%22Addon%20Name%201.2%22%0A%09//%202%20-%20show%20as%20%22acceltext%22%20%28in%20place%20for%20hotkey%20text%29%0A%09showHidden%3A%201%2C%0A%09//%200%20%20-%20don%27t%20show%20hidden%20add-ons%0A%09//%20-1%20-%20show%20only%20enabled%20hidden%20add-ons%20%28e.g.%20to%20track%20new%20items%29%0A%09//%201%20%20-%20show%20all%20hidden%20add-ons%0A%09sort%3A%20%7B%0A%09%09enabled%3A%20%20%20%20%200%2C%0A%09%09clickToPlay%3A%200%2C%0A%09%09disabled%3A%20%20%20%200%0A%09%09//%20Sort%20order%3A%0A%09%09//%200%2C%200%2C%200%20-%20sort%20add-ons%20of%20each%20type%20alphabetically%0A%09%09//%200%2C%200%2C%201%20-%20show%20enabled%20add-ons%20%28of%20each%20type%29%20first%0A%09%09//%200%2C%201%2C%202%20-%20enabled%20add-ons%2C%20then%20click-to-play%20and%20then%20disabled%0A%09%7D%2C%0A%09closeMenu%3A%20false%2C%20//%20Close%20menu%20after%20left-click%0A%09closeMenuClickToPlay%3A%20false%20//%20Close%20menu%20after%20left-click%2C%20for%20click%20to%20play%20plugins%0A%09//%20Use%20Shift+click%20to%20invert%20closeMenu*%20behavior%0A%7D%3B%0A%0Avar%20xulns%20%3D%20%22http%3A//www.mozilla.org/keymaster/gatekeeper/there.is.only.xul%22%3B%0A%0Avar%20mp%20%3D%20document.createElementNS%28xulns%2C%20%22menupopup%22%29%3B%0Amp.setAttribute%28%22onpopupshowing%22%2C%20%22this.updateMenu%28%29%3B%22%29%3B%0Amp.setAttribute%28%22oncommand%22%2C%20%22this.handleEvent%28event%29%3B%22%29%3B%0Amp.setAttribute%28%22onmousedown%22%2C%20%22if%28event.button%20%3D%3D%200%29%20this.handleEvent%28event%29%3B%22%29%3B%0Amp.setAttribute%28%22onclick%22%2C%20%22if%28event.button%20%3E%200%29%20this.handleEvent%28event%29%3B%22%29%3B%0Amp.setAttribute%28%22oncontextmenu%22%2C%20%22return%20false%3B%22%29%3B%0Amp.setAttribute%28%22onpopuphidden%22%2C%20%22this.destroyMenu%28%29%3B%22%29%3B%0A%0Avar%20tb%20%3D%20this.parentNode%3B%0Aif%28tb%20%26%26%20tb.getAttribute%28%22orient%22%29%20%3D%3D%20%22vertical%22%29%20%7B%0A%09//%20https%3A//addons.mozilla.org/firefox/addon/vertical-toolbar/%0A%09var%20isRight%20%3D%20tb.parentNode.getAttribute%28%22placement%22%29%20%3D%3D%20%22right%22%3B%0A%09mp.setAttribute%28%22position%22%2C%20isRight%20%3F%20%22start_before%22%20%3A%20%22end_before%22%29%3B%0A%7D%0A%0Avar%20cleanupTimer%20%3D%200%3B%0Amp.updateMenu%20%3D%20function%28%29%20%7B%0A%09clearTimeout%28cleanupTimer%29%3B%0A%09addStyle%28%29%3B%0A%09getRestartlessAddons%28options.addonTypes%2C%20function%28addons%29%20%7B%0A%09%09var%20df%20%3D%20document.createDocumentFragment%28%29%3B%0A%09%09var%20prevType%3B%0A%09%09function%20sortPosition%28addon%29%20%7B%0A%09%09%09if%28%22STATE_ASK_TO_ACTIVATE%22%20in%20AddonManager%20%26%26%20addon.userDisabled%20%3D%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%29%0A%09%09%09%09return%20options.sort.clickToPlay%3B%0A%09%09%09if%28addon.isActive%29%0A%09%09%09%09return%20options.sort.enabled%3B%0A%09%09%09return%20options.sort.disabled%3B%0A%09%09%7D%0A%09%09function%20key%28addon%29%20%7B%0A%09%09%09return%20options.addonTypes.indexOf%28addon.type%29%0A%09%09%09%09+%20%22%5Cn%22%20+%20sortPosition%28addon%29%0A%09%09%09%09+%20%22%5Cn%22%20+%20addon.name.toLowerCase%28%29%3B%0A%09%09%7D%0A%09%09addons.sort%28function%28a%2C%20b%29%20%7B%0A%09%09%09var%20ka%20%3D%20key%28a%29%3B%0A%09%09%09var%20kb%20%3D%20key%28b%29%3B%0A%09%09%09return%20ka%20%3D%3D%20kb%20%3F%200%20%3A%20ka%20%3C%20kb%20%3F%20-1%20%3A%201%3B%0A%09%09%7D%29.forEach%28function%28addon%29%20%7B%0A%09%09%09var%20type%20%3D%20addon.type%3B%0A%09%09%09if%28prevType%20%26%26%20type%20%21%3D%20prevType%29%0A%09%09%09%09df.appendChild%28document.createElementNS%28xulns%2C%20%22menuseparator%22%29%29%3B%0A%09%09%09prevType%20%3D%20type%3B%0A%09%09%09var%20icon%20%3D%20addon.iconURL%20%7C%7C%20addon.icon64URL%3B%0A%09%09%09var%20mi%20%3D%20document.createElementNS%28xulns%2C%20%22menuitem%22%29%3B%0A%09%09%09mi.className%20%3D%20%22menuitem-iconic%22%3B%0A%09%09%09var%20label%20%3D%20addon.name%3B%0A%09%09%09if%28options.showVersions%20%3D%3D%201%29%0A%09%09%09%09label%20+%3D%20%22%20%22%20+%20addon.version%3B%0A%09%09%09else%20if%28options.showVersions%20%3D%3D%202%29%0A%09%09%09%09mi.setAttribute%28%22acceltext%22%2C%20addon.version%29%3B%0A%09%09%09mi.setAttribute%28%22label%22%2C%20label%29%3B%0A%09%09%09mi.setAttribute%28%22image%22%2C%20icon%20%7C%7C%20mp.icons%5Btype%5D%20%7C%7C%20%22%22%29%3B%0A%09%09%09if%28%21icon%20%26%26%20mp.icons.useSVG%29%0A%09%09%09%09mi.style.fill%20%3D%20%22%2315c%22%3B%0A%09%09%09var%20tip%20%3D%20addon.description%20%7C%7C%20%22%22%3B%0A%09%09%09var%20delay%20%3D%20%22delayedStartupAddons%22%20in%20Services%0A%09%09%09%09%26%26%20Services.delayedStartupAddons%5Baddon.id%5D%20%7C%7C%20null%3B%0A%09%09%09var%20isDelayed%20%3D%20delay%20%21%3D%3D%20null%3B%0A%09%09%09mi.classList.toggle%28%22toggleRestartlessAddons-isDelayed%22%2C%20isDelayed%29%3B%0A%09%09%09if%28isDelayed%29%0A%09%09%09%09tip%20%3D%20%22%5BDelayed%20Startup%3A%20%22%20+%20delay.toLocaleString%28%29%20+%20%22%5D%22%20+%20%28tip%20%3F%20%22%5Cn%22%20+%20tip%20%3A%20%22%22%29%3B%0A%09%09%09tip%20%26%26%20mi.setAttribute%28%22tooltiptext%22%2C%20tip%29%3B%0A%09%09%09mi.classList.toggle%28%22toggleRestartlessAddons-isHidden%22%2C%20addon.hidden%20%7C%7C%20false%29%3B%0A%09%09%09setDisabled%28mi%2C%20addon.userDisabled%29%3B%0A%09%09%09mi._cbAddon%20%3D%20addon%3B%0A%09%09%09df.appendChild%28mi%29%3B%0A%09%09%7D%29%3B%0A%09%09mp.textContent%20%3D%20%22%22%3B%0A%09%09mp.appendChild%28df%29%3B%0A%09%7D%29%3B%0A%7D%3B%0Amp.handleEvent%20%3D%20function%28e%29%20%7B%0A%09var%20mi%20%3D%20e.target%3B%0A%09if%28%21%28%22_cbAddon%22%20in%20mi%29%29%0A%09%09return%3B%0A%09var%20addon%20%3D%20mi._cbAddon%3B%0A%09if%28e.type%20%3D%3D%20%22mousedown%22%29%20%7B%0A%09%09var%20closeMenu%20%3D%20isAskToActivateAddon%28addon%29%0A%09%09%09%3F%20options.closeMenuClickToPlay%0A%09%09%09%3A%20options.closeMenu%3B%0A%09%09if%28e.shiftKey%29%0A%09%09%09closeMenu%20%3D%20%21closeMenu%3B%0A%09%09mi.setAttribute%28%22closemenu%22%2C%20closeMenu%20%3F%20%22auto%22%20%3A%20%22none%22%29%3B%0A%09%09return%3B%0A%09%7D%0A%09var%20hasMdf%20%3D%20hasModifier%28e%29%3B%0A%09if%28e.type%20%3D%3D%20%22command%22%20%26%26%20%28%21hasMdf%20%7C%7C%20e.shiftKey%29%29%20%7B%0A%09%09let%20newDis%20%3D%20setNewDisabled%28addon%29%3B%0A%09%09setDisabled%28mi%2C%20newDis%29%3B%0A%09%7D%0A%09else%20if%28e.type%20%3D%3D%20%22command%22%20%26%26%20hasMdf%20%7C%7C%20e.type%20%3D%3D%20%22click%22%20%26%26%20e.button%20%3D%3D%201%29%20%7B%0A%09%09openAddonPage%28addon%29%3B%0A%09%09closeMenus%28mi%29%3B%0A%09%7D%0A%09else%20if%28e.type%20%3D%3D%20%22click%22%20%26%26%20e.button%20%3D%3D%202%29%20%7B%0A%09%09if%28openAddonOptions%28addon%29%29%0A%09%09%09closeMenus%28mi%29%3B%0A%09%7D%0A%7D%3B%0Amp.destroyMenu%20%3D%20function%28%29%20%7B%0A%09removeStyle%28%29%3B%0A%09clearTimeout%28cleanupTimer%29%3B%0A%09cleanupTimer%20%3D%20setTimeout%28function%28%29%20%7B%0A%09%09mp.textContent%20%3D%20%22%22%3B%0A%09%7D%2C%205000%29%3B%0A%7D%3B%0Amp.icons%20%3D%20%7B%0A%09get%20platformVersion%28%29%20%7B%0A%09%09delete%20this.platformVersion%3B%0A%09%09return%20this.platformVersion%20%3D%20parseFloat%28Services.appinfo.platformVersion%29%3B%0A%09%7D%2C%0A%09get%20useSVG%28%29%20%7B%0A%09%09delete%20this.useSVG%3B%0A%09%09return%20this.useSVG%20%3D%20Services.appinfo.name%20%3D%3D%20%22Firefox%22%20%26%26%20this.platformVersion%20%3E%3D%2057%3B%0A%09%7D%2C%0A%09get%20plugin%28%29%20%7B%0A%09%09delete%20this.plugin%3B%0A%09%09return%20this.plugin%20%3D%20this.useSVG%0A%09%09%09%3F%20this.platformVersion%20%3E%3D%2065%0A%09%09%09%09%3F%20%22chrome%3A//global/skin/plugins/pluginGeneric.svg%22%0A%09%09%09%09%3A%20%22chrome%3A//mozapps/skin/plugins/pluginGeneric.svg%22%0A%09%09%09%3A%20%22chrome%3A//mozapps/skin/plugins/pluginGeneric-16.png%22%3B%0A%09%7D%2C%0A%09get%20extension%28%29%20%7B%0A%09%09delete%20this.extension%3B%0A%09%09return%20this.extension%20%3D%20this.useSVG%0A%09%09%09%3F%20this.platformVersion%20%3E%3D%2076%0A%09%09%09%09%3F%20%22chrome%3A//mozapps/skin/extensions/extensionGeneric.svg%22%20//%20Or%20chrome%3A//mozapps/skin/extensions/extension.svg%0A%09%09%09%09%3A%20%22chrome%3A//mozapps/skin/extensions/extensionGeneric-16.svg%22%0A%09%09%09%3A%20%22chrome%3A//mozapps/skin/extensions/extensionGeneric-16.png%22%3B%0A%09%7D%0A%7D%3B%0Afunction%20isAskToActivateAddon%28addon%29%20%7B%0A%09return%20addon.type%20%3D%3D%20%22plugin%22%0A%09%09%26%26%20%22STATE_ASK_TO_ACTIVATE%22%20in%20AddonManager%0A%09%09%26%26%20Services.prefs.getBoolPref%28%22plugins.click_to_play%22%2C%20true%29%3B%0A%7D%0Afunction%20setNewDisabled%28addon%29%20%7B%0A%09var%20newDis%20%3D%20getNewDisabled%28addon%29%3B%0A%09var%20oldDis%20%3D%20addon.userDisabled%3B%0A%09try%20%7B%0A%09%09addon.userDisabled%20%3D%20newDis%3B%0A%09%7D%0A%09catch%28e%29%20%7B%20//%20Error%3A%20Cannot%20disable%20hidden%20add-on%20firefox@getpocket.com%0A%09%09_log%28%22Can%27t%20set%20addon.userDisabled%20to%20%22%20+%20newDis%20+%20%22%2C%20error%3A%5Cn%22%20+%20e%29%3B%0A%09%09if%28addon.hidden%29%0A%09%09%09setNewDisabledRaw%28addon%2C%20newDis%29%3B%0A%09%7D%0A%09var%20realDis%20%3D%20addon.userDisabled%3B%0A%09if%28realDis%20%21%3D%20newDis%20%26%26%20addon.type%20%3D%3D%20%22extension%22%29%20%7B%20//%20Firefox%2062+%3F%20Weird%20things%20happens%0A%09%09setNewDisabledRaw%28addon%2C%20newDis%29%3B%0A%09%09realDis%20%3D%20addon.userDisabled%3B%0A%09%7D%0A%09if%28realDis%20%21%3D%20newDis%29%20%7B%20//%20We%20can%27t%20enable%20vulnerable%20plugins%0A%09%09let%20err%20%3D%20%22Can%27t%20set%20addon.userDisabled%20to%20%22%20+%20newDis%20+%20%22%2C%20real%20value%3A%20%22%20+%20realDis%3B%0A%09%09if%28newDis%29%20%7B%0A%09%09%09_log%28err%20+%20%22%5CnSTATE_ASK_TO_ACTIVATE%20not%20supported%3F%22%29%3B%0A%09%09%09newDis%20%3D%20false%3B%0A%09%09%7D%0A%09%09else%20%7B%0A%09%09%09_log%28err%20+%20%22%5CnVulnerable%20plugin%3F%22%29%3B%0A%09%09%09if%28oldDis%20%3D%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%29%0A%09%09%09%09newDis%20%3D%20true%3B%0A%09%09%09else%0A%09%09%09%09newDis%20%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%3B%0A%09%09%7D%0A%09%09addon.userDisabled%20%3D%20newDis%3B%0A%09%7D%0A%09ensureSpecialDisabled%28addon%2C%20newDis%29%3B%0A%09return%20addon.userDisabled%3B%0A%7D%0Afunction%20getNewDisabled%28addon%29%20%7B%0A%09//%20disabled%20-%3E%20STATE_ASK_TO_ACTIVATE%20-%3E%20enabled%20-%3E%20...%0A%09var%20curDis%20%3D%20addon.userDisabled%3B%0A%09var%20newDis%3B%0A%09if%28%22STATE_ASK_TO_ACTIVATE%22%20in%20AddonManager%20%26%26%20curDis%20%3D%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%29%0A%09%09newDis%20%3D%20false%3B%0A%09else%20if%28%21curDis%29%0A%09%09newDis%20%3D%20true%3B%0A%09else%20%7B%0A%09%09if%28isAskToActivateAddon%28addon%29%29%0A%09%09%09newDis%20%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%3B%0A%09%09else%0A%09%09%09newDis%20%3D%20false%3B%0A%09%7D%0A%09return%20newDis%3B%0A%7D%0Afunction%20setNewDisabledRaw%28addon%2C%20newDis%29%20%7B%0A%09_log%28%22Let%27s%20try%20set%20addon.userDisabled%20using%20raw%20hack%22%29%3B%0A%09let%20g%20%3D%20Components.utils.import%28%22resource%3A//gre/modules/addons/XPIProvider.jsm%22%2C%20%7B%7D%29%3B%0A%09if%28%22XPIDatabase%22%20in%20g%20%26%26%20%22updateAddonDisabledState%22%20in%20g.XPIDatabase%29%20%7B%20//%20Firefox%2061+%0A%09%09let%20rawAddon%20%3D%20g.XPIDatabase.getAddons%28%29.find%28function%28rawAddon%29%20%7B%0A%09%09%09return%20rawAddon.id%20%3D%3D%20addon.id%3B%0A%09%09%7D%29%3B%0A%09%09g.XPIDatabase.updateAddonDisabledState%28%0A%09%09%09rawAddon%2C%0A%09%09%09g.XPIDatabase.updateAddonDisabledState.length%20%3D%3D%201%20//%20Firefox%2074+%0A%09%09%09%09%3F%20%7B%20userDisabled%3A%20newDis%20%7D%0A%09%09%09%09%3A%20newDis%0A%09%09%29%3B%0A%09%7D%0A%09else%20if%28%22eval%22%20in%20g%29%20%7B%20//%20See%20%22set%20userDisabled%28val%29%22%0A%09%09let%20addonFor%20%3D%20g.eval%28%22addonFor%22%29%3B%0A%09%09let%20rawAddon%20%3D%20addonFor%28addon%29%3B%0A%09%09//rawAddon.userDisabled%20%3D%20newDis%3B%0A%09%09g.XPIProvider.updateAddonDisabledState%28rawAddon%2C%20newDis%29%3B%0A%09%7D%0A%09else%20%7B%20//%20Firefox%2057+%3F%20See%20https%3A//forum.mozilla-russia.org/viewtopic.php%3Fpid%3D745272%23p745272%0A%09%09updateAddonDisabledState%28addon%2C%20newDis%29%3B%0A%09%7D%0A%7D%0Afunction%20updateAddonDisabledState%28addon%2C%20newDis%29%20%7B%0A%09var%20nsvo%20%3D%20Components.utils.import%28%22resource%3A//gre/modules/addons/XPIProvider.jsm%22%2C%20%7B%7D%29%3B%0A%09var%20key%20%3D%20%22_cbToggleRestartlessAddonsData%22%3B%0A%09var%20url%20%3D%20URL.createObjectURL%28new%20Blob%28%5B%0A%09%09%22XPIProvider.updateAddonDisabledState%28addonFor%28this.%22%20+%20key%20+%20%22%5B0%5D%29%2C%20this.%22%20+%20key%20+%20%22%5B1%5D%29%3B%20delete%20this.%22%20+%20key%20+%20%22%3B%22%0A%09%5D%29%29%3B%0A%09addDestructor%28function%28%29%20%7B%0A%09%09URL.revokeObjectURL%28url%29%3B%0A%09%7D%29%3B%0A%09%28updateAddonDisabledState%20%3D%20function%28addon%2C%20newDis%29%20%7B%0A%09%09nsvo%5Bkey%5D%20%3D%20%5Baddon%2C%20newDis%5D%3B%0A%09%09Services.scriptloader.loadSubScript%28url%2C%20nsvo%29%3B%0A%09%7D%29%28addon%2C%20newDis%29%3B%0A%7D%0Afunction%20setDisabled%28mi%2C%20disabled%29%20%7B%0A%09var%20askToActivate%20%3D%20%22STATE_ASK_TO_ACTIVATE%22%20in%20AddonManager%20%26%26%20disabled%20%3D%3D%20AddonManager.STATE_ASK_TO_ACTIVATE%3B%0A%09var%20cl%20%3D%20mi.classList%3B%0A%09cl.toggle%28%22toggleRestartlessAddons-askToActivate%22%2C%20askToActivate%29%3B%0A%09cl.toggle%28%22toggleRestartlessAddons-disabled%22%2C%20disabled%20%26%26%20%21askToActivate%29%3B%0A%7D%0Afunction%20ensureSpecialDisabled%28addon%2C%20newDis%29%20%7B%0A%09if%28addon.id%20%3D%3D%20%22screenshots@mozilla.org%22%29%0A%09%09Services.prefs.setBoolPref%28%22extensions.screenshots.disabled%22%2C%20newDis%29%3B%0A%7D%0A%0Aif%28%0A%09this%20instanceof%20XULElement%20//%20Custom%20Buttons%0A%09%26%26%20typeof%20event%20%3D%3D%20%22object%22%0A%09%26%26%20%21%28%22type%22%20in%20event%29%20%26%26%20typeof%20_phase%20%3D%3D%20%22string%22%20%26%26%20_phase%20%3D%3D%20%22init%22%20//%20Initialization%0A%29%20%7B%0A%09this.type%20%3D%20%22menu%22%3B%0A%09this.orient%20%3D%20%22horizontal%22%3B%0A%09this.appendChild%28mp%29%3B%0A%0A%09this.onmouseover%20%3D%20function%28e%29%20%7B%0A%09%09if%28e.target%20%21%3D%20this%29%0A%09%09%09return%3B%0A%09%09Array.prototype.some.call%28%0A%09%09%09this.parentNode.getElementsByTagName%28%22*%22%29%2C%0A%09%09%09function%28node%29%20%7B%0A%09%09%09%09if%28%0A%09%09%09%09%09node%20%21%3D%20this%0A%09%09%09%09%09%26%26%20node.namespaceURI%20%3D%3D%20xulns%0A%09%09%09%09%09//%20See%20https%3A//github.com/Infocatcher/Custom_Buttons/issues/28%0A%09%09%09%09%09//%26%26%20node.boxObject%0A%09%09%09%09%09//%26%26%20node.boxObject%20instanceof%20Components.interfaces.nsIMenuBoxObject%0A%09%09%09%09%09%26%26%20%22open%22%20in%20node%0A%09%09%09%09%09%26%26%20node.open%0A%09%09%09%09%09%26%26%20node.getElementsByTagName%28%22menupopup%22%29.length%0A%09%09%09%09%29%20%7B%0A%09%09%09%09%09node.open%20%3D%20false%3B%0A%09%09%09%09%09this.open%20%3D%20true%3B%0A%09%09%09%09%09return%20true%3B%0A%09%09%09%09%7D%0A%09%09%09%09return%20false%3B%0A%09%09%09%7D%2C%0A%09%09%09this%0A%09%09%29%3B%0A%09%7D%3B%0A%09this.onmousedown%20%3D%20function%28e%29%20%7B%0A%09%09if%28e.target%20%3D%3D%20this%20%26%26%20e.button%20%3D%3D%200%20%26%26%20hasModifier%28e%29%29%0A%09%09%09e.preventDefault%28%29%3B%0A%09%7D%3B%0A%09this.oncontextmenu%20%3D%20function%28e%29%20%7B%0A%09%09if%28e.target%20%3D%3D%20this%20%26%26%20%21hasModifier%28e%29%20%26%26%20hasUpdater%28%29%29%0A%09%09%09e.preventDefault%28%29%3B%0A%09%7D%3B%0A%09this.onclick%20%3D%20function%28e%29%20%7B%0A%09%09if%28e.target%20%21%3D%20this%29%0A%09%09%09return%3B%0A%09%09if%28e.button%20%3D%3D%200%20%26%26%20hasModifier%28e%29%20%7C%7C%20e.button%20%3D%3D%201%29%0A%09%09%09openAddonsManager%28%29%3B%0A%09%09else%20if%28e.button%20%3D%3D%202%20%26%26%20%21hasModifier%28e%29%20%26%26%20hasUpdater%28%29%29%0A%09%09%09checkForAddonsUpdates.call%28this%29%3B%0A%09%7D%3B%0A%7D%0Aelse%20%7B%20//%20Mouse%20gestures%20or%20something%20other...%0A%09let%20e%3B%0A%09if%28typeof%20event%20%3D%3D%20%22object%22%20%26%26%20event%20instanceof%20Event%20%26%26%20%22screenX%22%20in%20event%29%20//%20FireGestures%0A%09%09e%20%3D%20event%3B%0A%09else%20if%28%0A%09%09this%20instanceof%20Components.interfaces.nsIDOMChromeWindow%0A%09%09%26%26%20%22mgGestureState%22%20in%20window%20%26%26%20%22endEvent%22%20in%20mgGestureState%20//%20Mouse%20Gestures%20Redox%0A%09%29%0A%09%09e%20%3D%20mgGestureState.endEvent%3B%0A%09else%20%7B%0A%09%09let%20anchor%20%3D%20this%20instanceof%20XULElement%20%26%26%20this%0A%09%09%09%7C%7C%20window.gBrowser%20%26%26%20gBrowser.selectedBrowser%0A%09%09%09%7C%7C%20document.documentElement%3B%0A%09%09if%28%22boxObject%22%20in%20anchor%29%20%7B%0A%09%09%09let%20bo%20%3D%20anchor.boxObject%3B%0A%09%09%09e%20%3D%20%7B%0A%09%09%09%09screenX%3A%20bo.screenX%2C%0A%09%09%09%09screenY%3A%20bo.screenY%0A%09%09%09%7D%3B%0A%09%09%09if%28this%20instanceof%20XULElement%29%0A%09%09%09%09e.screenY%20+%3D%20bo.height%3B%0A%09%09%7D%0A%09%7D%0A%09if%28%21e%20%7C%7C%20%21%28%22screenX%22%20in%20e%29%29%0A%09%09throw%20new%20Error%28%22%5BToggle%20Restartless%20Add-ons%5D%3A%20Can%27t%20get%20event%20object%22%29%3B%0A%09document.documentElement.appendChild%28mp%29%3B%0A%09mp.addEventListener%28%22popuphidden%22%2C%20function%20destroy%28e%29%20%7B%0A%09%09mp.removeEventListener%28e.type%2C%20destroy%2C%20false%29%3B%0A%09%09setTimeout%28function%28%29%20%7B%0A%09%09%09mp.destroyMenu%28%29%3B%0A%09%09%09mp.parentNode.removeChild%28mp%29%3B%0A%09%09%7D%2C%200%29%3B%0A%09%7D%2C%20false%29%3B%0A%09mp.openPopupAtScreen%28e.screenX%2C%20e.screenY%29%3B%0A%7D%0A%0Afunction%20getRestartlessAddons%28addonTypes%2C%20callback%2C%20context%29%20%7B%0A%09if%28%21%28%22AddonManager%22%20in%20window%29%29%0A%09%09Components.utils.import%28%22resource%3A//gre/modules/AddonManager.jsm%22%29%3B%0A%09if%28%21%28%22Services%22%20in%20window%29%29%0A%09%09Components.utils.import%28%22resource%3A//gre/modules/Services.jsm%22%29%3B%0A%09var%20then%2C%20promise%20%3D%20AddonManager.getAddonsByTypes%28addonTypes%2C%20then%20%3D%20function%28addons%29%20%7B%0A%09%09callback.call%28context%2C%20addons.filter%28function%28addon%29%20%7B%0A%09%09%09var%20ops%20%3D%20addon.operationsRequiringRestart%3B%0A%09%09%09return%20%21addon.appDisabled%0A%09%09%09%09%26%26%20%21%28ops%20%26%20AddonManager.OP_NEEDS_RESTART_ENABLE%20%7C%7C%20ops%20%26%20AddonManager.OP_NEEDS_RESTART_DISABLE%29%0A%09%09%09%09%26%26%20%28%0A%09%09%09%09%09%21addon.hidden%0A%09%09%09%09%09%7C%7C%20options.showHidden%20%3E%200%0A%09%09%09%09%09%7C%7C%20options.showHidden%20%3D%3D%20-1%20%26%26%20%21addon.userDisabled%0A%09%09%09%09%29%0A%09%09%09%09%26%26%20%28addon.iconURL%20%7C%7C%20%22%22%29.substr%280%2C%2029%29%20%21%3D%20%22resource%3A//search-extensions/%22%3B%0A%09%09%7D%29%29%3B%0A%09%7D%29%3B%0A%09promise%20%26%26%20typeof%20promise.then%20%3D%3D%20%22function%22%20%26%26%20promise.then%28then%2C%20Components.utils.reportError%29%3B%20//%20Firefox%2061+%0A%7D%0Afunction%20openAddonOptions%28addon%29%20%7B%0A%09//%20Based%20on%20code%20from%20chrome%3A//mozapps/content/extensions/extensions.js%0A%09//%20Firefox%2021.0a1%20%282013-01-27%29%0A%09var%20optionsURL%20%3D%20addon.optionsURL%3B%0A%09if%28%21addon.isActive%20%7C%7C%20%21optionsURL%29%0A%09%09return%20false%3B%0A%09if%28addon.type%20%3D%3D%20%22plugin%22%29%20//%20No%20options%20for%20now%21%0A%09%09return%20false%3B%0A%09if%28%0A%09%09addon.optionsType%20%3D%3D%20%28AddonManager.OPTIONS_TYPE_INLINE%20%7C%7C%20NaN%29%0A%09%09%7C%7C%20addon.optionsType%20%3D%3D%20%28AddonManager.OPTIONS_TYPE_INLINE_INFO%20%7C%7C%20NaN%29%0A%09%09%7C%7C%20addon.optionsType%20%3D%3D%20%28AddonManager.OPTIONS_TYPE_INLINE_BROWSER%20%7C%7C%20NaN%29%0A%09%29%0A%09%09openAddonPage%28addon%2C%20true%29%3B%0A%09else%20if%28addon.optionsType%20%3D%3D%20AddonManager.OPTIONS_TYPE_TAB%20%26%26%20%22switchToTabHavingURI%22%20in%20window%29%0A%09%09switchToTabHavingURI%28optionsURL%2C%20true%29%3B%0A%09else%20%7B%0A%09%09let%20windows%20%3D%20Services.wm.getEnumerator%28null%29%3B%0A%09%09while%28windows.hasMoreElements%28%29%29%20%7B%0A%09%09%09let%20win%20%3D%20windows.getNext%28%29%3B%0A%09%09%09if%28win.document.documentURI%20%3D%3D%20optionsURL%29%20%7B%0A%09%09%09%09win.focus%28%29%3B%0A%09%09%09%09return%20true%3B%0A%09%09%09%7D%0A%09%09%7D%0A%09%09//%20Note%3A%20original%20code%20checks%20browser.preferences.instantApply%20and%20may%20open%20modal%20windows%0A%09%09window.openDialog%28optionsURL%2C%20%22%22%2C%20%22chrome%2Ctitlebar%2Ctoolbar%2Ccenterscreen%2Cdialog%3Dno%22%29%3B%0A%09%7D%0A%09return%20true%3B%0A%7D%0Afunction%20openAddonsManager%28view%29%20%7B%0A%09var%20openAddonsMgr%20%3D%20window.BrowserOpenAddonsMgr%20//%20Firefox%0A%09%09%7C%7C%20window.openAddonsMgr%20//%20Thunderbird%0A%09%09%7C%7C%20window.toEM%3B%20//%20SeaMonkey%0A%09openAddonsMgr%28view%29%3B%0A%7D%0Afunction%20openAddonPage%28addon%2C%20scrollToPreferences%29%20%7B%0A%09var%20platformVersion%20%3D%20parseFloat%28%0A%09%09Services.appinfo.name%20%3D%3D%20%22Pale%20Moon%22%0A%09%09%09%3F%20Services.appinfo.version%0A%09%09%09%3A%20Services.appinfo.platformVersion%0A%09%29%3B%0A%09scrollToPreferences%20%3D%20scrollToPreferences%20%26%26%20platformVersion%20%3E%3D%2012%0A%09%09%3F%20%22/preferences%22%0A%09%09%3A%20%22%22%3B%0A%09openAddonsManager%28%22addons%3A//detail/%22%20+%20encodeURIComponent%28addon.id%29%20+%20scrollToPreferences%29%3B%0A%7D%0A%0Afunction%20hasModifier%28e%29%20%7B%0A%09return%20e.ctrlKey%20%7C%7C%20e.shiftKey%20%7C%7C%20e.altKey%20%7C%7C%20e.metaKey%3B%0A%7D%0A%0Afunction%20addStyle%28%29%20%7B%0A%09if%28addStyle.hasOwnProperty%28%22_style%22%29%29%0A%09%09return%3B%0A%09var%20style%20%3D%20%27%5C%0A%09%09.toggleRestartlessAddons-isDelayed%20%3E%20.menu-iconic-text%20%7B%5Cn%5C%0A%09%09%09opacity%3A%200.75%3B%5Cn%5C%0A%09%09%09color%3A%20%23070%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%09.toggleRestartlessAddons-isHidden%20%3E%20.menu-iconic-text%20%7B%5Cn%5C%0A%09%09%09color%3A%20%23609%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%09.toggleRestartlessAddons-disabled%20%3E%20.menu-iconic-left%20%7B%5Cn%5C%0A%09%09%09opacity%3A%200.4%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%09.toggleRestartlessAddons-disabled%20%3E%20.menu-iconic-text%2C%5Cn%5C%0A%09%09.toggleRestartlessAddons-disabled%20%3E%20.menu-accel-container%20%7B%5Cn%5C%0A%09%09%09opacity%3A%200.5%3B%5Cn%5C%0A%09%09%7D%5Cn%5C%0A%09%09.toggleRestartlessAddons-askToActivate%20%7B%5Cn%5C%0A%09%09%09color%3A%20-moz-nativehyperlinktext%3B%5Cn%5C%0A%09%09%7D%27%3B%0A%09addStyle._style%20%3D%20document.insertBefore%28%0A%09%09document.createProcessingInstruction%28%0A%09%09%09%22xml-stylesheet%22%2C%0A%09%09%09%27href%3D%22%27%20+%20%22data%3Atext/css%2C%22%0A%09%09%09%09+%20encodeURIComponent%28style%29%20+%20%27%22%20type%3D%22text/css%22%27%0A%09%09%29%2C%0A%09%09document.documentElement%0A%09%29%3B%0A%7D%0Afunction%20removeStyle%28%29%20%7B%0A%09if%28%21addStyle.hasOwnProperty%28%22_style%22%29%29%0A%09%09return%3B%0A%09var%20s%20%3D%20addStyle._style%3B%0A%09s.parentNode.removeChild%28s%29%3B%0A%09delete%20addStyle._style%3B%0A%7D%0Afunction%20closeMenus%28node%29%20%7B%0A%09//%20Based%20on%20function%20closeMenus%20from%20chrome%3A//browser/content/utilityOverlay.js%0A%09for%28%3B%20node%20%26%26%20%22tagName%22%20in%20node%3B%20node%20%3D%20node.parentNode%29%20%7B%0A%09%09if%28%0A%09%09%09node.namespaceURI%20%3D%3D%20%22http%3A//www.mozilla.org/keymaster/gatekeeper/there.is.only.xul%22%0A%09%09%09%26%26%20%28node.localName%20%3D%3D%20%22menupopup%22%20%7C%7C%20node.localName%20%3D%3D%20%22popup%22%29%0A%09%09%29%0A%09%09%09node.hidePopup%28%29%3B%0A%09%7D%0A%7D%0Afunction%20_log%28s%29%20%7B%0A%09if%28typeof%20LOG%20%3D%3D%20%22function%22%29%20//%20Custom%20Buttons%0A%09%09LOG%28s%29%3B%0A%09else%20//%20Or%20something%20else%0A%09%09Services.console.logStringMessage%28%22Toggle%20Restartless%20Add-ons%3A%20%22%20+%20s%29%3B%0A%7D%0A%0Afunction%20hasUpdater%28%29%20%7B%0A%09var%20has%20%3D%20checkForAddonsUpdates.toString%28%29.indexOf%28%22about%3Aaddons%22%29%20%21%3D%20-1%3B%0A%09hasUpdater%20%3D%20function%28%29%20%7B%0A%09%09return%20has%3B%0A%09%7D%3B%0A%09return%20has%3B%0A%7D%0Afunction%20checkForAddonsUpdates%28%29%20%7B%0A//%3D%3D%20Check%20for%20Addons%20Updates%20begin%0A%0A//%3D%3D%20Check%20for%20Addons%20Updates%20end%0A%7D%0A%0A%0A%5D%5D%3E%3C/initcode%3E%0A%20%20%3Ccode%3E%3C%21%5BCDATA%5B%20%0A%0A%0A%0A%0A%0A%5D%5D%3E%3C/code%3E%0A%20%20%3Caccelkey%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/accelkey%3E%0A%20%20%3Chelp%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/help%3E%0A%20%20%3Cattributes/%3E%0A%3C/custombutton%3E |
Garalf > 04-03-2021 11:17:47 |
На 87 обновления не работают |
Dumby > 04-03-2021 12:37:31 |
Garalf Там образуется петля, а это нехорошо, скрытый текст Выделить код Код:/* if(!vb) { win.setTimeout(processAddonsTab, 20, win); return; } */ if(!vb) { if(HTMLHtmlElement.isInstance(doc.documentElement)) vb = browser; else { win.setTimeout(processAddonsTab, 20, win); return; } } |
Garalf > 05-03-2021 13:02:43 |
Dumby |
Infocatcher > 28-03-2021 00:08:41 |
Dumby пишет
Уфф, добрался… обновил, огромное спасибо! |
_zt > 28-03-2021 03:00:34 |
Упс. На что то старое отвечал. DEL |
momo2000 > 12-07-2021 16:44:01 |
СКМ по расширению в списке стал вкл/выкл расширение. |
Infocatcher > 12-07-2021 21:23:36 |
momo2000 пишет
Какие-то новые обратно-несовместимые улучшения: https://bugzilla.mozilla.org/show_bug.cgi?id=1704948
Вот это вообще эпично: не понимаю, зачем ради расширений ломать вообще все меню. https://bugzilla.mozilla.org/show_bug.cgi?id=1469148 12-07-2021 21:26:27 12-07-2021 21:32:03 |
Garalf > 18-05-2023 19:59:10 |
Dumby |