Merge branch 'master' into ns-use-display-layers

This commit is contained in:
Nathan Sobo
2016-04-05 16:40:41 -06:00
3 changed files with 80 additions and 23 deletions

View File

@@ -77,12 +77,12 @@
"autocomplete-atom-api": "0.10.0",
"autocomplete-css": "0.11.0",
"autocomplete-html": "0.7.2",
"autocomplete-plus": "2.29.1",
"autocomplete-plus": "2.29.2",
"autocomplete-snippets": "1.10.0",
"autoflow": "0.27.0",
"autosave": "0.23.1",
"background-tips": "0.26.0",
"bookmarks": "0.38.2",
"bookmarks": "0.38.3",
"bracket-matcher": "0.82.0",
"command-palette": "0.38.0",
"deprecation-cop": "0.54.1",
@@ -107,7 +107,7 @@
"settings-view": "0.235.1",
"snippets": "1.0.2",
"spell-check": "0.67.0",
"status-bar": "1.2.0",
"status-bar": "1.2.1",
"styleguide": "0.45.2",
"symbols-view": "0.112.0",
"tabs": "0.92.0",
@@ -138,7 +138,7 @@
"language-php": "0.37.0",
"language-property-list": "0.8.0",
"language-python": "0.43.1",
"language-ruby": "0.68.4",
"language-ruby": "0.68.5",
"language-ruby-on-rails": "0.25.0",
"language-sass": "0.46.0",
"language-shellscript": "0.21.1",

View File

@@ -3747,6 +3747,21 @@ describe('TextEditorComponent', function () {
return event
}
function buildKeydownEvent ({keyCode, target}) {
let event = new KeyboardEvent('keydown')
Object.defineProperty(event, 'keyCode', {
get: function () {
return keyCode
}
})
Object.defineProperty(event, 'target', {
get: function () {
return target
}
})
return event
}
let inputNode
beforeEach(function () {
@@ -3769,11 +3784,12 @@ describe('TextEditorComponent', function () {
expect(editor.lineTextForBufferRow(0)).toBe('xyvar quicksort = function () {')
})
it('replaces the last character if the length of the input\'s value does not increase, as occurs with the accented character menu', async function () {
componentNode.dispatchEvent(buildTextInputEvent({
data: 'u',
target: inputNode
}))
it('replaces the last character if a keypress event is bracketed by keydown events with matching keyCodes, which occurs when the accented character menu is shown', async function () {
componentNode.dispatchEvent(buildKeydownEvent({keyCode: 85, target: inputNode}))
componentNode.dispatchEvent(buildTextInputEvent({data: 'u', target: inputNode}))
componentNode.dispatchEvent(new KeyboardEvent('keypress'))
componentNode.dispatchEvent(buildKeydownEvent({keyCode: 85, target: inputNode}))
componentNode.dispatchEvent(new KeyboardEvent('keyup'))
await nextViewUpdatePromise()
expect(editor.lineTextForBufferRow(0)).toBe('uvar quicksort = function () {')

View File

@@ -247,9 +247,50 @@ class TextEditorComponent
@scrollViewNode.addEventListener 'mousedown', @onMouseDown
@scrollViewNode.addEventListener 'scroll', @onScrollViewScroll
@detectAccentedCharacterMenu()
@listenForIMEEvents()
@trackSelectionClipboard() if process.platform is 'linux'
detectAccentedCharacterMenu: ->
# We need to get clever to detect when the accented character menu is
# opened on OS X. Usually, every keydown event that could cause input is
# followed by a corresponding keypress. However, pressing and holding
# long enough to open the accented character menu causes additional keydown
# events to fire that aren't followed by their own keypress and textInput
# events.
#
# Therefore, we assume the accented character menu has been deployed if,
# before observing any keyup event, we observe events in the following
# sequence:
#
# keydown(keyCode: X), keypress, keydown(keyCode: X)
#
# The keyCode X must be the same in the keydown events that bracket the
# keypress, meaning we're *holding* the _same_ key we intially pressed.
# Got that?
lastKeydown = null
lastKeydownBeforeKeypress = null
@domNode.addEventListener 'keydown', (event) =>
if lastKeydownBeforeKeypress
if lastKeydownBeforeKeypress.keyCode is event.keyCode
@openedAccentedCharacterMenu = true
lastKeydownBeforeKeypress = null
else
lastKeydown = event
@domNode.addEventListener 'keypress', =>
lastKeydownBeforeKeypress = lastKeydown
lastKeydown = null
# This cancels the accented character behavior if we type a key normally
# with the menu open.
@openedAccentedCharacterMenu = false
@domNode.addEventListener 'keyup', =>
lastKeydownBeforeKeypress = null
lastKeydown = null
listenForIMEEvents: ->
# The IME composition events work like this:
#
@@ -266,6 +307,9 @@ class TextEditorComponent
checkpoint = null
@domNode.addEventListener 'compositionstart', =>
if @openedAccentedCharacterMenu
@editor.selectLeft()
@openedAccentedCharacterMenu = false
checkpoint = @editor.createCheckpoint()
@domNode.addEventListener 'compositionupdate', (event) =>
@editor.insertText(event.data, select: true)
@@ -321,24 +365,21 @@ class TextEditorComponent
onTextInput: (event) =>
event.stopPropagation()
# If we prevent the insertion of a space character, then the browser
# interprets the spacebar keypress as a page-down command.
event.preventDefault() unless event.data is ' '
event.preventDefault()
return unless @isInputEnabled()
inputNode = event.target
# Workaround of the accented character suggestion feature in OS X.
# This will only occur when the user is not composing in IME mode.
# When the user selects a modified character from the OSX menu, `textInput`
# will occur twice, once for the initial character, and once for the
# modified character. However, only a single keypress will have fired. If
# this is the case, select backward to replace the original character.
if @openedAccentedCharacterMenu
@editor.selectLeft()
@openedAccentedCharacterMenu = false
# Work around of the accented character suggestion feature in OS X.
# Text input fires before a character is inserted, and if the browser is
# replacing the previous un-accented character with an accented variant, it
# will select backward over it.
selectedLength = inputNode.selectionEnd - inputNode.selectionStart
@editor.selectLeft() if selectedLength is 1
insertedRange = @editor.insertText(event.data, groupUndo: true)
inputNode.value = event.data if insertedRange
@editor.insertText(event.data, groupUndo: true)
onVerticalScroll: (scrollTop) =>
return if @updateRequested or scrollTop is @presenter.getScrollTop()