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

Unified Diff: safari/ext/content.js

Issue 29340571: Issue 3687 - Add experimental support for Safari content blockers (Closed)
Patch Set: Addressed feedback Created May 17, 2016, 3:10 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 | « safari/ext/background.js ('k') | safari/include.youtube.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: safari/ext/content.js
diff --git a/safari/ext/content.js b/safari/ext/content.js
index 164d1a4d9574b6b1e4ef569a15260b2f313f57db..1a465c32481d71298c86e0aac6524a0f1221b113 100644
--- a/safari/ext/content.js
+++ b/safari/ext/content.js
@@ -28,6 +28,20 @@
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 +60,9 @@
referrer: document.referrer,
isTopLevel: isTopLevel,
isPrerendered: isPrerendered,
- documentId: documentId
+ documentId: documentId,
+ legacyAPISupported: "canLoad" in safari.self.tab &&
+ "onbeforeload" in Element.prototype
});
}
@@ -60,83 +76,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);
+ }, 0);
+ }
+ }, true);
+ }
/* Context menus */
« no previous file with comments | « safari/ext/background.js ('k') | safari/include.youtube.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld