/** * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or http://ckeditor.com/license */ CKEDITOR.dialog.add( 'colordialog', function( editor ) { // Define some shorthands. var $el = CKEDITOR.dom.element, $doc = CKEDITOR.document, lang = editor.lang.colordialog; // Reference the dialog. var dialog; var spacer = { type: 'html', html: ' ' }; var selected; function clearSelected() { $doc.getById( selHiColorId ).removeStyle( 'background-color' ); dialog.getContentElement( 'picker', 'selectedColor' ).setValue( '' ); selected && selected.removeAttribute( 'aria-selected' ); selected = null; } function updateSelected( evt ) { var target = evt.data.getTarget(), color; if ( target.getName() == 'td' && ( color = target.getChild( 0 ).getHtml() ) ) { selected = target; selected.setAttribute( 'aria-selected', true ); dialog.getContentElement( 'picker', 'selectedColor' ).setValue( color ); } } // Basing black-white decision off of luma scheme using the Rec. 709 version function whiteOrBlack( color ) { color = color.replace( /^#/, '' ); for ( var i = 0, rgb = []; i <= 2; i++ ) rgb[ i ] = parseInt( color.substr( i * 2, 2 ), 16 ); var luma = ( 0.2126 * rgb[ 0 ] ) + ( 0.7152 * rgb[ 1 ] ) + ( 0.0722 * rgb[ 2 ] ); return '#' + ( luma >= 165 ? '000' : 'fff' ); } // Distinguish focused and hover states. var focused, hovered; // Apply highlight style. function updateHighlight( event ) { // Convert to event. !event.name && ( event = new CKEDITOR.event( event ) ); var isFocus = !( /mouse/ ).test( event.name ), target = event.data.getTarget(), color; if ( target.getName() == 'td' && ( color = target.getChild( 0 ).getHtml() ) ) { removeHighlight( event ); isFocus ? focused = target : hovered = target; // Apply outline style to show focus. if ( isFocus ) { target.setStyle( 'border-color', whiteOrBlack( color ) ); target.setStyle( 'border-style', 'dotted' ); } $doc.getById( hicolorId ).setStyle( 'background-color', color ); $doc.getById( hicolorTextId ).setHtml( color ); } } function clearHighlight() { var color = focused.getChild( 0 ).getHtml(); focused.setStyle( 'border-color', color ); focused.setStyle( 'border-style', 'solid' ); $doc.getById( hicolorId ).removeStyle( 'background-color' ); $doc.getById( hicolorTextId ).setHtml( ' ' ); focused = null; } // Remove previously focused style. function removeHighlight( event ) { var isFocus = !( /mouse/ ).test( event.name ), target = isFocus && focused; if ( target ) { var color = target.getChild( 0 ).getHtml(); target.setStyle( 'border-color', color ); target.setStyle( 'border-style', 'solid' ); } if ( !( focused || hovered ) ) { $doc.getById( hicolorId ).removeStyle( 'background-color' ); $doc.getById( hicolorTextId ).setHtml( ' ' ); } } function onKeyStrokes( evt ) { var domEvt = evt.data; var element = domEvt.getTarget(); var relative, nodeToMove; var keystroke = domEvt.getKeystroke(), rtl = editor.lang.dir == 'rtl'; switch ( keystroke ) { // UP-ARROW case 38: // relative is TR if ( ( relative = element.getParent().getPrevious() ) ) { nodeToMove = relative.getChild( [ element.getIndex() ] ); nodeToMove.focus(); } domEvt.preventDefault(); break; // DOWN-ARROW case 40: // relative is TR if ( ( relative = element.getParent().getNext() ) ) { nodeToMove = relative.getChild( [ element.getIndex() ] ); if ( nodeToMove && nodeToMove.type == 1 ) nodeToMove.focus(); } domEvt.preventDefault(); break; // SPACE // ENTER case 32: case 13: updateSelected( evt ); domEvt.preventDefault(); break; // RIGHT-ARROW case rtl ? 37 : 39: // relative is TD if ( ( nodeToMove = element.getNext() ) ) { if ( nodeToMove.type == 1 ) { nodeToMove.focus(); domEvt.preventDefault( true ); } } // relative is TR else if ( ( relative = element.getParent().getNext() ) ) { nodeToMove = relative.getChild( [ 0 ] ); if ( nodeToMove && nodeToMove.type == 1 ) { nodeToMove.focus(); domEvt.preventDefault( true ); } } break; // LEFT-ARROW case rtl ? 39 : 37: // relative is TD if ( ( nodeToMove = element.getPrevious() ) ) { nodeToMove.focus(); domEvt.preventDefault( true ); } // relative is TR else if ( ( relative = element.getParent().getPrevious() ) ) { nodeToMove = relative.getLast(); nodeToMove.focus(); domEvt.preventDefault( true ); } break; default: // Do not stop not handled events. return; } } function createColorTable() { table = CKEDITOR.dom.element.createFromHtml( '' + '' + '
' + lang.options + '
' ); table.on( 'mouseover', updateHighlight ); table.on( 'mouseout', removeHighlight ); // Create the base colors array. var aColors = [ '00', '33', '66', '99', 'cc', 'ff' ]; // This function combines two ranges of three values from the color array into a row. function appendColorRow( rangeA, rangeB ) { for ( var i = rangeA; i < rangeA + 3; i++ ) { var row = new $el( table.$.insertRow( -1 ) ); row.setAttribute( 'role', 'row' ); for ( var j = rangeB; j < rangeB + 3; j++ ) { for ( var n = 0; n < 6; n++ ) { appendColorCell( row.$, '#' + aColors[ j ] + aColors[ n ] + aColors[ i ] ); } } } } // This function create a single color cell in the color table. function appendColorCell( targetRow, color ) { var cell = new $el( targetRow.insertCell( -1 ) ); cell.setAttribute( 'class', 'ColorCell' ); cell.setAttribute( 'tabIndex', -1 ); cell.setAttribute( 'role', 'gridcell' ); cell.on( 'keydown', onKeyStrokes ); cell.on( 'click', updateSelected ); cell.on( 'focus', updateHighlight ); cell.on( 'blur', removeHighlight ); cell.setStyle( 'background-color', color ); cell.setStyle( 'border', '1px solid ' + color ); cell.setStyle( 'width', '14px' ); cell.setStyle( 'height', '14px' ); var colorLabel = numbering( 'color_table_cell' ); cell.setAttribute( 'aria-labelledby', colorLabel ); cell.append( CKEDITOR.dom.element.createFromHtml( '' + color + '', CKEDITOR.document ) ); } appendColorRow( 0, 0 ); appendColorRow( 3, 0 ); appendColorRow( 0, 3 ); appendColorRow( 3, 3 ); // Create the last row. var oRow = new $el( table.$.insertRow( -1 ) ); oRow.setAttribute( 'role', 'row' ); // Create the gray scale colors cells. appendColorCell( oRow.$, '#000000' ); for ( var n = 0; n < 16; n++ ) { var c = n.toString( 16 ); appendColorCell( oRow.$, '#' + c + c + c + c + c + c ); } appendColorCell( oRow.$, '#ffffff' ); } var numbering = function( id ) { return CKEDITOR.tools.getNextId() + '_' + id; }, hicolorId = numbering( 'hicolor' ), hicolorTextId = numbering( 'hicolortext' ), selHiColorId = numbering( 'selhicolor' ), table; createColorTable(); return { title: lang.title, minWidth: 360, minHeight: 220, onLoad: function() { // Update reference. dialog = this; }, onHide: function() { clearSelected(); clearHighlight(); }, contents: [ { id: 'picker', label: lang.title, accessKey: 'I', elements: [ { type: 'hbox', padding: 0, widths: [ '70%', '10%', '30%' ], children: [ { type: 'html', html: '
', onLoad: function() { CKEDITOR.document.getById( this.domId ).append( table ); }, focus: function() { // Restore the previously focused cell, // otherwise put the initial focus on the first table cell. ( focused || this.getElement().getElementsByTag( 'td' ).getItem( 0 ) ).focus(); } }, spacer, { type: 'vbox', padding: 0, widths: [ '70%', '5%', '25%' ], children: [ { type: 'html', html: '' + lang.highlight + '' + '
' + '
 
' + lang.selected + '' + '
' }, { type: 'text', label: lang.selected, labelStyle: 'display:none', id: 'selectedColor', style: 'width: 76px;margin-top:4px', onChange: function() { // Try to update color preview with new value. If fails, then set it no none. try { $doc.getById( selHiColorId ).setStyle( 'background-color', this.getValue() ); } catch ( e ) { clearSelected(); } } }, spacer, { type: 'button', id: 'clear', label: lang.clear, onClick: clearSelected } ] } ] } ] } ] }; } );