From 4091cd3a1d45fe58bdf834dbaa4febd010c64f4a Mon Sep 17 00:00:00 2001 From: AlexVallat Date: Fri, 24 Apr 2015 18:57:30 +0100 Subject: [PATCH 1/5] Imported https://github.com/AlexVallat/uBlock/commit/5ac4ec21e9e960346b72889e842dbb6b0772aa76 --- .../firefox/css/legacy-toolbar-button.css | 37 ++ .../firefox/img/browsericons/icon32-off.svg | 12 + platform/firefox/img/browsericons/icon32.svg | 12 + platform/firefox/vapi-background.js | 316 ++++++++++++++++-- platform/firefox/vapi-common.js | 17 +- 5 files changed, 355 insertions(+), 39 deletions(-) create mode 100644 platform/firefox/css/legacy-toolbar-button.css create mode 100644 platform/firefox/img/browsericons/icon32-off.svg create mode 100644 platform/firefox/img/browsericons/icon32.svg diff --git a/platform/firefox/css/legacy-toolbar-button.css b/platform/firefox/css/legacy-toolbar-button.css new file mode 100644 index 000000000..2e2f34505 --- /dev/null +++ b/platform/firefox/css/legacy-toolbar-button.css @@ -0,0 +1,37 @@ +#uBlock-legacy-button { + list-style-image: url('../img/browsericons/icon32.svg'); +} +#uBlock-legacy-button.off { + list-style-image: url('../img/browsericons/icon32-off.svg'); +} + +toolbar[iconsize="small"] #uBlock-legacy-button { + list-style-image: url('../img/browsericons/icon16.svg'); +} +toolbar[iconsize="small"] #uBlock-legacy-button.off { + list-style-image: url('../img/browsericons/icon16-off.svg'); +} +#uBlock-legacy-button[badge]::before { + position: fixed; + margin-top: -2px; + padding: 1px 2px; + font-size: 9px; + font-weight: bold; + color: #fff; + background: #666; + content: attr(badge); +} +/* This hack required because if the before content changes it de-pops the popup (without firing any events). So just hide it instead. Note, can't actually *hide* it, or the same thing happens. '*/ +#uBlock-legacy-button[badge=""]::before { + padding: 0; +} + +/* Override off state when in palette */ +toolbarpaletteitem #uBlock-legacy-button.off { + list-style-image: url('../img/browsericons/icon32.svg'); +} + +/* Override badge when in palette */ +toolbarpaletteitem #uBlock-legacy-button[badge]::before { + content: none; +} \ No newline at end of file diff --git a/platform/firefox/img/browsericons/icon32-off.svg b/platform/firefox/img/browsericons/icon32-off.svg new file mode 100644 index 000000000..0b9030845 --- /dev/null +++ b/platform/firefox/img/browsericons/icon32-off.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/platform/firefox/img/browsericons/icon32.svg b/platform/firefox/img/browsericons/icon32.svg new file mode 100644 index 000000000..e70d65a3a --- /dev/null +++ b/platform/firefox/img/browsericons/icon32.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index 1ca8b737e..fecac3554 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -59,6 +59,11 @@ vAPI.app.restart = function() { /******************************************************************************/ +// Set default preferences for user to find in about:config +vAPI.localStorage.setDefaultBool("forceLegacyToolbarButton", false); + +/******************************************************************************/ + // List of things that needs to be destroyed when disabling the extension // Only functions should be added to it @@ -68,8 +73,8 @@ var cleanupTasks = []; // Fixed by github.com/AlexVallat: // https://github.com/AlexVallat/uBlock/commit/7b781248f00cbe3d61b1cc367c440db80fa06049 -// 8 instances of cleanupTasks.push, but one is unique to fennec, and one to desktop. -var expectedNumberOfCleanups = 7; +// several instances of cleanupTasks.push, but one is unique to fennec, and three to desktop. +var expectedNumberOfCleanups = vAPI.fennec ? 7 : 9; window.addEventListener('unload', function() { if ( typeof vAPI.app.onShutdown === 'function' ) { @@ -479,6 +484,88 @@ vAPI.storage = (function() { /******************************************************************************/ +var windowWatcher = { + onReady: function(e) { + if ( e ) { + this.removeEventListener(e.type, windowWatcher.onReady); + } + + var wintype = this.document.documentElement.getAttribute('windowtype'); + + if ( wintype !== 'navigator:browser' ) { + return; + } + + var attachToTabBrowser = function(window, tabBrowser) { + if (!tabBrowser) { + return; + } + + var tabContainer; + if ( tabBrowser.deck ) { + // Fennec + tabContainer = tabBrowser.deck; + } else if ( tabBrowser.tabContainer ) { + // desktop Firefox + tabContainer = tabBrowser.tabContainer; + vAPI.contextMenu.register(window.document); + if (vAPI.toolbarButton.attachToNewWindow) { + vAPI.toolbarButton.attachToNewWindow(window); + } + } else { + return; + } + + tabContainer.addEventListener('TabClose', tabWatcher.onTabClose); + tabContainer.addEventListener('TabSelect', tabWatcher.onTabSelect); + // when new window is opened TabSelect doesn't run on the selected tab? + } + + var win = this; + var tabBrowser = getTabBrowser(win); + if ( !tabBrowser ) { + // On some platforms, the tab browser isn't immediately available, try waiting a bit + win.setTimeout(function() { + attachToTabBrowser(win, getTabBrowser(win)); + }, 250); + } else { + attachToTabBrowser(win, tabBrowser); + } + + }, + + observe: function(win, topic) { + if ( topic === 'domwindowopened' ) { + win.addEventListener('DOMContentLoaded', this.onReady); + } + } +}; + +/******************************************************************************/ + +var tabWatcher = { + onTabClose: function({target}) { + // target is tab in Firefox, browser in Fennec + var tabId = vAPI.tabs.getTabId(target); + vAPI.tabs.onClosed(tabId); + delete vAPI.toolbarButton.tabs[tabId]; + }, + + onTabSelect: function({target}) { + vAPI.setIcon(vAPI.tabs.getTabId(target), getOwnerWindow(target)); + }, +}; + +/******************************************************************************/ + +vAPI.isBehindTheSceneTabId = function(tabId) { + return tabId.toString() === '-1'; +}; + +vAPI.noTabId = '-1'; + +/******************************************************************************/ + var getTabBrowser = function(win) { return vAPI.fennec && win.BrowserApp || win.gBrowser || null; }; @@ -1846,13 +1933,141 @@ vAPI.toolbarButton.init = function() { return; } + vAPI.messaging.globalMessageManager.addMessageListener( + location.host + ':closePopup', + vAPI.toolbarButton.onPopupCloseRequested + ); + + cleanupTasks.push(function() { + vAPI.messaging.globalMessageManager.removeMessageListener( + location.host + ':closePopup', + vAPI.toolbarButton.onPopupCloseRequested + ); + }); + var CustomizableUI; + + var forceLegacyToolbarButton = vAPI.localStorage.getBool("forceLegacyToolbarButton"); + if (!forceLegacyToolbarButton) { try { CustomizableUI = Cu.import('resource:///modules/CustomizableUI.jsm', null).CustomizableUI; } catch (ex) { + } + } + + if (!CustomizableUI) { + // Create a fallback non-customizable UI button + var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); + var styleSheetUri = Services.io.newURI(vAPI.getURL("css/legacy-toolbar-button.css"), null, null); + var legacyButtonId = "uBlock-legacy-button"; // NOTE: must match legacy-toolbar-button.css + this.id = legacyButtonId; + this.viewId = legacyButtonId + "-panel"; + + if (!sss.sheetRegistered(styleSheetUri, sss.AUTHOR_SHEET)) { + sss.loadAndRegisterSheet(styleSheetUri, sss.AUTHOR_SHEET); // Register global so it works in all windows, including palette + } + + var addLegacyToolbarButton = function(window) { + var document = window.document; + var toolbox = document.getElementById('navigator-toolbox') || document.getElementById('mail-toolbox'); + + if (toolbox) { + var palette = toolbox.palette; + + if (!palette) { + // palette might take a little longer to appear on some platforms, give it a small delay and try again + window.setTimeout(function() { + if (toolbox.palette) { + addLegacyToolbarButton(window); + } + }, 250); return; } + var toolbarButton = document.createElement('toolbarbutton'); + toolbarButton.setAttribute('id', legacyButtonId); + toolbarButton.setAttribute('type', 'panel'); + toolbarButton.setAttribute('removable', 'true'); + toolbarButton.setAttribute('class', 'toolbarbutton-1 chromeclass-toolbar-additional'); + toolbarButton.setAttribute('label', vAPI.toolbarButton.label); + + var toolbarButtonPanel = document.createElement("panel"); + toolbarButtonPanel.setAttribute('level', 'parent'); + vAPI.toolbarButton.populatePanel(document, toolbarButtonPanel); + toolbarButtonPanel.addEventListener('popupshowing', vAPI.toolbarButton.onViewShowing); + toolbarButtonPanel.addEventListener('popuphiding', vAPI.toolbarButton.onViewHiding); + toolbarButton.appendChild(toolbarButtonPanel); + + palette.appendChild(toolbarButton); + + vAPI.toolbarButton.closePopup = function() { + toolbarButtonPanel.hidePopup(); + } + + if (!vAPI.localStorage.getBool('legacyToolbarButtonAdded')) { + // No button yet so give it a default location. If forcing the button, just put in in the palette rather than on any specific toolbar (who knows what toolbars will be available or visible!) + var toolbar = !forceLegacyToolbarButton && document.getElementById('nav-bar'); + if (toolbar) { + toolbar.appendChild(toolbarButton); + toolbar.setAttribute('currentset', toolbar.currentSet); + document.persist(toolbar.id, 'currentset'); + } + vAPI.localStorage.setBool('legacyToolbarButtonAdded', 'true'); + } else { + // Find the place to put the button + var toolbars = toolbox.externalToolbars.slice(); + for (var child of toolbox.children) { + if (child.localName === 'toolbar') { + toolbars.push(child); + } + } + + for (var toolbar of toolbars) { + var currentsetString = toolbar.getAttribute('currentset'); + if (currentsetString) { + var currentset = currentsetString.split(','); + var index = currentset.indexOf(legacyButtonId); + if (index >= 0) { + // Found our button on this toolbar - but where on it? + var before = null; + for (var i = index + 1; i < currentset.length; i++) { + before = document.getElementById(currentset[i]); + if (before) { + toolbar.insertItem(legacyButtonId, before); + break; + } + } + if (!before) { + toolbar.insertItem(legacyButtonId); + } + } + } + } + } + } + } + + vAPI.toolbarButton.attachToNewWindow = function(win) { + addLegacyToolbarButton(win); + } + + cleanupTasks.push(function() { + for ( var win of vAPI.tabs.getWindows() ) { + var toolbarButton = win.document.getElementById(legacyButtonId); + if (toolbarButton) { + toolbarButton.parentNode.removeChild(toolbarButton); + } + } + + if (sss.sheetRegistered(styleSheetUri, sss.AUTHOR_SHEET)) { + sss.unregisterSheet(styleSheetUri, sss.AUTHOR_SHEET); + } + }.bind(this)); + return; + } + + this.CustomizableUI = CustomizableUI; + this.defaultArea = CustomizableUI.AREA_NAVBAR; this.styleURI = [ '#' + this.id + '.off {', @@ -1957,17 +2172,14 @@ vAPI.toolbarButton.init = function() { null ); - this.closePopup = function({target}) { + this.closePopup = function(tabBrowser) { CustomizableUI.hidePanelForNode( - target.ownerDocument.getElementById(vAPI.toolbarButton.viewId) + tabBrowser.ownerDocument.getElementById(vAPI.toolbarButton.viewId) ); }; CustomizableUI.createWidget(this); - vAPI.messaging.globalMessageManager.addMessageListener( - location.host + ':closePopup', - this.closePopup - ); + cleanupTasks.push(function() { if ( this.CUIEvents ) { @@ -1975,11 +2187,7 @@ vAPI.toolbarButton.init = function() { } CustomizableUI.destroyWidget(this.id); - vAPI.messaging.globalMessageManager.removeMessageListener( - location.host + ':closePopup', - this.closePopup - ); - + for ( var win of vAPI.tabs.getWindows() ) { var panel = win.document.getElementById(this.viewId); panel.parentNode.removeChild(panel); @@ -1994,35 +2202,66 @@ vAPI.toolbarButton.init = function() { /******************************************************************************/ +vAPI.toolbarButton.onPopupCloseRequested = function({target}) { + if (vAPI.toolbarButton.closePopup) { + vAPI.toolbarButton.closePopup(target); + } +} + +/******************************************************************************/ + vAPI.toolbarButton.onBeforeCreated = function(doc) { var panel = doc.createElement('panelview'); + + vAPI.toolbarButton.populatePanel(doc, panel); + + doc.getElementById('PanelUI-multiView').appendChild(panel); + + doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .loadSheet(this.styleURI, 1); +}; + +vAPI.toolbarButton.populatePanel = function(doc, panel) { panel.setAttribute('id', this.viewId); var iframe = doc.createElement('iframe'); iframe.setAttribute('type', 'content'); - doc.getElementById('PanelUI-multiView') - .appendChild(panel) - .appendChild(iframe); + panel.appendChild(iframe); var updateTimer = null; - var delayedResize = function() { + var delayedResize = function(attempts) { if ( updateTimer ) { return; } - updateTimer = vAPI.setTimeout(resizePopup, 10); - }; - var resizePopup = function() { + // Sanity check + attempts = (attempts || 0) + 1; + if (attempts > 1000) { + console.error('uBlock> delayedResize: giving up after too many attemps'); + return; + } + + updateTimer = vAPI.setTimeout(resizePopup, 10, attempts); }; + var resizePopup = function(attempts) { updateTimer = null; var body = iframe.contentDocument.body; panel.parentNode.style.maxWidth = 'none'; // https://github.com/chrisaljoudi/uBlock/issues/730 // Voodoo programming: this recipe works - panel.style.height = iframe.style.height = body.clientHeight.toString() + 'px'; - panel.style.width = iframe.style.width = body.clientWidth.toString() + 'px'; + var toPixelString = pixels => pixels.toString() + 'px'; + + var clientHeight = body.clientHeight; + iframe.style.height = toPixelString(clientHeight); + panel.style.height = toPixelString(clientHeight + (panel.boxObject.height - panel.clientHeight)); + + var clientWidth = body.clientWidth; + iframe.style.width = toPixelString(clientWidth); + panel.style.width = toPixelString(clientWidth + (panel.boxObject.width - panel.clientWidth)); + if ( iframe.clientHeight !== body.clientHeight || iframe.clientWidth !== body.clientWidth ) { - delayedResize(); + delayedResize(attempts); } }; var onPopupReady = function() { @@ -2032,16 +2271,23 @@ vAPI.toolbarButton.onBeforeCreated = function(doc) { return; } - // https://github.com/gorhill/uBlock/issues/83 - // Add `portrait` class if width is constrained. - try { - var CustomizableUI = Cu.import('resource:///modules/CustomizableUI.jsm', null).CustomizableUI; - iframe.contentDocument.body.classList.toggle( - 'portrait', - CustomizableUI.getWidget(vAPI.toolbarButton.id).areaType === CustomizableUI.TYPE_MENU_PANEL - ); - } catch (ex) { - /* noop */ + if (CustomizableUI) { + + // https://github.com/gorhill/uBlock/issues/83 + // Add `portrait` class if width is constrained. + try { + iframe.contentDocument.body.classList.toggle( + 'portrait', + CustomizableUI.getWidget(vAPI.toolbarButton.id).areaType === CustomizableUI.TYPE_MENU_PANEL + ); + } catch (ex) { + /* noop */ + } + var placement = CustomizableUI.getPlacementOfWidget(widgetId); + if (placement.area === CustomizableUI.AREA_PANEL) { + // Add some overrides for displaying the popup correctly in a panel + win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils) + .loadSheet(Services.io.newURI(vAPI.getURL("css/popup-vertical.css"), null, null), Ci.nsIDOMWindowUtils.AUTHOR_SHEET); } new win.MutationObserver(delayedResize).observe(win.document.body, { @@ -2054,10 +2300,6 @@ vAPI.toolbarButton.onBeforeCreated = function(doc) { }; iframe.addEventListener('load', onPopupReady, true); - - doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils) - .loadSheet(this.styleURI, 1); }; /******************************************************************************/ diff --git a/platform/firefox/vapi-common.js b/platform/firefox/vapi-common.js index 714a77e58..5c5bb6755 100644 --- a/platform/firefox/vapi-common.js +++ b/platform/firefox/vapi-common.js @@ -125,9 +125,9 @@ vAPI.closePopup = function() { // background page or auxiliary pages. // This storage is optional, but it is nice to have, for a more polished user // experience. - +const branchName = 'extensions.' + location.host + '.'; vAPI.localStorage = { - PB: Services.prefs.getBranch('extensions.' + location.host + '.'), + PB: Services.prefs.getBranch(branchName), str: Components.classes['@mozilla.org/supports-string;1'] .createInstance(Components.interfaces.nsISupportsString), getItem: function(key) { @@ -148,6 +148,19 @@ vAPI.localStorage = { this.str ); }, + getBool: function(key) { + try { + return this.PB.getBoolPref(key); + } catch (ex) { + return null; + } + }, + setBool: function(key, value) { + this.PB.setBoolPref(key, value); + }, + setDefaultBool: function(key, defaultValue) { + Services.prefs.getDefaultBranch(branchName).setBoolPref(key, defaultValue); + }, removeItem: function(key) { this.PB.clearUserPref(key); }, From 9e3684d6ca903fdf651e4fc6941e4bd091ad8878 Mon Sep 17 00:00:00 2001 From: AlexVallat Date: Sat, 25 Apr 2015 14:08:01 +0100 Subject: [PATCH 2/5] Imported https://github.com/AlexVallat/uBlock/commit/d9b23d4f109881a87e2516aee31c20f23105c90e --- platform/firefox/css/legacy-toolbar-button.css | 11 ++++++++--- platform/firefox/frameModule.js | 11 +++++++++++ .../{icon32-off.svg => icon-large-off.svg} | 2 +- .../img/browsericons/{icon32.svg => icon-large.svg} | 2 +- platform/firefox/vapi-background.js | 12 ++++++++---- 5 files changed, 29 insertions(+), 9 deletions(-) rename platform/firefox/img/browsericons/{icon32-off.svg => icon-large-off.svg} (94%) rename platform/firefox/img/browsericons/{icon32.svg => icon-large.svg} (94%) diff --git a/platform/firefox/css/legacy-toolbar-button.css b/platform/firefox/css/legacy-toolbar-button.css index 2e2f34505..f29052ab7 100644 --- a/platform/firefox/css/legacy-toolbar-button.css +++ b/platform/firefox/css/legacy-toolbar-button.css @@ -1,8 +1,8 @@ #uBlock-legacy-button { - list-style-image: url('../img/browsericons/icon32.svg'); + list-style-image: url('../img/browsericons/icon-large.svg'); } #uBlock-legacy-button.off { - list-style-image: url('../img/browsericons/icon32-off.svg'); + list-style-image: url('../img/browsericons/icon-large-off.svg'); } toolbar[iconsize="small"] #uBlock-legacy-button { @@ -28,10 +28,15 @@ toolbar[iconsize="small"] #uBlock-legacy-button.off { /* Override off state when in palette */ toolbarpaletteitem #uBlock-legacy-button.off { - list-style-image: url('../img/browsericons/icon32.svg'); + list-style-image: url('../img/browsericons/icon-large.svg'); } /* Override badge when in palette */ toolbarpaletteitem #uBlock-legacy-button[badge]::before { content: none; +} + +/* Prevent pale moon from showing the arrow underneath the button */ +#uBlock-legacy-button .toolbarbutton-menu-dropmarker { + -moz-box-orient: horizontal; } \ No newline at end of file diff --git a/platform/firefox/frameModule.js b/platform/firefox/frameModule.js index 87edc757d..1d759a86d 100644 --- a/platform/firefox/frameModule.js +++ b/platform/firefox/frameModule.js @@ -331,6 +331,17 @@ const contentObserver = { let docReady = (e) => { let doc = e.target; doc.removeEventListener(e.type, docReady, true); + + if (doc.docShell) { + // It is possible, in some cases (#1140) for document-element-inserted to occur *before* nsIWebProgressListener.onLocationChange, so ensure that the URL is correct before continuing + let messageManager = doc.docShell.getInterface(Ci.nsIContentFrameMessageManager); + + messageManager.sendSyncMessage(locationChangedMessageName, { + url: loc.href, + noRefresh: true, // If the URL is the same, then don't refresh it so that if this occurs after onLocationChange, no the block count isn't reset + }); + } + lss(this.contentBaseURI + 'contentscript-end.js', sandbox); if ( doc.querySelector('a[href^="abp:"]') ) { diff --git a/platform/firefox/img/browsericons/icon32-off.svg b/platform/firefox/img/browsericons/icon-large-off.svg similarity index 94% rename from platform/firefox/img/browsericons/icon32-off.svg rename to platform/firefox/img/browsericons/icon-large-off.svg index 0b9030845..684a696c9 100644 --- a/platform/firefox/img/browsericons/icon32-off.svg +++ b/platform/firefox/img/browsericons/icon-large-off.svg @@ -1,7 +1,7 @@ + width="24px" height="24px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve"> + width="24px" height="24px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve"> Date: Sat, 30 May 2015 12:12:00 +0100 Subject: [PATCH 3/5] Imported https://github.com/AlexVallat/uBlock/commit/620a7d78d146d071f3f7ba09710c6fa332dcc3f0 --- .../img/browsericons/icon-large-off.svg | 17 +++--- .../firefox/img/browsericons/icon-large.svg | 17 +++--- platform/firefox/vapi-background.js | 53 +++++++++---------- platform/firefox/vapi-client.js | 4 +- platform/firefox/vapi-common.js | 4 +- src/js/scriptlets/element-picker.js | 3 -- 6 files changed, 41 insertions(+), 57 deletions(-) diff --git a/platform/firefox/img/browsericons/icon-large-off.svg b/platform/firefox/img/browsericons/icon-large-off.svg index 684a696c9..9ea55a45b 100644 --- a/platform/firefox/img/browsericons/icon-large-off.svg +++ b/platform/firefox/img/browsericons/icon-large-off.svg @@ -1,12 +1,7 @@ - - - - - + + + + + + diff --git a/platform/firefox/img/browsericons/icon-large.svg b/platform/firefox/img/browsericons/icon-large.svg index 1fc812caf..848306a09 100644 --- a/platform/firefox/img/browsericons/icon-large.svg +++ b/platform/firefox/img/browsericons/icon-large.svg @@ -1,12 +1,7 @@ - - - - - + + + + + + diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index e4d518aba..48a65387c 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -498,26 +498,26 @@ var windowWatcher = { var attachToTabBrowser = function(window, tabBrowser) { if (!tabBrowser) { - return; - } + return; + } var tabContainer; - if ( tabBrowser.deck ) { - // Fennec - tabContainer = tabBrowser.deck; - } else if ( tabBrowser.tabContainer ) { - // desktop Firefox - tabContainer = tabBrowser.tabContainer; + if ( tabBrowser.deck ) { + // Fennec + tabContainer = tabBrowser.deck; + } else if (tabBrowser.tabContainer) { + // desktop Firefox + tabContainer = tabBrowser.tabContainer; vAPI.contextMenu.register(window.document); if (vAPI.toolbarButton.attachToNewWindow) { vAPI.toolbarButton.attachToNewWindow(window); } - } else { - return; - } + } else { + return; + } - tabContainer.addEventListener('TabClose', tabWatcher.onTabClose); - tabContainer.addEventListener('TabSelect', tabWatcher.onTabSelect); + tabContainer.addEventListener('TabClose', tabWatcher.onTabClose); + tabContainer.addEventListener('TabSelect', tabWatcher.onTabSelect); // when new window is opened TabSelect doesn't run on the selected tab? } @@ -1953,9 +1953,9 @@ vAPI.toolbarButton.init = function() { var forceLegacyToolbarButton = vAPI.localStorage.getBool("forceLegacyToolbarButton"); if (!forceLegacyToolbarButton) { - try { - CustomizableUI = Cu.import('resource:///modules/CustomizableUI.jsm', null).CustomizableUI; - } catch (ex) { + try { + CustomizableUI = Cu.import('resource:///modules/CustomizableUI.jsm', null).CustomizableUI; + } catch (ex) { } } @@ -1985,8 +1985,8 @@ vAPI.toolbarButton.init = function() { addLegacyToolbarButton(window); } }, 250); - return; - } + return; + } var toolbarButton = document.createElement('toolbarbutton'); toolbarButton.setAttribute('id', legacyButtonId); @@ -2183,7 +2183,6 @@ vAPI.toolbarButton.init = function() { }; CustomizableUI.createWidget(this); - cleanupTasks.push(function() { if ( this.CUIEvents ) { @@ -2242,12 +2241,14 @@ vAPI.toolbarButton.populatePanel = function(doc, panel) { // Sanity check attempts = (attempts || 0) + 1; - if (attempts > 1000) { - console.error('uBlock> delayedResize: giving up after too many attemps'); + if (attempts > 1/*000*/) { + debugger; + console.error('uBlock> delayedResize: giving up after too many attempts'); return; } - updateTimer = vAPI.setTimeout(resizePopup, 10, attempts); }; + updateTimer = vAPI.setTimeout(resizePopup, 10, attempts); + }; var resizePopup = function(attempts) { updateTimer = null; var body = iframe.contentDocument.body; @@ -2268,6 +2269,8 @@ vAPI.toolbarButton.populatePanel = function(doc, panel) { delayedResize(attempts); } }; + + var CustomizableUI = this.CustomizableUI; var onPopupReady = function() { var win = this.contentWindow; @@ -2276,7 +2279,6 @@ vAPI.toolbarButton.populatePanel = function(doc, panel) { } if (CustomizableUI) { - // https://github.com/gorhill/uBlock/issues/83 // Add `portrait` class if width is constrained. try { @@ -2287,11 +2289,6 @@ vAPI.toolbarButton.populatePanel = function(doc, panel) { } catch (ex) { /* noop */ } - var placement = CustomizableUI.getPlacementOfWidget(widgetId); - if (placement.area === CustomizableUI.AREA_PANEL) { - // Add some overrides for displaying the popup correctly in a panel - win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils) - .loadSheet(Services.io.newURI(vAPI.getURL("css/popup-vertical.css"), null, null), Ci.nsIDOMWindowUtils.AUTHOR_SHEET); } new win.MutationObserver(delayedResize).observe(win.document.body, { diff --git a/platform/firefox/vapi-client.js b/platform/firefox/vapi-client.js index b62a9b593..8ca8b88a8 100644 --- a/platform/firefox/vapi-client.js +++ b/platform/firefox/vapi-client.js @@ -38,8 +38,8 @@ vAPI.sessionId = String.fromCharCode(Date.now() % 26 + 97) + /******************************************************************************/ -vAPI.setTimeout = vAPI.setTimeout || function(callback, delay) { - return setTimeout(function() { callback(); }, delay); +vAPI.setTimeout = vAPI.setTimeout || function(callback, delay, args) { + return setTimeout(function(args) { callback(args); }, delay, args); }; /******************************************************************************/ diff --git a/platform/firefox/vapi-common.js b/platform/firefox/vapi-common.js index 5c5bb6755..2ded85ea8 100644 --- a/platform/firefox/vapi-common.js +++ b/platform/firefox/vapi-common.js @@ -40,8 +40,8 @@ var vAPI = self.vAPI = self.vAPI || {}; /******************************************************************************/ -vAPI.setTimeout = vAPI.setTimeout || function(callback, delay) { - return setTimeout(function() { callback(); }, delay); +vAPI.setTimeout = vAPI.setTimeout || function(callback, delay, args) { + return setTimeout(function(args) { callback(args); }, delay, args); }; /******************************************************************************/ diff --git a/src/js/scriptlets/element-picker.js b/src/js/scriptlets/element-picker.js index 24e878c0c..cad0c4a59 100644 --- a/src/js/scriptlets/element-picker.js +++ b/src/js/scriptlets/element-picker.js @@ -952,9 +952,6 @@ var startPicker = function(details) { showDialog({ modifier: true }); return; } - - // A target was specified, but it wasn't found: abort. - stopPicker(); }; /******************************************************************************/ From aeeaa4d5b32ed4418b7157c6d8b3011d377b214e Mon Sep 17 00:00:00 2001 From: gorhill Date: Wed, 17 Jun 2015 13:49:43 -0400 Subject: [PATCH 4/5] code review --- .../firefox/css/legacy-toolbar-button.css | 52 +- platform/firefox/frameModule.js | 11 - platform/firefox/vapi-background.js | 1199 +++++++++-------- platform/firefox/vapi-client.js | 4 +- platform/firefox/vapi-common.js | 31 +- src/js/scriptlets/element-picker.js | 3 + tools/make-firefox.sh | 1 + 7 files changed, 721 insertions(+), 580 deletions(-) diff --git a/platform/firefox/css/legacy-toolbar-button.css b/platform/firefox/css/legacy-toolbar-button.css index f29052ab7..37900cb30 100644 --- a/platform/firefox/css/legacy-toolbar-button.css +++ b/platform/firefox/css/legacy-toolbar-button.css @@ -1,42 +1,44 @@ -#uBlock-legacy-button { - list-style-image: url('../img/browsericons/icon-large.svg'); +#uBlock0-legacy-button { + list-style-image: url('../img/browsericons/icon-large.svg'); } -#uBlock-legacy-button.off { - list-style-image: url('../img/browsericons/icon-large-off.svg'); +#uBlock0-legacy-button.off { + list-style-image: url('../img/browsericons/icon-large-off.svg'); } -toolbar[iconsize="small"] #uBlock-legacy-button { - list-style-image: url('../img/browsericons/icon16.svg'); +toolbar[iconsize="small"] #uBlock0-legacy-button { + list-style-image: url('../img/browsericons/icon16.svg'); } -toolbar[iconsize="small"] #uBlock-legacy-button.off { - list-style-image: url('../img/browsericons/icon16-off.svg'); +toolbar[iconsize="small"] #uBlock0-legacy-button.off { + list-style-image: url('../img/browsericons/icon16-off.svg'); } -#uBlock-legacy-button[badge]::before { - position: fixed; - margin-top: -2px; - padding: 1px 2px; - font-size: 9px; - font-weight: bold; +#uBlock0-legacy-button[badge]::before { + background: #555; color: #fff; - background: #666; content: attr(badge); + font: bold 10px sans-serif; + margin-top: -2px; + padding: 0 2px; + position: fixed; } -/* This hack required because if the before content changes it de-pops the popup (without firing any events). So just hide it instead. Note, can't actually *hide* it, or the same thing happens. '*/ -#uBlock-legacy-button[badge=""]::before { - padding: 0; +/* This hack required because if the before content changes it de-pops the + popup (without firing any events). So just hide it instead. Note, can't + actually *hide* it, or the same thing happens. +**/ +#uBlock0-legacy-button[badge=""]::before { + padding: 0; } /* Override off state when in palette */ -toolbarpaletteitem #uBlock-legacy-button.off { - list-style-image: url('../img/browsericons/icon-large.svg'); +toolbarpaletteitem #uBlock0-legacy-button.off { + list-style-image: url('../img/browsericons/icon-large.svg'); } /* Override badge when in palette */ -toolbarpaletteitem #uBlock-legacy-button[badge]::before { - content: none; +toolbarpaletteitem #uBlock0-legacy-button[badge]::before { + content: none; } /* Prevent pale moon from showing the arrow underneath the button */ -#uBlock-legacy-button .toolbarbutton-menu-dropmarker { - -moz-box-orient: horizontal; -} \ No newline at end of file +#uBlock0-legacy-button .toolbarbutton-menu-dropmarker { + -moz-box-orient: horizontal; +} diff --git a/platform/firefox/frameModule.js b/platform/firefox/frameModule.js index 1d759a86d..87edc757d 100644 --- a/platform/firefox/frameModule.js +++ b/platform/firefox/frameModule.js @@ -331,17 +331,6 @@ const contentObserver = { let docReady = (e) => { let doc = e.target; doc.removeEventListener(e.type, docReady, true); - - if (doc.docShell) { - // It is possible, in some cases (#1140) for document-element-inserted to occur *before* nsIWebProgressListener.onLocationChange, so ensure that the URL is correct before continuing - let messageManager = doc.docShell.getInterface(Ci.nsIContentFrameMessageManager); - - messageManager.sendSyncMessage(locationChangedMessageName, { - url: loc.href, - noRefresh: true, // If the URL is the same, then don't refresh it so that if this occurs after onLocationChange, no the block count isn't reset - }); - } - lss(this.contentBaseURI + 'contentscript-end.js', sandbox); if ( doc.querySelector('a[href^="abp:"]') ) { diff --git a/platform/firefox/vapi-background.js b/platform/firefox/vapi-background.js index 48a65387c..050308855 100644 --- a/platform/firefox/vapi-background.js +++ b/platform/firefox/vapi-background.js @@ -60,7 +60,7 @@ vAPI.app.restart = function() { /******************************************************************************/ // Set default preferences for user to find in about:config -vAPI.localStorage.setDefaultBool("forceLegacyToolbarButton", false); +vAPI.localStorage.setDefaultBool('forceLegacyToolbarButton', false); /******************************************************************************/ @@ -70,11 +70,7 @@ vAPI.localStorage.setDefaultBool("forceLegacyToolbarButton", false); var cleanupTasks = []; // This must be updated manually, every time a new task is added/removed - -// Fixed by github.com/AlexVallat: -// https://github.com/AlexVallat/uBlock/commit/7b781248f00cbe3d61b1cc367c440db80fa06049 -// several instances of cleanupTasks.push, but one is unique to fennec, and three to desktop. -var expectedNumberOfCleanups = vAPI.fennec ? 7 : 9; +var expectedNumberOfCleanups = 7; window.addEventListener('unload', function() { if ( typeof vAPI.app.onShutdown === 'function' ) { @@ -484,88 +480,6 @@ vAPI.storage = (function() { /******************************************************************************/ -var windowWatcher = { - onReady: function(e) { - if ( e ) { - this.removeEventListener(e.type, windowWatcher.onReady); - } - - var wintype = this.document.documentElement.getAttribute('windowtype'); - - if ( wintype !== 'navigator:browser' ) { - return; - } - - var attachToTabBrowser = function(window, tabBrowser) { - if (!tabBrowser) { - return; - } - - var tabContainer; - if ( tabBrowser.deck ) { - // Fennec - tabContainer = tabBrowser.deck; - } else if (tabBrowser.tabContainer) { - // desktop Firefox - tabContainer = tabBrowser.tabContainer; - vAPI.contextMenu.register(window.document); - if (vAPI.toolbarButton.attachToNewWindow) { - vAPI.toolbarButton.attachToNewWindow(window); - } - } else { - return; - } - - tabContainer.addEventListener('TabClose', tabWatcher.onTabClose); - tabContainer.addEventListener('TabSelect', tabWatcher.onTabSelect); - // when new window is opened TabSelect doesn't run on the selected tab? - } - - var win = this; - var tabBrowser = getTabBrowser(win); - if ( !tabBrowser ) { - // On some platforms, the tab browser isn't immediately available, try waiting a bit - win.setTimeout(function() { - attachToTabBrowser(win, getTabBrowser(win)); - }, 250); - } else { - attachToTabBrowser(win, tabBrowser); - } - - }, - - observe: function(win, topic) { - if ( topic === 'domwindowopened' ) { - win.addEventListener('DOMContentLoaded', this.onReady); - } - } -}; - -/******************************************************************************/ - -var tabWatcher = { - onTabClose: function({target}) { - // target is tab in Firefox, browser in Fennec - var tabId = vAPI.tabs.getTabId(target); - vAPI.tabs.onClosed(tabId); - delete vAPI.toolbarButton.tabs[tabId]; - }, - - onTabSelect: function({target}) { - vAPI.setIcon(vAPI.tabs.getTabId(target), getOwnerWindow(target)); - }, -}; - -/******************************************************************************/ - -vAPI.isBehindTheSceneTabId = function(tabId) { - return tabId.toString() === '-1'; -}; - -vAPI.noTabId = '-1'; - -/******************************************************************************/ - var getTabBrowser = function(win) { return vAPI.fennec && win.BrowserApp || win.gBrowser || null; }; @@ -643,12 +557,8 @@ vAPI.tabs.get = function(tabId, callback) { var browser; if ( tabId === null ) { - win = Services.wm.getMostRecentWindow('navigator:browser'); - var tabBrowser = getTabBrowser(win); - if (tabBrowser) { - tab = tabBrowser.selectedTab; - tabId = this.getTabId(tab); - } + browser = tabWatcher.currentBrowser(); + tabId = tabWatcher.tabIdFromTarget(browser); } else { browser = tabWatcher.browserFromTabId(tabId); } @@ -1031,6 +941,35 @@ var tabWatcher = (function() { vAPI.setIcon(tabIdFromTarget(target), getOwnerWindow(target)); }; + var attachToTabBrowser = function(window) { + var tabBrowser = getTabBrowser(window); + if ( !tabBrowser ) { + return false; + } + + var tabContainer; + if ( tabBrowser.deck ) { // Fennec + tabContainer = tabBrowser.deck; + } else if ( tabBrowser.tabContainer ) { // Firefox + tabContainer = tabBrowser.tabContainer; + vAPI.contextMenu.register(window.document); + } else { + return true; + } + + if ( typeof vAPI.toolbarButton.attachToNewWindow === 'function' ) { + vAPI.toolbarButton.attachToNewWindow(window); + } + + tabContainer.addEventListener('TabOpen', onOpen); + tabContainer.addEventListener('TabShow', onShow); + tabContainer.addEventListener('TabClose', onClose); + // when new window is opened TabSelect doesn't run on the selected tab? + tabContainer.addEventListener('TabSelect', onSelect); + + return true; + }; + var onWindowLoad = function(ev) { if ( ev ) { this.removeEventListener(ev.type, onWindowLoad); @@ -1041,28 +980,12 @@ var tabWatcher = (function() { return; } - var tabBrowser = getTabBrowser(this); - if ( !tabBrowser ) { - return; + // On some platforms, the tab browser isn't immediately available, + // try waiting a bit if this happens. + var win = this; + if ( attachToTabBrowser(win) === false ) { + vAPI.setTimeout(attachToTabBrowser.bind(null, win), 250); } - - var tabContainer; - if ( tabBrowser.deck ) { - // Fennec - tabContainer = tabBrowser.deck; - } else if ( tabBrowser.tabContainer ) { - // desktop Firefox - tabContainer = tabBrowser.tabContainer; - vAPI.contextMenu.register(this.document); - } else { - return; - } - tabContainer.addEventListener('TabOpen', onOpen); - tabContainer.addEventListener('TabShow', onShow); - tabContainer.addEventListener('TabClose', onClose); - tabContainer.addEventListener('TabSelect', onSelect); - - // when new window is opened TabSelect doesn't run on the selected tab? }; var onWindowUnload = function() { @@ -1853,6 +1776,7 @@ vAPI.net.registerListeners = function() { }); }; +/******************************************************************************/ /******************************************************************************/ vAPI.toolbarButton = { @@ -1861,240 +1785,462 @@ vAPI.toolbarButton = { viewId: location.host + '-panel', label: vAPI.app.name, tooltiptext: vAPI.app.name, - tabs: {/*tabId: {badge: 0, img: boolean}*/} + tabs: {/*tabId: {badge: 0, img: boolean}*/}, + init: null, + codePath: '' }; /******************************************************************************/ -// Toolbar button UI for desktop Firefox -vAPI.toolbarButton.init = function() { - if ( vAPI.fennec ) { - // Menu UI for Fennec - var tb = { - menuItemIds: new WeakMap(), - label: vAPI.app.name, - tabs: {} - }; - vAPI.toolbarButton = tb; - - tb.getMenuItemLabel = function(tabId) { - var label = this.label; - if ( tabId === undefined ) { - return label; - } - var tabDetails = this.tabs[tabId]; - if ( !tabDetails ) { - return label; - } - if ( !tabDetails.img ) { - label += ' (' + vAPI.i18n('fennecMenuItemBlockingOff') + ')'; - } else if ( tabDetails.badge ) { - label += ' (' + tabDetails.badge + ')'; - } - return label; - }; - - tb.onClick = function() { - var win = Services.wm.getMostRecentWindow('navigator:browser'); - var curTabId = tabWatcher.tabIdFromTarget(getTabBrowser(win).selectedTab); - vAPI.tabs.open({ - url: 'popup.html?tabId=' + curTabId, - index: -1, - select: true - }); - }; - - tb.updateState = function(win, tabId) { - var id = this.menuItemIds.get(win); - if ( !id ) { - return; - } - win.NativeWindow.menu.update(id, { - name: this.getMenuItemLabel(tabId) - }); - }; - - // Only actually expecting one window under Fennec (note, not tabs, windows) - for ( var win of vAPI.tabs.getWindows() ) { - var label = tb.getMenuItemLabel(); - var id = win.NativeWindow.menu.add({ - name: label, - callback: tb.onClick - }); - tb.menuItemIds.set(win, id); - } - - cleanupTasks.push(function() { - for ( var win of vAPI.tabs.getWindows() ) { - var id = tb.menuItemIds.get(win); - if ( id ) { - win.NativeWindow.menu.remove(id); - tb.menuItemIds.delete(win); - } - } - }); +// Fennec +(function() { + if ( !vAPI.fennec ) { return; } - vAPI.messaging.globalMessageManager.addMessageListener( - location.host + ':closePopup', - vAPI.toolbarButton.onPopupCloseRequested - ); + var tbb = vAPI.toolbarButton; - cleanupTasks.push(function() { - vAPI.messaging.globalMessageManager.removeMessageListener( - location.host + ':closePopup', - vAPI.toolbarButton.onPopupCloseRequested - ); - }); + tbb.codePath = 'fennec'; - var CustomizableUI; + var menuItemIds = new WeakMap(); - var forceLegacyToolbarButton = vAPI.localStorage.getBool("forceLegacyToolbarButton"); - if (!forceLegacyToolbarButton) { + var shutdown = function() { + for ( var win of vAPI.tabs.getWindows() ) { + var id = menuItemIds.get(win); + if ( !id ) { + continue; + } + win.NativeWindow.menu.remove(id); + menuItemIds.delete(win); + } + }; + + tbb.getMenuItemLabel = function(tabId) { + var label = this.label; + if ( tabId === undefined ) { + return label; + } + var tabDetails = this.tabs[tabId]; + if ( !tabDetails ) { + return label; + } + if ( !tabDetails.img ) { + label += ' (' + vAPI.i18n('fennecMenuItemBlockingOff') + ')'; + } else if ( tabDetails.badge ) { + label += ' (' + tabDetails.badge + ')'; + } + return label; + }; + + tbb.onClick = function() { + var win = Services.wm.getMostRecentWindow('navigator:browser'); + var curTabId = tabWatcher.tabIdFromTarget(getTabBrowser(win).selectedTab); + vAPI.tabs.open({ + url: 'popup.html?tabId=' + curTabId, + index: -1, + select: true + }); + }; + + tbb.updateState = function(win, tabId) { + var id = menuItemIds.get(win); + if ( !id ) { + return; + } + win.NativeWindow.menu.update(id, { + name: this.getMenuItemLabel(tabId) + }); + }; + + tbb.init = function() { + // Only actually expecting one window under Fennec (note, not tabs, windows) + for ( var win of vAPI.tabs.getWindows() ) { + var label = this.getMenuItemLabel(); + var id = win.NativeWindow.menu.add({ + name: label, + callback: this.onClick + }); + menuItemIds.set(win, id); + } + + cleanupTasks.push(shutdown); + }; +})(); + +/******************************************************************************/ + +// Non-Fennec: common code paths. + +(function() { + if ( vAPI.fennec ) { + return; + } + + var tbb = vAPI.toolbarButton; + + tbb.onViewShowing = function({target}) { + target.firstChild.setAttribute('src', vAPI.getURL('popup.html')); + }; + + tbb.onViewHiding = function({target}) { + target.parentNode.style.maxWidth = ''; + target.firstChild.setAttribute('src', 'about:blank'); + }; + + tbb.updateState = function(win, tabId) { + var button = win.document.getElementById(this.id); + + if ( !button ) { + return; + } + + var icon = this.tabs[tabId]; + + button.setAttribute('badge', icon && icon.badge || ''); + button.classList.toggle('off', !icon || !icon.img); + }; + + tbb.populatePanel = function(doc, panel) { + panel.setAttribute('id', this.viewId); + + var iframe = doc.createElement('iframe'); + iframe.setAttribute('type', 'content'); + + panel.appendChild(iframe); + + var resizeTimer = null; + + var resizePopupDelayed = function(attempts) { + if ( resizeTimer !== null ) { + return; + } + + // Sanity check + attempts = (attempts || 0) + 1; + if ( attempts > 1/*000*/ ) { + console.error('uBlock0> resizePopupDelayed: giving up after too many attempts'); + return; + } + + resizeTimer = vAPI.setTimeout(resizePopup, 10, attempts); + }; + + var resizePopup = function(attempts) { + resizeTimer = null; + var body = iframe.contentDocument.body; + panel.parentNode.style.maxWidth = 'none'; + // https://github.com/chrisaljoudi/uBlock/issues/730 + // Voodoo programming: this recipe works + var toPixelString = pixels => pixels.toString() + 'px'; + + var clientHeight = body.clientHeight; + iframe.style.height = toPixelString(clientHeight); + panel.style.height = toPixelString(clientHeight + (panel.boxObject.height - panel.clientHeight)); + + var clientWidth = body.clientWidth; + iframe.style.width = toPixelString(clientWidth); + panel.style.width = toPixelString(clientWidth + (panel.boxObject.width - panel.clientWidth)); + + if ( iframe.clientHeight !== body.clientHeight || iframe.clientWidth !== body.clientWidth ) { + resizePopupDelayed(attempts); + } + }; + + var onPopupReady = function() { + var win = this.contentWindow; + + if ( !win || win.location.host !== location.host ) { + return; + } + + if ( typeof tbb.onBeforePopupReady === 'function' ) { + tbb.onBeforePopupReady.call(this); + } + + new win.MutationObserver(resizePopupDelayed).observe(win.document.body, { + attributes: true, + characterData: true, + subtree: true + }); + + resizePopupDelayed(); + }; + + iframe.addEventListener('load', onPopupReady, true); + }; +})(); + +/******************************************************************************/ + +// Firefox 28 and less + +(function() { + var tbb = vAPI.toolbarButton; + if ( tbb.init !== null ) { + return; + } + var CustomizableUI = null; + var forceLegacyToolbarButton = vAPI.localStorage.getBool('forceLegacyToolbarButton'); + if ( !forceLegacyToolbarButton ) { try { CustomizableUI = Cu.import('resource:///modules/CustomizableUI.jsm', null).CustomizableUI; } catch (ex) { } } - - if (!CustomizableUI) { - // Create a fallback non-customizable UI button - var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); - var styleSheetUri = Services.io.newURI(vAPI.getURL("css/legacy-toolbar-button.css"), null, null); - var legacyButtonId = "uBlock-legacy-button"; // NOTE: must match legacy-toolbar-button.css - this.id = legacyButtonId; - this.viewId = legacyButtonId + "-panel"; - - if (!sss.sheetRegistered(styleSheetUri, sss.AUTHOR_SHEET)) { - sss.loadAndRegisterSheet(styleSheetUri, sss.AUTHOR_SHEET); // Register global so it works in all windows, including palette - } - - var addLegacyToolbarButton = function(window) { - var document = window.document; - var toolbox = document.getElementById('navigator-toolbox') || document.getElementById('mail-toolbox'); - - if (toolbox) { - var palette = toolbox.palette; - - if (!palette) { - // palette might take a little longer to appear on some platforms, give it a small delay and try again - window.setTimeout(function() { - if (toolbox.palette) { - addLegacyToolbarButton(window); - } - }, 250); - return; - } - - var toolbarButton = document.createElement('toolbarbutton'); - toolbarButton.setAttribute('id', legacyButtonId); - toolbarButton.setAttribute('type', 'menu'); // type = panel would be more accurate, but doesn't look as good - toolbarButton.setAttribute('removable', 'true'); - toolbarButton.setAttribute('class', 'toolbarbutton-1 chromeclass-toolbar-additional'); - toolbarButton.setAttribute('label', vAPI.toolbarButton.label); - - var toolbarButtonPanel = document.createElement("panel"); - // toolbarButtonPanel.setAttribute('level', 'parent'); NOTE: Setting level to parent breaks the popup for PaleMoon under linux (mouse pointer misaligned with content). For some reason. - vAPI.toolbarButton.populatePanel(document, toolbarButtonPanel); - toolbarButtonPanel.addEventListener('popupshowing', vAPI.toolbarButton.onViewShowing); - toolbarButtonPanel.addEventListener('popuphiding', vAPI.toolbarButton.onViewHiding); - toolbarButton.appendChild(toolbarButtonPanel); - - palette.appendChild(toolbarButton); - - vAPI.toolbarButton.closePopup = function() { - toolbarButtonPanel.hidePopup(); - } - - if (!vAPI.localStorage.getBool('legacyToolbarButtonAdded')) { - // No button yet so give it a default location. If forcing the button, just put in in the palette rather than on any specific toolbar (who knows what toolbars will be available or visible!) - var toolbar = !forceLegacyToolbarButton && document.getElementById('nav-bar'); - if (toolbar) { - toolbar.appendChild(toolbarButton); - toolbar.setAttribute('currentset', toolbar.currentSet); - document.persist(toolbar.id, 'currentset'); - } - vAPI.localStorage.setBool('legacyToolbarButtonAdded', 'true'); - } else { - // Find the place to put the button - var toolbars = toolbox.externalToolbars.slice(); - for (var child of toolbox.children) { - if (child.localName === 'toolbar') { - toolbars.push(child); - } - } - - for (var toolbar of toolbars) { - var currentsetString = toolbar.getAttribute('currentset'); - if (currentsetString) { - var currentset = currentsetString.split(','); - var index = currentset.indexOf(legacyButtonId); - if (index >= 0) { - // Found our button on this toolbar - but where on it? - var before = null; - for (var i = index + 1; i < currentset.length; i++) { - before = document.getElementById(currentset[i]); - if (before) { - toolbar.insertItem(legacyButtonId, before); - break; - } - } - if (!before) { - toolbar.insertItem(legacyButtonId); - } - } - } - } - } - } - } - - vAPI.toolbarButton.attachToNewWindow = function(win) { - addLegacyToolbarButton(win); - } - - cleanupTasks.push(function() { - for ( var win of vAPI.tabs.getWindows() ) { - var toolbarButton = win.document.getElementById(legacyButtonId); - if (toolbarButton) { - toolbarButton.parentNode.removeChild(toolbarButton); - } - } - - if (sss.sheetRegistered(styleSheetUri, sss.AUTHOR_SHEET)) { - sss.unregisterSheet(styleSheetUri, sss.AUTHOR_SHEET); - } - }.bind(this)); + if ( CustomizableUI !== null ) { return; } - this.CustomizableUI = CustomizableUI; + tbb.codePath = 'legacy'; + tbb.id = 'uBlock0-legacy-button'; // NOTE: must match legacy-toolbar-button.css + tbb.viewId = tbb.id + '-panel'; - this.defaultArea = CustomizableUI.AREA_NAVBAR; - this.styleURI = [ - '#' + this.id + '.off {', - 'list-style-image: url(', - vAPI.getURL('img/browsericons/icon16-off.svg'), - ');', - '}', - '#' + this.id + ' {', - 'list-style-image: url(', - vAPI.getURL('img/browsericons/icon16.svg'), - ');', - '}', - '#' + this.viewId + ', #' + this.viewId + ' > iframe {', - 'width: 160px;', - 'height: 290px;', - 'overflow: hidden !important;', - '}' - ]; + var sss = null; + var styleSheetUri = null; - var platformVersion = Services.appinfo.platformVersion; + var addLegacyToolbarButton = function(window) { + var document = window.document; - if ( Services.vc.compare(platformVersion, '36.0') < 0 ) { - this.styleURI.push( + var toolbox = document.getElementById('navigator-toolbox') || document.getElementById('mail-toolbox'); + if ( !toolbox ) { + return; + } + + // palette might take a little longer to appear on some platforms, + // give it a small delay and try again. + var palette = toolbox.palette; + if ( !palette ) { + vAPI.setTimeout(function() { + if ( toolbox.palette ) { + addLegacyToolbarButton(window); + } + }, 250); + return; + } + + var toolbarButton = document.createElement('toolbarbutton'); + toolbarButton.setAttribute('id', tbb.id); + // type = panel would be more accurate, but doesn't look as good + toolbarButton.setAttribute('type', 'menu'); + toolbarButton.setAttribute('removable', 'true'); + toolbarButton.setAttribute('class', 'toolbarbutton-1 chromeclass-toolbar-additional'); + toolbarButton.setAttribute('label', tbb.label); + + var toolbarButtonPanel = document.createElement("panel"); + // NOTE: Setting level to parent breaks the popup for PaleMoon under + // linux (mouse pointer misaligned with content). For some reason. + // toolbarButtonPanel.setAttribute('level', 'parent'); + tbb.populatePanel(document, toolbarButtonPanel); + toolbarButtonPanel.addEventListener('popupshowing', tbb.onViewShowing); + toolbarButtonPanel.addEventListener('popuphiding', tbb.onViewHiding); + toolbarButton.appendChild(toolbarButtonPanel); + + palette.appendChild(toolbarButton); + + tbb.closePopup = function() { + toolbarButtonPanel.hidePopup(); + }; + + // No button yet so give it a default location. If forcing the button, + // just put in in the palette rather than on any specific toolbar (who + // knows what toolbars will be available or visible!) + var toolbar; + if ( !vAPI.localStorage.getBool('legacyToolbarButtonAdded') ) { + toolbar = document.getElementById('nav-bar'); + if ( toolbar ) { + toolbar.appendChild(toolbarButton); + toolbar.setAttribute('currentset', toolbar.currentSet); + document.persist(toolbar.id, 'currentset'); + } + vAPI.localStorage.setBool('legacyToolbarButtonAdded', 'true'); + return; + } + + // Find the place to put the button + var toolbars = toolbox.externalToolbars.slice(); + for ( var child of toolbox.children ) { + if ( child.localName === 'toolbar' ) { + toolbars.push(child); + } + } + + for ( toolbar of toolbars ) { + var currentsetString = toolbar.getAttribute('currentset'); + if ( !currentsetString ) { + continue; + } + var currentset = currentsetString.split(','); + var index = currentset.indexOf(tbb.id); + if ( index === -1 ) { + continue; + } + // Found our button on this toolbar - but where on it? + var before = null; + for ( var i = index + 1; i < currentset.length; i++ ) { + before = document.getElementById(currentset[i]); + if ( before === null ) { + continue; + } + toolbar.insertItem(tbb.id, before); + break; + } + if ( before === null ) { + toolbar.insertItem(tbb.id); + } + } + }; + + var onPopupCloseRequested = function({target}) { + if ( typeof tbb.closePopup === 'function' ) { + tbb.closePopup(target); + } + }; + + var shutdown = function() { + for ( var win of vAPI.tabs.getWindows() ) { + var toolbarButton = win.document.getElementById(tbb.id); + if ( toolbarButton ) { + toolbarButton.parentNode.removeChild(toolbarButton); + } + } + if ( sss === null ) { + return; + } + if ( sss.sheetRegistered(styleSheetUri, sss.AUTHOR_SHEET) ) { + sss.unregisterSheet(styleSheetUri, sss.AUTHOR_SHEET); + } + sss = null; + styleSheetUri = null; + + vAPI.messaging.globalMessageManager.removeMessageListener( + location.host + ':closePopup', + onPopupCloseRequested + ); + }; + + tbb.attachToNewWindow = function(win) { + addLegacyToolbarButton(win); + }; + + tbb.init = function() { + vAPI.messaging.globalMessageManager.addMessageListener( + location.host + ':closePopup', + onPopupCloseRequested + ); + + sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); + styleSheetUri = Services.io.newURI(vAPI.getURL("css/legacy-toolbar-button.css"), null, null); + + // Register global so it works in all windows, including palette + if ( !sss.sheetRegistered(styleSheetUri, sss.AUTHOR_SHEET) ) { + sss.loadAndRegisterSheet(styleSheetUri, sss.AUTHOR_SHEET); + } + + cleanupTasks.push(shutdown); + }; +})(); + +/******************************************************************************/ + +// Firefox Australis < 36. + +(function() { + var tbb = vAPI.toolbarButton; + if ( tbb.init !== null ) { + return; + } + if ( Services.vc.compare(Services.appinfo.platformVersion, '36.0') >= 0 ) { + return null; + } + if ( vAPI.localStorage.getBool('forceLegacyToolbarButton') ) { + return null; + } + var CustomizableUI = null; + try { + CustomizableUI = Cu.import('resource:///modules/CustomizableUI.jsm', null).CustomizableUI; + } catch (ex) { + } + if ( CustomizableUI === null ) { + return; + } + tbb.codePath = 'australis'; + tbb.CustomizableUI = CustomizableUI; + tbb.defaultArea = CustomizableUI.AREA_NAVBAR; + + var styleURI = null; + + var onPopupCloseRequested = function({target}) { + if ( typeof tbb.closePopup === 'function' ) { + tbb.closePopup(target); + } + }; + + var shutdown = function() { + CustomizableUI.destroyWidget(tbb.id); + + for ( var win of vAPI.tabs.getWindows() ) { + var panel = win.document.getElementById(tbb.viewId); + panel.parentNode.removeChild(panel); + win.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .removeSheet(styleURI, 1); + } + + vAPI.messaging.globalMessageManager.removeMessageListener( + location.host + ':closePopup', + onPopupCloseRequested + ); + }; + + tbb.onBeforeCreated = function(doc) { + var panel = doc.createElement('panelview'); + + this.populatePanel(doc, panel); + + doc.getElementById('PanelUI-multiView').appendChild(panel); + + doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .loadSheet(styleURI, 1); + }; + + tbb.onBeforePopupReady = function() { + // https://github.com/gorhill/uBlock/issues/83 + // Add `portrait` class if width is constrained. + try { + this.contentDocument.body.classList.toggle( + 'portrait', + CustomizableUI.getWidget(tbb.id).areaType === CustomizableUI.TYPE_MENU_PANEL + ); + } catch (ex) { + /* noop */ + } + }; + + tbb.init = function() { + vAPI.messaging.globalMessageManager.addMessageListener( + location.host + ':closePopup', + onPopupCloseRequested + ); + + var style = [ + '#' + this.id + '.off {', + 'list-style-image: url(', + vAPI.getURL('img/browsericons/icon16-off.svg'), + ');', + '}', + '#' + this.id + ' {', + 'list-style-image: url(', + vAPI.getURL('img/browsericons/icon16.svg'), + ');', + '}', + '#' + this.viewId + ',', + '#' + this.viewId + ' > iframe {', + 'width: 160px;', + 'height: 290px;', + 'overflow: hidden !important;', + '}', '#' + this.id + '[badge]:not([badge=""])::after {', 'position: absolute;', 'margin-left: -16px;', @@ -2106,235 +2252,228 @@ vAPI.toolbarButton.init = function() { 'background: #666;', 'content: attr(badge);', '}' + ]; + + styleURI = Services.io.newURI( + 'data:text/css,' + encodeURIComponent(style.join('')), + null, + null ); - } else { - this.CUIEvents = {}; - var updateBadge = function() { - var wId = vAPI.toolbarButton.id; - var buttonInPanel = CustomizableUI.getWidget(wId).areaType === CustomizableUI.TYPE_MENU_PANEL; - for ( var win of vAPI.tabs.getWindows() ) { - var button = win.document.getElementById(wId); - if ( button === null ) { - continue; - } - if ( buttonInPanel ) { - button.classList.remove('badged-button'); - continue; - } - button.classList.add('badged-button'); - } - - if ( buttonInPanel ) { - return; - } - - // Anonymous elements need some time to be reachable - vAPI.setTimeout(this.updateBadgeStyle, 250); - }.bind(this.CUIEvents); - - // https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/CustomizableUI.jsm#Listeners - this.CUIEvents.onCustomizeEnd = updateBadge; - this.CUIEvents.onWidgetAdded = updateBadge; - this.CUIEvents.onWidgetUnderflow = updateBadge; - - this.CUIEvents.updateBadgeStyle = function() { - var css = [ - 'background: #666', - 'color: #fff' - ].join(';'); - - for ( var win of vAPI.tabs.getWindows() ) { - var button = win.document.getElementById(vAPI.toolbarButton.id); - if ( button === null ) { - continue; - } - var badge = button.ownerDocument.getAnonymousElementByAttribute( - button, - 'class', - 'toolbarbutton-badge' - ); - if ( !badge ) { - return; - } - - badge.style.cssText = css; - } + this.closePopup = function(tabBrowser) { + CustomizableUI.hidePanelForNode( + tabBrowser.ownerDocument.getElementById(this.viewId) + ); }; - this.onCreated = function(button) { - button.setAttribute('badge', ''); - vAPI.setTimeout(updateBadge, 250); - }; + CustomizableUI.createWidget(this); - CustomizableUI.addListener(this.CUIEvents); + cleanupTasks.push(shutdown); + }; +})(); + +/******************************************************************************/ + +// Firefox Australis >= 36. + +(function() { + var tbb = vAPI.toolbarButton; + if ( tbb.init !== null ) { + return; } + if ( Services.vc.compare(Services.appinfo.platformVersion, '36.0') < 0 ) { + return null; + } + if ( vAPI.localStorage.getBool('forceLegacyToolbarButton') ) { + return null; + } + var CustomizableUI = null; + try { + CustomizableUI = Cu.import('resource:///modules/CustomizableUI.jsm', null).CustomizableUI; + } catch (ex) { + } + if ( CustomizableUI === null ) { + return null; + } + tbb.CustomizableUI = CustomizableUI; + tbb.defaultArea = CustomizableUI.AREA_NAVBAR; - this.styleURI = Services.io.newURI( - 'data:text/css,' + encodeURIComponent(this.styleURI.join('')), - null, - null - ); + var CUIEvents = {}; - this.closePopup = function(tabBrowser) { - CustomizableUI.hidePanelForNode( - tabBrowser.ownerDocument.getElementById(vAPI.toolbarButton.viewId) - ); + var badgeCSSRules = [ + 'background: #666', + 'color: #fff' + ].join(';'); + + var updateBadgeStyle = function() { + for ( var win of vAPI.tabs.getWindows() ) { + var button = win.document.getElementById(tbb.id); + if ( button === null ) { + continue; + } + var badge = button.ownerDocument.getAnonymousElementByAttribute( + button, + 'class', + 'toolbarbutton-badge' + ); + if ( !badge ) { + continue; + } + + badge.style.cssText = badgeCSSRules; + } }; - CustomizableUI.createWidget(this); + var updateBadge = function() { + var wId = tbb.id; + var buttonInPanel = CustomizableUI.getWidget(wId).areaType === CustomizableUI.TYPE_MENU_PANEL; - cleanupTasks.push(function() { - if ( this.CUIEvents ) { - CustomizableUI.removeListener(this.CUIEvents); + for ( var win of vAPI.tabs.getWindows() ) { + var button = win.document.getElementById(wId); + if ( button === null ) { + continue; + } + if ( buttonInPanel ) { + button.classList.remove('badged-button'); + continue; + } + button.classList.add('badged-button'); } - CustomizableUI.destroyWidget(this.id); - + if ( buttonInPanel ) { + return; + } + + // Anonymous elements need some time to be reachable + vAPI.setTimeout(updateBadgeStyle, 250); + }.bind(CUIEvents); + + // https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/CustomizableUI.jsm#Listeners + CUIEvents.onCustomizeEnd = updateBadge; + CUIEvents.onWidgetAdded = updateBadge; + CUIEvents.onWidgetUnderflow = updateBadge; + + var onPopupCloseRequested = function({target}) { + if ( typeof tbb.closePopup === 'function' ) { + tbb.closePopup(target); + } + }; + + var shutdown = function() { + CustomizableUI.removeListener(CUIEvents); + CustomizableUI.destroyWidget(tbb.id); + for ( var win of vAPI.tabs.getWindows() ) { - var panel = win.document.getElementById(this.viewId); + var panel = win.document.getElementById(tbb.viewId); panel.parentNode.removeChild(panel); win.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils) - .removeSheet(this.styleURI, 1); + .removeSheet(styleURI, 1); } - }.bind(this)); - this.init = null; -}; + + vAPI.messaging.globalMessageManager.removeMessageListener( + location.host + ':closePopup', + onPopupCloseRequested + ); + }; + + var styleURI = null; + + tbb.onBeforeCreated = function(doc) { + var panel = doc.createElement('panelview'); + + this.populatePanel(doc, panel); + + doc.getElementById('PanelUI-multiView').appendChild(panel); + + doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .loadSheet(styleURI, 1); + }; + + tbb.onCreated = function(button) { + button.setAttribute('badge', ''); + vAPI.setTimeout(updateBadge, 250); + }; + + tbb.onBeforePopupReady = function() { + // https://github.com/gorhill/uBlock/issues/83 + // Add `portrait` class if width is constrained. + try { + this.contentDocument.body.classList.toggle( + 'portrait', + CustomizableUI.getWidget(tbb.id).areaType === CustomizableUI.TYPE_MENU_PANEL + ); + } catch (ex) { + /* noop */ + } + }; + + tbb.closePopup = function(tabBrowser) { + CustomizableUI.hidePanelForNode( + tabBrowser.ownerDocument.getElementById(tbb.viewId) + ); + }; + + tbb.init = function() { + vAPI.messaging.globalMessageManager.addMessageListener( + location.host + ':closePopup', + onPopupCloseRequested + ); + + CustomizableUI.addListener(CUIEvents); + + var style = [ + '#' + this.id + '.off {', + 'list-style-image: url(', + vAPI.getURL('img/browsericons/icon16-off.svg'), + ');', + '}', + '#' + this.id + ' {', + 'list-style-image: url(', + vAPI.getURL('img/browsericons/icon16.svg'), + ');', + '}', + '#' + this.viewId + ',', + '#' + this.viewId + ' > iframe {', + 'width: 160px;', + 'height: 290px;', + 'overflow: hidden !important;', + '}' + ]; + + styleURI = Services.io.newURI( + 'data:text/css,' + encodeURIComponent(style.join('')), + null, + null + ); + + CustomizableUI.createWidget(this); + + cleanupTasks.push(shutdown); + }; +})(); /******************************************************************************/ -vAPI.toolbarButton.onPopupCloseRequested = function({target}) { - if (vAPI.toolbarButton.closePopup) { - vAPI.toolbarButton.closePopup(target); +// No toolbar button. + +(function() { + // Just to ensure the number of cleanup tasks is as expected: toolbar + // button code is one single cleanup task regardless of platform. + if ( vAPI.toolbarButton.init === null ) { + cleanupTasks.push(function(){}); } +})(); + +/******************************************************************************/ + +if ( vAPI.toolbarButton.init !== null ) { + vAPI.toolbarButton.init(); } /******************************************************************************/ - -vAPI.toolbarButton.onBeforeCreated = function(doc) { - var panel = doc.createElement('panelview'); - - vAPI.toolbarButton.populatePanel(doc, panel); - - doc.getElementById('PanelUI-multiView').appendChild(panel); - - doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils) - .loadSheet(this.styleURI, 1); -}; - -vAPI.toolbarButton.populatePanel = function(doc, panel) { - panel.setAttribute('id', this.viewId); - - var iframe = doc.createElement('iframe'); - iframe.setAttribute('type', 'content'); - - panel.appendChild(iframe); - - var updateTimer = null; - var delayedResize = function(attempts) { - if ( updateTimer ) { - return; - } - - // Sanity check - attempts = (attempts || 0) + 1; - if (attempts > 1/*000*/) { - debugger; - console.error('uBlock> delayedResize: giving up after too many attempts'); - return; - } - - updateTimer = vAPI.setTimeout(resizePopup, 10, attempts); - }; - var resizePopup = function(attempts) { - updateTimer = null; - var body = iframe.contentDocument.body; - panel.parentNode.style.maxWidth = 'none'; - // https://github.com/chrisaljoudi/uBlock/issues/730 - // Voodoo programming: this recipe works - var toPixelString = pixels => pixels.toString() + 'px'; - - var clientHeight = body.clientHeight; - iframe.style.height = toPixelString(clientHeight); - panel.style.height = toPixelString(clientHeight + (panel.boxObject.height - panel.clientHeight)); - - var clientWidth = body.clientWidth; - iframe.style.width = toPixelString(clientWidth); - panel.style.width = toPixelString(clientWidth + (panel.boxObject.width - panel.clientWidth)); - - if ( iframe.clientHeight !== body.clientHeight || iframe.clientWidth !== body.clientWidth ) { - delayedResize(attempts); - } - }; - - var CustomizableUI = this.CustomizableUI; - var onPopupReady = function() { - var win = this.contentWindow; - - if ( !win || win.location.host !== location.host ) { - return; - } - - if (CustomizableUI) { - // https://github.com/gorhill/uBlock/issues/83 - // Add `portrait` class if width is constrained. - try { - iframe.contentDocument.body.classList.toggle( - 'portrait', - CustomizableUI.getWidget(vAPI.toolbarButton.id).areaType === CustomizableUI.TYPE_MENU_PANEL - ); - } catch (ex) { - /* noop */ - } - } - - new win.MutationObserver(delayedResize).observe(win.document.body, { - attributes: true, - characterData: true, - subtree: true - }); - - delayedResize(); - }; - - iframe.addEventListener('load', onPopupReady, true); -}; - -/******************************************************************************/ - -vAPI.toolbarButton.onViewShowing = function({target}) { - target.firstChild.setAttribute('src', vAPI.getURL('popup.html')); -}; - -/******************************************************************************/ - -vAPI.toolbarButton.onViewHiding = function({target}) { - target.parentNode.style.maxWidth = ''; - target.firstChild.setAttribute('src', 'about:blank'); -}; - -/******************************************************************************/ - -vAPI.toolbarButton.updateState = function(win, tabId) { - var button = win.document.getElementById(this.id); - - if ( !button ) { - return; - } - - var icon = this.tabs[tabId]; - - button.setAttribute('badge', icon && icon.badge || ''); - button.classList.toggle('off', !icon || !icon.img); -}; - -/******************************************************************************/ - -vAPI.toolbarButton.init(); - /******************************************************************************/ vAPI.contextMenu = { diff --git a/platform/firefox/vapi-client.js b/platform/firefox/vapi-client.js index 8ca8b88a8..88b11da09 100644 --- a/platform/firefox/vapi-client.js +++ b/platform/firefox/vapi-client.js @@ -38,8 +38,8 @@ vAPI.sessionId = String.fromCharCode(Date.now() % 26 + 97) + /******************************************************************************/ -vAPI.setTimeout = vAPI.setTimeout || function(callback, delay, args) { - return setTimeout(function(args) { callback(args); }, delay, args); +vAPI.setTimeout = vAPI.setTimeout || function(callback, delay, extra) { + return setTimeout(function(a) { callback(a); }, delay, extra); }; /******************************************************************************/ diff --git a/platform/firefox/vapi-common.js b/platform/firefox/vapi-common.js index 2ded85ea8..9cd21bb82 100644 --- a/platform/firefox/vapi-common.js +++ b/platform/firefox/vapi-common.js @@ -40,8 +40,8 @@ var vAPI = self.vAPI = self.vAPI || {}; /******************************************************************************/ -vAPI.setTimeout = vAPI.setTimeout || function(callback, delay, args) { - return setTimeout(function(args) { callback(args); }, delay, args); +vAPI.setTimeout = vAPI.setTimeout || function(callback, delay, extra) { + return setTimeout(function(a) { callback(a); }, delay, extra); }; /******************************************************************************/ @@ -125,14 +125,19 @@ vAPI.closePopup = function() { // background page or auxiliary pages. // This storage is optional, but it is nice to have, for a more polished user // experience. -const branchName = 'extensions.' + location.host + '.'; + vAPI.localStorage = { - PB: Services.prefs.getBranch(branchName), + pbName: '', + pb: null, str: Components.classes['@mozilla.org/supports-string;1'] - .createInstance(Components.interfaces.nsISupportsString), + .createInstance(Components.interfaces.nsISupportsString), + init: function(pbName) { + this.pbName = pbName; + this.pb = Services.prefs.getBranch(pbName); + }, getItem: function(key) { try { - return this.PB.getComplexValue( + return this.pb.getComplexValue( key, Components.interfaces.nsISupportsString ).data; @@ -142,7 +147,7 @@ vAPI.localStorage = { }, setItem: function(key, value) { this.str.data = value; - this.PB.setComplexValue( + this.pb.setComplexValue( key, Components.interfaces.nsISupportsString, this.str @@ -150,25 +155,27 @@ vAPI.localStorage = { }, getBool: function(key) { try { - return this.PB.getBoolPref(key); + return this.pb.getBoolPref(key); } catch (ex) { return null; } }, setBool: function(key, value) { - this.PB.setBoolPref(key, value); + this.pb.setBoolPref(key, value); }, setDefaultBool: function(key, defaultValue) { - Services.prefs.getDefaultBranch(branchName).setBoolPref(key, defaultValue); + Services.prefs.getDefaultBranch(this.pbName).setBoolPref(key, defaultValue); }, removeItem: function(key) { - this.PB.clearUserPref(key); + this.pb.clearUserPref(key); }, clear: function() { - this.PB.deleteBranch(''); + this.pb.deleteBranch(''); } }; +vAPI.localStorage.init('extensions.' + location.host + '.'); + /******************************************************************************/ })(); diff --git a/src/js/scriptlets/element-picker.js b/src/js/scriptlets/element-picker.js index cad0c4a59..24e878c0c 100644 --- a/src/js/scriptlets/element-picker.js +++ b/src/js/scriptlets/element-picker.js @@ -952,6 +952,9 @@ var startPicker = function(details) { showDialog({ modifier: true }); return; } + + // A target was specified, but it wasn't found: abort. + stopPicker(); }; /******************************************************************************/ diff --git a/tools/make-firefox.sh b/tools/make-firefox.sh index 85beb60bc..e5da0e766 100755 --- a/tools/make-firefox.sh +++ b/tools/make-firefox.sh @@ -17,6 +17,7 @@ cp -R src/lib $DES/ cp -R src/_locales $DES/ cp src/*.html $DES/ mv $DES/img/icon_128.png $DES/icon.png +cp platform/firefox/css/* $DES/css/ cp platform/firefox/vapi-*.js $DES/js/ cp platform/firefox/bootstrap.js $DES/ cp platform/firefox/frame*.js $DES/ From fd198d9c509e44fd840d5e9142ebc44b55345ca1 Mon Sep 17 00:00:00 2001 From: gorhill Date: Wed, 17 Jun 2015 13:56:10 -0400 Subject: [PATCH 5/5] just renaming using natural resolution --- platform/firefox/css/legacy-toolbar-button.css | 6 +++--- .../img/browsericons/{icon-large-off.svg => icon24-off.svg} | 0 .../firefox/img/browsericons/{icon-large.svg => icon24.svg} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename platform/firefox/img/browsericons/{icon-large-off.svg => icon24-off.svg} (100%) rename platform/firefox/img/browsericons/{icon-large.svg => icon24.svg} (100%) diff --git a/platform/firefox/css/legacy-toolbar-button.css b/platform/firefox/css/legacy-toolbar-button.css index 37900cb30..b6489d555 100644 --- a/platform/firefox/css/legacy-toolbar-button.css +++ b/platform/firefox/css/legacy-toolbar-button.css @@ -1,8 +1,8 @@ #uBlock0-legacy-button { - list-style-image: url('../img/browsericons/icon-large.svg'); + list-style-image: url('../img/browsericons/icon24.svg'); } #uBlock0-legacy-button.off { - list-style-image: url('../img/browsericons/icon-large-off.svg'); + list-style-image: url('../img/browsericons/icon24-off.svg'); } toolbar[iconsize="small"] #uBlock0-legacy-button { @@ -30,7 +30,7 @@ toolbar[iconsize="small"] #uBlock0-legacy-button.off { /* Override off state when in palette */ toolbarpaletteitem #uBlock0-legacy-button.off { - list-style-image: url('../img/browsericons/icon-large.svg'); + list-style-image: url('../img/browsericons/icon24.svg'); } /* Override badge when in palette */ diff --git a/platform/firefox/img/browsericons/icon-large-off.svg b/platform/firefox/img/browsericons/icon24-off.svg similarity index 100% rename from platform/firefox/img/browsericons/icon-large-off.svg rename to platform/firefox/img/browsericons/icon24-off.svg diff --git a/platform/firefox/img/browsericons/icon-large.svg b/platform/firefox/img/browsericons/icon24.svg similarity index 100% rename from platform/firefox/img/browsericons/icon-large.svg rename to platform/firefox/img/browsericons/icon24.svg