From 35003b7e23f6ad8f5c8a5b3a9704481c0c753ba9 Mon Sep 17 00:00:00 2001 From: gorhill Date: Mon, 20 Oct 2014 16:40:09 -0400 Subject: [PATCH] continued refactoring work: revert, revert all, persist are back --- src/js/httpsb.js | 53 +-------- src/js/matrix.js | 186 +++++++++++++++++------------ src/js/messaging-handlers.js | 70 ++++++++--- src/js/popup.js | 224 ++++++++++++----------------------- 4 files changed, 239 insertions(+), 294 deletions(-) diff --git a/src/js/httpsb.js b/src/js/httpsb.js index b76d62d..08a290f 100644 --- a/src/js/httpsb.js +++ b/src/js/httpsb.js @@ -135,44 +135,6 @@ /******************************************************************************/ -// Apply a set of rules - -µMatrix.applyRulesetPermanently = function(ruleset) { - var changed = false; - var aa, i, o; - if ( aa = ruleset.rulesToAdd ) { - i = aa.length; - while ( i-- ) { - o = aa[i]; - changed = this.pMatrix.setRule(o.k, o.v) || changed; - } - } - if ( aa = ruleset.rulesToRemove ) { - i = aa.length; - while ( i-- ) { - changed = this.pMatrix.setRule(aa[i]) || changed; - } - } - if ( aa = ruleset.switchesToAdd ) { - i = aa.length; - while ( i-- ) { - o = aa[i]; - changed = this.pMatrix.setSwitch(o.k, o.v) || changed; - } - } - if ( aa = ruleset.switchesToRemove ) { - i = aa.length; - while ( i-- ) { - changed = this.pMatrix.setSwitch(aa[i]) || changed; - } - } - if ( changed ) { - this.saveMatrix(); - } -}; - -/******************************************************************************/ - // TODO: Should type be transposed by the caller or in place here? Not an // issue at this point but to keep in mind as this function is called // more and more from different places. @@ -214,23 +176,12 @@ /******************************************************************************/ -µMatrix.getTemporaryColor = function(srcHostname, type, desHostname) { - // console.debug('HTTP Switchboard > getTemporaryColor(%s, %s, %s) = %s', src, type, hostname, evaluate(src, type, hostname)); - return this.tMatrix.evaluateCellZXYColor(srcHostname, desHostname, type); -}; - -µMatrix.getPermanentColor = function(srcHostname, type, desHostname) { - return this.pMatrix.evaluateCellZXYColor(srcHostname, desHostname, type); -}; - -/******************************************************************************/ - µMatrix.getTemporaryMtxFiltering = function(srcHostname) { - return this.tMatrix.evaluateSwitch(srcHostname); + return this.tMatrix.evaluateSwitchZ(srcHostname); }; µMatrix.getPermanentMtxFiltering = function(srcHostname) { - return this.pMatrix.evaluateSwitch(srcHostname); + return this.pMatrix.evaluateSwitchZ(srcHostname); }; µMatrix.toggleTemporaryMtxFiltering = function(srcHostname, state) { diff --git a/src/js/matrix.js b/src/js/matrix.js index de41acf..6775daa 100644 --- a/src/js/matrix.js +++ b/src/js/matrix.js @@ -70,6 +70,26 @@ var typeBitOffsets = { /******************************************************************************/ +var columnHeaders = (function() { + var out = {}; + var i = 0; + for ( var type in typeBitOffsets ) { + if ( typeBitOffsets.hasOwnProperty(type) === false ) { + continue; + } + out[type] = i++; + } + return out; +})(); + +/******************************************************************************/ + +Matrix.getColumnHeaders = function() { + return columnHeaders; +}; + +/******************************************************************************/ + Matrix.prototype.reset = function() { this.switchedOn = {}; this.rules = {}; @@ -99,25 +119,6 @@ Matrix.prototype.assign = function(other) { /******************************************************************************/ -// If value is undefined, the rule is removed - -Matrix.prototype.setRule = function(rule, value) { - if ( value !== undefined ) { - if ( this.rules.hasOwnProperty(rule) === false || this.rules[rule] !== value ) { - this.rules[rule] = value; - return true; - } - } else { - if ( this.rules.hasOwnProperty(rule) ) { - delete this.rules[rule]; - return true; - } - } - return false; -}; - -/******************************************************************************/ - // If value is undefined, the switch is removed Matrix.prototype.setSwitch = function(srcHostname, state) { @@ -137,14 +138,14 @@ Matrix.prototype.setSwitch = function(srcHostname, state) { /******************************************************************************/ -Matrix.prototype.setCell = function(srcHostname, desHostname, type, v) { +Matrix.prototype.setCell = function(srcHostname, desHostname, type, state) { var bitOffset = typeBitOffsets[type]; var k = srcHostname + ' ' + desHostname; var oldBitmap = this.rules[k]; if ( oldBitmap === undefined ) { oldBitmap = 0; } - var newBitmap = oldBitmap & ~(3 << bitOffset) | (v << bitOffset); + var newBitmap = oldBitmap & ~(3 << bitOffset) | (state << bitOffset); if ( newBitmap === oldBitmap ) { return false; } @@ -218,7 +219,7 @@ Matrix.prototype.evaluateCell = function(srcHostname, desHostname, type) { /******************************************************************************/ Matrix.prototype.evaluateCellZ = function(srcHostname, desHostname, type) { - if ( this.evaluateSwitch(srcHostname) !== true ) { + if ( this.evaluateSwitchZ(srcHostname) !== true ) { return Matrix.Transparent; } var bitOffset = typeBitOffsets[type]; @@ -286,40 +287,39 @@ Matrix.prototype.evaluateCellZXY = function(srcHostname, desHostname, type) { /******************************************************************************/ -Matrix.prototype.evaluateRowZ = function(srcHostname, desHostname) { +Matrix.prototype.evaluateRow = function(srcHostname, desHostname) { var out = []; for ( var type in typeBitOffsets ) { if ( typeBitOffsets.hasOwnProperty(type) === false ) { continue; } - out.push(this.evaluateCellZ(srcHostname, desHostname, type)); + out.push(this.evaluateCell(srcHostname, desHostname, type)); } return out.join(''); }; /******************************************************************************/ -Matrix.prototype.evaluateRowZXY = function(srcHostname, desHostname) { +Matrix.prototype.evaluateRowZ = function(srcHostname, desHostname) { var out = []; for ( var type in typeBitOffsets ) { if ( typeBitOffsets.hasOwnProperty(type) === false ) { continue; } - out.push(this.evaluateCellZXY(srcHostname, desHostname, type)); + out.push(this.evaluateCellZ(srcHostname, desHostname, type)); } - return out; + return out.join(''); }; /******************************************************************************/ -Matrix.prototype.getColumnHeaders = function() { - var out = {}; - var i = 0; +Matrix.prototype.evaluateRowZXY = function(srcHostname, desHostname) { + var out = []; for ( var type in typeBitOffsets ) { if ( typeBitOffsets.hasOwnProperty(type) === false ) { continue; } - out[type] = i++; + out.push(this.evaluateCellZXY(srcHostname, desHostname, type)); } return out; }; @@ -368,28 +368,9 @@ Matrix.prototype.extractZRules = function(srcHostname, desHostname, out) { /******************************************************************************/ -Matrix.prototype.evaluateCellZXYColor = function(srcHostname, desHostname, type) { - var v = this.evaluateCellZXY(srcHostname, desHostname, type); - if ( v === Matrix.RedIndirect ) { - return 'ri'; - } - if ( v === Matrix.GreenIndirect ) { - return 'gi'; - } - if ( v === Matrix.RedDirect ) { - return 'rd'; - } - if ( v === Matrix.GreenDirect ) { - return 'gd'; - } - return 'xx'; -}; - -/******************************************************************************/ - Matrix.prototype.toggleSwitch = function(srcHostname, newState) { delete this.switchedOn[srcHostname]; - var oldState = this.evaluateSwitch(srcHostname); + var oldState = this.evaluateSwitchZ(srcHostname); if ( newState === oldState ) { return false; } @@ -400,37 +381,23 @@ Matrix.prototype.toggleSwitch = function(srcHostname, newState) { /******************************************************************************/ Matrix.prototype.evaluateSwitch = function(srcHostname) { - var b; - var s = srcHostname; - var pos; - for (;;) { - b = this.switchedOn[s]; - if ( b !== undefined ) { - return b; - } - pos = s.indexOf('.'); - if ( pos !== -1 ) { - s = s.slice(pos + 1); - continue; - } - if ( s !== '*' ) { - s = '*'; - continue; - } - break; + var b = this.switchedOn[srcHostname]; + if ( b !== undefined ) { + return b; } return true; }; /******************************************************************************/ -Matrix.prototype.extractSwitches = function(srcHostname, out) { +Matrix.prototype.evaluateSwitchZ = function(srcHostname) { + var b; var s = srcHostname; - var v, pos; + var pos; for (;;) { - v = this.rules[s]; - if ( v !== undefined ) { - out[s] = v; + b = this.switchedOn[s]; + if ( b !== undefined ) { + return b; } pos = s.indexOf('.'); if ( pos !== -1 ) { @@ -443,6 +410,7 @@ Matrix.prototype.extractSwitches = function(srcHostname, out) { } break; } + return true; }; /******************************************************************************/ @@ -478,6 +446,76 @@ Matrix.prototype.fromSelfie = function(selfie) { /******************************************************************************/ +Matrix.prototype.diff = function(other, srcHostname, desHostnames) { + var out = []; + var desHostname, type; + var i, pos, thisVal, otherVal; + for (;;) { + thisVal = this.evaluateSwitch(srcHostname); + otherVal = other.evaluateSwitch(srcHostname); + if ( thisVal !== otherVal ) { + out.push({ + 'what': 'switch', + 'src': srcHostname + }); + } + i = desHostnames.length; + while ( i-- ) { + desHostname = desHostnames[i]; + for ( type in typeBitOffsets ) { + if ( typeBitOffsets.hasOwnProperty(type) === false ) { + continue; + } + thisVal = this.evaluateCell(srcHostname, desHostname, type); + otherVal = other.evaluateCell(srcHostname, desHostname, type); + if ( thisVal === otherVal ) { + continue; + } + out.push({ + 'what': 'rule', + 'src': srcHostname, + 'des': desHostname, + 'type': type + }); + } + } + if ( srcHostname === '*' ) { + break; + } + pos = srcHostname.indexOf('.'); + if ( pos !== -1 ) { + srcHostname = srcHostname.slice(pos + 1); + } else { + srcHostname = '*'; + } + } + return out; +}; + +/******************************************************************************/ + +Matrix.prototype.applyDiff = function(diff, from) { + var changed = false; + var i = diff.length; + var action, val; + while ( i-- ) { + action = diff[i]; + if ( action.what === 'switch' ) { + val = from.evaluateSwitch(action.src); + changed = this.setSwitch(action.src, val) || changed; + continue; + } + if ( action.what === 'rule' ) { + val = from.evaluateCell(action.src, action.des, action.type); + changed = this.setCell(action.src, action.des, action.type, val) || changed; + continue; + } + } + return changed; +}; + +/******************************************************************************/ + return Matrix; /******************************************************************************/ diff --git a/src/js/messaging-handlers.js b/src/js/messaging-handlers.js index dae75f1..9c8b17b 100644 --- a/src/js/messaging-handlers.js +++ b/src/js/messaging-handlers.js @@ -43,16 +43,16 @@ var smartReload = function(tabs) { // Constructor is faster than object literal -var HostnameSnapshot = function(srcHostname, desHostname, desDomain) { +var RowSnapshot = function(srcHostname, desHostname, desDomain) { this.domain = desDomain; this.temporary = µm.tMatrix.evaluateRowZXY(srcHostname, desHostname); this.permanent = µm.pMatrix.evaluateRowZXY(srcHostname, desHostname); - this.counts = HostnameSnapshot.counts.slice(); - this.totals = HostnameSnapshot.counts.slice(); + this.counts = RowSnapshot.counts.slice(); + this.totals = RowSnapshot.counts.slice(); }; -HostnameSnapshot.counts = (function() { - var i = Object.keys(µm.tMatrix.getColumnHeaders()).length; +RowSnapshot.counts = (function() { + var i = Object.keys(µm.Matrix.getColumnHeaders()).length; var aa = new Array(i); while ( i-- ) { aa[i] = 0; @@ -62,19 +62,32 @@ HostnameSnapshot.counts = (function() { /******************************************************************************/ -var matrixSnapshot = function (tabId) { +var matrixSnapshot = function(details) { var r = { - tabId: tabId, + tabId: details.tabId, url: '', hostname: '', domain: '', + scopeLevel: µm.userSettings.scopeLevel, scope: '*', - headers: µm.tMatrix.getColumnHeaders(), + headers: µm.Matrix.getColumnHeaders(), + tSwitch: false, + pSwitch: false, rows: {}, - rowCount: 0 + rowCount: 0, + diff: [] }; - - var pageStore = µm.pageStatsFromTabId(tabId); +/* + // Allow to scope on behind-the-scene virtual tab + if ( tab.url.indexOf('chrome-extension://' + chrome.runtime.id + '/') === 0 ) { + targetTabId = µm.behindTheSceneTabId; + targetPageURL = µm.behindTheSceneURL; + } else { + targetTabId = tab.id; + targetPageURL = µm.pageUrlFromTabId(targetTabId); + } +*/ + var pageStore = µm.pageStatsFromTabId(details.tabId); if ( !pageStore ) { return r; } @@ -85,14 +98,17 @@ var matrixSnapshot = function (tabId) { r.hostname = pageStore.pageHostname; r.domain = pageStore.pageDomain; - if ( µm.userSettings.scopeLevel === 'site' ) { + if ( r.scopeLevel === 'site' ) { r.scope = r.hostname; - } else if ( µm.userSettings.scopeLevel === 'domain' ) { + } else if ( r.scopeLevel === 'domain' ) { r.scope = r.domain; } + r.tSwitch = µm.tMatrix.evaluateSwitchZ(r.scope); + r.pSwitch = µm.pMatrix.evaluateSwitchZ(r.scope); + // This one always exist - r.rows['*'] = new HostnameSnapshot(r.hostname, '*', '*'); + r.rows['*'] = new RowSnapshot(r.scope, '*', '*'); r.rowCount += 1; var µmuri = µm.URI; @@ -124,7 +140,7 @@ var matrixSnapshot = function (tabId) { if ( r.rows.hasOwnProperty(desHostname) !== false ) { break; } - r.rows[desHostname] = new HostnameSnapshot(r.hostname, desHostname, reqDomain); + r.rows[desHostname] = new RowSnapshot(r.scope, desHostname, reqDomain); r.rowCount += 1; if ( desHostname === reqDomain ) { break; @@ -153,6 +169,8 @@ var matrixSnapshot = function (tabId) { row.totals[anyIndex] += 1; } + r.diff = µm.tMatrix.diff(µm.pMatrix, r.hostname, Object.keys(r.rows)); + return r; }; @@ -171,23 +189,37 @@ var onMessage = function(request, sender, callback) { switch ( request.what ) { case 'disconnected': // https://github.com/gorhill/httpswitchboard/issues/94 - if ( µMatrix.userSettings.smartAutoReload ) { + if ( µm.userSettings.smartAutoReload ) { chrome.tabs.query({ active: true }, smartReload); } break; case 'matrixSnapshot': - response = matrixSnapshot(request.tabId); + response = matrixSnapshot(request); + break; + + case 'applyDiffToPermanentMatrix': // aka "persist" + if ( µm.pMatrix.applyDiff(request.diff, µm.tMatrix) ) { + µm.saveMatrix(); + } + break; + + case 'applyDiffToTemporaryMatrix': // aka "revert" + µm.tMatrix.applyDiff(request.diff, µm.pMatrix); + break; + + case 'revertTemporaryMatrix': + µm.tMatrix.assign(µm.pMatrix); break; default: - return µMatrix.messaging.defaultHandler(request, sender, callback); + return µm.messaging.defaultHandler(request, sender, callback); } callback(response); }; -µMatrix.messaging.listen('popup.js', onMessage); +µm.messaging.listen('popup.js', onMessage); })(); diff --git a/src/js/popup.js b/src/js/popup.js index 1584860..74f090f 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -30,16 +30,6 @@ /******************************************************************************/ /******************************************************************************/ -var µMatrix = chrome.extension.getBackgroundPage().µMatrix; -var matrixSnapshot = {}; -var matrixStats = {}; -var targetTabId; -var targetPageURL; -var targetPageHostname; -var targetPageDomain; -var targetScope = '*'; -var matrixCellHotspots = null; - // Must be consistent with definitions in matrix.js const Pale = 0x00; const Dark = 0x80; @@ -54,6 +44,30 @@ const PaleGreen = Pale | Green; const DarkGray = Dark | Gray; const PaleGray = Pale | Gray; +var µMatrix = chrome.extension.getBackgroundPage().µMatrix; +var matrixSnapshot = {}; +var groupsSnapshot = []; +var allHostnamesSnapshot = 'do not leave this initial string empty'; + +var targetTabId; +var targetPageURL; +var targetPageHostname; +var targetPageDomain; +var targetScope = '*'; +var matrixCellHotspots = null; + +var matrixHeaderPrettyNames = { + 'all': '', + 'cookie': '', + 'css': '', + 'image': '', + 'plugin': '', + 'script': '', + 'xhr': '', + 'frame': '', + 'other': '' +}; + /******************************************************************************/ /******************************************************************************/ @@ -94,31 +108,6 @@ function setUserSetting(setting, value) { /******************************************************************************/ -var HTTPSBPopup = { - matrixDomains: {}, - matrixHeaderTypes: ['*'], - matrixGroup3Collapsed: false, - - groupsSnapshot: [], - domainListSnapshot: 'do not leave this initial string empty', - - matrixHeaderPrettyNames: { - 'all': '', - 'cookie': '', - 'css': '', - 'image': '', - 'plugin': '', - 'script': '', - 'xhr': '', - 'frame': '', - 'other': '' - }, - - dummy: 0 -}; - -/******************************************************************************/ - function updateMatrixSnapshot() { var snapshotReady = function(response) { matrixSnapshot = response; @@ -126,7 +115,7 @@ function updateMatrixSnapshot() { updateMatrixBehavior(); updateMatrixButtons(); }; - messaging.ask({ what: 'matrixSnapshot', tabId: matrixSnapshot.tabId }, snapshotReady); + queryMatrixSnapshot(snapshotReady); } /******************************************************************************/ @@ -142,10 +131,10 @@ function getGroupStats() { // Try to not reshuffle groups around while popup is opened if // no new hostname added. var latestDomainListSnapshot = Object.keys(matrixSnapshot.rows).sort().join(); - if ( latestDomainListSnapshot === HTTPSBPopup.domainListSnapshot ) { - return HTTPSBPopup.groupsSnapshot; + if ( latestDomainListSnapshot === allHostnamesSnapshot ) { + return groupsSnapshot; } - HTTPSBPopup.domainListSnapshot = latestDomainListSnapshot; + allHostnamesSnapshot = latestDomainListSnapshot; // First, group according to whether at least one node in the domain // hierarchy is white or blacklisted @@ -216,7 +205,7 @@ function getGroupStats() { group[domain][hostname] = true; } - HTTPSBPopup.groupsSnapshot = groups; + groupsSnapshot = groups; return groups; } @@ -389,71 +378,6 @@ function handleBlacklistFilter(button) { /******************************************************************************/ -function getTemporaryRuleset() { - var µm = µMatrix; - var temporaryRules = {}; - var permanentRules = {}; - var temporarySwitches = {}; - var permanentSwitches = {}; - var ruleset = { - rulesToAdd: [], - rulesToRemove: [], - switchesToAdd: [], - switchesToRemove: [], - count: 0 - }; - for ( var hostname in matrixStats ) { - if ( matrixStats.hasOwnProperty(hostname) === false ) { - continue; - } - µm.tMatrix.extractZRules(targetPageHostname, hostname, temporaryRules); - µm.pMatrix.extractZRules(targetPageHostname, hostname, permanentRules); - } - µm.tMatrix.extractSwitches(targetPageHostname, temporarySwitches); - µm.pMatrix.extractSwitches(targetPageHostname, permanentSwitches); - - var k; - for ( k in temporaryRules ) { - if ( temporaryRules.hasOwnProperty(k) === false ) { - continue; - } - if ( temporaryRules[k] !== permanentRules[k] ) { - ruleset.rulesToAdd.push({ k: k, v: temporaryRules[k] }); - } - } - for ( k in permanentRules ) { - if ( permanentRules.hasOwnProperty(k) === false ) { - continue; - } - if ( temporaryRules[k] === undefined ) { - ruleset.rulesToRemove.push(k); - } - } - for ( k in temporarySwitches ) { - if ( temporarySwitches.hasOwnProperty(k) === false ) { - continue; - } - if ( temporarySwitches[k] !== permanentSwitches[k] ) { - ruleset.switchesToAdd.push({ k: k, v: temporarySwitches[k] }); - } - } - for ( k in permanentSwitches ) { - if ( permanentSwitches.hasOwnProperty(k) === false ) { - continue; - } - if ( temporarySwitches[k] === undefined ) { - ruleset.switchesToRemove.push(k); - } - } - ruleset.count = ruleset.rulesToAdd.length + - ruleset.rulesToRemove.length + - ruleset.switchesToAdd.length + - ruleset.switchesToRemove.length; - return ruleset; -} - -/******************************************************************************/ - var matrixRowPool = []; var matrixSectionPool = []; var matrixGroupPool = []; @@ -685,6 +609,7 @@ function computeMatrixGroupMetaStats(group) { totals[i] += matrixSnapshot.rows[domains[j]].totals[i]; } } + // TODO: column 0 is supposed to be count of blacklisted hostnames return totals; } @@ -881,8 +806,7 @@ function makeMatrixGroup3(group) { if ( domains.length === 0 ) { return; } - var groupDiv = createMatrixGroup() - .addClass('g3'); + var groupDiv = createMatrixGroup().addClass('g3'); createMatrixSection() .addClass('g3Meta') .toggleClass('g3Collapsed', !!getUserSetting('popupHideBlacklisted')) @@ -930,7 +854,7 @@ var makeMenu = function() { // Do all the stuff that needs to be done before building menu et al. function initMenuEnvironment() { - var prettyNames = HTTPSBPopup.matrixHeaderPrettyNames; + var prettyNames = matrixHeaderPrettyNames; var keys = Object.keys(prettyNames); var i = keys.length; var cell, key, text; @@ -1013,7 +937,7 @@ function updateScopeCell() { function updateMtxbutton() { var µm = µMatrix; - var masterSwitch = µm.getTemporaryMtxFiltering(targetScope); + var masterSwitch = matrixSnapshot.tSwitch; var pageStats = getPageStats(); var count = pageStats ? pageStats.requestStats.blocked.all : ''; var button = uDom('#buttonMtxFiltering'); @@ -1032,23 +956,26 @@ function toggleMtxFiltering() { /******************************************************************************/ function updatePersistButton() { - var ruleset = getTemporaryRuleset(); + var diffCount = matrixSnapshot.diff.length; var button = uDom('#buttonPersist'); button.contents() .filter(function(){return this.nodeType===3;}) .first() - .text(ruleset.count > 0 ? '\uf13e' : '\uf023'); - button.descendants('span.badge').text(ruleset.count > 0 ? ruleset.count : ''); - var disabled = ruleset.count === 0; + .text(diffCount > 0 ? '\uf13e' : '\uf023'); + button.descendants('span.badge').text(diffCount > 0 ? diffCount : ''); + var disabled = diffCount === 0; button.toggleClass('disabled', disabled); uDom('#buttonRevertScope').toggleClass('disabled', disabled); } -function persistScope() { - var µm = µMatrix; - var ruleset = getTemporaryRuleset(); - µm.applyRulesetPermanently(ruleset); - updateMatrixSnapshot(); +/******************************************************************************/ + +function persistMatrix() { + var request = { + what: 'applyDiffToPermanentMatrix', + diff: matrixSnapshot.diff + }; + messaging.ask(request, updateMatrixSnapshot); } /******************************************************************************/ @@ -1056,11 +983,12 @@ function persistScope() { // rhill 2014-03-12: revert completely ALL changes related to the // current page, including scopes. -function revertScope() { - var µm = µMatrix; - var ruleset = getTemporaryRuleset(); - µm.revertScopeRules(ruleset.tScopeKey); - updateMatrixSnapshot(); +function revertMatrix() { + var request = { + what: 'applyDiffToTemporaryMatrix', + diff: matrixSnapshot.diff + }; + messaging.ask(request, updateMatrixSnapshot); } /******************************************************************************/ @@ -1076,8 +1004,10 @@ function updateMatrixButtons() { /******************************************************************************/ function revertAll() { - µMatrix.revertAllRules(); - updateMatrixSnapshot(); + var request = { + what: 'revertTemporaryMatrix' + }; + messaging.ask(request, updateMatrixSnapshot); } /******************************************************************************/ @@ -1132,24 +1062,6 @@ function dropDownMenuHide() { // Because chrome.tabs.query() is async var onMatrixSnapshotReady = function(response) { -/* - // TODO: can tabs be empty? - if ( !tabs.length ) { - return; - } - - var µm = µMatrix; - - // Important! Before calling makeMenu() - // Allow to scope on behind-the-scene virtual tab - if ( tab.url.indexOf('chrome-extension://' + chrome.runtime.id + '/') === 0 ) { - targetTabId = µm.behindTheSceneTabId; - targetPageURL = µm.behindTheSceneURL; - } else { - targetTabId = tab.id; - targetPageURL = µm.pageUrlFromTabId(targetTabId); - } -*/ matrixSnapshot = response; targetTabId = response.tabId; @@ -1175,11 +1087,23 @@ var onMatrixSnapshotReady = function(response) { /******************************************************************************/ -var onTabsReceived = function(tabs) { - if ( tabs.length === 0 ) { - return; +var queryMatrixSnapshot = function(callback) { + var request = { + what: 'matrixSnapshot', + tabId: targetTabId + }; + var onTabsReceived = function(tabs) { + if ( tabs.length === 0 ) { + return; + } + request.tabId = targetTabId = tabs[0].id; + messaging.ask(request, callback); + }; + if ( targetTabId === undefined ) { + chrome.tabs.query({ active: true, currentWindow: true }, onTabsReceived); + } else { + messaging.ask(request, callback); } - messaging.ask({ what: 'matrixSnapshot', tabId: tabs[0].id }, onMatrixSnapshotReady); }; /******************************************************************************/ @@ -1187,7 +1111,7 @@ var onTabsReceived = function(tabs) { // Make menu only when popup html is fully loaded uDom.onLoad(function() { - chrome.tabs.query({ active: true, currentWindow: true }, onTabsReceived); + queryMatrixSnapshot(onMatrixSnapshotReady); // Below is UI stuff which is not key to make the menu, so this can // be done without having to wait for a tab to be bound to the menu. @@ -1217,8 +1141,8 @@ uDom.onLoad(function() { uDom('#scopeKeyDomain').on('click', createDomainScope); uDom('#scopeKeySite').on('click', createSiteScope); uDom('#buttonMtxFiltering').on('click', toggleMtxFiltering); - uDom('#buttonPersist').on('click', persistScope); - uDom('#buttonRevertScope').on('click', revertScope); + uDom('#buttonPersist').on('click', persistMatrix); + uDom('#buttonRevertScope').on('click', revertMatrix); uDom('#buttonRevertAll').on('click', revertAll); uDom('#buttonReload').on('click', buttonReloadHandler);