/*
|
Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
For licensing, see LICENSE.html 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
|
(
|
'<table tabIndex="-1" aria-label="' + lang.options + '"' +
|
' role="grid" style="border-collapse:separate;" cellspacing="0">' +
|
'<caption class="cke_voice_label">' + lang.options + '</caption>' +
|
'<tbody role="presentation"></tbody></table>'
|
);
|
|
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( '<span id="' + colorLabel + '" class="cke_voice_label">' + color + '</span>', 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.
|
for ( var n = 0 ; n < 6 ; n++ )
|
{
|
appendColorCell( oRow.$, '#' + aColors[n] + aColors[n] + aColors[n] ) ;
|
}
|
|
// Fill the row with black cells.
|
for ( var i = 0 ; i < 12 ; i++ )
|
{
|
appendColorCell( oRow.$, '#000000' ) ;
|
}
|
}
|
|
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 : '<div></div>',
|
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 : '<span>' + lang.highlight +'</span>\
|
<div id="' + hicolorId + '" style="border: 1px solid; height: 74px; width: 74px;"></div>\
|
<div id="' + hicolorTextId + '"> </div><span>' + lang.selected + '</span>\
|
<div id="' + selHiColorId + '" style="border: 1px solid; height: 20px; width: 74px;"></div>'
|
},
|
{
|
type : 'text',
|
label : lang.selected,
|
labelStyle: 'display:none',
|
id : 'selectedColor',
|
style : 'width: 74px',
|
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',
|
style : 'margin-top: 5px',
|
label : lang.clear,
|
onClick : clearSelected
|
}
|
]
|
}
|
]
|
}
|
]
|
}
|
]
|
};
|
}
|
);
|