aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEinar Egilsson <einar@einaregilsson.com>2019-12-12 10:07:21 +0000
committerEinar Egilsson <einar@einaregilsson.com>2019-12-12 10:07:21 +0000
commit72e3f6da46d4e8586e9d1982453dc9f3f7d4b1c2 (patch)
tree01ef4547baaf8ab2d79f9d363f3fe12501a046a7
parent0fcc8c5e734d5e3ea769c5ef7be9f2200c3aca06 (diff)
Fix inline handlers
-rw-r--r--css/redirector.css4
-rw-r--r--js/editredirect.js37
-rw-r--r--js/importexport.js9
-rw-r--r--js/redirectorpage.js43
-rw-r--r--redirector.html32
-rw-r--r--unittest/run.html98
-rw-r--r--unittest/testcases.js129
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()">&#x2716;</a>
+ <a id="hide-message">&#x2716;</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;
- }
- }]
- ]
- }
-};