Refactor secretariat.js to specify data source origin
global.forget() is currently broken in this commit.
This commit is contained in:
		
							parent
							
								
									9ade82ccbe
								
							
						
					
					
						commit
						50d02b8c06
					
				
					 1 changed files with 379 additions and 378 deletions
				
			
		|  | @ -6,65 +6,33 @@ import logging from "/scripts/logging.js"; | ||||||
| import texts from "/scripts/mapping/read.js"; | import texts from "/scripts/mapping/read.js"; | ||||||
| import hash from "/scripts/utils/hash.js"; | import hash from "/scripts/utils/hash.js"; | ||||||
| 
 | 
 | ||||||
| /* Read all stored data in the browser cache. | /* | ||||||
| 
 | Global data storage, which refers to local and synchronized storage | ||||||
| @param {array} DATA_NAME the data name |  | ||||||
| @param {int} CLOUD determine cloud reading, which is otherwise set to automatic (0) |  | ||||||
| @param {string} PARAMETER_CHECK Determine which parameter to check via regular expressions. |  | ||||||
| @return {object} the data |  | ||||||
| */ | */ | ||||||
| export async function read(DATA_NAME, CLOUD = 0) { | class global { | ||||||
| 	// Initialize the selected pref data.
 | 	/* Read all stored data in the browser cache. | ||||||
| 	let DATA, DATA_RETURNED; |  | ||||||
| 	 | 	 | ||||||
|  | 	@param {array} name the data name | ||||||
|  | 	@param {int} cloud determines cloud reading, which is otherwise set to automatic (0) | ||||||
|  | 	@return {object} the data | ||||||
|  | 	*/ | ||||||
|  | 	static async read(name, cloud = 0) { | ||||||
| 		/* | 		/* | ||||||
| 		Get all storage values. | 		Get all storage values. | ||||||
| 
 | 
 | ||||||
| 		@param {number} SOURCE the data source | 		@param {number} SOURCE the data source | ||||||
| 		*/ | 		*/ | ||||||
| 	async function read_database(SOURCE = -1) { | 		function pull(SOURCE = -1) { | ||||||
| 		let data, data_returned; | 			return (chrome.storage[(SOURCE > 0) ? `sync` : `local`].get(null)); | ||||||
| 
 |  | ||||||
| 		async function read_database_local() { |  | ||||||
| 			return new Promise((resolve, reject) => { |  | ||||||
| 				chrome.storage.local.get(null, function (result) { |  | ||||||
| 					if (chrome.runtime.lastError) { |  | ||||||
| 						// Something went wrong
 |  | ||||||
| 						reject(new Error(chrome.runtime.lastError)); |  | ||||||
| 					} else { |  | ||||||
| 						// If the key exists, return the value
 |  | ||||||
| 						resolve(result); |  | ||||||
| 					} |  | ||||||
| 				}); |  | ||||||
| 			}); |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		async function read_database_sync() { | 		/* | ||||||
| 			return new Promise((resolve, reject) => { | 		Find a data given its path.  | ||||||
| 				chrome.storage.sync.get(null, function (result) { |  | ||||||
| 					if (chrome.runtime.lastError) { |  | ||||||
| 						// Something went wrong
 |  | ||||||
| 						reject(new Error(chrome.runtime.lastError)); |  | ||||||
| 					} else { |  | ||||||
| 						// If the key exists, return the value
 |  | ||||||
| 						resolve(result); |  | ||||||
| 					} |  | ||||||
| 				}); |  | ||||||
| 			}); |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		// Return the data.
 | 		@param {object} DATA_ALL the data | ||||||
| 		data_returned = (SOURCE > 0) ? read_database_sync() : read_database_local(); |  | ||||||
| 		return data_returned; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* Recursively find through each data, returning either that value or null when the object is not found. |  | ||||||
| 
 |  | ||||||
| 	@param {dictionary} DATA_ALL the data |  | ||||||
| 		@param {object} DATA_PATH the path of the data | 		@param {object} DATA_PATH the path of the data | ||||||
| 	@return {object} the data |  | ||||||
| 		*/ | 		*/ | ||||||
| 	function find_data(DATA_ALL, DATA_PATH) { | 		function find(DATA_ALL, DATA_PATH) { | ||||||
| 			let DATA = DATA_ALL; | 			let DATA = DATA_ALL; | ||||||
| 
 | 
 | ||||||
| 			// Pull the data out.
 | 			// Pull the data out.
 | ||||||
|  | @ -77,7 +45,7 @@ export async function read(DATA_NAME, CLOUD = 0) { | ||||||
| 				// must run if there is actually a parameter to test
 | 				// must run if there is actually a parameter to test
 | ||||||
| 				if (DATA_PATH.length > 0) { | 				if (DATA_PATH.length > 0) { | ||||||
| 					// Recursively run to make use of the existing data.
 | 					// Recursively run to make use of the existing data.
 | ||||||
| 				DATA = find_data(DATA, DATA_PATH); | 					DATA = find(DATA, DATA_PATH); | ||||||
| 				}; | 				}; | ||||||
| 			} else { | 			} else { | ||||||
| 				return null; | 				return null; | ||||||
|  | @ -85,47 +53,56 @@ export async function read(DATA_NAME, CLOUD = 0) { | ||||||
| 
 | 
 | ||||||
| 			// Now return the data.
 | 			// Now return the data.
 | ||||||
| 			return DATA; | 			return DATA; | ||||||
| 	} | 		}; | ||||||
|  | 
 | ||||||
|  | 		// Initialize the selected pref data.
 | ||||||
|  | 		let DATA, 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 (!Array.isArray(DATA_NAME) && DATA_NAME != null) { | 		let NAME = (!Array.isArray(name) && name != null)  | ||||||
| 		// Syntax of splitting is by commas.
 | 			? String(name).trim().split(`,`) | ||||||
| 		DATA_NAME = String(DATA_NAME).trim().split(","); | 			: name; | ||||||
| 	} |  | ||||||
| 		 | 		 | ||||||
| 	switch (CLOUD) { | 		 | ||||||
|  | 		switch (cloud) { | ||||||
| 			case 0: | 			case 0: | ||||||
| 				DATA = {}; DATA_RETURNED = {}; | 				DATA = {}; DATA_RETURNED = {}; | ||||||
| 
 | 
 | ||||||
| 			DATA[`sync`] = await read((DATA_NAME) ? [...DATA_NAME] : null, 1); | 				DATA[`sync`] = await global.read((NAME) ? [...NAME] : null, 1); | ||||||
| 			DATA[`local`] = await read((DATA_NAME) ? [...DATA_NAME] : null, -1); | 				DATA[`local`] = await global.read((NAME) ? [...NAME] : null, -1); | ||||||
| 	 | 	 | ||||||
| 				// Now return the data.
 | 				// Now return the data.
 | ||||||
| 				DATA_RETURNED[`source`] = (DATA[`sync`] != null) ? `sync` : `local`; | 				DATA_RETURNED[`source`] = (DATA[`sync`] != null) ? `sync` : `local`; | ||||||
| 				DATA_RETURNED[`value`] = DATA[DATA_RETURNED[`source`]]; | 				DATA_RETURNED[`value`] = DATA[DATA_RETURNED[`source`]]; | ||||||
| 	 | 	 | ||||||
|  | 				// Override the data with managed data if available. 
 | ||||||
|  | 				if ((NAME != null) ? NAME.length : false) { | ||||||
|  | 					DATA[`managed`] = await managed.read((NAME) ? [...NAME] : null); | ||||||
|  | 					DATA_RETURNED[`value`] = (DATA[`managed`] != null) ? DATA[`managed`] : DATA_RETURNED[`value`]; | ||||||
|  | 				}; | ||||||
|  | 
 | ||||||
| 				return DATA_RETURNED[`value`]; | 				return DATA_RETURNED[`value`]; | ||||||
| 				break; | 				break; | ||||||
| 			default: | 			default: | ||||||
| 			CLOUD = (CLOUD > 0) ? 1 : -1; | 				cloud = (cloud > 0) ? 1 : -1; | ||||||
| 			DATA = await read_database(CLOUD); | 				DATA = await pull(cloud); | ||||||
| 			DATA_RETURNED = (DATA_NAME) ? find_data(DATA, DATA_NAME) : DATA; | 				DATA_RETURNED = (NAME) ? find(DATA, NAME) : DATA; | ||||||
| 	 | 	 | ||||||
| 				return(DATA_RETURNED); | 				return(DATA_RETURNED); | ||||||
| 				break; | 				break; | ||||||
| 	} | 		}; | ||||||
| } | 	}; | ||||||
| 
 | 
 | ||||||
| /* More enhanced searching. | 	/* More enhanced searching. | ||||||
| 
 | 
 | ||||||
| @param {Array} SOURCE the source of the data | 	@param {Array} SOURCE the source of the data | ||||||
| @param {string} TERM the term to search | 	@param {string} TERM the term to search | ||||||
| @param {Array} ADDITIONAL_PLACES additional places to search | 	@param {Array} ADDITIONAL_PLACES additional places to search | ||||||
| @param {object} OPTIONS the options | 	@param {object} OPTIONS the options | ||||||
| @return {Array} the results | 	@return {Array} the results | ||||||
| */ | 	*/ | ||||||
| export async function search(SOURCE, TERM, ADDITIONAL_PLACES, STRICT = 0, OPTIONS = {}) { | 	static async search(SOURCE, TERM, ADDITIONAL_PLACES, STRICT = 0, OPTIONS = {}) { | ||||||
| 	let DATA = await read(SOURCE, (OPTIONS[`cloud`] != null) ? OPTIONS[`cloud`] : 0); | 		let DATA = await global.read(SOURCE, (OPTIONS[`cloud`] != null) ? OPTIONS[`cloud`] : 0); | ||||||
| 		let RESULTS; | 		let RESULTS; | ||||||
| 
 | 
 | ||||||
| 		if (DATA) { | 		if (DATA) { | ||||||
|  | @ -141,10 +118,10 @@ export async function search(SOURCE, TERM, ADDITIONAL_PLACES, STRICT = 0, OPTION | ||||||
| 
 | 
 | ||||||
| 				// Then, get the additional places.
 | 				// Then, get the additional places.
 | ||||||
| 				if ((ADDITIONAL_PLACES != null ? Array.isArray(ADDITIONAL_PLACES) : false) ? ADDITIONAL_PLACES.length > 0 : false) { | 				if ((ADDITIONAL_PLACES != null ? Array.isArray(ADDITIONAL_PLACES) : false) ? ADDITIONAL_PLACES.length > 0 : false) { | ||||||
| 				for (let PARAMETER_PRIORITY_NUMBER = 0; PARAMETER_PRIORITY_NUMBER < ADDITIONAL_PLACES.length; PARAMETER_PRIORITY_NUMBER++) { | 					ADDITIONAL_PLACES.forEach((ADDITIONAL_PLACE) => { | ||||||
| 						// Recursively search
 | 						// Recursively search
 | ||||||
| 					RESULTS = Object.assign({}, RESULTS, search(SOURCE, TERM, ADDITIONAL_PLACES[PARAMETER_PRIORITY_NUMBER], STRICT)); | 						RESULTS = Object.assign({}, RESULTS, global.search(SOURCE, TERM, ADDITIONAL_PLACE, STRICT)); | ||||||
| 				}; | 					}) | ||||||
| 				} | 				} | ||||||
| 			} else if (((typeof ADDITIONAL_PLACES).includes(`str`) && (ADDITIONAL_PLACES)) ? ADDITIONAL_PLACES.trim() : false) { | 			} else if (((typeof ADDITIONAL_PLACES).includes(`str`) && (ADDITIONAL_PLACES)) ? ADDITIONAL_PLACES.trim() : false) { | ||||||
| 				// Perform a sequential search on the data.
 | 				// Perform a sequential search on the data.
 | ||||||
|  | @ -199,41 +176,32 @@ export async function search(SOURCE, TERM, ADDITIONAL_PLACES, STRICT = 0, OPTION | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return RESULTS; | 		return RESULTS; | ||||||
| } | 	}; | ||||||
| 
 | 
 | ||||||
| /* Write the data on the selected prefname. | 	/* Write the data on the selected prefname. | ||||||
| 
 | 
 | ||||||
| @param {string} PATH the preference name | 	@param {string} path the preference name | ||||||
| @param {object} DATA the new data to be written | 	@param {object} data the new data to be written | ||||||
| @param {int} CLOUD store in the cloud; otherwise set to automatic | 	@param {int} CLOUD store in the cloud; otherwise set to automatic | ||||||
| @param {object} OPTIONS the options | 	@param {object} OPTIONS the options | ||||||
| */ | 	*/ | ||||||
| export async function write(PATH, DATA, CLOUD = -1, OPTIONS = {}) { | 	static async write(path, data, CLOUD = -1, OPTIONS = {}) { | ||||||
| 		let DATA_INJECTED = {}; | 		let DATA_INJECTED = {}; | ||||||
| 
 | 
 | ||||||
| 		// Inform the user that saving is in progress.
 | 		// Inform the user that saving is in progress.
 | ||||||
| 	if (((typeof OPTIONS).includes(`obj`) && OPTIONS != null) ? (!(!!OPTIONS[`silent`])) : true) { | 		(((typeof OPTIONS).includes(`obj`) && OPTIONS != null) ? (!(!!OPTIONS[`silent`])) : true)  | ||||||
| 		new logging ((new texts(`saving_current`)).localized, (new texts(`saving_current_message`)).localized, false) | 			? new logging ((new texts(`saving_current`)).localized, (new texts(`saving_current_message`)).localized, false) | ||||||
| 	}; | 			: false; | ||||||
| 
 |  | ||||||
| 	/* Forcibly write the data to chrome database |  | ||||||
| 
 |  | ||||||
| 	@param {object} DATA the data |  | ||||||
| 	@param {number} CLOUD the storage |  | ||||||
| 	*/ |  | ||||||
| 	const store = async (DATA, CLOUD = 0) => { |  | ||||||
| 		// If CLOUD is set to 0, it should automatically determine where the previous source of data was taken from.
 |  | ||||||
| 		return((CLOUD > 0) ? chrome.storage.sync.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 | ||||||
|  | 		@param {boolean} STRICT determines whether data is to be overridden or merged | ||||||
| 		@return {object} the updated data | 		@return {object} the updated data | ||||||
| 		*/ | 		*/ | ||||||
| 	function nest(EXISTING, SUBPATH, VALUE) { | 		function nest(EXISTING, SUBPATH, VALUE, STRICT = false) { | ||||||
| 			let DATABASE = EXISTING; | 			let DATABASE = EXISTING; | ||||||
| 
 | 
 | ||||||
| 			// Get the current path.
 | 			// Get the current path.
 | ||||||
|  | @ -242,13 +210,17 @@ export async function write(PATH, DATA, CLOUD = -1, OPTIONS = {}) { | ||||||
| 			PATH[`target`] = SUBPATH; | 			PATH[`target`] = SUBPATH; | ||||||
| 
 | 
 | ||||||
| 			if (PATH[`target`].length > 0) { | 			if (PATH[`target`].length > 0) { | ||||||
| 			if (DATABASE[PATH[`current`]] == null) { | 				DATABASE[PATH[`current`]] = (DATABASE[PATH[`current`]] == null) | ||||||
| 				DATABASE[PATH[`current`]] = {}; | 					? {} | ||||||
| 			} | 					: DATABASE[PATH[`current`]]; | ||||||
| 			DATABASE[PATH[`current`]] = nest(DATABASE[PATH[`current`]], PATH[`target`], VALUE); | 				DATABASE[PATH[`current`]] = nest(DATABASE[PATH[`current`]], PATH[`target`], VALUE, STRICT); | ||||||
| 			} else { | 			} else { | ||||||
| 			DATABASE[PATH[`current`]] = VALUE; | 				// If not strict and the data selected is a dictionary, then merge them. 
 | ||||||
|  | 				DATABASE[PATH[`current`]] = (((DATABASE[PATH[`current`]]) ? ((typeof DATABASE[PATH[`current`]]).includes(`obj`) && !Array.isArray(DATABASE[PATH[`current`]])) : false) && !STRICT) | ||||||
|  | 					? Object.assign(DATABASE[PATH[`current`]], VALUE) | ||||||
|  | 					: VALUE; | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
| 			// Return the value.
 | 			// Return the value.
 | ||||||
| 			return DATABASE; | 			return DATABASE; | ||||||
| 		} | 		} | ||||||
|  | @ -260,7 +232,7 @@ export async function write(PATH, DATA, CLOUD = -1, OPTIONS = {}) { | ||||||
| 			DATA_CHECK[`state`] = await compare(NAME, DATA); | 			DATA_CHECK[`state`] = await compare(NAME, DATA); | ||||||
| 
 | 
 | ||||||
| 			(!DATA_CHECK[`state`]) | 			(!DATA_CHECK[`state`]) | ||||||
| 			? logging.error((new texts(`error_msg_save_failed`)).localized, String(PATH), JSON.stringify(DATA)) | 				? logging.error((new texts(`error_msg_save_failed`)).localized, String(path), JSON.stringify(DATA)) | ||||||
| 				: ((((typeof OPTIONS).includes(`obj`) && OPTIONS != null) ? (!(!!OPTIONS[`silent`])) : true) | 				: ((((typeof OPTIONS).includes(`obj`) && OPTIONS != null) ? (!(!!OPTIONS[`silent`])) : true) | ||||||
| 					? new logging (new texts(`saving_done`).localized) | 					? new logging (new texts(`saving_done`).localized) | ||||||
| 					: false); | 					: false); | ||||||
|  | @ -268,25 +240,79 @@ export async function write(PATH, DATA, CLOUD = -1, OPTIONS = {}) { | ||||||
| 			return (DATA_CHECK[`state`]); | 			return (DATA_CHECK[`state`]); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	let DATA_ALL = await read(null, CLOUD); | 		let DATA_ALL; | ||||||
| 	if ((DATA_ALL != null && (typeof DATA_ALL).includes(`obj`)) ? Object.keys(DATA_ALL).length <= 0 : true) { |  | ||||||
| 		DATA_ALL = {}; |  | ||||||
| 	}; |  | ||||||
| 
 | 
 | ||||||
| 	let DATA_NAME = PATH; | 		// Get all data and set a blank value if it doesn't exist yet. 
 | ||||||
|  | 		DATA_ALL = await global.read(null, CLOUD); | ||||||
|  | 		DATA_ALL = ((DATA_ALL != null && (typeof DATA_ALL).includes(`obj`)) ? Object.keys(DATA_ALL).length <= 0 : true)  | ||||||
|  | 			? {} | ||||||
|  | 			: DATA_ALL; | ||||||
| 
 | 
 | ||||||
| 	// Convert the entered prefname to an array if it is not one.
 | 		// Set the data name. 
 | ||||||
| 	if (!(typeof SUBPATH).includes(`object`)) { | 		let DATA_NAME = (!(Array.isArray(path)) && path) | ||||||
| 		// Split what is not an object.
 | 			? String(path).trim().split(",") | ||||||
| 		DATA_NAME = String(PATH).trim().split(","); | 			: path; | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 		// Merge!
 | 		// Merge!
 | ||||||
| 	DATA_INJECTED = nest(DATA_ALL, [...DATA_NAME], DATA); | 		DATA_INJECTED = nest(DATA_ALL, [...DATA_NAME], data, (OPTIONS[`strict`] != null) ? OPTIONS[`strict`] : false); | ||||||
|  | 
 | ||||||
|  | 		// If cloud is not selected, get where the data is already existent. 
 | ||||||
|  | 		(CLOUD == 0 || CLOUD == null) | ||||||
|  | 			? (CLOUD = (DATA_ALL[`local`] != null) ? -1 : 1) | ||||||
|  | 			: false; | ||||||
| 
 | 
 | ||||||
| 		// Write!
 | 		// Write!
 | ||||||
| 	store(DATA_INJECTED, CLOUD); | 		chrome.storage[(CLOUD > 0) ? `sync` : `local`].set(DATA_INJECTED); | ||||||
| 	return (verify(DATA_NAME, DATA)); | 		return (verify(DATA_NAME, data)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	Dangerous: Resets a particular data.  | ||||||
|  | 
 | ||||||
|  | 	@param {string} preference the preference name to delete | ||||||
|  | 	@param {string} subpreference the subpreference name to delete | ||||||
|  | 	@param {int} CLOUD the storage of the data | ||||||
|  | 	@return {boolean} the user's confirmation | ||||||
|  | 	*/ | ||||||
|  | 	static async forget(preference, CLOUD = 0, override = false) { | ||||||
|  | 		// Confirm the action.
 | ||||||
|  | 		let CONFIRMATION = override ? override : await logging.confirm(); | ||||||
|  | 
 | ||||||
|  | 		if (CONFIRMATION) { | ||||||
|  | 			if (preference) { | ||||||
|  | 				/* | ||||||
|  | 				Erase applicable storage from a provider.  | ||||||
|  | 
 | ||||||
|  | 				@param {string} name the name of the data | ||||||
|  | 				@param {int} cloud the usage of cloud storage | ||||||
|  | 				*/ | ||||||
|  | 				async function erase(name, cloud) { | ||||||
|  | 					let DATA_NAME = (!(Array.isArray(name))) ? String(name).trim().split(",") : name; | ||||||
|  | 
 | ||||||
|  | 					console.log(DATA_NAME, cloud, [...DATA_NAME.slice(0,-1)]); | ||||||
|  | 
 | ||||||
|  | 					let DATA = await global.read((DATA_NAME.length > 1) ? [...DATA_NAME.slice(0,-1)] : null, cloud); | ||||||
|  | 
 | ||||||
|  | 					console.log(DATA, DATA_NAME, cloud, [...DATA_NAME.slice(0,-1)]); | ||||||
|  | 
 | ||||||
|  | 					(((((typeof (DATA)).includes(`obj`) && !Array.isArray(DATA) && DATA != null) ? Object.keys(DATA) : false) ? Object.keys(DATA).includes(DATA_NAME[DATA_NAME.length - 1]) : false)) | ||||||
|  | 						? delete DATA[DATA_NAME[DATA_NAME.length - 1]] | ||||||
|  | 						: false; | ||||||
|  | 
 | ||||||
|  | 					await global.write(DATA_NAME.slice(0,-1), DATA, CLOUD, {"strict": true}); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				(CLOUD >= 0) ? await erase(preference, 1) : false; | ||||||
|  | 				(CLOUD <= 0) ? await erase(preference, -1) : false; | ||||||
|  | 			} else { | ||||||
|  | 				// Clear the data storage.
 | ||||||
|  | 				(CLOUD >= 0) ? chrome.storage.sync.clear() : false; | ||||||
|  | 				(CLOUD <= 0) ? chrome.storage.local.clear() : false; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return CONFIRMATION; | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class session { | class session { | ||||||
|  | @ -376,33 +402,6 @@ class session { | ||||||
| 		// Write!
 | 		// Write!
 | ||||||
| 		store(DATA[`inject`]); | 		store(DATA[`inject`]); | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	/* Compare a data against the stored data. Useful when comparing dictionaries.  |  | ||||||
| 
 |  | ||||||
| 	@param {string} PATH the name |  | ||||||
| 	@param {object} DATA the data to compare to |  | ||||||
| 	@return {boolean} the result: true is when the data is the same, false otherwise |  | ||||||
| 	*/ |  | ||||||
| 	static async compare(PATH, DATA) { |  | ||||||
| 		/* The actual comparison of data. */ |  | ||||||
| 		async function comparison(DATA_ONE, DATA_TWO) { |  | ||||||
| 			let RESULT = true; |  | ||||||
| 
 |  | ||||||
| 			// The first round of checking is on the data type.
 |  | ||||||
| 			RESULT = ((typeof DATA_ONE == typeof DATA_TWO) ? ((Array.isArray(DATA_TWO) == Array.isArray(DATA_ONE)) && !((DATA_ONE == null && DATA_TWO != null) || (DATA_ONE != null && DATA_TWO == null))) : false) ? ((typeof DATA_ONE).includes(`obj`) ? (await hash.digest(DATA_ONE, {"output": "Number"}) == await hash.digest(DATA_TWO, {"output": "Number"})) : DATA_ONE == DATA_TWO) : false; |  | ||||||
| 
 |  | ||||||
| 			return (RESULT); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 		let COMPARISON = {}; |  | ||||||
| 		COMPARISON[`test`] = (PATH) ? DATA : DATA[1]; |  | ||||||
| 		COMPARISON[`against`] = (PATH) ? (await session.read((Array.isArray(PATH)) ? [...PATH] : PATH)) : DATA[0]; |  | ||||||
| 		COMPARISON[`result`] = comparison(COMPARISON[`against`], COMPARISON[`test`]); |  | ||||||
| 
 |  | ||||||
| 		// Return the result.
 |  | ||||||
| 		return (COMPARISON[`result`]); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|  | @ -432,130 +431,132 @@ export async function compare(PATH, DATA) { | ||||||
| 
 | 
 | ||||||
| 	let COMPARISON = {}; | 	let COMPARISON = {}; | ||||||
| 	COMPARISON[`test`] = (PATH) ? DATA : DATA[1]; | 	COMPARISON[`test`] = (PATH) ? DATA : DATA[1]; | ||||||
| 	COMPARISON[`against`] = (PATH) ? (await read((Array.isArray(PATH)) ? [...PATH] : PATH)) : DATA[0]; | 	COMPARISON[`against`] = (PATH) ? (await global.read((Array.isArray(PATH)) ? [...PATH] : PATH)) : DATA[0]; | ||||||
| 	COMPARISON[`result`] = comparison(COMPARISON[`against`], COMPARISON[`test`]); | 	COMPARISON[`result`] = comparison(COMPARISON[`against`], COMPARISON[`test`]); | ||||||
| 
 | 
 | ||||||
| 	// Return the result.
 | 	// Return the result.
 | ||||||
| 	return (COMPARISON[`result`]); | 	return (COMPARISON[`result`]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Dangerous: Resets all data or a domain's data. | class template { | ||||||
|  | 	/* Initialize the storage. | ||||||
| 	 | 	 | ||||||
| @param {string} preference the preference name to delete | 	@param {dictionary} data this build's managed data | ||||||
| @param {string} subpreference the subpreference name to delete | 	*/ | ||||||
| @param {int} CLOUD the storage of the data | 	static set(data) { | ||||||
| @return {boolean} the user's confirmation | 		let PREFERENCES = {}; | ||||||
| */ | 		PREFERENCES[`all`] = {}; | ||||||
| export async function forget(preference, CLOUD = 0, override = false) { |  | ||||||
| 	// Confirm the action.
 |  | ||||||
| 	let forget_action = override ? override : await logging.confirm(); |  | ||||||
| 
 | 
 | ||||||
| 	if (forget_action) { | 		((typeof data).includes(`obj`) && data != null) ? PREFERENCES[`all`][`build`] = data : false; | ||||||
| 		if (preference) { |  | ||||||
| 			let erase = async (CLOUD) => { |  | ||||||
| 				if (!(Array.isArray(preference))) { |  | ||||||
| 					preference = String(preference).trim().split(","); |  | ||||||
| 				}; |  | ||||||
| 
 |  | ||||||
| 				let DATA = await read((preference.length > 1) ? [...preference.slice(0,-1)] : null, CLOUD); |  | ||||||
| 
 |  | ||||||
| 				if (((((typeof (DATA)).includes(`obj`) && !Array.isArray(DATA) && DATA != null) ? Object.keys(DATA) : false) ? Object.keys(DATA).includes((preference.slice(-1))[0]) : false)) { |  | ||||||
| 					delete DATA[preference.slice(-1)]; |  | ||||||
| 				}; |  | ||||||
| 
 |  | ||||||
| 				await write(preference.slice(0,-1), DATA, CLOUD); |  | ||||||
| 			}; |  | ||||||
| 
 |  | ||||||
| 			if (CLOUD >= 0) { |  | ||||||
| 				erase(1); |  | ||||||
| 			}; |  | ||||||
| 			if (CLOUD <= 0) { |  | ||||||
| 				erase(-1); |  | ||||||
| 			}; |  | ||||||
| 		} else { |  | ||||||
| 			// Clear the data storage.
 |  | ||||||
| 			if (CLOUD >= 0) { |  | ||||||
| 				chrome.storage.sync.clear(); |  | ||||||
| 			} |  | ||||||
| 			if (CLOUD <= 0) { |  | ||||||
| 				chrome.storage.local.clear(); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return forget_action; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Initialize the storage. |  | ||||||
| 
 |  | ||||||
| @param {dictionary} data this build's managed data |  | ||||||
| */ |  | ||||||
| export function init(data) { |  | ||||||
| 	let PREFERENCES_ALL = {}; |  | ||||||
| 	PREFERENCES_ALL[`build`] = data; |  | ||||||
| 
 | 
 | ||||||
| 		// Read all data. 
 | 		// Read all data. 
 | ||||||
| 	chrome.storage.managed.get(null, function (DATA_MANAGED) { | 		[`managed`, `local`, `sync`].forEach((SOURCE) => { | ||||||
| 		PREFERENCES_ALL[`managed`] = DATA_MANAGED; | 			chrome.storage[SOURCE].get(null, (DATA) => { | ||||||
|  | 				PREFERENCES[`all`][SOURCE] = DATA; | ||||||
|  | 			}) | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 	chrome.storage.local.get(null, function (DATA_LOCAL) { | 		// Merge the data. 
 | ||||||
| 		PREFERENCES_ALL[`local`] = DATA_LOCAL; |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	chrome.storage.sync.get(null, function (DATA_SYNC) { |  | ||||||
| 		PREFERENCES_ALL[`sync`] = DATA_SYNC; |  | ||||||
| 	}); |  | ||||||
| 
 |  | ||||||
| 	// Merge data.
 |  | ||||||
| 		// Managed > Synchronized > Imported > Local
 | 		// Managed > Synchronized > Imported > Local
 | ||||||
|  | 		managed.reinforce(); | ||||||
| 
 | 
 | ||||||
| 	if (PREFERENCES_ALL[`managed`]) { | 		// Set the managed preferences. 
 | ||||||
| 		Object.keys(PREFERENCES_ALL[`managed`]).forEach((item) => { | 		if ((PREFERENCES[`all`][`managed`] && (typeof PREFERENCES[`all`][`managed`]).includes(`obj`) && !Array.isArray(PREFERENCES[`all`][`managed`])) ? Object.keys(PREFERENCES[`all`][`managed`]).length > 0 : false) { | ||||||
| 			let PREFERENCE = { name: item, existing: false }; | 			Object.keys(PREFERENCES[`all`][`managed`]).forEach((item) => { | ||||||
|  | 				let PREFERENCE = {}; | ||||||
|  | 				PREFERENCE[`name`] = item; | ||||||
| 
 | 
 | ||||||
| 			if (PREFERENCES_ALL[`sync`]) { | 				// Get if the data already exists. 
 | ||||||
| 				PREFERENCE[`existing`] = PREFERENCES_ALL[`sync`].hasOwnProperty( | 				PREFERENCE[`existing`] = (PREFERENCES[`all`][`sync`] && (typeof PREFERENCES[`all`][`sync`]).includes(`obj`)) | ||||||
| 					PREFERENCE[`name`], | 					? PREFERENCES[`all`][`sync`].hasOwnProperty(PREFERENCE[`name`]) | ||||||
| 				); | 					: false; | ||||||
| 			} |  | ||||||
| 
 | 
 | ||||||
| 				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`]); | 					global.forget(PREFERENCE[`name`], 0, true); | ||||||
| 				write( | 					global.write(PREFERENCE[`name`], PREFERENCES_ALL[`managed`][PREFERENCE[`name`]]); | ||||||
| 					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`]) { | 				(!PREFERENCE[`existing`]) | ||||||
| 				write( | 					? global.write(PREFERENCE[`name`], PREFERENCES[`all`][`build`][PREFERENCE[`name`]], -1) | ||||||
| 					PREFERENCE[`name`], | 					: false; | ||||||
| 					PREFERENCES_ALL[`build`][PREFERENCE[`name`]], |  | ||||||
| 					-1, |  | ||||||
| 				); |  | ||||||
| 			} |  | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|  | 	}; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | managed data functions | ||||||
|  | */ | ||||||
|  | class managed { | ||||||
|  | 	/* | ||||||
|  | 	Reinforce managed data.  | ||||||
|  | 	*/ | ||||||
|  | 	static reinforce() { | ||||||
|  | 		chrome.storage.managed.get(null, (DATA_MANAGED) => { | ||||||
|  | 			// Saving the data asynchronously
 | ||||||
|  | 			(Object.keys(DATA_MANAGED)).forEach(async (SOURCE) => { | ||||||
|  | 				await write(SOURCE, DATA_MANAGED[SOURCE], -1, {"strict": false}); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 	Read for any applicable managed data.  | ||||||
|  | 
 | ||||||
|  | 	@param {string} name the name of the data | ||||||
|  | 	@return {boolean} the result | ||||||
|  | 	*/ | ||||||
|  | 	static async read(name) { | ||||||
|  | 		function find(DATA_ALL, DATA_PATH) { | ||||||
|  | 			let DATA = DATA_ALL; | ||||||
|  | 
 | ||||||
|  | 			// Pull the data out.
 | ||||||
|  | 			if (DATA_ALL != null && (Array.isArray(DATA_PATH) && DATA_PATH != null) ? DATA_PATH.length > 0 : false) { | ||||||
|  | 				let DATA_PATH_SELECTED = String(DATA_PATH.shift()).trim(); | ||||||
|  | 
 | ||||||
|  | 				// Get the selected data.
 | ||||||
|  | 				DATA = DATA_ALL[DATA_PATH_SELECTED]; | ||||||
|  | 
 | ||||||
|  | 				// must run if there is actually a parameter to test
 | ||||||
|  | 				if (DATA_PATH.length > 0) { | ||||||
|  | 					// Recursively run to make use of the existing data.
 | ||||||
|  | 					DATA = find(DATA, DATA_PATH); | ||||||
|  | 				}; | ||||||
|  | 			} else { | ||||||
|  | 				return null; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// Now return the data.
 | ||||||
|  | 			return DATA; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		let DATA = {}; | ||||||
|  | 		DATA[`all`] = await chrome.storage.managed.get(null); | ||||||
|  | 		DATA[`selected`] = ((DATA[`all`] && (typeof DATA[`all`]).includes(`obj`) && !Array.isArray(DATA[`all`])) ? Object.keys(DATA[`all`]).length : false) | ||||||
|  | 			? find(DATA[`all`], name) | ||||||
|  | 			: null; | ||||||
|  | 		 | ||||||
|  | 		return (DATA[`selected`]); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
|  | @ -569,4 +570,4 @@ export function observe(reaction) { | ||||||
| 	}); | 	}); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export {session} | export {global, session, template, managed}; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue