1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-11-06 02:42:33 +01:00

Bring setIcon performance improvements to Chrome

This commit is contained in:
Chris 2015-05-01 04:40:17 -06:00
parent b9b8f739a0
commit 2a105b3b59

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
µBlock - a browser extension to block requests. µBlock - a browser extension to block requests.
Copyright (C) 2014 The µBlock authors Copyright (C) 2014-2015 The µBlock authors
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -74,8 +74,17 @@ vAPI.storage = chrome.storage.local;
/******************************************************************************/ /******************************************************************************/
// https://github.com/gorhill/uBlock/issues/101 vAPI.tabs = {};
// chrome API expects tab id to be a number, not a string.
/******************************************************************************/
vAPI.isBehindTheSceneTabId = function(tabId) {
return tabId.toString() === '-1';
};
vAPI.noTabId = '-1';
/******************************************************************************/
var toChromiumTabId = function(tabId) { var toChromiumTabId = function(tabId) {
if ( typeof tabId === 'string' ) { if ( typeof tabId === 'string' ) {
@ -89,22 +98,11 @@ var toChromiumTabId = function(tabId) {
/******************************************************************************/ /******************************************************************************/
vAPI.tabs = {};
/******************************************************************************/
vAPI.isBehindTheSceneTabId = function(tabId) {
return tabId.toString() === '-1';
};
vAPI.noTabId = '-1';
/******************************************************************************/
vAPI.tabs.registerListeners = function() { vAPI.tabs.registerListeners = function() {
var onNavigationClient = this.onNavigation || noopFunc; var onNavigationClient = this.onNavigation || noopFunc;
var onPopupClient = this.onPopup || noopFunc; var onPopupClient = this.onPopup || noopFunc;
var onUpdatedClient = this.onUpdated || noopFunc; var onUpdatedClient = this.onUpdated || noopFunc;
var onClosedClient = this.onClosed || noopFunc;
// https://developer.chrome.com/extensions/webNavigation // https://developer.chrome.com/extensions/webNavigation
// [onCreatedNavigationTarget ->] // [onCreatedNavigationTarget ->]
@ -203,21 +201,23 @@ vAPI.tabs.registerListeners = function() {
return; return;
} }
onNavigationClient(details); onNavigationClient(details);
delete iconStateForTabId[details.tabId];
//console.debug('onCommitted: popup candidate tab id %d = "%s"', details.tabId, details.url); //console.debug('onCommitted: popup candidate tab id %d = "%s"', details.tabId, details.url);
if ( popupCandidateTest(details) === true ) { if ( popupCandidateTest(details) === true ) {
return; return;
} }
popupCandidateDestroy(details); popupCandidateDestroy(details);
}; };
var onClosed = function(tabId) {
delete iconStateForTabId[tabId];
onClosedClient(tabId);
};
chrome.webNavigation.onCreatedNavigationTarget.addListener(onCreatedNavigationTarget); chrome.webNavigation.onCreatedNavigationTarget.addListener(onCreatedNavigationTarget);
chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigate); chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigate);
chrome.webNavigation.onCommitted.addListener(onCommitted); chrome.webNavigation.onCommitted.addListener(onCommitted);
chrome.tabs.onUpdated.addListener(onUpdated); chrome.tabs.onUpdated.addListener(onUpdated);
chrome.tabs.onRemoved.addListener(onClosed);
if ( typeof this.onClosed === 'function' ) {
chrome.tabs.onRemoved.addListener(this.onClosed);
}
}; };
/******************************************************************************/ /******************************************************************************/
@ -236,8 +236,7 @@ vAPI.tabs.get = function(tabId, callback) {
tabId = toChromiumTabId(tabId); tabId = toChromiumTabId(tabId);
if ( tabId === 0 ) { if ( tabId === 0 ) {
onTabReady(null); onTabReady(null);
} } else {
else {
chrome.tabs.get(tabId, onTabReady); chrome.tabs.get(tabId, onTabReady);
} }
return; return;
@ -380,10 +379,11 @@ vAPI.tabs.remove = function(tabId) {
var onTabRemoved = function() { var onTabRemoved = function() {
// https://code.google.com/p/chromium/issues/detail?id=410868#c8 // https://code.google.com/p/chromium/issues/detail?id=410868#c8
if ( vAPI.lastError() ) { if ( chrome.runtime.lastError ) {
/* noop */ /* noop */
} }
}; };
chrome.tabs.remove(tabId, onTabRemoved); chrome.tabs.remove(tabId, onTabRemoved);
}; };
@ -426,6 +426,23 @@ vAPI.tabs.injectScript = function(tabId, details, callback) {
/******************************************************************************/ /******************************************************************************/
var IconState = function(badge, img) {
this.badge = badge;
// ^ a number -- the badge 'value'
this.img = img;
// ^ a string -- 'on' or 'off'
this.dirty = (1 << 1) | (1 << 0);
/* ^ bitmask AB: two bits, A and B
where A is whether img has changed and needs render
and B is whether badge has changed and needs render */
};
var iconStateForTabId = {}; // {tabId: IconState}
var ICON_PATHS = {
"on": { '19': 'img/browsericons/icon19.png', '38': 'img/browsericons/icon38.png' },
"off": { '19': 'img/browsericons/icon19-off.png', '38': 'img/browsericons/icon38-off.png' }
};
// Must read: https://code.google.com/p/chromium/issues/detail?id=410868#c8 // Must read: https://code.google.com/p/chromium/issues/detail?id=410868#c8
// https://github.com/chrisaljoudi/uBlock/issues/19 // https://github.com/chrisaljoudi/uBlock/issues/19
@ -444,19 +461,26 @@ vAPI.setIcon = function(tabId, iconStatus, badge) {
return; return;
} }
chrome.browserAction.setBadgeText({ tabId: tabId, text: badge }); chrome.browserAction.setBadgeText({ tabId: tabId, text: badge });
if ( badge !== '' ) { chrome.browserAction.setBadgeBackgroundColor({
chrome.browserAction.setBadgeBackgroundColor({ tabId: tabId,
tabId: tabId, color: '#666'
color: '#666' });
});
}
}; };
var state = iconStateForTabId[tabId];
var iconPaths = iconStatus === 'on' ? if(typeof state === "undefined") {
{ '19': 'img/browsericons/icon19.png', '38': 'img/browsericons/icon38.png' } : state = iconStateForTabId[tabId] = new IconState(badge, iconStatus);
{ '19': 'img/browsericons/icon19-off.png', '38': 'img/browsericons/icon38-off.png' }; }
else {
chrome.browserAction.setIcon({ tabId: tabId, path: iconPaths }, onIconReady); state.dirty = ((state.badge !== badge) << 1) | ((state.img !== iconStatus) << 0);
state.badge = badge;
state.img = iconStatus;
}
if(state.dirty & 1) { // got a new icon?
chrome.browserAction.setIcon({ tabId: tabId, path: ICON_PATHS[iconStatus] }, onIconReady);
}
else if(state.dirty & 2) {
chrome.browserAction.setBadgeText({ tabId: tabId, text: badge });
}
}; };
/******************************************************************************/ /******************************************************************************/
@ -762,21 +786,16 @@ vAPI.onLoadAllCompleted = function() {
} }
}; };
var iconPaths = {
'19': 'img/browsericons/icon19-off.png',
'38': 'img/browsericons/icon38-off.png'
};
try { try {
// Hello? Is this a recent version of Chrome? // Hello? Is this a recent version of Chrome?
chrome.browserAction.setIcon({ path: iconPaths }); chrome.browserAction.setIcon({ path: ICON_PATHS.off });
} }
catch(e) { catch(e) {
// Nope; looks like older than v23 // Nope; looks like older than v23
chrome.browserAction._setIcon = chrome.browserAction.setIcon; chrome.browserAction._setIcon = chrome.browserAction.setIcon;
// Shim // Shim
chrome.browserAction.setIcon = function(x, clbk) { chrome.browserAction.setIcon = function(x, callback) {
this._setIcon({path: x.path[19], tabId: x.tabId}, clbk); this._setIcon({path: x.path[19], tabId: x.tabId}, callback);
}; };
// maybe this time... I'll win! // maybe this time... I'll win!
chrome.browserAction.setIcon({ path: iconPaths }); chrome.browserAction.setIcon({ path: iconPaths });