| 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) |