MDL-64506 templates: Move BS2 btns' to BS4 btns'
[moodle.git] / lib / editor / atto / plugins / charmap / yui / src / button / js / button.js
1 // This file is part of Moodle - http://moodle.org/
2 //
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16 /*
17  * @package    atto_charmap
18  * @copyright  2014 Frédéric Massart
19  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
20  */
22 /**
23  * Atto text editor character map plugin
24  *
25  * @module moodle-atto_charmap-button
26  */
28 var COMPONENTNAME = 'atto_charmap',
29     CSS = {
30         BUTTON: 'atto_charmap_character',
31         CHARMAP: 'atto_charmap_selector'
32     },
33     /*
34      * Map of special characters, kindly borrowed from TinyMCE.
35      *
36      * Each entries contains in order:
37      * - {String} HTML code
38      * - {String} HTML numerical code
39      * - {Boolean} Whether or not to include it in the list
40      * - {String} The language string key
41      *
42      * @property CHARMAP
43      * @type {Array}
44      */
45     CHARMAP = [
46         ['&nbsp;', '&#160;', true, 'nobreakspace'],
47         ['&amp;', '&#38;', true, 'ampersand'],
48         ['&quot;', '&#34;', true, 'quotationmark'],
49         ['&#8253;', '&#8253;', true, 'interrobang'],
50         // Finance.
51         ['&cent;', '&#162;', true, 'centsign'],
52         ['&euro;', '&#8364;', true, 'eurosign'],
53         ['&pound;', '&#163;', true, 'poundsign'],
54         ['&yen;', '&#165;', true, 'yensign'],
55         // Signs.
56         ['&copy;', '&#169;', true, 'copyrightsign'],
57         ['&reg;', '&#174;', true, 'registeredsign'],
58         ['&trade;', '&#8482;', true, 'trademarksign'],
59         ['&permil;', '&#8240;', true, 'permillesign'],
60         ['&micro;', '&#181;', true, 'microsign'],
61         ['&middot;', '&#183;', true, 'middledot'],
62         ['&bull;', '&#8226;', true, 'bullet'],
63         ['&hellip;', '&#8230;', true, 'threedotleader'],
64         ['&prime;', '&#8242;', true, 'minutesfeet'],
65         ['&Prime;', '&#8243;', true, 'secondsinches'],
66         ['&sect;', '&#167;', true, 'sectionsign'],
67         ['&para;', '&#182;', true, 'paragraphsign'],
68         ['&szlig;', '&#223;', true, 'sharpsesszed'],
69         // Quotations.
70         ['&lsaquo;', '&#8249;', true, 'singleleftpointinganglequotationmark'],
71         ['&rsaquo;', '&#8250;', true, 'singlerightpointinganglequotationmark'],
72         ['&laquo;', '&#171;', true, 'leftpointingguillemet'],
73         ['&raquo;', '&#187;', true, 'rightpointingguillemet'],
74         ['&lsquo;', '&#8216;', true, 'leftsinglequotationmark'],
75         ['&rsquo;', '&#8217;', true, 'rightsinglequotationmark'],
76         ['&ldquo;', '&#8220;', true, 'leftdoublequotationmark'],
77         ['&rdquo;', '&#8221;', true, 'rightdoublequotationmark'],
78         ['&sbquo;', '&#8218;', true, 'singlelow9quotationmark'],
79         ['&bdquo;', '&#8222;', true, 'doublelow9quotationmark'],
80         ['&lt;', '&#60;', true, 'lessthansign'],
81         ['&gt;', '&#62;', true, 'greaterthansign'],
82         ['&le;', '&#8804;', true, 'lessthanorequalto'],
83         ['&ge;', '&#8805;', true, 'greaterthanorequalto'],
84         ['&ndash;', '&#8211;', true, 'endash'],
85         ['&mdash;', '&#8212;', true, 'emdash'],
86         ['&macr;', '&#175;', true, 'macron'],
87         ['&oline;', '&#8254;', true, 'overline'],
88         ['&curren;', '&#164;', true, 'currencysign'],
89         ['&brvbar;', '&#166;', true, 'brokenbar'],
90         ['&uml;', '&#168;', true, 'diaeresis'],
91         ['&iexcl;', '&#161;', true, 'invertedexclamationmark'],
92         ['&iquest;', '&#191;', true, 'turnedquestionmark'],
93         ['&circ;', '&#710;', true, 'circumflexaccent'],
94         ['&tilde;', '&#732;', true, 'smalltilde'],
95         ['&deg;', '&#176;', true, 'degreesign'],
96         ['&minus;', '&#8722;', true, 'minussign'],
97         ['&plusmn;', '&#177;', true, 'plusminussign'],
98         ['&divide;', '&#247;', true, 'divisionsign'],
99         ['&frasl;', '&#8260;', true, 'fractionslash'],
100         ['&times;', '&#215;', true, 'multiplicationsign'],
101         ['&sup1;', '&#185;', true, 'superscriptone'],
102         ['&sup2;', '&#178;', true, 'superscripttwo'],
103         ['&sup3;', '&#179;', true, 'superscriptthree'],
104         ['&frac14;', '&#188;', true, 'fractiononequarter'],
105         ['&frac12;', '&#189;', true, 'fractiononehalf'],
106         ['&frac34;', '&#190;', true, 'fractionthreequarters'],
107         // Math / logical.
108         ['&fnof;', '&#402;', true, 'functionflorin'],
109         ['&int;', '&#8747;', true, 'integral'],
110         ['&sum;', '&#8721;', true, 'narysumation'],
111         ['&infin;', '&#8734;', true, 'infinity'],
112         ['&radic;', '&#8730;', true, 'squareroot'],
113         ['&sim;', '&#8764;', false, 'similarto'],
114         ['&cong;', '&#8773;', false, 'approximatelyequalto'],
115         ['&asymp;', '&#8776;', true, 'almostequalto'],
116         ['&ne;', '&#8800;', true, 'notequalto'],
117         ['&equiv;', '&#8801;', true, 'identicalto'],
118         ['&isin;', '&#8712;', false, 'elementof'],
119         ['&notin;', '&#8713;', false, 'notanelementof'],
120         ['&ni;', '&#8715;', false, 'containsasmember'],
121         ['&prod;', '&#8719;', true, 'naryproduct'],
122         ['&and;', '&#8743;', false, 'logicaland'],
123         ['&or;', '&#8744;', false, 'logicalor'],
124         ['&not;', '&#172;', true, 'notsign'],
125         ['&cap;', '&#8745;', true, 'intersection'],
126         ['&cup;', '&#8746;', false, 'union'],
127         ['&part;', '&#8706;', true, 'partialdifferential'],
128         ['&forall;', '&#8704;', false, 'forall'],
129         ['&exist;', '&#8707;', false, 'thereexists'],
130         ['&empty;', '&#8709;', false, 'diameter'],
131         ['&nabla;', '&#8711;', false, 'backwarddifference'],
132         ['&lowast;', '&#8727;', false, 'asteriskoperator'],
133         ['&prop;', '&#8733;', false, 'proportionalto'],
134         ['&ang;', '&#8736;', false, 'angle'],
135         // Undefined.
136         ['&acute;', '&#180;', true, 'acuteaccent'],
137         ['&cedil;', '&#184;', true, 'cedilla'],
138         ['&ordf;', '&#170;', true, 'feminineordinalindicator'],
139         ['&ordm;', '&#186;', true, 'masculineordinalindicator'],
140         ['&dagger;', '&#8224;', true, 'dagger'],
141         ['&Dagger;', '&#8225;', true, 'doubledagger'],
142         // Alphabetical special chars.
143         ['&Agrave;', '&#192;', true, 'agrave_caps'],
144         ['&Aacute;', '&#193;', true, 'aacute_caps'],
145         ['&Acirc;', '&#194;', true, 'acircumflex_caps'],
146         ['&Atilde;', '&#195;', true, 'atilde_caps'],
147         ['&Auml;', '&#196;', true, 'adiaeresis_caps'],
148         ['&Aring;', '&#197;', true, 'aringabove_caps'],
149         ['&#256;', '&#256;', true, 'amacron_caps'],
150         ['&AElig;', '&#198;', true, 'ligatureae_caps'],
151         ['&Ccedil;', '&#199;', true, 'ccedilla_caps'],
152         ['&Egrave;', '&#200;', true, 'egrave_caps'],
153         ['&Eacute;', '&#201;', true, 'eacute_caps'],
154         ['&Ecirc;', '&#202;', true, 'ecircumflex_caps'],
155         ['&Euml;', '&#203;', true, 'ediaeresis_caps'],
156         ['&#274;', '&#274;', true, 'emacron_caps'],
157         ['&Igrave;', '&#204;', true, 'igrave_caps'],
158         ['&Iacute;', '&#205;', true, 'iacute_caps'],
159         ['&Icirc;', '&#206;', true, 'icircumflex_caps'],
160         ['&Iuml;', '&#207;', true, 'idiaeresis_caps'],
161         ['&#298;', '&#298;', true, 'imacron_caps'],
162         ['&ETH;', '&#208;', true, 'eth_caps'],
163         ['&Ntilde;', '&#209;', true, 'ntilde_caps'],
164         ['&Ograve;', '&#210;', true, 'ograve_caps'],
165         ['&Oacute;', '&#211;', true, 'oacute_caps'],
166         ['&Ocirc;', '&#212;', true, 'ocircumflex_caps'],
167         ['&Otilde;', '&#213;', true, 'otilde_caps'],
168         ['&Ouml;', '&#214;', true, 'odiaeresis_caps'],
169         ['&Oslash;', '&#216;', true, 'oslash_caps'],
170         ['&#332;', '&#332;', true, 'omacron_caps'],
171         ['&OElig;', '&#338;', true, 'ligatureoe_caps'],
172         ['&Scaron;', '&#352;', true, 'scaron_caps'],
173         ['&Ugrave;', '&#217;', true, 'ugrave_caps'],
174         ['&Uacute;', '&#218;', true, 'uacute_caps'],
175         ['&Ucirc;', '&#219;', true, 'ucircumflex_caps'],
176         ['&Uuml;', '&#220;', true, 'udiaeresis_caps'],
177         ['&#362;', '&#362;', true, 'umacron_caps'],
178         ['&Yacute;', '&#221;', true, 'yacute_caps'],
179         ['&Yuml;', '&#376;', true, 'ydiaeresis_caps'],
180         ['&THORN;', '&#222;', true, 'thorn_caps'],
181         ['&agrave;', '&#224;', true, 'agrave'],
182         ['&aacute;', '&#225;', true, 'aacute'],
183         ['&acirc;', '&#226;', true, 'acircumflex'],
184         ['&atilde;', '&#227;', true, 'atilde'],
185         ['&auml;', '&#228;', true, 'adiaeresis'],
186         ['&aring;', '&#229;', true, 'aringabove'],
187         ['&#257;', '&#257;', true, 'amacron'],
188         ['&aelig;', '&#230;', true, 'ligatureae'],
189         ['&ccedil;', '&#231;', true, 'ccedilla'],
190         ['&egrave;', '&#232;', true, 'egrave'],
191         ['&eacute;', '&#233;', true, 'eacute'],
192         ['&ecirc;', '&#234;', true, 'ecircumflex'],
193         ['&euml;', '&#235;', true, 'ediaeresis'],
194         ['&#275;', '&#275;', true, 'emacron'],
195         ['&igrave;', '&#236;', true, 'igrave'],
196         ['&iacute;', '&#237;', true, 'iacute'],
197         ['&icirc;', '&#238;', true, 'icircumflex'],
198         ['&iuml;', '&#239;', true, 'idiaeresis'],
199         ['&#299;', '&#299;', true, 'imacron'],
200         ['&eth;', '&#240;', true, 'eth'],
201         ['&ntilde;', '&#241;', true, 'ntilde'],
202         ['&ograve;', '&#242;', true, 'ograve'],
203         ['&oacute;', '&#243;', true, 'oacute'],
204         ['&ocirc;', '&#244;', true, 'ocircumflex'],
205         ['&otilde;', '&#245;', true, 'otilde'],
206         ['&ouml;', '&#246;', true, 'odiaeresis'],
207         ['&oslash;', '&#248;', true, 'oslash'],
208         ['&#333;', '&#333;', true, 'omacron'],
209         ['&oelig;', '&#339;', true, 'ligatureoe'],
210         ['&scaron;', '&#353;', true, 'scaron'],
211         ['&ugrave;', '&#249;', true, 'ugrave'],
212         ['&uacute;', '&#250;', true, 'uacute'],
213         ['&ucirc;', '&#251;', true, 'ucircumflex'],
214         ['&uuml;', '&#252;', true, 'udiaeresis'],
215         ['&#363;', '&#363;', true, 'umacron'],
216         ['&yacute;', '&#253;', true, 'yacute'],
217         ['&thorn;', '&#254;', true, 'thorn'],
218         ['&yuml;', '&#255;', true, 'ydiaeresis'],
219         ['&Alpha;', '&#913;', true, 'alpha_caps'],
220         ['&Beta;', '&#914;', true, 'beta_caps'],
221         ['&Gamma;', '&#915;', true, 'gamma_caps'],
222         ['&Delta;', '&#916;', true, 'delta_caps'],
223         ['&Epsilon;', '&#917;', true, 'epsilon_caps'],
224         ['&Zeta;', '&#918;', true, 'zeta_caps'],
225         ['&Eta;', '&#919;', true, 'eta_caps'],
226         ['&Theta;', '&#920;', true, 'theta_caps'],
227         ['&Iota;', '&#921;', true, 'iota_caps'],
228         ['&Kappa;', '&#922;', true, 'kappa_caps'],
229         ['&Lambda;', '&#923;', true, 'lambda_caps'],
230         ['&Mu;', '&#924;', true, 'mu_caps'],
231         ['&Nu;', '&#925;', true, 'nu_caps'],
232         ['&Xi;', '&#926;', true, 'xi_caps'],
233         ['&Omicron;', '&#927;', true, 'omicron_caps'],
234         ['&Pi;', '&#928;', true, 'pi_caps'],
235         ['&Rho;', '&#929;', true, 'rho_caps'],
236         ['&Sigma;', '&#931;', true, 'sigma_caps'],
237         ['&Tau;', '&#932;', true, 'tau_caps'],
238         ['&Upsilon;', '&#933;', true, 'upsilon_caps'],
239         ['&Phi;', '&#934;', true, 'phi_caps'],
240         ['&Chi;', '&#935;', true, 'chi_caps'],
241         ['&Psi;', '&#936;', true, 'psi_caps'],
242         ['&Omega;', '&#937;', true, 'omega_caps'],
243         ['&alpha;', '&#945;', true, 'alpha'],
244         ['&beta;', '&#946;', true, 'beta'],
245         ['&gamma;', '&#947;', true, 'gamma'],
246         ['&delta;', '&#948;', true, 'delta'],
247         ['&epsilon;', '&#949;', true, 'epsilon'],
248         ['&zeta;', '&#950;', true, 'zeta'],
249         ['&eta;', '&#951;', true, 'eta'],
250         ['&theta;', '&#952;', true, 'theta'],
251         ['&iota;', '&#953;', true, 'iota'],
252         ['&kappa;', '&#954;', true, 'kappa'],
253         ['&lambda;', '&#955;', true, 'lambda'],
254         ['&mu;', '&#956;', true, 'mu'],
255         ['&nu;', '&#957;', true, 'nu'],
256         ['&xi;', '&#958;', true, 'xi'],
257         ['&omicron;', '&#959;', true, 'omicron'],
258         ['&pi;', '&#960;', true, 'pi'],
259         ['&rho;', '&#961;', true, 'rho'],
260         ['&sigmaf;', '&#962;', true, 'finalsigma'],
261         ['&sigma;', '&#963;', true, 'sigma'],
262         ['&tau;', '&#964;', true, 'tau'],
263         ['&upsilon;', '&#965;', true, 'upsilon'],
264         ['&phi;', '&#966;', true, 'phi'],
265         ['&chi;', '&#967;', true, 'chi'],
266         ['&psi;', '&#968;', true, 'psi'],
267         ['&omega;', '&#969;', true, 'omega'],
268         // Symbols.
269         ['&alefsym;', '&#8501;', false, 'alefsymbol'],
270         ['&piv;', '&#982;', false, 'pisymbol'],
271         ['&real;', '&#8476;', false, 'realpartsymbol'],
272         ['&thetasym;', '&#977;', false, 'thetasymbol'],
273         ['&upsih;', '&#978;', false, 'upsilonhooksymbol'],
274         ['&weierp;', '&#8472;', false, 'weierstrassp'],
275         ['&image;', '&#8465;', false, 'imaginarypart'],
276         // Arrows.
277         ['&larr;', '&#8592;', true, 'leftwardsarrow'],
278         ['&uarr;', '&#8593;', true, 'upwardsarrow'],
279         ['&rarr;', '&#8594;', true, 'rightwardsarrow'],
280         ['&darr;', '&#8595;', true, 'downwardsarrow'],
281         ['&harr;', '&#8596;', true, 'leftrightarrow'],
282         ['&crarr;', '&#8629;', false, 'carriagereturn'],
283         ['&lArr;', '&#8656;', false, 'leftwardsdoublearrow'],
284         ['&uArr;', '&#8657;', false, 'upwardsdoublearrow'],
285         ['&rArr;', '&#8658;', false, 'rightwardsdoublearrow'],
286         ['&dArr;', '&#8659;', false, 'downwardsdoublearrow'],
287         ['&hArr;', '&#8660;', false, 'leftrightdoublearrow'],
288         ['&there4;', '&#8756;', false, 'therefore'],
289         ['&sub;', '&#8834;', false, 'subsetof'],
290         ['&sup;', '&#8835;', false, 'supersetof'],
291         ['&nsub;', '&#8836;', false, 'notasubsetof'],
292         ['&sube;', '&#8838;', false, 'subsetoforequalto'],
293         ['&supe;', '&#8839;', false, 'supersetoforequalto'],
294         ['&oplus;', '&#8853;', false, 'circledplus'],
295         ['&otimes;', '&#8855;', false, 'circledtimes'],
296         ['&perp;', '&#8869;', false, 'perpendicular'],
297         ['&sdot;', '&#8901;', false, 'dotoperator'],
298         ['&lceil;', '&#8968;', false, 'leftceiling'],
299         ['&rceil;', '&#8969;', false, 'rightceiling'],
300         ['&lfloor;', '&#8970;', false, 'leftfloor'],
301         ['&rfloor;', '&#8971;', false, 'rightfloor'],
302         ['&lang;', '&#9001;', false, 'leftpointinganglebracket'],
303         ['&rang;', '&#9002;', false, 'rightpointinganglebracket'],
304         ['&loz;', '&#9674;', true, 'lozenge'],
305         ['&spades;', '&#9824;', true, 'blackspadesuit'],
306         ['&clubs;', '&#9827;', true, 'blackclubsuit'],
307         ['&hearts;', '&#9829;', true, 'blackheartsuit'],
308         ['&diams;', '&#9830;', true, 'blackdiamondsuit'],
309         ['&ensp;', '&#8194;', false, 'enspace'],
310         ['&emsp;', '&#8195;', false, 'emspace'],
311         ['&thinsp;', '&#8201;', false, 'thinspace'],
312         ['&zwnj;', '&#8204;', false, 'zerowidthnonjoiner'],
313         ['&zwj;', '&#8205;', false, 'zerowidthjoiner'],
314         ['&lrm;', '&#8206;', false, 'lefttorightmark'],
315         ['&rlm;', '&#8207;', false, 'righttoleftmark'],
316         ['&shy;', '&#173;', false, 'softhyphen']
317     ];
319 /**
320  * Atto text editor charmap plugin.
321  *
322  * @namespace M.atto_charmap
323  * @class button
324  * @extends M.editor_atto.EditorPlugin
325  */
327 Y.namespace('M.atto_charmap').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], {
328     /**
329      * A reference to the current selection at the time that the dialogue
330      * was opened.
331      *
332      * @property _currentSelection
333      * @type Range
334      * @private
335      */
336     _currentSelection: null,
338     initializer: function() {
339         this.addButton({
340             icon: 'e/special_character',
341             callback: this._displayDialogue
342         });
343     },
345     /**
346      * Display the Character Map selector.
347      *
348      * @method _displayDialogue
349      * @private
350      */
351     _displayDialogue: function() {
352         // Store the current selection.
353         this._currentSelection = this.get('host').getSelection();
354         if (this._currentSelection === false) {
355             return;
356         }
358         var dialogue = this.getDialogue({
359             headerContent: M.util.get_string('insertcharacter', COMPONENTNAME),
360             focusAfterHide: true
361         }, true);
363         // Set the dialogue content, and then show the dialogue.
364         dialogue.set('bodyContent', this._getDialogueContent())
365                 .show();
366     },
368     /**
369      * Return the dialogue content for the tool.
370      *
371      * @method _getDialogueContent
372      * @private
373      * @return {Node} The content to place in the dialogue.
374      */
375     _getDialogueContent: function() {
376         var template = Y.Handlebars.compile(
377             '<div class="{{CSS.CHARMAP}}">' +
378                 '{{#each CHARMAP}}' +
379                     '{{#if this.[2]}}' +
380                     '<button class="btn btn-secondary btn-sm {{../../CSS.BUTTON}}" ' +
381                         'aria-label="{{get_string this.[3] ../../component}}" ' +
382                         'title="{{get_string this.[3] ../../component}}" ' +
383                         'data-character="{{this.[0]}}" ' +
384                     '>{{{this.[0]}}}</button>' +
385                     '{{/if}}' +
386                 '{{/each}}' +
387             '</div>'
388         );
390         var content = Y.Node.create(template({
391             component: COMPONENTNAME,
392             CSS: CSS,
393             CHARMAP: CHARMAP
394         }));
396         content.delegate('click', this._insertChar, '.' + CSS.BUTTON, this);
397         return content;
398     },
400     /**
401      * Insert the picked character into the editor.
402      *
403      * @method _insertChar
404      * @param {EventFacade} e
405      * @private
406      */
407     _insertChar: function(e) {
408         var character = e.target.getData('character');
410         // Hide the dialogue.
411         this.getDialogue({
412             focusAfterHide: null
413         }).hide();
415         var host = this.get('host');
417         // Focus on the last point.
418         host.setSelection(this._currentSelection);
420         // And add the character.
421         host.insertContentAtFocusPoint(character);
423         // And mark the text area as updated.
424         this.markUpdated();
425     }
426 });