diff --git a/assets/javascripts/app/app.coffee b/assets/javascripts/app/app.coffee index 22845ccf..e92a5722 100644 --- a/assets/javascripts/app/app.coffee +++ b/assets/javascripts/app/app.coffee @@ -16,6 +16,7 @@ @store = new Store @appCache = new app.AppCache if app.AppCache.isEnabled() @settings = new app.Settings @store + @db = new app.DB() @docs = new app.collections.Docs @disabledDocs = new app.collections.Docs @@ -86,7 +87,6 @@ @entries.add doc.toEntry() for doc in @docs.all() @entries.add doc.toEntry() for doc in @disabledDocs.all() @initDoc(doc) for doc in @docs.all() - @db = new app.DB() @trigger 'ready' @router.start() @hideLoading() @@ -125,6 +125,7 @@ saveDocs: -> @settings.setDocs(doc.slug for doc in @docs.all()) + @db.migrate() @appCache?.updateInBackground() welcomeBack: -> diff --git a/assets/javascripts/app/db.coffee b/assets/javascripts/app/db.coffee index bdac72aa..af37a8c3 100644 --- a/assets/javascripts/app/db.coffee +++ b/assets/javascripts/app/db.coffee @@ -3,7 +3,7 @@ class app.DB constructor: -> @useIndexedDB = @useIndexedDB() - @indexedDBVersion = @indexedDBVersion() + @appVersion = @appVersion() @callbacks = [] db: (fn) -> @@ -13,7 +13,7 @@ class app.DB try @open = true - req = indexedDB.open(NAME, @indexedDBVersion) + req = indexedDB.open(NAME, @schemaVersion()) req.onsuccess = @onOpenSuccess req.onerror = @onOpenError req.onupgradeneeded = @onUpgradeNeeded @@ -59,14 +59,16 @@ class app.DB onUpgradeNeeded: (event) -> return unless db = event.target.result - unless db.objectStoreNames.contains('docs') + objectStoreNames = $.makeArray(db.objectStoreNames) + + unless $.arrayDelete(objectStoreNames, 'docs') db.createObjectStore('docs') - for doc in app.docs.all() when not db.objectStoreNames.contains(doc.slug) + for doc in app.docs.all() when not $.arrayDelete(objectStoreNames, doc.slug) db.createObjectStore(doc.slug) - for doc in app.disabledDocs.all() when not db.objectStoreNames.contains(doc.slug) - db.createObjectStore(doc.slug) + for name in objectStoreNames + db.deleteObjectStore(name) return store: (doc, data, onSuccess, onError) -> @@ -201,6 +203,11 @@ class app.DB onError() return + unless db.objectStoreNames.contains(entry.doc.slug) + onError() + @loadDocsCache(db) + return + txn = @idbTransaction db, stores: [entry.doc.slug], mode: 'readonly' store = txn.objectStore(entry.doc.slug) @@ -212,10 +219,11 @@ class app.DB event.preventDefault() onError() return - @loadDocsCache(db) unless @cachedDocs + @loadDocsCache(db) return loadDocsCache: (db) -> + return if @cachedDocs @cachedDocs = {} txn = @idbTransaction db, stores: ['docs'], mode: 'readonly' @@ -261,5 +269,15 @@ class app.DB catch false - indexedDBVersion: -> - if app.config.env is 'production' then parseInt(app.config.version, 10) else Date.now() / 1000 + migrate: -> + app.settings.set('schema', @userVersion() + 1) + return + + schemaVersion: -> + @appVersion * 10 + @userVersion() + + userVersion: -> + app.settings.get('schema') + + appVersion: -> + if app.config.env is 'production' then parseInt(app.config.version, 10) else Math.floor(Date.now() / 1000) diff --git a/assets/javascripts/app/settings.coffee b/assets/javascripts/app/settings.coffee index 9e547eb9..8f04d483 100644 --- a/assets/javascripts/app/settings.coffee +++ b/assets/javascripts/app/settings.coffee @@ -5,18 +5,19 @@ class app.Settings LAYOUT_KEY = 'layout' SIZE_KEY = 'size' - @defaults: -> + @defaults: count: 0 hideDisabled: false hideIntro: false news: 0 autoUpdate: true + schema: 0 constructor: (@store) -> @create() unless @settings = @store.get(SETTINGS_KEY) create: -> - @settings = @constructor.defaults() + @settings = $.extend({}, @constructor.defaults) @applyLegacyValues @settings @save() return @@ -35,7 +36,7 @@ class app.Settings @save() get: (key) -> - @settings[key] + @settings[key] ? @constructor.defaults[key] hasDocs: -> try !!Cookies.get DOCS_KEY diff --git a/assets/javascripts/lib/util.coffee b/assets/javascripts/lib/util.coffee index 9f54e485..baf36124 100644 --- a/assets/javascripts/lib/util.coffee +++ b/assets/javascripts/lib/util.coffee @@ -239,6 +239,14 @@ $.makeArray = (object) -> else Array::slice.apply(object) +$.arrayDelete = (array, object) -> + index = array.indexOf(object) + if index >= 0 + array.splice(index, 1) + true + else + false + # Returns true if the object is an array or a collection of DOM elements. $.isCollection = (object) -> Array.isArray(object) or typeof object?.item is 'function' diff --git a/assets/javascripts/views/sidebar/doc_picker.coffee b/assets/javascripts/views/sidebar/doc_picker.coffee index 63618dad..29af650f 100644 --- a/assets/javascripts/views/sidebar/doc_picker.coffee +++ b/assets/javascripts/views/sidebar/doc_picker.coffee @@ -50,7 +50,9 @@ class app.views.DocPicker extends app.View app.settings.setDocs(docs) @saveLink.textContent = if app.appCache then 'Downloading\u2026' else 'Saving\u2026' disabledDocs = new app.collections.Docs(doc for doc in app.docs.all() when docs.indexOf(doc.slug) is -1) - disabledDocs.uninstall -> app.reload() + disabledDocs.uninstall -> + app.db.migrate() + app.reload() return getSelectedDocs: ->