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

Unified Diff: lib/elemHide.js

Issue 29345663: Issue 4140 - Remove Firefox-specific element hiding functionality (Closed)
Patch Set: Created June 8, 2016, 8:23 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 | « no previous file | lib/filterListener.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/elemHide.js
===================================================================
--- a/lib/elemHide.js
+++ b/lib/elemHide.js
@@ -14,23 +14,19 @@
* 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");
+let {Utils} = require("utils");
+let {ElemHideException} = require("filterClasses");
+let {FilterNotifier} = require("filterNotifier");
/**
* Lookup table, filters by their associated key
* @type Object
*/
var filterByKey = [];
/**
@@ -81,70 +77,34 @@ 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
+ * Container for element hiding filters
* @class
*/
var ElemHide = exports.ElemHide =
{
/**
- * Indicates whether filters have been added or removed since the last apply() call.
- * @type Boolean
- */
- isDirty: false,
-
- /**
- * Indicates 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 = [];
keyByFilter = Object.create(null);
filtersByDomain = Object.create(null);
filtersBySelector = Object.create(null);
unconditionalSelectors = null;
knownExceptions = Object.create(null);
exceptions = Object.create(null);
- ElemHide.isDirty = false;
- ElemHide.unapply();
+ FilterNotifier.emit("elemhideupdate");
},
_addToFiltersByDomain: function(filter)
{
let key = keyByFilter[filter.text];
let domains = filter.domains || defaultDomains;
for (let domain in domains)
{
@@ -217,19 +177,19 @@ var ElemHide = exports.ElemHide =
}
}
else
{
// The new filter's selector only applies to some domains
this._addToFiltersByDomain(filter);
}
}
+ }
- ElemHide.isDirty = true;
- }
+ FilterNotifier.emit("elemhideupdate");
},
/**
* Removes an element hiding filter
* @param {ElemHideFilter} filter
*/
remove: function(filter)
{
@@ -247,17 +207,16 @@ var ElemHide = exports.ElemHide =
else
{
if (!(filter.text in keyByFilter))
return;
let key = keyByFilter[filter.text];
delete filterByKey[key];
delete keyByFilter[filter.text];
- ElemHide.isDirty = true;
if (usingGetSelectorsForDomain)
{
let filters = filtersBySelector[filter.selector];
if (filters)
{
if (filters.length > 1)
{
@@ -277,16 +236,18 @@ var ElemHide = exports.ElemHide =
{
let filters = filtersByDomain[domain];
if (filters)
delete filters[key];
}
}
}
}
+
+ FilterNotifier.emit("elemhideupdate");
},
/**
* Checks whether an exception rule is registered for a filter on a particular
* domain.
*/
getException: function(/**Filter*/ filter, /**String*/ docDomain) /**ElemHideException*/
{
@@ -297,200 +258,48 @@ var ElemHide = exports.ElemHide =
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
+ * Retrieves an element hiding filter by the corresponding protocol key
*/
- _applying: false,
+ getFilterByKey: function(/**String*/ key) /**Filter*/
+ {
+ return (key in filterByKey ? filterByKey[key] : null);
+ },
/**
- * Will be set to true if an apply() call arrives while apply() is already
- * running (delayed execution).
- * @type Boolean
+ * Returns a list of all selectors as a nested map. On first level, the keys
+ * are all values of `ElemHideBase.selectorDomain` (domains on which these
+ * selectors should apply, ignoring exceptions). The values are maps again,
+ * with the keys being selectors and values the corresponding filter keys.
+ * @returns {Map.<String,Map<String,String>>}
*/
- _needsApply: false,
-
- /**
- * Generates stylesheet URL and applies it globally
- */
- apply: function()
+ getSelectors: 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;
+ let domains = new Map();
for (let key in filterByKey)
{
let filter = filterByKey[key];
let selector = filter.selector;
if (!selector)
continue;
let domain = filter.selectorDomain || "";
- let list;
- if (domain in domains)
- list = domains[domain];
- else
- {
- list = Object.create(null);
- domains[domain] = list;
- }
- list[selector] = key;
- hasFilters = true;
+ if (!domains.has(domain))
+ domains.set(domain, new Map());
+ domains.get(domain).set(selector, key);
}
- 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);
+ return domains;
},
/**
* Returns a list of all selectors active on a particular domain, must not be
* used in Firefox (when usingGetSelectorsForDomain is false).
*/
getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly)
{
« no previous file with comments | « no previous file | lib/filterListener.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld