|
| 1 | +//register an event listener for all web requests |
| 2 | +chrome.webRequest.onBeforeRequest.addListener(manageRequest, {urls: ["<all_urls>"]}, ["blocking"]); |
| 3 | + |
| 4 | +/** |
| 5 | + * Manages a webrequest, redirecting or blocking as necessary. Called |
| 6 | + * directly by Chrome when the onBeforeRequest even fires. |
| 7 | + * @param request - The webrequest. |
| 8 | + */ |
| 9 | +function manageRequest(request){ |
| 10 | + var list = completeFilterList(); |
| 11 | + for(var i in list){ |
| 12 | + if(match(list[i].source, request.url)){ |
| 13 | + |
| 14 | + //block or redirect |
| 15 | + var redirect = |
| 16 | + redirectUrl(list[i].source, list[i].target, request.url); |
| 17 | + |
| 18 | + if(redirect){ |
| 19 | + console.log("Redirecting "+request.url+" to " + redirect); |
| 20 | + return {redirectUrl: redirect}; |
| 21 | + } |
| 22 | + |
| 23 | + else { |
| 24 | + //block the request |
| 25 | + console.log("Blocking " + request.url); |
| 26 | + return {cancel: true}; |
| 27 | + } |
| 28 | + |
| 29 | + } |
| 30 | + } |
| 31 | +} |
| 32 | + |
| 33 | +/** |
| 34 | + * Returns a complete list of URLs to filter. |
| 35 | + */ |
| 36 | +function completeFilterList(){ |
| 37 | + return standardList; |
| 38 | +} |
| 39 | + |
| 40 | +/** |
| 41 | + * Tells if the parameters source and target match, including wildcards |
| 42 | + * which may be present in the source. |
| 43 | + * @param {String} source - The URL to match, which may include '*' as |
| 44 | + * wildcards, matching one or more of any character. |
| 45 | + * @param {String} target - The URL to test against. |
| 46 | + * @return {Boolean} Tells if target matches source. |
| 47 | + */ |
| 48 | +function match(source, target){ |
| 49 | + return new RegExp(escapeUrl(source)).test(target); |
| 50 | +} |
| 51 | + |
| 52 | +/** |
| 53 | + * Calculates a redirect URL given source and target (optionally |
| 54 | + * containing wildcards), and the URL requested, by replaceing wildcards |
| 55 | + * in target with their respective matches in url. For example, |
| 56 | + * redirectUrl("*nowhere*", "*somewhere*", "http://nowhere.nil") returns |
| 57 | + * "http://somewhere.nil". |
| 58 | + * @param {String} source - A string optionally with wildcards, matching |
| 59 | + * url. |
| 60 | + * @param {String} target - A string optionally with wildcards matching |
| 61 | + * url. |
| 62 | + * @param {String} url - The string from which to find matches for |
| 63 | + * wildcards. |
| 64 | + * @return A string like url, with values matching source chagned to those |
| 65 | + * in target. Or, if no target is provided, false. |
| 66 | + */ |
| 67 | +function redirectUrl(source, target, url){ |
| 68 | + if(!target) return false; |
| 69 | + //a list of concrete values for the wildcards |
| 70 | + var matches = url.match(new RegExp(escapeUrl(source))); |
| 71 | + //a list of the non-wildcard parts of target |
| 72 | + var targetSplit = target.split("*"); |
| 73 | + //now we join the two, taking every other, starting with targetSplit |
| 74 | + var joined = targetSplit[0]; |
| 75 | + //i = 1 because targetSplit[0] has been appended above, and because |
| 76 | + //matches[0] is the same as url |
| 77 | + for(var i = 1; i < targetSplit.length; i++){ |
| 78 | + joined += matches[i] + targetSplit[i]; |
| 79 | + } |
| 80 | + return joined; |
| 81 | +} |
| 82 | + |
| 83 | +/** |
| 84 | + * Escape the match URL to make it safe for regex parsing, and convert all |
| 85 | + * wildcards '*' to regex syntax. |
| 86 | + * @param {String} url - the URL to be escaped |
| 87 | + * @return {String} - The escaped URL. |
| 88 | + **/ |
| 89 | +function escapeUrl(url) { |
| 90 | + //regex from http://stackoverflow.com/questions/2593637/how-to-escape-regular-expression-in-javascript |
| 91 | + return url.replace(/([.?+^$[\]\\(){}|-])/g, '\\$1') |
| 92 | + .split('*').join('(.+)'); |
| 93 | +} |
0 commit comments