diff --git a/internal_packages/composer/lib/composer-view.jsx b/internal_packages/composer/lib/composer-view.jsx index c957293e2..c7b84e787 100644 --- a/internal_packages/composer/lib/composer-view.jsx +++ b/internal_packages/composer/lib/composer-view.jsx @@ -117,7 +117,7 @@ export default class ComposerView extends React.Component { _setupForProps({draft, session}) { this.setState({ - showQuotedText: Utils.isForwardedMessage(draft), + showQuotedText: DraftHelpers.isForwardedMessage(draft), }); // TODO: This is a dirty hack to save selection state into the undo/redo @@ -546,63 +546,6 @@ export default class ComposerView extends React.Component { Actions.selectAttachment({messageClientId: this.props.draft.clientId}); } - undo = (event) => { - event.preventDefault(); - event.stopPropagation(); - - const historyItem = this.undoManager.undo() || {}; - if (!historyItem.state) { - return; - } - - this._recoveredSelection = historyItem.currentSelection; - this._applyChanges(historyItem.state, {fromUndoManager: true}); - this._recoveredSelection = null; - } - - redo = (event) => { - event.preventDefault(); - event.stopPropagation(); - const historyItem = this.undoManager.redo() || {} - if (!historyItem.state) { - return; - } - this._recoveredSelection = historyItem.currentSelection; - this._applyChanges(historyItem.state, {fromUndoManager: true}); - this._recoveredSelection = null; - } - - _getSelections = () => { - const bodyComponent = this.refs[Fields.Body]; - return { - currentSelection: bodyComponent.getCurrentSelection ? bodyComponent.getCurrentSelection() : null, - previousSelection: bodyComponent.getPreviousSelection ? bodyComponent.getPreviousSelection() : null, - } - } - - _saveToHistory = (selections) => { - const {previousSelection, currentSelection} = selections || this._getSelections(); - - const historyItem = { - previousSelection, - currentSelection, - state: { - body: _.clone(this.props.draft.body), - subject: _.clone(this.props.draft.subject), - to: _.clone(this.props.draft.to), - cc: _.clone(this.props.draft.cc), - bcc: _.clone(this.props.draft.bcc), - }, - } - - const lastState = this.undoManager.current() - if (lastState) { - lastState.currentSelection = historyItem.previousSelection; - } - - this.undoManager.saveToHistory(historyItem); - } - render() { const dropCoverDisplay = this.state.isDropping ? 'block' : 'none'; diff --git a/internal_packages/composer/spec/quoted-text-spec.cjsx b/internal_packages/composer/spec/quoted-text-spec.cjsx index f671696b4..0bc291118 100644 --- a/internal_packages/composer/spec/quoted-text-spec.cjsx +++ b/internal_packages/composer/spec/quoted-text-spec.cjsx @@ -26,7 +26,7 @@ describe "Composer Quoted Text", -> @session = trigger: -> changes: - add: -> + add: jasmine.createSpy('changes.add') draft: => @draft afterEach -> @@ -58,10 +58,9 @@ describe "Composer Quoted Text", -> it "allows the text to update", -> textToAdd = "MORE TEXT!" - spyOn(@composer, "_applyChanges") expect(@$contentEditable.innerHTML).toBe @htmlNoQuote setHTML.call(@, textToAdd + @htmlNoQuote) - ev = @composer._applyChanges.mostRecentCall.args[0].body + ev = @session.changes.add.mostRecentCall.args[0].body expect(ev).toEqual(textToAdd + @htmlNoQuote) it 'should not render the quoted-text-control toggle', -> @@ -84,20 +83,18 @@ describe "Composer Quoted Text", -> it 'should display the quoted text', -> expect(@$contentEditable.innerHTML).toBe @htmlWithQuote - it "should call `_applyChanges` with the entire HTML string", -> + it "should call add changes with the entire HTML string", -> textToAdd = "MORE TEXT!" - spyOn(@composer, "_applyChanges") expect(@$contentEditable.innerHTML).toBe @htmlWithQuote setHTML.call(@, textToAdd + @htmlWithQuote) - ev = @composer._applyChanges.mostRecentCall.args[0].body + ev = @session.changes.add.mostRecentCall.args[0].body expect(ev).toEqual(textToAdd + @htmlWithQuote) it "should allow the quoted text to be changed", -> newText = 'Test NEW 1 HTML
QUOTE CHANGED!!!
' - spyOn(@composer, "_applyChanges") expect(@$contentEditable.innerHTML).toBe @htmlWithQuote setHTML.call(@, newText) - ev = @composer._applyChanges.mostRecentCall.args[0].body + ev = @session.changes.add.mostRecentCall.args[0].body expect(ev).toEqual(newText) describe 'quoted text control toggle button', -> @@ -125,22 +122,20 @@ describe "Composer Quoted Text", -> it 'should not display any quoted text', -> expect(@$contentEditable.innerHTML).toBe @htmlNoQuote - it "should let you change the text, and then append the quoted text part to the end before firing `_applyChanges`", -> + it "should let you change the text, and then append the quoted text part to the end before firing adding changes", -> textToAdd = "MORE TEXT!" - spyOn(@composer, "_applyChanges") expect(@$contentEditable.innerHTML).toBe @htmlNoQuote setHTML.call(@, textToAdd + @htmlNoQuote) - ev = @composer._applyChanges.mostRecentCall.args[0].body + ev = @session.changes.add.mostRecentCall.args[0].body # Note that we expect the version WITH a quote while setting the # version withOUT a quote. expect(ev).toEqual(wrapBody(textToAdd + @htmlWithQuote)) it "should let you add more html that looks like quoted text, and still properly appends the old quoted text", -> textToAdd = "Yo
I'm a fake quote
" - spyOn(@composer, "_applyChanges") expect(@$contentEditable.innerHTML).toBe @htmlNoQuote setHTML.call(@, textToAdd + @htmlNoQuote) - ev = @composer._applyChanges.mostRecentCall.args[0].body + ev = @session.changes.add.mostRecentCall.args[0].body # Note that we expect the version WITH a quote while setting the # version withOUT a quote. expect(ev).toEqual(wrapBody(textToAdd + @htmlWithQuote)) diff --git a/spec/stores/draft-editing-session-spec.coffee b/spec/stores/draft-editing-session-spec.coffee index 133840105..72ef6ac35 100644 --- a/spec/stores/draft-editing-session-spec.coffee +++ b/spec/stores/draft-editing-session-spec.coffee @@ -8,18 +8,22 @@ _ = require 'underscore' describe "DraftEditingSession Specs", -> - describe "DraftChangeSet", -> beforeEach -> - @triggerSpy = jasmine.createSpy('trigger') + @onDidAddChanges = jasmine.createSpy('onDidAddChanges') + @onWillAddChanges = jasmine.createSpy('onWillAddChanges') @commitResolve = null @commitResolves = [] - @commitSpy = jasmine.createSpy('commit').andCallFake => + @onCommit = jasmine.createSpy('commit').andCallFake => new Promise (resolve, reject) => @commitResolves.push(resolve) @commitResolve = resolve - @changeSet = new DraftChangeSet(@triggerSpy, @commitSpy) + @changeSet = new DraftChangeSet({ + onDidAddChanges: @onDidAddChanges, + onWillAddChanges: @onWillAddChanges, + onCommit: @onCommit, + }) @changeSet._pending = subject: 'Change to subject line' @@ -51,7 +55,7 @@ describe "DraftEditingSession Specs", -> @changeSet._pending = {} waitsForPromise => @changeSet.commit().then => - expect(@commitSpy).not.toHaveBeenCalled() + expect(@onCommit).not.toHaveBeenCalled() it "should move changes to the saving set", -> pendingBefore = _.extend({}, @changeSet._pending) @@ -257,8 +261,10 @@ describe "DraftEditingSession Specs", -> updatedDraft.pristine = false @session = new DraftEditingSession('client-id', pristineDraft) - @session._onDraftChanged(objectClass: 'message', objects: [updatedDraft]) - expect(@session.draftPristineBody()).toBe('Hiya') + waitsForPromise => + @session._draftPromise.then => + @session._onDraftChanged(objectClass: 'message', objects: [updatedDraft]) + expect(@session.draftPristineBody()).toBe('Hiya') describe "when the draft given to the session is not pristine", -> it "should return null", -> diff --git a/spec/undo-stack-spec.es6 b/spec/undo-stack-spec.es6 index edae1bdf3..a273b448a 100644 --- a/spec/undo-stack-spec.es6 +++ b/spec/undo-stack-spec.es6 @@ -11,9 +11,9 @@ describe("UndoStack", function UndoStackSpecs() { describe("undo", () => { it("can restore history items, and returns null when none are available", () => { - this.undoManager.saveToHistory("A") - this.undoManager.saveToHistory("B") - this.undoManager.saveToHistory("C") + this.undoManager.save("A") + this.undoManager.save("B") + this.undoManager.save("C") expect(this.undoManager.current()).toBe("C") expect(this.undoManager.undo()).toBe("B") expect(this.undoManager.current()).toBe("B") @@ -25,10 +25,10 @@ describe("UndoStack", function UndoStackSpecs() { it("limits the undo stack to the MAX_HISTORY_SIZE", () => { this.undoManager._MAX_STACK_SIZE = 3 - this.undoManager.saveToHistory("A") - this.undoManager.saveToHistory("B") - this.undoManager.saveToHistory("C") - this.undoManager.saveToHistory("D") + this.undoManager.save("A") + this.undoManager.save("B") + this.undoManager.save("C") + this.undoManager.save("D") expect(this.undoManager.current()).toBe("D") expect(this.undoManager.undo()).toBe("C") expect(this.undoManager.undo()).toBe("B") @@ -39,9 +39,9 @@ describe("UndoStack", function UndoStackSpecs() { describe("undo followed by redo", () => { it("can restore previously undone history items", () => { - this.undoManager.saveToHistory("A") - this.undoManager.saveToHistory("B") - this.undoManager.saveToHistory("C") + this.undoManager.save("A") + this.undoManager.save("B") + this.undoManager.save("C") expect(this.undoManager.current()).toBe("C") expect(this.undoManager.undo()).toBe("B") expect(this.undoManager.current()).toBe("B") @@ -50,12 +50,12 @@ describe("UndoStack", function UndoStackSpecs() { }); it("cannot be used after pushing additional items", () => { - this.undoManager.saveToHistory("A") - this.undoManager.saveToHistory("B") - this.undoManager.saveToHistory("C") + this.undoManager.save("A") + this.undoManager.save("B") + this.undoManager.save("C") expect(this.undoManager.current()).toBe("C") expect(this.undoManager.undo()).toBe("B") - this.undoManager.saveToHistory("D") + this.undoManager.save("D") expect(this.undoManager.redo()).toBe(null) expect(this.undoManager.current()).toBe("D") }); diff --git a/src/flux/stores/draft-editing-session.coffee b/src/flux/stores/draft-editing-session.coffee index 35f0f640e..9453690a9 100644 --- a/src/flux/stores/draft-editing-session.coffee +++ b/src/flux/stores/draft-editing-session.coffee @@ -4,7 +4,7 @@ NylasAPI = require '../nylas-api' AccountStore = require './account-store' ContactStore = require './contact-store' DatabaseStore = require './database-store' -UndoStack = require '../../undo-stack' +UndoStack = require('../../undo-stack').default DraftHelpers = require '../stores/draft-helpers' ExtensionRegistry = require '../../extension-registry' {Listener, Publisher} = require '../modules/reflux-coffee' diff --git a/src/undo-stack.es6 b/src/undo-stack.es6 index 6bf438ea2..7d3994c17 100644 --- a/src/undo-stack.es6 +++ b/src/undo-stack.es6 @@ -31,7 +31,7 @@ export default class UndoStack { Object.assign(this._accumulated, state); const shouldSnapshot = this._options.shouldSnapshot && this._options.shouldSnapshot(this.current(), this._accumulated); if (!this.current() || shouldSnapshot) { - this.saveToHistory(this._accumulated); + this.save(this._accumulated); this._accumulated = {}; } }