Index: lib/child/contentPolicy.js |
=================================================================== |
--- a/lib/child/contentPolicy.js |
+++ b/lib/child/contentPolicy.js |
@@ -55,57 +55,71 @@ let collapsedClass = null; |
let types = new Map(); |
/** |
* Checks whether a request should be allowed, hides it if necessary |
* @param wnd {nsIDOMWindow} |
* @param node {nsIDOMElement} |
* @param contentType {String} |
* @param location {String} |
+ * @param [callback] {Function} If present, the request will be sent |
+ * asynchronously and callback called with the |
+ * response |
* @return {Boolean} false if the request should be blocked |
*/ |
-function shouldAllow(window, node, contentType, location) |
+function shouldAllow(window, node, contentType, location, callback) |
tschuster
2015/11/12 13:38:13
This should really be two functions. If you reuse
Wladimir Palant
2015/11/12 15:01:13
Done.
|
{ |
- let response = sendSyncMessage("AdblockPlus:ShouldAllow", { |
+ function processResponse(response) |
+ { |
+ if (typeof response == "undefined") |
+ return true; |
+ |
+ let {allow, collapse, hits} = response; |
+ for (let {frameIndex, contentType, docDomain, thirdParty, location, filter} of hits) |
+ { |
+ let context = node; |
+ if (typeof frameIndex == "number") |
+ { |
+ context = window; |
+ for (let i = 0; i < frameIndex; i++) |
+ context = context.parent; |
+ context = context.document; |
+ } |
+ RequestNotifier.addNodeData(context, window.top, contentType, docDomain, thirdParty, location, filter); |
+ } |
+ |
+ if (node.nodeType == Ci.nsIDOMNode.ELEMENT_NODE) |
+ { |
+ // Track mouse events for objects |
+ if (allow && contentType == "OBJECT") |
+ { |
+ node.addEventListener("mouseover", objectMouseEventHander, true); |
+ node.addEventListener("mouseout", objectMouseEventHander, true); |
+ } |
+ |
+ if (collapse) |
+ schedulePostProcess(node); |
+ } |
+ return allow; |
+ } |
Wladimir Palant
2015/11/04 15:05:22
The diff is messy but all the code above has merel
|
+ |
+ let data = { |
contentType: contentType, |
location: location, |
frames: getFrames(window), |
isPrivate: isPrivate(window) |
- }); |
- if (typeof response == "undefined") |
- return true; |
- |
- let {allow, collapse, hits} = response; |
- for (let {frameIndex, contentType, docDomain, thirdParty, location, filter} of hits) |
+ }; |
+ if (typeof callback == "function") |
{ |
- let context = node; |
- if (typeof frameIndex == "number") |
- { |
- context = window; |
- for (let i = 0; i < frameIndex; i++) |
- context = context.parent; |
- context = context.document; |
- } |
- RequestNotifier.addNodeData(context, window.top, contentType, docDomain, thirdParty, location, filter); |
+ sendAsyncMessage("AdblockPlus:ShouldAllow", data, (data) => { |
+ callback(processResponse(data)); |
+ }); |
} |
- |
- if (node.nodeType == Ci.nsIDOMNode.ELEMENT_NODE) |
- { |
- // Track mouse events for objects |
- if (allow && contentType == "OBJECT") |
- { |
- node.addEventListener("mouseover", objectMouseEventHander, true); |
- node.addEventListener("mouseout", objectMouseEventHander, true); |
- } |
- |
- if (collapse) |
- schedulePostProcess(node); |
- } |
- |
- return allow; |
+ else |
+ return processResponse(sendSyncMessage("AdblockPlus:ShouldAllow", data)); |
} |
/** |
* Actual nsIContentPolicy and nsIChannelEventSink implementation |
* @class |
*/ |
var PolicyImplementation = |
{ |
@@ -229,17 +243,17 @@ var PolicyImplementation = |
}, |
// |
// nsIChannelEventSink interface implementation |
// |
asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback) |
{ |
- let result = Cr.NS_OK; |
+ let async = false; |
try |
{ |
// nsILoadInfo.contentPolicyType was introduced in Gecko 35, then |
// renamed to nsILoadInfo.externalContentPolicyType in Gecko 44. |
let loadInfo = oldChannel.loadInfo; |
let contentType = ("externalContentPolicyType" in loadInfo ? |
loadInfo.externalContentPolicyType : loadInfo.contentPolicyType); |
if (!contentType) |
@@ -257,27 +271,31 @@ var PolicyImplementation = |
// seen the original channel yet because the redirect happened before |
// the async code in observe() had a chance to run. |
this.observe(wnd, "content-document-global-created", null, oldChannel.URI.spec); |
this.observe(wnd, "content-document-global-created", null, newChannel.URI.spec); |
} |
return; |
} |
- if (!shouldAllow(wnd, wnd.document, types.get(contentType), newChannel.URI.spec)) |
- result = Cr.NS_BINDING_ABORTED; |
+ shouldAllow(wnd, wnd.document, types.get(contentType), newChannel.URI.spec, function(allow) |
+ { |
+ callback.onRedirectVerifyCallback(allow ? Cr.NS_OK : Cr.NS_BINDING_ABORTED); |
+ }); |
+ async = true; |
} |
catch (e) |
{ |
// We shouldn't throw exceptions here - this will prevent the redirect. |
Cu.reportError(e); |
} |
finally |
{ |
- callback.onRedirectVerifyCallback(result); |
+ if (!async) |
+ callback.onRedirectVerifyCallback(Cr.NS_OK); |
} |
}, |
// |
// nsIFactory interface implementation |
// |
createInstance: function(outer, iid) |