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; - } - }] - ] - } -}; |