Skip to content

Commit

Permalink
Merge pull request #83 from basecamp/compose-current-attributes
Browse files Browse the repository at this point in the history
Compose current attributes
  • Loading branch information
javan committed Nov 5, 2015
2 parents af1dd1f + f9a9242 commit 4d31462
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 18 deletions.
23 changes: 16 additions & 7 deletions src/trix/controllers/input_controller.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -236,21 +236,30 @@ class Trix.InputController extends Trix.BasicObject
event.preventDefault()

compositionstart: (event) ->
@mutationObserver.stop()
unless @selectionIsExpanded()
textAdded = @responder?.insertPlaceholder()
@setInputSummary({textAdded})
@requestRender()

@setInputSummary(composing: true, compositionStart: event.data)

compositionupdate: (event) ->
if @responder?.selectPlaceholder()
@responder?.forgetPlaceholder()

@setInputSummary(composing: true, compositionUpdate: event.data)

compositionend: (event) ->
@mutationObserver.start()
composedString = event.data
@setInputSummary(composing: true, compositionEnd: composedString)
if @responder?.selectPlaceholder()
@responder?.forgetPlaceholder()

{compositionStart} = @inputSummary
{data} = event

if composedString? and composedString isnt @inputSummary.compositionStart
if compositionStart? and data? and compositionStart isnt data
@delegate?.inputControllerWillPerformTyping()
@responder?.insertString(composedString)
{added, removed} = summarizeStringChange(@inputSummary.compositionStart, composedString)
@responder?.insertString(data)
{added, removed} = summarizeStringChange(compositionStart, data)
@setInputSummary(textAdded: added, didDelete: Boolean(removed))

input: (event) ->
Expand Down
15 changes: 15 additions & 0 deletions src/trix/models/composition.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,21 @@ class Trix.Composition extends Trix.BasicObject
@removeCurrentAttribute(block.getLastAttribute())
@setSelection(startPosition)

placeholder = " "

insertPlaceholder: ->
@placeholderPosition = @getPosition()
@insertString(placeholder)
placeholder

selectPlaceholder: ->
if @placeholderPosition?
@setSelectedRange([@placeholderPosition, @placeholderPosition + placeholder.length])
true

forgetPlaceholder: ->
@placeholderPosition = null

# Current attributes

hasCurrentAttribute: (attributeName) ->
Expand Down
10 changes: 0 additions & 10 deletions test/src/system/basic_input_test.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@ editorTest "typing", (expectDocument) ->
typeCharacters "abc", ->
expectDocument "abc\n"

editorTest "composing", (expectDocument) ->
composeString "abc", ->
expectDocument "abc\n"

editorTest "typing and composing", (expectDocument) ->
typeCharacters "a", ->
composeString "bcd", ->
typeCharacters "e", ->
expectDocument "abcde\n"

editorTest "backspacing", (expectDocument) ->
typeCharacters "abc\b", ->
assertLocationRange(index: 0, offset: 2)
Expand Down
34 changes: 34 additions & 0 deletions test/src/system/composition_input_test.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
editorModule "Composition input", template: "editor_empty"

editorTest "composing", (expectDocument) ->
composeString "abc", ->
expectDocument "abc\n"

editorTest "typing and composing", (expectDocument) ->
typeCharacters "a", ->
composeString "bcd", ->
typeCharacters "e", ->
expectDocument "abcde\n"

editorTest "pressing return after a canceled composition", (expectDocument) ->
typeCharacters "ab", ->
triggerEvent document.activeElement, "compositionend", data: "ab"
pressKey "return", ->
expectDocument "ab\n\n"

editorTest "composing formatted text", (expectDocument) ->
typeCharacters "abc", ->
clickToolbarButton attribute: "bold", ->
composeString "def", ->
expectAttributes([0, 3], {})
expectAttributes([3, 6], bold: true)
expectDocument("abcdef\n")

editorTest "composing away from formatted text", (expectDocument) ->
clickToolbarButton attribute: "bold", ->
typeCharacters "abc", ->
clickToolbarButton attribute: "bold", ->
composeString "def", ->
expectAttributes([0, 3], bold: true)
expectAttributes([3, 6], {})
expectDocument("abcdef\n")
7 changes: 6 additions & 1 deletion test/src/test_helpers/input_helpers.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ for code, name of Trix.InputController.keyNames
insertNode(node, callback)
else
updated = true
compose(string.slice(0, index++), "update", continueComposition)
# The cursor doesn't acually move like this during a composition, but
# it can move and cause the location range and current attributes to change.
# Moving the cursor and then putting it back is enough exercise those changes.
moveCursor "left", ->
moveCursor "right", ->
compose(string.slice(0, index++), "update", continueComposition)
else
started = true
compose(string.slice(0, index++), "start", continueComposition)
Expand Down

0 comments on commit 4d31462

Please sign in to comment.