Index: abp2blocklist.js |
diff --git a/abp2blocklist.js b/abp2blocklist.js |
index f91bd10ce1097904bd8b8bdcd345d9e65d96bb30..36da06ee6bd0b404ad9d54df770f7040259fdf6f 100644 |
--- a/abp2blocklist.js |
+++ b/abp2blocklist.js |
@@ -11,270 +11,292 @@ var elemhideFilters = []; |
var elemhideExceptions = []; |
var elemhideSelectorExceptions = Object.create(null); |
-function recordException(filter) { |
- if (filter.contentType & (typeMap.IMAGE |
- | typeMap.STYLESHEET |
- | typeMap.SCRIPT |
- | typeMap.FONT |
- | typeMap.MEDIA |
- | typeMap.POPUP |
- | typeMap.OBJECT |
- | typeMap.OBJECT_SUBREQUEST |
- | typeMap.XMLHTTPREQUEST |
- | typeMap.PING |
- | typeMap.SUBDOCUMENT |
- | typeMap.OTHER)) |
- requestExceptions.push(filter); |
- |
- if (filter.contentType & typeMap.ELEMHIDE) |
- elemhideExceptions.push(filter); |
+function recordException(filter) |
+{ |
+ if (filter.contentType & (typeMap.IMAGE |
+ | typeMap.STYLESHEET |
+ | typeMap.SCRIPT |
+ | typeMap.FONT |
+ | typeMap.MEDIA |
+ | typeMap.POPUP |
+ | typeMap.OBJECT |
+ | typeMap.OBJECT_SUBREQUEST |
+ | typeMap.XMLHTTPREQUEST |
+ | typeMap.PING |
+ | typeMap.SUBDOCUMENT |
+ | typeMap.OTHER)) |
+ requestExceptions.push(filter); |
+ |
+ if (filter.contentType & typeMap.ELEMHIDE) |
+ elemhideExceptions.push(filter); |
} |
-function parseDomains(domains, included, excluded) { |
- for (var domain in domains) { |
- if (domain != "") { |
- var enabled = domains[domain]; |
- domain = punycode.toASCII(domain.toLowerCase()); |
- |
- if (!enabled) |
- excluded.push(domain); |
- else if (!domains[""]) |
- included.push(domain); |
- } |
- } |
+function parseDomains(domains, included, excluded) |
+{ |
+ for (var domain in domains) |
+ { |
+ if (domain != "") |
+ { |
+ var enabled = domains[domain]; |
+ domain = punycode.toASCII(domain.toLowerCase()); |
+ |
+ if (!enabled) |
+ excluded.push(domain); |
+ else if (!domains[""]) |
+ included.push(domain); |
+ } |
+ } |
} |
-function recordSelectorException(filter) { |
- var domains = elemhideSelectorExceptions[filter.selector]; |
- if (!domains) |
- domains = elemhideSelectorExceptions[filter.selector] = []; |
+function recordSelectorException(filter) |
+{ |
+ var domains = elemhideSelectorExceptions[filter.selector]; |
+ if (!domains) |
+ domains = elemhideSelectorExceptions[filter.selector] = []; |
- parseDomains(filter.domains, domains, []); |
+ parseDomains(filter.domains, domains, []); |
} |
-function parseFilter(line) { |
- if (line.charAt(0) == "[") |
- return; |
- |
- var filter = filterClasses.Filter.fromText(line); |
- |
- if (filter.sitekeys) |
- return; |
- if (filter instanceof filterClasses.RegExpFilter && !filter.regexpSource) |
- return; |
- |
- if (filter instanceof filterClasses.BlockingFilter) |
- requestFilters.push(filter); |
- if (filter instanceof filterClasses.WhitelistFilter) |
- recordException(filter); |
- if (filter instanceof filterClasses.ElemHideFilter) |
- elemhideFilters.push(filter); |
- if (filter instanceof filterClasses.ElemHideException) |
- recordSelectorException(filter); |
+function parseFilter(line) |
+{ |
+ if (line.charAt(0) == "[") |
+ return; |
+ |
+ var filter = filterClasses.Filter.fromText(line); |
+ |
+ if (filter.sitekeys) |
+ return; |
+ if (filter instanceof filterClasses.RegExpFilter && !filter.regexpSource) |
+ return; |
+ |
+ if (filter instanceof filterClasses.BlockingFilter) |
+ requestFilters.push(filter); |
+ if (filter instanceof filterClasses.WhitelistFilter) |
+ recordException(filter); |
+ if (filter instanceof filterClasses.ElemHideFilter) |
+ elemhideFilters.push(filter); |
+ if (filter instanceof filterClasses.ElemHideException) |
+ recordSelectorException(filter); |
} |
-function escapeRegExp(s) { |
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); |
+function escapeRegExp(s) |
+{ |
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); |
} |
-function matchDomain(domain) { |
- return "^https?://([^/:]*\\.)?" + escapeRegExp(domain) + "[/:]"; |
+function matchDomain(domain) |
+{ |
+ return "^https?://([^/:]*\\.)?" + escapeRegExp(domain) + "[/:]"; |
} |
-function convertElemHideFilter(filter) { |
- var included = []; |
- var excluded = []; |
- var rules = []; |
- |
- parseDomains(filter.domains, included, excluded); |
- |
- if (excluded.length == 0 && !(filter.selector in elemhideSelectorExceptions)) { |
- var action = { |
- type: "css-display-none", |
- selector: filter.selector |
- }; |
- |
- for (var i = 0; i < included.length; i++) |
- rules.push({ |
- trigger: {"url-filter": matchDomain(included[i])}, |
- action: action |
- }); |
- |
- if (included.length == 0) |
- rules.push({ |
- trigger: {"url-filter": "^https?://"}, |
- action: action |
- }); |
- } |
- |
- return rules; |
+function convertElemHideFilter(filter) |
+{ |
+ var included = []; |
+ var excluded = []; |
+ var rules = []; |
+ |
+ parseDomains(filter.domains, included, excluded); |
+ |
+ if (excluded.length == 0 && !(filter.selector in elemhideSelectorExceptions)) |
+ { |
+ var action = { |
+ type: "css-display-none", |
+ selector: filter.selector |
+ }; |
+ |
+ for (var i = 0; i < included.length; i++) |
+ rules.push({ |
+ trigger: {"url-filter": matchDomain(included[i])}, |
+ action: action |
+ }); |
+ |
+ if (included.length == 0) |
+ rules.push({ |
+ trigger: {"url-filter": "^https?://"}, |
+ action: action |
+ }); |
+ } |
+ |
+ return rules; |
} |
-function toRegExp(text) { |
- var result = ""; |
- var lastIndex = text.length - 1; |
- |
- for (var i = 0; i < text.length; i++) |
- { |
- var c = text[i]; |
- |
- switch (c) |
- { |
- case "*": |
- if (result.length > 0 && i < lastIndex && text[i + 1] != "*") |
- result += ".*"; |
- break; |
- case "^": |
- if (i < lastIndex) |
- result += "."; |
- break; |
- case "|": |
- if (i == 0) |
- { |
- result += "^"; |
- break; |
- } |
- if (i == lastIndex) |
- { |
- result += "$"; |
- break; |
- } |
- if (i == 1 && text[0] == "|") |
- { |
- result += "https?://"; |
- break; |
- } |
- case ".": case "+": case "?": case "$": |
- case "{": case "}": case "(": case ")": |
- case "[": case "]": case "\\": |
- result += "\\"; |
- default: |
- result += c; |
- } |
- } |
- |
- return result; |
+function toRegExp(text) |
+{ |
+ var result = ""; |
+ var lastIndex = text.length - 1; |
+ |
+ for (var i = 0; i < text.length; i++) |
+ { |
+ var c = text[i]; |
+ |
+ switch (c) |
+ { |
+ case "*": |
+ if (result.length > 0 && i < lastIndex && text[i + 1] != "*") |
+ result += ".*"; |
+ break; |
+ case "^": |
+ if (i < lastIndex) |
+ result += "."; |
+ break; |
+ case "|": |
+ if (i == 0) |
+ { |
+ result += "^"; |
+ break; |
+ } |
+ if (i == lastIndex) |
+ { |
+ result += "$"; |
+ break; |
+ } |
+ if (i == 1 && text[0] == "|") |
+ { |
+ result += "https?://"; |
+ break; |
+ } |
+ case ".": case "+": case "?": case "$": |
+ case "{": case "}": case "(": case ")": |
+ case "[": case "]": case "\\": |
+ result += "\\"; |
+ default: |
+ result += c; |
+ } |
+ } |
+ |
+ return result; |
} |
-function getRegExpSource(filter) { |
- var source = toRegExp(filter.regexpSource.replace( |
- // Safari expects punycode, filter lists use unicode |
- /^(\|\||\|?https?:\/\/)([\w\-.*\u0080-\uFFFF]+)/i, |
- function (match, prefix, domain) { |
- return prefix + punycode.toASCII(domain); |
- } |
- )); |
- |
- // Limit rules to to HTTP(S) URLs |
- if (!/^(\^|http)/i.test(source)) |
- source = "^https?://.*" + source; |
- |
- return source; |
+function getRegExpSource(filter) |
+{ |
+ var source = toRegExp(filter.regexpSource.replace( |
+ // Safari expects punycode, filter lists use unicode |
+ /^(\|\||\|?https?:\/\/)([\w\-.*\u0080-\uFFFF]+)/i, |
+ function (match, prefix, domain) |
+ { |
+ return prefix + punycode.toASCII(domain); |
+ } |
+ )); |
+ |
+ // Limit rules to to HTTP(S) URLs |
+ if (!/^(\^|http)/i.test(source)) |
+ source = "^https?://.*" + source; |
+ |
+ return source; |
} |
-function getResourceTypes(filter) { |
- var types = []; |
- |
- if (filter.contentType & typeMap.IMAGE) |
- types.push("image"); |
- if (filter.contentType & typeMap.STYLESHEET) |
- types.push("style-sheet"); |
- if (filter.contentType & typeMap.SCRIPT) |
- types.push("script"); |
- if (filter.contentType & typeMap.FONT) |
- types.push("font"); |
- if (filter.contentType & (typeMap.MEDIA | typeMap.OBJECT)) |
- types.push("media"); |
- if (filter.contentType & typeMap.POPUP) |
- types.push("popup"); |
- if (filter.contentType & (typeMap.XMLHTTPREQUEST | typeMap.OBJECT_SUBREQUEST | typeMap.PING | typeMap.OTHER)) |
- types.push("raw"); |
- if (filter.contentType & typeMap.SUBDOCUMENT) |
- types.push("document"); |
- |
- return types; |
+function getResourceTypes(filter) |
+{ |
+ var types = []; |
+ |
+ if (filter.contentType & typeMap.IMAGE) |
+ types.push("image"); |
+ if (filter.contentType & typeMap.STYLESHEET) |
+ types.push("style-sheet"); |
+ if (filter.contentType & typeMap.SCRIPT) |
+ types.push("script"); |
+ if (filter.contentType & typeMap.FONT) |
+ types.push("font"); |
+ if (filter.contentType & (typeMap.MEDIA | typeMap.OBJECT)) |
+ types.push("media"); |
+ if (filter.contentType & typeMap.POPUP) |
+ types.push("popup"); |
+ if (filter.contentType & (typeMap.XMLHTTPREQUEST | typeMap.OBJECT_SUBREQUEST |
+ | typeMap.PING | typeMap.OTHER)) |
+ types.push("raw"); |
+ if (filter.contentType & typeMap.SUBDOCUMENT) |
+ types.push("document"); |
+ |
+ return types; |
} |
-function addDomainPrefix(domains) { |
- var result = []; |
+function addDomainPrefix(domains) |
+{ |
+ var result = []; |
- for (var i = 0; i < domains.length; i++) { |
- var domain = domains[i]; |
- result.push(domain); |
+ for (var i = 0; i < domains.length; i++) |
+ { |
+ var domain = domains[i]; |
+ result.push(domain); |
- if (tldjs.getSubdomain(domain) == "") |
- result.push("www." + domain); |
- } |
+ if (tldjs.getSubdomain(domain) == "") |
+ result.push("www." + domain); |
+ } |
- return result; |
+ return result; |
} |
-function convertFilter(filter, action, withResourceTypes) { |
- var trigger = {"url-filter": getRegExpSource(filter)}; |
- var included = []; |
- var excluded = []; |
+function convertFilter(filter, action, withResourceTypes) |
+{ |
+ var trigger = {"url-filter": getRegExpSource(filter)}; |
+ var included = []; |
+ var excluded = []; |
- parseDomains(filter.domains, included, excluded); |
+ parseDomains(filter.domains, included, excluded); |
- if (withResourceTypes) |
- trigger["resource-type"] = getResourceTypes(filter); |
- if (filter.thirdParty != null) |
- trigger["load-type"] = [filter.thirdParty ? "third-party" : "first-party"]; |
+ if (withResourceTypes) |
+ trigger["resource-type"] = getResourceTypes(filter); |
+ if (filter.thirdParty != null) |
+ trigger["load-type"] = [filter.thirdParty ? "third-party" : "first-party"]; |
- if (included.length > 0) |
- trigger["if-domain"] = addDomainPrefix(included); |
- else if (excluded.length > 0) |
- trigger["unless-domain"] = addDomainPrefix(excluded); |
+ if (included.length > 0) |
+ trigger["if-domain"] = addDomainPrefix(included); |
+ else if (excluded.length > 0) |
+ trigger["unless-domain"] = addDomainPrefix(excluded); |
- return {trigger: trigger, action: {type: action}}; |
+ return {trigger: trigger, action: {type: action}}; |
} |
-function hasNonASCI(obj) { |
- if (typeof obj == "string") { |
- if (/[^\x00-\x7F]/.test(obj)) |
- return true; |
- } |
- |
- if (typeof obj == "object") { |
- var i; |
- if (obj instanceof Array) |
- for (i = 0; i < obj.length; i++) |
- if (hasNonASCI(obj[i])) |
- return true; |
- |
- var names = Object.getOwnPropertyNames(obj); |
- for (i = 0; i < names.length; i++) |
- if (hasNonASCI(obj[names[i]])) |
- return true; |
- } |
- |
- return false; |
+function hasNonASCI(obj) |
+{ |
+ if (typeof obj == "string") |
+ { |
+ if (/[^\x00-\x7F]/.test(obj)) |
+ return true; |
+ } |
+ |
+ if (typeof obj == "object") |
+ { |
+ var i; |
+ if (obj instanceof Array) |
+ for (i = 0; i < obj.length; i++) |
+ if (hasNonASCI(obj[i])) |
+ return true; |
+ |
+ var names = Object.getOwnPropertyNames(obj); |
+ for (i = 0; i < names.length; i++) |
+ if (hasNonASCI(obj[names[i]])) |
+ return true; |
+ } |
+ |
+ return false; |
} |
-function logRules() { |
- var rules = []; |
- var i; |
- |
- function addRule(rule) { |
- if (!hasNonASCI(rule)) |
- rules.push(rule); |
- } |
- |
- // HACK: We ignore element hiding filter for now to get the list of |
- // rules down below 50K. This limit is enforced by iOS and Safari. |
- // To be undone with https://issues.adblockplus.org/ticket/3585 |
- |
- //for (i = 0; i < elemhideFilters.length; i++) |
- // convertElemHideFilter(elemhideFilters[i]).forEach(addRule); |
- //for (i = 0; i < elemhideExceptions.length; i++) |
- // addRule(convertFilter(elemhideExceptions[i], "ignore-previous-rules", false)); |
- |
- for (i = 0; i < requestFilters.length; i++) |
- addRule(convertFilter(requestFilters[i], "block", true)); |
- for (i = 0; i < requestExceptions.length; i++) |
- addRule(convertFilter(requestExceptions[i], "ignore-previous-rules", true)); |
- |
- console.log(JSON.stringify(rules, null, "\t")); |
+function logRules() |
+{ |
+ var rules = []; |
+ var i; |
+ |
+ // HACK: We ignore element hiding filter for now to get the list of |
+ // rules down below 50K. This limit is enforced by iOS and Safari. |
+ // To be undone with https://issues.adblockplus.org/ticket/3585 |
+ function addRule(rule) |
+ { |
+ if (!hasNonASCI(rule)) |
+ rules.push(rule); |
+ } |
+ |
+ //for (i = 0; i < elemhideFilters.length; i++) |
+ // convertElemHideFilter(elemhideFilters[i]).forEach(addRule); |
+ //for (i = 0; i < elemhideExceptions.length; i++) |
+ // addRule(convertFilter(elemhideExceptions[i], "ignore-previous-rules", false)); |
+ |
+ for (i = 0; i < requestFilters.length; i++) |
+ addRule(convertFilter(requestFilters[i], "block", true)); |
+ for (i = 0; i < requestExceptions.length; i++) |
+ addRule(convertFilter(requestExceptions[i], "ignore-previous-rules", true)); |
+ |
+ console.log(JSON.stringify(rules, null, "\t")); |
} |
var rl = readline.createInterface({input: process.stdin, terminal: false}); |