Update document edited status in workspace model

This also fixes a previous oversight where the status wasn’t updated
when switching between pane items with different modified status.
This commit is contained in:
Nathan Sobo 2014-09-24 17:00:05 -06:00
parent 28deb9dec5
commit ae488fc7fe
3 changed files with 66 additions and 21 deletions

View File

@ -426,3 +426,35 @@ describe "Workspace", ->
item = atom.workspace.getActivePaneItem()
expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPath()}"
workspace2.destroy()
describe "document edited status", ->
[item1, item2] = []
beforeEach ->
waitsForPromise -> atom.workspace.open('a')
waitsForPromise -> atom.workspace.open('b')
runs ->
[item1, item2] = atom.workspace.getPaneItems()
spyOn(atom, 'setDocumentEdited')
it "calls atom.setDocumentEdited when the active item changes", ->
expect(atom.workspace.getActivePaneItem()).toBe item2
item1.insertText('a')
expect(item1.isModified()).toBe true
atom.workspace.getActivePane().activateNextItem()
expect(atom.setDocumentEdited).toHaveBeenCalledWith(true)
it "calls atom.setDocumentEdited when the active item's modified status changes", ->
expect(atom.workspace.getActivePaneItem()).toBe item2
item2.insertText('a')
advanceClock(item2.getBuffer().getStoppedChangingDelay())
expect(item2.isModified()).toBe true
expect(atom.setDocumentEdited).toHaveBeenCalledWith(true)
item2.undo()
advanceClock(item2.getBuffer().getStoppedChangingDelay())
expect(item2.isModified()).toBe false
expect(atom.setDocumentEdited).toHaveBeenCalledWith(false)

View File

@ -107,8 +107,6 @@ class WorkspaceView extends View
@subscribe $(window), 'focus', (e) =>
@handleFocus(e) if document.activeElement is document.body
@on 'pane:active-item-modified-status-changed', '.active.pane', => @updateDocumentEdited()
@command 'application:about', -> ipc.send('command', 'application:about')
@command 'application:run-all-specs', -> ipc.send('command', 'application:run-all-specs')
@command 'application:run-benchmarks', -> ipc.send('command', 'application:run-benchmarks')
@ -344,12 +342,6 @@ class WorkspaceView extends View
confirmClose: ->
@model.confirmClose()
# On OS X, fades the application window's proxy icon when the current file
# has been modified.
updateDocumentEdited: ->
modified = @model.getActivePaneItem()?.isModified?() ? false
atom.setDocumentEdited(modified)
# Get all editor views.
#
# You should prefer {Workspace::getEditors} unless you absolutely need access

View File

@ -39,14 +39,13 @@ class Workspace extends Model
super
@emitter = new Emitter
@subscriptions = new CompositeDisposable
@openers = []
@viewRegistry ?= new ViewRegistry
@paneContainer ?= new PaneContainer({@viewRegistry})
@paneContainer.onDidDestroyPaneItem(@onPaneItemDestroyed)
@maintainWindowTitle()
@subscribeToActiveItem()
@registerOpener (filePath) =>
switch filePath
@ -121,18 +120,17 @@ class Workspace extends Model
message: "Commands installed."
detailedMessage: "The shell commands `atom` and `apm` are installed."
maintainWindowTitle: ->
subscribeToActiveItem: ->
@updateWindowTitle()
@updateDocumentEdited()
atom.project.on 'path-changed', @updateWindowTitle
titleSubscription = null
@subscribe @onDidChangeActivePaneItem (item) =>
@observeActivePaneItem (item) =>
@updateWindowTitle()
@updateDocumentEdited()
if titleSubscription?
@subscriptions.remove(titleSubscription)
titleSubscription.dispose()
titleSubscription = null
@activeItemSubscriptions?.dispose()
@activeItemSubscriptions = new CompositeDisposable
if typeof item?.onDidChangeTitle is 'function'
titleSubscription = item.onDidChangeTitle(@updateWindowTitle)
@ -141,7 +139,15 @@ class Workspace extends Model
unless typeof titleSubscription?.dispose is 'function'
titleSubscription = new Disposable => item.off('title-changed', @updateWindowTitle)
@subscriptions.add(titleSubscription) if titleSubscription?
if typeof item?.onDidChangeModified is 'function'
modifiedSubscription = item.onDidChangeModified(@updateDocumentEdited)
else if typeof item?.on? is 'function'
modifiedSubscription = item.on('modified-status-changed', @updateDocumentEdited)
unless typeof modifiedSubscription?.dispose is 'function'
modifiedSubscription = new Disposable => item.off('modified-status-changed', @updateDocumentEdited)
@activeItemSubscriptions.add(titleSubscription) if titleSubscription?
@activeItemSubscriptions.add(modifiedSubscription) if modifiedSubscription?
# Updates the application's title and proxy icon based on whichever file is
# open.
@ -157,6 +163,12 @@ class Workspace extends Model
document.title = 'untitled'
atom.setRepresentedFilename('')
# On OS X, fades the application window's proxy icon when the current file
# has been modified.
updateDocumentEdited: =>
modified = @getActivePaneItem()?.isModified?() ? false
atom.setDocumentEdited(modified)
###
Section: Event Subscription
###
@ -173,8 +185,8 @@ class Workspace extends Model
callback(textEditor) for textEditor in @getTextEditors()
@onDidAddTextEditor ({textEditor}) -> callback(textEditor)
# Essential: Invoke the given callback with all current and future panes items in
# the workspace.
# Essential: Invoke the given callback with all current and future panes items
# in the workspace.
#
# * `callback` {Function} to be called with current and future pane items.
# * `item` An item that is present in {::getPaneItems} at the time of
@ -192,6 +204,15 @@ class Workspace extends Model
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
onDidChangeActivePaneItem: (callback) -> @paneContainer.onDidChangeActivePaneItem(callback)
# Essential: Invoke the given callback with the current active pane item and
# with all future active pane items in the workspace.
#
# * `callback` {Function} to be called when the active pane item changes.
# * `item` The current active pane item.
#
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
observeActivePaneItem: (callback) -> @paneContainer.observeActivePaneItem(callback)
# Essential: Invoke the given callback whenever an item is opened. Unlike
# {::onDidAddPaneItem}, observers will be notified for items that are already
# present in the workspace when they are reopened.
@ -561,7 +582,7 @@ class Workspace extends Model
# Called by Model superclass when destroyed
destroyed: ->
@paneContainer.destroy()
@subscriptions.dispose()
@activeItemSubscriptions?.dispose()
###
Section: View Management