initial attmept to add search
This commit is contained in:
		
							parent
							
								
									4c2f0cdfdf
								
							
						
					
					
						commit
						1e9c50dc9e
					
				
					 1 changed files with 378 additions and 296 deletions
				
			
		|  | @ -12,160 +12,242 @@ import logging from "/gui/scripts/logging.JS"; | ||||||
| @return {object} the data | @return {object} the data | ||||||
| */ | */ | ||||||
| export async function read(DATA_NAME, CLOUD = 0, PARAMETER_TEST = null) { | export async function read(DATA_NAME, CLOUD = 0, PARAMETER_TEST = null) { | ||||||
| 	// Initialize the selected pref data.
 |   // Initialize the selected pref data.
 | ||||||
| 	let DATA = {}, |   let DATA = {}, | ||||||
| 		DATA_ALL = {}, |     DATA_ALL = {}, | ||||||
| 		DATA_RETURNED = {}; |     DATA_RETURNED = {}; | ||||||
| 
 | 
 | ||||||
| 	// Convert the entered prefname to an array if it is not one.
 |   // Convert the entered prefname to an array if it is not one.
 | ||||||
| 	if (!(typeof DATA_NAME).includes(`object`)) { |   if (!(typeof DATA_NAME).includes(`object`)) { | ||||||
| 		// Avoid null
 |     // Avoid null
 | ||||||
| 		if ((typeof DATA_NAME).includes(`str`) ? DATA_NAME.trim() : DATA_NAME) { |     if ((typeof DATA_NAME).includes(`str`) ? DATA_NAME.trim() : DATA_NAME) { | ||||||
| 			// Syntax of splitting is by commas.
 |       // Syntax of splitting is by commas.
 | ||||||
| 			DATA_NAME = String(DATA_NAME).trim().split(","); |       DATA_NAME = String(DATA_NAME).trim().split(","); | ||||||
| 		} |     } | ||||||
| 	} |   } | ||||||
| 
 | 
 | ||||||
| 	/* |   /* | ||||||
| 			Get all dataset. |       Get all dataset. | ||||||
| 
 | 
 | ||||||
| 			@param {number} SOURCE the data source |       @param {number} SOURCE the data source | ||||||
| 	*/ |   */ | ||||||
| 	async function read_database(SOURCE = -1) { |   async function read_database(SOURCE = -1) { | ||||||
| 		let data = {}; |     let data = {}; | ||||||
| 		let data_returned; |     let data_returned; | ||||||
| 
 | 
 | ||||||
| 		async function read_database_local() { |     async function read_database_local() { | ||||||
| 			return new Promise((resolve, reject) => { |       return new Promise((resolve, reject) => { | ||||||
| 				chrome.storage.local.get(null, function (result) { |         chrome.storage.local.get(null, function (result) { | ||||||
| 					if (chrome.runtime.lastError) { |           if (chrome.runtime.lastError) { | ||||||
| 						// Something went wrong
 |             // Something went wrong
 | ||||||
| 						reject(new Error(chrome.runtime.lastError)); |             reject(new Error(chrome.runtime.lastError)); | ||||||
| 					} else { |           } else { | ||||||
| 						// If the key exists, return the value
 |             // If the key exists, return the value
 | ||||||
| 						resolve(result); |             resolve(result); | ||||||
| 					} |           } | ||||||
| 				}); |         }); | ||||||
| 			}); |       }); | ||||||
| 		} |     } | ||||||
| 
 | 
 | ||||||
| 		async function read_database_sync() { |     async function read_database_sync() { | ||||||
| 			return new Promise((resolve, reject) => { |       return new Promise((resolve, reject) => { | ||||||
| 				chrome.storage.sync.get(null, function (result) { |         chrome.storage.sync.get(null, function (result) { | ||||||
| 					if (chrome.runtime.lastError) { |           if (chrome.runtime.lastError) { | ||||||
| 						// Something went wrong
 |             // Something went wrong
 | ||||||
| 						reject(new Error(chrome.runtime.lastError)); |             reject(new Error(chrome.runtime.lastError)); | ||||||
| 					} else { |           } else { | ||||||
| 						// If the key exists, return the value
 |             // If the key exists, return the value
 | ||||||
| 						resolve(result); |             resolve(result); | ||||||
| 					} |           } | ||||||
| 				}); |         }); | ||||||
| 			}); |       }); | ||||||
| 		} |     } | ||||||
| 
 | 
 | ||||||
| 		// Return the data.
 |     // Return the data.
 | ||||||
| 		if (SOURCE > 0) { |     if (SOURCE > 0) { | ||||||
| 			data_returned = read_database_sync(); |       data_returned = read_database_sync(); | ||||||
| 		} else { |     } else { | ||||||
| 			data_returned = read_database_local(); |       data_returned = read_database_local(); | ||||||
| 		} |     } | ||||||
| 
 | 
 | ||||||
| 		return data_returned; |     return data_returned; | ||||||
| 	} |   } | ||||||
| 
 | 
 | ||||||
| 	/* Recursively find through each data, returning either that value or null when the object is not found. |   /* Recursively find through each data, returning either that value or null when the object is not found. | ||||||
| 
 | 
 | ||||||
| 	@param {dictionary} DATA_ALL the data |   @param {dictionary} DATA_ALL the data | ||||||
| 	@param {object} DATA_PATH the path of the data |   @param {object} DATA_PATH the path of the data | ||||||
| 	@param {object} PARAMETER_TEST what among the value to test |   @param {object} PARAMETER_TEST what among the value to test | ||||||
| 	@return {object} the data |   @return {object} the data | ||||||
| 	*/ |   */ | ||||||
| 	function find_data(DATA_ALL, DATA_PATH, PARAMETER_TEST) { |   function find_data(DATA_ALL, DATA_PATH, PARAMETER_TEST) { | ||||||
| 		let DATA_SELECTED = DATA_ALL; |     let DATA_SELECTED = DATA_ALL; | ||||||
| 
 | 
 | ||||||
| 		// Pull the data out.
 |     // Pull the data out.
 | ||||||
| 		if (DATA_ALL && DATA_PATH && (DATA_PATH != null) ? DATA_PATH.length > 0 : false) { |     if ( | ||||||
| 			let DATA_PATH_SELECTED = String(DATA_PATH.shift()).trim(); |       DATA_ALL && DATA_PATH && DATA_PATH != null ? DATA_PATH.length > 0 : false | ||||||
| 			 |     ) { | ||||||
| 			// Get the selected data.
 |       let DATA_PATH_SELECTED = String(DATA_PATH.shift()).trim(); | ||||||
| 			DATA_SELECTED = DATA_ALL[DATA_PATH_SELECTED]; |  | ||||||
| 
 | 
 | ||||||
| 			// must run if there is actually a parameter to test
 |       // Get the selected data.
 | ||||||
| 			if (DATA_PATH.length > 0 || (((PARAMETER_TEST != null) ? PARAMETER_TEST.length > 0 : false) ? PARAMETER_TEST[`field`] : false)) { |       DATA_SELECTED = DATA_ALL[DATA_PATH_SELECTED]; | ||||||
| 				// Recursively run to make use of the existing data.
 |  | ||||||
| 				DATA_SELECTED = find_data(DATA_SELECTED, DATA_PATH, PARAMETER_TEST); |  | ||||||
| 			} |  | ||||||
| 		} else if ((PARAMETER_TEST) ? (!!PARAMETER_TEST[`field`] && !!PARAMETER_TEST[`test value`]) : false) { |  | ||||||
| 			let QUALIFIED = false; |  | ||||||
| 			let DATA_SELECTED_KEYS = Object.keys(DATA_SELECTED); |  | ||||||
| 
 | 
 | ||||||
| 			// Perform a sequential search.
 |       // must run if there is actually a parameter to test
 | ||||||
| 			for ( |       if ( | ||||||
| 				let DATA_SELECTED_KEY_INDEX = 0; |         DATA_PATH.length > 0 || | ||||||
| 				(DATA_SELECTED_KEY_INDEX < DATA_SELECTED_KEYS.length) && !QUALIFIED; |         ((PARAMETER_TEST != null ? PARAMETER_TEST.length > 0 : false) | ||||||
| 				DATA_SELECTED_KEY_INDEX++ |           ? PARAMETER_TEST[`field`] | ||||||
| 			) { |           : false) | ||||||
| 				PARAMETER_TEST[`value`] = |       ) { | ||||||
| 					DATA_SELECTED[DATA_SELECTED_KEYS[DATA_SELECTED_KEY_INDEX]][ |         // Recursively run to make use of the existing data.
 | ||||||
| 						PARAMETER_TEST[`field`] |         DATA_SELECTED = find_data(DATA_SELECTED, DATA_PATH, PARAMETER_TEST); | ||||||
| 					]; |       } | ||||||
| 				if (PARAMETER_TEST[`value`]) { |     } else if ( | ||||||
| 					QUALIFIED = |       PARAMETER_TEST | ||||||
| 						new RegExp(String(PARAMETER_TEST[`value`])).test( |         ? !!PARAMETER_TEST[`field`] && !!PARAMETER_TEST[`test value`] | ||||||
| 							PARAMETER_TEST[`test value`], |         : false | ||||||
| 						) || |     ) { | ||||||
| 						PARAMETER_TEST[`test value`].includes(PARAMETER_TEST[`value`]); |       let QUALIFIED = false; | ||||||
| 				} |       let DATA_SELECTED_KEYS = Object.keys(DATA_SELECTED); | ||||||
| 	 |  | ||||||
| 				if (QUALIFIED) { |  | ||||||
| 					DATA_SELECTED = |  | ||||||
| 						DATA_SELECTED[DATA_SELECTED_KEYS[DATA_SELECTED_KEY_INDEX]]; |  | ||||||
| 					break; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 	 |  | ||||||
| 			if (!QUALIFIED) { |  | ||||||
| 				DATA_SELECTED = null; |  | ||||||
| 			} |  | ||||||
| 		} else {return (null);} |  | ||||||
| 
 | 
 | ||||||
| 		// Now return the data.
 |       // Perform a sequential search.
 | ||||||
| 		return DATA_SELECTED; |       for ( | ||||||
| 	} |         let DATA_SELECTED_KEY_INDEX = 0; | ||||||
|  |         DATA_SELECTED_KEY_INDEX < DATA_SELECTED_KEYS.length && !QUALIFIED; | ||||||
|  |         DATA_SELECTED_KEY_INDEX++ | ||||||
|  |       ) { | ||||||
|  |         PARAMETER_TEST[`value`] = | ||||||
|  |           DATA_SELECTED[DATA_SELECTED_KEYS[DATA_SELECTED_KEY_INDEX]][ | ||||||
|  |             PARAMETER_TEST[`field`] | ||||||
|  |           ]; | ||||||
|  |         if (PARAMETER_TEST[`value`]) { | ||||||
|  |           QUALIFIED = | ||||||
|  |             new RegExp(String(PARAMETER_TEST[`value`])).test( | ||||||
|  |               PARAMETER_TEST[`test value`], | ||||||
|  |             ) || PARAMETER_TEST[`test value`].includes(PARAMETER_TEST[`value`]); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
| 	// Read data from local and sync storage (asynchronous operations)
 |         if (QUALIFIED) { | ||||||
| 	try { |           DATA_SELECTED = | ||||||
| 		if (CLOUD <= 0) { |             DATA_SELECTED[DATA_SELECTED_KEYS[DATA_SELECTED_KEY_INDEX]]; | ||||||
| 			[DATA_ALL[`local`]] = await Promise.all([read_database(-1)]); |           break; | ||||||
| 		} |         } | ||||||
| 		if (CLOUD >= 0) { |       } | ||||||
| 			[DATA_ALL[`sync`]] = await Promise.all([read_database(1)]); |  | ||||||
| 		} |  | ||||||
| 	} catch ({ name, message }) { |  | ||||||
| 		logging.error(name, message); |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// Let's get through everything and then determine which one has…
 |       if (!QUALIFIED) { | ||||||
| 	Object.keys(DATA_ALL).forEach((DATA_SOURCE) => { |         DATA_SELECTED = null; | ||||||
| 		if (DATA_ALL[DATA_SOURCE]) { |       } | ||||||
| 			DATA[DATA_SOURCE] = DATA_NAME |     } else { | ||||||
| 				? find_data(DATA_ALL[DATA_SOURCE], DATA_NAME, PARAMETER_TEST) |       return null; | ||||||
| 				: DATA_ALL[DATA_SOURCE]; |     } | ||||||
| 		} |  | ||||||
| 	}); |  | ||||||
| 
 | 
 | ||||||
| 	// Now return the data.
 |     // Now return the data.
 | ||||||
| 	DATA_RETURNED[`source`] = |     return DATA_SELECTED; | ||||||
| 		CLOUD != 0 |   } | ||||||
| 			? CLOUD > 0 |  | ||||||
| 				? `sync` |  | ||||||
| 				: `local` |  | ||||||
| 			: (DATA[`sync`] ? DATA[`sync`].length <= 0 : DATA[`sync`]) |  | ||||||
| 				? `sync` |  | ||||||
| 				: `local`; |  | ||||||
| 	DATA_RETURNED[`value`] = DATA[DATA_RETURNED[`source`]]; |  | ||||||
| 
 | 
 | ||||||
| 	return DATA_RETURNED[`value`]; |   // Read data from local and sync storage (asynchronous operations)
 | ||||||
|  |   try { | ||||||
|  |     if (CLOUD <= 0) { | ||||||
|  |       [DATA_ALL[`local`]] = await Promise.all([read_database(-1)]); | ||||||
|  |     } | ||||||
|  |     if (CLOUD >= 0) { | ||||||
|  |       [DATA_ALL[`sync`]] = await Promise.all([read_database(1)]); | ||||||
|  |     } | ||||||
|  |   } catch ({ name, message }) { | ||||||
|  |     logging.error(name, message); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // Let's get through everything and then determine which one has…
 | ||||||
|  |   Object.keys(DATA_ALL).forEach((DATA_SOURCE) => { | ||||||
|  |     if (DATA_ALL[DATA_SOURCE]) { | ||||||
|  |       DATA[DATA_SOURCE] = DATA_NAME | ||||||
|  |         ? find_data(DATA_ALL[DATA_SOURCE], DATA_NAME, PARAMETER_TEST) | ||||||
|  |         : DATA_ALL[DATA_SOURCE]; | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   // Now return the data.
 | ||||||
|  |   DATA_RETURNED[`source`] = | ||||||
|  |     CLOUD != 0 | ||||||
|  |       ? CLOUD > 0 | ||||||
|  |         ? `sync` | ||||||
|  |         : `local` | ||||||
|  |       : (DATA[`sync`] ? DATA[`sync`].length <= 0 : DATA[`sync`]) | ||||||
|  |         ? `sync` | ||||||
|  |         : `local`; | ||||||
|  |   DATA_RETURNED[`value`] = DATA[DATA_RETURNED[`source`]]; | ||||||
|  | 
 | ||||||
|  |   return DATA_RETURNED[`value`]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* More enhanced searching. | ||||||
|  | 
 | ||||||
|  | @param {Array} SOURCE the source of the data | ||||||
|  | @param {string} TERM the term to search | ||||||
|  | @param {Array} ADDITIONAL_PLACES additional places to search | ||||||
|  | @return {Array} the results | ||||||
|  | */ | ||||||
|  | export function search(SOURCE, TERM, VALUE, ADDITIONAL_PLACES, STRICT = false) { | ||||||
|  |   let DATA = read(SOURCE); | ||||||
|  |   let RESULTS; | ||||||
|  | 
 | ||||||
|  |   if (DATA) { | ||||||
|  |     RESULTS = {}; | ||||||
|  | 
 | ||||||
|  |     if (TERM) { | ||||||
|  |       // Sequentially search through the data, first by key.
 | ||||||
|  |       for (let DATA_NAME in Object.keys(DATA)) { | ||||||
|  |         if (STRICT) { | ||||||
|  |           if ( | ||||||
|  |             STRICT | ||||||
|  |               ? DATA_NAME == TERM | ||||||
|  |               : DATA_NAME.includes(TERM) || TERM.includes(DATA_NAME) | ||||||
|  |           ) { | ||||||
|  |             RESULTS[`DATA_NAME`] = DATA[DATA_NAME]; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Then, get the additional places.
 | ||||||
|  |       if ( | ||||||
|  |         (ADDITIONAL_PLACES != null ? Array.isArray(ADDITIONAL_PLACES) : false) | ||||||
|  |           ? ADDITIONAL_PLACES.length > 0 | ||||||
|  |           : false | ||||||
|  |       ) { | ||||||
|  |         for (let FIELD_NAME in ADDITIONAL_PLACES) { | ||||||
|  |           let RESULT = read(SOURCE, 0, { | ||||||
|  |             field: FIELD_NAME, | ||||||
|  |             "test value": TERM, | ||||||
|  |           }); | ||||||
|  |           if (RESULT) { | ||||||
|  |             RESULTS = Object.assign( | ||||||
|  |               {}, | ||||||
|  |               RESULTS, | ||||||
|  |               search(SOURCE, null, RESULT, null, true), | ||||||
|  |             ); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } else if (VALUE) { | ||||||
|  |       for (let ENTRY in (typeof SOURCE).includes(`obj`) && | ||||||
|  |       !Array.isArray(SOURCE) && | ||||||
|  |       SOURCE != null | ||||||
|  |         ? Object.keys(SOURCE) | ||||||
|  |         : SOURCE) { | ||||||
|  |         if ( | ||||||
|  |           (typeof SOURCE).includes(`obj`) && !Array.isArray(SOURCE) | ||||||
|  |             ? SOURCE[ENTRY] == VALUE | ||||||
|  |             : false | ||||||
|  |         ) { | ||||||
|  |           RESULTS[ENTRY] = VALUE; | ||||||
|  |         } else if (SOURCE[ENTRY] == VALUE) { | ||||||
|  |           RESULTS[SOURCE.indexOf(ENTRY)] = VALUE; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return RESULTS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Write the data on the selected prefname. | /* Write the data on the selected prefname. | ||||||
|  | @ -175,74 +257,74 @@ export async function read(DATA_NAME, CLOUD = 0, PARAMETER_TEST = null) { | ||||||
| @param {int} CLOUD store in the cloud; otherwise set to automatic | @param {int} CLOUD store in the cloud; otherwise set to automatic | ||||||
| */ | */ | ||||||
| export function write(PATH, DATA, CLOUD = -1) { | export function write(PATH, DATA, CLOUD = -1) { | ||||||
| 	let DATA_INJECTED = {}; |   let DATA_INJECTED = {}; | ||||||
| 
 | 
 | ||||||
| 	/* Forcibly write the data to chrome database |   /* Forcibly write the data to chrome database | ||||||
| 
 | 
 | ||||||
| 	@param {object} DATA the data |   @param {object} DATA the data | ||||||
| 	@param {number} CLOUD the storage |   @param {number} CLOUD the storage | ||||||
| 	*/ |   */ | ||||||
| 	function write_database(DATA, CLOUD = 0) { |   function write_database(DATA, CLOUD = 0) { | ||||||
| 		// If CLOUD is set to 0, it should automatically determine where the previous source of data was taken from.
 |     // If CLOUD is set to 0, it should automatically determine where the previous source of data was taken from.
 | ||||||
| 
 | 
 | ||||||
| 		if (CLOUD > 0) { |     if (CLOUD > 0) { | ||||||
| 			chrome.storage.sync.set(DATA); |       chrome.storage.sync.set(DATA); | ||||||
| 		} else if (CLOUD < 0) { |     } else if (CLOUD < 0) { | ||||||
| 			chrome.storage.local.set(DATA); |       chrome.storage.local.set(DATA); | ||||||
| 		} |     } | ||||||
| 	} |   } | ||||||
| 
 | 
 | ||||||
| 	/* Appropriately nest and merge the data. |   /* Appropriately nest and merge the data. | ||||||
| 
 | 
 | ||||||
| 	@param {object} EXISTING the original data |   @param {object} EXISTING the original data | ||||||
| 	@param {object} PATH the subpath |   @param {object} PATH the subpath | ||||||
| 	@param {object} VALUE the value |   @param {object} VALUE the value | ||||||
| 	@return {object} the updated data |   @return {object} the updated data | ||||||
| 	*/ |   */ | ||||||
| 	function nest(EXISTING, SUBPATH, VALUE) { |   function nest(EXISTING, SUBPATH, VALUE) { | ||||||
| 		let DATABASE = EXISTING; |     let DATABASE = EXISTING; | ||||||
| 
 | 
 | ||||||
| 		// Get the current path.
 |     // Get the current path.
 | ||||||
| 		let PATH = {}; |     let PATH = {}; | ||||||
| 		PATH[`current`] = String(SUBPATH.shift()).trim(); |     PATH[`current`] = String(SUBPATH.shift()).trim(); | ||||||
| 		PATH[`target`] = SUBPATH; |     PATH[`target`] = SUBPATH; | ||||||
| 
 | 
 | ||||||
| 		if (PATH[`target`].length > 0) { |     if (PATH[`target`].length > 0) { | ||||||
| 			if (DATABASE[PATH[`current`]] == null) { |       if (DATABASE[PATH[`current`]] == null) { | ||||||
| 				DATABASE[PATH[`current`]] = {}; |         DATABASE[PATH[`current`]] = {}; | ||||||
| 			} |       } | ||||||
| 			DATABASE[PATH[`current`]] = nest( |       DATABASE[PATH[`current`]] = nest( | ||||||
| 				DATABASE[PATH[`current`]], |         DATABASE[PATH[`current`]], | ||||||
| 				PATH[`target`], |         PATH[`target`], | ||||||
| 				VALUE, |         VALUE, | ||||||
| 			); |       ); | ||||||
| 		} else { |     } else { | ||||||
| 			DATABASE[PATH[`current`]] = VALUE; |       DATABASE[PATH[`current`]] = VALUE; | ||||||
| 		} |     } | ||||||
| 		// Return the value.
 |     // Return the value.
 | ||||||
| 		return DATABASE; |     return DATABASE; | ||||||
| 	} |   } | ||||||
| 
 | 
 | ||||||
| 	read(null, CLOUD).then((DATA_ALL) => { |   read(null, CLOUD).then((DATA_ALL) => { | ||||||
| 		// handle empty collected data.
 |     // handle empty collected data.
 | ||||||
| 		if (!DATA_ALL) { |     if (!DATA_ALL) { | ||||||
| 			DATA_ALL = {}; |       DATA_ALL = {}; | ||||||
| 		} |     } | ||||||
| 
 | 
 | ||||||
| 		let DATA_NAME = PATH; |     let DATA_NAME = PATH; | ||||||
| 
 | 
 | ||||||
| 		// Convert the entered prefname to an array if it is not one.
 |     // Convert the entered prefname to an array if it is not one.
 | ||||||
| 		if (!(typeof SUBPATH).includes(`object`)) { |     if (!(typeof SUBPATH).includes(`object`)) { | ||||||
| 			// Split what is not an object.
 |       // Split what is not an object.
 | ||||||
| 			DATA_NAME = String(PATH).trim().split(","); |       DATA_NAME = String(PATH).trim().split(","); | ||||||
| 		} |     } | ||||||
| 
 | 
 | ||||||
| 		// Merge!
 |     // Merge!
 | ||||||
| 		DATA_INJECTED = nest(DATA_ALL, DATA_NAME, DATA); |     DATA_INJECTED = nest(DATA_ALL, DATA_NAME, DATA); | ||||||
| 
 | 
 | ||||||
| 		// Write!
 |     // Write!
 | ||||||
| 		write_database(DATA_INJECTED, CLOUD); |     write_database(DATA_INJECTED, CLOUD); | ||||||
| 	}); |   }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Dangerous: Resets all data or a domain's data. | /* Dangerous: Resets all data or a domain's data. | ||||||
|  | @ -253,58 +335,58 @@ export function write(PATH, DATA, CLOUD = -1) { | ||||||
| @return {boolean} the user's confirmation | @return {boolean} the user's confirmation | ||||||
| */ | */ | ||||||
| export function forget(preference, subpreference, CLOUD = 0) { | export function forget(preference, subpreference, CLOUD = 0) { | ||||||
| 	let forget_action = false; |   let forget_action = false; | ||||||
| 
 | 
 | ||||||
| 	(async () => { |   (async () => { | ||||||
| 		// Import alerts module.
 |     // Import alerts module.
 | ||||||
| 		let alerts = (await import(chrome.runtime.getURL(`gui/scripts/alerts.js`)))[ |     let alerts = (await import(chrome.runtime.getURL(`gui/scripts/alerts.js`)))[ | ||||||
| 			`alerts` |       `alerts` | ||||||
| 		]; |     ]; | ||||||
| 
 | 
 | ||||||
| 		// Confirm the action.
 |     // Confirm the action.
 | ||||||
| 		let forget_action = alerts.confirm_action(); |     let forget_action = alerts.confirm_action(); | ||||||
| 
 | 
 | ||||||
| 		if (forget_action) { |     if (forget_action) { | ||||||
| 			if (preference) { |       if (preference) { | ||||||
| 				if (subpreference) { |         if (subpreference) { | ||||||
| 					// Get the data.
 |           // Get the data.
 | ||||||
| 					data = read(preference, CLOUD); |           data = read(preference, CLOUD); | ||||||
| 
 | 
 | ||||||
| 					// Should only run when existent
 |           // Should only run when existent
 | ||||||
| 					if (data[subpreference]) { |           if (data[subpreference]) { | ||||||
| 						delete data[subpreference]; |             delete data[subpreference]; | ||||||
| 						write([preference, subpreference], data, CLOUD); |             write([preference, subpreference], data, CLOUD); | ||||||
| 					} |           } | ||||||
| 				} else { |         } else { | ||||||
| 					// Remove that particular data.
 |           // Remove that particular data.
 | ||||||
| 					if (CLOUD <= 0) { |           if (CLOUD <= 0) { | ||||||
| 						chrome.storage.local.get(null, (data) => { |             chrome.storage.local.get(null, (data) => { | ||||||
| 							delete data[preference]; |               delete data[preference]; | ||||||
| 
 | 
 | ||||||
| 							chrome.storage.local.set(data, (result) => {}); |               chrome.storage.local.set(data, (result) => {}); | ||||||
| 						}); |             }); | ||||||
| 					} |           } | ||||||
| 					if (CLOUD >= 0) { |           if (CLOUD >= 0) { | ||||||
| 						chrome.storage.sync.get(null, (data) => { |             chrome.storage.sync.get(null, (data) => { | ||||||
| 							delete data[preference]; |               delete data[preference]; | ||||||
| 
 | 
 | ||||||
| 							chrome.storage.sync.set(data, (result) => {}); |               chrome.storage.sync.set(data, (result) => {}); | ||||||
| 						}); |             }); | ||||||
| 					} |           } | ||||||
| 				} |         } | ||||||
| 			} else { |       } else { | ||||||
| 				// Clear the data storage.
 |         // Clear the data storage.
 | ||||||
| 				if (CLOUD >= 0) { |         if (CLOUD >= 0) { | ||||||
| 					chrome.storage.sync.clear(); |           chrome.storage.sync.clear(); | ||||||
| 				} |         } | ||||||
| 				if (CLOUD <= 0) { |         if (CLOUD <= 0) { | ||||||
| 					chrome.storage.local.clear(); |           chrome.storage.local.clear(); | ||||||
| 				} |         } | ||||||
| 			} |       } | ||||||
| 		} |     } | ||||||
| 	})(); |   })(); | ||||||
| 
 | 
 | ||||||
| 	return forget_action; |   return forget_action; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Initialize the storage. | /* Initialize the storage. | ||||||
|  | @ -312,71 +394,71 @@ export function forget(preference, subpreference, CLOUD = 0) { | ||||||
| @param {dictionary} data this build's managed data | @param {dictionary} data this build's managed data | ||||||
| */ | */ | ||||||
| export function init(data) { | export function init(data) { | ||||||
| 	let PREFERENCES_ALL = {}; |   let PREFERENCES_ALL = {}; | ||||||
| 	PREFERENCES_ALL[`build`] = data; |   PREFERENCES_ALL[`build`] = data; | ||||||
| 
 | 
 | ||||||
| 	// Read all data.
 |   // Read all data.
 | ||||||
| 	chrome.storage.managed.get(null, function (DATA_MANAGED) { |   chrome.storage.managed.get(null, function (DATA_MANAGED) { | ||||||
| 		PREFERENCES_ALL[`managed`] = DATA_MANAGED; |     PREFERENCES_ALL[`managed`] = DATA_MANAGED; | ||||||
| 	}); |   }); | ||||||
| 
 | 
 | ||||||
| 	chrome.storage.local.get(null, function (DATA_LOCAL) { |   chrome.storage.local.get(null, function (DATA_LOCAL) { | ||||||
| 		PREFERENCES_ALL[`local`] = DATA_LOCAL; |     PREFERENCES_ALL[`local`] = DATA_LOCAL; | ||||||
| 	}); |   }); | ||||||
| 
 | 
 | ||||||
| 	chrome.storage.sync.get(null, function (DATA_SYNC) { |   chrome.storage.sync.get(null, function (DATA_SYNC) { | ||||||
| 		PREFERENCES_ALL[`sync`] = DATA_SYNC; |     PREFERENCES_ALL[`sync`] = DATA_SYNC; | ||||||
| 	}); |   }); | ||||||
| 
 | 
 | ||||||
| 	// Merge data.
 |   // Merge data.
 | ||||||
| 	// Managed > Synchronized > Imported > Local
 |   // Managed > Synchronized > Imported > Local
 | ||||||
| 
 | 
 | ||||||
| 	if (PREFERENCES_ALL[`managed`]) { |   if (PREFERENCES_ALL[`managed`]) { | ||||||
| 		Object.keys(PREFERENCES_ALL[`managed`]).forEach((item) => { |     Object.keys(PREFERENCES_ALL[`managed`]).forEach((item) => { | ||||||
| 			let PREFERENCE = { name: item, existing: false }; |       let PREFERENCE = { name: item, existing: false }; | ||||||
| 
 | 
 | ||||||
| 			if (PREFERENCES_ALL[`sync`]) { |       if (PREFERENCES_ALL[`sync`]) { | ||||||
| 				PREFERENCE[`existing`] = PREFERENCES_ALL[`sync`].hasOwnProperty( |         PREFERENCE[`existing`] = PREFERENCES_ALL[`sync`].hasOwnProperty( | ||||||
| 					PREFERENCE[`name`], |           PREFERENCE[`name`], | ||||||
| 				); |         ); | ||||||
| 			} |       } | ||||||
| 
 | 
 | ||||||
| 			if (!PREFERENCE[`existing`]) { |       if (!PREFERENCE[`existing`]) { | ||||||
| 				// Do not allow synchronized data to interfere with managed data.
 |         // Do not allow synchronized data to interfere with managed data.
 | ||||||
| 				forget(PREFERENCE[`name`]); |         forget(PREFERENCE[`name`]); | ||||||
| 				write( |         write( | ||||||
| 					PREFERENCE[`name`], |           PREFERENCE[`name`], | ||||||
| 					PREFERENCES_ALL[`managed`][PREFERENCE[`name`]], |           PREFERENCES_ALL[`managed`][PREFERENCE[`name`]], | ||||||
| 				); |         ); | ||||||
| 			} |       } | ||||||
| 		}); |     }); | ||||||
| 	} |   } | ||||||
| 
 | 
 | ||||||
| 	// Import build data
 |   // Import build data
 | ||||||
| 	if (PREFERENCES_ALL[`build`]) { |   if (PREFERENCES_ALL[`build`]) { | ||||||
| 		Object.keys(PREFERENCES_ALL[`build`]).forEach((item) => { |     Object.keys(PREFERENCES_ALL[`build`]).forEach((item) => { | ||||||
| 			let PREFERENCE = { name: item, existing: false }; |       let PREFERENCE = { name: item, existing: false }; | ||||||
| 
 | 
 | ||||||
| 			PREFERENCE[`existing`] = |       PREFERENCE[`existing`] = | ||||||
| 				(PREFERENCES_ALL[`sync`] |         (PREFERENCES_ALL[`sync`] | ||||||
| 					? PREFERENCES_ALL[`sync`].hasOwnProperty(PREFERENCE[`name`]) |           ? PREFERENCES_ALL[`sync`].hasOwnProperty(PREFERENCE[`name`]) | ||||||
| 					: false) || |           : false) || | ||||||
| 				(PREFERENCES_ALL[`managed`] |         (PREFERENCES_ALL[`managed`] | ||||||
| 					? PREFERENCES_ALL[`managed`].hasOwnProperty(PREFERENCE[`name`]) |           ? PREFERENCES_ALL[`managed`].hasOwnProperty(PREFERENCE[`name`]) | ||||||
| 					: false) || |           : false) || | ||||||
| 				(PREFERENCES_ALL[`local`] |         (PREFERENCES_ALL[`local`] | ||||||
| 					? PREFERENCES_ALL[`local`].hasOwnProperty(PREFERENCE[`local`]) |           ? PREFERENCES_ALL[`local`].hasOwnProperty(PREFERENCE[`local`]) | ||||||
| 					: false); |           : false); | ||||||
| 
 | 
 | ||||||
| 			if (!PREFERENCE[`existing`]) { |       if (!PREFERENCE[`existing`]) { | ||||||
| 				write( |         write( | ||||||
| 					PREFERENCE[`name`], |           PREFERENCE[`name`], | ||||||
| 					PREFERENCES_ALL[`build`][PREFERENCE[`name`]], |           PREFERENCES_ALL[`build`][PREFERENCE[`name`]], | ||||||
| 					-1, |           -1, | ||||||
| 				); |         ); | ||||||
| 			} |       } | ||||||
| 		}); |     }); | ||||||
| 	} |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|  | @ -385,7 +467,7 @@ Run a script when the browser storage has been changed. | ||||||
| @param {object} reaction the function to run | @param {object} reaction the function to run | ||||||
| */ | */ | ||||||
| export function observe(reaction) { | export function observe(reaction) { | ||||||
| 	chrome.storage.onChanged.addListener((changes, namespace) => { |   chrome.storage.onChanged.addListener((changes, namespace) => { | ||||||
| 		reaction(changes, namespace); |     reaction(changes, namespace); | ||||||
| 	}); |   }); | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue