diff options
Diffstat (limited to 'js')
| -rw-r--r-- | js/organizemode.js | 42 | ||||
| -rw-r--r-- | js/redirect.js | 48 | ||||
| -rw-r--r-- | js/redirectorpage.js | 194 | ||||
| -rw-r--r-- | js/util.js | 8 | 
4 files changed, 253 insertions, 39 deletions
diff --git a/js/organizemode.js b/js/organizemode.js new file mode 100644 index 0000000..800a53f --- /dev/null +++ b/js/organizemode.js @@ -0,0 +1,42 @@ + +function displayOrganizeModeMessage() { +    if(el('#message-box').classList.contains('visible')) { +        hideMessage(); +    } else { +        showMessage("Use ⟱ to move a redirect to the bottom, ⟰ to move to the top, and use the checkboxes to select multiple redirects and move them together.", true) +    } +} + +function organizeModeToggle(ev) { +    ev.preventDefault(); +    let organizeModes = ['.groupings', '.arrows'] +    for (let mode of organizeModes) { +        let organizeModeElms = document.querySelectorAll(mode); +        for (i = 0; i < organizeModeElms.length; ++i) { +            let elm = organizeModeElms[i]; +            let isHidden = ''; +            if(mode === '.arrows') { +                // targeting parent span for arrows +                elm = elm.parentElement; +            } +            isHidden = elm.classList.contains('hidden'); +            isHidden ? elm.classList.remove('hidden') : elm.classList.add('hidden'); +        } +    } + +    // let buttonText = el('#organize-mode').textContent; +    // buttonText.includes('Show') ? el('#organize-mode').textContent = 'Hide Organize' : el('#organize-mode').textContent = 'Show Organize'; + +    let buttonClasses = el('#organize-mode').classList; +    console.log('NSC: organizeModeToggle -> buttonClasses', buttonClasses); +    !buttonClasses.contains('active') ? el('#organize-mode').classList.add('active') : el('#organize-mode').classList.remove('active'); + +    displayOrganizeModeMessage(); +} + + +function setupOrganizeModeToggleEventListener() { +    el('#organize-mode').addEventListener('click', organizeModeToggle); +} + +setupOrganizeModeToggleEventListener();
\ No newline at end of file diff --git a/js/redirect.js b/js/redirect.js index 4ad57d5..b902da2 100644 --- a/js/redirect.js +++ b/js/redirect.js @@ -27,7 +27,7 @@ Redirect.requestTypes = {  Redirect.prototype = { -	 +  	//attributes  	description : '',  	exampleUrl : '', @@ -40,7 +40,8 @@ Redirect.prototype = {  	patternType : '',  	processMatches : 'noProcessing',  	disabled : false, -	 +	grouped: false, +  	compile : function() {  		var incPattern = this._preparePattern(this.includePattern); @@ -65,7 +66,7 @@ Redirect.prototype = {  			&& this.processMatches == redirect.processMatches  			&& this.appliesTo.toString() == redirect.appliesTo.toString();  	}, -	 +  	toObject : function() {  		return {  			description : this.description, @@ -79,6 +80,7 @@ Redirect.prototype = {  			patternType : this.patternType,  			processMatches : this.processMatches,  			disabled : this.disabled, +			grouped: this.grouped,  			appliesTo : this.appliesTo.slice(0)  		};  	}, @@ -87,10 +89,10 @@ Redirect.prototype = {  		if (!this._rxInclude) {  			this.compile();  		} -		var result = {  -			isMatch : false,  -			isExcludeMatch : false,  -			isDisabledMatch : false,  +		var result = { +			isMatch : false, +			isExcludeMatch : false, +			isDisabledMatch : false,  			redirectTo : '',  			toString : function() { return JSON.stringify(this); }  		}; @@ -106,11 +108,11 @@ Redirect.prototype = {  				result.redirectTo = redirectTo;  			}  		} -		return result;	  +		return result;  	}, -	 +  	//Updates the .exampleResult field or the .error -	//field depending on if the example url and patterns match  +	//field depending on if the example url and patterns match  	//and make a good redirect  	updateExampleResult : function() { @@ -171,25 +173,25 @@ Redirect.prototype = {  	isRegex: function() {  		return this.patternType == Redirect.REGEX;  	}, -	 +  	isWildcard : function() { -		return this.patternType == Redirect.WILDCARD;	 +		return this.patternType == Redirect.WILDCARD;  	},  	test : function() { -		return this.getMatch(this.exampleUrl);	 +		return this.getMatch(this.exampleUrl);  	}, -	//Private functions below	 +	//Private functions below  	_rxInclude : null,  	_rxExclude : null, -	 +  	_preparePattern : function(pattern) {  		if (!pattern) {  			return null;  		}  		if (this.patternType == Redirect.REGEX) { -			return pattern;  +			return pattern;  		} else { //Convert wildcard to regex pattern  			var converted = '^';  			for (var i = 0; i < pattern.length; i++) { @@ -206,7 +208,7 @@ Redirect.prototype = {  			return converted;  		}  	}, -	 +  	_init : function(o) {  		o = o || {};  		this.description = o.description || ''; @@ -240,7 +242,7 @@ Redirect.prototype = {  	get appliesToText() {  		return this.appliesTo.map(type => Redirect.requestTypes[type]).join(', ');  	}, -	 +  	get processMatchesExampleText() {  		let examples = {  			noProcessing : 'Use matches as they are', @@ -256,11 +258,11 @@ Redirect.prototype = {  	toString : function() {  		return JSON.stringify(this.toObject(), null, 2);  	}, -	 +  	_includeMatch : function(url) {  		if (!this._rxInclude) {  			return null; -		}	 +		}  		var matches = this._rxInclude.exec(url);  		if (!matches) {  			return null; @@ -285,12 +287,12 @@ Redirect.prototype = {  		this._rxInclude.lastIndex = 0;  		return resultUrl;  	}, -	 +  	_excludeMatch : function(url) {  		if (!this._rxExclude) { -			return false;	 +			return false;  		} -		var shouldExclude = this._rxExclude.test(url);	 +		var shouldExclude = this._rxExclude.test(url);  		this._rxExclude.lastIndex = 0;  		return shouldExclude;  	} diff --git a/js/redirectorpage.js b/js/redirectorpage.js index f82b0b7..959b73c 100644 --- a/js/redirectorpage.js +++ b/js/redirectorpage.js @@ -23,15 +23,15 @@ function saveChanges() {  		}  	});  } -		 +  function toggleSyncSetting() {  	chrome.runtime.sendMessage({type:"toggle-sync", isSyncEnabled: !options.isSyncEnabled}, function(response) {  		if(response.message === "sync-enabled"){  			options.isSyncEnabled = true; -			showMessage('Sync is enabled!',true); +			showMessage('Sync is enabled!', true);  		} else if(response.message === "sync-disabled"){  			options.isSyncEnabled = false; -			showMessage('Sync is disabled - local storage will be used!',true); +			showMessage('Sync is disabled - local storage will be used!', true);  		} else if(response.message.indexOf("Sync Not Possible")>-1){  			options.isSyncEnabled = false;  			chrome.storage.local.set({isSyncEnabled: $s.isSyncEnabled}, function(){ @@ -60,16 +60,16 @@ function renderRedirects() {  }  function renderSingleRedirect(node, redirect, index) { -	 +  	//Add extra props to help with rendering...  	if (index === 0) {  		redirect.$first = true;  	}  	if (index === REDIRECTS.length - 1) {  		redirect.$last = true; -	}  +	}  	redirect.$index = index; -	 +  	dataBind(node, redirect);  	node.setAttribute('data-index', index); @@ -77,6 +77,12 @@ function renderSingleRedirect(node, redirect, index) {  		btn.setAttribute('data-index', index);  	} +	let checkmark = node.querySelectorAll('.checkmark'); + +	if(checkmark.length == 1) { +		checkmark[0].setAttribute('data-index', index); +	} +  	//Remove extra props...  	delete redirect.$first;  	delete redirect.$last; @@ -117,19 +123,170 @@ function toggleDisabled(index) {  	saveChanges();  } +// function handleGroupedMove(index) { +//     console.log(`NSC`, arguments); +// 	let grouping = REDIRECTS.filter(row => row.grouped); +// 	let size = grouping.length; +// 	console.log(grouping) +// } + +// function wrap(node, elm) { +// 	node.parentNode.insertBefore(elm, node); +// 	// node.previousElementSibling.appendChild(node); +// } + +function swap(node1, node2) { +    const afterNode2 = node2.nextElementSibling; +    const parent = node2.parentNode; +    node1.replaceWith(node2); +    parent.insertBefore(node1, afterNode2); +} + +function groupedMoveDown(group) { +	// let grouping = REDIRECTS.map((row, i) => { return { row, index: i}}) +	// 								.filter(result => result.row.grouped) +	// 								.sort((a, b) => b.index - a.index); +		for(let rule of group) { +			// swap positions in dom +			let elm = document.querySelector("[data-index='" + (rule.index).toString() + "']"); +			let prev = document.querySelector("[data-index='" + (rule.index + group.length).toString() + "']"); +			swap(elm,prev); +		} + +		for(let rule of group) { +			// swap positions in array +			rule.row.grouping = false; +			let prevRedir = REDIRECTS[rule.index + group.length]; +			REDIRECTS[rule.index + group.length] = REDIRECTS[rule.index]; +			REDIRECTS[rule.index] = prevRedir; +			// REDIRECTS[rule.index].grouped = false; +		} +} + +function isGroupAdjacent(grouping) { +	let distances = []; +	for(let i = grouping.length - 1; i >= 0; i--) { + +		if(i != 0) { +			distances.push(grouping[i].index - grouping[i - 1].index); + +		} + +	} +	return distances.every(distance => distance === 1); +} + +function groupedMoveUp(group) { + + +	console.log(group); + +	// working config - sort of +	// for(let rule of group) { +	// 	// swap positions in dom +	// 	let elm = document.querySelector("[data-index='" + (rule.index).toString() + "']"); +	// 	let prev = document.querySelector("[data-index='" + (rule.index - group.length).toString() + "']"); +	// 	elm.childNodes[7].childNodes[3].classList.remove("checkMarked"); +    //     console.log(`NSC: groupedMoveUp -> elm`, elm); +	// 	prev.childNodes[7].childNodes[3].classList.remove("checkMarked"); +    //     console.log(`NSC: groupedMoveUp -> prev`, prev); +	// 	swap(elm,prev); +	// } + +	// for(let rule of group) { +	// 	// swap positions in array +	// 	rule.row.grouping = false; +	// 	let prevRedir = REDIRECTS[rule.index - group.length]; +	// 	REDIRECTS[rule.index - group.length] = REDIRECTS[rule.index]; +	// 	REDIRECTS[rule.index] = prevRedir; +	// 	// REDIRECTS[rule.index].grouped = false; +	// } + +	// only set the below to 1 if groupings are not next to each other. +	var jumpLength = 1; + +	if(isGroupAdjacent(group)) { +		console.log('adjacent') +		jumpLength = group.length; +	} + + + + +	for(let rule of group) { +        console.log(`NSC: groupedMoveUp -> rule`, rule); +		// swap positions in dom +		let elm = document.querySelector("[data-index='" + (rule.index).toString() + "']"); +        console.log(`NSC: groupedMoveUp -> elm`, elm); +		let prev = document.querySelector("[data-index='" + (rule.index - jumpLength).toString() + "']"); +        console.log(`NSC: groupedMoveUp -> prev`, prev); +		elm.childNodes[7].childNodes[3].classList.remove("checkMarked"); +		prev.childNodes[7].childNodes[3].classList.remove("checkMarked"); +		if(jumpLength > 1) { +			swap(elm,prev); +		} + +	} +	for(let rule of group) { +		// swap positions in array +		rule.row.grouping = false; +		let prevRedir = REDIRECTS[rule.index - jumpLength]; +		REDIRECTS[rule.index - jumpLength] = REDIRECTS[rule.index]; +		REDIRECTS[rule.index] = prevRedir; +	} +}  function moveUp(index) { -	let prev = REDIRECTS[index-1]; -	REDIRECTS[index-1] = REDIRECTS[index]; -	REDIRECTS[index] = prev; +	let grouping = REDIRECTS.map((row, i) => { return { row, index: i}}) +									.filter(result => result.row.grouped) +									.sort((a, b) => a.index - b.index); + +	if(grouping.length > 1) { +		// many +		console.log('many') + +		groupedMoveUp(grouping); + +	} else { +		// one +		let prev = REDIRECTS[index-1]; +		REDIRECTS[index-1] = REDIRECTS[index]; +		REDIRECTS[index] = prev; +	} +  	updateBindings();  	saveChanges();  }  function moveDown(index) { -	let next = REDIRECTS[index+1]; -	REDIRECTS[index+1] = REDIRECTS[index]; -	REDIRECTS[index] = next; +	let grouping = REDIRECTS.map((row, i) => { return { row, index: i}}) +									.filter(result => result.row.grouped) +									.sort((a, b) => a.index - b.index); + +	if(grouping.length > 1) { +		// many +		groupedMoveDown(grouping); +	} else { +		// one +		let next = REDIRECTS[index+1]; +		REDIRECTS[index+1] = REDIRECTS[index]; +		REDIRECTS[index] = next; +	} + +	updateBindings(); +	saveChanges(); +} + +function moveUpTop(index) { +	let top = REDIRECTS[0]; +	move(REDIRECTS, index, top); +	updateBindings(); +	saveChanges(); +} + +function moveDownBottom(index) { +	let bottom = REDIRECTS.length - 1; +	move(REDIRECTS, index, bottom);  	updateBindings();  	saveChanges();  } @@ -138,7 +295,7 @@ function moveDown(index) {  function pageLoad() {  	template = el('#redirect-row-template');  	template.parentNode.removeChild(template); -	 +  	//Need to proxy this through the background page, because Firefox gives us dead objects  	//nonsense when accessing chrome.storage directly.  	chrome.runtime.sendMessage({type: "get-redirects"}, function(response) { @@ -169,7 +326,7 @@ function pageLoad() {  			));  		}  		renderRedirects(); -	});  +	});  	chrome.storage.local.get({isSyncEnabled:false}, function(obj){  		options.isSyncEnabled = obj.isSyncEnabled; @@ -186,6 +343,11 @@ function pageLoad() {  	el('#storage-sync-option input').addEventListener('click', toggleSyncSetting);  	el('.redirect-rows').addEventListener('click', function(ev) { +		// apply checkMarked class for Grouping +		if(ev.target.type == 'checkbox') { +			ev.target.nextElementSibling.classList.add("checkMarked"); +		} +  		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 @@ -214,4 +376,8 @@ let mql = window.matchMedia('(prefers-color-scheme:dark)');  mql.onchange = updateFavicon;  updateFavicon(mql); +function toggleGrouping(index) { +	REDIRECTS[index].grouped = !REDIRECTS[index].grouped; +} +  pageLoad();
\ No newline at end of file @@ -36,12 +36,12 @@ function dataBind(el, dataObject) {  		}  	}  	for (let tag of el.querySelectorAll('[data-show]')) { -		let shouldShow = boolValue(tag.getAttribute('data-show'));	 +		let shouldShow = boolValue(tag.getAttribute('data-show'));  		tag.style.display = shouldShow ? '' : 'none';  	}  	for (let tag of el.querySelectorAll('[data-disabled]')) {  		let isDisabled = boolValue(tag.getAttribute('data-disabled')); -		 +  		if (isDisabled) {  			tag.classList.add('disabled');  			tag.setAttribute('disabled', 'disabled'); @@ -82,6 +82,10 @@ function showForm(selector, dataObject) {  	show(selector);  } +function move(arr, from, to) { +    arr.splice(to, 0, arr.splice(from, 1)[0]); +} +  function hideForm(selector) {  	hide('#cover');  	hide(selector);  | 
