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

Unified Diff: lib/child/elemHide.js

Issue 29356078: Issue 524 - Stop using @-moz-document (Closed) Base URL: https://hg.adblockplus.org/adblockplus
Patch Set: Improved comment Created Oct. 6, 2016, 12:24 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 | « dependencies ('k') | lib/contentPolicy.js » ('j') | lib/contentPolicy.js » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/child/elemHide.js
===================================================================
--- a/lib/child/elemHide.js
+++ b/lib/child/elemHide.js
@@ -11,17 +11,17 @@
* 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 Hit counts for element hiding.
+ * @fileOverview Serves CSS for element hiding and processes hits.
*/
try
{
// Hack: SDK loader masks our Components object with a getter.
let proto = Object.getPrototypeOf(this);
let property = Object.getOwnPropertyDescriptor(proto, "Components");
if (property && property.get)
@@ -36,22 +36,16 @@ let {XPCOMUtils} = Cu.import("resource:/
let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
let {shouldAllowAsync} = require("child/contentPolicy");
let {getFrames, isPrivate} = require("child/utils");
let {RequestNotifier} = require("child/requestNotifier");
let {port} = require("messaging");
let {Utils} = require("utils");
-// The allowXBL binding below won't have any effect on the element. For elements
-// that should be hidden however we don't return any binding at all, this makes
-// Gecko stop constructing the node - it cannot be shown.
-const allowXBL = "<bindings xmlns='http://www.mozilla.org/xbl'><binding id='dummy' bindToUntrustedContent='true'/></bindings>";
-const hideXBL = "<bindings xmlns='http://www.mozilla.org/xbl'/>";
-
const notImplemented = () => Cr.NS_ERROR_NOT_IMPLEMENTED;
/**
* about: URL module used to count hits.
* @class
*/
let AboutHandler =
{
@@ -91,24 +85,28 @@ let AboutHandler =
getURIFlags: function(uri)
{
return Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT;
},
newChannel: function(uri, loadInfo)
{
- let match = /\?(?:hit(\d+)|css)$/.exec(uri.path);
- if (!match)
- throw Cr.NS_ERROR_FAILURE;
+ let match = /\?hit(\d+)$/.exec(uri.path);
+ if (match)
+ return new HitRegistrationChannel(uri, loadInfo, match[1]);
- if (match[1])
- return new HitRegistrationChannel(uri, loadInfo, match[1]);
- else
- return new StyleDataChannel(uri, loadInfo);
+ match = /\?css(?:=(.*?))?$/.exec(uri.path);
+ if (match)
+ {
+ return new StyleDataChannel(uri, loadInfo,
+ match[1] ? decodeURIComponent(match[1]) : null);
+ }
+
+ throw Cr.NS_ERROR_FAILURE;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule])
};
AboutHandler.init();
/**
* Base class for channel implementations, subclasses usually only need to
@@ -207,68 +205,52 @@ BaseChannel.prototype = {
cancel: notImplemented,
suspend: notImplemented,
resume: notImplemented,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
};
/**
- * Channel returning CSS data for the global stylesheet.
+ * Channel returning CSS data for the global as well as site-specific stylesheet.
* @constructor
*/
-function StyleDataChannel(uri, loadInfo)
+function StyleDataChannel(uri, loadInfo, domain)
{
BaseChannel.call(this, uri, loadInfo);
+ this._domain = domain;
}
StyleDataChannel.prototype = {
__proto__: BaseChannel.prototype,
contentType: "text/css",
+ _domain: null,
_getResponse: function()
{
function escapeChar(match)
{
return "\\" + match.charCodeAt(0).toString(16) + " ";
}
// Would be great to avoid sync messaging here but nsIStyleSheetService
// insists on opening channels synchronously.
- let domains = port.emitSync("getSelectors");
+ let [selectors, keys] = (this._domain ?
+ port.emitSync("getSelectorsForDomain", this._domain) :
+ port.emitSync("getUnconditionalSelectors"));
let cssPrefix = "{-moz-binding: url(about:abp-elemhide?hit";
let cssSuffix = "#dummy) !important;}\n";
let result = [];
- for (let [domain, selectors] of domains)
+ for (let i = 0; i < selectors.length; i++)
{
- if (domain)
- {
- result.push('@-moz-document domain("',
- domain.replace(/[^\x01-\x7F]/g, escapeChar)
- .split(",").join('"),domain("'),
- '"){\n');
- }
- else
- {
- // Only allow unqualified rules on a few protocols to prevent them
- // from blocking chrome content
- result.push('@-moz-document url-prefix("http://"),',
- 'url-prefix("https://"),url-prefix("mailbox://"),',
- 'url-prefix("imap://"),url-prefix("news://"),',
- 'url-prefix("snews://"){\n');
- }
-
- for (let [selector, key] of selectors)
- {
- result.push(selector.replace(/[^\x01-\x7F]/g, escapeChar),
- cssPrefix, key, cssSuffix);
- }
-
- result.push("}\n");
+ let selector = selectors[i];
+ let key = keys[i];
+ result.push(selector.replace(/[^\x01-\x7F]/g, escapeChar),
+ cssPrefix, key, cssSuffix);
}
return result.join("");
}
};
/**
* Channel returning data for element hiding hits.
@@ -281,24 +263,27 @@ function HitRegistrationChannel(uri, loa
}
HitRegistrationChannel.prototype = {
__proto__: BaseChannel.prototype,
key: null,
contentType: "text/xml",
_getResponse: function()
{
- return new Promise((resolve, reject) =>
+ let window = Utils.getRequestWindow(this);
+ port.emitWithResponse("registerElemHideHit", {
+ key: this.key,
+ frames: getFrames(window),
+ isPrivate: isPrivate(window)
+ }).then(hit =>
{
- let window = Utils.getRequestWindow(this);
- shouldAllowAsync(window, window.document, "ELEMHIDE", this.key, allow =>
- {
- resolve(allow ? allowXBL : hideXBL);
- });
+ if (hit)
+ RequestNotifier.addNodeData(window.document, window.top, hit);
kzar 2016/10/06 13:02:32 (Doesn't storing all the details returned by regis
Wladimir Palant 2016/10/06 13:08:48 That's how the list of blockable items works - it
});
+ return "<bindings xmlns='http://www.mozilla.org/xbl'/>";
}
};
let observer = {
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIObserver, Ci.nsISupportsWeakReference
]),
@@ -370,16 +355,34 @@ let observer = {
catch (e)
{
// Ignore NS_ERROR_ILLEGAL_VALUE - it will be thrown if we try to add
// the stylesheet multiple times to the same document (the observer
// will be notified twice for some documents).
if (e.result != Cr.NS_ERROR_ILLEGAL_VALUE)
throw e;
}
+
+ let host = subject.location.hostname;
+ if (host)
+ {
+ try
+ {
+ utils.loadSheetUsingURIString(this.styleURL.spec + "=" +
+ encodeURIComponent(host), Ci.nsIStyleSheetService.USER_SHEET);
+ }
+ catch (e)
+ {
+ // Ignore NS_ERROR_ILLEGAL_VALUE - it will be thrown if we try to add
+ // the stylesheet multiple times to the same document (the observer
+ // will be notified twice for some documents).
+ if (e.result != Cr.NS_ERROR_ILLEGAL_VALUE)
+ throw e;
+ }
+ }
}
else if (filter)
{
RequestNotifier.addNodeData(window.document, window.top, {
contentType, docDomain, thirdParty, location, filter, filterType
});
}
});
« no previous file with comments | « dependencies ('k') | lib/contentPolicy.js » ('j') | lib/contentPolicy.js » ('J')

Powered by Google App Engine
This is Rietveld