promisify DB access
This commit is contained in:
		
							parent
							
								
									02fd4f1abe
								
							
						
					
					
						commit
						acc4d83b9d
					
				|  | @ -1,4 +1,4 @@ | |||
| /* global getDatabase, getStyles, saveStyle */ | ||||
| /* global dbExec, getStyles, saveStyle */ | ||||
| 'use strict'; | ||||
| 
 | ||||
| // eslint-disable-next-line no-var
 | ||||
|  | @ -6,7 +6,7 @@ var browserCommands, contextMenus; | |||
| 
 | ||||
| // *************************************************************************
 | ||||
| // preload the DB and report errors
 | ||||
| getDatabase(() => {}, (...args) => { | ||||
| dbExec().catch((...args) => { | ||||
|   args.forEach(arg => 'message' in arg && console.error(arg.message)); | ||||
| }); | ||||
| 
 | ||||
|  | @ -183,7 +183,7 @@ prefs.subscribe((id, checked) => { | |||
| // *************************************************************************
 | ||||
| 
 | ||||
| function webNavigationListener(method, {url, tabId, frameId}) { | ||||
|   getStyles({matchUrl: url, enabled: true, asHash: true}, styles => { | ||||
|   getStyles({matchUrl: url, enabled: true, asHash: true}).then(styles => { | ||||
|     if (method && !url.startsWith('chrome:') && tabId >= 0) { | ||||
|       chrome.tabs.sendMessage(tabId, { | ||||
|         method, | ||||
|  | @ -209,9 +209,9 @@ function updateIcon(tab, styles) { | |||
|     stylesReceived(styles); | ||||
|     return; | ||||
|   } | ||||
|   getTabRealURL(tab).then(url => | ||||
|     getStyles({matchUrl: url, enabled: true, asHash: true}, | ||||
|       stylesReceived)); | ||||
|   getTabRealURL(tab) | ||||
|     .then(url => getStyles({matchUrl: url, enabled: true, asHash: true})) | ||||
|     .then(stylesReceived); | ||||
| 
 | ||||
|   function stylesReceived(styles) { | ||||
|     let numStyles = styles.length; | ||||
|  | @ -255,7 +255,7 @@ function onRuntimeMessage(request, sender, sendResponse) { | |||
|   switch (request.method) { | ||||
| 
 | ||||
|     case 'getStyles': | ||||
|       getStyles(request, sendResponse); | ||||
|       getStyles(request).then(sendResponse); | ||||
|       return KEEP_CHANNEL_OPEN; | ||||
| 
 | ||||
|     case 'saveStyle': | ||||
|  | @ -263,9 +263,9 @@ function onRuntimeMessage(request, sender, sendResponse) { | |||
|       return KEEP_CHANNEL_OPEN; | ||||
| 
 | ||||
|     case 'healthCheck': | ||||
|       getDatabase( | ||||
|         () => sendResponse(true), | ||||
|         () => sendResponse(false)); | ||||
|       dbExec() | ||||
|         .then(() => sendResponse(true)) | ||||
|         .catch(() => sendResponse(false)); | ||||
|       return KEEP_CHANNEL_OPEN; | ||||
| 
 | ||||
|     case 'download': | ||||
|  |  | |||
							
								
								
									
										23
									
								
								messaging.js
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								messaging.js
									
									
									
									
									
								
							|  | @ -268,13 +268,13 @@ function sessionStorageHash(name) { | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| function onBackgroundReady() { | ||||
|   return BG ? Promise.resolve() : new Promise(ping); | ||||
| function onBackgroundReady(...dataPassthru) { | ||||
|   return BG ? Promise.resolve(...dataPassthru) : new Promise(ping); | ||||
|   function ping(resolve) { | ||||
|     chrome.runtime.sendMessage({method: 'healthCheck'}, health => { | ||||
|       if (health !== undefined) { | ||||
|         BG = chrome.extension.getBackgroundPage(); | ||||
|         resolve(); | ||||
|         resolve(...dataPassthru); | ||||
|       } else { | ||||
|         ping(resolve); | ||||
|       } | ||||
|  | @ -285,20 +285,13 @@ function onBackgroundReady() { | |||
| 
 | ||||
| // in case Chrome haven't yet loaded the bg page and displays our page like edit/manage
 | ||||
| function getStylesSafe(options) { | ||||
|   return new Promise(resolve => { | ||||
|     if (BG) { | ||||
|       BG.getStyles(options, resolve); | ||||
|     } else { | ||||
|       onBackgroundReady().then(() => | ||||
|         BG.getStyles(options, resolve)); | ||||
|     } | ||||
|   }); | ||||
|   return onBackgroundReady(options).then(BG.getStyles); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function saveStyleSafe(style) { | ||||
|   return onBackgroundReady() | ||||
|     .then(() => BG.saveStyle(BG.deepCopy(style))) | ||||
|   return onBackgroundReady(BG.deepCopy(style)) | ||||
|     .then(BG.saveStyle) | ||||
|     .then(savedStyle => { | ||||
|       if (style.notify === false) { | ||||
|         handleUpdate(savedStyle, style); | ||||
|  | @ -309,8 +302,8 @@ function saveStyleSafe(style) { | |||
| 
 | ||||
| 
 | ||||
| function deleteStyleSafe({id, notify = true} = {}) { | ||||
|   return onBackgroundReady() | ||||
|     .then(() => BG.deleteStyle({id, notify})) | ||||
|   return onBackgroundReady({id, notify}) | ||||
|     .then(BG.deleteStyle) | ||||
|     .then(() => { | ||||
|       if (!notify) { | ||||
|         handleDelete(id); | ||||
|  |  | |||
							
								
								
									
										120
									
								
								storage.js
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								storage.js
									
									
									
									
									
								
							|  | @ -43,58 +43,69 @@ var chromeLocal = { | |||
| }; | ||||
| 
 | ||||
| 
 | ||||
| function getDatabase(ready, error) { | ||||
|   const dbOpenRequest = window.indexedDB.open('stylish', 2); | ||||
|   dbOpenRequest.onsuccess = event => { | ||||
|     ready(event.target.result); | ||||
|   }; | ||||
|   dbOpenRequest.onerror = event => { | ||||
|     console.warn(event.target.errorCode); | ||||
|     if (error) { | ||||
|       error(event); | ||||
| function dbExec(method, data) { | ||||
|   return new Promise((resolve, reject) => { | ||||
|     Object.assign(indexedDB.open('stylish', 2), { | ||||
|       onsuccess(event) { | ||||
|         const database = event.target.result; | ||||
|         if (!method) { | ||||
|           resolve(database); | ||||
|         } else { | ||||
|           const transaction = database.transaction(['styles'], 'readwrite'); | ||||
|           const store = transaction.objectStore('styles'); | ||||
|           Object.assign(store[method](data), { | ||||
|             onsuccess: event => resolve(event, store, transaction, database), | ||||
|             onerror: reject, | ||||
|           }); | ||||
|         } | ||||
|   }; | ||||
|   dbOpenRequest.onupgradeneeded = event => { | ||||
|       }, | ||||
|       onerror(event) { | ||||
|         console.warn(event.target.errorCode); | ||||
|         reject(event); | ||||
|       }, | ||||
|       onupgradeneeded(event) { | ||||
|         if (event.oldVersion == 0) { | ||||
|           event.target.result.createObjectStore('styles', { | ||||
|             keyPath: 'id', | ||||
|             autoIncrement: true, | ||||
|           }); | ||||
|         } | ||||
|   }; | ||||
|       }, | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function getStyles(options, callback) { | ||||
| function getStyles(options) { | ||||
|   if (cachedStyles.list) { | ||||
|     callback(filterStyles(options)); | ||||
|     return; | ||||
|     return Promise.resolve(filterStyles(options)); | ||||
|   } | ||||
|   if (cachedStyles.mutex.inProgress) { | ||||
|     cachedStyles.mutex.onDone.push({options, callback}); | ||||
|     return; | ||||
|     return new Promise(resolve => { | ||||
|       cachedStyles.mutex.onDone.push({options, resolve}); | ||||
|     }); | ||||
|   } | ||||
|   cachedStyles.mutex.inProgress = true; | ||||
| 
 | ||||
|   getDatabase(db => { | ||||
|     const tx = db.transaction(['styles'], 'readonly'); | ||||
|     const os = tx.objectStore('styles'); | ||||
|     os.getAll().onsuccess = event => { | ||||
|   return dbExec('getAll').then(event => { | ||||
|     cachedStyles.list = event.target.result || []; | ||||
|     cachedStyles.byId.clear(); | ||||
|     const t0 = performance.now(); | ||||
|     let hasTimeToCompile = true; | ||||
|     for (const style of cachedStyles.list) { | ||||
|       cachedStyles.byId.set(style.id, style); | ||||
|         compileStyleRegExps({style}); | ||||
|       if (hasTimeToCompile) { | ||||
|         hasTimeToCompile = !compileStyleRegExps({style}) || performance.now() - t0 > 100; | ||||
|       } | ||||
|     } | ||||
|       callback(filterStyles(options)); | ||||
| 
 | ||||
|     cachedStyles.mutex.inProgress = false; | ||||
|       for (const {options, callback} of cachedStyles.mutex.onDone) { | ||||
|         callback(filterStyles(options)); | ||||
|     for (const {options, resolve} of cachedStyles.mutex.onDone) { | ||||
|       resolve(filterStyles(options)); | ||||
|     } | ||||
|     cachedStyles.mutex.onDone = []; | ||||
|     }; | ||||
|   }, null); | ||||
|     return filterStyles(options); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -213,12 +224,7 @@ function filterStylesInternal({ | |||
| 
 | ||||
| 
 | ||||
| function saveStyle(style) { | ||||
|   return new Promise(resolve => { | ||||
|     getDatabase(db => { | ||||
|       const tx = db.transaction(['styles'], 'readwrite'); | ||||
|       const os = tx.objectStore('styles'); | ||||
| 
 | ||||
|       const id = style.id == '0' ? 0 : Number(style.id) || null; | ||||
|   const id = Number(style.id) >= 0 ? Number(style.id) : null; | ||||
|   const reason = style.reason; | ||||
|   const notify = style.notify !== false; | ||||
|   delete style.method; | ||||
|  | @ -228,32 +234,42 @@ function saveStyle(style) { | |||
|     delete style.name; | ||||
|   } | ||||
|   let existed, codeIsUpdated; | ||||
| 
 | ||||
|   if (id !== null) { | ||||
|     // Update or create
 | ||||
|     style.id = id; | ||||
|         os.get(id).onsuccess = eventGet => { | ||||
|           const oldStyle = eventGet.target.result; | ||||
|     return dbExec('get', id).then((event, store) => { | ||||
|       const oldStyle = event.target.result; | ||||
|       existed = Boolean(oldStyle); | ||||
|       codeIsUpdated = !existed || style.sections && !styleSectionsEqual(style, oldStyle); | ||||
|           write(Object.assign({}, oldStyle, style)); | ||||
|         }; | ||||
|       style = Object.assign({}, oldStyle, style); | ||||
|       return write(style, store); | ||||
|     }); | ||||
|   } else { | ||||
|     // Create
 | ||||
|     delete style.id; | ||||
|         write(Object.assign({ | ||||
|     style = Object.assign({ | ||||
|       // Set optional things if they're undefined
 | ||||
|       enabled: true, | ||||
|       updateUrl: null, | ||||
|       md5Url: null, | ||||
|       url: null, | ||||
|       originalMd5: null, | ||||
|         }, style)); | ||||
|     }, style); | ||||
|     return write(style); | ||||
|   } | ||||
| 
 | ||||
|       function write(style) { | ||||
|   function write(style, store) { | ||||
|     style.sections = normalizeStyleSections(style); | ||||
|         os.put(style).onsuccess = event => { | ||||
|     if (store) { | ||||
|       return new Promise(resolve => { | ||||
|         store.put(style).onsuccess = event => resolve(done(event)); | ||||
|       }); | ||||
|     } else { | ||||
|       return dbExec('put', style).then(done); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   function done(event) { | ||||
|     style.id = style.id || event.target.result; | ||||
|     invalidateCache(existed ? {updated: style} : {added: style}); | ||||
|     compileStyleRegExps({style}); | ||||
|  | @ -268,28 +284,21 @@ function saveStyle(style) { | |||
|     } else if (reason == 'import') { | ||||
|       chrome.storage.local.remove(DIGEST_KEY_PREFIX + style.id, ignoreChromeError); | ||||
|     } | ||||
|           resolve(style); | ||||
|         }; | ||||
|     return style; | ||||
|   } | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function deleteStyle({id, notify = true}) { | ||||
|   id = Number(id); | ||||
|   chrome.storage.local.remove(DIGEST_KEY_PREFIX + id, ignoreChromeError); | ||||
|   return new Promise(resolve => | ||||
|     getDatabase(db => { | ||||
|       const tx = db.transaction(['styles'], 'readwrite'); | ||||
|       const os = tx.objectStore('styles'); | ||||
|       os.delete(Number(id)).onsuccess = () => { | ||||
|   return dbExec('delete', id).then(() => { | ||||
|     invalidateCache({deletedId: id}); | ||||
|     if (notify) { | ||||
|       notifyAllTabs({method: 'styleDeleted', id}); | ||||
|     } | ||||
|         resolve(id); | ||||
|       }; | ||||
|     })); | ||||
|     return id; | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -448,11 +457,12 @@ function compileStyleRegExps({style, compileAll}) { | |||
|         const rx = tryRegExp(anchored); | ||||
|         cachedStyles.regexps.set(cacheKey, rx || false); | ||||
|         if (!compileAll && performance.now() - t0 > 100) { | ||||
|           return; | ||||
|           return false; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										13
									
								
								update.js
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								update.js
									
									
									
									
									
								
							|  | @ -22,17 +22,14 @@ var updater = { | |||
| 
 | ||||
|   checkAllStyles({observer = () => {}, save = true, ignoreDigest} = {}) { | ||||
|     updater.resetInterval(); | ||||
|     return new Promise(resolve => { | ||||
|       getStyles({}, styles => { | ||||
|     return getStyles({}).then(styles => { | ||||
|       styles = styles.filter(style => style.updateUrl); | ||||
|       observer(updater.COUNT, styles.length); | ||||
|         Promise.all(styles.map(style => | ||||
|           updater.checkStyle({style, observer, save, ignoreDigest}) | ||||
|         )).then(() => { | ||||
|       return Promise.all( | ||||
|         styles.map(style => | ||||
|           updater.checkStyle({style, observer, save, ignoreDigest}))); | ||||
|     }).then(() => { | ||||
|       observer(updater.DONE); | ||||
|           resolve(); | ||||
|         }); | ||||
|       }); | ||||
|     }); | ||||
|   }, | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user