Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/elemHide.js

Issue 29335650: Issue 2595 - Use the core code from adblockpluscore (Closed)
Patch Set: Created Feb. 4, 2016, 6:35 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/downloader.js ('k') | lib/filterClasses.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/elemHide.js
===================================================================
deleted file mode 100644
--- a/lib/elemHide.js
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2016 Eyeo GmbH
- *
- * Adblock Plus is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3 as
- * published by the Free Software Foundation.
- *
- * Adblock Plus 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 Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * @fileOverview Element hiding implementation.
- */
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-var {Utils} = require("utils");
-var {IO} = require("io");
-var {Prefs} = require("prefs");
-var {ElemHideException} = require("filterClasses");
-var {FilterNotifier} = require("filterNotifier");
-
-/**
- * Lookup table, filters by their associated key
- * @type Object
- */
-var filterByKey = Object.create(null);
-
-/**
- * Lookup table, keys of the filters by filter text
- * @type Object
- */
-var keyByFilter = Object.create(null);
-
-/**
- * Lookup table, keys are known element hiding exceptions
- * @type Object
- */
-var knownExceptions = Object.create(null);
-
-/**
- * Lookup table, lists of element hiding exceptions by selector
- * @type Object
- */
-var exceptions = Object.create(null);
-
-/**
- * Currently applied stylesheet URL
- * @type nsIURI
- */
-var styleURL = null;
-
-/**
- * Element hiding component
- * @class
- */
-var ElemHide = exports.ElemHide =
-{
- /**
- * Indicates whether filters have been added or removed since the last apply() call.
- * @type Boolean
- */
- isDirty: false,
-
- /**
- * Inidicates whether the element hiding stylesheet is currently applied.
- * @type Boolean
- */
- applied: false,
-
- /**
- * Called on module startup.
- */
- init: function()
- {
- Prefs.addListener(function(name)
- {
- if (name == "enabled")
- ElemHide.apply();
- });
- onShutdown.add(() => ElemHide.unapply());
-
- let styleFile = IO.resolveFilePath(Prefs.data_directory);
- styleFile.append("elemhide.css");
- styleURL = Services.io.newFileURI(styleFile).QueryInterface(Ci.nsIFileURL);
- },
-
- /**
- * Removes all known filters
- */
- clear: function()
- {
- filterByKey = Object.create(null);
- keyByFilter = Object.create(null);
- knownExceptions = Object.create(null);
- exceptions = Object.create(null);
- ElemHide.isDirty = false;
- ElemHide.unapply();
- },
-
- /**
- * Add a new element hiding filter
- * @param {ElemHideFilter} filter
- */
- add: function(filter)
- {
- if (filter instanceof ElemHideException)
- {
- if (filter.text in knownExceptions)
- return;
-
- let selector = filter.selector;
- if (!(selector in exceptions))
- exceptions[selector] = [];
- exceptions[selector].push(filter);
- knownExceptions[filter.text] = true;
- }
- else
- {
- if (filter.text in keyByFilter)
- return;
-
- let key;
- do {
- key = Math.random().toFixed(15).substr(5);
- } while (key in filterByKey);
-
- filterByKey[key] = filter;
- keyByFilter[filter.text] = key;
- ElemHide.isDirty = true;
- }
- },
-
- /**
- * Removes an element hiding filter
- * @param {ElemHideFilter} filter
- */
- remove: function(filter)
- {
- if (filter instanceof ElemHideException)
- {
- if (!(filter.text in knownExceptions))
- return;
-
- let list = exceptions[filter.selector];
- let index = list.indexOf(filter);
- if (index >= 0)
- list.splice(index, 1);
- delete knownExceptions[filter.text];
- }
- else
- {
- if (!(filter.text in keyByFilter))
- return;
-
- let key = keyByFilter[filter.text];
- delete filterByKey[key];
- delete keyByFilter[filter.text];
- ElemHide.isDirty = true;
- }
- },
-
- /**
- * Checks whether an exception rule is registered for a filter on a particular
- * domain.
- */
- getException: function(/**Filter*/ filter, /**String*/ docDomain) /**ElemHideException*/
- {
- if (!(filter.selector in exceptions))
- return null;
-
- let list = exceptions[filter.selector];
- for (let i = list.length - 1; i >= 0; i--)
- if (list[i].isActiveOnDomain(docDomain))
- return list[i];
-
- return null;
- },
-
- /**
- * Will be set to true if apply() is running (reentrance protection).
- * @type Boolean
- */
- _applying: false,
-
- /**
- * Will be set to true if an apply() call arrives while apply() is already
- * running (delayed execution).
- * @type Boolean
- */
- _needsApply: false,
-
- /**
- * Generates stylesheet URL and applies it globally
- */
- apply: function()
- {
- if (this._applying)
- {
- this._needsApply = true;
- return;
- }
-
- if (!ElemHide.isDirty || !Prefs.enabled)
- {
- // Nothing changed, looks like we merely got enabled/disabled
- if (Prefs.enabled && !ElemHide.applied)
- {
- try
- {
- Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
- ElemHide.applied = true;
- }
- catch (e)
- {
- Cu.reportError(e);
- }
- }
- else if (!Prefs.enabled && ElemHide.applied)
- {
- ElemHide.unapply();
- }
-
- return;
- }
-
- IO.writeToFile(styleURL.file, this._generateCSSContent(), function(e)
- {
- this._applying = false;
-
- // _generateCSSContent is throwing NS_ERROR_NOT_AVAILABLE to indicate that
- // there are no filters. If that exception is passed through XPCOM we will
- // see a proper exception here, otherwise a number.
- let noFilters = (e == Cr.NS_ERROR_NOT_AVAILABLE || (e && e.result == Cr.NS_ERROR_NOT_AVAILABLE));
- if (noFilters)
- {
- e = null;
- IO.removeFile(styleURL.file, function(e) {});
- }
- else if (e)
- Cu.reportError(e);
-
- if (this._needsApply)
- {
- this._needsApply = false;
- this.apply();
- }
- else if (!e)
- {
- ElemHide.isDirty = false;
-
- ElemHide.unapply();
-
- if (!noFilters)
- {
- try
- {
- Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
- ElemHide.applied = true;
- }
- catch (e)
- {
- Cu.reportError(e);
- }
- }
-
- FilterNotifier.triggerListeners("elemhideupdate");
- }
- }.bind(this));
-
- this._applying = true;
- },
-
- _generateCSSContent: function*()
- {
- // Grouping selectors by domains
- let domains = Object.create(null);
- let hasFilters = false;
- for (let key in filterByKey)
- {
- let filter = filterByKey[key];
- let domain = filter.selectorDomain || "";
-
- let list;
- if (domain in domains)
- list = domains[domain];
- else
- {
- list = Object.create(null);
- domains[domain] = list;
- }
- list[filter.selector] = key;
- hasFilters = true;
- }
-
- if (!hasFilters)
- throw Cr.NS_ERROR_NOT_AVAILABLE;
-
- function escapeChar(match)
- {
- return "\\" + match.charCodeAt(0).toString(16) + " ";
- }
-
- // Return CSS data
- let cssTemplate = "-moz-binding: url(about:abp-elemhidehit?%ID%#dummy) !important;";
- for (let domain in domains)
- {
- let rules = [];
- let list = domains[domain];
-
- if (domain)
- yield ('@-moz-document domain("' + domain.split(",").join('"),domain("') + '"){').replace(/[^\x01-\x7F]/g, escapeChar);
- else
- {
- // Only allow unqualified rules on a few protocols to prevent them from blocking chrome
- yield '@-moz-document url-prefix("http://"),url-prefix("https://"),'
- + 'url-prefix("mailbox://"),url-prefix("imap://"),'
- + 'url-prefix("news://"),url-prefix("snews://"){';
- }
-
- for (let selector in list)
- yield selector.replace(/[^\x01-\x7F]/g, escapeChar) + "{" + cssTemplate.replace("%ID%", list[selector]) + "}";
- yield '}';
- }
- },
-
- /**
- * Unapplies current stylesheet URL
- */
- unapply: function()
- {
- if (ElemHide.applied)
- {
- try
- {
- Utils.styleService.unregisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
- }
- catch (e)
- {
- Cu.reportError(e);
- }
- ElemHide.applied = false;
- }
- },
-
- /**
- * Retrieves the currently applied stylesheet URL
- * @type String
- */
- get styleURL()
- {
- return ElemHide.applied ? styleURL.spec : null;
- },
-
- /**
- * Retrieves an element hiding filter by the corresponding protocol key
- */
- getFilterByKey: function(/**String*/ key) /**Filter*/
- {
- return (key in filterByKey ? filterByKey[key] : null);
- },
-
- /**
- * Returns a list of all selectors active on a particular domain (currently
- * used only in Chrome, Opera and Safari).
- */
- getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly)
- {
- let result = [];
- let keys = Object.getOwnPropertyNames(filterByKey);
- for (let key of keys)
- {
- let filter = filterByKey[key];
- if (specificOnly && (!filter.domains || filter.domains[""]))
- continue;
-
- if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain))
- result.push(filter.selector);
- }
- return result;
- }
-};
« no previous file with comments | « lib/downloader.js ('k') | lib/filterClasses.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld