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