| Index: safari/ext/content.js |
| diff --git a/safari/ext/content.js b/safari/ext/content.js |
| index 164d1a4d9574b6b1e4ef569a15260b2f313f57db..07b89742a8f2d44e52915fb3d794074c50d5feb0 100644 |
| --- a/safari/ext/content.js |
| +++ b/safari/ext/content.js |
| @@ -28,6 +28,22 @@ |
| var beforeLoadEvent = document.createEvent("Event"); |
| beforeLoadEvent.initEvent("beforeload"); |
| + // Decide if we should use the new content blocker API or not. (Note when the |
| + // API is used Safari breaks the canLoad function, making it either throw an |
| + // exception or return true when used.) |
| + var usingContentBlockerAPI = true; |
| + try |
| + { |
| + if (safari.self.tab.canLoad(beforeLoadEvent, |
| + {category: "request", |
| + payload: {type: "prefs.get", |
| + key: "safariContentBlocker"}}) != true) |
| + usingContentBlockerAPI = false; |
| + } |
| + catch (e) |
| + { |
| + } |
| + |
| var isTopLevel; |
| var isPrerendered; |
| var documentId; |
| @@ -46,7 +62,9 @@ |
| referrer: document.referrer, |
| isTopLevel: isTopLevel, |
| isPrerendered: isPrerendered, |
| - documentId: documentId |
| + documentId: documentId, |
| + legacyAPISupported: "canLoad" in safari.self.tab && |
| + "onbeforeload" in Element.prototype |
| }); |
| } |
| @@ -60,83 +78,87 @@ |
| notifyFrameLoading(); |
| }); |
| - // Notify the background page when a prerendered page is displayed. That way |
| - // the existing page of the tab can be replaced with this new one. |
| - if (isTopLevel && isPrerendered) |
| + if (!usingContentBlockerAPI) |
| { |
| - var onVisibilitychange = function() |
| + // Notify the background page when a prerendered page is displayed. That way |
| + // the existing page of the tab can be replaced with this new one. |
| + if (isTopLevel && isPrerendered) |
| { |
| - safari.self.tab.dispatchMessage("replaced", {documentId: documentId}); |
| - document.removeEventListener("visibilitychange", onVisibilitychange); |
| - }; |
| - document.addEventListener("visibilitychange", onVisibilitychange); |
| - } |
| - |
| + var onVisibilitychange = function() |
| + { |
| + safari.self.tab.dispatchMessage("replaced", {documentId: documentId}); |
| + document.removeEventListener("visibilitychange", onVisibilitychange); |
| + }; |
| + document.addEventListener("visibilitychange", onVisibilitychange); |
| + } |
| /* Web requests */ |
| - document.addEventListener("beforeload", function(event) |
| - { |
| - // we don't block non-HTTP requests anyway, so we can bail out |
| - // without asking the background page. This is even necessary |
| - // because passing large data (like a photo encoded as data: URL) |
| - // to the background page, freezes Safari. |
| - if (/^(?!https?:)[\w-]+:/.test(event.url)) |
| - return; |
| + document.addEventListener("beforeload", function(event) |
| + { |
| + // we don't block non-HTTP requests anyway, so we can bail out |
| + // without asking the background page. This is even necessary |
| + // because passing large data (like a photo encoded as data: URL) |
| + // to the background page, freezes Safari. |
| + if (/^(?!https?:)[\w-]+:/.test(event.url)) |
| + return; |
| - var type = "OTHER"; |
| - var eventName = "error"; |
| + var type = "OTHER"; |
| + var eventName = "error"; |
| - switch(event.target.localName) |
| - { |
| - case "frame": |
| - case "iframe": |
| - type = "SUBDOCUMENT"; |
| - eventName = "load"; |
| - break; |
| - case "img": |
| - case "input": |
| - type = "IMAGE"; |
| - break; |
| - case "video": |
| - case "audio": |
| - case "source": |
| - type = "MEDIA"; |
| - break; |
| - case "object": |
| - case "embed": |
| - type = "OBJECT"; |
| - break; |
| - case "script": |
| - type = "SCRIPT"; |
| - break; |
| - case "link": |
| - if (/\bstylesheet\b/i.test(event.target.rel)) |
| - type = "STYLESHEET"; |
| - break; |
| - } |
| + switch(event.target.localName) |
| + { |
| + case "frame": |
| + case "iframe": |
| + type = "SUBDOCUMENT"; |
| + eventName = "load"; |
| + break; |
| + case "img": |
| + case "input": |
| + type = "IMAGE"; |
| + break; |
| + case "video": |
| + case "audio": |
| + case "source": |
| + type = "MEDIA"; |
| + break; |
| + case "object": |
| + case "embed": |
| + type = "OBJECT"; |
| + break; |
| + case "script": |
| + type = "SCRIPT"; |
| + break; |
| + case "link": |
| + if (/\bstylesheet\b/i.test(event.target.rel)) |
| + type = "STYLESHEET"; |
| + break; |
| + } |
| - if (!safari.self.tab.canLoad(event, { |
| - category: "webRequest", |
| - url: event.url, |
| - type: type, |
| - documentId: documentId})) |
| - { |
| - event.preventDefault(); |
| - |
| - // Safari doesn't dispatch the expected events for elements that have been |
| - // prevented from loading by having their "beforeload" event cancelled. |
| - // That is a "load" event for blocked frames, and an "error" event for |
| - // other blocked elements. We need to dispatch those events manually here |
| - // to avoid breaking element collapsing and pages that rely on those events. |
| - setTimeout(function() |
| + if (!safari.self.tab.canLoad( |
| + event, { |
| + category: "webRequest", |
| + url: event.url, |
| + type: type, |
| + documentId: documentId})) |
| { |
| - var evt = document.createEvent("Event"); |
| - evt.initEvent(eventName); |
| - event.target.dispatchEvent(evt); |
| - }, 0); |
| - } |
| - }, true); |
| + event.preventDefault(); |
| + |
| + // Safari doesn't dispatch the expected events for elements that have |
| + // been prevented from loading by having their "beforeload" event |
| + // cancelled. That is a "load" event for blocked frames, and an "error" |
| + // event for other blocked elements. We need to dispatch those events |
| + // manually here to avoid breaking element collapsing and pages that |
| + // rely on those events. |
| + setTimeout(function() |
| + { |
| + var evt = document.createEvent("Event"); |
| + evt.initEvent(eventName); |
| + event.target.dispatchEvent(evt); |
| + }); |
| + } |
| + }, true); |
| + } |
| /* Context menus */ |