123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804 |
- /*******************************************************************************
- ηMatrix - a browser extension to black/white list requests.
- Copyright (C) 2014-2019 Raymond Hill
- Copyright (C) 2019-2022 Alessio Vanni
- 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
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see {http://www.gnu.org/licenses/}.
- Home: https://gitlab.com/vannilla/ematrix
- uMatrix Home: https://github.com/gorhill/uMatrix
- */
- 'use strict';
- (function () {
- Cu.import('chrome://ematrix/content/lib/UriTools.jsm');
- Cu.import('chrome://ematrix/content/lib/Tools.jsm');
- Cu.import('chrome://ematrix/content/lib/RowSnapshot.jsm');
- let ηm = ηMatrix;
- // I personally find this method better than a giant (or multiple
- // giant) switch statement(s), but all things considered it's not
- // as nice as when the language has proper macros. The idea is to
- // make a more flexible system, at the cost of a slightly more
- // verbose code and a bit more memory usage due to the new
- // function objects.
- // Method tables.
- // "Early" is for those methods that do not call the callback.
- let methods = {};
- let methodsEarly = {};
- // The message queue callback.
- let dispatchMethod = function (request, sender, cb) {
- let f = methods[request.what];
- let early = false;
- if (!f) {
- f = methodsEarly[request.what];
- if (!f) {
- return vAPI.messaging.UNHANDLED;
- }
- early = true;
- }
- let response = f(request, sender, cb);
- if (early === true) {
- return response;
- }
- cb(response);
- };
- // Used here to add dispatchable functions
- let addMethod = function (name, f, /* &optional */ early) {
- if (early) {
- methodsEarly[name] = f;
- } else {
- methods[name] = f;
- }
- }
- // Default
- addMethod('getAssetContent', function (request, sender, cb) {
- ηm.assets.get(request.url, {
- dontCache: true,
- }, cb);
- return undefined;
- }, true);
- addMethod('selectHostsFiles', function (request, sender, cb) {
- ηm.selectHostsFiles(request, cb);
- return undefined;
- }, true);
- addMethod('forceReloadTab', function (request, sender, cb) {
- ηm.forceReload(request.tabId, request.bypassCache);
- return undefined;
- });
- addMethod('forceUpdateAssets', function (request, sender, cb) {
- ηm.scheduleAssetUpdater(0);
- ηm.assets.updateStart({
- delay: 1000,
- });
- return undefined;
- });
- addMethod('getUserSettings', function (request, sender, cb) {
- let pmat = ηm.pMatrix;
- return {
- userSettings: ηm.userSettings,
- matrixSwitches: {
- 'https-strict': (pmat.evaluateSwitch('https-strict', '*')
- === 1),
- 'referrer-spoof': (pmat.evaluateSwitch('referrer-spoof', '*')
- === 1),
- 'noscript-spoof': (pmat.evaluateSwitch('noscript-spoof', '*')
- === 1),
- },
- };
- });
- addMethod('gotoExtensionURL', function (request, sender, cb) {
- Tools.gotoExtensionURL({
- api: vAPI,
- details: request,
- matrix: ηm,
- });
- return undefined;
- });
- addMethod('gotoURL', function (request, sender, cb) {
- Tools.gotoURL({
- api: vAPI,
- details: request,
- });
- return undefined;
- });
- addMethod('mustBlock', function (request, sender, cb) {
- return ηm.mustBlock(request.scope,
- request.hostname,
- request.type);
- });
- addMethod('readRawSettings', function (request, sender, cb) {
- return ηm.stringFromRawSettings();
- });
- addMethod('writeRawSettings', function (request, sender, cb) {
- ηm.rawSettingsFromString(request.content);
- return undefined;
- });
- addMethod('reloadHostsFiles', function (request, sender, cb) {
- ηm.reloadHostsFiles();
- return undefined;
- });
- addMethod('setMatrixSwitch', function (request, sender, cb) {
- ηm.tMatrix.setSwitch(request.switchName, '*', request.state);
- if (ηm.pMatrix.setSwitch(request.switchName, '*', request.state)) {
- ηm.saveMatrix();
- }
- return undefined;
- });
- addMethod('userSettings', function (request, sender, cb) {
- if (request.hasOwnProperty('value') === false) {
- request.value = undefined;
- }
- return ηm.changeUserSettings(request.name, request.value);
- });
- vAPI.messaging.setup(dispatchMethod);
- // popup.js begins here
- addMethod('matrixSnapshot', function (request, sender, cb) {
- let snapShot = function (store, details) {
- let user = ηm.userSettings;
- let indices = ηm.Matrix.columnHeaderIndices;
- let r = {
- appVersion: vAPI.app.version,
- blockedCount: store.requestStats.blocked.all,
- collapseAllDomains: user.popupCollapseAllDomains,
- collapseBlacklistedDomains: user.popupCollapseBlacklistedDomains,
- diff: [],
- domain: store.pageDomain,
- has3pReferrer: store.has3pReferrer,
- hasMixedContent: store.hasMixedContent,
- hasNoscriptTags: store.hasNoscriptTags,
- hasWebWorkers: store.hasWebWorkers,
- headerIndices: Array.from(indices),
- hostname: store.pageHostname,
- mtxContentModified: (store.mtxContentModifiedTime
- !== details.mtxContentModifiedTime),
- mtxCountModified: (store.mtxCountModifiedTime
- !== details.mtxCountModifiedTime),
- mtxContentModifiedTime: store.mtxContentModifiedTime,
- mtxCountModifiedTime: store.mtxCountModifiedTime,
- pMatrixModified: (ηm.pMatrix.modifiedTime
- !== details.pMatrixModifiedTime),
- pMatrixModifiedTime: ηm.pMatrix.modifiedTime,
- pSwitches: {},
- rows: {},
- rowCount: 0,
- scope: '*',
- tabId: store.tabId,
- tMatrixModified: (ηm.tMatrix.modifiedTime
- !== details.tMatrixModifiedTime),
- tMatrixModifiedTime: ηm.tMatrix.modifiedTime,
- tSwitches: {},
- url: store.pageUrl,
- userSettings: {
- colorBlindFriendly: user.colorBlindFriendly,
- displayTextSize: user.displayTextSize,
- popupScopeLevel: user.popupScopeLevel,
- },
- };
- if (typeof details.scope === 'string') {
- r.scope = details.scope;
- } else if (user.popupScopeLevel === 'site') {
- r.scope = r.hostname;
- } else if (user.popupScopeLevel === 'domain') {
- r.scope = r.domain;
- }
- for (let s of ηm.Matrix.switchNames) {
- r.tSwitches[s] = ηm.tMatrix.evaluateSwitchZ(s, r.scope);
- r.pSwitches[s] = ηm.pMatrix.evaluateSwitchZ(s, r.scope);
- }
- r.rows['*'] = new RowSnapshot(ηm, r.scope, '*', '*');
- r.rows['1st-party'] = new RowSnapshot(ηm, r.scope,
- '1st-party', '1st-party');
- r.rowCount += 1;
- let any = indices.get('*');
- for (let e of store.hostnameTypeCells) {
- let pos = e[0].indexOf(' ');
- let reqhn = e[0].slice(0, pos);
- let reqt = e[0].slice(pos+1);
- // Hostname can be empty in some cases
- // (reported from uMatrix)
- if (reqhn === '') {
- reqhn = store.pageHostname;
- }
- let reqd = UriTools.domainFromHostname(reqhn) || reqhn;
- let desthn = reqhn;
- while (true) {
- if (r.rows.hasOwnProperty(desthn) !== false) {
- break;
- }
- r.rows[desthn] = new RowSnapshot(ηm,
- r.scope,
- desthn,
- reqd);
- r.rowCount += 1;
- if (desthn === reqd) {
- break;
- }
- pos = desthn.indexOf('.');
- if (pos === -1) {
- break;
- }
- desthn = desthn.slice(pos + 1);
- }
- let count = e[1].size;
- let tindex = indices.get(reqt);
- let row = r.rows[reqhn];
- row.counts[tindex] += count;
- row.counts[any] += count;
- row = r.rows[reqd];
- row.totals[tindex] += count;
- row.totals[any] += count;
- row = r.rows['*'];
- row.totals[tindex] += count;
- row.totals[any] += count;
- }
- r.diff = ηm.tMatrix.diff(ηm.pMatrix,
- r.hostname,
- Object.keys(r.rows));
- return r;
- };
- let snapFromId = function (details, cb) {
- let snapIf = function (id, details) {
- let store = ηm.pageStoreFromTabId(id);
- if (store === null) {
- cb('ENOTFOUND');
- return;
- }
- let tmat = ηm.tMatrix;
- let pmat = ηm.pMatrix;
- let mtx = details.mtxContentModifiedTime;
- if (tmat.modifiedTime === details.tMatrixModifiedTime
- && pmat.modifiedTime === details.pMatrixModifiedTime
- && store.mtxContentModifiedTime === mtx
- && store.mtxCountModifiedTime === mtx) {
- cb('ENOCHANGE');
- return;
- }
- cb(snapShot(store, details));
- };
- if (details.tabId) {
- snapIf(details.tabId, details);
- return;
- }
- let onReady = function (tab) {
- if (tab instanceof Object === false) {
- cb('ENOTFOUND');
- return;
- }
- let id =
- tab.url.lastIndexOf(vAPI.getURL('dashboard.html'), 0) !== 0
- ? tab.id
- : vAPI.noTabId;
- snapIf(id, details);
- };
- vAPI.tabs.get(null, onReady);
- };
- snapFromId(request, cb);
- return undefined;
- }, true);
- addMethod('toggleMatrixSwitch', function (request, sender, cb) {
- let sz = ηm.tMatrix.evaluateSwitchZ(request.switchName,
- request.srcHostname);
- ηm.tMatrix.setSwitchZ(request.switchName,
- request.srcHostname,
- sz === false);
- return undefined;
- });
- addMethod('blacklistMatrixCell', function (request, sender, cb) {
- ηm.tMatrix.blacklistCell(request.srcHostname,
- request.desHostname,
- request.type);
- return undefined;
- });
- addMethod('whitelistMatrixCell', function (request, sender, cb) {
- ηm.tMatrix.whitelistCell(request.srcHostname,
- request.desHostname,
- request.type);
- return undefined;
- });
- addMethod('graylistMatrixCell', function (request, sender, cb) {
- ηm.tMatrix.graylistCell(request.srcHostname,
- request.desHostname,
- request.type);
- return undefined;
- });
- addMethod('applyDiffToPermanentMatrix', function (request, sender, cb) {
- if (ηm.pMatrix.applyDiff(request.diff, ηm.tMatrix)) {
- ηm.saveMatrix();
- }
- return undefined;
- });
- addMethod('applyDiffToTemporaryMatrix', function (request, sender, cb) {
- ηm.tMatrix.applyDiff(request.diff, ηm.pMatrix);
- return undefined;
- });
- addMethod('revertTemporaryMatrix', function (request, sender, cb) {
- ηm.tMatrix.assign(ηm.pMatrix);
- return undefined;
- });
- vAPI.messaging.listen('popup.js', dispatchMethod);
- // Content scripts handling begins here
- let placeholders = undefined;
- let phReadTime = 0;
- addMethod('contentScriptHasLocalStorage', function (request, sender, cb) {
- let contentScriptLocalStorageHandler = function (id, originURL) {
- let tabContext = ηm.tabContextManager.lookup(id);
- if (tabContext === null) {
- return;
- }
- let blocked = ηm.mustBlock(tabContext.rootHostname,
- UriTools.hostnameFromURI(originURL),
- 'cookie');
- let store = ηm.pageStoreFromTabId(id);
- if (store !== null) {
- let requestURL = originURL + '/{localStorage}';
- store.recordRequest('cookie', requestURL, blocked);
- ηm.logger.writeOne(id, 'net', tabContext.rootHostname,
- requestURL, 'cookie', blocked);
- }
- let removeStorage = blocked && ηm.userSettings.deleteLocalStorage;
- if (removeStorage) {
- ηm.localStorageRemovedCounter++;
- }
- return removeStorage;
- };
- let tabId = sender && sender.tab ? sender.tab.id || 0 : 0;
- return contentScriptLocalStorageHandler(tabId, request.originURL);
- });
- addMethod('lookupBlockedCollapsibles', function (request, sender, cb) {
- let lookupBlockedCollapsibles = function (id, requests) {
- if (phReadTime < ηm.rawSettingsWriteTime) {
- placeholders = undefined;
- }
- if (placeholders === undefined) {
- placeholders = {
- frame: ηm.rawSettings.framePlaceholder,
- image: ηm.rawSettings.imagePlaceholder,
- };
- if (placeholders.frame) {
- let doc = ηm.rawSettings.framePlaceholderDocument;
- let bg = ηm.rawSettings.framePlaceholderBackground;
- placeholders.frameDocument =
- doc.replace('{{bg}}',
- bg !== 'default'
- ? bg
- : ηm.rawSettings.placeHolderBackground);
- }
- if (placeholders.image) {
- placeholders.imageBorder =
- ηm.rawSettings.imagePlaceholderBorder !== 'default'
- ? ηm.rawSettings.imagePlaceholderBorder
- : ηm.rawSettings.placeholderBorder;
- placeholders.imageBackground =
- ηm.rawSettings.imagePlaceholderBackground !== 'default'
- ? ηm.rawSettings.imagePlaceholderBackground
- : ηm.rawSettings.placeholderBackground;
- }
- phReadTime = Date.now();
- }
- let response = {
- blockedResources: [],
- hash: requests.hash,
- id: requests.id,
- placeholders: placeholders,
- };
- let context = ηm.tabContextManager.lookup(id);
- if (context === null) {
- return response;
- }
- let store = ηm.pageStoreFromTabId(id);
- if (store !== null) {
- store.lookupBlockedCollapsibles(requests, response);
- }
- return response;
- };
- let tabId = sender && sender.tab ? sender.tab.id || 0 : 0;
- return lookupBlockedCollapsibles(tabId, request);
- });
- addMethod('mustRenderNoscriptTags?', function (request, sender, cb) {
- let tabId = sender && sender.tab ? sender.tab.id || 0 : 0;
- let tabContext = ηm.tabContextManager.lookup(tabId);
- let rootHostname = tabContext && tabContext.rootHostname;
- let pageStore = ηm.pageStoreFromTabId(tabId);
- if (tabContext === null) {
- return undefined;
- }
- let response =
- ηm.tMatrix.mustBlock(rootHostname, rootHostname, 'script')
- && ηm.tMatrix.evaluateSwitchZ('noscript-spoof', rootHostname);
- if (pageStore !== null) {
- pageStore.hasNoscriptTags = true;
- }
- // https://github.com/gorhill/uMatrix/issues/225
- // A good place to force an update of the page title, as
- // at this point the DOM has been loaded.
- ηm.updateTitle(tabId);
- return response;
- });
- addMethod('securityPolicyViolation', function (request, sender, cb) {
- let foundInlineCode = function (id, store, details, type) {
- if (store === null) {
- return;
- }
- let pageHostname = store.pageHostname;
- let uri = UriTools.set(details.documentURI);
- let frameURL = UriTools.normalizedURI();
- let blocked = details.blocked;
- if (blocked === undefined) {
- blocked = ηm.mustBlock(pageHostname, uri.hostname, type);
- }
- let mapTo = {
- css: 'style',
- script: 'script',
- };
- // https://github.com/gorhill/httpswitchboard/issues/333
- // Look-up here whether inline scripting is blocked for the frame.
- let url = frameURL + '{inline_' + mapTo[type] + '}';
- store.recordRequest(type, url, blocked);
- ηm.logger.writeOne(id, 'net', pageHostname, url, type, blocked);
- };
- let tabId = sender && sender.tab ? sender.tab.id || 0 : 0;
- let tabContext = ηm.tabContextManager.lookup(tabId);
- let rootHostname = tabContext && tabContext.rootHostname;
- let pageStore = ηm.pageStoreFromTabId(tabId);
- if (request.directive === 'worker-src') {
- let url = UriTools.hostnameFromURI(request.blockedURI) !== ''
- ? request.blockedURI
- : request.documentURI;
- if (pageStore !== null) {
- pageStore.hasWebWorkers = true;
- pageStore.recordRequest('script', url, request.blocked);
- }
- if (tabContext !== null) {
- ηm.logger.writeOne(tabId, 'net', rootHostname,
- url, 'worker', request.blocked);
- }
- } else if (request.directive === 'script-src') {
- foundInlineCode(tabId, pageStore, request, 'script');
- } else if (request.directive === 'style-src') {
- foundInlineCode(tabId, pageStore, request, 'css');
- }
- return undefined;
- });
- addMethod('shutdown?', function (request, sender, cb) {
- let tabId = sender && sender.tab ? sender.tab.id || 0 : 0;
- let tabContext = ηm.tabContextManager.lookup(tabId);
- let rootHostname = tabContext && tabContext.rootHostname;
- let response = undefined;
- if (tabContext !== null) {
- response =
- ηm.tMatrix.evaluateSwitchZ('matrixb-off', rootHostname);
- }
- return response;
- });
- vAPI.messaging.listen('contentscript.js', dispatchMethod);
- // cloud-ui.js begins here
- addMethod('cloudGetOptions', function (request, sender, cb) {
- vAPI.cloud.getOptions(function (options) {
- options.enabled = ηm.userSettings.cloudStorageEnabled === true;
- cb(options);
- });
- return undefined;
- }, true);
- addMethod('cloudSetOptions', function (request, sender, cb) {
- vAPI.cloud.setOptions(request.options, cb);
- return undefined;
- }, true);
- addMethod('cloudPull', function (request, sender, cb) {
- return vAPI.cloud.pull(request.datakey, cb);
- }, true);
- addMethod('cloudPush', function (request, sender, cb) {
- return vAPI.cloud.push(request.datakey, request.data, cb);
- }, true);
- vAPI.messaging.listen('cloud-ui.js', dispatchMethod);
- // user-rules.js begins here
- addMethod('getUserRules', function (request, sender, cb) {
- return {
- temporaryRules: ηm.tMatrix.toString(),
- permanentRules: ηm.pMatrix.toString(),
- };
- });
- addMethod('setUserRules', function (request, sender, cb) {
- if (typeof request.temporaryRules === 'string') {
- ηm.tMatrix.fromString(request.temporaryRules);
- }
- if (typeof request.permanentRules === 'string') {
- ηm.pMatrix.fromString(request.permanentRules);
- ηm.saveMatrix();
- }
- return {
- temporaryRules: ηm.tMatrix.toString(),
- permanentRules: ηm.pMatrix.toString(),
- };
- });
- vAPI.messaging.listen('user-rules.js', dispatchMethod);
- // hosts-files.js begins here
- addMethod('getLists', function (request, sender, cb) {
- let prepare = function (entries) {
- for (let e in entries) {
- if (entries.hasOwnProperty(e) === false) {
- continue;
- }
- let entry = entries[e];
- if (typeof entry.homeURL === 'string') {
- let homehost = UriTools.hostnameFromURI(entry.homeURL);
- entry.homeHostname = homehost
- entry.homeDomain = UriTools.domainFromHostname(homehost);
- }
- }
- };
- let getLists = function (cb) {
- let r = {
- autoUpdate: ηm.userSettings.autoUpdate,
- available: null,
- cache: null,
- current: ηm.liveHostsFiles,
- blockedHostnameCount: ηm.ubiquitousBlacklist.count,
- };
- let onMetadataReady = function (entries) {
- r.cache = entries;
- prepare(r.cache);
- cb(r);
- };
- let onHostsReady = function (lists) {
- r.available = lists;
- prepare(r.available);
- ηm.assets.metadata(onMetadataReady);
- };
- ηm.getAvailableHostsFiles(onHostsReady);
- };
- return getLists(cb);
- }, true);
- addMethod('purgeCache', function (request, sender, cb) {
- ηm.assets.purge(request.assetKey);
- ηm.assets.remove('cache/' + request.assetKey);
- return undefined;
- });
- addMethod('purgeAllCaches', function (request, sender, cb) {
- if (request.hard) {
- ηm.assets.remove(/./);
- } else {
- ηm.assets.purge(/./, 'public_suffix_list.dat');
- }
- return undefined;
- });
- vAPI.messaging.listen('hosts-files.js', dispatchMethod);
- // about.js begins here
- addMethod('getAllUserData', function (request, sender, cb) {
- return {
- app: vAPI.app.name,
- version: vAPI.app.version,
- when: Date.now(),
- settings: ηm.userSettings,
- rules: ηm.pMatrix.toString(),
- hostsFiles: ηm.liveHostsFiles,
- rawSettings: ηm.rawSettings,
- };
- });
- addMethod('getSomeStats', function (request, sender, cb) {
- return {
- version: vAPI.app.version,
- storageUsed: ηm.storageUsed
- };
- });
- addMethod('restoreAllUserData', function (request, sender, cb) {
- let restoreData = function (data) {
- let countdown = 4;
- let onCountdown = function () {
- countdown -= 1;
- if (countdown === 0) {
- vAPI.app.restart();
- }
- };
- let onAllRemoved = function () {
- vAPI.storage.set(data.settings, onCountdown);
- vAPI.storage.set({
- userMatrix: data.rules,
- }, onCountdown);
- vAPI.storage.set({
- liveHostsFiles: data.hostsFiles,
- }, onCountdown);
- if (data.rawSettings instanceof Object) {
- ηMatrix.saveRawSettings(data.rawSettings, onCountdown);
- }
- };
- // If we are going to restore all, might as well wipe out
- // clean local storage
- ηm.XAL.keyvalRemoveAll(onAllRemoved);
- };
- restoreData(request.userData);
- return undefined;
- });
- addMethod('resetAllUserData', function (request, sender, cb) {
- let onAllRemoved = function () {
- vAPI.app.restart();
- };
- ηm.XAL.keyvalRemoveAll(onAllRemoved);
- /* Let's also clear the database, just to really make it a reset */
- ηm.assets.rmrf();
- return undefined;
- });
- vAPI.messaging.listen('about.js', dispatchMethod);
- // logger-ui.js begins here
- let loggerURL = vAPI.getURL('logger-ui.html');
- addMethod('readMany', function (request, sender, cb) {
- if (ηm.logger.ownerId !== undefined
- && request.ownerId !== ηm.logger.ownerId) {
- return {
- unavailable: true,
- };
- }
- let tabIds = {};
- for (let id in ηm.pageStores) {
- let store = ηm.pageStoreFromTabId(id);
- if (store === null) {
- continue;
- }
- if (store.rawUrl.startsWith(loggerURL)) {
- continue;
- }
- tabIds[id] = store.title || store.rawUrl;
- }
- return {
- colorBlind: false,
- entries: ηm.logger.readAll(request.ownerId),
- maxLoggedRequests: ηm.userSettings.maxLoggedRequests,
- noTabId: vAPI.noTabId,
- tabIds: tabIds,
- tabIdsToken: ηm.pageStoresToken,
- };
- });
- addMethod('releaseView', function (request, sender, cb) {
- if (request.ownerId === ηm.logger.ownerId) {
- ηm.logger.ownerId = undefined;
- }
- return undefined;
- });
- vAPI.messaging.listen('logger-ui.js', dispatchMethod);
- })();
|