]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/javascript/tiny_mce/classes/ui/ColorSplitButton.js
Release 6.5.0
[Github/sugarcrm.git] / include / javascript / tiny_mce / classes / ui / ColorSplitButton.js
1 /**
2  * ColorSplitButton.js
3  *
4  * Copyright 2009, Moxiecode Systems AB
5  * Released under LGPL License.
6  *
7  * License: http://tinymce.moxiecode.com/license
8  * Contributing: http://tinymce.moxiecode.com/contributing
9  */
10
11 (function(tinymce) {
12         var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each;
13
14         /**
15          * This class is used to create UI color split button. A color split button will present show a small color picker
16          * when you press the open menu.
17          *
18          * @class tinymce.ui.ColorSplitButton
19          * @extends tinymce.ui.SplitButton
20          */
21         tinymce.create('tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton', {
22                 /**
23                  * Constructs a new color split button control instance.
24                  *
25                  * @constructor
26                  * @method ColorSplitButton
27                  * @param {String} id Control id for the color split button.
28                  * @param {Object} s Optional name/value settings object.
29                  * @param {Editor} ed The editor instance this button is for.
30                  */
31                 ColorSplitButton : function(id, s, ed) {
32                         var t = this;
33
34                         t.parent(id, s, ed);
35
36                         /**
37                          * Settings object.
38                          *
39                          * @property settings
40                          * @type Object
41                          */
42                         t.settings = s = tinymce.extend({
43                                 colors : '000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF',
44                                 grid_width : 8,
45                                 default_color : '#888888'
46                         }, t.settings);
47
48                         /**
49                          * Fires when the menu is shown.
50                          *
51                          * @event onShowMenu
52                          */
53                         t.onShowMenu = new tinymce.util.Dispatcher(t);
54
55                         /**
56                          * Fires when the menu is hidden.
57                          *
58                          * @event onHideMenu
59                          */
60                         t.onHideMenu = new tinymce.util.Dispatcher(t);
61
62                         /**
63                          * Current color value.
64                          *
65                          * @property value
66                          * @type String
67                          */
68                         t.value = s.default_color;
69                 },
70
71                 /**
72                  * Shows the color menu. The color menu is a layer places under the button
73                  * and displays a table of colors for the user to pick from.
74                  *
75                  * @method showMenu
76                  */
77                 showMenu : function() {
78                         var t = this, r, p, e, p2;
79
80                         if (t.isDisabled())
81                                 return;
82
83                         if (!t.isMenuRendered) {
84                                 t.renderMenu();
85                                 t.isMenuRendered = true;
86                         }
87
88                         if (t.isMenuVisible)
89                                 return t.hideMenu();
90
91                         e = DOM.get(t.id);
92                         DOM.show(t.id + '_menu');
93                         DOM.addClass(e, 'mceSplitButtonSelected');
94                         p2 = DOM.getPos(e);
95                         DOM.setStyles(t.id + '_menu', {
96                                 left : p2.x,
97                                 top : p2.y + e.clientHeight,
98                                 zIndex : 200000
99                         });
100                         e = 0;
101
102                         Event.add(DOM.doc, 'mousedown', t.hideMenu, t);
103                         t.onShowMenu.dispatch(t);
104
105                         if (t._focused) {
106                                 t._keyHandler = Event.add(t.id + '_menu', 'keydown', function(e) {
107                                         if (e.keyCode == 27)
108                                                 t.hideMenu();
109                                 });
110
111                                 DOM.select('a', t.id + '_menu')[0].focus(); // Select first link
112                         }
113
114                         t.isMenuVisible = 1;
115                 },
116
117                 /**
118                  * Hides the color menu. The optional event parameter is used to check where the event occured so it
119                  * doesn't close them menu if it was a event inside the menu.
120                  *
121                  * @method hideMenu
122                  * @param {Event} e Optional event object.
123                  */
124                 hideMenu : function(e) {
125                         var t = this;
126
127                         if (t.isMenuVisible) {
128                                 // Prevent double toogles by canceling the mouse click event to the button
129                                 if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id + '_open';}))
130                                         return;
131
132                                 if (!e || !DOM.getParent(e.target, '.mceSplitButtonMenu')) {
133                                         DOM.removeClass(t.id, 'mceSplitButtonSelected');
134                                         Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);
135                                         Event.remove(t.id + '_menu', 'keydown', t._keyHandler);
136                                         DOM.hide(t.id + '_menu');
137                                 }
138
139                                 t.isMenuVisible = 0;
140                         }
141                 },
142
143                 /**
144                  * Renders the menu to the DOM.
145                  *
146                  * @method renderMenu
147                  */
148                 renderMenu : function() {
149                         var t = this, m, i = 0, s = t.settings, n, tb, tr, w, context;
150
151                         w = DOM.add(s.menu_container, 'div', {role: 'listbox', id : t.id + '_menu', 'class' : s['menu_class'] + ' ' + s['class'], style : 'position:absolute;left:0;top:-1000px;'});
152                         m = DOM.add(w, 'div', {'class' : s['class'] + ' mceSplitButtonMenu'});
153                         DOM.add(m, 'span', {'class' : 'mceMenuLine'});
154
155                         n = DOM.add(m, 'table', {role: 'presentation', 'class' : 'mceColorSplitMenu'});
156                         tb = DOM.add(n, 'tbody');
157
158                         // Generate color grid
159                         i = 0;
160                         each(is(s.colors, 'array') ? s.colors : s.colors.split(','), function(c) {
161                                 c = c.replace(/^#/, '');
162
163                                 if (!i--) {
164                                         tr = DOM.add(tb, 'tr');
165                                         i = s.grid_width - 1;
166                                 }
167
168                                 n = DOM.add(tr, 'td');
169                                 n = DOM.add(n, 'a', {
170                                         role : 'option',
171                                         href : 'javascript:;',
172                                         style : {
173                                                 backgroundColor : '#' + c
174                                         },
175                                         'title': t.editor.getLang('colors.' + c, c),
176                                         'data-mce-color' : '#' + c
177                                 });
178
179                                 if (t.editor.forcedHighContrastMode) {
180                                         n = DOM.add(n, 'canvas', { width: 16, height: 16, 'aria-hidden': 'true' });
181                                         if (n.getContext && (context = n.getContext("2d"))) {
182                                                 context.fillStyle = '#' + c;
183                                                 context.fillRect(0, 0, 16, 16);
184                                         } else {
185                                                 // No point leaving a canvas element around if it's not supported for drawing on anyway.
186                                                 DOM.remove(n);
187                                         }
188                                 }
189                         });
190
191                         if (s.more_colors_func) {
192                                 n = DOM.add(tb, 'tr');
193                                 n = DOM.add(n, 'td', {colspan : s.grid_width, 'class' : 'mceMoreColors'});
194                                 n = DOM.add(n, 'a', {role: 'option', id : t.id + '_more', href : 'javascript:;', onclick : 'return false;', 'class' : 'mceMoreColors'}, s.more_colors_title);
195
196                                 Event.add(n, 'click', function(e) {
197                                         s.more_colors_func.call(s.more_colors_scope || this);
198                                         return Event.cancel(e); // Cancel to fix onbeforeunload problem
199                                 });
200                         }
201
202                         DOM.addClass(m, 'mceColorSplitMenu');
203                         
204                         new tinymce.ui.KeyboardNavigation({
205                                 root: t.id + '_menu',
206                                 items: DOM.select('a', t.id + '_menu'),
207                                 onCancel: function() {
208                                         t.hideMenu();
209                                         t.focus();
210                                 }
211                         });
212
213                         // Prevent IE from scrolling and hindering click to occur #4019
214                         Event.add(t.id + '_menu', 'mousedown', function(e) {return Event.cancel(e);});
215
216                         Event.add(t.id + '_menu', 'click', function(e) {
217                                 var c;
218
219                                 e = DOM.getParent(e.target, 'a', tb);
220
221                                 if (e && e.nodeName.toLowerCase() == 'a' && (c = e.getAttribute('data-mce-color')))
222                                         t.setColor(c);
223
224                                 return Event.cancel(e); // Prevent IE auto save warning
225                         });
226
227                         return w;
228                 },
229
230                 /**
231                  * Sets the current color for the control and hides the menu if it should be visible.
232                  *
233                  * @method setColor
234                  * @param {String} c Color code value in hex for example: #FF00FF
235                  */
236                 setColor : function(c) {
237                         this.displayColor(c);
238                         this.hideMenu();
239                         this.settings.onselect(c);
240                 },
241                 
242                 /**
243                  * Change the currently selected color for the control.
244                  *
245                  * @method displayColor
246                  * @param {String} c Color code value in hex for example: #FF00FF
247                  */
248                 displayColor : function(c) {
249                         var t = this;
250
251                         DOM.setStyle(t.id + '_preview', 'backgroundColor', c);
252
253                         t.value = c;
254                 },
255
256                 /**
257                  * Post render event. This will be executed after the control has been rendered and can be used to
258                  * set states, add events to the control etc. It's recommended for subclasses of the control to call this method by using this.parent().
259                  *
260                  * @method postRender
261                  */
262                 postRender : function() {
263                         var t = this, id = t.id;
264
265                         t.parent();
266                         DOM.add(id + '_action', 'div', {id : id + '_preview', 'class' : 'mceColorPreview'});
267                         DOM.setStyle(t.id + '_preview', 'backgroundColor', t.value);
268                 },
269
270                 /**
271                  * Destroys the control. This means it will be removed from the DOM and any
272                  * events tied to it will also be removed.
273                  *
274                  * @method destroy
275                  */
276                 destroy : function() {
277                         this.parent();
278
279                         Event.clear(this.id + '_menu');
280                         Event.clear(this.id + '_more');
281                         DOM.remove(this.id + '_menu');
282                 }
283         });
284 })(tinymce);