mirror of
https://github.com/atom/atom.git
synced 2026-04-06 03:02:13 -04:00
Merge pull request #11060 from atom/as-serialize-history-without-snapshots
Serialize MarkerLayers only on quit
This commit is contained in:
@@ -54,7 +54,7 @@
|
||||
"service-hub": "^0.7.0",
|
||||
"source-map-support": "^0.3.2",
|
||||
"temp": "0.8.1",
|
||||
"text-buffer": "8.3.2",
|
||||
"text-buffer": "8.4.1",
|
||||
"typescript-simple": "1.0.0",
|
||||
"underscore-plus": "^1.6.6",
|
||||
"yargs": "^3.23.0"
|
||||
|
||||
@@ -185,12 +185,12 @@ describe "AtomEnvironment", ->
|
||||
keydown = new KeyboardEvent('keydown')
|
||||
atom.document.dispatchEvent(keydown)
|
||||
advanceClock atom.saveStateDebounceInterval
|
||||
expect(atom.saveState).toHaveBeenCalled()
|
||||
expect(atom.saveState).toHaveBeenCalledWith({isUnloading: false})
|
||||
|
||||
mousedown = new MouseEvent('mousedown')
|
||||
atom.document.dispatchEvent(mousedown)
|
||||
advanceClock atom.saveStateDebounceInterval
|
||||
expect(atom.saveState).toHaveBeenCalled()
|
||||
expect(atom.saveState).toHaveBeenCalledWith({isUnloading: false})
|
||||
|
||||
describe "openInitialEmptyEditorIfNecessary", ->
|
||||
describe "when there are no paths set", ->
|
||||
|
||||
@@ -541,7 +541,7 @@ describe('GitRepositoryAsync', () => {
|
||||
await atom.workspace.open('file.txt')
|
||||
|
||||
project2 = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm})
|
||||
project2.deserialize(atom.project.serialize(), atom.deserializers)
|
||||
project2.deserialize(atom.project.serialize({isUnloading: true}))
|
||||
|
||||
const repo = project2.getRepositories()[0].async
|
||||
waitsForPromise(() => repo.refreshStatus())
|
||||
|
||||
@@ -347,7 +347,7 @@ describe "GitRepository", ->
|
||||
|
||||
runs ->
|
||||
project2 = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm})
|
||||
project2.deserialize(atom.project.serialize(), atom.deserializers)
|
||||
project2.deserialize(atom.project.serialize({isUnloading: false}))
|
||||
buffer = project2.getBuffers()[0]
|
||||
|
||||
waitsFor ->
|
||||
|
||||
@@ -37,7 +37,7 @@ describe "Project", ->
|
||||
expect(atom.project.getBuffers().length).toBe 1
|
||||
|
||||
deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm})
|
||||
deserializedProject.deserialize(atom.project.serialize(), atom.deserializers)
|
||||
deserializedProject.deserialize(atom.project.serialize({isUnloading: false}))
|
||||
expect(deserializedProject.getBuffers().length).toBe 0
|
||||
|
||||
it "listens for destroyed events on deserialized buffers and removes them when they are destroyed", ->
|
||||
@@ -47,7 +47,7 @@ describe "Project", ->
|
||||
runs ->
|
||||
expect(atom.project.getBuffers().length).toBe 1
|
||||
deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm})
|
||||
deserializedProject.deserialize(atom.project.serialize(), atom.deserializers)
|
||||
deserializedProject.deserialize(atom.project.serialize({isUnloading: false}))
|
||||
|
||||
expect(deserializedProject.getBuffers().length).toBe 1
|
||||
deserializedProject.getBuffers()[0].destroy()
|
||||
@@ -64,7 +64,7 @@ describe "Project", ->
|
||||
expect(atom.project.getBuffers().length).toBe 1
|
||||
fs.mkdirSync(pathToOpen)
|
||||
deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm})
|
||||
deserializedProject.deserialize(atom.project.serialize(), atom.deserializers)
|
||||
deserializedProject.deserialize(atom.project.serialize({isUnloading: false}))
|
||||
expect(deserializedProject.getBuffers().length).toBe 0
|
||||
|
||||
it "does not deserialize buffers when their path is inaccessible", ->
|
||||
@@ -78,9 +78,26 @@ describe "Project", ->
|
||||
expect(atom.project.getBuffers().length).toBe 1
|
||||
fs.chmodSync(pathToOpen, '000')
|
||||
deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm})
|
||||
deserializedProject.deserialize(atom.project.serialize(), atom.deserializers)
|
||||
deserializedProject.deserialize(atom.project.serialize({isUnloading: false}))
|
||||
expect(deserializedProject.getBuffers().length).toBe 0
|
||||
|
||||
it "serializes marker layers only if Atom is quitting", ->
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('a')
|
||||
|
||||
runs ->
|
||||
bufferA = atom.project.getBuffers()[0]
|
||||
layerA = bufferA.addMarkerLayer(maintainHistory: true)
|
||||
markerA = layerA.markPosition([0, 3])
|
||||
|
||||
notQuittingProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm})
|
||||
notQuittingProject.deserialize(atom.project.serialize({isUnloading: false}))
|
||||
expect(notQuittingProject.getBuffers()[0].getMarkerLayer(layerA.id)?.getMarker(markerA.id)).toBeUndefined()
|
||||
|
||||
quittingProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm})
|
||||
quittingProject.deserialize(atom.project.serialize({isUnloading: true}))
|
||||
expect(quittingProject.getBuffers()[0].getMarkerLayer(layerA.id)?.getMarker(markerA.id)).not.toBeUndefined()
|
||||
|
||||
describe "when an editor is saved and the project has no path", ->
|
||||
it "sets the project's path to the saved file's parent directory", ->
|
||||
tempFile = temp.openSync().path
|
||||
|
||||
@@ -55,6 +55,11 @@ describe "WindowEventHandler", ->
|
||||
jasmine.unspy(TextEditor.prototype, "shouldPromptToSave")
|
||||
spyOn(ipcRenderer, 'send')
|
||||
|
||||
it "saves AtomEnvironment's state with the {isUnloading: true} option", ->
|
||||
spyOn(atom, 'saveState')
|
||||
window.dispatchEvent(new CustomEvent('beforeunload'))
|
||||
expect(atom.saveState).toHaveBeenCalledWith({isUnloading: true})
|
||||
|
||||
describe "when pane items are modified", ->
|
||||
editor = null
|
||||
beforeEach ->
|
||||
|
||||
@@ -22,11 +22,11 @@ describe "Workspace", ->
|
||||
describe "serialization", ->
|
||||
simulateReload = ->
|
||||
workspaceState = atom.workspace.serialize()
|
||||
projectState = atom.project.serialize()
|
||||
projectState = atom.project.serialize({isUnloading: true})
|
||||
atom.workspace.destroy()
|
||||
atom.project.destroy()
|
||||
atom.project = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm.bind(atom)})
|
||||
atom.project.deserialize(projectState, atom.deserializers)
|
||||
atom.project.deserialize(projectState)
|
||||
atom.workspace = new Workspace({
|
||||
config: atom.config, project: atom.project, packageManager: atom.packages,
|
||||
grammarRegistry: atom.grammars, deserializerManager: atom.deserializers,
|
||||
|
||||
@@ -230,7 +230,7 @@ class AtomEnvironment extends Model
|
||||
checkPortableHomeWritable()
|
||||
|
||||
attachSaveStateListeners: ->
|
||||
debouncedSaveState = _.debounce((=> @saveState()), @saveStateDebounceInterval)
|
||||
debouncedSaveState = _.debounce((=> @saveState({isUnloading: false})), @saveStateDebounceInterval)
|
||||
@document.addEventListener('mousedown', debouncedSaveState, true)
|
||||
@document.addEventListener('keydown', debouncedSaveState, true)
|
||||
@disposables.add new Disposable =>
|
||||
@@ -684,9 +684,9 @@ class AtomEnvironment extends Model
|
||||
|
||||
@openInitialEmptyEditorIfNecessary()
|
||||
|
||||
serialize: ->
|
||||
serialize: (options) ->
|
||||
version: @constructor.version
|
||||
project: @project.serialize()
|
||||
project: @project.serialize(options)
|
||||
workspace: @workspace.serialize()
|
||||
packageStates: @packages.serialize()
|
||||
grammars: {grammarOverridesByPath: @grammars.grammarOverridesByPath}
|
||||
@@ -831,12 +831,12 @@ class AtomEnvironment extends Model
|
||||
|
||||
@blobStore.save()
|
||||
|
||||
saveState: ->
|
||||
saveState: (options) ->
|
||||
return Promise.resolve() unless @enablePersistence
|
||||
|
||||
new Promise (resolve, reject) =>
|
||||
window.requestIdleCallback =>
|
||||
state = @serialize()
|
||||
state = @serialize(options)
|
||||
savePromise =
|
||||
if storageKey = @getStateKey(@project?.getPaths())
|
||||
@stateStore.save(storageKey, state)
|
||||
|
||||
@@ -54,7 +54,7 @@ class Project extends Model
|
||||
Section: Serialization
|
||||
###
|
||||
|
||||
deserialize: (state, deserializerManager) ->
|
||||
deserialize: (state) ->
|
||||
state.paths = [state.path] if state.path? # backward compatibility
|
||||
state.paths = state.paths.filter (directoryPath) -> fs.isDirectorySync(directoryPath)
|
||||
|
||||
@@ -66,15 +66,15 @@ class Project extends Model
|
||||
fs.closeSync(fs.openSync(bufferState.filePath, 'r'))
|
||||
catch error
|
||||
return unless error.code is 'ENOENT'
|
||||
deserializerManager.deserialize(bufferState)
|
||||
TextBuffer.deserialize(bufferState)
|
||||
|
||||
@subscribeToBuffer(buffer) for buffer in @buffers
|
||||
@setPaths(state.paths)
|
||||
|
||||
serialize: ->
|
||||
serialize: (options) ->
|
||||
deserializer: 'Project'
|
||||
paths: @getPaths()
|
||||
buffers: _.compact(@buffers.map (buffer) -> buffer.serialize() if buffer.isRetained())
|
||||
buffers: _.compact(@buffers.map (buffer) -> buffer.serialize({markerLayers: options.isUnloading is true}) if buffer.isRetained())
|
||||
|
||||
###
|
||||
Section: Event Subscription
|
||||
|
||||
@@ -24,16 +24,13 @@ class StateStore {
|
||||
}
|
||||
|
||||
save (key, value) {
|
||||
// Serialize values using JSON.stringify, as it seems way faster than IndexedDB structured clone.
|
||||
// (Ref.: https://bugs.chromium.org/p/chromium/issues/detail?id=536620)
|
||||
let jsonValue = JSON.stringify(value)
|
||||
return new Promise((resolve, reject) => {
|
||||
this.dbPromise.then(db => {
|
||||
if (db == null) resolve()
|
||||
|
||||
var request = db.transaction(['states'], 'readwrite')
|
||||
.objectStore('states')
|
||||
.put({value: jsonValue, storedAt: new Date().toString(), isJSON: true}, key)
|
||||
.put({value: value, storedAt: new Date().toString()}, key)
|
||||
|
||||
request.onsuccess = resolve
|
||||
request.onerror = reject
|
||||
@@ -52,9 +49,8 @@ class StateStore {
|
||||
|
||||
request.onsuccess = (event) => {
|
||||
let result = event.target.result
|
||||
if (result) {
|
||||
// TODO: remove this when state will be serialized only via JSON.
|
||||
resolve(result.isJSON ? JSON.parse(result.value) : result.value)
|
||||
if (result && !result.isJSON) {
|
||||
resolve(result.value)
|
||||
} else {
|
||||
resolve(null)
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ class WindowEventHandler
|
||||
@reloadRequested = false
|
||||
|
||||
@atomEnvironment.storeWindowDimensions()
|
||||
@atomEnvironment.saveState()
|
||||
@atomEnvironment.saveState({isUnloading: true})
|
||||
if confirmed
|
||||
@atomEnvironment.unloadEditorWindow()
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user