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

Side by Side Diff: lib/scriptInjection.js

Issue 29737561: Issue 6539, 6782 - Implement support for snippets (Closed) Base URL: https://hg.adblockplus.org/adblockpluschrome/
Patch Set: Rebase Created May 2, 2018, 7:50 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/cssInjection.js ('k') | metadata.chrome » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 "use strict";
19
20 const {RegExpFilter} = require("../adblockpluscore/lib/filterClasses");
21 const {Snippets, compileScript} = require("../adblockpluscore/lib/snippets");
22 const {verifySignature} = require("../adblockpluscore/lib/rsa");
23 const {extractHostFromFrame} = require("./url");
24 const {checkWhitelisted} = require("./whitelisting");
25 const info = require("../buildtools/info");
26
27 const {typeMap} = RegExpFilter;
28 const {getScriptsForDomain} = Snippets;
29
30 const remoteURL = "https://easylist-downloads.adblockplus.org/snippets.js";
31
32 let libraries = {local: "", remote: ""};
33 let executableCode = new Map();
34
35 function fetchText(url)
36 {
37 return fetch(url, {cache: "no-cache"}).then(
38 response => response.ok ? response.text() : ""
hub 2018/05/09 12:23:00 you should return a promise if response is not ok.
Manish Jethani 2018/05/09 13:47:38 The function already returns a promise. That promi
hub 2018/05/09 14:27:07 ok.
39 );
40 }
41
42 function updateLibrary(name, text)
43 {
44 libraries[name] = text;
45
46 executableCode.clear();
47 }
48
49 function checkLibrarySignature(url, text)
50 {
51 return fetchText(`${url}.sig`).then(
52 signature => fetchText(browser.extension.getURL("/key")).then(
53 key => verifySignature(key.replace(/=/g, ""), signature, text)
54 )
55 );
56 }
57
58 function loadLibrary(name, url, {verify = true} = {})
59 {
60 fetchText(url).then(text =>
61 {
62 if (text != libraries[name])
63 {
64 let check = verify ? checkLibrarySignature(url, text) :
65 Promise.resolve(true);
66 check.then(ok =>
67 {
68 if (ok)
69 updateLibrary(name, text);
70 });
71 }
72 });
73 }
74
75 function loadLocalLibrary()
76 {
77 loadLibrary("local", browser.extension.getURL("/snippets.js"),
78 {verify: false});
79 }
80
81 function loadRemoteLibrary()
82 {
83 loadLibrary("remote", remoteURL);
84 }
85
86 function getExecutableCode(script)
87 {
88 let code = executableCode.get(script);
89 if (code)
90 return code;
91
92 code = compileScript(script, [libraries.local, libraries.remote]);
93
94 executableCode.set(script, code);
95 return code;
96 }
97
98 function injectCode(script, tabId, frameId)
99 {
100 try
101 {
102 browser.tabs.executeScript(tabId, {
103 code: getExecutableCode(script),
104 frameId,
105 matchAboutBlank: true,
106 runAt: "document_start"
107 })
hub 2018/05/09 17:19:49 shouldn't we log that the filter was applied (ie i
Manish Jethani 2018/05/23 05:12:45 You're right, let me look into that.
108 .catch(error =>
109 {
110 // Sometimes a frame is added and removed very quickly, in such cases we
111 // simply ignore the error.
112 if (error.message == "The frame was removed.")
113 return;
114
115 throw error;
116 });
117 }
118 catch (error)
119 {
120 }
121 }
122
123 loadLocalLibrary();
124
125 // Only Chrome supports dynamic loading of JS.
126 if (info.platform == "chromium")
127 {
128 loadRemoteLibrary();
129
130 // Download every 24 hours.
131 setInterval(loadRemoteLibrary, 24 * 60 * 60 * 1000);
132 }
133
134 browser.webNavigation.onCommitted.addListener(({tabId, frameId, url}) =>
135 {
136 // There's a bug in Chrome that causes webNavigation.onCommitted to get
137 // dispatched twice if there's a URL filter present, therefore we must listen
138 // for all URLs and do an explicit check here.
139 // https://crbug.com/827855
140 if (!/^(https?:\/\/|about:blank\b|about:srcdoc\b)/.test(url))
141 return;
142
143 let page = new ext.Page({id: tabId, url});
144 let frame = ext.getFrame(tabId, frameId);
145
146 if (checkWhitelisted(page, frame, null, typeMap.DOCUMENT | typeMap.ELEMHIDE))
147 return;
148
149 let hostname = extractHostFromFrame(frame);
150
151 for (let script of getScriptsForDomain(hostname))
152 injectCode(script, tabId, frameId);
153 });
OLDNEW
« no previous file with comments | « lib/cssInjection.js ('k') | metadata.chrome » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld