aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEinar Egilsson <einar@einaregilsson.com>2015-09-11 14:50:34 +0000
committerEinar Egilsson <einar@einaregilsson.com>2015-09-11 14:50:34 +0000
commit89ba5a704619de23cb7111d086b26d72ab8df274 (patch)
tree3901ac419e380e8b251e79e2cf91a0cbf51c072d
parent462ca78e5c63682c06f96dade70d193b9e1b68c1 (diff)
Almost ready
-rw-r--r--icon.html2
-rw-r--r--images/icon19redirected.pngbin0 -> 262 bytes
-rw-r--r--images/icon38redirected.pngbin0 -> 386 bytes
-rw-r--r--js/background.js196
-rw-r--r--manifest.json2
-rw-r--r--redirector.html2
6 files changed, 176 insertions, 26 deletions
diff --git a/icon.html b/icon.html
index 579a6a9..67a8079 100644
--- a/icon.html
+++ b/icon.html
@@ -32,7 +32,7 @@
function createImageLink(size, logoFontSize, logoX, logoY) {
- var colors = {'#333' : 'active', '#bbb' : 'disabled'};
+ var colors = {'#333' : 'active', '#bbb' : 'disabled', 'green' : 'redirected'};
for (var color in colors) {
var canvas = document.createElement('canvas');
canvas.width = canvas.height = size;
diff --git a/images/icon19redirected.png b/images/icon19redirected.png
new file mode 100644
index 0000000..dce8b13
--- /dev/null
+++ b/images/icon19redirected.png
Binary files differ
diff --git a/images/icon38redirected.png b/images/icon38redirected.png
new file mode 100644
index 0000000..45c1db8
--- /dev/null
+++ b/images/icon38redirected.png
Binary files differ
diff --git a/js/background.js b/js/background.js
index 35b1243..d080504 100644
--- a/js/background.js
+++ b/js/background.js
@@ -1,50 +1,200 @@
+//This is the background script. It is responsible for actually redirecting requests,
+//as well as monitoring changes in the redirects and the disabled status and reacting to them.
-function checkForRedirect(details) {
+//TODO: Better browser detection...
+var isFirefox = !!navigator.userAgent.match(/Firefox\//);
+var storage = chrome.storage.local; //TODO: Change to sync when Firefox supports it...
+
+//Hopefully Firefox will fix this at some point and we can just use onBeforeRequest everywhere...
+var redirectEvent = isFirefox ? chrome.webRequest.onBeforeSendHeaders : chrome.webRequest.onBeforeRequest;
+
+//Redirects partitioned by request type, so we have to run through
+//the minimum number of redirects for each request.
+var partitionedRedirects = {};
+
+//Keep track of tabids where the main_frame url has been redirected.
+//Mark it as green until a new url is loaded.
+var tabIdToIcon = {
+};
+
+function log(msg) {
+ if (log.enabled) {
+ console.log(msg);
+ }
+}
+log.enabled = true;
+
+function setIcon(image19, image38, tabId) {
+ var data = {
+ path: {
+ 19: image19,
+ 38: image38
+ }
+ };
+ if (typeof tabId !== 'undefined') {
+ data.tabId = tabId;
+ }
+ chrome.browserAction.setIcon(data, function(tab) {
+ var err = chrome.runtime.lastError;
+ if (err) {
+ //If not checked we will get unchecked errors in the background page console...
+ log('Error in SetIcon: ' + err.message);
+ }
+ });
+}
+
+//This is the actual function that gets called for each request and must
+//decide whether or not we want to redirect.
+function checkRedirects(details) {
+
+ log('Checking: ' + details.url);
+
//We only allow GET request to be redirected, don't want to accidentally redirect
//sensitive POST parameters
if (details.method != 'GET') {
return null;
}
- if (details.url.match(/mbl\.is/)) {
- console.log('Redirecting ' + details.url);
- return {redirectUrl: 'http://foo.is'}; //this doesn't work
- }
- return null; //{redirectUrl: 'http://foo.is'}; //this doesn't work
+ var list = partitionedRedirects[details.type];
+ if (!list) {
+ log('No list for type: ' + details.type);
+ return;
+ }
+
+ for (var i = 0; i < list.length; i++) {
+ var r = list[i];
+ var result = r.getMatch(details.url);
+
+ if (result.isMatch) {
+
+ //Have to check if the result also matches, which would cause a loop...
+ //Based on tests in chrome it actually looks like we don't get passed the redirect url back into our listener so
+ //this should be unneccessary. But lets verify on Firefox and Opera first, before removing this code (and the recursive warning in the
+ //edit box)
+ var recursiveResult = r.getMatch(result.redirectTo);
+ if (recursiveResult.isMatch) {
+ log('Ignoring pattern ' + r.includePattern + ' for url ' + details.url + ', because it would also match the result: ' + result.redirectTo);
+ } else {
+ log('Redirecting ' + details.url + ' ===> ' + result.redirectTo + ', type: ' + details.type + ', pattern: ' + r.includePattern);
+
+ /* Unfortunately the setBrowserIcon for a specific tab function is way too unreliable, fails all the time with tab not found,
+ even though the tab is there. So, for now I'm cancelling this feature, which would have been pretty great ... :/
+ if (details.type == 'main_frame') {
+ log('Setting icon on tab ' + details.tabId + ' to green');
+
+ setIcon("images/icon19redirected.png", "images/icon38redirected.png", details.tabId);
+ tabIdToIcon[details.tabId] = true;
+ }*/
+ return { redirectUrl: result.redirectTo };
+ }
+ }
+ }
+
+ /* Cancelled for now because of setBrowserIcon being really unreliable...
+ if (details.type == 'main_frame' && tabIdToIcon[details.tabId]) {
+ log('Setting icon on tab ' + details.tabId + ' back to active');
+ setIcon("images/icon19active.png", "images/icon38active.png", details.tabId);
+ delete tabIdToIcon[details.tabId];
+ }*/
+
+ return null;
}
+//Monitor changes in data, and setup everything again.
+//This could probably be optimized to not do everything on every change
+//but why bother?
+chrome.storage.onChanged.addListener(function(changes, namespace) {
+ if (changes.disabled) {
+ updateIcon();
-var filter = {urls:["http://*/*", "https://*/*"]};
+ if (changes.disabled.newValue == true) {
+ log('Disabling Redirector, removing listener');
+ redirectEvent.removeListener(checkRedirects);
+ } else {
+ log('Enabling Redirector, setting up listener');
+ setUpRedirectListener();
+ }
+ }
-//TODO: Better browser detection...
-var isFirefox = !!navigator.userAgent.match(/Firefox\//);
+ if (changes.redirects) {
+ log('Redirects have changed, setting up listener again');
+ setUpRedirectListener();
+ }
+});
-var ev = isFirefox ? chrome.webRequest.onBeforeSendHeaders : chrome.webRequest.onBeforeRequest;
-ev.addListener(checkForRedirect, filter, ["blocking"]);
+//Creates a filter to pass to the listener so we don't have to run through
+//all the redirects for all the request types we don't have any redirects for anyway.
+function createFilter(redirects) {
+ var types = [];
+ for (var i = 0; i < redirects.length; i++) {
+ redirects[i].appliesTo.forEach(function(type) {
+ if (types.indexOf(type) == -1) {
+ types.push(type);
+ }
+ });
+ }
+ types.sort();
-var storage = chrome.storage.local; //TODO: Change to sync when Firefox supports it...
+ return {
+ urls: ["http://*/*", "https://*/*"],
+ types : types
+ };
+}
+function createPartitionedRedirects(redirects) {
+ var partitioned = {};
-//Icon updating code below
+ for (var i = 0; i < redirects.length; i++) {
+ var redirect = new Redirect(redirects[i]);
+ redirect.compile();
+ for (var j=0; j<redirect.appliesTo.length;j++) {
+ var requestType = redirect.appliesTo[j];
+ if (partitioned[requestType]) {
+ partitioned[requestType].push(redirect);
+ } else {
+ partitioned[requestType] = [redirect];
+ }
+ }
+ }
+ return partitioned;
+}
+
+//Sets up the listener, partitions the redirects, creates the appropriate filters etc.
+function setUpRedirectListener() {
+
+ redirectEvent.removeListener(checkRedirects); //Unsubscribe first, in case there are changes...
+
+ storage.get('redirects', function(obj) {
+ if (!obj.redirects) {
+ log('No redirects to set up');
+ return;
+ }
+
+ partitionedRedirects = createPartitionedRedirects(obj.redirects);
+ var filter = createFilter(obj.redirects);
+
+ log('Setting filter for listener: ' + JSON.stringify(filter));
+ redirectEvent.addListener(checkRedirects, filter, ["blocking"]);
+ });
+}
function updateIcon() {
storage.get({disabled:false}, function(obj) {
- chrome.browserAction.setIcon({
- path: {
- 19: obj.disabled ? "images/icon19disabled.png" : "images/icon19active.png",
- 38: obj.disabled ? "images/icon38disabled.png" : "images/icon38active.png"
- }
- });
+ if (obj.disabled) {
+ setIcon("images/icon19disabled.png", "images/icon38disabled.png");
+ } else {
+ setIcon("images/icon19active.png", "images/icon38active.png");
+ }
});
}
+//First time setup
updateIcon();
-
-chrome.storage.onChanged.addListener(function(changes, namespace) {
- if (changes.disabled) {
- updateIcon();
+storage.get({disabled:false}, function(obj) {
+ if (!obj.disabled) {
+ setUpRedirectListener();
}
});
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
index 75579fa..834b928 100644
--- a/manifest.json
+++ b/manifest.json
@@ -17,7 +17,7 @@
},
"background": {
- "scripts": ["js/background.js"],
+ "scripts": ["js/redirect.js", "js/background.js"],
"persistent": true
},
diff --git a/redirector.html b/redirector.html
index 2af7493..c437288 100644
--- a/redirector.html
+++ b/redirector.html
@@ -99,7 +99,7 @@
</div>
</div>
<div class="button-container">
- <a ng-class="{disabled:redirect.error}" class="btn green large" ng-click="saveRedirect()">Save</a>
+ <a ng-class="{disabled:redirect.error || redirect.includePattern == ''}" class="btn green large" ng-click="saveRedirect()">Save</a>
<a class="btn red large" ng-click="cancelEdit()">Cancel</a>
</div>
</div>