aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgorhill <rhill@raymondhill.net>2015-06-17 13:49:43 -0400
committergorhill <rhill@raymondhill.net>2015-06-17 14:06:59 -0400
commit34485a04658ae7d8357dabe5e42b18e3e066a4b9 (patch)
treef54dd3ef03a63194886edfe52407221774205f77
parent9406e40fdc1644040234b3e0b240e24fa576a214 (diff)
downloaduBlock-34485a04658ae7d8357dabe5e42b18e3e066a4b9.zip
uBlock-34485a04658ae7d8357dabe5e42b18e3e066a4b9.tar.gz
uBlock-34485a04658ae7d8357dabe5e42b18e3e066a4b9.tar.bz2
code review
-rw-r--r--platform/firefox/css/legacy-toolbar-button.css52
-rw-r--r--platform/firefox/frameModule.js11
-rw-r--r--platform/firefox/vapi-background.js1101
-rw-r--r--platform/firefox/vapi-client.js4
-rw-r--r--platform/firefox/vapi-common.js31
-rw-r--r--src/js/scriptlets/element-picker.js3
-rwxr-xr-xtools/make-firefox.sh1
7 files changed, 672 insertions, 531 deletions
diff --git a/platform/firefox/css/legacy-toolbar-button.css b/platform/firefox/css/legacy-toolbar-button.css
index f29052a..37900cb 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 1d759a8..87edc75 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 48a6538..0503088 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,38 +941,51 @@ var tabWatcher = (function() {
vAPI.setIcon(tabIdFromTarget(target), getOwnerWindow(target));
};
- var onWindowLoad = function(ev) {
- if ( ev ) {
- this.removeEventListener(ev.type, onWindowLoad);
- }
-
- var wintype = this.document.documentElement.getAttribute('windowtype');
- if ( wintype !== 'navigator:browser' ) {
- return;
- }
-
- var tabBrowser = getTabBrowser(this);
+ var attachToTabBrowser = function(window) {
+ var tabBrowser = getTabBrowser(window);
if ( !tabBrowser ) {
- return;
+ return false;
}
var tabContainer;
- if ( tabBrowser.deck ) {
- // Fennec
+ if ( tabBrowser.deck ) { // Fennec
tabContainer = tabBrowser.deck;
- } else if ( tabBrowser.tabContainer ) {
- // desktop Firefox
+ } else if ( tabBrowser.tabContainer ) { // Firefox
tabContainer = tabBrowser.tabContainer;
- vAPI.contextMenu.register(this.document);
+ vAPI.contextMenu.register(window.document);
} else {
- return;
+ 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);
- // when new window is opened TabSelect doesn't run on the selected tab?
+ return true;
+ };
+
+ var onWindowLoad = function(ev) {
+ if ( ev ) {
+ this.removeEventListener(ev.type, onWindowLoad);
+ }
+
+ var wintype = this.document.documentElement.getAttribute('windowtype');
+ if ( wintype !== 'navigator:browser' ) {
+ 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 onWindowUnload = function() {
@@ -1854,6 +1777,7 @@ vAPI.net.registerListeners = function() {
};
/******************************************************************************/
+/******************************************************************************/
vAPI.toolbarButton = {
id: location.host + '-button',
@@ -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;
+// Fennec
- 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;
- };
+(function() {
+ if ( !vAPI.fennec ) {
+ return;
+ }
- 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
- });
- };
+ var tbb = vAPI.toolbarButton;
+
+ tbb.codePath = 'fennec';
+
+ var menuItemIds = new WeakMap();
- tb.updateState = function(win, tabId) {
- var id = this.menuItemIds.get(win);
+ var shutdown = function() {
+ for ( var win of vAPI.tabs.getWindows() ) {
+ var id = menuItemIds.get(win);
if ( !id ) {
- return;
+ continue;
}
- win.NativeWindow.menu.update(id, {
- name: this.getMenuItemLabel(tabId)
- });
- };
+ 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 = tb.getMenuItemLabel();
+ var label = this.getMenuItemLabel();
var id = win.NativeWindow.menu.add({
name: label,
- callback: tb.onClick
+ callback: this.onClick
});
- tb.menuItemIds.set(win, id);
+ 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);
- }
- }
- });
+ cleanupTasks.push(shutdown);
+ };
+})();
+
+/******************************************************************************/
+// Non-Fennec: common code paths.
+
+(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.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);
+ }
- var CustomizableUI;
+ new win.MutationObserver(resizePopupDelayed).observe(win.document.body, {
+ attributes: true,
+ characterData: true,
+ subtree: true
+ });
- var forceLegacyToolbarButton = vAPI.localStorage.getBool("forceLegacyToolbarButton");
- if (!forceLegacyToolbarButton) {
+ 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 !== null ) {
+ return;
+ }
- 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;
- }
+ tbb.codePath = 'legacy';
+ tbb.id = 'uBlock0-legacy-button'; // NOTE: must match legacy-toolbar-button.css
+ tbb.viewId = tbb.id + '-panel';
- 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();
- }
+ var sss = null;
+ var styleSheetUri = null;
- 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);
- }
- }
+ var addLegacyToolbarButton = function(window) {
+ var document = window.document;
- 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);
- }
- }
- }
- }
+ 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);
- vAPI.toolbarButton.attachToNewWindow = function(win) {
- addLegacyToolbarButton(win);
+ 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);
+ }
}
- cleanupTasks.push(function() {
- for ( var win of vAPI.tabs.getWindows() ) {
- var toolbarButton = win.document.getElementById(legacyButtonId);
- if (toolbarButton) {
- toolbarButton.parentNode.removeChild(toolbarButton);
+ 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);
+ }
+ };
- if (sss.sheetRegistered(styleSheetUri, sss.AUTHOR_SHEET)) {
- sss.unregisterSheet(styleSheetUri, sss.AUTHOR_SHEET);
+ var shutdown = function() {
+ for ( var win of vAPI.tabs.getWindows() ) {
+ var toolbarButton = win.document.getElementById(tbb.id);
+ if ( toolbarButton ) {
+ toolbarButton.parentNode.removeChild(toolbarButton);
}
- }.bind(this));
+ }
+ 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);
- this.CustomizableUI = CustomizableUI;
-
- 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 platformVersion = Services.appinfo.platformVersion;
-
- if ( Services.vc.compare(platformVersion, '36.0') < 0 ) {
- this.styleURI.push(
+ 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,236 +2252,229 @@ vAPI.toolbarButton.init = function() {
'background: #666;',
'content: attr(badge);',
'}'
- );
- } 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);
+ styleURI = Services.io.newURI(
+ 'data:text/css,' + encodeURIComponent(style.join('')),
+ null,
+ null
+ );
- // 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.closePopup = function(tabBrowser) {
+ CustomizableUI.hidePanelForNode(
+ tabBrowser.ownerDocument.getElementById(this.viewId)
+ );
+ };
- this.CUIEvents.updateBadgeStyle = function() {
- var css = [
- 'background: #666',
- 'color: #fff'
- ].join(';');
+ CustomizableUI.createWidget(this);
- 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;
- }
+ cleanupTasks.push(shutdown);
+ };
+})();
- badge.style.cssText = css;
- }
- };
+/******************************************************************************/
- this.onCreated = function(button) {
- button.setAttribute('badge', '');
- vAPI.setTimeout(updateBadge, 250);
- };
+// Firefox Australis >= 36.
- CustomizableUI.addListener(this.CUIEvents);
+(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(';');
- CustomizableUI.createWidget(this);
+ 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;
+ }
- cleanupTasks.push(function() {
- if ( this.CUIEvents ) {
- CustomizableUI.removeListener(this.CUIEvents);
+ badge.style.cssText = badgeCSSRules;
}
+ };
+
+ var updateBadge = function() {
+ var wId = tbb.id;
+ var buttonInPanel = CustomizableUI.getWidget(wId).areaType === CustomizableUI.TYPE_MENU_PANEL;
- CustomizableUI.destroyWidget(this.id);
-
for ( var win of vAPI.tabs.getWindows() ) {
- var panel = win.document.getElementById(this.viewId);
- panel.parentNode.removeChild(panel);
- win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils)
- .removeSheet(this.styleURI, 1);
+ var button = win.document.getElementById(wId);
+ if ( button === null ) {
+ continue;
+ }
+ if ( buttonInPanel ) {
+ button.classList.remove('badged-button');
+ continue;
+ }
+ button.classList.add('badged-button');
}
- }.bind(this));
- this.init = null;
-};
+ if ( buttonInPanel ) {
+ return;
+ }
-/******************************************************************************/
+ // Anonymous elements need some time to be reachable
+ vAPI.setTimeout(updateBadgeStyle, 250);
+ }.bind(CUIEvents);
-vAPI.toolbarButton.onPopupCloseRequested = function({target}) {
- if (vAPI.toolbarButton.closePopup) {
- vAPI.toolbarButton.closePopup(target);
- }
-}
+ // 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);
+ }
+ };
-vAPI.toolbarButton.onBeforeCreated = function(doc) {
- var panel = doc.createElement('panelview');
-
- vAPI.toolbarButton.populatePanel(doc, panel);
+ var shutdown = function() {
+ CustomizableUI.removeListener(CUIEvents);
+ CustomizableUI.destroyWidget(tbb.id);
- doc.getElementById('PanelUI-multiView').appendChild(panel);
+ 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);
+ }
- doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils)
- .loadSheet(this.styleURI, 1);
-};
-vAPI.toolbarButton.populatePanel = function(doc, panel) {
- panel.setAttribute('id', this.viewId);
+ vAPI.messaging.globalMessageManager.removeMessageListener(
+ location.host + ':closePopup',
+ onPopupCloseRequested
+ );
+ };
- var iframe = doc.createElement('iframe');
- iframe.setAttribute('type', 'content');
+ var styleURI = null;
- panel.appendChild(iframe);
+ tbb.onBeforeCreated = function(doc) {
+ var panel = doc.createElement('panelview');
- var updateTimer = null;
- var delayedResize = function(attempts) {
- if ( updateTimer ) {
- return;
- }
+ this.populatePanel(doc, panel);
- // Sanity check
- attempts = (attempts || 0) + 1;
- if (attempts > 1/*000*/) {
- debugger;
- console.error('uBlock> delayedResize: giving up after too many attempts');
- return;
- }
+ doc.getElementById('PanelUI-multiView').appendChild(panel);
- updateTimer = vAPI.setTimeout(resizePopup, 10, attempts);
+ doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils)
+ .loadSheet(styleURI, 1);
};
- 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);
- }
+ tbb.onCreated = function(button) {
+ button.setAttribute('badge', '');
+ vAPI.setTimeout(updateBadge, 250);
};
- 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 */
- }
+ 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 */
}
+ };
- new win.MutationObserver(delayedResize).observe(win.document.body, {
- attributes: true,
- characterData: true,
- subtree: true
- });
-
- delayedResize();
+ tbb.closePopup = function(tabBrowser) {
+ CustomizableUI.hidePanelForNode(
+ tabBrowser.ownerDocument.getElementById(tbb.viewId)
+ );
};
- iframe.addEventListener('load', onPopupReady, true);
-};
+ 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;',
+ '}'
+ ];
-vAPI.toolbarButton.onViewShowing = function({target}) {
- target.firstChild.setAttribute('src', vAPI.getURL('popup.html'));
-};
+ styleURI = Services.io.newURI(
+ 'data:text/css,' + encodeURIComponent(style.join('')),
+ null,
+ null
+ );
-/******************************************************************************/
+ CustomizableUI.createWidget(this);
-vAPI.toolbarButton.onViewHiding = function({target}) {
- target.parentNode.style.maxWidth = '';
- target.firstChild.setAttribute('src', 'about:blank');
-};
+ cleanupTasks.push(shutdown);
+ };
+})();
/******************************************************************************/
-vAPI.toolbarButton.updateState = function(win, tabId) {
- var button = win.document.getElementById(this.id);
+// No toolbar button.
- if ( !button ) {
- return;
+(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(){});
}
-
- var icon = this.tabs[tabId];
-
- button.setAttribute('badge', icon && icon.badge || '');
- button.classList.toggle('off', !icon || !icon.img);
-};
+})();
/******************************************************************************/
-vAPI.toolbarButton.init();
+if ( vAPI.toolbarButton.init !== null ) {
+ vAPI.toolbarButton.init();
+}
/******************************************************************************/
+/******************************************************************************/
vAPI.contextMenu = {
contextMap: {
diff --git a/platform/firefox/vapi-client.js b/platform/firefox/vapi-client.js
index 8ca8b88..88b11da 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 2ded85e..9cd21bb 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 cad0c4a..24e878c 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 85beb60..e5da0e7 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/