// 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_emoticon * @copyright 2014 Frédéric Massart * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ /** * @module moodle-atto_emoticon-button */ var COMPONENTNAME = 'atto_emoticon', CSS = { EMOTE: 'atto_emoticon_emote', MAP: 'atto_emoticon_map' }, SELECTORS = { EMOTE: '.atto_emoticon_emote' }, TEMPLATE = '' + '
' + '' + '
'; /** * Atto text editor emoticon plugin. * * @namespace M.atto_emoticon * @class button * @extends M.editor_atto.EditorPlugin */ Y.namespace('M.atto_emoticon').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() { this.addButton({ icon: 'e/emoticons', callback: this._displayDialogue }); }, /** * Display the Emoticon chooser. * * @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('insertemoticon', COMPONENTNAME), focusAfterHide: true }, true); // Set the dialogue content, and then show the dialogue. dialogue.set('bodyContent', this._getDialogueContent()) .show(); }, /** * Insert the emoticon. * * @method _insertEmote * @param {EventFacade} e * @private */ _insertEmote: function(e) { var target = e.target.ancestor(SELECTORS.EMOTE, true), host = this.get('host'); e.preventDefault(); // Hide the dialogue. this.getDialogue({ focusAfterHide: null }).hide(); // Build the Emoticon text. var html = ' ' + target.getData('text') + ' '; // Focus on the previous selection. host.setSelection(this._currentSelection); // And add the character. host.insertContentAtFocusPoint(html); 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 template = Y.Handlebars.compile(TEMPLATE), content = Y.Node.create(template({ emoticons: this.get('emoticons'), CSS: CSS })); content.delegate('click', this._insertEmote, SELECTORS.EMOTE, this); content.delegate('key', this._insertEmote, '32', SELECTORS.EMOTE, this); return content; } }, { ATTRS: { /** * The list of emoticons to display. * * @attribute emoticons * @type array * @default {} */ emoticons: { value: {} } } });