From 11786e6688f76e40bf40f90d15301f4eddfc422b Mon Sep 17 00:00:00 2001 From: Ryan Wyllie Date: Thu, 17 Oct 2019 15:44:01 +0800 Subject: [PATCH] MDL-46779 editor: add emoji picker atto plugin --- .../emojipicker/classes/privacy/provider.php | 46 ++++++ .../emojipicker/lang/en/atto_emojipicker.php | 27 ++++ lib/editor/atto/plugins/emojipicker/lib.php | 48 ++++++ .../atto/plugins/emojipicker/styles.css | 8 + .../atto/plugins/emojipicker/version.php | 29 ++++ .../moodle-atto_emojipicker-button-debug.js | 140 ++++++++++++++++++ .../moodle-atto_emojipicker-button-min.js | 1 + .../moodle-atto_emojipicker-button.js | 140 ++++++++++++++++++ .../emojipicker/yui/src/button/build.json | 10 ++ .../emojipicker/yui/src/button/js/button.js | 135 +++++++++++++++++ .../yui/src/button/meta/button.json | 7 + 11 files changed, 591 insertions(+) create mode 100644 lib/editor/atto/plugins/emojipicker/classes/privacy/provider.php create mode 100644 lib/editor/atto/plugins/emojipicker/lang/en/atto_emojipicker.php create mode 100644 lib/editor/atto/plugins/emojipicker/lib.php create mode 100644 lib/editor/atto/plugins/emojipicker/styles.css create mode 100644 lib/editor/atto/plugins/emojipicker/version.php create mode 100644 lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button-debug.js create mode 100644 lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button-min.js create mode 100644 lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button.js create mode 100644 lib/editor/atto/plugins/emojipicker/yui/src/button/build.json create mode 100644 lib/editor/atto/plugins/emojipicker/yui/src/button/js/button.js create mode 100644 lib/editor/atto/plugins/emojipicker/yui/src/button/meta/button.json diff --git a/lib/editor/atto/plugins/emojipicker/classes/privacy/provider.php b/lib/editor/atto/plugins/emojipicker/classes/privacy/provider.php new file mode 100644 index 00000000000..308bf19c07b --- /dev/null +++ b/lib/editor/atto/plugins/emojipicker/classes/privacy/provider.php @@ -0,0 +1,46 @@ +. + +/** + * Privacy Subsystem implementation for atto_emojipicker. + * + * @package atto_emojipicker + * @copyright 2019 Ryan Wyllie + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace atto_emojipicker\privacy; + +defined('MOODLE_INTERNAL') || die(); + +/** + * Privacy Subsystem for atto_emojipicker implementing null_provider. + * + * @copyright 2019 Ryan Wyllie + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class provider implements \core_privacy\local\metadata\null_provider { + + /** + * Get the language string identifier with the component's language + * file to explain why this plugin stores no data. + * + * @return string + */ + public static function get_reason() : string { + return 'privacy:metadata'; + } +} diff --git a/lib/editor/atto/plugins/emojipicker/lang/en/atto_emojipicker.php b/lib/editor/atto/plugins/emojipicker/lang/en/atto_emojipicker.php new file mode 100644 index 00000000000..91e41183fa4 --- /dev/null +++ b/lib/editor/atto/plugins/emojipicker/lang/en/atto_emojipicker.php @@ -0,0 +1,27 @@ +. + +/** + * Strings for component 'atto_emojipicker', language 'en'. + * + * @package atto_emojipicker + * @copyright 2019 Ryan Wyllie + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$string['emojipicker'] = 'Emoji picker'; +$string['pluginname'] = 'Emoji Picker'; +$string['privacy:metadata'] = 'The atto_emojipicker plugin does not store any personal data.'; diff --git a/lib/editor/atto/plugins/emojipicker/lib.php b/lib/editor/atto/plugins/emojipicker/lib.php new file mode 100644 index 00000000000..2c50535b780 --- /dev/null +++ b/lib/editor/atto/plugins/emojipicker/lib.php @@ -0,0 +1,48 @@ +. + +/** + * Atto text editor emoji picker plugin lib. + * + * @package atto_emojipicker + * @copyright 2019 Ryan Wyllie + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Initialise the strings required for JS. + * + * @return void + */ +function atto_emojipicker_strings_for_js() { + global $PAGE; + $PAGE->requires->strings_for_js(['emojipicker'], 'atto_emojipicker'); +} + +/** + * Sends the parameters to JS module. + * + * @return array + */ +function atto_emojipicker_params_for_js() { + global $CFG; + + return [ + 'disabled' => empty($CFG->allowemojipicker) ? true : false + ]; +} diff --git a/lib/editor/atto/plugins/emojipicker/styles.css b/lib/editor/atto/plugins/emojipicker/styles.css new file mode 100644 index 00000000000..34278fe0d64 --- /dev/null +++ b/lib/editor/atto/plugins/emojipicker/styles.css @@ -0,0 +1,8 @@ +.emoji-picker-dialogue.moodle-dialogue-base .moodle-dialogue .moodle-dialogue-bd { + padding: 0; +} + +.emoji-picker-dialogue .emoji-picker { + box-shadow: none !important; /* stylelint-disable-line declaration-no-important */ + border: 0; +} \ No newline at end of file diff --git a/lib/editor/atto/plugins/emojipicker/version.php b/lib/editor/atto/plugins/emojipicker/version.php new file mode 100644 index 00000000000..c569f25e36d --- /dev/null +++ b/lib/editor/atto/plugins/emojipicker/version.php @@ -0,0 +1,29 @@ +. + +/** + * Atto text editor emoji picker plugin version file. + * + * @package atto_emojipicker + * @copyright 2019 Ryan Wyllie + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$plugin->version = 2019101700; // The current plugin version (Date: YYYYMMDDXX). +$plugin->requires = 2019101200; // Requires this Moodle version. +$plugin->component = 'atto_emojipicker'; // Full name of the plugin (used for diagnostics). diff --git a/lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button-debug.js b/lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button-debug.js new file mode 100644 index 00000000000..059c96a1539 --- /dev/null +++ b/lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button-debug.js @@ -0,0 +1,140 @@ +YUI.add('moodle-atto_emojipicker-button', function (Y, NAME) { + +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/* + * @package atto_emojipicker + * @copyright 2019 Ryan Wyllie + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * @module moodle-atto_emojipicker-button + */ +var COMPONENTNAME = 'atto_emojipicker'; + +/** + * Atto text editor emoji picker plugin. + * + * @namespace M.atto_emojipicker + * @class button + * @extends M.editor_atto.EditorPlugin + */ + +Y.namespace('M.atto_emojipicker').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { + + /** + * A reference to the current selection at the time that the dialogue + * was opened. + * + * @property _currentSelection + * @type Range + * @private + */ + _currentSelection: null, + + initializer: function() { + if (this.get('disabled')) { + return; + } + + this.addButton({ + icon: 'e/emoticons', + callback: this._displayDialogue + }); + }, + + /** + * Display the emoji picker. + * + * @method _displayDialogue + * @private + */ + _displayDialogue: function() { + // Store the current selection. + this._currentSelection = this.get('host').getSelection(); + if (this._currentSelection === false) { + return; + } + + var dialogue = this.getDialogue({ + headerContent: M.util.get_string('emojipicker', COMPONENTNAME), + width: 'auto', + focusAfterHide: true, + additionalBaseClass: 'emoji-picker-dialogue' + }, true); + + // Set the dialogue content, and then show the dialogue. + dialogue.set('bodyContent', this._getDialogueContent()) + .show(); + }, + + /** + * Insert the emoticon. + * + * @method _insertEmote + * @param {String} emoji + * @private + */ + _insertEmoji: function(emoji) { + var host = this.get('host'); + + // Hide the dialogue. + this.getDialogue({ + focusAfterHide: null + }).hide(); + + // Focus on the previous selection. + host.setSelection(this._currentSelection); + + // And add the character. + host.insertContentAtFocusPoint(emoji); + + this.markUpdated(); + }, + + /** + * Generates the content of the dialogue, attaching event listeners to + * the content. + * + * @method _getDialogueContent + * @return {Node} Node containing the dialogue content + * @private + */ + _getDialogueContent: function() { + var wrapper = Y.Node.create('
'); + + require(['core/templates', 'core/emoji/picker'], function(Templates, initialiseEmojiPicker) { + Templates.render('core/emoji/picker', {}).then(function(html) { + var domNode = wrapper.getDOMNode(); + domNode.innerHTML = html; + initialiseEmojiPicker(domNode, this._insertEmoji.bind(this)); + this.getDialogue().centerDialogue(); + }.bind(this)); + }.bind(this)); + + return wrapper; + } +}, { + ATTRS: { + disabled: { + value: true + } + } +}); + + +}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]}); diff --git a/lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button-min.js b/lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button-min.js new file mode 100644 index 00000000000..e4293f0255d --- /dev/null +++ b/lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button-min.js @@ -0,0 +1 @@ +YUI.add("moodle-atto_emojipicker-button",function(e,t){var n="atto_emojipicker";e.namespace("M.atto_emojipicker").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_currentSelection:null,initializer:function(){if(this.get("disabled"))return;this.addButton({icon:"e/emoticons",callback:this._displayDialogue})},_displayDialogue:function(){this._currentSelection=this.get("host").getSelection();if(this._currentSelection===!1)return;var e=this.getDialogue({headerContent:M.util.get_string("emojipicker",n),width:"auto",focusAfterHide:!0,additionalBaseClass:"emoji-picker-dialogue"},!0);e.set("bodyContent",this._getDialogueContent()).show()},_insertEmoji:function(e){var t=this.get("host");this.getDialogue({focusAfterHide:null}).hide(),t.setSelection(this._currentSelection),t.insertContentAtFocusPoint(e),this.markUpdated()},_getDialogueContent:function(){var t=e.Node.create("
");return require(["core/templates","core/emoji/picker"],function(e,n){e.render("core/emoji/picker",{}).then(function(e){var r=t.getDOMNode();r.innerHTML=e,n(r,this._insertEmoji.bind(this)),this.getDialogue().centerDialogue()}.bind(this))}.bind(this)),t}},{ATTRS:{disabled:{value:!0}}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]}); diff --git a/lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button.js b/lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button.js new file mode 100644 index 00000000000..059c96a1539 --- /dev/null +++ b/lib/editor/atto/plugins/emojipicker/yui/build/moodle-atto_emojipicker-button/moodle-atto_emojipicker-button.js @@ -0,0 +1,140 @@ +YUI.add('moodle-atto_emojipicker-button', function (Y, NAME) { + +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/* + * @package atto_emojipicker + * @copyright 2019 Ryan Wyllie + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * @module moodle-atto_emojipicker-button + */ +var COMPONENTNAME = 'atto_emojipicker'; + +/** + * Atto text editor emoji picker plugin. + * + * @namespace M.atto_emojipicker + * @class button + * @extends M.editor_atto.EditorPlugin + */ + +Y.namespace('M.atto_emojipicker').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { + + /** + * A reference to the current selection at the time that the dialogue + * was opened. + * + * @property _currentSelection + * @type Range + * @private + */ + _currentSelection: null, + + initializer: function() { + if (this.get('disabled')) { + return; + } + + this.addButton({ + icon: 'e/emoticons', + callback: this._displayDialogue + }); + }, + + /** + * Display the emoji picker. + * + * @method _displayDialogue + * @private + */ + _displayDialogue: function() { + // Store the current selection. + this._currentSelection = this.get('host').getSelection(); + if (this._currentSelection === false) { + return; + } + + var dialogue = this.getDialogue({ + headerContent: M.util.get_string('emojipicker', COMPONENTNAME), + width: 'auto', + focusAfterHide: true, + additionalBaseClass: 'emoji-picker-dialogue' + }, true); + + // Set the dialogue content, and then show the dialogue. + dialogue.set('bodyContent', this._getDialogueContent()) + .show(); + }, + + /** + * Insert the emoticon. + * + * @method _insertEmote + * @param {String} emoji + * @private + */ + _insertEmoji: function(emoji) { + var host = this.get('host'); + + // Hide the dialogue. + this.getDialogue({ + focusAfterHide: null + }).hide(); + + // Focus on the previous selection. + host.setSelection(this._currentSelection); + + // And add the character. + host.insertContentAtFocusPoint(emoji); + + this.markUpdated(); + }, + + /** + * Generates the content of the dialogue, attaching event listeners to + * the content. + * + * @method _getDialogueContent + * @return {Node} Node containing the dialogue content + * @private + */ + _getDialogueContent: function() { + var wrapper = Y.Node.create('
'); + + require(['core/templates', 'core/emoji/picker'], function(Templates, initialiseEmojiPicker) { + Templates.render('core/emoji/picker', {}).then(function(html) { + var domNode = wrapper.getDOMNode(); + domNode.innerHTML = html; + initialiseEmojiPicker(domNode, this._insertEmoji.bind(this)); + this.getDialogue().centerDialogue(); + }.bind(this)); + }.bind(this)); + + return wrapper; + } +}, { + ATTRS: { + disabled: { + value: true + } + } +}); + + +}, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]}); diff --git a/lib/editor/atto/plugins/emojipicker/yui/src/button/build.json b/lib/editor/atto/plugins/emojipicker/yui/src/button/build.json new file mode 100644 index 00000000000..0a50ee9297d --- /dev/null +++ b/lib/editor/atto/plugins/emojipicker/yui/src/button/build.json @@ -0,0 +1,10 @@ +{ + "name": "moodle-atto_emojipicker-button", + "builds": { + "moodle-atto_emojipicker-button": { + "jsfiles": [ + "button.js" + ] + } + } +} diff --git a/lib/editor/atto/plugins/emojipicker/yui/src/button/js/button.js b/lib/editor/atto/plugins/emojipicker/yui/src/button/js/button.js new file mode 100644 index 00000000000..be0c29ec6d3 --- /dev/null +++ b/lib/editor/atto/plugins/emojipicker/yui/src/button/js/button.js @@ -0,0 +1,135 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/* + * @package atto_emojipicker + * @copyright 2019 Ryan Wyllie + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * @module moodle-atto_emojipicker-button + */ +var COMPONENTNAME = 'atto_emojipicker'; + +/** + * Atto text editor emoji picker plugin. + * + * @namespace M.atto_emojipicker + * @class button + * @extends M.editor_atto.EditorPlugin + */ + +Y.namespace('M.atto_emojipicker').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { + + /** + * A reference to the current selection at the time that the dialogue + * was opened. + * + * @property _currentSelection + * @type Range + * @private + */ + _currentSelection: null, + + initializer: function() { + if (this.get('disabled')) { + return; + } + + this.addButton({ + icon: 'e/emoticons', + callback: this._displayDialogue + }); + }, + + /** + * Display the emoji picker. + * + * @method _displayDialogue + * @private + */ + _displayDialogue: function() { + // Store the current selection. + this._currentSelection = this.get('host').getSelection(); + if (this._currentSelection === false) { + return; + } + + var dialogue = this.getDialogue({ + headerContent: M.util.get_string('emojipicker', COMPONENTNAME), + width: 'auto', + focusAfterHide: true, + additionalBaseClass: 'emoji-picker-dialogue' + }, true); + + // Set the dialogue content, and then show the dialogue. + dialogue.set('bodyContent', this._getDialogueContent()) + .show(); + }, + + /** + * Insert the emoticon. + * + * @method _insertEmote + * @param {String} emoji + * @private + */ + _insertEmoji: function(emoji) { + var host = this.get('host'); + + // Hide the dialogue. + this.getDialogue({ + focusAfterHide: null + }).hide(); + + // Focus on the previous selection. + host.setSelection(this._currentSelection); + + // And add the character. + host.insertContentAtFocusPoint(emoji); + + this.markUpdated(); + }, + + /** + * Generates the content of the dialogue, attaching event listeners to + * the content. + * + * @method _getDialogueContent + * @return {Node} Node containing the dialogue content + * @private + */ + _getDialogueContent: function() { + var wrapper = Y.Node.create('
'); + + require(['core/templates', 'core/emoji/picker'], function(Templates, initialiseEmojiPicker) { + Templates.render('core/emoji/picker', {}).then(function(html) { + var domNode = wrapper.getDOMNode(); + domNode.innerHTML = html; + initialiseEmojiPicker(domNode, this._insertEmoji.bind(this)); + this.getDialogue().centerDialogue(); + }.bind(this)); + }.bind(this)); + + return wrapper; + } +}, { + ATTRS: { + disabled: { + value: true + } + } +}); diff --git a/lib/editor/atto/plugins/emojipicker/yui/src/button/meta/button.json b/lib/editor/atto/plugins/emojipicker/yui/src/button/meta/button.json new file mode 100644 index 00000000000..9ea3e8152ac --- /dev/null +++ b/lib/editor/atto/plugins/emojipicker/yui/src/button/meta/button.json @@ -0,0 +1,7 @@ +{ + "moodle-atto_emojipicker-button": { + "requires": [ + "moodle-editor_atto-plugin" + ] + } +}