diff --git a/spec/state-store-spec.js b/spec/state-store-spec.js index 955ceb767..95fdcb71b 100644 --- a/spec/state-store-spec.js +++ b/spec/state-store-spec.js @@ -21,7 +21,21 @@ describe("StateStore", () => { return store.load('no-such-key').then((value) => { expect(value).toBeNull() }) - }); + }) + + it("can clear the state object store", () => { + const store = new StateStore(databaseName, version) + return store.save('key', {foo:'bar'}) + .then(() => store.count()) + .then((count) => + expect(count).toBe(1) + ) + .then(() => store.clear()) + .then(() => store.count()) + .then((count) => { + expect(count).toBe(0) + }) + }) describe("when there is an error reading from the database", () => { it("rejects the promise returned by load", () => { diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 248ee7e6a..cdb22b40d 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -122,13 +122,15 @@ class AtomEnvironment extends Model {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params @loadTime = null - {devMode, safeMode, resourcePath} = @getLoadSettings() + {devMode, safeMode, resourcePath, clearState} = @getLoadSettings() @emitter = new Emitter @disposables = new CompositeDisposable @stateStore = new StateStore('AtomEnvironments', 1) + @stateStore.clear() if clearState + @deserializers = new DeserializerManager(this) @deserializeTimings = {} diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 5ff24c458..891caf19d 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -65,7 +65,7 @@ class AtomApplication exit: (status) -> app.exit(status) constructor: (options) -> - {@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout} = options + {@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout, clearState} = options @socketPath = null if options.test @@ -89,16 +89,16 @@ class AtomApplication else @loadState(options) or @openPath(options) - openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout}) -> + openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearState}) -> if test @runTests({headless: true, devMode, @resourcePath, executedFrom, pathsToOpen, logFile, timeout}) else if pathsToOpen.length > 0 - @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup}) + @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearState}) else if urlsToOpen.length > 0 @openUrl({urlToOpen, devMode, safeMode}) for urlToOpen in urlsToOpen else # Always open a editor window if this is the first instance of Atom. - @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup}) + @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearState}) # Public: Removes the {AtomWindow} from the global window list. removeWindow: (window) -> @@ -387,8 +387,8 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :profileStartup - Boolean to control creating a profile of the startup time. # :window - {AtomWindow} to open file paths in. - openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window} = {}) -> - @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window}) + openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearState} = {}) -> + @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearState}) # Public: Opens multiple paths, in existing windows if possible. # @@ -400,9 +400,10 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :windowDimensions - Object with height and width keys. # :window - {AtomWindow} to open file paths in. - openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window}={}) -> + openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearState}={}) -> devMode = Boolean(devMode) safeMode = Boolean(safeMode) + clearState = Boolean(clearState) locationsToOpen = (@locationForPathToOpen(pathToOpen, executedFrom) for pathToOpen in pathsToOpen) pathsToOpen = (locationToOpen.pathToOpen for locationToOpen in locationsToOpen) @@ -435,7 +436,7 @@ class AtomApplication windowInitializationScript ?= require.resolve('../initialize-application-window') resourcePath ?= @resourcePath windowDimensions ?= @getDimensionsForNewWindow() - openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup}) + openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearState}) if pidToKillWhenClosed? @pidsToOpenWindows[pidToKillWhenClosed] = openedWindow diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 20ba2ad5c..35ccabb8a 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -50,6 +50,7 @@ class AtomWindow loadSettings.safeMode ?= false loadSettings.atomHome = process.env.ATOM_HOME loadSettings.firstLoad = true + loadSettings.clearState ?= false # Only send to the first non-spec window created if @constructor.includeShellLoadTime and not @isSpec diff --git a/src/browser/main.coffee b/src/browser/main.coffee index bbce1d87f..c1df3455f 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -123,6 +123,7 @@ parseCommandLine = -> options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.') options.string('socket-path') options.string('user-data-dir') + options.boolean('clear-state').describe('clear-state', 'Delete all Atom environment state.') args = options.argv @@ -146,6 +147,7 @@ parseCommandLine = -> socketPath = args['socket-path'] userDataDir = args['user-data-dir'] profileStartup = args['profile-startup'] + clearState = args['clear-state'] urlsToOpen = [] devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getHomeDir(), 'github', 'atom') setPortable = args.portable @@ -169,6 +171,7 @@ parseCommandLine = -> {resourcePath, devResourcePath, pathsToOpen, urlsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, - logFile, socketPath, userDataDir, profileStartup, timeout, setPortable} + logFile, socketPath, userDataDir, profileStartup, timeout, setPortable, + clearState} start() diff --git a/src/state-store.js b/src/state-store.js index feefbbb34..2175bbe4c 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -25,9 +25,7 @@ class StateStore { save (key, value) { return this.dbPromise.then(db => { - if (!db) { - return - } + if (!db) return return new Promise((resolve, reject) => { var request = db.transaction(['states'], 'readwrite') @@ -42,9 +40,7 @@ class StateStore { load (key) { return this.dbPromise.then(db => { - if (!db) { - return null - } + if (!db) return return new Promise((resolve, reject) => { var request = db.transaction(['states']) @@ -60,4 +56,36 @@ class StateStore { }) }) } + + clear () { + return this.dbPromise.then(db => { + if (!db) return + + return new Promise((resolve, reject) => { + var request = db.transaction(['states'], 'readwrite') + .objectStore('states') + .clear() + + request.onsuccess = resolve + request.onerror = reject + }) + }) + } + + count () { + return this.dbPromise.then(db => { + if (!db) return + + return new Promise((resolve, reject) => { + var request = db.transaction(['states']) + .objectStore('states') + .count() + + request.onsuccess = () => { + resolve(request.result) + } + request.onerror = reject + }) + }) + } }