From 590cafbe734202ca00e779dfa39f6241caf55b8c Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Tue, 12 Mar 2019 16:46:17 +0100 Subject: [PATCH] WAI-ARIA compliant smiley interaction See #2713 --- .../templates/__messageFormSmilies.tpl | 6 +- .../templates/messageFormSmilies.tpl | 4 +- .../acp/templates/__messageFormSmilies.tpl | 6 +- .../acp/templates/messageFormSmilies.tpl | 4 +- wcfsetup/install/files/js/WCF.Message.js | 36 +------ .../js/WoltLabSuite/Core/Ui/Smiley/Insert.js | 97 +++++++++++++++++++ 6 files changed, 111 insertions(+), 42 deletions(-) create mode 100644 wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Smiley/Insert.js diff --git a/com.woltlab.wcf/templates/__messageFormSmilies.tpl b/com.woltlab.wcf/templates/__messageFormSmilies.tpl index bb49b5f545..bb35e8e2e4 100644 --- a/com.woltlab.wcf/templates/__messageFormSmilies.tpl +++ b/com.woltlab.wcf/templates/__messageFormSmilies.tpl @@ -1,5 +1,5 @@ \ No newline at end of file + diff --git a/com.woltlab.wcf/templates/messageFormSmilies.tpl b/com.woltlab.wcf/templates/messageFormSmilies.tpl index d81a8feb2d..cf632e523a 100644 --- a/com.woltlab.wcf/templates/messageFormSmilies.tpl +++ b/com.woltlab.wcf/templates/messageFormSmilies.tpl @@ -42,8 +42,8 @@ {event name='fields'} diff --git a/wcfsetup/install/files/acp/templates/__messageFormSmilies.tpl b/wcfsetup/install/files/acp/templates/__messageFormSmilies.tpl index bb49b5f545..bb35e8e2e4 100644 --- a/wcfsetup/install/files/acp/templates/__messageFormSmilies.tpl +++ b/wcfsetup/install/files/acp/templates/__messageFormSmilies.tpl @@ -1,5 +1,5 @@ \ No newline at end of file + diff --git a/wcfsetup/install/files/acp/templates/messageFormSmilies.tpl b/wcfsetup/install/files/acp/templates/messageFormSmilies.tpl index ae7276dd2b..a5d0d5250f 100644 --- a/wcfsetup/install/files/acp/templates/messageFormSmilies.tpl +++ b/wcfsetup/install/files/acp/templates/messageFormSmilies.tpl @@ -48,8 +48,8 @@ {event name='fields'} diff --git a/wcfsetup/install/files/js/WCF.Message.js b/wcfsetup/install/files/js/WCF.Message.js index a39bfc78d2..94fede9a15 100644 --- a/wcfsetup/install/files/js/WCF.Message.js +++ b/wcfsetup/install/files/js/WCF.Message.js @@ -683,41 +683,13 @@ if (COMPILER_TARGET_DEFAULT) { }); /** - * Handles smiley clicks. - * - * @param string wysiwygSelector + * @deprecated 5.2 Use `WoltLabSuite/Core/Ui/Smiley/Insert` instead. */ WCF.Message.Smilies = Class.extend({ - /** - * wysiwyg editor id - * @var string - */ - _editorId: '', - - /** - * Initializes the smiley handler. - * - * @param {string} editorId - */ init: function (editorId) { - this._editorId = editorId; - - $('.messageTabMenu[data-wysiwyg-container-id=' + this._editorId + ']').on('mousedown', '.jsSmiley', this._smileyClick.bind(this)); - }, - - /** - * Handles tab smiley clicks. - * - * @param {Event} event - */ - _smileyClick: function (event) { - event.preventDefault(); - - require(['EventHandler'], (function (EventHandler) { - EventHandler.fire('com.woltlab.wcf.redactor2', 'insertSmiley_' + this._editorId, { - img: event.currentTarget.children[0] - }); - }).bind(this)); + require(['WoltLabSuite/Core/Ui/Smiley/Insert'], function(UiSmileyInsert) { + new UiSmileyInsert(editorId); + }); } }); diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Smiley/Insert.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Smiley/Insert.js new file mode 100644 index 0000000000..bfe42a179b --- /dev/null +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Smiley/Insert.js @@ -0,0 +1,97 @@ +/** + * Inserts smilies into a WYSIWYG editor instance, with WAI-ARIA keyboard support. + * + * @author Alexander Ebert + * @copyright 2001-2019 WoltLab GmbH + * @license GNU Lesser General Public License + * @module WoltLabSuite/Core/Ui/Smiley/Insert + */ +define(['EventHandler', 'EventKey'], function (EventHandler, EventKey) { + 'use strict'; + + function UiSmileyInsert(editorId) { this.init(editorId); } + + UiSmileyInsert.prototype = { + _editorId: '', + + /** + * @param {string} editorId + */ + init: function (editorId) { + this._editorId = editorId; + + var container = elBySel('.messageTabMenu[data-wysiwyg-container-id=' + this._editorId + ']'); + if (!container) { + throw new Error('Unable to find the message tab menu container containing the smilies.'); + } + + container.addEventListener('keydown', this._keydown.bind(this)); + container.addEventListener('mousedown', this._mousedown.bind(this)); + }, + + /** + * @param {KeyboardEvent} event + * @protected + */ + _keydown: function(event) { + var activeButton = document.activeElement; + if (!activeButton.classList.contains('jsSmiley')) { + return; + } + + if (EventKey.ArrowLeft(event) || EventKey.ArrowRight(event) || EventKey.Home(event) || EventKey.End(event)) { + event.preventDefault(); + + var smilies = Array.prototype.slice.call(elBySelAll('.jsSmiley', event.currentTarget)); + if (EventKey.ArrowLeft(event)) { + smilies.reverse(); + } + + var index = smilies.indexOf(activeButton); + if (EventKey.Home(event)) { + index = 0; + } + else if (EventKey.End(event)) { + index = smilies.length - 1; + } + else { + index = index + 1; + if (index === smilies.length) { + index = 0; + } + } + + smilies[index].focus(); + } + else if (EventKey.Enter(event) || EventKey.Space(event)) { + event.preventDefault(); + + this._insert(elBySel('img', activeButton)); + } + }, + + /** + * @param {MouseEvent} event + * @protected + */ + _mousedown: function (event) { + event.preventDefault(); + + // Clicks may occur on a few different elements, but we are only looking for the image. + var listItem = event.target.closest('li'); + var img = elBySel('img', listItem); + if (img) this._insert(img); + }, + + /** + * @param {Element} img + * @protected + */ + _insert: function(img) { + EventHandler.fire('com.woltlab.wcf.redactor2', 'insertSmiley_' + this._editorId, { + img: img + }); + } + }; + return UiSmileyInsert; +}); -- 2.20.1