MDL-42102 TinyMCE: Toolbar wrapping < 480px.
[moodle.git] / lib / editor / tinymce / plugins / wrap / tinymce / editor_plugin.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  * Plugin for Moodle 'wrap' button.
18  *
19  * @package   tinymce_wrap
20  * @copyright 2013 Damyon Wiese
21  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22  */
23 (function() {
24     tinymce.create('tinymce.ui.Wrap:tinymce.ui.Control', {
25         /**
26          * Constructor for the tinymce.Wrap class.
27          */
28         Wrap : function(id, s) {
29             this.parent(id, s);
30             this.groupEndClass = 'mceGroupEnd';
31             this.toolbarEndClass = 'mceLast';
32             this.groupEndPlaceholder = 'mceToolbarEndPlaceholder';
33             this.groupStartClass = 'mceGroupStart';
34             this.wrapClass = 'mceWrap';
35             this.noWrapClass = 'mceNoWrap';
36             this.toolbarClass = 'mceToolbar';
37             this.selectListArrowClass = 'mceOpen';
38             this.setDisabled(true);
39         },
41         /**
42          * Returns the HTML for this control. This control actually ends the current td
43          * container and opens a new one so that the containers can be styled with CSS
44          * to wrap at certain screen widths.
45          * @return string HTML
46          */
47         renderHTML : function() {
48             var separator = tinymce.DOM.createHTML('span', {role : 'separator',
49                                                             'aria-orientation' : 'vertical',
50                                                             tabindex : '-1'});
51             return '</td>' +
52                    '<td style="position: relative" class="' + this.groupEndPlaceholder + '">' + separator + '</td>' +
53                    '<td style="position: relative" class="' + this.groupStartClass + ' ' + this.wrapClass + '">' + separator + '</td>';
54         },
56         postRender : function() {
57             var self = this;
58             // Add a class to the item prior to the wrap.
59             YUI().use('node', function(Y) {
60                 var endGroupElements = tinymce.DOM.select('td.' + self.groupEndPlaceholder),
61                     index = 0, curElement, endOfLast,
62                     endBarElements = tinymce.DOM.select('td.' + self.toolbarEndClass);
64                 for (index = 0; index < endGroupElements.length; index++) {
65                     if (!endGroupElements.hasOwnProperty(index)) {
66                           continue;
67                     }
68                     curElement = Y.one(endGroupElements[index]);
69                     endOfLast = curElement.previous('td').previous('td');
70                     if (endOfLast) {
71                         endOfLast.addClass(self.groupEndClass);
72                     }
73                 }
74                 for (index = 0; index < endBarElements.length; index++) {
75                     if (!endBarElements.hasOwnProperty(index)) {
76                         continue;
77                     }
78                     curElement = Y.one(endBarElements[index]);
79                     endOfLast = curElement.previous('td');
80                     if (endOfLast) {
81                         endOfLast.addClass(self.groupEndClass);
82                     }
83                 }
84                 // Any separators closer together than 5 buttons get the noWrapClass.
85                 var toolbars = Y.all('table.' + self.toolbarClass),
86                     buttonWrapPoint = 5;
88                 toolbars.each(function(toolbar) {
89                     var count = 0;
90                     widgets = toolbar.all('td.' + self.wrapClass + ', td > a');
91                     widgets.each(function(widget) {
92                         if (widget.hasClass(self.wrapClass)) {
93                             if (count >= buttonWrapPoint) {
94                                 count = 0;
95                             } else {
96                                 widget.addClass(self.noWrapClass);
97                             }
98                         } else {
99                             if (widget.hasClass(self.selectListArrowClass) ||
100                                     (widget.getAttribute('role') === 'button')) {
101                                 count++;
102                             } else {
103                                 // Count select inputs as 3 buttons. The down arrow on the select also gets counted so 2+1 = 3.
104                                 count += 2;
105                             }
106                         }
107                     });
108                 });
110             });
111         }
112     });
114     tinymce.create('tinymce.plugins.wrapPlugin', {
115         /**
116          * Returns a new instance of this control, in this case a custom Wrap class.
117          *
118          * @param string name - The name of the control to create. Return false if we can't create this control type.
119          * @param tinymce.ControlManager cc - Tinymce control manager class.
120          * @return mixed - false or the new control
121          */
122         createControl : function(name, cc) {
123             if (name === "wrap") {
124                 return new tinymce.ui.Wrap();
125             }
126             return false;
127         },
129         /**
130          * Returns information about the plugin as a name/value array.
131          * The current keys are longname, author, authorurl, infourl and version.
132          *
133          * @return {Object} Name/value array containing information about the plugin.
134          */
135         getInfo : function() {
136             return {
137                 longname : 'wrap plugin',
138                 author : 'Damyon Wiese',
139                 authorurl : 'http://moodle.com/hq',
140                 infourl : 'http://docs.moodle.org/en/TinyMCE',
141                 version : "1.0"
142             };
143         }
144     });
146     // Register plugin.
147     tinymce.PluginManager.add('wrap', tinymce.plugins.wrapPlugin);
148 })();