aboutsummaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorEinar Egilsson <einar@einaregilsson.com>2015-09-09 14:53:22 +0000
committerEinar Egilsson <einar@einaregilsson.com>2015-09-09 14:53:22 +0000
commit8a77401f48360fe0d5501d4fd6b4cc194279d4f0 (patch)
tree6c6069b54de898c72a2281caa9702039df8a2bfb /js
parenta7506a34544f4df3ba65a854c81fadcca2eb303f (diff)
Plenty of changes
Diffstat (limited to 'js')
-rw-r--r--js/app.js270
-rw-r--r--js/background.js4
-rw-r--r--js/controllers/deleteredirect.js25
-rw-r--r--js/controllers/editredirect.js82
-rw-r--r--js/controllers/importexport.js110
-rw-r--r--js/controllers/listredirects.js44
-rw-r--r--js/controllers/redirectorpage.js50
-rw-r--r--js/popup.js13
-rw-r--r--js/redirect.js119
9 files changed, 424 insertions, 293 deletions
diff --git a/js/app.js b/js/app.js
index 00c23fb..c6cf731 100644
--- a/js/app.js
+++ b/js/app.js
@@ -1,276 +1,14 @@
-var redirectorApp = angular.module('redirectorApp', [])
-.config( [
- '$compileProvider',
- function( $compileProvider )
- {
- $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension|data):/);
- }
-]);
+//Nothing really here except the app object. Filters, and directives are
+//include with the controllers that use them. If we need to add any that
+//are used by multiple controllers then we'll define them here.
+var redirectorApp = angular.module('redirectorApp', []);
-//Directive for file upload:
-redirectorApp.directive('fileselected', function() {
- return {
- restrict: 'A',
- link: function(scope, element, attr, ctrl) {
- element.bind('change', function(e) {
- var f = element[0].files[0];
- element[0].value = '';
- scope.$eval(attr.fileselected, {'$file':f});
- });
- }
- }
-});
-//Filter for displaying nice names for request types
-redirectorApp.filter('requestTypeDisplay', function() {
- return function(input) {
- return input.map(function(key) { return requestTypes[key]; }).join(', ');
- }
-});
-var storage = chrome.storage.local; //TODO: Change to sync when Firefox supports it...
-var requestTypes = {
- main_frame: "Main window (address bar)",
- sub_frame: "IFrames",
- stylesheet : "Stylesheets",
- script : "Scripts",
- image : "Images",
- object : "Objects (e.g. Flash videos, Java applets)",
- xmlhttprequest : "XMLHttpRequests (Ajax)",
- other : "Other"
-};
-redirectorApp.controller('redirectorController', ['$scope', '$timeout', function($s, $timeout) {
- $s.activeRedirect = null;
- $s.editIndex = -1;
- $s.requestTypes = requestTypes;
- $s.appliesTo = function(key) {
- if (!$s.activeRedirect) {
- return;
- }
- return $s.activeRedirect.appliesTo.indexOf(key) != -1;
- };
- $s.toggleApplies = function(key) {
- if (!$s.activeRedirect) {
- return;
- }
- var arr = $s.activeRedirect.appliesTo;
-
- var index = arr.indexOf(key);
- if (index == -1) {
- arr.push(key);
- } else {
- arr.splice(index, 1);
- }
-
- var order = 'main_frame,sub_frame,stylesheet,script,image,object,xmlhttprequest,other';
-
- arr.sort(function(a,b) {
- return order.indexOf(a) - order.indexOf(b);
- });
- };
-
-
- function closeEditForm() {
- $s.editIndex = -1;
- $s.activeRedirect = null;
- $s.showAdvanced = false;
- $s.showModal = false;
- }
-
- $s.createNew = function() {
- $s.activeRedirect = new Redirect({}).toObject();
- $s.showModal = true;
- };
-
- $s.saveRedirect = function() {
- if ($s.editIndex >= 0) {
- $s.redirects[$s.editIndex] = $s.activeRedirect;
- } else {
- $s.redirects.push(new Redirect($s.activeRedirect).toObject());
- }
- closeEditForm();
- saveChanges();
- };
-
- $s.cancelEdit = function() {
- closeEditForm();
- }
-
- function saveChanges() {
-
- var arr = [];
- for (var i=0; i < $s.redirects.length; i++) {
- var r = $s.redirects[i];
- arr.push(new Redirect(r).toObject());
- }
-
- storage.set({redirects:arr}, function() {
- console.log('Saved redirects');
- });
- updateExportLink();
- }
-
- function swap(arr, i, n) {
- var item = arr[i];
- arr[i] = arr[n];
- arr[n] = item;
- }
-
- $s.moveUp = function(index) {
- if (index == 0) {
- return;
- }
- swap($s.redirects, index, index-1);
- saveChanges();
- };
-
- $s.moveDown = function(index) {
- if (index == $s.redirects.length-1) {
- return;
- }
- swap($s.redirects, index, index+1);
- saveChanges();
- };
-
- $s.confirmDelete = function(index) {
- $s.deleting = $s.redirects[index];
- $s.deletingIndex = index;
- $s.showModal = true;
- }
-
- $s.cancelDelete = function(index) {
- delete $s.deleting;
- delete $s.deletingIndex;
- $s.showModal = false;
- }
-
- $s.deleteRedirect = function() {
- $s.redirects.splice($s.deletingIndex, 1);
- delete $s.deleting;
- delete $s.deletingIndex;
- $s.showModal = false;
- saveChanges();
- };
-
- $s.editRedirect = function(index) {
- $s.activeRedirect = new Redirect($s.redirects[index]).toObject();
- $s.editIndex = index;
- $s.showModal = true;
- };
-
- $s.toggleDisabled = function(redirect) {
- redirect.disabled = !redirect.disabled;
- saveChanges();
- }
-
- $s.redirects = [];
- storage.get('redirects', function(results) {
- if (!results || !results.redirects) {
- return;
- }
- for (var i=0; i < results.redirects.length; i++) {
- $s.redirects.push(new Redirect(results.redirects[i]).toObject());
- }
- updateExportLink();
- $s.$apply();
- });
-
- function msg(message, success) {
- $s.message = message;
- $s.messageType = success ? 'success' : 'error';
-
- var m = message;
-
- //Remove the message in 5 seconds if it hasn't been changed...
- $timeout(function() {
- if ($s.message == m) {
- $s.message = null;
- }
- }, 20 * 1000);
- }
-
- /* Import/Export of Redirects */
- $s.importRedirects = function(file) {
- if (!file) {
- return;
- }
- var reader = new FileReader();
-
- reader.onload = function(e) {
- var data;
- try {
- var data = JSON.parse(reader.result);
- } catch(e) {
- msg('Failed to parse JSON data, invalid JSON: ' + (e.message||'').substr(0,100));
- return $s.$apply();
- }
-
- if (!data.redirects) {
- msg('Invalid JSON, missing "redirects" property');
- return $s.$apply();
- }
-
- var imported = 0, existing = 0;
- for (var i = 0; i < data.redirects.length; i++) {
- var r = new Redirect(data.redirects[i]);
-
- if ($s.redirects.some(function(i) { return new Redirect(i).equals(r);})) {
- existing++;
- } else {
- $s.redirects.push(r.toObject());
- imported++;
- }
- }
- if (imported == 0 && existing == 0) {
- msg('No redirects existed in the file.');
- }
- if (imported > 0 && existing == 0) {
- msg('Successfully imported ' + imported + ' redirect' + (imported > 1 ? 's.' : '.'), true);
- }
- if (imported == 0 && existing > 0) {
- msg('All redirects in the file already existed and were ignored.');
- }
- if (imported > 0 && existing > 0) {
- var m = 'Successfully imported ' + imported + ' redirect' + (imported > 1 ? 's' : '') + '. ';
- if (existing == 1) {
- m += '1 redirect already existed and was ignored.';
- } else {
- m += existing + ' redirects already existed and were ignored.';
- }
- msg(m, true);
- }
-
- saveChanges();
- $s.$apply();
- };
- try {
- reader.readAsText(file, 'utf-8');
- } catch(e) {
- msg('Failed to read import file');
- }
- }
-
- function updateExportLink() {
- var redirects = $s.redirects.map(function(r) {
- return new Redirect(r).toObject();
- });
-
- var exportObj = {
- createdBy : 'Redirector v' + chrome.app.getDetails().version,
- createdAt : new Date(),
- redirects : redirects
- };
-
- var json = JSON.stringify(exportObj, null, 4);
-
- $s.redirectDownload = 'data:text/plain;charset=utf-8,' + encodeURIComponent(json);
- }
-
-}]);
diff --git a/js/background.js b/js/background.js
index b9ef47b..b6260d7 100644
--- a/js/background.js
+++ b/js/background.js
@@ -19,7 +19,7 @@ function checkForRedirect(details) {
var filter = {urls:["http://*/*", "https://*/*"]};
//TODO: Better browser detection...
-var isChrome = !!navigator.userAgent.match(/ Chrome\//);
+var isFirefox = !!navigator.userAgent.match(/Firefox\//);
-var ev = isChrome ? chrome.webRequest.onBeforeRequest : chrome.webRequest.onBeforeSendHeaders;
+var ev = isFirefox ? chrome.webRequest.onBeforeSendHeaders : chrome.webRequest.onBeforeRequest;
ev.addListener(checkForRedirect, filter, ["blocking"]);
diff --git a/js/controllers/deleteredirect.js b/js/controllers/deleteredirect.js
new file mode 100644
index 0000000..f480339
--- /dev/null
+++ b/js/controllers/deleteredirect.js
@@ -0,0 +1,25 @@
+redirectorApp.controller('DeleteRedirectCtrl', ['$scope', function($s) {
+
+ // Ok, this is pretty ugly. But I want to make this controller to control
+ // everything about the deleting process, so I make this available on
+ // the parent scope, so the RedirectListCtrl can access it.
+ $s.$parent.confirmDeleteRedirect = function(index) {
+ $s.redirect = $s.redirects[index];
+ $s.deleteIndex = index;
+ $s.$parent.showDeleteForm = true;
+ };
+
+ $s.cancelDelete = function(index) {
+ delete $s.redirect;
+ delete $s.deletingIndex;
+ $s.$parent.showDeleteForm = false;
+ }
+
+ $s.deleteRedirect = function() {
+ $s.redirects.splice($s.deletingIndex, 1);
+ delete $s.redirect;
+ delete $s.deletingIndex;
+ $s.$parent.showDeleteForm = false;
+ $s.saveChanges();
+ };
+}]); \ No newline at end of file
diff --git a/js/controllers/editredirect.js b/js/controllers/editredirect.js
new file mode 100644
index 0000000..f24f3e6
--- /dev/null
+++ b/js/controllers/editredirect.js
@@ -0,0 +1,82 @@
+redirectorApp.controller('EditRedirectCtrl', ['$scope', function($s) {
+
+
+ $s.requestTypes = Redirect.requestTypes;
+
+ // Ok, this is pretty ugly. But I want to make this controller to control
+ // everything about the editing process, so I make this available on
+ // the parent scope, so the RedirectListCtrl can access it.
+ $s.$parent.editRedirect = function(index) {
+ $s.redirect = new Redirect($s.redirects[index]);
+ $s.editIndex = index;
+ $s.redirect.updateExampleResult();
+ if ($s.redirect.escapeMatches || $s.redirect.unescapeMatches || $s.redirect.excludePattern
+ || !($s.redirect.appliesTo.length == 1 && $s.redirect.appliesTo[0] == "main_frame")) {
+ $s.showAdvanced = true; //Auto show advanced if redirect uses advanced options
+ }
+ $s.$parent.showEditForm = true;
+ };
+
+ // Same, this is for the Create New button, which is starting
+ // the edit form, so I want to control it from here.
+ $s.$parent.createNewRedirect = function() {
+ $s.redirect = new Redirect({});
+ $s.$parent.showEditForm = true;
+ };
+
+ $s.saveRedirect = function() {
+ if ($s.redirect.error) {
+ return; //Button is already disabled, but we still get the click
+ }
+
+ if ($s.editIndex >= 0) {
+ $s.redirects[$s.editIndex] = $s.redirect;
+ } else {
+ $s.redirects.push($s.redirect);
+ }
+ closeEditForm();
+ $s.saveChanges();
+ };
+
+ $s.cancelEdit = function() {
+ closeEditForm();
+ }
+
+ // To bind a list of strings to a list of checkboxes
+ $s.appliesTo = function(key) {
+ if (!$s.redirect) {
+ return;
+ }
+ return $s.redirect.appliesTo.indexOf(key) != -1;
+ };
+
+ // Add or remove string from array based on whether checkbox is checked
+ $s.toggleApplies = function(key) {
+ if (!$s.redirect) {
+ return;
+ }
+ var arr = $s.redirect.appliesTo;
+
+ var index = arr.indexOf(key);
+ if (index == -1) {
+ arr.push(key);
+ } else {
+ arr.splice(index, 1);
+ }
+
+ var order = 'main_frame,sub_frame,stylesheet,script,image,object,xmlhttprequest,other';
+
+ arr.sort(function(a,b) {
+ return order.indexOf(a) - order.indexOf(b);
+ });
+
+ $s.redirect.updateExampleResult();
+ };
+
+ function closeEditForm() {
+ $s.editIndex = -1;
+ $s.redirect = null;
+ $s.showAdvanced = false;
+ $s.$parent.showEditForm = false;
+ }
+}]);
diff --git a/js/controllers/importexport.js b/js/controllers/importexport.js
new file mode 100644
index 0000000..191990c
--- /dev/null
+++ b/js/controllers/importexport.js
@@ -0,0 +1,110 @@
+
+//This controller, and associated directives and config, are responsible for import and exporting redirects
+//from .json files.
+
+redirectorApp.config([
+ '$compileProvider',
+ function($compileProvider) {
+ $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension|data):/);
+ }]
+).directive('fileselected', function() { //Directive for file upload:
+ return {
+ restrict: 'A',
+ link: function(scope, element, attr, ctrl) {
+ element.bind('change', function(e) {
+ var f = element[0].files[0];
+ element[0].value = '';
+ scope.$eval(attr.fileselected, {'$file':f});
+ });
+ }
+ }
+}).controller('ImportExportCtrl', ['$scope', function($s) {
+
+ // Shows a message explaining how many redirects were imported.
+ function showImportedMessage(imported, existing) {
+ if (imported == 0 && existing == 0) {
+ $s.showMessage('No redirects existed in the file.');
+ }
+ if (imported > 0 && existing == 0) {
+ $s.showMessage('Successfully imported ' + imported + ' redirect' + (imported > 1 ? 's.' : '.'), true);
+ }
+ if (imported == 0 && existing > 0) {
+ $s.showMessage('All redirects in the file already existed and were ignored.');
+ }
+ if (imported > 0 && existing > 0) {
+ var m = 'Successfully imported ' + imported + ' redirect' + (imported > 1 ? 's' : '') + '. ';
+ if (existing == 1) {
+ m += '1 redirect already existed and was ignored.';
+ } else {
+ m += existing + ' redirects already existed and were ignored.';
+ }
+ $s.showMessage(m, true);
+ }
+ }
+
+ $s.importRedirects = function(file) {
+ if (!file) {
+ return;
+ }
+ var reader = new FileReader();
+
+ reader.onload = function(e) {
+ var data;
+ try {
+ var data = JSON.parse(reader.result);
+ } catch(e) {
+ $s.showMessage('Failed to parse JSON data, invalid JSON: ' + (e.message||'').substr(0,100));
+ return $s.$parent.$apply();
+ }
+
+ if (!data.redirects) {
+ $s.showMessage('Invalid JSON, missing "redirects" property');
+ return $s.$parent.$apply();
+ }
+
+ var imported = 0, existing = 0;
+ for (var i = 0; i < data.redirects.length; i++) {
+ var r = new Redirect(data.redirects[i]);
+
+ if ($s.redirects.some(function(i) { return new Redirect(i).equals(r);})) {
+ existing++;
+ } else {
+ $s.redirects.push(r.toObject());
+ imported++;
+ }
+ }
+
+ showImportedMessage(imported, existing);
+
+ $s.saveChanges();
+ $s.$parent.$apply();
+ };
+ try {
+ reader.readAsText(file, 'utf-8');
+ } catch(e) {
+ $s.showMessage('Failed to read import file');
+ }
+ }
+
+ // Updates the export link with a data url containing all the redirects.
+ // We want to have the href updated instead of just generated on click to
+ // allow people to right click and choose Save As...
+ $s.updateExportLink = function() {
+ var redirects = $s.redirects.map(function(r) {
+ return new Redirect(r).toObject();
+ });
+
+ var exportObj = {
+ createdBy : 'Redirector v' + chrome.app.getDetails().version,
+ createdAt : new Date(),
+ redirects : redirects
+ };
+
+ var json = JSON.stringify(exportObj, null, 4);
+
+ //Using encodeURIComponent here instead of base64 because base64 always messed up our encoding for some reason...
+ $s.redirectDownload = 'data:text/plain;charset=utf-8,' + encodeURIComponent(json);
+ }
+
+ $s.updateExportLink(); //Run once so the a will have a href to begin with
+}]); \ No newline at end of file
diff --git a/js/controllers/listredirects.js b/js/controllers/listredirects.js
new file mode 100644
index 0000000..008a527
--- /dev/null
+++ b/js/controllers/listredirects.js
@@ -0,0 +1,44 @@
+// This controller is responsible for the list of redirects and the actions
+// that can be taken from there.
+redirectorApp.filter('requestTypeDisplay', function() { //Filter for displaying nice names for request types
+ return function(input) {
+ return input.map(function(key) { return Redirect.requestTypes[key]; }).join(', ');
+ }
+}).controller('ListRedirectsCtrl', ['$scope', function($s) {
+
+ function swap(arr, i, n) {
+ var item = arr[i];
+ arr[i] = arr[n];
+ arr[n] = item;
+ }
+
+ // Move the redirect at index up in the list, giving it higher priority
+ $s.moveUp = function(index) {
+ if (index == 0) {
+ return;
+ }
+ swap($s.redirects, index, index-1);
+ $s.saveChanges();
+ };
+
+ // Move the redirect at index down in the list, giving it lower priority
+ $s.moveDown = function(index) {
+ if (index == $s.redirects.length-1) {
+ return;
+ }
+ swap($s.redirects, index, index+1);
+ $s.saveChanges();
+ };
+
+ $s.toggleDisabled = function(redirect) {
+ redirect.disabled = !redirect.disabled;
+ $s.saveChanges();
+ };
+
+ $s.example = function(redirect) {
+ return new Redirect(redirect).getMatch(redirect.exampleUrl).redirectTo;
+ };
+
+ //Edit button is defined in EditRedirectCtrl
+ //Delete button is defined in DeleteRedirectCtrl
+}]); \ No newline at end of file
diff --git a/js/controllers/redirectorpage.js b/js/controllers/redirectorpage.js
new file mode 100644
index 0000000..05fbe9f
--- /dev/null
+++ b/js/controllers/redirectorpage.js
@@ -0,0 +1,50 @@
+// This is the main controller of the page. It is responsible for showing messages,
+// modal windows and loading and saving the list of redirects, that all of the
+// controllers work with.
+redirectorApp.controller('RedirectorPageCtrl', ['$scope', '$timeout', function($s, $timeout) {
+
+ $s.deleting = null; //Variable for redirect being edited, of the form { index:<nr>, redirect:<redirect>};
+ $s.showEditForm = $s.showDeleteForm = false; // Variables, child controllers can set them to show their forms
+
+ var storage = chrome.storage.local; //TODO: Change to sync when Firefox supports it...
+
+ function normalize(r) {
+ return new Redirect(r).toObject(); //Cleans out any extra props, and adds default values for missing ones.
+ }
+
+ // Saves the entire list of redirects to storage.
+ $s.saveChanges = 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 redirects at ' + new Date());
+ });
+ }
+
+ $s.redirects = [];
+ storage.get('redirects', function(results) {
+ if (!results || !results.redirects) {
+ return;
+ }
+
+ for (var i=0; i < results.redirects.length; i++) {
+ $s.redirects.push(normalize(results.redirects[i]));
+ }
+ $s.$apply();
+ });
+
+ // Shows a message bar above the list of redirects.
+ $s.showMessage = function(message, success) {
+ $s.message = message;
+ $s.messageType = success ? 'success' : 'error';
+
+ //Remove the message in 20 seconds if it hasn't been changed...
+ $timeout(function() {
+ if ($s.message == message) {
+ $s.message = null;
+ }
+ }, 20 * 1000);
+ }
+}]);
diff --git a/js/popup.js b/js/popup.js
new file mode 100644
index 0000000..fbff178
--- /dev/null
+++ b/js/popup.js
@@ -0,0 +1,13 @@
+function hi() {
+ chrome.browserAction.setIcon({
+ path: {
+ 19: "images/icon19disabled.png",
+ 38: "images/icon38disabled.png"
+ }
+ });
+ open('redirector.html');
+}
+
+document.addEventListener('DOMContentLoaded', function() {
+ document.getElementsByTagName('button')[0].addEventListener('click', hi);
+}) \ No newline at end of file
diff --git a/js/redirect.js b/js/redirect.js
index 41e3c1d..b895ed9 100644
--- a/js/redirect.js
+++ b/js/redirect.js
@@ -7,11 +7,24 @@ function Redirect(o) {
Redirect.WILDCARD = 'W';
Redirect.REGEX = 'R';
+Redirect.requestTypes = {
+ main_frame: "Main window (address bar)",
+ sub_frame: "IFrames",
+ stylesheet : "Stylesheets",
+ script : "Scripts",
+ image : "Images",
+ object : "Objects (e.g. Flash videos, Java applets)",
+ xmlhttprequest : "XMLHttpRequests (Ajax)",
+ other : "Other"
+};
+
Redirect.prototype = {
//attributes
description : '',
exampleUrl : '',
+ exampleResult : '',
+ error : null,
includePattern : '',
excludePattern : '',
redirectUrl : '',
@@ -21,8 +34,16 @@ Redirect.prototype = {
disabled : false,
compile : function() {
- this._rxInclude = this._compile(this._includePattern);
- this._rxExclude = this._compile(this._excludePattern);
+
+ var incPattern = this._preparePattern(this.includePattern);
+ var excPattern = this._preparePattern(this.excludePattern);
+
+ if (incPattern) {
+ this._rxInclude = new RegExp(incPattern, 'gi');
+ }
+ if (excPattern) {
+ this._rxExclude = new RegExp(excPattern, 'gi');
+ }
},
equals : function(redirect) {
@@ -41,6 +62,8 @@ Redirect.prototype = {
return {
description : this.description,
exampleUrl : this.exampleUrl,
+ exampleResult : this.exampleResult,
+ error : this.error,
includePattern : this.includePattern,
excludePattern : this.excludePattern,
redirectUrl : this.redirectUrl,
@@ -52,7 +75,10 @@ Redirect.prototype = {
};
},
- getMatch: function(url) {
+ getMatch: function(url, forceIgnoreDisabled) {
+ if (!this._rxInclude) {
+ this.compile();
+ }
var result = {
isMatch : false,
isExcludeMatch : false,
@@ -64,7 +90,7 @@ Redirect.prototype = {
redirectTo = this._includeMatch(url);
if (redirectTo !== null) {
- if (this.disabled) {
+ if (this.disabled && !forceIgnoreDisabled) {
result.isDisabledMatch = true;
} else if (this._excludeMatch(url)) {
result.isExcludeMatch = true;
@@ -76,6 +102,66 @@ Redirect.prototype = {
return result;
},
+ //Updates the .exampleResult field or the .error
+ //field depending on if the example url and patterns match
+ //and make a good redirect
+ updateExampleResult : function() {
+
+ //Default values
+ this.error = null;
+ this.exampleResult = '';
+
+
+ if (!this.exampleUrl) {
+ this.error = 'No example URL defined';
+ return;
+ }
+
+ if (this.patternType == Redirect.REGEX && this.includePattern) {
+ try {
+ new RegExp(this.includePattern, 'gi');
+ } catch(e) {
+ this.error = 'Invalid regular expression in Include pattern.';
+ return;
+ }
+ }
+
+ if (this.patternType == Redirect.REGEX && this.excludePattern) {
+ try {
+ new RegExp(this.excludePattern, 'gi');
+ } catch(e) {
+ this.error = 'Invalid regular expression in Exclude pattern.';
+ return;
+ }
+ }
+
+ if (!this.appliesTo || this.appliesTo.length == 0) {
+ this.error = 'At least one request type must be chosen.';
+ return;
+ }
+
+ this.compile();
+
+ var match = this.getMatch(this.exampleUrl, true);
+
+ if (match.isExcludeMatch) {
+ this.error = 'The exclude pattern excludes the example url.'
+ return;
+ }
+
+ if (!match.isMatch) {
+ this.error = 'The include pattern does not match the example url.';
+ return;
+ }
+
+ this.exampleResult = match.redirectTo;
+
+ if (this.getMatch(this.exampleResult, true).isMatch) {
+ this.exampleResult = '';
+ this.error = 'Result matches the redirect again, causing endless loop.'
+ }
+ },
+
isRegex: function() {
return this.patternType == Redirect.REGEX;
},
@@ -89,14 +175,13 @@ Redirect.prototype = {
},
//Private functions below
-
- _includePattern : null,
- _excludePattern : null,
- _patternType : null,
_rxInclude : null,
_rxExclude : null,
_preparePattern : function(pattern) {
+ if (!pattern) {
+ return null;
+ }
if (this.patternType == Redirect.REGEX) {
return pattern;
} else { //Convert wildcard to regex pattern
@@ -115,13 +200,6 @@ Redirect.prototype = {
return converted;
}
},
-
- _compile : function(pattern) {
- if (!pattern) {
- return null;
- }
- return new RegExp(this._preparePattern(pattern),"gi");
- },
_init : function(o) {
this.description = o.description || '',
@@ -141,16 +219,7 @@ Redirect.prototype = {
},
toString : function() {
- return 'REDIRECT: {'
- + '\n\tExample url : ' + this.exampleUrl
- + '\n\tInclude pattern : ' + this.includePattern
- + '\n\tExclude pattern : ' + this.excludePattern
- + '\n\tRedirect url : ' + this.redirectUrl
- + '\n\tPattern type : ' + this.patternType
- + '\n\tUnescape matches : ' + this.unescapeMatches
- + '\n\tEscape matches : ' + this.escapeMatches
- + '\n\tDisabled : ' + this.disabled
- + '\n}\n';
+ return JSON.stringify(this.toObject(), null, 2);
},
_includeMatch : function(url) {