diff options
| author | Einar Egilsson <einar@einaregilsson.com> | 2019-12-12 10:07:21 +0000 | 
|---|---|---|
| committer | Einar Egilsson <einar@einaregilsson.com> | 2019-12-12 10:07:21 +0000 | 
| commit | 72e3f6da46d4e8586e9d1982453dc9f3f7d4b1c2 (patch) | |
| tree | 01ef4547baaf8ab2d79f9d363f3fe12501a046a7 | |
| parent | 0fcc8c5e734d5e3ea769c5ef7be9f2200c3aca06 (diff) | |
Fix inline handlers
| -rw-r--r-- | css/redirector.css | 4 | ||||
| -rw-r--r-- | js/editredirect.js | 37 | ||||
| -rw-r--r-- | js/importexport.js | 9 | ||||
| -rw-r--r-- | js/redirectorpage.js | 43 | ||||
| -rw-r--r-- | redirector.html | 32 | ||||
| -rw-r--r-- | unittest/run.html | 98 | ||||
| -rw-r--r-- | unittest/testcases.js | 129 | 
7 files changed, 79 insertions, 273 deletions
diff --git a/css/redirector.css b/css/redirector.css index c6df8c1..d0046cc 100644 --- a/css/redirector.css +++ b/css/redirector.css @@ -218,8 +218,8 @@ input[type="radio"] {    color:#bbb !important;  } -button[disabled]:hover { - +button span { +  pointer-events:none;  }  /* Edit, Delete, Disable buttons */ diff --git a/js/editredirect.js b/js/editredirect.js index 08070b5..41944a4 100644 --- a/js/editredirect.js +++ b/js/editredirect.js @@ -9,8 +9,7 @@ function createNewRedirect() {  	el('#btn-save-redirect').setAttribute('disabled', 'disabled');  } -function editRedirect(ev) { -	let index = indexFromClickEvent(ev); +function editRedirect(index) {  	el('#edit-redirect-form h3').innerHTML = 'Edit Redirect';  	activeRedirect = new Redirect(REDIRECTS[index]); //Make a new one, which we can dump a bunch of stuff on...  	activeRedirect.existing = true; @@ -41,7 +40,8 @@ function saveRedirect() {  	hideForm('#edit-redirect-form');  } -function toggleAdvancedOptions() { +function toggleAdvancedOptions(ev) { +	ev.preventDefault();  	let advancedOptions = el('.advanced');  	if (advancedOptions.classList.contains('hidden')) {  		advancedOptions.classList.remove('hidden'); @@ -52,9 +52,8 @@ function toggleAdvancedOptions() {  	}  } -//Listen to any change from the edit form... -el('#edit-redirect-form').addEventListener('input', function(ev) { +function editFormChange() {  	//Now read values back from the form...  	for (let input of el('#edit-redirect-form').querySelectorAll('input[type="text"][data-bind]')) {  		let prop = input.getAttribute('data-bind'); @@ -72,12 +71,13 @@ el('#edit-redirect-form').addEventListener('input', function(ev) {  	activeRedirect.updateExampleResult();  	dataBind('#edit-redirect-form', activeRedirect); -}); +} +  var deleteIndex; -function confirmDeleteRedirect(ev) { -	deleteIndex = indexFromClickEvent(ev); +function confirmDeleteRedirect(index) { +	deleteIndex = index;  	let redirect = REDIRECTS[deleteIndex];  	showForm('#delete-redirect-form', redirect);  } @@ -93,4 +93,23 @@ function deleteRedirect() {  function cancelDelete() {  	hideForm('#delete-redirect-form'); -}
\ No newline at end of file +} + + +function setupEditAndDeleteEventListeners() { + +	el('#btn-save-redirect').addEventListener('click', saveRedirect); +	el('#btn-cancel-edit').addEventListener('click', cancelEdit); + +	el('#confirm-delete').addEventListener('click', deleteRedirect); +	el('#cancel-delete').addEventListener('click', cancelDelete); + +	el('#advanced-toggle a').addEventListener('click', toggleAdvancedOptions);	 + +	el('#create-new-redirect').addEventListener('click', createNewRedirect); +	//Listen to any change from the edit form... +	el('#edit-redirect-form').addEventListener('input', editFormChange); +} + + +setupEditAndDeleteEventListeners();
\ No newline at end of file diff --git a/js/importexport.js b/js/importexport.js index c47b71d..c3e79dd 100644 --- a/js/importexport.js +++ b/js/importexport.js @@ -86,4 +86,11 @@ function updateExportLink() {  	el('#export-link').href = 'data:text/plain;charset=utf-8,' + encodeURIComponent(json);   } -updateExportLink();
\ No newline at end of file +updateExportLink(); + +function setupImportExportEventListeners() { +	el("#import-file").addEventListener('change', importRedirects); +	el("#export-link").addEventListener('mousedown', updateExportLink); +} + +setupImportExportEventListeners();
\ No newline at end of file diff --git a/js/redirectorpage.js b/js/redirectorpage.js index fd5be8c..482838f 100644 --- a/js/redirectorpage.js +++ b/js/redirectorpage.js @@ -99,12 +99,7 @@ function updateBindings() {  	}  } -function indexFromClickEvent(ev) { -	return parseInt(ev.target.getAttribute('data-index') || ev.target.parentNode.getAttribute('data-index')); -} - -function duplicateRedirect(ev) { -	let index = indexFromClickEvent(ev); +function duplicateRedirect(index) {  	let redirect = new Redirect(REDIRECTS[index]);  	REDIRECTS.splice(index, 0, redirect); @@ -115,8 +110,7 @@ function duplicateRedirect(ev) {  	saveChanges();  } -function toggleDisabled(ev) { -	let index = indexFromClickEvent(ev); +function toggleDisabled(index) {  	let redirect = REDIRECTS[index];  	redirect.disabled = !redirect.disabled  	updateBindings(); @@ -124,11 +118,7 @@ function toggleDisabled(ev) {  } -function moveUp(ev) { -	if (ev.target.classList.contains('disabled')) { -		return; -	} -	let index = indexFromClickEvent(ev); +function moveUp(index) {  	let prev = REDIRECTS[index-1];  	REDIRECTS[index-1] = REDIRECTS[index];  	REDIRECTS[index] = prev; @@ -136,11 +126,7 @@ function moveUp(ev) {  	saveChanges();  } -function moveDown(ev) { -	if (ev.target.classList.contains('disabled')) { -		return; -	} -	let index = indexFromClickEvent(ev); +function moveDown(index) {  	let next = REDIRECTS[index+1];  	REDIRECTS[index+1] = REDIRECTS[index];  	REDIRECTS[index] = next; @@ -171,6 +157,27 @@ function pageLoad() {  	if(navigator.userAgent.toLowerCase().indexOf("chrome") > -1){  		show('#storage-sync-option');  	} + + +	//Setup event listeners +	el('#hide-message').addEventListener('click', hideMessage); +	el('#storage-sync-option input').addEventListener('click', toggleSyncSetting); + +	el('.redirect-rows').addEventListener('click', function(ev) { +		let action = ev.target.getAttribute('data-action'); + +		//We clone and re-use nodes all the time, so instead of attaching and removing event handlers endlessly we just put +		//a data-action attribute on them with the name of the function that should be called... +		if (!action) { +			return; +		} + +		let handler = window[action]; + +		let index = parseInt(ev.target.getAttribute('data-index')); + +		handler(index); +	});  }  pageLoad();
\ No newline at end of file diff --git a/redirector.html b/redirector.html index 593b16f..89cdbc2 100644 --- a/redirector.html +++ b/redirector.html @@ -35,8 +35,8 @@  				<span data-bind="patternTypeText"></span>  			</div>  			<div class="button-container"> -				<button id="confirm-delete" class="btn red large" onclick="deleteRedirect(event)">Yes, delete it</button> -				<button id="cancel-delete" class="btn grey large" onclick="cancelDelete(event)">No, don't delete it</button> +				<button id="confirm-delete" class="btn red large">Yes, delete it</button> +				<button id="cancel-delete" class="btn grey large">No, don't delete it</button>  			</div>  		</div> @@ -80,7 +80,7 @@  				</div>  			</div>  			<div id="advanced-toggle"> -				<a onclick="toggleAdvancedOptions()">Show advanced options...</a> +				<a href="#show-advanced">Show advanced options...</a>  			</div>  			<div class="form-grid advanced hidden">  				<div> @@ -116,8 +116,8 @@  				</div>  			</div>  			<div class="button-container"> -				<button id="btn-save-redirect" data-disabled="error" data-class="disabled:error" class="btn green large" onclick="saveRedirect()">Save</button> -				<button class="btn red large" onclick="cancelEdit()">Cancel</button> +				<button id="btn-save-redirect" data-disabled="error" data-class="disabled:error" class="btn green large">Save</button> +				<button id="btn-cancel-edit" class="btn red large">Cancel</button>  			</div>  		</div> @@ -128,13 +128,13 @@  			<h5>Go where <em>YOU</em> want!</h5>  			<div id="menu"> -				<a class="btn blue large" onclick="createNewRedirect()">Create new redirect</a> +				<a id="create-new-redirect" class="btn blue large">Create new redirect</a>  				<!-- Importing/Exporting of redirects -->  				<span> -					<input type="file" id="import-file" onchange="importRedirects(event)" accept=".rjson,.json,.txt"  /> +					<input type="file" id="import-file" accept=".rjson,.json,.txt"  />  					<label for="import-file" class="btn blue large">Import</label> -					<a class="btn blue large" id="export-link" onmousedown="updateExportLink()" download="Redirector.json">Export</a> +					<a class="btn blue large" id="export-link" download="Redirector.json">Export</a>  				</span>  				<a class="btn blue large" href="help.html" target="_blank">Help</a> @@ -143,7 +143,7 @@  			<div id="message-box">  				<span data-bind="message" id="message"></span> -				<a id="hide-message" onclick="hideMessage()">✖</a> +				<a id="hide-message">✖</a>  			</div>  			<!-- List of existing redirects --> @@ -173,16 +173,16 @@  								</div>  							</div>  							<div> -								<button class="btn medium blue" onclick="toggleDisabled(event)"><span data-show="disabled">Enable</span><span data-show="!disabled">Disable</span></button> -								<button class="btn medium green" onclick="editRedirect(event)">Edit</button> -								<button class="btn medium red" onclick="confirmDeleteRedirect(event)">Delete</button> -								<button class="btn medium grey move-up-btn" onclick="moveUp(event)" data-disabled="$first">▲</button> -								<button class="btn medium grey move-down-btn" onclick="moveDown(event)" data-disabled="$last">▼</button> -								<button class="btn medium grey" onclick="duplicateRedirect(event)">Duplicate</button> +								<button class="btn medium blue" data-action="toggleDisabled"><span data-show="disabled">Enable</span><span data-show="!disabled">Disable</span></button> +								<button class="btn medium green" data-action="editRedirect">Edit</button> +								<button class="btn medium red" data-action="confirmDeleteRedirect">Delete</button> +								<button class="btn medium grey move-up-btn" data-action="moveUp" data-disabled="$first">▲</button> +								<button class="btn medium grey move-down-btn" data-action="moveDown" data-disabled="$last">▼</button> +								<button class="btn medium grey" data-action="duplicateRedirect">Duplicate</button>  							</div>  						</div>  					</div> -				<label id="storage-sync-option"><input type="checkbox" onclick="toggleSyncSetting()" /> Enable Storage Sync</label> +				<label id="storage-sync-option"><input type="checkbox" /> Enable Storage Sync</label>  			</div>  			<footer> diff --git a/unittest/run.html b/unittest/run.html deleted file mode 100644 index 1c056d5..0000000 --- a/unittest/run.html +++ /dev/null @@ -1,98 +0,0 @@ -<!-- $Id$ --> -<html> -	<head> -		<title>Redirector Unit Tests</title> -		<style type="text/css"> -			body { font-family: Verdana, Arial; color:black; background-color:white; font-size:0.8em; width:800px; margin:auto; text-align:center;} -			a { color:blue; } -			h1 { text-align:center; margin:10px 0px; } -			table { margin:10px auto; border:solid 1px black; width:700px; border-collapse:collapse;} -			td { border:solid 1px black; padding:3px; } -			td.result { width:20px; height:20px; padding:0;} -			td.result div { width:70%; height:70%; margin:auto;  } -			button { margin:20px auto; } -		</style> -		<script type="text/javascript"> - -		//Global variables -		Components.utils.import("chrome://redirector/content/js/redirect.js"); -		Components.utils.import("chrome://redirector/content/js/redirector.js"); -		var redirector = Redirector; -		 -		function setupTest(name, testcase) { -			var table = document.createElement('table'); -			var row = document.createElement('tr'); -			var cell = document.createElement('th'); -			var testdata; -			cell.setAttribute('colspan', 2); -			row.appendChild(cell); -			table.appendChild(row); -			cell.innerHTML = name; -			document.getElementById('tests').appendChild(table); -			for (var i = 0; i < testcase.tests.length; i++) { -				var testdata = testcase.tests[i]; -				row = document.createElement('tr'); -				cell = document.createElement('td'); -				cell.setAttribute('class', 'result'); -				var dot = document.createElement('div'); -				dot.setAttribute('id', name + '_' + i); -				cell.appendChild(dot); -				 -				row.appendChild(cell); -				cell = document.createElement('td'); -				cell.innerHTML = testcase.describe(testdata); -				row.appendChild(cell); -				table.appendChild(row); -			} -		} -		 -		function setup() { -			//quick and dirty cleanup -			document.getElementById('tests').innerHTML = ''; -			 -			var sorted = []; -			for (var name in tests) { -				sorted.push(name); -			}	 -			 -			sorted.sort();			 -			for each(var name in sorted) { -				setupTest(name, tests[name]); -			} -		} -		 -		function runTests() { -			for (var testcaseName in tests) { -				var testcase = tests[testcaseName]; -				for (var i = 0; i < testcase.tests.length; i++) { -					try { -						var dot = document.getElementById(testcaseName + '_' + i); -						var result = testcase.run(testcase.tests[i]); -						if (result && result.passed) { -							dot.style.backgroundColor = '#17f816'; -						} else { -							dot.style.backgroundColor = '#ff0000'; -							if (result && result.message) { -								dot.parentNode.nextSibling.innerHTML += '<br/><span style="color:red;">' + result.message + '</span>'; -							} -						} -					} catch(e) { -						dot.style.backgroundColor = '#ff0000'; -						dot.parentNode.nextSibling.innerHTML += '<br/><span style="color:red;">' + e + '</span>'; -						; -					} -				} -			}	 -		} -		 -		</script> -		<script type="text/javascript" src="testcases.js"></script> -	</head> -	<body onload="setup();"> -		<h1>Redirector Unit Tests</h1> -		<button onclick="runTests();">Run tests</button> -		<button onclick="setup();">Reload tests</button> -		<div id="tests"> -		</div> -	</body> -</html>
\ No newline at end of file diff --git a/unittest/testcases.js b/unittest/testcases.js deleted file mode 100644 index 0c0c10c..0000000 --- a/unittest/testcases.js +++ /dev/null @@ -1,129 +0,0 @@ -//// $Id$ -var nsIContentPolicy = Components.interfaces.nsIContentPolicy; - -var tests = { -	"Wildcard matches" : { -		run : function(data,log) {  -			var pattern = data[0], -				url = data[1], -				expected = data[2]; -			var parts = expected.split(','); -			var redirectUrl = ''; -			if (!(parts.length == 1 && parts[0] == '')) { -				for (var i in parts) { -					redirectUrl += '$' + (parseFloat(i)+1) + ','; -				} -				redirectUrl = redirectUrl.substr(0, redirectUrl.length-1); -			} -			var redirect = new Redirect(null, pattern, redirectUrl, Redirect.WILDCARD); -			var result = redirect.getMatch(url); -			return { passed: result.isMatch && (result.redirectTo == expected), message : "Expected '" + expected + "', actual was '" + result.redirectTo + "'"}; -		}, -		 -		describe : function(data) { return data[0] + ' == ' + data[1] + ', matches=' + data[2]; }, -		tests : [ -			['http://foo*', 'http://foobar.is', 'bar.is'], -			['http://foo*', 'http://foo', ''], -			['*://foo.is', 'http://foo.is', 'http'], -			['*http://foo.is', 'http://foo.is', ''], -			['http*foo*', 'http://foobar.is', '://,bar.is'], -			['http*foo*', 'http://foo', '://,'], -			['*://f*.is', 'http://foo.is', 'http,oo'], -			['*http://f*.is', 'http://foo.is', ',oo'], -			['*foo*', 'http://foo', 'http://,'], -			['*foo*', 'foobar.is', ',bar.is'], -			['*foo*', 'http://foobar.is', 'http://,bar.is'], -			['http://foo.is', 'http://foo.is', ''], -			['*', 'http://foo.is', 'http://foo.is'], -			['*://*oo*bar*', 'http://foo.is/bar/baz', 'http,f,.is/,/baz'], -			['*://**oo*bar*', 'http://foo.is/bar/baz', 'http,,f,.is/,/baz'], -		] -	}, -	 -	"Regex matches" : { -		run : function(data) {  -			var pattern = data[0], -				url = data[1], -				expected = data[2]; -			var parts = expected.split(','); -			var redirectUrl = ''; -			if (!(parts.length == 1 && parts[0] == '')) { -				for (var i in parts) { -					redirectUrl += '$' + (parseFloat(i)+1) + ','; -				} -				redirectUrl = redirectUrl.substr(0, redirectUrl.length-1); -			} -			var redirect = new Redirect(null, pattern, redirectUrl, Redirect.REGEX, null, null); -			var result = redirect.getMatch(url); -			return { passed: result.isMatch && result.redirectTo == expected, message : "Expected '" + expected + "', actual was '" + result.redirectTo + "'"}; -		}, -		 -		describe : function(data) { return data[0] + ' == ' + data[1] + ', matches=' + data[2]; }, -		tests : [ -			['http://foo(.*)', 'http://foobar.is', 'bar.is'], -			['http://foo(.*)', 'http://foo', ''], -			['(.*)://foo.is', 'http://foo.is', 'http'], -			['(.*)http://foo\\.is', 'http://foo.is', ''], -			['http(.*)foo(.*)', 'http://foobar.is', '://,bar.is'], -			['http(.*)foo(.*)', 'http://foo', '://,'], -			['(.*)://f(.*)\\.is', 'http://foo.is', 'http,oo'], -			['(.*)http://f(.*)\\.is', 'http://foo.is', ',oo'], -			['(.*)foo(.*)', 'http://foo', 'http://,'], -			['(.*)foo(.*)', 'foobar.is', ',bar.is'], -			['(.*)foo(.*)', 'http://foobar.is', 'http://,bar.is'], -			['http://foo\.is', 'http://foo.is', ''], -			['(.*)', 'http://foo.is', 'http://foo.is'], -			['(.*)://(.*)oo(.*)bar(.*)', 'http://foo.is/bar/baz', 'http,f,.is/,/baz'], -			['(.*)://(.*?)(.*)oo(.*)bar(.*)', 'http://foo.is/bar/baz', 'http,,f,.is/,/baz'], -		] -	}, -	 -	"nsIContentPolicy implementation" : { -		run : function(data) { -			var runTest = function() { -				var args = { -					contentType : nsIContentPolicy.TYPE_DOCUMENT,  -					contentLocation : "http://foo.is",  -					requestOrigin : null,  -					aContext : { loadURI : function(){}},  -					mimeTypeGuess : null,  -					extra : null -				}; -				for (var key in data[1]) { -					args[key] = data[1][key]; -				} -				 -				var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);   -				args.contentLocation = ioService.newURI(args.contentLocation, null, null); -				var contentPolicy = redirector.QueryInterface(nsIContentPolicy); -				var result = contentPolicy.shouldLoad(args.contentType, args.contentLocation, args.requestOrigin, args.aContext, args.mimeTypeGuess, args.extra); -				return { passed: result == nsIContentPolicy.ACCEPT, message : "Expected nsIContentPolicy.ACCEPT, actual was " + result }; -			} -			 -			if (typeof data[2] == "function") { -				return data[2](runTest); -			} else { -				return runTest(); -			} -		}, -		 -		describe : function(data) { return data[0]; }, -		tests : [ -			["Accepts if not TYPE_DOCUMENT", { contentType : nsIContentPolicy.TYPE_STYLESHEET}], -			["Accepts if not http or https", { contentLocation : "resource://foo/bar"}], -			["Accepts if no aContext", { aContext : null}], -			["Accepts if aContext has no loadURI function", { aContext : { foo : function(){}}}], -			["Accepts if Redirector is not enabled", {}, function(doFunc) { -				try { -					redirector.enabled = false; -					return doFunc(); -					redirector.enabled = true; - -				} catch(e) { -					redirector.enabled = true; -					throw e;	 -				} -			}] -		]		 -	} -};  | 
