mirror of
https://github.com/wbbaddons/Tims-Chat.git
synced 2024-10-31 14:10:08 +00:00
Maximilian Mader
724540a8b2
Chrome on macOS sends a KeyEvent with `key` set to `Enter`, the keyCode `229` and `isComposing` set to `true` when pressing enter while a character composition sequence is active, then an event for the composed key and ends with a Enter key event with the correct key code. This has thrown our Enter key detection off and resulted in sending of the wanted message and a public message with the single composed character as content. Ignoring the Enter key while characters are being composed seems to be safe.
145 lines
3.5 KiB
JavaScript
145 lines
3.5 KiB
JavaScript
/*
|
|
* Copyright (c) 2010-2018 Tim Düsterhus.
|
|
*
|
|
* Use of this software is governed by the Business Source License
|
|
* included in the LICENSE file.
|
|
*
|
|
* Change Date: 2022-08-22
|
|
*
|
|
* On the date above, in accordance with the Business Source
|
|
* License, use of this software will be governed by version 2
|
|
* or later of the General Public License.
|
|
*/
|
|
|
|
define([ '../console'
|
|
, '../Helper'
|
|
, 'WoltLabSuite/Core/Core'
|
|
, 'WoltLabSuite/Core/Event/Key'
|
|
, '../DataStructure/EventEmitter'
|
|
, '../DataStructure/Throttle'
|
|
], function (console, Helper, Core, EventKey, EventEmitter, Throttle) {
|
|
"use strict";
|
|
|
|
class Input {
|
|
constructor() {
|
|
this.inputContainer = elById('chatInputContainer')
|
|
this.input = elBySel('textarea', this.inputContainer)
|
|
this.charCounter = elBySel('.charCounter', this.inputContainer)
|
|
this.errorElement = elBySel('.innerError', this.inputContainer)
|
|
}
|
|
|
|
bootstrap() {
|
|
if (typeof window.elInnerError === 'function') {
|
|
elRemove(this.errorElement)
|
|
}
|
|
|
|
this.input.addEventListener('keydown', this.handleInputKeyDown.bind(this))
|
|
this.input.addEventListener('input', Throttle(this.handleInput.bind(this)))
|
|
|
|
Helper.makeFlexible(this.input)
|
|
this.handleInput()
|
|
}
|
|
|
|
handleInput(event) {
|
|
this.charCounter.textContent = `${this.input.value.length} / ${this.input.getAttribute('maxlength')}`
|
|
this.emit('input')
|
|
}
|
|
|
|
handleInputKeyDown(event) {
|
|
if (EventKey.Enter(event) && !event.shiftKey) {
|
|
if (event.isComposing) {
|
|
console.debug('Ui/Input.handleInputKeyDown', 'Ignored Enter key while composing characters.')
|
|
return
|
|
}
|
|
|
|
// prevent generation of a new line
|
|
event.preventDefault()
|
|
|
|
if (this.getText().length === 0) return
|
|
|
|
const parameters = { cancel: false, input: this }
|
|
this.emit('beforeSubmit', parameters)
|
|
if (!parameters.cancel) {
|
|
this.emit('submit')
|
|
}
|
|
}
|
|
else if (EventKey.Tab(event)) {
|
|
// prevent leaving the input
|
|
event.preventDefault()
|
|
|
|
this.emit('autocomplete')
|
|
}
|
|
}
|
|
|
|
getText(raw = false) {
|
|
if (raw) {
|
|
return this.input.value
|
|
}
|
|
|
|
return this.input.value.trim()
|
|
}
|
|
|
|
select(start, end = undefined) {
|
|
if (end === undefined) end = this.getText(true).length
|
|
|
|
this.input.setSelectionRange(start, end)
|
|
}
|
|
|
|
focus() {
|
|
this.input.focus()
|
|
}
|
|
|
|
insertText(text, options) {
|
|
this.focus()
|
|
|
|
options = Object.assign({ append: true
|
|
, prepend: false
|
|
}, options)
|
|
|
|
if (!(options.append || options.prepend)) {
|
|
// replace
|
|
this.input.value = text
|
|
}
|
|
|
|
if (options.append) {
|
|
this.input.value += text;
|
|
}
|
|
|
|
if (options.prepend) {
|
|
this.input.value = text + this.input.value;
|
|
}
|
|
|
|
// always position caret at the end
|
|
const length = this.input.value.length
|
|
this.input.setSelectionRange(length, length)
|
|
|
|
Core.triggerEvent(this.input, 'input')
|
|
}
|
|
|
|
inputError(message) {
|
|
if (typeof window.elInnerError === 'function') {
|
|
elInnerError(this.inputContainer.firstElementChild, message)
|
|
}
|
|
else {
|
|
this.inputContainer.classList.add('formError')
|
|
this.errorElement.textContent = message
|
|
elShow(this.errorElement)
|
|
}
|
|
}
|
|
|
|
hideInputError() {
|
|
if (typeof window.elInnerError === 'function') {
|
|
elInnerError(this.inputContainer.firstElementChild, false)
|
|
}
|
|
else {
|
|
this.inputContainer.classList.remove('formError')
|
|
this.errorElement.textContent = ''
|
|
elHide(this.errorElement)
|
|
}
|
|
}
|
|
}
|
|
EventEmitter(Input.prototype)
|
|
|
|
return Input
|
|
});
|