| 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-2017 eyeo GmbH | 3  * Copyright (C) 2006-2017 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 22 matching lines...) Expand all  Loading... | 
| 33  * Checks whether the given page is ready to use the filter composer | 33  * Checks whether the given page is ready to use the filter composer | 
| 34  * | 34  * | 
| 35  * @param {Page} page | 35  * @param {Page} page | 
| 36  * @return {boolean} | 36  * @return {boolean} | 
| 37  */ | 37  */ | 
| 38 exports.isPageReady = page => | 38 exports.isPageReady = page => | 
| 39 { | 39 { | 
| 40   return readyPages.has(page); | 40   return readyPages.has(page); | 
| 41 }; | 41 }; | 
| 42 | 42 | 
| 43 function isValidString(s) { | 43 function isValidString(s) | 
|  | 44 { | 
| 44   return s && s.indexOf("\0") == -1; | 45   return s && s.indexOf("\0") == -1; | 
| 45 } | 46 } | 
| 46 | 47 | 
| 47 function escapeChar(chr) | 48 function escapeChar(chr) | 
| 48 { | 49 { | 
| 49   let code = chr.charCodeAt(0); | 50   let code = chr.charCodeAt(0); | 
| 50 | 51 | 
| 51   // Control characters and leading digits must be escaped based on | 52   // Control characters and leading digits must be escaped based on | 
| 52   // their char code in CSS. Moreover, curly brackets aren't allowed | 53   // their char code in CSS. Moreover, curly brackets aren't allowed | 
| 53   // in elemhide filters, and therefore must be escaped based on their | 54   // in elemhide filters, and therefore must be escaped based on their | 
| 54   // char code as well. | 55   // char code as well. | 
| 55   if (code <= 0x1F || code == 0x7F || /[\d\{\}]/.test(chr)) | 56   if (code <= 0x1F || code == 0x7F || /[\d{}]/.test(chr)) | 
| 56     return "\\" + code.toString(16) + " "; | 57     return "\\" + code.toString(16) + " "; | 
| 57 | 58 | 
| 58   return "\\" + chr; | 59   return "\\" + chr; | 
| 59 } | 60 } | 
| 60 | 61 | 
| 61 let escapeCSS = | 62 let escapeCSS = | 
| 62 /** | 63 /** | 
| 63  * Escapes a token (e.g. tag, id, class or attribute) to be used in CSS selector
     s. | 64  * Escapes a token (e.g. tag, id, class or attribute) to be used in | 
|  | 65  * CSS selectors. | 
| 64  * | 66  * | 
| 65  * @param {string} s | 67  * @param {string} s | 
| 66  * @return {string} | 68  * @return {string} | 
| 67  * @static | 69  * @static | 
| 68  */ | 70  */ | 
| 69 exports.escapeCSS = s => | 71 exports.escapeCSS = s => | 
| 70 { | 72 { | 
| 71   return s.replace(/^[\d\-]|[^\w\-\u0080-\uFFFF]/g, escapeChar); | 73   return s.replace(/^[\d-]|[^\w\-\u0080-\uFFFF]/g, escapeChar); | 
| 72 }; | 74 }; | 
| 73 | 75 | 
| 74 let quoteCSS = | 76 let quoteCSS = | 
| 75 /** | 77 /** | 
| 76  * Quotes a string to be used as attribute value in CSS selectors. | 78  * Quotes a string to be used as attribute value in CSS selectors. | 
| 77  * | 79  * | 
| 78  * @param {string} value | 80  * @param {string} value | 
| 79  * @return {string} | 81  * @return {string} | 
| 80  * @static | 82  * @static | 
| 81  */ | 83  */ | 
| 82 exports.quoteCSS = value => | 84 exports.quoteCSS = value => | 
| 83 { | 85 { | 
| 84   return '"' + value.replace(/["\\\{\}\x00-\x1F\x7F]/g, escapeChar) + '"'; | 86   return '"' + value.replace(/["\\{}\x00-\x1F\x7F]/g, escapeChar) + '"'; | 
| 85 }; | 87 }; | 
| 86 | 88 | 
| 87 function composeFilters(details) | 89 function composeFilters(details) | 
| 88 { | 90 { | 
|  | 91   let {page, frame} = details; | 
| 89   let filters = []; | 92   let filters = []; | 
| 90   let selectors = []; | 93   let selectors = []; | 
| 91 | 94 | 
| 92   let page = details.page; |  | 
| 93   let frame = details.frame; |  | 
| 94 |  | 
| 95   if (!checkWhitelisted(page, frame)) | 95   if (!checkWhitelisted(page, frame)) | 
| 96   { | 96   { | 
| 97     let typeMask = RegExpFilter.typeMap[details.type]; | 97     let typeMask = RegExpFilter.typeMap[details.type]; | 
| 98     let docDomain = extractHostFromFrame(frame); | 98     let docDomain = extractHostFromFrame(frame); | 
| 99     let specificOnly = checkWhitelisted(page, frame, RegExpFilter.typeMap.GENERI
     CBLOCK); | 99     let specificOnly = checkWhitelisted(page, frame, | 
|  | 100                                         RegExpFilter.typeMap.GENERICBLOCK); | 
| 100 | 101 | 
| 101     // Add a blocking filter for each URL of the element that can be blocked | 102     // Add a blocking filter for each URL of the element that can be blocked | 
| 102     for (let url of details.urls) | 103     for (let url of details.urls) | 
| 103     { | 104     { | 
| 104       let urlObj = new URL(url, details.baseURL); | 105       let urlObj = new URL(url, details.baseURL); | 
| 105       url = stringifyURL(urlObj); | 106       url = stringifyURL(urlObj); | 
| 106 | 107 | 
| 107       let filter = defaultMatcher.whitelist.matchesAny( | 108       let filter = defaultMatcher.whitelist.matchesAny( | 
| 108         url, typeMask, docDomain, | 109         url, typeMask, docDomain, | 
| 109         isThirdParty(urlObj, docDomain), | 110         isThirdParty(urlObj, docDomain), | 
| 110         getKey(page, frame), specificOnly | 111         getKey(page, frame), specificOnly | 
| 111       ); | 112       ); | 
| 112 | 113 | 
| 113       if (!filter) | 114       if (!filter) | 
| 114       { | 115       { | 
| 115         let filterText = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"); | 116         let filterText = url.replace(/^[\w-]+:\/+(?:www\.)?/, "||"); | 
| 116 | 117 | 
| 117         if (specificOnly) | 118         if (specificOnly) | 
| 118           filterText += "$domain=" + docDomain; | 119           filterText += "$domain=" + docDomain; | 
| 119 | 120 | 
| 120         if (filters.indexOf(filterText) == -1) | 121         if (filters.indexOf(filterText) == -1) | 
| 121           filters.push(filterText); | 122           filters.push(filterText); | 
| 122       } | 123       } | 
| 123     } | 124     } | 
| 124 | 125 | 
| 125     // If we couldn't generate any blocking filters, fallback to element hiding | 126     // If we couldn't generate any blocking filters, fallback to element hiding | 
| 126     let selectors = []; | 127     if (filters.length == 0 && !checkWhitelisted(page, frame, | 
| 127     if (filters.length == 0 && !checkWhitelisted(page, frame, RegExpFilter.typeM
     ap.ELEMHIDE)) | 128                                                  RegExpFilter.typeMap.ELEMHIDE)) | 
| 128     { | 129     { | 
| 129       // Generate CSS selectors based on the element's "id" and "class" attribut
     e | 130       // Generate CSS selectors based on the element's "id" and | 
|  | 131       // "class" attribute. | 
| 130       if (isValidString(details.id)) | 132       if (isValidString(details.id)) | 
| 131         selectors.push("#" + escapeCSS(details.id)); | 133         selectors.push("#" + escapeCSS(details.id)); | 
| 132 | 134 | 
| 133       let classes = details.classes.filter(isValidString); | 135       let classes = details.classes.filter(isValidString); | 
| 134       if (classes.length > 0) | 136       if (classes.length > 0) | 
| 135         selectors.push(classes.map(c => "." + escapeCSS(c)).join("")); | 137         selectors.push(classes.map(c => "." + escapeCSS(c)).join("")); | 
| 136 | 138 | 
| 137       // If there is a "src" attribute, specifiying a URL that we can't block, | 139       // If there is a "src" attribute, specifiying a URL that we can't block, | 
| 138       // generate a CSS selector matching the "src" attribute | 140       // generate a CSS selector matching the "src" attribute | 
| 139       if (isValidString(details.src)) | 141       if (isValidString(details.src)) | 
| 140         selectors.push(escapeCSS(details.tagName) + "[src=" + quoteCSS(details.s
     rc) + "]"); | 142       { | 
|  | 143         selectors.push( | 
|  | 144           escapeCSS(details.tagName) + "[src=" + quoteCSS(details.src) + "]" | 
|  | 145         ); | 
|  | 146       } | 
| 141 | 147 | 
| 142       // As last resort, if there is a "style" attribute, and we couldn't genera
     te | 148       // As last resort, if there is a "style" attribute, and we | 
| 143       // any filters so far, generate a CSS selector matching the "style" attrib
     ute | 149       // couldn't generate any filters so far, generate a CSS selector | 
| 144       if (isValidString(details.style) && selectors.length == 0 && filters.lengt
     h == 0) | 150       // matching the "style" attribute | 
| 145         selectors.push(escapeCSS(details.tagName) + "[style=" + quoteCSS(details
     .style) + "]"); | 151       if (isValidString(details.style) && selectors.length == 0 && | 
|  | 152           filters.length == 0) | 
|  | 153       { | 
|  | 154         selectors.push( | 
|  | 155           escapeCSS(details.tagName) + "[style=" + quoteCSS(details.style) + "]" | 
|  | 156         ); | 
|  | 157       } | 
| 146 | 158 | 
| 147       // Add an element hiding filter for each generated CSS selector | 159       // Add an element hiding filter for each generated CSS selector | 
| 148       for (let selector of selectors) | 160       for (let selector of selectors) | 
| 149         filters.push(docDomain.replace(/^www\./, "") + "##" + selector); | 161         filters.push(docDomain.replace(/^www\./, "") + "##" + selector); | 
| 150     } | 162     } | 
| 151   } | 163   } | 
| 152 | 164 | 
| 153   return {filters: filters, selectors: selectors}; | 165   return {filters, selectors}; | 
| 154 } | 166 } | 
| 155 | 167 | 
| 156 let contextMenuItem = { | 168 let contextMenuItem = { | 
| 157   title: ext.i18n.getMessage("block_element"), | 169   title: ext.i18n.getMessage("block_element"), | 
| 158   contexts: ["image", "video", "audio"], | 170   contexts: ["image", "video", "audio"], | 
| 159   onclick(page) | 171   onclick(page) | 
| 160   { | 172   { | 
| 161     page.sendMessage({type: "composer.content.contextMenuClicked"}); | 173     page.sendMessage({type: "composer.content.contextMenuClicked"}); | 
| 162   } | 174   } | 
| 163 }; | 175 }; | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 218       ext.pages.onRemoved.addListener(onRemoved); | 230       ext.pages.onRemoved.addListener(onRemoved); | 
| 219       resolve(popupPageId); | 231       resolve(popupPageId); | 
| 220     }); | 232     }); | 
| 221   }); | 233   }); | 
| 222 }); | 234 }); | 
| 223 | 235 | 
| 224 port.on("composer.getFilters", (message, sender) => | 236 port.on("composer.getFilters", (message, sender) => | 
| 225 { | 237 { | 
| 226   return composeFilters({ | 238   return composeFilters({ | 
| 227     tagName: message.tagName, | 239     tagName: message.tagName, | 
| 228     id:      message.id, | 240     id: message.id, | 
| 229     src:     message.src, | 241     src: message.src, | 
| 230     style:   message.style, | 242     style: message.style, | 
| 231     classes: message.classes, | 243     classes: message.classes, | 
| 232     urls:    message.urls, | 244     urls: message.urls, | 
| 233     type:    message.mediatype, | 245     type: message.mediatype, | 
| 234     baseURL: message.baseURL, | 246     baseURL: message.baseURL, | 
| 235     page:    sender.page, | 247     page: sender.page, | 
| 236     frame:   sender.frame | 248     frame: sender.frame | 
| 237   }); | 249   }); | 
| 238 }); | 250 }); | 
| 239 | 251 | 
| 240 ext.pages.onLoading.addListener(page => | 252 ext.pages.onLoading.addListener(page => | 
| 241 { | 253 { | 
| 242   page.sendMessage({type: "composer.content.finished"}); | 254   page.sendMessage({type: "composer.content.finished"}); | 
| 243 }); | 255 }); | 
| OLD | NEW | 
|---|