Left: | ||
Right: |
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-present eyeo GmbH | 3 * Copyright (C) 2006-present 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 | 21 |
22 const {defaultMatcher} = require("../adblockpluscore/lib/matcher"); | 22 const {defaultMatcher} = require("../adblockpluscore/lib/matcher"); |
23 const {RegExpFilter} = require("../adblockpluscore/lib/filterClasses"); | 23 const {RegExpFilter} = require("../adblockpluscore/lib/filterClasses"); |
24 const {filterNotifier} = require("../adblockpluscore/lib/filterNotifier"); | 24 const {filterNotifier} = require("../adblockpluscore/lib/filterNotifier"); |
25 const {Prefs} = require("./prefs"); | 25 const {Prefs} = require("./prefs"); |
26 const {extractHostFromFrame, isThirdParty} = require("./url"); | 26 const {extractHostFromFrame, isThirdParty} = require("./url"); |
27 const {getKey, checkWhitelisted} = require("./whitelisting"); | 27 const {getKey, checkWhitelisted} = require("./whitelisting"); |
28 const {port} = require("./messaging"); | 28 const {port} = require("./messaging"); |
29 const info = require("info"); | 29 const info = require("info"); |
30 | 30 |
31 let readyPages = new ext.PageMap(); | |
32 | |
33 /** | |
34 * Checks whether the given page is ready to use the filter composer | |
35 * | |
36 * @param {Page} page | |
37 * @return {boolean} | |
38 */ | |
39 exports.isPageReady = page => | |
kzar
2018/09/28 15:37:34
I coudln't see where `isPageReady` was being used
| |
40 { | |
41 return readyPages.has(page); | |
42 }; | |
43 | |
44 function isValidString(s) | 31 function isValidString(s) |
45 { | 32 { |
46 return s && s.indexOf("\0") == -1; | 33 return s && s.indexOf("\0") == -1; |
47 } | 34 } |
48 | 35 |
49 function escapeChar(chr) | 36 function escapeChar(chr) |
50 { | 37 { |
51 let code = chr.charCodeAt(0); | 38 let code = chr.charCodeAt(0); |
52 | 39 |
53 // Control characters and leading digits must be escaped based on | 40 // Control characters and leading digits must be escaped based on |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 | 144 |
158 // Add an element hiding filter for each generated CSS selector | 145 // Add an element hiding filter for each generated CSS selector |
159 for (let selector of selectors) | 146 for (let selector of selectors) |
160 filters.push(docDomain.replace(/^www\./, "") + "##" + selector); | 147 filters.push(docDomain.replace(/^www\./, "") + "##" + selector); |
161 } | 148 } |
162 } | 149 } |
163 | 150 |
164 return {filters, selectors}; | 151 return {filters, selectors}; |
165 } | 152 } |
166 | 153 |
167 let contextMenuItem = { | |
168 title: browser.i18n.getMessage("block_element"), | |
169 contexts: ["image", "video", "audio"], | |
170 onclick(page) | |
171 { | |
172 page.sendMessage({type: "composer.content.contextMenuClicked"}); | |
173 } | |
174 }; | |
175 | |
176 function updateContextMenu(page, filter) | |
177 { | |
178 page.contextMenus.remove(contextMenuItem); | |
179 | |
180 if (typeof filter == "undefined") | |
181 filter = checkWhitelisted(page); | |
182 | |
183 // We don't support the filter composer on Firefox for Android, because the | |
184 // user experience on mobile is quite different. | |
185 if (info.application != "fennec" && | |
186 !filter && Prefs.shouldShowBlockElementMenu && readyPages.has(page)) | |
187 { | |
188 page.contextMenus.create(contextMenuItem); | |
189 } | |
190 } | |
191 | |
192 filterNotifier.on("page.WhitelistingStateRevalidate", updateContextMenu); | |
193 | |
194 Prefs.on("shouldShowBlockElementMenu", () => | |
195 { | |
196 browser.tabs.query({}, tabs => | |
197 { | |
198 for (let tab of tabs) | |
199 updateContextMenu(new ext.Page(tab)); | |
200 }); | |
201 }); | |
202 | |
203 port.on("composer.isPageReady", (message, sender) => | |
204 { | |
205 return readyPages.has(new ext.Page({id: message.pageId})); | |
206 }); | |
207 | |
208 port.on("composer.ready", (message, sender) => | |
209 { | |
210 readyPages.set(sender.page, null); | |
211 updateContextMenu(sender.page); | |
212 }); | |
213 | |
214 port.on("composer.openDialog", (message, sender) => | 154 port.on("composer.openDialog", (message, sender) => |
215 { | 155 { |
216 return browser.windows.create({ | 156 return browser.windows.create({ |
217 url: browser.extension.getURL("composer.html"), | 157 url: browser.extension.getURL("composer.html"), |
218 left: 50, | 158 left: 50, |
219 top: 50, | 159 top: 50, |
220 width: 420, | 160 width: 420, |
221 height: 200, | 161 height: 200, |
222 type: "popup" | 162 type: "popup" |
223 }).then(window => | 163 }).then(window => |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
331 // When tabs start loading we send them a message to ensure that the state | 271 // When tabs start loading we send them a message to ensure that the state |
332 // of the "block element" tool is reset. This is necessary since Firefox will | 272 // of the "block element" tool is reset. This is necessary since Firefox will |
333 // sometimes cache the state of a tab when the user navigates back / forward, | 273 // sometimes cache the state of a tab when the user navigates back / forward, |
334 // which includes the state of the "block element" tool. | 274 // which includes the state of the "block element" tool. |
335 // Since sending this message will often fail (e.g. for new tabs which have | 275 // Since sending this message will often fail (e.g. for new tabs which have |
336 // just been opened) we catch and ignore any exception thrown. | 276 // just been opened) we catch and ignore any exception thrown. |
337 browser.tabs.sendMessage( | 277 browser.tabs.sendMessage( |
338 page.id, {type: "composer.content.finished"} | 278 page.id, {type: "composer.content.finished"} |
339 ).catch(() => {}); | 279 ).catch(() => {}); |
340 }); | 280 }); |
281 | |
282 | |
283 /* Context menu and popup button */ | |
284 | |
285 let readyActivePages = new ext.PageMap(); | |
286 let showingContextMenu = false; | |
287 | |
288 function showOrHideContextMenu(activePage) | |
289 { | |
290 // Firefox for Android does not support browser.contextMenus. | |
291 // https://bugzilla.mozilla.org/show_bug.cgi?id=1269062 | |
292 if (!("contextMenus" in browser)) | |
293 return; | |
294 | |
295 let shouldShowContextMenu = Prefs.shouldShowBlockElementMenu && | |
296 readyActivePages.get(activePage); | |
297 | |
298 if (shouldShowContextMenu && !showingContextMenu) | |
kzar
2018/09/28 15:37:34
The previous logic wasn't great, I noticed it was
| |
299 { | |
300 browser.contextMenus.create({ | |
kzar
2018/09/28 15:37:34
I originally kept the `contextMenuItem` variable,
| |
301 id: "block_element", | |
302 title: browser.i18n.getMessage("block_element"), | |
303 contexts: ["image", "video", "audio"], | |
304 onclick(itemInfo, tab) | |
305 { | |
306 let page = new ext.Page(tab); | |
307 page.sendMessage({type: "composer.content.contextMenuClicked"}); | |
308 } | |
309 }); | |
310 showingContextMenu = true; | |
311 } | |
312 else if (!shouldShowContextMenu && showingContextMenu) | |
313 { | |
314 browser.contextMenus.remove("block_element"); | |
315 showingContextMenu = false; | |
316 } | |
317 } | |
318 | |
319 function updateContextMenu(updatedPage) | |
320 { | |
321 browser.tabs.query({active: true, lastFocusedWindow: true}).then(tabs => | |
322 { | |
323 if (tabs.length > 0 && (!updatedPage || updatedPage.id == tabs[0].id)) | |
324 showOrHideContextMenu(updatedPage || new ext.Page(tabs[0])); | |
325 }); | |
326 } | |
327 | |
328 browser.tabs.onActivated.addListener(activeInfo => | |
329 { | |
330 showOrHideContextMenu(new ext.Page({id: activeInfo.tabId})); | |
331 }); | |
332 | |
333 // Firefox for Android does not support browser.windows. | |
kzar
2018/09/28 15:37:34
Like we discussed, it's kind of pointless to worry
| |
334 // https://issues.adblockplus.org/ticket/5347 | |
335 if ("windows" in browser) | |
336 { | |
337 browser.windows.onFocusChanged.addListener(windowId => | |
338 { | |
339 if (windowId != browser.windows.WINDOW_ID_NONE) | |
340 updateContextMenu(); | |
341 }); | |
342 } | |
343 | |
344 filterNotifier.on("page.WhitelistingStateRevalidate", (page, filter) => | |
345 { | |
346 if (readyActivePages.has(page)) | |
347 { | |
348 readyActivePages.set(page, !filter); | |
349 updateContextMenu(page); | |
350 } | |
351 }); | |
352 | |
353 Prefs.on("shouldShowBlockElementMenu", () => | |
354 { | |
355 updateContextMenu(); | |
356 }); | |
357 | |
358 port.on("composer.isPageReady", (message, sender) => | |
359 { | |
360 return readyActivePages.has(new ext.Page({id: message.pageId})); | |
361 }); | |
362 | |
363 port.on("composer.ready", (message, sender) => | |
364 { | |
365 readyActivePages.set(sender.page, !checkWhitelisted(sender.page)); | |
366 updateContextMenu(sender.page); | |
367 }); | |
OLD | NEW |