4 * Released under LGPL License.
5 * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
7 * License: http://www.tinymce.com/license
8 * Contributing: http://www.tinymce.com/contributing
11 /*global tinymce:true */
12 /*eslint consistent-this:0 */
14 tinymce.PluginManager.add('textcolor', function(editor) {
17 rows = editor.settings.textcolor_rows || 5;
18 cols = editor.settings.textcolor_cols || 8;
20 function getCurrentColor(format) {
23 editor.dom.getParents(editor.selection.getStart(), function(elm) {
26 if ((value = elm.style[format == 'forecolor' ? 'color' : 'background-color'])) {
34 function mapColors() {
35 var i, colors = [], colorMap;
37 colorMap = editor.settings.textcolor_map || [
39 "993300", "Burnt orange",
40 "333300", "Dark olive",
41 "003300", "Dark green",
42 "003366", "Dark azure",
43 "000080", "Navy Blue",
45 "333333", "Very dark gray",
52 "666699", "Grayish blue",
56 "99CC00", "Yellow green",
57 "339966", "Sea green",
58 "33CCCC", "Turquoise",
59 "3366FF", "Royal blue",
61 "999999", "Medium gray",
68 "993366", "Red violet",
72 "FFFF99", "Light yellow",
73 "CCFFCC", "Pale green",
74 "CCFFFF", "Pale cyan",
75 "99CCFF", "Light sky blue",
79 for (i = 0; i < colorMap.length; i += 2) {
81 text: colorMap[i + 1],
82 color: '#' + colorMap[i]
89 function renderColorPicker() {
90 var ctrl = this, colors, color, html, last, x, y, i, id = ctrl._id, count = 0;
92 function getColorCellHtml(color, title) {
93 var isNoColor = color == 'transparent';
96 '<td class="mce-grid-cell' + (isNoColor ? ' mce-colorbtn-trans' : '') + '">' +
97 '<div id="' + id + '-' + (count++) + '"' +
98 ' data-mce-color="' + (color ? color : '') + '"' +
101 ' style="' + (color ? 'background-color: ' + color : '') + '"' +
102 ' title="' + tinymce.translate(title) + '">' +
103 (isNoColor ? '×' : '') +
109 colors = mapColors();
111 text: tinymce.translate("No color"),
115 html = '<table class="mce-grid mce-grid-border mce-colorbutton-grid" role="list" cellspacing="0"><tbody>';
116 last = colors.length - 1;
118 for (y = 0; y < rows; y++) {
121 for (x = 0; x < cols; x++) {
128 html += getColorCellHtml(color.color, color.text);
135 if (editor.settings.color_picker_callback) {
138 '<td colspan="' + cols + '" class="mce-custom-color-btn">' +
139 '<div id="' + id + '-c" class="mce-widget mce-btn mce-btn-small mce-btn-flat" ' +
140 'role="button" tabindex="-1" aria-labelledby="' + id + '-c" style="width: 100%">' +
141 '<button type="button" role="presentation" tabindex="-1">' + tinymce.translate('Custom...') + '</button>' +
149 for (x = 0; x < cols; x++) {
150 html += getColorCellHtml('', 'Custom color');
156 html += '</tbody></table>';
161 function applyFormat(format, value) {
162 editor.undoManager.transact(function() {
164 editor.formatter.apply(format, {value: value});
165 editor.nodeChanged();
169 function removeFormat(format) {
170 editor.undoManager.transact(function() {
172 editor.formatter.remove(format, {value: null}, null, true);
173 editor.nodeChanged();
177 function onPanelClick(e) {
178 var buttonCtrl = this.parent(), value;
180 function selectColor(value) {
181 buttonCtrl.hidePanel();
182 buttonCtrl.color(value);
183 applyFormat(buttonCtrl.settings.format, value);
186 function resetColor() {
187 buttonCtrl.hidePanel();
188 buttonCtrl.resetColor();
189 removeFormat(buttonCtrl.settings.format);
192 function setDivColor(div, value) {
193 div.style.background = value;
194 div.setAttribute('data-mce-color', value);
197 if (tinymce.DOM.getParent(e.target, '.mce-custom-color-btn')) {
198 buttonCtrl.hidePanel();
200 editor.settings.color_picker_callback.call(editor, function(value) {
201 var tableElm = buttonCtrl.panel.getEl().getElementsByTagName('table')[0];
202 var customColorCells, div, i;
204 customColorCells = tinymce.map(tableElm.rows[tableElm.rows.length - 1].childNodes, function(elm) {
205 return elm.firstChild;
208 for (i = 0; i < customColorCells.length; i++) {
209 div = customColorCells[i];
210 if (!div.getAttribute('data-mce-color')) {
215 // Shift colors to the right
216 // TODO: Might need to be the left on RTL
218 for (i = 0; i < cols - 1; i++) {
219 setDivColor(customColorCells[i], customColorCells[i + 1].getAttribute('data-mce-color'));
223 setDivColor(div, value);
225 }, getCurrentColor(buttonCtrl.settings.format));
228 value = e.target.getAttribute('data-mce-color');
231 document.getElementById(this.lastId).setAttribute('aria-selected', false);
234 e.target.setAttribute('aria-selected', true);
235 this.lastId = e.target.id;
237 if (value == 'transparent') {
242 } else if (value !== null) {
243 buttonCtrl.hidePanel();
247 function onButtonClick() {
251 applyFormat(self.settings.format, self._color);
253 removeFormat(self.settings.format);
257 editor.addButton('forecolor', {
259 tooltip: 'Text color',
264 html: renderColorPicker,
265 onclick: onPanelClick
267 onclick: onButtonClick
270 editor.addButton('backcolor', {
272 tooltip: 'Background color',
273 format: 'hilitecolor',
277 html: renderColorPicker,
278 onclick: onPanelClick
280 onclick: onButtonClick