| OLD | NEW | 
|---|
| 1 // We are currently limited to ECMAScript 5 in this file, because it is being | 1 /* | 
| 2 // used in the browser tests. See https://issues.adblockplus.org/ticket/4796 | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
|  | 3  * Copyright (C) 2006-2017 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  */ | 
| 3 | 17 | 
| 4 var propertySelectorRegExp = /\[\-abp\-properties=(["'])([^"']+)\1\]/; | 18 /* globals filterToRegExp */ | 
|  | 19 | 
|  | 20 "use strict"; | 
|  | 21 | 
|  | 22 let propertySelectorRegExp = /\[-abp-properties=(["'])([^"']+)\1\]/; | 
| 5 | 23 | 
| 6 function splitSelector(selector) | 24 function splitSelector(selector) | 
| 7 { | 25 { | 
| 8   if (selector.indexOf(",") == -1) | 26   if (selector.indexOf(",") == -1) | 
| 9     return [selector]; | 27     return [selector]; | 
| 10 | 28 | 
| 11   var selectors = []; | 29   let selectors = []; | 
| 12   var start = 0; | 30   let start = 0; | 
| 13   var level = 0; | 31   let level = 0; | 
| 14   var sep = ""; | 32   let sep = ""; | 
| 15 | 33 | 
| 16   for (var i = 0; i < selector.length; i++) | 34   for (let i = 0; i < selector.length; i++) | 
| 17   { | 35   { | 
| 18     var chr = selector[i]; | 36     let chr = selector[i]; | 
| 19 | 37 | 
| 20     if (chr == "\\")        // ignore escaped characters | 38     if (chr == "\\")        // ignore escaped characters | 
| 21       i++; | 39       i++; | 
| 22     else if (chr == sep)    // don't split within quoted text | 40     else if (chr == sep)    // don't split within quoted text | 
| 23       sep = "";             // e.g. [attr=","] | 41       sep = "";             // e.g. [attr=","] | 
| 24     else if (sep == "") | 42     else if (sep == "") | 
| 25     { | 43     { | 
| 26       if (chr == '"' || chr == "'") | 44       if (chr == '"' || chr == "'") | 
| 27         sep = chr; | 45         sep = chr; | 
| 28       else if (chr == "(")  // don't split between parentheses | 46       else if (chr == "(")  // don't split between parentheses | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 42 } | 60 } | 
| 43 | 61 | 
| 44 function ElemHideEmulation(window, getFiltersFunc, addSelectorsFunc) | 62 function ElemHideEmulation(window, getFiltersFunc, addSelectorsFunc) | 
| 45 { | 63 { | 
| 46   this.window = window; | 64   this.window = window; | 
| 47   this.getFiltersFunc = getFiltersFunc; | 65   this.getFiltersFunc = getFiltersFunc; | 
| 48   this.addSelectorsFunc = addSelectorsFunc; | 66   this.addSelectorsFunc = addSelectorsFunc; | 
| 49 } | 67 } | 
| 50 | 68 | 
| 51 ElemHideEmulation.prototype = { | 69 ElemHideEmulation.prototype = { | 
| 52   stringifyStyle: function(style) | 70   stringifyStyle(style) | 
| 53   { | 71   { | 
| 54     var styles = []; | 72     let styles = []; | 
| 55     for (var i = 0; i < style.length; i++) | 73     for (let i = 0; i < style.length; i++) | 
| 56     { | 74     { | 
| 57       var property = style.item(i); | 75       let property = style.item(i); | 
| 58       var value    = style.getPropertyValue(property); | 76       let value = style.getPropertyValue(property); | 
| 59       var priority = style.getPropertyPriority(property); | 77       let priority = style.getPropertyPriority(property); | 
| 60       styles.push(property + ": " + value + (priority ? " !" + priority : "") + 
     ";"); | 78       styles.push(property + ": " + value + (priority ? " !" + priority : "") + | 
|  | 79                   ";"); | 
| 61     } | 80     } | 
| 62     styles.sort(); | 81     styles.sort(); | 
| 63     return styles.join(" "); | 82     return styles.join(" "); | 
| 64   }, | 83   }, | 
| 65 | 84 | 
| 66   isSameOrigin: function(stylesheet) | 85   isSameOrigin(stylesheet) | 
| 67   { | 86   { | 
| 68     try | 87     try | 
| 69     { | 88     { | 
| 70       return new URL(stylesheet.href).origin == this.window.location.origin; | 89       return new URL(stylesheet.href).origin == this.window.location.origin; | 
| 71     } | 90     } | 
| 72     catch (e) | 91     catch (e) | 
| 73     { | 92     { | 
| 74       // Invalid URL, assume that it is first-party. | 93       // Invalid URL, assume that it is first-party. | 
| 75       return true; | 94       return true; | 
| 76     } | 95     } | 
| 77   }, | 96   }, | 
| 78 | 97 | 
| 79   findSelectors: function(stylesheet, selectors, filters) | 98   findSelectors(stylesheet, selectors, filters) | 
| 80   { | 99   { | 
| 81     // Explicitly ignore third-party stylesheets to ensure consistent behavior | 100     // Explicitly ignore third-party stylesheets to ensure consistent behavior | 
| 82     // between Firefox and Chrome. | 101     // between Firefox and Chrome. | 
| 83     if (!this.isSameOrigin(stylesheet)) | 102     if (!this.isSameOrigin(stylesheet)) | 
| 84       return; | 103       return; | 
| 85 | 104 | 
| 86     var rules = stylesheet.cssRules; | 105     let rules = stylesheet.cssRules; | 
| 87     if (!rules) | 106     if (!rules) | 
| 88       return; | 107       return; | 
| 89 | 108 | 
| 90     for (var i = 0; i < rules.length; i++) | 109     for (let rule of rules) | 
| 91     { | 110     { | 
| 92       var rule = rules[i]; |  | 
| 93       if (rule.type != rule.STYLE_RULE) | 111       if (rule.type != rule.STYLE_RULE) | 
| 94         continue; | 112         continue; | 
| 95 | 113 | 
| 96       var style = this.stringifyStyle(rule.style); | 114       let style = this.stringifyStyle(rule.style); | 
| 97       for (var j = 0; j < this.patterns.length; j++) | 115       for (let pattern of this.patterns) | 
| 98       { | 116       { | 
| 99         var pattern = this.patterns[j]; |  | 
| 100         if (pattern.regexp.test(style)) | 117         if (pattern.regexp.test(style)) | 
| 101         { | 118         { | 
| 102           var subSelectors = splitSelector(rule.selectorText); | 119           let subSelectors = splitSelector(rule.selectorText); | 
| 103           for (var k = 0; k < subSelectors.length; k++) | 120           for (let subSelector of subSelectors) | 
| 104           { | 121           { | 
| 105             var subSelector = subSelectors[k]; |  | 
| 106             selectors.push(pattern.prefix + subSelector + pattern.suffix); | 122             selectors.push(pattern.prefix + subSelector + pattern.suffix); | 
| 107             filters.push(pattern.text); | 123             filters.push(pattern.text); | 
| 108           } | 124           } | 
| 109         } | 125         } | 
| 110       } | 126       } | 
| 111     } | 127     } | 
| 112   }, | 128   }, | 
| 113 | 129 | 
| 114   addSelectors: function(stylesheets) | 130   addSelectors(stylesheets) | 
| 115   { | 131   { | 
| 116     var selectors = []; | 132     let selectors = []; | 
| 117     var filters = []; | 133     let filters = []; | 
| 118     for (var i = 0; i < stylesheets.length; i++) | 134     for (let stylesheet of stylesheets) | 
| 119       this.findSelectors(stylesheets[i], selectors, filters); | 135       this.findSelectors(stylesheet, selectors, filters); | 
| 120     this.addSelectorsFunc(selectors, filters); | 136     this.addSelectorsFunc(selectors, filters); | 
| 121   }, | 137   }, | 
| 122 | 138 | 
| 123   onLoad: function(event) | 139   onLoad(event) | 
| 124   { | 140   { | 
| 125     var stylesheet = event.target.sheet; | 141     let stylesheet = event.target.sheet; | 
| 126     if (stylesheet) | 142     if (stylesheet) | 
| 127       this.addSelectors([stylesheet]); | 143       this.addSelectors([stylesheet]); | 
| 128   }, | 144   }, | 
| 129 | 145 | 
| 130   apply: function() | 146   apply() | 
| 131   { | 147   { | 
| 132     this.getFiltersFunc(function(patterns) | 148     this.getFiltersFunc(patterns => | 
| 133     { | 149     { | 
| 134       this.patterns = []; | 150       this.patterns = []; | 
| 135       for (var i = 0; i < patterns.length; i++) | 151       for (let pattern of patterns) | 
| 136       { | 152       { | 
| 137         var pattern = patterns[i]; | 153         let match = propertySelectorRegExp.exec(pattern.selector); | 
| 138         var match = propertySelectorRegExp.exec(pattern.selector); |  | 
| 139         if (!match) | 154         if (!match) | 
| 140           continue; | 155           continue; | 
| 141 | 156 | 
| 142         var propertyExpression = match[2]; | 157         let propertyExpression = match[2]; | 
| 143         var regexpString; | 158         let regexpString; | 
| 144         if (propertyExpression.length >= 2 && propertyExpression[0] == "/" && | 159         if (propertyExpression.length >= 2 && propertyExpression[0] == "/" && | 
| 145             propertyExpression[propertyExpression.length - 1] == "/") | 160             propertyExpression[propertyExpression.length - 1] == "/") | 
|  | 161         { | 
| 146           regexpString = propertyExpression.slice(1, -1) | 162           regexpString = propertyExpression.slice(1, -1) | 
| 147               .replace("\\x7B ", "{").replace("\\x7D ", "}"); | 163               .replace("\\x7B ", "{").replace("\\x7D ", "}"); | 
|  | 164         } | 
| 148         else | 165         else | 
| 149           regexpString = filterToRegExp(propertyExpression); | 166           regexpString = filterToRegExp(propertyExpression); | 
| 150 | 167 | 
| 151         this.patterns.push({ | 168         this.patterns.push({ | 
| 152           text: pattern.text, | 169           text: pattern.text, | 
| 153           regexp: new RegExp(regexpString, "i"), | 170           regexp: new RegExp(regexpString, "i"), | 
| 154           prefix: pattern.selector.substr(0, match.index), | 171           prefix: pattern.selector.substr(0, match.index), | 
| 155           suffix: pattern.selector.substr(match.index + match[0].length) | 172           suffix: pattern.selector.substr(match.index + match[0].length) | 
| 156         }); | 173         }); | 
| 157       } | 174       } | 
| 158 | 175 | 
| 159       if (this.patterns.length > 0) | 176       if (this.patterns.length > 0) | 
| 160       { | 177       { | 
| 161         var document = this.window.document; | 178         let {document} = this.window; | 
| 162         this.addSelectors(document.styleSheets); | 179         this.addSelectors(document.styleSheets); | 
| 163         document.addEventListener("load", this.onLoad.bind(this), true); | 180         document.addEventListener("load", this.onLoad.bind(this), true); | 
| 164       } | 181       } | 
| 165     }.bind(this)); | 182     }); | 
| 166   } | 183   } | 
| 167 }; | 184 }; | 
| OLD | NEW | 
|---|