diff options
| -rw-r--r-- | .jpmignore | 18 | ||||
| -rwxr-xr-x | build.py | 37 | ||||
| -rw-r--r-- | js/background.js | 64 | ||||
| -rw-r--r-- | js/controllers/redirectorpage.js | 17 | ||||
| -rw-r--r-- | js/firefox/background-shim.js | 243 | ||||
| -rw-r--r-- | js/firefox/page-shim.js | 80 | ||||
| -rw-r--r-- | js/popup-scriptload.js | 13 | ||||
| -rw-r--r-- | js/popup.js | 13 | ||||
| -rw-r--r-- | js/redirector-scriptload.js | 19 | ||||
| -rw-r--r-- | package.json | 18 | ||||
| -rw-r--r-- | popup.html | 3 | ||||
| -rw-r--r-- | redirector.html | 11 | 
12 files changed, 88 insertions, 448 deletions
diff --git a/.jpmignore b/.jpmignore deleted file mode 100644 index 8208b36..0000000 --- a/.jpmignore +++ /dev/null @@ -1,18 +0,0 @@ -.DS_Store -*.zip -*.xpi -manifest.json -.git/* -*.pem -.gitignore -.jpmignore -*.py -icon.html -devprofile/* -unittest/* -build/* -*.nex -debug.sh -*.sh -promo/* - @@ -20,36 +20,18 @@ def get_files_to_zip():  				zippable_files.append(file)  	return zippable_files -def create_firefox_addon(): -	print '' -	print '**** Creating addon for Firefox ****' -	os.system('jpm xpi') -	import glob, shutil -	name = glob.glob('*.xpi')[0] -	new_name = os.path.join('build', 'redirector-firefox.xpi') -	#Manually update the install.rdf to get the preferences button working... - -	#jpm created the install.rdf during build, but doesn't allow adding a options url -	#so we patch it here -	with zipfile.ZipFile(name, 'r') as zin: -		with zipfile.ZipFile(new_name, 'w') as zout: -			zout.comment = zin.comment  -			for item in zin.infolist(): -				bytes = zin.read(item.filename) -				if item.filename == 'install.rdf': -					bytes = bytes.replace('</em:creator>', '</em:creator>\n          <em:optionsURL>resource://redirector-at-einaregilsson-dot-com/redirector.html</em:optionsURL>\n          <em:optionsType>3</em:optionsType>\n') -				 -				zout.writestr(item, bytes) - -	os.remove(name) -  def create_addon(files, browser):  	output_folder = 'build'  	if not os.path.isdir(output_folder):  		os.mkdir(output_folder) -	output_file = os.path.join(output_folder, 'redirector-%s.zip' % browser) +	if browser == 'firefox': +		ext = 'xpi' +	else: +		ext = 'zip' + +	output_file = os.path.join(output_folder, 'redirector-%s.%s' % (browser,ext))  	zf = zipfile.ZipFile(output_file, 'w', zipfile.ZIP_STORED)  	cert = 'extension-certificate.pem' @@ -67,6 +49,10 @@ def create_addon(files, browser):  			if browser != 'firefox':  				del manifest['applications'] #Firefox specific, and causes warnings in other browsers... + +			if browser == 'firefox': +				del manifest['background']['persistent'] #Firefox chokes on this, is always persistent anyway +  			if browser == 'opera':  				manifest['options_ui']['page'] = 'redirector.html' #Opera opens options in new tab, where the popup would look really ugly  				manifest['options_ui']['chrome_style'] = False @@ -93,8 +79,7 @@ if __name__ == '__main__':  	print '******* REDIRECTOR BUILD SCRIPT *******'  	print '' -	browsers = ['chrome', 'firefox', 'opera']  	create_addon(files, 'chrome')  	create_addon(files, 'opera') -	create_firefox_addon() +	create_addon(files, 'firefox') diff --git a/js/background.js b/js/background.js index e66be8f..5b393db 100644 --- a/js/background.js +++ b/js/background.js @@ -6,25 +6,13 @@ function log(msg) {  		console.log('REDIRECTOR: ' + msg);  	}  } -log.enabled = false; - - -var isFirefox = false; - -if (typeof chrome == 'undefined') { -	console.log('Creating fake chrome...'); -	isFirefox = true; -	var firefoxShim = require('./firefox/background-shim'); -	chrome = firefoxShim.chrome; -	Redirect = firefoxShim.Redirect; -	log = firefoxShim.log; -	exports.onUnload = function (reason) {  -		log('Unloading (' + reason + '), removing listeners'); -		redirectEvent.removeListener(checkRedirects); -		chrome.storage.onChanged.removeListener(monitorChanges);	 -		chrome.storage.clearCache(); //<-Firefox specific -	}; -} +log.enabled = true; + + +var isFirefox = !!navigator.userAgent.match(/Firefox/i); + +log('Is Firefox: ' + isFirefox); +  //Hopefully Firefox will fix this at some point and we can just use onBeforeRequest everywhere...  var redirectEvent = isFirefox ? chrome.webRequest.onBeforeSendHeaders : chrome.webRequest.onBeforeRequest; @@ -121,6 +109,8 @@ function checkRedirects(details) {  			ignoreNextRequest[result.redirectTo] = new Date().getTime();  			return { redirectUrl: result.redirectTo }; +		} else { +			log(details.url + ' is not a match for ' + r.includePattern + ', type ' + r.patternType);  		}  	} @@ -163,10 +153,8 @@ function createFilter(redirects) {  	}  	types.sort(); -	//FIXME: The Firefox implementation of the url matching is seriously broken still, -	//so we can't filter by url on Firefox for now, have to cut non http urls out in checkRedirects.  	return { -		urls: isFirefox ? null : ["https://*/*", "http://*/*"], +		urls: ["https://*/*", "http://*/*"],  		types : types  	};  } @@ -215,6 +203,38 @@ function updateIcon() {  	});	  } + +//Firefox doesn't allow the "content script" which is actually privileged +//to access the objects it gets from chrome.storage directly, so we +//proxy it through here. +chrome.runtime.onMessage.addListener( +	function(request, sender, sendResponse) { +		log('Received background message: ' + JSON.stringify(request)); +		if (request.type == 'getredirects') { +			log('Getting redirects from storage'); +			chrome.storage.local.get({redirects:[]}, function(obj) { +				log('Got redirects from storage: ' + JSON.stringify(obj)); +				sendResponse(obj); +				log('Sent redirects to content page'); +			}); +		} else if (request.type == 'saveredirects') { +			console.log('Saving redirects, count=' + request.redirects.length); +			delete request.type; +			chrome.storage.local.set(request, function(a) { +				log('Finished saving redirects to storage'); +				sendResponse({message:"Redirects saved"}); +			}); +		} else { +			log('Unexpected message: ' + JSON.stringify(request)); +			return false; +		} + +		return true; //This tells the browser to keep sendResponse alive because +		//we're sending the response asynchronously. +	} +); + +  //First time setup  updateIcon(); diff --git a/js/controllers/redirectorpage.js b/js/controllers/redirectorpage.js index 9f0fba6..d18883c 100644 --- a/js/controllers/redirectorpage.js +++ b/js/controllers/redirectorpage.js @@ -18,19 +18,22 @@ redirectorApp.controller('RedirectorPageCtrl', ['$scope', '$timeout', function($  		// Clean them up so angular $$hash things and stuff don't get serialized.  		var arr = $s.redirects.map(normalize); -		storage.set({redirects:arr}, function() { -			console.log('Saved ' + arr.length + ' redirects at ' + new Date()); +		chrome.runtime.sendMessage({type:"saveredirects", redirects:arr}, function(response) { +			console.log('Saved ' + arr.length + ' redirects at ' + new Date() + '. Message from background page:' + response.message);  		});  	}   	$s.redirects = []; - 	storage.get({redirects:[]}, function(results) { - - 		for (var i=0; i < results.redirects.length; i++) { -			$s.redirects.push(normalize(results.redirects[i])); +	 +	//Need to proxy this through the background page, because Firefox gives us dead objects +	//nonsense when accessing chrome.storage directly. +	chrome.runtime.sendMessage({type: "getredirects"}, function(response) { +		console.log('Received redirects message, count=' + response.redirects.length); + 		for (var i=0; i < response.redirects.length; i++) { +			$s.redirects.push(normalize(response.redirects[i]));  		}  		$s.$apply(); - 	}); +	}); 	   	// Shows a message bar above the list of redirects.   	$s.showMessage = function(message, success) { diff --git a/js/firefox/background-shim.js b/js/firefox/background-shim.js deleted file mode 100644 index d937104..0000000 --- a/js/firefox/background-shim.js +++ /dev/null @@ -1,243 +0,0 @@ -var self = require('sdk/self'); -var tabs = require('sdk/tabs'); - -const {Cu} = require('chrome'); - -function log(msg) { -	console.log(msg); -} - -function migrateFromOlderVersion() { -	const { pathFor } = require('sdk/system'); -	const path = require('sdk/fs/path'); -	const file = require('sdk/io/file'); - -	var oldRedirectsFile = path.join(pathFor('ProfD'), 'Redirector.rjson'); -	if (!file.exists(oldRedirectsFile)) { -		return; -	} - -	var extensionId = require('sdk/self').id; -	var newFolder = path.join(pathFor('ProfD'), 'browser-extension-data', extensionId); -	file.mkpath(newFolder); -	var newFile = path.join(newFolder, 'storage.js'); -	 -	if (file.exists(newFile)) { -		return; -	}	 - - -	var textReader = file.open(oldRedirectsFile, 'r'); -	var jsonData = JSON.parse(textReader.read()); -	textReader.close(); -	var Redirect = require('../redirect').Redirect; -	var newData = {redirects:[]}; -	for (var r of jsonData.redirects) { -		var redirect = new Redirect(r); -		redirect.updateExampleResult(); -		newData.redirects.push(redirect.toObject()); -	} - -	Cu.import("resource://gre/modules/Services.jsm"); - -	var enabled = true; -	try { -		enabled = Services.prefs.getBoolPref('extensions.redirector.enabled'); -	} catch(e) {} -	newData.disabled = !enabled; - -	//Kill old prefs: -	var oldPrefs = ['enabled', 'debugEnabled', 'enableShortcutKey', 'version', 'defaultDir']; -	for (var p of oldPrefs) { -		try { -			Services.prefs.deleteBranch('extensions.redirector.' + p); -		} catch(e) { -		} -	} - -	 -	var textWriter = file.open(newFile, 'w'); -	textWriter.write(JSON.stringify(newData)); -	textWriter.close(); - -	file.remove(oldRedirectsFile); -} - -migrateFromOlderVersion(); - -function makeUrl(relativeUrl) { -	return self.data.url(relativeUrl).replace('/data/', '/'); -}  - -Cu.import('resource://gre/modules/ExtensionStorage.jsm'); - -//Create the browser action: -var { ToggleButton } = require("sdk/ui/button/toggle"); -var panels = require("sdk/panel"); - -var button = ToggleButton({ -	id: "redirector", -	label: "Redirector", -	icon: { -		"16": makeUrl("images/icon-active-16.png"), -		"32": makeUrl("images/icon-active-32.png"), -		"48": makeUrl("images/icon-active-48.png"), -		"64": makeUrl("images/icon-active-64.png") -	}, -	onChange: function(state) { -		if (state.checked) { -    		panel.show({position: button}); -    	} -	} -}); - -var extensionId = require('sdk/self').id; - -var chrome = { -	webRequest : Cu.import('resource://gre/modules/WebRequest.jsm', {}), -	 -	storage : { -		local : { -			get : function(query, callback) { -				ExtensionStorage.get(extensionId, query).then(callback || function(){}); -			}, -			set : function(data, callback) { -				ExtensionStorage.set(extensionId, data).then(callback || function(){}); -			} -		}, - -		clearCache : function() { -			ExtensionStorage.cache.clear(); -		}, - -		onChanged : { -			addListener : function(listener) { -				ExtensionStorage.addOnChangedListener(extensionId, listener); -			}, -			removeListener : function(listener) { -				ExtensionStorage.removeOnChangedListener(extensionId, listener); -			} -		}  -	}, - -	runtime : {  -	}, -	 -	browserAction : { -		setIcon : function(data, callback) { -			var icon = {}; -			for (var s of ['16','32','48', '64']) { -				icon[s] = makeUrl(data.path['19'].replace('19', s)); -			} -			button.icon = icon; -		} -	} -}; - -var pageMod = require("sdk/page-mod"); - -var panel = panels.Panel({ -	width: 200, -	height: 110, -	contentURL: makeUrl('popup.html'), -	contentScriptFile : [ -		makeUrl('js/firefox/page-shim.js'), -		makeUrl('js/angular.min.js'), -		makeUrl('js/popup.js') -	], -	onHide: function() { -		button.state('window', {checked: false}); -	} -}); - -function attachedPage(worker) { -	function sendReply(originalMessage, reply) { -		var msg = {messageId:originalMessage.messageId, payload:reply}; -		log('background sending message: ' + JSON.stringify(msg)); -		worker.port.emit('message', msg); -	} - -	//We proxy all logging over here so we can control it with one switch -	worker.port.on('log', log); - -	function receive(message) { -		log('background got message: ' + JSON.stringify(message)); - -		if (message.messageType == 'storage.get') { -			chrome.storage.local.get(message.payload, function(data) { -				sendReply(message, data); -			}); -		} else if (message.messageType == 'storage.set') { -			chrome.storage.local.set(message.payload, function(data) { -				sendReply(message, data); -			}); -		} else if (message.messageType == 'manifest.get') { -			var p = require('package.json'); -			sendReply(message, p); -		} else if (message.messageType == 'log.enabled') { -			if (!message.payload.enabled) { -				log('Logging has been disabled for Redirector'); -			} -			log.enabled = message.payload.enabled; -			if (log.enabled) { -				log('Logging has been enabled for Redirector'); -			} -		} else if (message.messageType == 'tabs.query') { -			var result = []; -			var windows = require("sdk/windows").browserWindows; -			 -			for (let tab of windows.activeWindow.tabs) { -				if (tab.url == message.payload.url) { -					result.push({id:tab.id, url:tab.url}); -				} -			} -			sendReply(message, result); -		} else if (message.messageType == 'tabs.update') { -			for (let tab of tabs) { -				if (tab.id == message.payload.tabId) { -					tab.activate(); -					panel.hide(); -					sendReply(message, tab); -				} -			} -			sendReply(message, null); -		} else if (message.messageType == 'tabs.create') { -			tabs.open(message.payload.url); -			panel.hide(); -			sendReply(message, null); -		}  -	} -    worker.port.on('message', receive); - -    worker.on('detach', function() { -    	worker.port.removeListener('message', receive); -    	worker.port.removeListener('log', log); -    }); -} - -attachedPage(panel); - -pageMod.PageMod({ -	include: makeUrl('redirector.html'), -	contentScriptFile: [ -		makeUrl("js/firefox/page-shim.js"), -		makeUrl("js/angular.min.js"), -		makeUrl("js/redirect.js"), -		makeUrl("js/app.js"), -		makeUrl("js/controllers/redirectorpage.js"), -		makeUrl("js/controllers/editredirect.js"), -		makeUrl("js/controllers/deleteredirect.js"), -		makeUrl("js/controllers/importexport.js"), -		makeUrl("js/controllers/listredirects.js") -	], -	contentScriptWhen: 'start', -	onAttach : attachedPage -}); - - -exports.chrome = chrome; - -//Get redirect.js, which is included in the background page in webextensions. -exports.Redirect = require('../redirect').Redirect; - -exports.log = log; diff --git a/js/firefox/page-shim.js b/js/firefox/page-shim.js deleted file mode 100644 index 4607d7c..0000000 --- a/js/firefox/page-shim.js +++ /dev/null @@ -1,80 +0,0 @@ -(function() { - -	function log(msg) { -		self.port.emit('log', msg); -	} -	var parts = location.pathname.split('/'); -	var urlName = parts[parts.length-1]; - -	var messageId = 1; -	var callbacks = {}; -	function send(type, message, callback) { -		var id = messageId++; -		self.port.emit('message', {url:urlName, messageId:id, messageType:type, payload:message}); -		callbacks[id] = callback || function(){}; -	} - - -	self.port.on('message', function(message) { -		log('page got message: ' + JSON.stringify(message)); -		 -		var callback = callbacks[message.messageId]; -		if (callback) { -			callback(message.payload); -			delete callbacks[message.messageId]; -		} -	}); - -	var manifest = { version:'unknown' }; -	send('manifest.get', {}, function(data) { -		manifest = data; -	}) - -	window.chrome = { -		storage : { -			local : { -				get : function(query, callback) { -					send('storage.get', query, callback); -				}, -				set : function(data, callback) { -					send('storage.set', data, callback); -				} -			} -		}, - -		extension : { -			getURL : function(file) { -				return document.location.protocol + '//' + document.location.host + '/' + file; -			} -		}, - -		tabs : { -			query : function(data, callback) { -				send('tabs.query', data, callback); -			}, - -			create : function(data, callback) { -				send('tabs.create', data, callback); -			}, - -			update : function(tabId, options, callback) { -				if (!options.active) { -					throw 'Unexpected update call'; -				} - -				options.tabId = tabId; - -				send('tabs.update', options, callback); -			} -		}, - -		runtime : {  -			getManifest : function() { -				return manifest; -			} -		} -	}; - -})(); - - diff --git a/js/popup-scriptload.js b/js/popup-scriptload.js deleted file mode 100644 index bcb5370..0000000 --- a/js/popup-scriptload.js +++ /dev/null @@ -1,13 +0,0 @@ - -//Do it this way to make the Firefox version work with content -//scripts and all that crap. Will be removed when everything -//can use the WebExtensions API. - -function loadScript(path) { -	document.write('<script src="' + path + '"></script>'); -} - -if (typeof chrome !== 'undefined') { -	loadScript("js/angular.min.js"); -	loadScript("js/popup.js"); -} diff --git a/js/popup.js b/js/popup.js index 5305f13..1241d20 100644 --- a/js/popup.js +++ b/js/popup.js @@ -21,6 +21,19 @@ angular.module('popupApp', []).controller('PopupCtrl', ['$scope', function($s) {  		//switch to open one if we have it to minimize conflicts  		var url = chrome.extension.getURL('redirector.html'); +		chrome.tabs.query({currentWindow:true}, function(tabs)) { +			for (var i=0; i < tabs.length; i++) { +				if (tabs[i].url == url) { +					chrome.tabs.update(tabs[i].id, {active:true}, function(tab) { +						close(); +					}); +					return; +				} +			} + +			chrome.tabs.create({url:url, active:true}); +		}); +		return;  		chrome.tabs.query({currentWindow:true, url:url}, function(tabs) {  			if (tabs.length > 0) {  				chrome.tabs.update(tabs[0].id, {active:true}, function(tab) { diff --git a/js/redirector-scriptload.js b/js/redirector-scriptload.js deleted file mode 100644 index 844576d..0000000 --- a/js/redirector-scriptload.js +++ /dev/null @@ -1,19 +0,0 @@ - -//Do it this way to make the Firefox version work with content -//scripts and all that crap. Will be removed when everything -//can use the WebExtensions API. - -function loadScript(path) { -	document.write('<script src="' + path + '"></script>'); -} - -if (typeof chrome !== 'undefined') { -	loadScript("js/angular.min.js"); -	loadScript("js/redirect.js"); -	loadScript("js/app.js"); -	loadScript("js/controllers/redirectorpage.js"); -	loadScript("js/controllers/editredirect.js"); -	loadScript("js/controllers/deleteredirect.js"); -	loadScript("js/controllers/importexport.js"); -	loadScript("js/controllers/listredirects.js"); -} diff --git a/package.json b/package.json deleted file mode 100644 index 955112b..0000000 --- a/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ -  "title": "Redirector", -  "name": "redirector", -  "id" : "redirector@einaregilsson.com", -  "version": "3.0.6", -  "homepage" : "http://einaregilsson.com/redirector", -  "icon" : "resource://redirector-at-einaregilsson-dot-com/images/icon-active-48.png", -  "icon64" : "resource://redirector-at-einaregilsson-dot-com/images/icon-active-64.png", -  "description": "Automatically redirect pages based on user-defined rules. E.g. always redirect an article url to its printer-friendly version.", -  "main": "js/background.js", -  "author": "Einar Egilsson", -  "permissions" : { "multiprocess" : true }, -  "engines": { -    "firefox": ">=41.0", -    "fennec": ">=41.0" -  }, -  "license": "MIT" -} @@ -4,7 +4,8 @@  		<title>REDIRECTOR</title>  		<link rel="stylesheet" href="css/popup.css" />  		<meta charset="UTF-8"> -		<script src="js/popup-scriptload.js"></script> +		<script src="js/angular.min.js"></script> +		<script src="js/popup.js"></script>  	</head>  	<body ng-app="popupApp" ng-controller="PopupCtrl">  		<h1>REDIRECTOR</h1> diff --git a/redirector.html b/redirector.html index 8717c1b..0285e00 100644 --- a/redirector.html +++ b/redirector.html @@ -6,7 +6,16 @@  		<link rel="stylesheet" href="css/redirector.css" />  		<!-- ☈ -->  		<link rel="shortcut icon" href="images/icon-active-32.png"> -		<script src="js/redirector-scriptload.js"></script> + + +		<script src="js/angular.min.js"></script> +		<script src="js/redirect.js"></script> +		<script src="js/app.js"></script> +		<script src="js/controllers/redirectorpage.js"></script> +		<script src="js/controllers/editredirect.js"></script> +		<script src="js/controllers/deleteredirect.js"></script> +		<script src="js/controllers/importexport.js"></script> +		<script src="js/controllers/listredirects.js"></script>  	</head>  	<body ng-app="redirectorApp" ng-controller="RedirectorPageCtrl" class="private">  		<div id="cover" ng-show="showEditForm || showDeleteForm">  | 
