| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-2016 Eyeo GmbH | 3  * Copyright (C) 2006-2016 Eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 21   // So we have to fallback to the safari object from the parent frame. | 21   // So we have to fallback to the safari object from the parent frame. | 
| 22   if (!("safari" in window)) | 22   if (!("safari" in window)) | 
| 23     window.safari = window.parent.safari; | 23     window.safari = window.parent.safari; | 
| 24 | 24 | 
| 25 | 25 | 
| 26   /* Intialization */ | 26   /* Intialization */ | 
| 27 | 27 | 
| 28   var beforeLoadEvent = document.createEvent("Event"); | 28   var beforeLoadEvent = document.createEvent("Event"); | 
| 29   beforeLoadEvent.initEvent("beforeload"); | 29   beforeLoadEvent.initEvent("beforeload"); | 
| 30 | 30 | 
|  | 31   // Decide if we should use the new content blocker API or not. (Note when the | 
|  | 32   // API is used Safari breaks the canLoad function, making it either throw an | 
|  | 33   // exception or return true when used.) | 
|  | 34   var usingContentBlockerAPI = true; | 
|  | 35   try | 
|  | 36   { | 
|  | 37     if (safari.self.tab.canLoad(beforeLoadEvent, | 
|  | 38                                 {category: "request", | 
|  | 39                                  payload: {type: "prefs.get", | 
|  | 40                                            key: "safariContentBlocker"}}) != tru
     e) | 
|  | 41       usingContentBlockerAPI = false; | 
|  | 42   } | 
|  | 43   catch (e) { }; | 
|  | 44 | 
| 31   var isTopLevel; | 45   var isTopLevel; | 
| 32   var isPrerendered; | 46   var isPrerendered; | 
| 33   var documentId; | 47   var documentId; | 
| 34   function notifyFrameLoading() | 48   function notifyFrameLoading() | 
| 35   { | 49   { | 
| 36     isTopLevel = window == window.top; | 50     isTopLevel = window == window.top; | 
| 37     isPrerendered = document.visibilityState == "prerender"; | 51     isPrerendered = document.visibilityState == "prerender"; | 
| 38     documentId = Math.random().toString().substr(2); | 52     documentId = Math.random().toString().substr(2); | 
| 39 | 53 | 
| 40     // Notify the background page that this frame is loading, generating | 54     // Notify the background page that this frame is loading, generating | 
| 41     // ourselves a random documentId while we're at it. That way the background | 55     // ourselves a random documentId while we're at it. That way the background | 
| 42     // page can communicate with us reliably, despite limitations in Safari's | 56     // page can communicate with us reliably, despite limitations in Safari's | 
| 43     // extension API. | 57     // extension API. | 
| 44     safari.self.tab.dispatchMessage("loading",  { | 58     safari.self.tab.dispatchMessage("loading",  { | 
| 45       url: window.location.href, | 59       url: window.location.href, | 
| 46       referrer: document.referrer, | 60       referrer: document.referrer, | 
| 47       isTopLevel: isTopLevel, | 61       isTopLevel: isTopLevel, | 
| 48       isPrerendered: isPrerendered, | 62       isPrerendered: isPrerendered, | 
| 49       documentId: documentId | 63       documentId: documentId, | 
|  | 64       legacyAPISupported: "canLoad" in safari.self.tab && | 
|  | 65                           "onbeforeload" in Element.prototype | 
| 50     }); | 66     }); | 
| 51   } | 67   } | 
| 52 | 68 | 
| 53   // We must notify the background page when this page is first loadeding (now) | 69   // We must notify the background page when this page is first loadeding (now) | 
| 54   // but also when it is re-shown (if the user uses the back button to return to | 70   // but also when it is re-shown (if the user uses the back button to return to | 
| 55   // this page in the future). | 71   // this page in the future). | 
| 56   notifyFrameLoading(); | 72   notifyFrameLoading(); | 
| 57   window.addEventListener("pageshow", function(event) | 73   window.addEventListener("pageshow", function(event) | 
| 58   { | 74   { | 
| 59     if (event.persisted) | 75     if (event.persisted) | 
| 60       notifyFrameLoading(); | 76       notifyFrameLoading(); | 
| 61   }); | 77   }); | 
| 62 | 78 | 
| 63   // Notify the background page when a prerendered page is displayed. That way | 79   if (!usingContentBlockerAPI) | 
| 64   // the existing page of the tab can be replaced with this new one. |  | 
| 65   if (isTopLevel && isPrerendered) |  | 
| 66   { | 80   { | 
| 67     var onVisibilitychange = function() | 81     // Notify the background page when a prerendered page is displayed. That way | 
|  | 82     // the existing page of the tab can be replaced with this new one. | 
|  | 83     if (isTopLevel && isPrerendered) | 
| 68     { | 84     { | 
| 69       safari.self.tab.dispatchMessage("replaced", {documentId: documentId}); | 85       var onVisibilitychange = function() | 
| 70       document.removeEventListener("visibilitychange", onVisibilitychange); | 86       { | 
| 71     }; | 87         safari.self.tab.dispatchMessage("replaced", {documentId: documentId}); | 
| 72     document.addEventListener("visibilitychange", onVisibilitychange); | 88         document.removeEventListener("visibilitychange", onVisibilitychange); | 
|  | 89       }; | 
|  | 90       document.addEventListener("visibilitychange", onVisibilitychange); | 
|  | 91     } | 
|  | 92 | 
|  | 93   /* Web requests */ | 
|  | 94 | 
|  | 95     document.addEventListener("beforeload", function(event) | 
|  | 96     { | 
|  | 97       // we don't block non-HTTP requests anyway, so we can bail out | 
|  | 98       // without asking the background page. This is even necessary | 
|  | 99       // because passing large data (like a photo encoded as data: URL) | 
|  | 100       // to the background page, freezes Safari. | 
|  | 101       if (/^(?!https?:)[\w-]+:/.test(event.url)) | 
|  | 102         return; | 
|  | 103 | 
|  | 104       var type = "OTHER"; | 
|  | 105       var eventName = "error"; | 
|  | 106 | 
|  | 107       switch(event.target.localName) | 
|  | 108       { | 
|  | 109         case "frame": | 
|  | 110         case "iframe": | 
|  | 111           type = "SUBDOCUMENT"; | 
|  | 112           eventName = "load"; | 
|  | 113           break; | 
|  | 114         case "img": | 
|  | 115         case "input": | 
|  | 116           type = "IMAGE"; | 
|  | 117           break; | 
|  | 118         case "video": | 
|  | 119         case "audio": | 
|  | 120         case "source": | 
|  | 121           type = "MEDIA"; | 
|  | 122           break; | 
|  | 123         case "object": | 
|  | 124         case "embed": | 
|  | 125           type = "OBJECT"; | 
|  | 126           break; | 
|  | 127         case "script": | 
|  | 128           type = "SCRIPT"; | 
|  | 129           break; | 
|  | 130         case "link": | 
|  | 131           if (/\bstylesheet\b/i.test(event.target.rel)) | 
|  | 132             type = "STYLESHEET"; | 
|  | 133           break; | 
|  | 134       } | 
|  | 135 | 
|  | 136       if (!safari.self.tab.canLoad( | 
|  | 137         event, { | 
|  | 138           category: "webRequest", | 
|  | 139           url: event.url, | 
|  | 140           type: type, | 
|  | 141           documentId: documentId})) | 
|  | 142       { | 
|  | 143         event.preventDefault(); | 
|  | 144 | 
|  | 145         // Safari doesn't dispatch the expected events for elements that have | 
|  | 146         // been prevented from loading by having their "beforeload" event | 
|  | 147         // cancelled. That is a "load" event for blocked frames, and an "error" | 
|  | 148         // event for other blocked elements. We need to dispatch those events | 
|  | 149         // manually here to avoid breaking element collapsing and pages that | 
|  | 150         // rely on those events. | 
|  | 151         setTimeout(function() | 
|  | 152         { | 
|  | 153           var evt = document.createEvent("Event"); | 
|  | 154           evt.initEvent(eventName); | 
|  | 155           event.target.dispatchEvent(evt); | 
|  | 156         }, 0); | 
|  | 157       } | 
|  | 158     }, true); | 
| 73   } | 159   } | 
| 74 | 160 | 
| 75 | 161 | 
| 76   /* Web requests */ |  | 
| 77 |  | 
| 78   document.addEventListener("beforeload", function(event) |  | 
| 79   { |  | 
| 80     // we don't block non-HTTP requests anyway, so we can bail out |  | 
| 81     // without asking the background page. This is even necessary |  | 
| 82     // because passing large data (like a photo encoded as data: URL) |  | 
| 83     // to the background page, freezes Safari. |  | 
| 84     if (/^(?!https?:)[\w-]+:/.test(event.url)) |  | 
| 85       return; |  | 
| 86 |  | 
| 87     var type = "OTHER"; |  | 
| 88     var eventName = "error"; |  | 
| 89 |  | 
| 90     switch(event.target.localName) |  | 
| 91     { |  | 
| 92       case "frame": |  | 
| 93       case "iframe": |  | 
| 94         type = "SUBDOCUMENT"; |  | 
| 95         eventName = "load"; |  | 
| 96         break; |  | 
| 97       case "img": |  | 
| 98       case "input": |  | 
| 99         type = "IMAGE"; |  | 
| 100         break; |  | 
| 101       case "video": |  | 
| 102       case "audio": |  | 
| 103       case "source": |  | 
| 104         type = "MEDIA"; |  | 
| 105         break; |  | 
| 106       case "object": |  | 
| 107       case "embed": |  | 
| 108         type = "OBJECT"; |  | 
| 109         break; |  | 
| 110       case "script": |  | 
| 111         type = "SCRIPT"; |  | 
| 112         break; |  | 
| 113       case "link": |  | 
| 114         if (/\bstylesheet\b/i.test(event.target.rel)) |  | 
| 115           type = "STYLESHEET"; |  | 
| 116         break; |  | 
| 117     } |  | 
| 118 |  | 
| 119     if (!safari.self.tab.canLoad(event, { |  | 
| 120         category: "webRequest", |  | 
| 121         url: event.url, |  | 
| 122         type: type, |  | 
| 123         documentId: documentId})) |  | 
| 124     { |  | 
| 125       event.preventDefault(); |  | 
| 126 |  | 
| 127       // Safari doesn't dispatch the expected events for elements that have been |  | 
| 128       // prevented from loading by having their "beforeload" event cancelled. |  | 
| 129       // That is a "load" event for blocked frames, and an "error" event for |  | 
| 130       // other blocked elements. We need to dispatch those events manually here |  | 
| 131       // to avoid breaking element collapsing and pages that rely on those event
     s. |  | 
| 132       setTimeout(function() |  | 
| 133       { |  | 
| 134         var evt = document.createEvent("Event"); |  | 
| 135         evt.initEvent(eventName); |  | 
| 136         event.target.dispatchEvent(evt); |  | 
| 137       }, 0); |  | 
| 138     } |  | 
| 139   }, true); |  | 
| 140 |  | 
| 141 |  | 
| 142   /* Context menus */ | 162   /* Context menus */ | 
| 143 | 163 | 
| 144   document.addEventListener("contextmenu", function(event) | 164   document.addEventListener("contextmenu", function(event) | 
| 145   { | 165   { | 
| 146     var element = event.srcElement; | 166     var element = event.srcElement; | 
| 147     safari.self.tab.setContextMenuEventUserInfo(event, { | 167     safari.self.tab.setContextMenuEventUserInfo(event, { | 
| 148       documentId: documentId, | 168       documentId: documentId, | 
| 149       tagName: element.localName | 169       tagName: element.localName | 
| 150     }); | 170     }); | 
| 151   }); | 171   }); | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 201   }); | 221   }); | 
| 202 | 222 | 
| 203 | 223 | 
| 204   /* Detecting extension reload/disable/uninstall (not supported on Safari) */ | 224   /* Detecting extension reload/disable/uninstall (not supported on Safari) */ | 
| 205 | 225 | 
| 206   ext.onExtensionUnloaded = { | 226   ext.onExtensionUnloaded = { | 
| 207     addListener: function() {}, | 227     addListener: function() {}, | 
| 208     removeListener: function() {} | 228     removeListener: function() {} | 
| 209   }; | 229   }; | 
| 210 })(); | 230 })(); | 
| OLD | NEW | 
|---|