mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-05-22 11:55:24 +00:00
Imported CKEDITOR 3.0
Monotone-Parent: 5f9c08dd6b5b34d815ddb2108abbf4055e846934 Monotone-Revision: b2cf7eda0ef8f15fb6e78f8c38a7406a47bcdd2f Monotone-Author: crobert@inverse.ca Monotone-Date: 2009-08-26T14:03:12 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -8,7 +8,7 @@ CKEDITOR.dialog.add( 'about', function( editor )
|
||||
var lang = editor.lang.about;
|
||||
|
||||
return {
|
||||
title : lang.title,
|
||||
title : CKEDITOR.env.ie ? lang.dlgTitle : lang.title,
|
||||
minWidth : 390,
|
||||
minHeight : 230,
|
||||
contents : [
|
||||
|
||||
@@ -99,7 +99,14 @@ CKEDITOR.ui.button.prototype =
|
||||
// Get the command name.
|
||||
var command = this.command;
|
||||
|
||||
if ( command )
|
||||
if ( this.modes )
|
||||
{
|
||||
editor.on( 'mode', function()
|
||||
{
|
||||
this.setState( this.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );
|
||||
}, this);
|
||||
}
|
||||
else if ( command )
|
||||
{
|
||||
// Get the command instance.
|
||||
command = editor.getCommand( command );
|
||||
@@ -130,7 +137,6 @@ CKEDITOR.ui.button.prototype =
|
||||
' class="', classes, '" href="javascript:void(\'', ( this.title || '' ).replace( "'", '' ), '\')"' +
|
||||
' title="', this.title, '"' +
|
||||
' tabindex="-1"' +
|
||||
' role="button"' +
|
||||
' hidefocus="true"' );
|
||||
|
||||
// Some browsers don't cancel key events in the keydown but in the
|
||||
|
||||
@@ -11,7 +11,7 @@ CKEDITOR.dialog.add( 'paste', function( editor )
|
||||
title : editor.lang.clipboard.title,
|
||||
|
||||
minWidth : CKEDITOR.env.ie && CKEDITOR.env.quirks ? 370 : 350,
|
||||
minHeight : CKEDITOR.env.ie && CKEDITOR.env.quirks ? 250 : 240,
|
||||
minHeight : CKEDITOR.env.quirks ? 250 : 245,
|
||||
htmlToLoad : '<!doctype html><script type="text/javascript">'
|
||||
+ 'window.onload = function()'
|
||||
+ '{'
|
||||
@@ -21,7 +21,12 @@ CKEDITOR.dialog.add( 'paste', function( editor )
|
||||
+ 'document.designMode = "on";'
|
||||
+ 'var iframe = new window.parent.CKEDITOR.dom.element( frameElement );'
|
||||
+ 'var dialog = iframe.getCustomData( "dialog" );'
|
||||
+ 'dialog.fire( "iframeAdded", { iframe : iframe } );'
|
||||
+ ''
|
||||
+ 'iframe.getFrameDocument().on( "keydown", function( e )\
|
||||
{\
|
||||
if ( e.data.getKeystroke() == 27 )\
|
||||
dialog.hide();\
|
||||
});'
|
||||
+ '};'
|
||||
+ '</script><style>body { margin: 3px; height: 95%; } </style><body></body>',
|
||||
|
||||
@@ -99,6 +104,12 @@ CKEDITOR.dialog.add( 'paste', function( editor )
|
||||
this.getParentEditor().document.getBody().$.contentEditable = 'true';
|
||||
},
|
||||
|
||||
onLoad : function()
|
||||
{
|
||||
if ( ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) && editor.lang.dir == 'rtl' )
|
||||
this.parts.contents.setStyle( 'overflow', 'hidden' );
|
||||
},
|
||||
|
||||
onOk : function()
|
||||
{
|
||||
var container = this.getContentElement( 'general', 'editing_area' ).getElement(),
|
||||
@@ -106,7 +117,9 @@ CKEDITOR.dialog.add( 'paste', function( editor )
|
||||
editor = this.getParentEditor(),
|
||||
html = iframe.$.contentWindow.document.body.innerHTML;
|
||||
|
||||
editor.insertHtml( html );
|
||||
setTimeout( function(){
|
||||
editor.insertHtml( html );
|
||||
}, 0 );
|
||||
|
||||
},
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ CKEDITOR.plugins.add( 'colorbutton',
|
||||
label : title,
|
||||
title : title,
|
||||
className : 'cke_button_' + name.toLowerCase(),
|
||||
modes : { wysiwyg : 1 },
|
||||
|
||||
panel :
|
||||
{
|
||||
@@ -54,7 +55,7 @@ CKEDITOR.plugins.add( 'colorbutton',
|
||||
function renderColors( panel, type )
|
||||
{
|
||||
var output = [],
|
||||
colors = CKEDITOR.config.colorButton_colors.split( ',' );
|
||||
colors = config.colorButton_colors.split( ',' );
|
||||
|
||||
var clickFn = CKEDITOR.tools.addFunction( function( color, type )
|
||||
{
|
||||
@@ -76,6 +77,7 @@ CKEDITOR.plugins.add( 'colorbutton',
|
||||
style.apply( editor.document );
|
||||
else
|
||||
style.remove( editor.document );
|
||||
editor.fire( 'saveSnapshot' );
|
||||
});
|
||||
|
||||
// Render the "Automatic" button.
|
||||
@@ -139,7 +141,24 @@ CKEDITOR.plugins.add( 'colorbutton',
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Whether to enable the "More Colors..." button in the color selectors.
|
||||
* @default false
|
||||
* @type Boolean
|
||||
* @example
|
||||
* config.colorButton_enableMore = false;
|
||||
*/
|
||||
CKEDITOR.config.colorButton_enableMore = false;
|
||||
|
||||
/**
|
||||
* Defines the colors to be displayed in the color selectors. It's a string
|
||||
* containing the hexadecimal notation for HTML colors, without the "#" prefix.
|
||||
* @type String
|
||||
* @default '000,800000,8B4513,2F4F4F,008080,000080,4B0082,696969,B22222,A52A2A,DAA520,006400,40E0D0,0000CD,800080,808080,F00,FF8C00,FFD700,008000,0FF,00F,EE82EE,A9A9A9,FFA07A,FFA500,FFFF00,00FF00,AFEEEE,ADD8E6,DDA0DD,D3D3D3,FFF0F5,FAEBD7,FFFFE0,F0FFF0,F0FFFF,F0F8FF,E6E6FA,FFF'
|
||||
* @example
|
||||
* // Brazil colors only.
|
||||
* config.colorButton_colors = '00923E,F8C100,28166F';
|
||||
*/
|
||||
CKEDITOR.config.colorButton_colors =
|
||||
'000,800000,8B4513,2F4F4F,008080,000080,4B0082,696969,' +
|
||||
'B22222,A52A2A,DAA520,006400,40E0D0,0000CD,800080,808080,' +
|
||||
@@ -147,6 +166,17 @@ CKEDITOR.config.colorButton_colors =
|
||||
'FFA07A,FFA500,FFFF00,00FF00,AFEEEE,ADD8E6,DDA0DD,D3D3D3,' +
|
||||
'FFF0F5,FAEBD7,FFFFE0,F0FFF0,F0FFFF,F0F8FF,E6E6FA,FFF';
|
||||
|
||||
/**
|
||||
* Holds the style definition to be used to apply the text foreground color.
|
||||
* @type Object
|
||||
* @example
|
||||
* // This is basically the default setting value.
|
||||
* config.colorButton_foreStyle =
|
||||
* {
|
||||
* element : 'span',
|
||||
* styles : { 'color' : '#(color)' }
|
||||
* };
|
||||
*/
|
||||
CKEDITOR.config.colorButton_foreStyle =
|
||||
{
|
||||
element : 'span',
|
||||
@@ -154,6 +184,17 @@ CKEDITOR.config.colorButton_foreStyle =
|
||||
overrides : [ { element : 'font', attributes : { 'color' : null } } ]
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds the style definition to be used to apply the text background color.
|
||||
* @type Object
|
||||
* @example
|
||||
* // This is basically the default setting value.
|
||||
* config.colorButton_backStyle =
|
||||
* {
|
||||
* element : 'span',
|
||||
* styles : { 'background-color' : '#(color)' }
|
||||
* };
|
||||
*/
|
||||
CKEDITOR.config.colorButton_backStyle =
|
||||
{
|
||||
element : 'span',
|
||||
|
||||
@@ -358,7 +358,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
|
||||
* IE BUG: If the initial focus went into a non-text element (e.g. button),
|
||||
* then IE would still leave the caret inside the editing area.
|
||||
*/
|
||||
if ( CKEDITOR.env.ie )
|
||||
if ( this._.editor.mode == 'wysiwyg' && CKEDITOR.env.ie )
|
||||
{
|
||||
var $selection = editor.document.$.selection,
|
||||
$range = $selection.createRange();
|
||||
@@ -442,6 +442,35 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
|
||||
CKEDITOR.skins.load( editor, 'dialog' );
|
||||
};
|
||||
|
||||
// Focusable interface. Use it via dialog.addFocusable.
|
||||
function Focusable( dialog, element, index ) {
|
||||
this.element = element;
|
||||
this.focusIndex = index;
|
||||
this.isFocusable = function()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
this.focus = function()
|
||||
{
|
||||
dialog._.currentFocusIndex = this.focusIndex;
|
||||
this.element.focus();
|
||||
};
|
||||
// Bind events
|
||||
element.on( 'keydown', function( e )
|
||||
{
|
||||
if ( e.data.getKeystroke() in { 32:1, 13:1 } )
|
||||
this.fire( 'click' );
|
||||
} );
|
||||
element.on( 'focus', function()
|
||||
{
|
||||
this.fire( 'mouseover' );
|
||||
} );
|
||||
element.on( 'blur', function()
|
||||
{
|
||||
this.fire( 'mouseout' );
|
||||
} );
|
||||
}
|
||||
|
||||
CKEDITOR.dialog.prototype =
|
||||
{
|
||||
/**
|
||||
@@ -547,7 +576,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
|
||||
*/
|
||||
show : function()
|
||||
{
|
||||
if ( CKEDITOR.env.ie )
|
||||
if ( this._.editor.mode == 'wysiwyg' && CKEDITOR.env.ie )
|
||||
this._.editor.getSelection().lock();
|
||||
|
||||
// Insert the dialog's element to the root document.
|
||||
@@ -618,7 +647,9 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
|
||||
var viewSize = CKEDITOR.document.getWindow().getViewPaneSize();
|
||||
var dialogSize = this.getSize();
|
||||
|
||||
this.move( ( viewSize.width - dialogSize.width ) / 2, ( viewSize.height - dialogSize.height ) / 2 );
|
||||
// We're using definition size for initial position because of
|
||||
// offten corrupted data in offsetWidth at this point. (#4084)
|
||||
this.move( ( viewSize.width - definition.minWidth ) / 2, ( viewSize.height - dialogSize.height ) / 2 );
|
||||
|
||||
this.parts.dialog.setStyle( 'visibility', '' );
|
||||
|
||||
@@ -722,7 +753,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
|
||||
var editor = this._.editor;
|
||||
editor.focus();
|
||||
|
||||
if ( CKEDITOR.env.ie )
|
||||
if ( editor.mode == 'wysiwyg' && CKEDITOR.env.ie )
|
||||
editor.getSelection().unlock( true );
|
||||
}
|
||||
else
|
||||
@@ -988,6 +1019,26 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
|
||||
getSelectedElement : function()
|
||||
{
|
||||
return this.getParentEditor().getSelection().getSelectedElement();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds element to dialog's focusable list.
|
||||
*
|
||||
* @param {CKEDITOR.dom.element} element
|
||||
* @param {Number} [index]
|
||||
*/
|
||||
addFocusable: function( element, index ) {
|
||||
if ( typeof index == 'undefined' )
|
||||
{
|
||||
index = this._.focusList.length;
|
||||
this._.focusList.push( new Focusable( this, element, index ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
this._.focusList.splice( index, 0, new Focusable( this, element, index ) );
|
||||
for ( var i = index + 1 ; i < this._.focusList.length ; i++ )
|
||||
this._.focusList[ i ].focusIndex++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1423,6 +1474,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;
|
||||
|
||||
dialog.parts.title.on( 'mousedown', function( evt )
|
||||
{
|
||||
dialog._.updateSize = true;
|
||||
|
||||
lastCoords = { x : evt.data.$.screenX, y : evt.data.$.screenY };
|
||||
|
||||
CKEDITOR.document.on( 'mousemove', mouseMoveHandler );
|
||||
|
||||
@@ -233,7 +233,12 @@ CKEDITOR.plugins.add( 'dialogui' );
|
||||
{
|
||||
// IE BUG: Text input fields in IE at 100% would exceed a <td> or inline
|
||||
// container's width, so need to wrap it inside a <div>.
|
||||
var html = [ '<div class="cke_dialog_ui_input_', elementDefinition.type, '"><input ' ];
|
||||
var html = [ '<div class="cke_dialog_ui_input_', elementDefinition.type, '"' ];
|
||||
|
||||
if ( elementDefinition.width )
|
||||
html.push( 'style="width:'+ elementDefinition.width +'" ' );
|
||||
|
||||
html.push( '><input ' );
|
||||
for ( var i in attributes )
|
||||
html.push( i + '="' + attributes[i] + '" ' );
|
||||
html.push( ' /></div>' );
|
||||
@@ -332,11 +337,13 @@ CKEDITOR.plugins.add( 'dialogui' );
|
||||
if ( elementDefinition[ 'default' ] )
|
||||
attributes.checked = 'checked';
|
||||
_.checkbox = new CKEDITOR.ui.dialog.uiElement( dialog, myDefinition, html, 'input', null, attributes );
|
||||
html.push( ' ', CKEDITOR.tools.htmlEncode( elementDefinition.label ) );
|
||||
html.push( ' <label for="', attributes.id, '">',
|
||||
CKEDITOR.tools.htmlEncode( elementDefinition.label ),
|
||||
'</label>' );
|
||||
return html.join( '' );
|
||||
};
|
||||
|
||||
CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'label', null, null, innerHTML );
|
||||
CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'span', null, null, innerHTML );
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -393,21 +400,23 @@ CKEDITOR.plugins.add( 'dialogui' );
|
||||
id : null,
|
||||
title : title
|
||||
}, true ),
|
||||
inputHtml = [],
|
||||
inputAttributes =
|
||||
{
|
||||
type : 'radio',
|
||||
'class' : 'cke_dialog_ui_radio_input',
|
||||
name : commonName,
|
||||
value : value
|
||||
};
|
||||
},
|
||||
inputHtml = [];
|
||||
if ( me._['default'] == value )
|
||||
inputAttributes.checked = 'checked';
|
||||
cleanInnerDefinition( inputDefinition );
|
||||
cleanInnerDefinition( labelDefinition );
|
||||
children.push( new CKEDITOR.ui.dialog.uiElement( dialog, inputDefinition, inputHtml, 'input', null, inputAttributes ) );
|
||||
new CKEDITOR.ui.dialog.uiElement( dialog, labelDefinition, inputHtmlList, 'label', null, null,
|
||||
inputHtml.join( '' ) + ' ' + item[0] );
|
||||
inputHtml.push( ' ' );
|
||||
new CKEDITOR.ui.dialog.uiElement( dialog, labelDefinition, inputHtml, 'label', null, { 'for' : inputAttributes.id },
|
||||
item[0] );
|
||||
inputHtmlList.push( inputHtml.join( '' ) );
|
||||
}
|
||||
new CKEDITOR.ui.dialog.hbox( dialog, [], inputHtmlList, html );
|
||||
return html.join( '' );
|
||||
@@ -596,6 +605,7 @@ CKEDITOR.plugins.add( 'dialogui' );
|
||||
' allowtransparency="0"' +
|
||||
' class="cke_dialog_ui_input_file"' +
|
||||
' id="', _.frameId, '"' +
|
||||
' title="', elementDefinition.label, '"' +
|
||||
' src="javascript:void(' ];
|
||||
|
||||
html.push(
|
||||
@@ -812,7 +822,8 @@ CKEDITOR.plugins.add( 'dialogui' );
|
||||
enable : function()
|
||||
{
|
||||
this._.disabled = false;
|
||||
this.getElement().removeClass( 'disabled' );
|
||||
var element = this.getElement();
|
||||
element && element.removeClass( 'disabled' );
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -895,7 +906,11 @@ CKEDITOR.plugins.add( 'dialogui' );
|
||||
var me = this.selectParentTab();
|
||||
|
||||
// GECKO BUG: setTimeout() is needed to workaround invisible selections.
|
||||
setTimeout( function(){ me.getInputElement().$.focus(); }, 0 );
|
||||
setTimeout( function()
|
||||
{
|
||||
var element = me.getInputElement();
|
||||
element && element.$.focus();
|
||||
}, 0 );
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -907,7 +922,15 @@ CKEDITOR.plugins.add( 'dialogui' );
|
||||
var me = this.selectParentTab();
|
||||
|
||||
// GECKO BUG: setTimeout() is needed to workaround invisible selections.
|
||||
setTimeout( function(){ var e = me.getInputElement().$; e.focus(); e.select(); }, 0 );
|
||||
setTimeout( function()
|
||||
{
|
||||
var e = me.getInputElement();
|
||||
if ( e )
|
||||
{
|
||||
e.$.focus();
|
||||
e.$.select();
|
||||
}
|
||||
}, 0 );
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1233,6 +1256,10 @@ CKEDITOR.plugins.add( 'dialogui' );
|
||||
if ( CKEDITOR.env.isCustomDomain() )
|
||||
frameDocument.$.domain = document.domain;
|
||||
|
||||
var size = '';
|
||||
if ( elementDefinition.size )
|
||||
size = elementDefinition.size - ( CKEDITOR.env.ie ? 7 : 0 ); // "Browse" button is bigger in IE.
|
||||
|
||||
frameDocument.$.write( [ '<html><head><title></title></head><body style="margin: 0; overflow: hidden; background: transparent;">',
|
||||
'<form enctype="multipart/form-data" method="POST" action="',
|
||||
CKEDITOR.tools.htmlEncode( elementDefinition.action ),
|
||||
@@ -1240,7 +1267,7 @@ CKEDITOR.plugins.add( 'dialogui' );
|
||||
'<input type="file" name="',
|
||||
CKEDITOR.tools.htmlEncode( elementDefinition.id || 'cke_upload' ),
|
||||
'" size="',
|
||||
CKEDITOR.tools.htmlEncode( elementDefinition.size || '' ),
|
||||
CKEDITOR.tools.htmlEncode( size > 0 ? size : "" ),
|
||||
'" />',
|
||||
'</form>',
|
||||
'</body></html>' ].join( '' ) );
|
||||
|
||||
@@ -19,6 +19,9 @@ CKEDITOR.plugins.add( 'domiterator' );
|
||||
|
||||
this.range = range;
|
||||
this.forceBrBreak = false;
|
||||
|
||||
// Whether include <br>s into the enlarged range.(#3730).
|
||||
this.enlargeBr = true;
|
||||
this.enforceRealBlocks = false;
|
||||
|
||||
this._ || ( this._ = {} );
|
||||
@@ -45,7 +48,8 @@ CKEDITOR.plugins.add( 'domiterator' );
|
||||
if ( !this._.lastNode )
|
||||
{
|
||||
range = this.range.clone();
|
||||
range.enlarge( this.forceBrBreak ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
|
||||
range.enlarge( this.forceBrBreak || !this.enlargeBr ?
|
||||
CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
|
||||
|
||||
var walker = new CKEDITOR.dom.walker( range ),
|
||||
ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( true, true );
|
||||
@@ -57,12 +61,32 @@ CKEDITOR.plugins.add( 'domiterator' );
|
||||
walker.evaluator = ignoreBookmarkTextEvaluator;
|
||||
var lastNode = walker.previous();
|
||||
this._.lastNode = lastNode.getNextSourceNode( true );
|
||||
|
||||
// We may have an empty text node at the end of block due to [3770].
|
||||
// If that node is the lastNode, it would cause our logic to leak to the
|
||||
// next block.(#3887)
|
||||
if ( this._.lastNode &&
|
||||
this._.lastNode.type == CKEDITOR.NODE_TEXT &&
|
||||
!CKEDITOR.tools.trim( this._.lastNode.getText( ) ) &&
|
||||
this._.lastNode.getParent().isBlockBoundary() )
|
||||
{
|
||||
var testRange = new CKEDITOR.dom.range( range.document );
|
||||
testRange.moveToPosition( this._.lastNode, CKEDITOR.POSITION_AFTER_END );
|
||||
if ( testRange.checkEndOfBlock() )
|
||||
{
|
||||
var path = new CKEDITOR.dom.elementPath( testRange.endContainer );
|
||||
var lastBlock = path.block || path.blockLimit;
|
||||
this._.lastNode = lastBlock.getNextSourceNode( true );
|
||||
}
|
||||
}
|
||||
|
||||
// Probably the document end is reached, we need a marker node.
|
||||
if ( !this._.lastNode )
|
||||
{
|
||||
this._.lastNode = range.document.createText( '' );
|
||||
this._.lastNode.insertAfter( lastNode );
|
||||
this._.lastNode = this._.docEndMarker = range.document.createText( '' );
|
||||
this._.lastNode.insertAfter( lastNode );
|
||||
}
|
||||
|
||||
// Let's reuse this variable.
|
||||
range = null;
|
||||
}
|
||||
@@ -180,6 +204,9 @@ CKEDITOR.plugins.add( 'domiterator' );
|
||||
if ( includeNode )
|
||||
range.setEndAt( currentNode, CKEDITOR.POSITION_AFTER_END );
|
||||
|
||||
currentNode = currentNode.getNextSourceNode( continueFromSibling, null, lastNode );
|
||||
isLast = !currentNode;
|
||||
|
||||
// We have found a block boundary. Let's close the range and move out of the
|
||||
// loop.
|
||||
if ( ( closeRange || isLast ) && range )
|
||||
@@ -187,10 +214,16 @@ CKEDITOR.plugins.add( 'domiterator' );
|
||||
var boundaryNodes = range.getBoundaryNodes(),
|
||||
startPath = new CKEDITOR.dom.elementPath( range.startContainer ),
|
||||
endPath = new CKEDITOR.dom.elementPath( range.endContainer );
|
||||
|
||||
// Drop the range if it only contains bookmark nodes.(#4087)
|
||||
if ( boundaryNodes.startNode.equals( boundaryNodes.endNode )
|
||||
&& boundaryNodes.startNode.getParent().equals( startPath.blockLimit )
|
||||
&& boundaryNodes.startNode.type == CKEDITOR.NODE_ELEMENT && boundaryNodes.startNode.getAttribute( '_fck_bookmark' ) )
|
||||
&& boundaryNodes.startNode.getParent().equals( startPath.blockLimit )
|
||||
&& boundaryNodes.startNode.type == CKEDITOR.NODE_ELEMENT
|
||||
&& boundaryNodes.startNode.getAttribute( '_fck_bookmark' ) )
|
||||
{
|
||||
range = null;
|
||||
this._.nextNode = null;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -198,7 +231,6 @@ CKEDITOR.plugins.add( 'domiterator' );
|
||||
if ( isLast )
|
||||
break;
|
||||
|
||||
currentNode = currentNode.getNextSourceNode( continueFromSibling, null, lastNode );
|
||||
}
|
||||
|
||||
// Now, based on the processed range, look for (or create) the block to be returned.
|
||||
@@ -207,6 +239,7 @@ CKEDITOR.plugins.add( 'domiterator' );
|
||||
// If no range has been found, this is the end.
|
||||
if ( !range )
|
||||
{
|
||||
this._.docEndMarker && this._.docEndMarker.remove();
|
||||
this._.nextNode = null;
|
||||
return null;
|
||||
}
|
||||
@@ -287,11 +320,16 @@ CKEDITOR.plugins.add( 'domiterator' );
|
||||
|
||||
if ( removeLastBr )
|
||||
{
|
||||
// Ignore bookmark nodes.(#3783)
|
||||
var bookmarkGuard = CKEDITOR.dom.walker.bookmark( false, true );
|
||||
|
||||
var lastChild = block.getLast();
|
||||
if ( lastChild && lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.getName() == 'br' )
|
||||
{
|
||||
// Take care not to remove the block expanding <br> in non-IE browsers.
|
||||
if ( CKEDITOR.env.ie || lastChild.getPrevious() || lastChild.getNext() )
|
||||
if ( CKEDITOR.env.ie
|
||||
|| lastChild.getPrevious( bookmarkGuard )
|
||||
|| lastChild.getNext( bookmarkGuard ) )
|
||||
lastChild.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +169,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
if ( mode == this.mode )
|
||||
return;
|
||||
|
||||
this.fire( 'beforeModeUnload' );
|
||||
|
||||
var currentMode = getMode( this );
|
||||
data = currentMode.getData();
|
||||
currentMode.unload( holderElement );
|
||||
@@ -211,7 +213,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
* @type String
|
||||
* @default 'wysiwyg'
|
||||
* @example
|
||||
* config.toolbarLocation = 'source';
|
||||
* config.startupMode = 'source';
|
||||
*/
|
||||
CKEDITOR.config.startupMode = 'wysiwyg';
|
||||
|
||||
@@ -219,7 +221,16 @@ CKEDITOR.config.startupMode = 'wysiwyg';
|
||||
* Sets whether the editor should have the focus when the page loads.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
* @example
|
||||
* config.startupFocus = true;
|
||||
*/
|
||||
CKEDITOR.config.startupFocus = false;
|
||||
|
||||
/**
|
||||
* Whether to render or not the editing block area in the editor interface.
|
||||
* @type Boolean
|
||||
* @default true
|
||||
* @example
|
||||
* config.editingBlock = false;
|
||||
*/
|
||||
CKEDITOR.config.editingBlock = true;
|
||||
|
||||
@@ -256,6 +256,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
else
|
||||
lineBreak = doc.createElement( 'br' );
|
||||
|
||||
range.deleteContents();
|
||||
range.insertNode( lineBreak );
|
||||
|
||||
// A text node is required by Gecko only to make the cursor blink.
|
||||
|
||||
@@ -145,8 +145,56 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
});
|
||||
})();
|
||||
|
||||
/**
|
||||
* Whether to use HTML entities in the output.
|
||||
* @type Boolean
|
||||
* @default true
|
||||
* @example
|
||||
* config.entities = false;
|
||||
*/
|
||||
CKEDITOR.config.entities = true;
|
||||
|
||||
/**
|
||||
* Whether to convert some Latin characters (Latin alphabet No. 1, ISO 8859-1)
|
||||
* to HTML entities. The list of entities can be found at the
|
||||
* <a href="http://www.w3.org/TR/html4/sgml/entities.html#h-24.2.1">W3C HTML 4.01 Specification, section 24.2.1</a>.
|
||||
* @type Boolean
|
||||
* @default true
|
||||
* @example
|
||||
* config.entities_latin = false;
|
||||
*/
|
||||
CKEDITOR.config.entities_latin = true;
|
||||
|
||||
/**
|
||||
* Whether to convert some symbols, mathematical symbols, and Greek letters to
|
||||
* HTML entities. This may be more relevant for users typing text written in Greek.
|
||||
* The list of entities can be found at the
|
||||
* <a href="http://www.w3.org/TR/html4/sgml/entities.html#h-24.3.1">W3C HTML 4.01 Specification, section 24.3.1</a>.
|
||||
* @type Boolean
|
||||
* @default true
|
||||
* @example
|
||||
* config.entities_greek = false;
|
||||
*/
|
||||
CKEDITOR.config.entities_greek = true;
|
||||
|
||||
/**
|
||||
* Whether to convert all remaining characters, not comprised in the ASCII
|
||||
* character table, to their relative numeric representation of HTML entity.
|
||||
* For example, the phrase "This is Chinese: 汉语." is outputted
|
||||
* as "This is Chinese: &#27721;&#35821;."
|
||||
* @type Boolean
|
||||
* @default false
|
||||
* @example
|
||||
* config.entities_processNumerical = true;
|
||||
*/
|
||||
CKEDITOR.config.entities_processNumerical = false;
|
||||
|
||||
/**
|
||||
* An additional list of entities to be used. It's a string containing each
|
||||
* entry separated by a comma. Entities names or number must be used, exclusing
|
||||
* the "&" preffix and the ";" termination.
|
||||
* @default '#39' // The single quote (') character.
|
||||
* @type String
|
||||
* @example
|
||||
*/
|
||||
CKEDITOR.config.entities_additional = '#39';
|
||||
|
||||
@@ -711,7 +711,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
dialog.getValueOf( 'replace', 'txtReplaceCaseChk' ),
|
||||
dialog.getValueOf( 'replace', 'txtReplaceWordChk' ),
|
||||
false, true ) )
|
||||
;
|
||||
{ /*jsl:pass*/ }
|
||||
|
||||
if ( finder.replaceCounter )
|
||||
{
|
||||
|
||||
@@ -31,5 +31,16 @@ CKEDITOR.plugins.add( 'find',
|
||||
requires : [ 'styles' ]
|
||||
} );
|
||||
|
||||
// Styles for highlighting search results.
|
||||
/**
|
||||
* Defines the style to be used to highlight results with the find dialog.
|
||||
* @type Object
|
||||
* @default { element : 'span', styles : { 'background-color' : '#004', 'color' : '#fff' } }
|
||||
* @example
|
||||
* // Highlight search results with blue on yellow.
|
||||
* config.find_highlight =
|
||||
* {
|
||||
* element : 'span',
|
||||
* styles : { 'background-color' : '#ff0', 'color' : '#00f' }
|
||||
* };
|
||||
*/
|
||||
CKEDITOR.config.find_highlight = { element : 'span', styles : { 'background-color' : '#004', 'color' : '#fff' } };
|
||||
|
||||
@@ -356,6 +356,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
type : 'text',
|
||||
id : 'width',
|
||||
style : 'width:95px',
|
||||
label : editor.lang.flash.width,
|
||||
validate : CKEDITOR.dialog.validate.integer( editor.lang.flash.validateWidth ),
|
||||
setup : function( objectNode, embedNode, paramMap, fakeImage )
|
||||
@@ -378,6 +379,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
type : 'text',
|
||||
id : 'height',
|
||||
style : 'width:95px',
|
||||
label : editor.lang.flash.height,
|
||||
validate : CKEDITOR.dialog.validate.integer( editor.lang.flash.validateHeight ),
|
||||
setup : function( objectNode, embedNode, paramMap, fakeImage )
|
||||
@@ -400,6 +402,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
type : 'text',
|
||||
id : 'hSpace',
|
||||
style : 'width:95px',
|
||||
label : editor.lang.flash.hSpace,
|
||||
validate : CKEDITOR.dialog.validate.integer( editor.lang.flash.validateHSpace ),
|
||||
setup : loadValue,
|
||||
@@ -408,6 +411,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
type : 'text',
|
||||
id : 'vSpace',
|
||||
style : 'width:95px',
|
||||
label : editor.lang.flash.vSpace,
|
||||
validate : CKEDITOR.dialog.validate.integer( editor.lang.flash.validateVSpace ),
|
||||
setup : loadValue,
|
||||
|
||||
@@ -19,7 +19,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
var attributes = element.attributes;
|
||||
|
||||
return ( attributes.type != 'application/x-shockwave-flash' || !flashFilenameRegex.test( attributes.src || '' ) );
|
||||
return ( attributes.type == 'application/x-shockwave-flash' || flashFilenameRegex.test( attributes.src || '' ) );
|
||||
}
|
||||
|
||||
function createFakeElement( editor, realElement )
|
||||
|
||||
@@ -121,6 +121,9 @@ CKEDITOR.plugins.add( 'floatpanel',
|
||||
if ( corner == 3 || corner == 4 )
|
||||
top += offsetParent.$.offsetHeight - 1;
|
||||
|
||||
// Memorize offsetParent by it's ID.
|
||||
this._.panel._.offsetParentId = offsetParent.getId();
|
||||
|
||||
element.setStyles(
|
||||
{
|
||||
top : top + 'px',
|
||||
@@ -180,7 +183,7 @@ CKEDITOR.plugins.add( 'floatpanel',
|
||||
},
|
||||
this );
|
||||
|
||||
setTimeout( function()
|
||||
CKEDITOR.tools.setTimeout( function()
|
||||
{
|
||||
if ( rtl )
|
||||
left -= element.$.offsetWidth;
|
||||
@@ -211,15 +214,8 @@ CKEDITOR.plugins.add( 'floatpanel',
|
||||
panel._.currentBlock.element.setStyle( 'display', 'none' ).removeStyle( 'display' );
|
||||
}
|
||||
|
||||
if ( !CKEDITOR.env.gecko || panel.isLoaded )
|
||||
{
|
||||
// IE7 needs some time (setting the delay to 0ms won't work) to refresh
|
||||
// the scrollHeight. (#3174)
|
||||
if ( CKEDITOR.env.ie && CKEDITOR.env.version >= 7 )
|
||||
setTimeout( setHeight, 50 );
|
||||
else
|
||||
setHeight();
|
||||
}
|
||||
if ( panel.isLoaded )
|
||||
setHeight();
|
||||
else
|
||||
panel.onLoad = setHeight;
|
||||
}
|
||||
@@ -227,7 +223,7 @@ CKEDITOR.plugins.add( 'floatpanel',
|
||||
element.getFirst().removeStyle( 'height' );
|
||||
|
||||
// Set the IFrame focus, so the blur event gets fired.
|
||||
setTimeout( function()
|
||||
CKEDITOR.tools.setTimeout( function()
|
||||
{
|
||||
if ( definition.voiceLabel )
|
||||
{
|
||||
@@ -244,9 +240,12 @@ CKEDITOR.plugins.add( 'floatpanel',
|
||||
iframe.focus();
|
||||
else
|
||||
iframe.$.contentWindow.focus();
|
||||
}, 0);
|
||||
}, 0);
|
||||
|
||||
// We need this get fired manually because of unfired focus() function.
|
||||
if ( CKEDITOR.env.ie && !CKEDITOR.env.quirks )
|
||||
this.allowBlur( true );
|
||||
}, 0, this);
|
||||
}, 0, this);
|
||||
this.visible = 1;
|
||||
|
||||
if ( this.onShow )
|
||||
@@ -276,6 +275,10 @@ CKEDITOR.plugins.add( 'floatpanel',
|
||||
|
||||
showAsChild : function( panel, blockName, offsetParent, corner, offsetX, offsetY )
|
||||
{
|
||||
// Skip reshowing of child which is already visible.
|
||||
if ( this._.activeChild == panel && panel._.panel._.offsetParentId == offsetParent.getId() )
|
||||
return;
|
||||
|
||||
this.hideChild();
|
||||
|
||||
panel.onHide = CKEDITOR.tools.bind( function()
|
||||
|
||||
@@ -117,8 +117,24 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
});
|
||||
})();
|
||||
|
||||
// Font settings.
|
||||
|
||||
/**
|
||||
* The list of fonts names to be displayed in the Font combo in the toolbar.
|
||||
* Entries are separated by semi-colons (;), while it's possible to have more
|
||||
* than one font for each entry, in the HTML way (separated by comma).
|
||||
*
|
||||
* A display name may be optionally defined by prefixing the entries with the
|
||||
* name and the slash character. For example, "Arial/Arial, Helvetica, sans-serif"
|
||||
* will be displayed as "Arial" in the list, but will be outputted as
|
||||
* "Arial, Helvetica, sans-serif".
|
||||
* @type String
|
||||
* @example
|
||||
* config.font_names =
|
||||
* 'Arial/Arial, Helvetica, sans-serif;' +
|
||||
* 'Times New Roman/Times New Roman, Times, serif;' +
|
||||
* 'Verdana';
|
||||
* @example
|
||||
* config.font_names = 'Arial;Times New Roman;Verdana';
|
||||
*/
|
||||
CKEDITOR.config.font_names =
|
||||
'Arial/Arial, Helvetica, sans-serif;' +
|
||||
'Comic Sans MS/Comic Sans MS, cursive;' +
|
||||
@@ -130,7 +146,28 @@ CKEDITOR.config.font_names =
|
||||
'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' +
|
||||
'Verdana/Verdana, Geneva, sans-serif';
|
||||
|
||||
/**
|
||||
* The text to be displayed in the Font combo is none of the available values
|
||||
* matches the current cursor position or text selection.
|
||||
* @type String
|
||||
* @example
|
||||
* // If the default site font is Arial, we may making it more explicit to the end user.
|
||||
* config.font_defaultLabel = 'Arial';
|
||||
*/
|
||||
CKEDITOR.config.font_defaultLabel = '';
|
||||
|
||||
/**
|
||||
* The style definition to be used to apply the font in the text.
|
||||
* @type Object
|
||||
* @example
|
||||
* // This is actually the default value for it.
|
||||
* config.font_style =
|
||||
* {
|
||||
* element : 'span',
|
||||
* styles : { 'font-family' : '#(family)' },
|
||||
* overrides : [ { element : 'font', attributes : { 'face' : null } } ]
|
||||
* };
|
||||
*/
|
||||
CKEDITOR.config.font_style =
|
||||
{
|
||||
element : 'span',
|
||||
@@ -138,15 +175,53 @@ CKEDITOR.config.font_style =
|
||||
overrides : [ { element : 'font', attributes : { 'face' : null } } ]
|
||||
};
|
||||
|
||||
// Font Size setting.
|
||||
|
||||
/**
|
||||
* The list of fonts size to be displayed in the Font Size combo in the
|
||||
* toolbar. Entries are separated by semi-colons (;).
|
||||
*
|
||||
* Any kind of "CSS like" size can be used, like "12px", "2.3em", "130%",
|
||||
* "larger" or "x-small".
|
||||
*
|
||||
* A display name may be optionally defined by prefixing the entries with the
|
||||
* name and the slash character. For example, "Bigger Font/14px" will be
|
||||
* displayed as "Bigger Font" in the list, but will be outputted as "14px".
|
||||
* @type String
|
||||
* @default '8/8px;9/9px;10/10px;11/11px;12/12px;14/14px;16/16px;18/18px;20/20px;22/22px;24/24px;26/26px;28/28px;36/36px;48/48px;72/72px'
|
||||
* @example
|
||||
* config.fontSize_sizes = '16/16px;24/24px;48/48px;';
|
||||
* @example
|
||||
* config.fontSize_sizes = '12px;2.3em;130%;larger;x-small';
|
||||
* @example
|
||||
* config.fontSize_sizes = '12 Pixels/12px;Big/2.3em;30 Percent More/130%;Bigger/larger;Very Small/x-small';
|
||||
*/
|
||||
CKEDITOR.config.fontSize_sizes =
|
||||
'8/8px;9/9px;10/10px;11/11px;12/12px;14/14px;16/16px;18/18px;20/20px;22/22px;24/24px;26/26px;28/28px;36/36px;48/48px;72/72px';
|
||||
|
||||
/**
|
||||
* The text to be displayed in the Font Size combo is none of the available
|
||||
* values matches the current cursor position or text selection.
|
||||
* @type String
|
||||
* @example
|
||||
* // If the default site font size is 12px, we may making it more explicit to the end user.
|
||||
* config.fontSize_defaultLabel = '12px';
|
||||
*/
|
||||
CKEDITOR.config.fontSize_defaultLabel = '';
|
||||
|
||||
/**
|
||||
* The style definition to be used to apply the font size in the text.
|
||||
* @type Object
|
||||
* @example
|
||||
* // This is actually the default value for it.
|
||||
* config.fontSize_style =
|
||||
* {
|
||||
* element : 'span',
|
||||
* styles : { 'font-size' : '#(size)' },
|
||||
* overrides : [ { element : 'font', attributes : { 'size' : null } } ]
|
||||
* };
|
||||
*/
|
||||
CKEDITOR.config.fontSize_style =
|
||||
{
|
||||
element : 'span',
|
||||
styles : { 'font-size' : '#(size)' },
|
||||
overrides : [ { element : 'font', attributes : { 'face' : null } } ]
|
||||
overrides : [ { element : 'font', attributes : { 'size' : null } } ]
|
||||
};
|
||||
|
||||
@@ -87,15 +87,105 @@ CKEDITOR.plugins.add( 'format',
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* A list of semi colon separated style names (by default tags) representing
|
||||
* the style definition for each entry to be displayed in the Format combo in
|
||||
* the toolbar. Each entry must have its relative definition configuration in a
|
||||
* setting named "format_(tagName)". For example, the "p" entry has its
|
||||
* definition taken from config.format_p.
|
||||
* @type String
|
||||
* @default 'p;h1;h2;h3;h4;h5;h6;pre;address;div'
|
||||
* @example
|
||||
* config.format_tags = 'p;h2;h3;pre'
|
||||
*/
|
||||
CKEDITOR.config.format_tags = 'p;h1;h2;h3;h4;h5;h6;pre;address;div';
|
||||
|
||||
CKEDITOR.config.format_p = { element : 'p' };
|
||||
CKEDITOR.config.format_div = { element : 'div' };
|
||||
CKEDITOR.config.format_pre = { element : 'pre' };
|
||||
CKEDITOR.config.format_address = { element : 'address' };
|
||||
CKEDITOR.config.format_h1 = { element : 'h1' };
|
||||
CKEDITOR.config.format_h2 = { element : 'h2' };
|
||||
CKEDITOR.config.format_h3 = { element : 'h3' };
|
||||
CKEDITOR.config.format_h4 = { element : 'h4' };
|
||||
CKEDITOR.config.format_h5 = { element : 'h5' };
|
||||
CKEDITOR.config.format_h6 = { element : 'h6' };
|
||||
/**
|
||||
* The style definition to be used to apply the "Normal" format.
|
||||
* @type Object
|
||||
* @default { element : 'p' }
|
||||
* @example
|
||||
* config.format_p = { element : 'p', attributes : { class : 'normalPara' } };
|
||||
*/
|
||||
CKEDITOR.config.format_p = { element : 'p' };
|
||||
|
||||
/**
|
||||
* The style definition to be used to apply the "Normal (DIV)" format.
|
||||
* @type Object
|
||||
* @default { element : 'div' }
|
||||
* @example
|
||||
* config.format_div = { element : 'div', attributes : { class : 'normalDiv' } };
|
||||
*/
|
||||
CKEDITOR.config.format_div = { element : 'div' };
|
||||
|
||||
/**
|
||||
* The style definition to be used to apply the "Formatted" format.
|
||||
* @type Object
|
||||
* @default { element : 'pre' }
|
||||
* @example
|
||||
* config.format_pre = { element : 'pre', attributes : { class : 'code' } };
|
||||
*/
|
||||
CKEDITOR.config.format_pre = { element : 'pre' };
|
||||
|
||||
/**
|
||||
* The style definition to be used to apply the "Address" format.
|
||||
* @type Object
|
||||
* @default { element : 'address' }
|
||||
* @example
|
||||
* config.format_address = { element : 'address', attributes : { class : 'styledAddress' } };
|
||||
*/
|
||||
CKEDITOR.config.format_address = { element : 'address' };
|
||||
|
||||
/**
|
||||
* The style definition to be used to apply the "Heading 1" format.
|
||||
* @type Object
|
||||
* @default { element : 'h1' }
|
||||
* @example
|
||||
* config.format_h1 = { element : 'h1', attributes : { class : 'contentTitle1' } };
|
||||
*/
|
||||
CKEDITOR.config.format_h1 = { element : 'h1' };
|
||||
|
||||
/**
|
||||
* The style definition to be used to apply the "Heading 1" format.
|
||||
* @type Object
|
||||
* @default { element : 'h2' }
|
||||
* @example
|
||||
* config.format_h2 = { element : 'h2', attributes : { class : 'contentTitle2' } };
|
||||
*/
|
||||
CKEDITOR.config.format_h2 = { element : 'h2' };
|
||||
|
||||
/**
|
||||
* The style definition to be used to apply the "Heading 1" format.
|
||||
* @type Object
|
||||
* @default { element : 'h3' }
|
||||
* @example
|
||||
* config.format_h3 = { element : 'h3', attributes : { class : 'contentTitle3' } };
|
||||
*/
|
||||
CKEDITOR.config.format_h3 = { element : 'h3' };
|
||||
|
||||
/**
|
||||
* The style definition to be used to apply the "Heading 1" format.
|
||||
* @type Object
|
||||
* @default { element : 'h4' }
|
||||
* @example
|
||||
* config.format_h4 = { element : 'h4', attributes : { class : 'contentTitle4' } };
|
||||
*/
|
||||
CKEDITOR.config.format_h4 = { element : 'h4' };
|
||||
|
||||
/**
|
||||
* The style definition to be used to apply the "Heading 1" format.
|
||||
* @type Object
|
||||
* @default { element : 'h5' }
|
||||
* @example
|
||||
* config.format_h5 = { element : 'h5', attributes : { class : 'contentTitle5' } };
|
||||
*/
|
||||
CKEDITOR.config.format_h5 = { element : 'h5' };
|
||||
|
||||
/**
|
||||
* The style definition to be used to apply the "Heading 1" format.
|
||||
* @type Object
|
||||
* @default { element : 'h6' }
|
||||
* @example
|
||||
* config.format_h6 = { element : 'h6', attributes : { class : 'contentTitle6' } };
|
||||
*/
|
||||
CKEDITOR.config.format_h6 = { element : 'h6' };
|
||||
|
||||
@@ -9,7 +9,7 @@ CKEDITOR.dialog.add( 'form', function( editor )
|
||||
action : 1,
|
||||
id : 1,
|
||||
method : 1,
|
||||
encoding : 1,
|
||||
enctype : 1,
|
||||
target : 1
|
||||
};
|
||||
|
||||
@@ -119,7 +119,7 @@ CKEDITOR.dialog.add( 'form', function( editor )
|
||||
accessKey : 'I'
|
||||
},
|
||||
{
|
||||
id : 'encoding',
|
||||
id : 'enctype',
|
||||
type : 'select',
|
||||
label : editor.lang.form.encoding,
|
||||
style : 'width:100%',
|
||||
|
||||
@@ -6,7 +6,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
(function()
|
||||
{
|
||||
// Regex to scan for at the end of blocks, which are actually placeholders.
|
||||
var tailNbspRegex = /^[\t\r\n ]* $/;
|
||||
// Safari transforms the to \xa0. (#4172)
|
||||
var tailNbspRegex = /^[\t\r\n ]*(?: |\xa0)$/;
|
||||
|
||||
var protectedSourceMarker = '{cke_protected}';
|
||||
|
||||
@@ -72,12 +73,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
delete blockLikeTags.pre;
|
||||
var defaultDataFilterRules =
|
||||
{
|
||||
elementNames :
|
||||
[
|
||||
// Elements that cause problems in wysiwyg mode.
|
||||
[ ( /^(object|embed|param)$/ ), 'cke:$1' ]
|
||||
],
|
||||
|
||||
attributeNames :
|
||||
[
|
||||
// Event attributes (onXYZ) must not be directly set. They can become
|
||||
@@ -91,17 +86,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
for ( i in blockLikeTags )
|
||||
defaultDataBlockFilterRules.elements[ i ] = extendBlockForDisplay;
|
||||
|
||||
/**
|
||||
* IE sucks with dynamic 'name' attribute after element is created, '_cke_saved_name' is used instead for this attribute.
|
||||
*/
|
||||
var removeName = function( element )
|
||||
{
|
||||
var attribs = element.attributes;
|
||||
|
||||
if ( attribs._cke_saved_name )
|
||||
delete attribs.name;
|
||||
};
|
||||
|
||||
var defaultHtmlFilterRules =
|
||||
{
|
||||
elementNames :
|
||||
@@ -124,6 +108,23 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
|
||||
elements :
|
||||
{
|
||||
$ : function( element )
|
||||
{
|
||||
// Remove duplicated attributes - #3789.
|
||||
var attribs = element.attributes;
|
||||
|
||||
if ( attribs )
|
||||
{
|
||||
var attributeNames = [ 'name', 'href', 'src' ],
|
||||
savedAttributeName;
|
||||
for ( var i = 0 ; i < attributeNames.length ; i++ )
|
||||
{
|
||||
savedAttributeName = '_cke_saved_' + attributeNames[ i ];
|
||||
savedAttributeName in attribs && ( delete attribs[ attributeNames[ i ] ] );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
embed : function( element )
|
||||
{
|
||||
var parent = element.parent;
|
||||
@@ -132,35 +133,30 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
// and height attributes from it.
|
||||
if ( parent && parent.name == 'object' )
|
||||
{
|
||||
element.attributes.width = parent.attributes.width;
|
||||
element.attributes.height = parent.attributes.height;
|
||||
var parentWidth = parent.attributes.width,
|
||||
parentHeight = parent.attributes.height;
|
||||
parentWidth && ( element.attributes.width = parentWidth );
|
||||
parentHeight && ( element.attributes.height = parentHeight );
|
||||
}
|
||||
},
|
||||
|
||||
img : function( element )
|
||||
// Restore param elements into self-closing.
|
||||
param : function( param )
|
||||
{
|
||||
var attribs = element.attributes;
|
||||
|
||||
if ( attribs._cke_saved_name )
|
||||
delete attribs.name;
|
||||
if ( attribs._cke_saved_src )
|
||||
delete attribs.src;
|
||||
param.children = [];
|
||||
param.isEmpty = true;
|
||||
return param;
|
||||
},
|
||||
|
||||
// Remove empty link but not empty anchor.(#3829)
|
||||
a : function( element )
|
||||
{
|
||||
var attribs = element.attributes;
|
||||
|
||||
if ( attribs._cke_saved_name )
|
||||
delete attribs.name;
|
||||
if ( attribs._cke_saved_href )
|
||||
delete attribs.href;
|
||||
},
|
||||
|
||||
input : removeName,
|
||||
textarea : removeName,
|
||||
select : removeName,
|
||||
form : removeName
|
||||
if ( !( element.children.length ||
|
||||
element.attributes.name ||
|
||||
element.attributes._cke_saved_name ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
attributes :
|
||||
@@ -205,6 +201,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
|
||||
var protectStyleTagsRegex = /<(style)(?=[ >])[^>]*>[^<]*<\/\1>/gi;
|
||||
var encodedTagsRegex = /<cke:encoded>([^<]*)<\/cke:encoded>/gi;
|
||||
var protectElementNamesRegex = /(<\/?)((?:object|embed|param).*?>)/gi;
|
||||
var protectSelfClosingRegex = /<cke:param(.*?)\/>/gi;
|
||||
|
||||
function protectStyleTagsMatch( match )
|
||||
{
|
||||
@@ -215,6 +213,14 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
return html.replace( protectStyleTagsRegex, protectStyleTagsMatch );
|
||||
}
|
||||
function protectElementsNames( html )
|
||||
{
|
||||
return html.replace( protectElementNamesRegex, '$1cke:$2');
|
||||
}
|
||||
function protectSelfClosingElements( html )
|
||||
{
|
||||
return html.replace( protectSelfClosingRegex, '<cke:param$1></cke:param>' );
|
||||
}
|
||||
|
||||
function unprotectEncodedTagsMatch( match, encoded )
|
||||
{
|
||||
@@ -228,11 +234,13 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
|
||||
function protectSource( data, protectRegexes )
|
||||
{
|
||||
var protectedHtml = [],
|
||||
tempRegex = /<\!--\{cke_temp\}(\d*?)-->/g;
|
||||
var regexes =
|
||||
[
|
||||
// First of any other protection, we must protect all comments
|
||||
// to avoid loosing them (of course, IE related).
|
||||
/<!--[\s\S]*?-->/g,
|
||||
(/<!--[\s\S]*?-->/g),
|
||||
|
||||
// Script tags will also be forced to be protected, otherwise
|
||||
// IE will execute them.
|
||||
@@ -247,10 +255,22 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
data = data.replace( regexes[i], function( match )
|
||||
{
|
||||
return '<!--' + protectedSourceMarker + encodeURIComponent( match ).replace( /--/g, '%2D%2D' ) + '-->';
|
||||
match = match.replace( tempRegex, // There could be protected source inside another one. (#3869).
|
||||
function( $, id )
|
||||
{
|
||||
return protectedHtml[ id ];
|
||||
}
|
||||
);
|
||||
return '<!--{cke_temp}' + ( protectedHtml.push( match ) - 1 ) + '-->';
|
||||
});
|
||||
}
|
||||
|
||||
data = data.replace( tempRegex, function( $, id )
|
||||
{
|
||||
return '<!--' + protectedSourceMarker +
|
||||
encodeURIComponent( protectedHtml[ id ] ).replace( /--/g, '%2D%2D' ) +
|
||||
'-->';
|
||||
}
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -298,11 +318,20 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
if ( CKEDITOR.env.ie )
|
||||
data = protectStyleTags( data );
|
||||
|
||||
// Certain elements has problem to go through DOM operation, protect
|
||||
// them by prefixing 'cke' namespace.(#3591)
|
||||
data = protectElementsNames( data );
|
||||
|
||||
// All none-IE browsers ignore self-closed custom elements,
|
||||
// protecting them into open-close.(#3591)
|
||||
data = protectSelfClosingElements( data );
|
||||
|
||||
// Call the browser to help us fixing a possibly invalid HTML
|
||||
// structure.
|
||||
var div = document.createElement( 'div' );
|
||||
div.innerHTML = data;
|
||||
data = div.innerHTML;
|
||||
// Add fake character to workaround IE comments bug. (#3801)
|
||||
div.innerHTML = 'a' + data;
|
||||
data = div.innerHTML.substr( 1 );
|
||||
|
||||
if ( CKEDITOR.env.ie )
|
||||
data = unprotectEncodedTags( data );
|
||||
@@ -331,4 +360,14 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* Whether to force using "&" instead of "&amp;" in elements attributes
|
||||
* values. It's not recommended to change this setting for compliance with the
|
||||
* W3C XHTML 1.0 standards
|
||||
* (<a href="http://www.w3.org/TR/xhtml1/#C_12">C.12, XHTML 1.0</a>).
|
||||
* @type Boolean
|
||||
* @default false
|
||||
* @example
|
||||
* config.forceSimpleAmpersand = false;
|
||||
*/
|
||||
CKEDITOR.config.forceSimpleAmpersand = false;
|
||||
|
||||
@@ -209,20 +209,22 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
this.preview = CKEDITOR.document.getById( 'previewImage' );
|
||||
|
||||
var editor = this.getParentEditor(),
|
||||
element = this.getParentEditor().getSelection().getSelectedElement();
|
||||
sel = this.getParentEditor().getSelection(),
|
||||
element = sel.getSelectedElement(),
|
||||
link = element && element.getAscendant( 'a' );
|
||||
|
||||
// Copy of the image
|
||||
this.originalElement = editor.document.createElement( 'img' );
|
||||
this.originalElement.setAttribute( 'alt', '' );
|
||||
this.originalElement.setCustomData( 'isReady', 'false' );
|
||||
|
||||
if ( element && element.getName() == 'a' )
|
||||
if ( link )
|
||||
{
|
||||
this.linkElement = element;
|
||||
this.linkElement = link;
|
||||
this.linkEditMode = true;
|
||||
|
||||
// Look for Image element.
|
||||
var linkChildren = element.getChildren();
|
||||
var linkChildren = link.getChildren();
|
||||
if ( linkChildren.count() == 1 ) // 1 child.
|
||||
{
|
||||
var childTagName = linkChildren.getItem( 0 ).getName();
|
||||
@@ -237,9 +239,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
}
|
||||
// Fill out all fields.
|
||||
if ( dialogType == 'image' )
|
||||
this.setupContent( LINK, element );
|
||||
this.setupContent( LINK, link );
|
||||
}
|
||||
else if ( element && element.getName() == 'img' && !element.getAttribute( '_cke_protected_html' ) )
|
||||
|
||||
if ( element && element.getName() == 'img' && !element.getAttribute( '_cke_protected_html' ) )
|
||||
this.imageEditMode = 'img';
|
||||
else if ( element && element.getName() == 'input' && element.getAttribute( 'type' ) && element.getAttribute( 'type' ) == 'image' )
|
||||
this.imageEditMode = 'input';
|
||||
@@ -261,8 +264,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
// Edit existing Image.
|
||||
if ( this.imageEditMode )
|
||||
{
|
||||
var imgTagName = this.imageEditMode,
|
||||
removeObj = this.imageElement;
|
||||
var imgTagName = this.imageEditMode;
|
||||
|
||||
// Image dialog and Input element.
|
||||
if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) )
|
||||
@@ -271,9 +273,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
imgTagName = 'img';
|
||||
this.imageElement = editor.document.createElement( 'img' );
|
||||
this.imageElement.setAttribute( 'alt', '' );
|
||||
removeObj.insertBeforeMe( this.imageElement );
|
||||
removeObj.remove( false );
|
||||
|
||||
editor.insertElement( this.imageElement );
|
||||
}
|
||||
// ImageButton dialog and Image element.
|
||||
else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button ))
|
||||
@@ -287,8 +287,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
alt : ''
|
||||
}
|
||||
);
|
||||
removeObj.insertBeforeMe( this.imageElement );
|
||||
removeObj.remove( false );
|
||||
editor.insertElement( this.imageElement );
|
||||
}
|
||||
}
|
||||
else // Create a new image.
|
||||
@@ -320,11 +319,11 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
//Insert a new Link.
|
||||
if ( !this.linkEditMode )
|
||||
{
|
||||
this.linkElement.append( this.imageElement, false );
|
||||
editor.insertElement( this.linkElement );
|
||||
editor.insertElement(this.linkElement);
|
||||
this.linkElement.append(this.imageElement, false);
|
||||
}
|
||||
else //Link already exists, image not.
|
||||
this.linkElement.append( this.imageElement, false );
|
||||
else //Link already exists, image not.
|
||||
editor.insertElement(this.imageElement );
|
||||
}
|
||||
else
|
||||
editor.insertElement( this.imageElement );
|
||||
@@ -334,18 +333,24 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
//Add a new link element.
|
||||
if ( !this.linkEditMode && this.addLink )
|
||||
{
|
||||
this.imageElement.insertBeforeMe( this.linkElement );
|
||||
editor.insertElement( this.linkElement );
|
||||
this.imageElement.appendTo( this.linkElement );
|
||||
}
|
||||
//Remove Link, Image exists.
|
||||
else if ( this.linkEditMode && !this.addLink )
|
||||
this.linkElement.remove( true );
|
||||
{
|
||||
editor.getSelection().selectElement( this.linkElement );
|
||||
editor.insertElement( this.imageElement );
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad : function()
|
||||
{
|
||||
if ( dialogType != 'image' )
|
||||
this.hidePage( 'Link' ); //Hide Link tab.
|
||||
var doc = this._.element.getDocument();
|
||||
this.addFocusable( doc.getById( 'btnResetSize' ), 5 );
|
||||
this.addFocusable( doc.getById( 'btnLockSizes' ), 5 );
|
||||
},
|
||||
onHide : function()
|
||||
{
|
||||
@@ -417,13 +422,18 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
if ( type == IMAGE )
|
||||
{
|
||||
var dialog = this.getDialog();
|
||||
var url = element.getAttribute( '_cke_saved_src' );
|
||||
if ( !url )
|
||||
url = element.getAttribute( 'src' );
|
||||
dialog.dontResetSize = true;
|
||||
this.setValue( url ); // And call this.onChange()
|
||||
this.focus();
|
||||
var url = element.getAttribute( '_cke_saved_src' ) || element.getAttribute( 'src' );
|
||||
var field = this;
|
||||
|
||||
this.getDialog().dontResetSize = true;
|
||||
|
||||
// In IE7 the dialog is being rendered improperly when loading
|
||||
// an image with a long URL. So we need to delay it a bit. (#4122)
|
||||
setTimeout( function()
|
||||
{
|
||||
field.setValue( url ); // And call this.onChange()
|
||||
field.focus();
|
||||
}, 0 );
|
||||
}
|
||||
},
|
||||
commit : function( type, element )
|
||||
@@ -506,6 +516,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
[
|
||||
{
|
||||
type : 'text',
|
||||
width: '40px',
|
||||
id : 'txtWidth',
|
||||
labelLayout : 'horizontal',
|
||||
label : editor.lang.image.width,
|
||||
@@ -552,6 +563,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
type : 'text',
|
||||
id : 'txtHeight',
|
||||
width: '40px',
|
||||
labelLayout : 'horizontal',
|
||||
label : editor.lang.image.height,
|
||||
onKeyUp : onSizeChange,
|
||||
@@ -598,7 +610,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
},
|
||||
{
|
||||
type : 'html',
|
||||
style : 'position:relative;top:10px;height:50px;',
|
||||
style : 'margin-top:10px;width:40px;height:40px;',
|
||||
onLoad : function()
|
||||
{
|
||||
// Activate Reset button
|
||||
@@ -612,11 +624,11 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
}, this.getDialog() );
|
||||
resetButton.on( 'mouseover', function()
|
||||
{
|
||||
this.addClass( 'BtnOver' );
|
||||
this.addClass( 'cke_btn_over' );
|
||||
}, resetButton );
|
||||
resetButton.on( 'mouseout', function()
|
||||
{
|
||||
this.removeClass( 'BtnOver' );
|
||||
this.removeClass( 'cke_btn_over' );
|
||||
}, resetButton );
|
||||
}
|
||||
// Activate (Un)LockRatio button
|
||||
@@ -640,19 +652,19 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
}, this.getDialog() );
|
||||
ratioButton.on( 'mouseover', function()
|
||||
{
|
||||
this.addClass( 'BtnOver' );
|
||||
this.addClass( 'cke_btn_over' );
|
||||
}, ratioButton );
|
||||
ratioButton.on( 'mouseout', function()
|
||||
{
|
||||
this.removeClass( 'BtnOver' );
|
||||
this.removeClass( 'cke_btn_over' );
|
||||
}, ratioButton );
|
||||
}
|
||||
},
|
||||
html : '<div>'+
|
||||
'<div title="' + editor.lang.image.lockRatio +
|
||||
'" class="cke_btn_locked" id="btnLockSizes"></div>' +
|
||||
'<div title="' + editor.lang.image.resetSize +
|
||||
'" class="cke_btn_reset" id="btnResetSize"></div>'+
|
||||
'<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.lockRatio +
|
||||
'" class="cke_btn_locked" id="btnLockSizes"></a>' +
|
||||
'<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +
|
||||
'" class="cke_btn_reset" id="btnResetSize"></a>'+
|
||||
'</div>'
|
||||
}
|
||||
]
|
||||
@@ -665,6 +677,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
type : 'text',
|
||||
id : 'txtBorder',
|
||||
width: '60px',
|
||||
labelLayout : 'horizontal',
|
||||
label : editor.lang.image.border,
|
||||
'default' : '',
|
||||
@@ -706,6 +719,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
type : 'text',
|
||||
id : 'txtHSpace',
|
||||
width: '60px',
|
||||
labelLayout : 'horizontal',
|
||||
label : editor.lang.image.hSpace,
|
||||
'default' : '',
|
||||
@@ -753,6 +767,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
type : 'text',
|
||||
id : 'txtVSpace',
|
||||
width : '60px',
|
||||
labelLayout : 'horizontal',
|
||||
label : editor.lang.image.vSpace,
|
||||
'default' : '',
|
||||
@@ -798,7 +813,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
type : 'select',
|
||||
labelLayout : 'horizontal',
|
||||
widths : [ '35%','65%' ],
|
||||
style : 'width:100%',
|
||||
style : 'width:90px',
|
||||
label : editor.lang.image.align,
|
||||
'default' : '',
|
||||
items :
|
||||
@@ -967,6 +982,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
type : 'file',
|
||||
id : 'upload',
|
||||
label : editor.lang.image.btnUpload,
|
||||
style: 'height:40px',
|
||||
size : 38
|
||||
},
|
||||
{
|
||||
@@ -1009,7 +1025,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
id : 'cmbLangDir',
|
||||
type : 'select',
|
||||
style : 'width : 100%;',
|
||||
style : 'width : 100px;',
|
||||
label : editor.lang.common.langDir,
|
||||
'default' : '',
|
||||
items :
|
||||
|
||||
@@ -54,4 +54,11 @@ CKEDITOR.plugins.add( 'image',
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* Whether to remove links when emptying the link URL field in the image dialog.
|
||||
* @type Boolean
|
||||
* @default true
|
||||
* @example
|
||||
* config.image_removeLinkByEmptyURL = false;
|
||||
*/
|
||||
CKEDITOR.config.image_removeLinkByEmptyURL = true;
|
||||
|
||||
@@ -42,7 +42,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
|
||||
else
|
||||
{
|
||||
while ( listItem && ( listItem = listItem.getPrevious() ) )
|
||||
while ( listItem && ( listItem = listItem.getPrevious( CKEDITOR.dom.walker.whitespaces( true ) ) ) )
|
||||
{
|
||||
if ( listItem.getName && listItem.getName() == 'li' )
|
||||
return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
|
||||
@@ -69,7 +69,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
indentStep = this.indentClassMap[ indentClass ];
|
||||
}
|
||||
if ( ( this.name == 'outdent' && !indentStep ) ||
|
||||
( this.name == 'indent' && indentStep == editor.config.indentClass.length ) )
|
||||
( this.name == 'indent' && indentStep == editor.config.indentClasses.length ) )
|
||||
return setState.call( this, editor, CKEDITOR.TRISTATE_DISABLED );
|
||||
return setState.call( this, editor, CKEDITOR.TRISTATE_OFF );
|
||||
}
|
||||
@@ -116,7 +116,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
// list's DOM tree itself. The array model demands that it knows as much as
|
||||
// possible about the surrounding lists, we need to feed it the further
|
||||
// ancestor node that is still a list.
|
||||
var listParents = listNode.getParents();
|
||||
var listParents = listNode.getParents( true );
|
||||
for ( var i = 0 ; i < listParents.length ; i++ )
|
||||
{
|
||||
if ( listParents[i].getName && listNodeNames[ listParents[i].getName() ] )
|
||||
@@ -144,18 +144,60 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
// Convert the array back to a DOM forest (yes we might have a few subtrees now).
|
||||
// And replace the old list with the new forest.
|
||||
var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, 0 );
|
||||
|
||||
// Avoid nested <li> after outdent even they're visually same,
|
||||
// recording them for later refactoring.(#3982)
|
||||
if ( this.name == 'outdent' )
|
||||
{
|
||||
var parentLiElement;
|
||||
if ( ( parentLiElement = listNode.getParent() ) && parentLiElement.is( 'li' ) )
|
||||
{
|
||||
var children = newList.listNode.getChildren(),
|
||||
pendingLis = [],
|
||||
count = children.count(),
|
||||
child;
|
||||
|
||||
for ( i = count - 1 ; i >= 0 ; i-- )
|
||||
{
|
||||
if( ( child = children.getItem( i ) ) && child.is && child.is( 'li' ) )
|
||||
pendingLis.push( child );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( newList )
|
||||
newList.listNode.replace( listNode );
|
||||
|
||||
// Move the nested <li> to be appeared after the parent.
|
||||
if ( pendingLis && pendingLis.length )
|
||||
{
|
||||
for ( i = 0; i < pendingLis.length ; i++ )
|
||||
{
|
||||
var li = pendingLis[ i ],
|
||||
followingList = li;
|
||||
|
||||
// Nest preceding <ul>/<ol> inside current <li> if any.
|
||||
while( ( followingList = followingList.getNext() ) &&
|
||||
followingList.is &&
|
||||
followingList.getName() in listNodeNames )
|
||||
{
|
||||
li.append( followingList );
|
||||
}
|
||||
|
||||
li.insertAfter( parentLiElement );
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up the markers.
|
||||
CKEDITOR.dom.element.clearAllMarkers( database );
|
||||
}
|
||||
|
||||
function indentBlock( editor, range )
|
||||
{
|
||||
var iterator = range.createIterator();
|
||||
var iterator = range.createIterator(),
|
||||
enterMode = editor.config.enterMode;
|
||||
iterator.enforceRealBlocks = true;
|
||||
|
||||
iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
|
||||
var block;
|
||||
while ( ( block = iterator.getNextParagraph() ) )
|
||||
{
|
||||
|
||||
@@ -147,11 +147,19 @@ CKEDITOR.keystrokeHandler = function( editor )
|
||||
})();
|
||||
|
||||
/**
|
||||
* A list of keystrokes to be blocked if not defined in the {@link #keystrokes}
|
||||
* A list of keystrokes to be blocked if not defined in the {@link CKEDITOR.config.keystrokes}
|
||||
* setting. In this way it is possible to block the default browser behavior
|
||||
* for those keystrokes.
|
||||
* @type Array
|
||||
* @default (see example)
|
||||
* @example
|
||||
* // This is actually the default value.
|
||||
* config.blockedKeystrokes =
|
||||
* [
|
||||
* CKEDITOR.CTRL + 66 /*B*/,
|
||||
* CKEDITOR.CTRL + 73 /*I*/,
|
||||
* CKEDITOR.CTRL + 85 /*U*/
|
||||
* ];
|
||||
*/
|
||||
CKEDITOR.config.blockedKeystrokes =
|
||||
[
|
||||
@@ -163,9 +171,30 @@ CKEDITOR.config.blockedKeystrokes =
|
||||
/**
|
||||
* A list associating keystrokes to editor commands. Each element in the list
|
||||
* is an array where the first item is the keystroke, and the second is the
|
||||
* command to be executed.
|
||||
* name of the command to be executed.
|
||||
* @type Array
|
||||
* @default (see example)
|
||||
* @example
|
||||
* // This is actually the default value.
|
||||
* config.keystrokes =
|
||||
* [
|
||||
* [ CKEDITOR.ALT + 121 /*F10*/, 'toolbarFocus' ],
|
||||
* [ CKEDITOR.ALT + 122 /*F11*/, 'elementsPathFocus' ],
|
||||
*
|
||||
* [ CKEDITOR.SHIFT + 121 /*F10*/, 'contextMenu' ],
|
||||
*
|
||||
* [ CKEDITOR.CTRL + 90 /*Z*/, 'undo' ],
|
||||
* [ CKEDITOR.CTRL + 89 /*Y*/, 'redo' ],
|
||||
* [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 90 /*Z*/, 'redo' ],
|
||||
*
|
||||
* [ CKEDITOR.CTRL + 76 /*L*/, 'link' ],
|
||||
*
|
||||
* [ CKEDITOR.CTRL + 66 /*B*/, 'bold' ],
|
||||
* [ CKEDITOR.CTRL + 73 /*I*/, 'italic' ],
|
||||
* [ CKEDITOR.CTRL + 85 /*U*/, 'underline' ],
|
||||
*
|
||||
* [ CKEDITOR.ALT + 109 /*-*/, 'toolbarCollapse' ]
|
||||
* ];
|
||||
*/
|
||||
CKEDITOR.config.keystrokes =
|
||||
[
|
||||
|
||||
@@ -828,7 +828,8 @@ CKEDITOR.dialog.add( 'link', function( editor )
|
||||
type : 'file',
|
||||
id : 'upload',
|
||||
label : editor.lang.common.upload,
|
||||
size : 38
|
||||
style: 'height:40px',
|
||||
size : 29
|
||||
},
|
||||
{
|
||||
type : 'fileButton',
|
||||
@@ -867,7 +868,7 @@ CKEDITOR.dialog.add( 'link', function( editor )
|
||||
id : 'advLangDir',
|
||||
label : editor.lang.link.langDir,
|
||||
'default' : '',
|
||||
style : 'width: 100%;',
|
||||
style : 'width:110px',
|
||||
items :
|
||||
[
|
||||
[ editor.lang.link.langDirNotSet, '' ],
|
||||
@@ -880,6 +881,7 @@ CKEDITOR.dialog.add( 'link', function( editor )
|
||||
{
|
||||
type : 'text',
|
||||
id : 'advAccessKey',
|
||||
width : '80px',
|
||||
label : editor.lang.link.acccessKey,
|
||||
maxLength : 1,
|
||||
setup : setupAdvParams,
|
||||
@@ -905,6 +907,7 @@ CKEDITOR.dialog.add( 'link', function( editor )
|
||||
type : 'text',
|
||||
label : editor.lang.link.langCode,
|
||||
id : 'advLangCode',
|
||||
width : '110px',
|
||||
'default' : '',
|
||||
setup : setupAdvParams,
|
||||
commit : commitAdvParams
|
||||
@@ -914,6 +917,7 @@ CKEDITOR.dialog.add( 'link', function( editor )
|
||||
type : 'text',
|
||||
label : editor.lang.link.tabIndex,
|
||||
id : 'advTabIndex',
|
||||
width : '80px',
|
||||
maxLength : 5,
|
||||
setup : setupAdvParams,
|
||||
commit : commitAdvParams
|
||||
@@ -1017,16 +1021,16 @@ CKEDITOR.dialog.add( 'link', function( editor )
|
||||
{
|
||||
selection.selectElement( element );
|
||||
}
|
||||
else
|
||||
else if ( ( element = rangeRoot.getAscendant( 'img', true ) ) &&
|
||||
element.getAttribute( '_cke_real_element_type' ) &&
|
||||
element.getAttribute( '_cke_real_element_type' ) == 'anchor' )
|
||||
{
|
||||
element = rangeRoot.getAscendant( 'img', true );
|
||||
if ( element && element.getAttribute( '_cke_real_element_type' ) && element.getAttribute( '_cke_real_element_type' ) == 'anchor' )
|
||||
{
|
||||
this.fakeObj = element;
|
||||
element = editor.restoreRealElement( this.fakeObj );
|
||||
selection.selectElement( this.fakeObj );
|
||||
}
|
||||
this.fakeObj = element;
|
||||
element = editor.restoreRealElement( this.fakeObj );
|
||||
selection.selectElement( this.fakeObj );
|
||||
}
|
||||
else
|
||||
element = null;
|
||||
}
|
||||
|
||||
this.setupContent( parseLink.apply( this, [ editor, element ] ) );
|
||||
|
||||
@@ -116,7 +116,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
for ( i = 0 ; i < item.contents.length ; i++ )
|
||||
currentListItem.append( item.contents[i].clone( true, true ) );
|
||||
|
||||
if ( currentListItem.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT )
|
||||
if ( currentListItem.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT
|
||||
&& currentIndex != listArray.length - 1 )
|
||||
{
|
||||
if ( currentListItem.getLast()
|
||||
&& currentListItem.getLast().type == CKEDITOR.NODE_ELEMENT
|
||||
@@ -176,9 +177,14 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
|
||||
function onSelectionChange( evt )
|
||||
{
|
||||
var elements = evt.data.path.elements;
|
||||
var path = evt.data.path,
|
||||
blockLimit = path.blockLimit,
|
||||
elements = path.elements,
|
||||
element;
|
||||
|
||||
for ( var i = 0 ; i < elements.length ; i++ )
|
||||
// Grouping should only happen under blockLimit.(#3940).
|
||||
for ( var i = 0 ; i < elements.length && ( element = elements[ i ] )
|
||||
&& !element.equals( blockLimit ); i++ )
|
||||
{
|
||||
if ( listNodeNames[ elements[i].getName() ] )
|
||||
{
|
||||
@@ -335,14 +341,23 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
}
|
||||
|
||||
var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode );
|
||||
// If groupObj.root is the last element in its parent, or its nextSibling is a <br>, then we should
|
||||
// not add a <br> after the final item. So, check for the cases and trim the <br>.
|
||||
if ( !groupObj.root.getNext() || groupObj.root.getNext().$.nodeName.toLowerCase() == 'br' )
|
||||
|
||||
// Compensate <br> before/after the list node if the surrounds are non-blocks.(#3836)
|
||||
var docFragment = newList.listNode, boundaryNode, siblingNode;
|
||||
function compensateBrs( isStart )
|
||||
{
|
||||
if ( newList.listNode.getLast().$.nodeName.toLowerCase() == 'br' )
|
||||
newList.listNode.getLast().remove();
|
||||
if ( ( boundaryNode = docFragment[ isStart ? 'getFirst' : 'getLast' ]() )
|
||||
&& !( boundaryNode.is && boundaryNode.isBlockBoundary() )
|
||||
&& ( siblingNode = groupObj.root[ isStart ? 'getPrevious' : 'getNext' ]
|
||||
( CKEDITOR.dom.walker.whitespaces( true ) ) )
|
||||
&& !( siblingNode.is && siblingNode.isBlockBoundary( { br : 1 } ) ) )
|
||||
editor.document.createElement( 'br' )[ isStart ? 'insertBefore' : 'insertAfter' ]( boundaryNode );
|
||||
}
|
||||
newList.listNode.replace( groupObj.root );
|
||||
compensateBrs( true );
|
||||
compensateBrs();
|
||||
|
||||
var rootParent = groupObj.root.getParent();
|
||||
docFragment.replace( groupObj.root );
|
||||
}
|
||||
|
||||
function listCommand( name, type )
|
||||
@@ -387,6 +402,18 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
ranges[ 0 ].selectNodeContents( paragraph );
|
||||
selection.selectRanges( ranges );
|
||||
}
|
||||
// Maybe a single range there enclosing the whole list,
|
||||
// turn on the list state manually(#4129).
|
||||
else
|
||||
{
|
||||
var range = ranges.length == 1 && ranges[ 0 ],
|
||||
enclosedNode = range && range.getEnclosedNode();
|
||||
if ( enclosedNode && enclosedNode.is
|
||||
&& this.type == enclosedNode.getName() )
|
||||
{
|
||||
setState.call( this, editor, CKEDITOR.TRISTATE_ON );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var bookmarks = selection.createBookmarks( true );
|
||||
@@ -398,17 +425,21 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
|
||||
while ( ranges.length > 0 )
|
||||
{
|
||||
var range = ranges.shift(),
|
||||
boundaryNodes = range.getBoundaryNodes(),
|
||||
range = ranges.shift();
|
||||
|
||||
var boundaryNodes = range.getBoundaryNodes(),
|
||||
startNode = boundaryNodes.startNode,
|
||||
endNode = boundaryNodes.endNode;
|
||||
|
||||
if ( startNode.type == CKEDITOR.NODE_ELEMENT && startNode.getName() == 'td' )
|
||||
range.setStartAt( boundaryNodes.startNode, CKEDITOR.POSITION_AFTER_START );
|
||||
|
||||
if ( endNode.type == CKEDITOR.NODE_ELEMENT && endNode.getName() == 'td' )
|
||||
range.setEndAt( boundaryNodes.endNode, CKEDITOR.POSITION_BEFORE_END );
|
||||
|
||||
var iterator = range.createIterator(),
|
||||
block;
|
||||
|
||||
iterator.forceBrBreak = ( this.state == CKEDITOR.TRISTATE_OFF );
|
||||
|
||||
while ( ( block = iterator.getNextParagraph() ) )
|
||||
@@ -416,12 +447,13 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
var path = new CKEDITOR.dom.elementPath( block ),
|
||||
listNode = null,
|
||||
processedFlag = false,
|
||||
blockLimit = path.blockLimit;
|
||||
blockLimit = path.blockLimit,
|
||||
element;
|
||||
|
||||
// First, try to group by a list ancestor.
|
||||
for ( var i = 0 ; i < path.elements.length ; i++ )
|
||||
for ( var i = 0 ; i < path.elements.length &&
|
||||
( element = path.elements[ i ] ) && !element.equals( blockLimit ); i++ )
|
||||
{
|
||||
var element = path.elements[i];
|
||||
if ( listNodeNames[ element.getName() ] )
|
||||
{
|
||||
// If we've encountered a list inside a block limit
|
||||
@@ -486,12 +518,14 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
var mergeSibling, listCommand = this;
|
||||
( mergeSibling = function( rtl ){
|
||||
|
||||
var sibling = listNode[ rtl ? 'getPrevious' : 'getNext' ].call( listNode, true );
|
||||
var sibling = listNode[ rtl ?
|
||||
'getPrevious' : 'getNext' ]( CKEDITOR.dom.walker.whitespaces( true ) );
|
||||
if ( sibling && sibling.getName &&
|
||||
sibling.getName() == listCommand.type )
|
||||
{
|
||||
sibling.remove();
|
||||
sibling.moveChildren( listNode );
|
||||
// Move children order by merge direction.(#3820)
|
||||
sibling.moveChildren( listNode, rtl ? true : false );
|
||||
}
|
||||
} )();
|
||||
mergeSibling( true );
|
||||
|
||||
@@ -106,6 +106,12 @@ CKEDITOR.tools.extend( CKEDITOR.editor.prototype,
|
||||
{
|
||||
add : function( item )
|
||||
{
|
||||
// Later we may sort the items, but Array#sort is not stable in
|
||||
// some browsers, here we're forcing the original sequence with
|
||||
// 'order' attribute if it hasn't been assigned. (#3868)
|
||||
if ( !item.order )
|
||||
item.order = this.items.length;
|
||||
|
||||
this.items.push( item );
|
||||
},
|
||||
|
||||
@@ -342,7 +348,27 @@ CKEDITOR.menuItem = CKEDITOR.tools.createClass(
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The amount of time, in milliseconds, the editor waits before showing submenu
|
||||
* options when moving the mouse over options that contains submenus, like the
|
||||
* "Cell Properties" entry for tables.
|
||||
* @type Number
|
||||
* @default 400
|
||||
* @example
|
||||
* // Remove the submenu delay.
|
||||
* config.menu_subMenuDelay = 0;
|
||||
*/
|
||||
CKEDITOR.config.menu_subMenuDelay = 400;
|
||||
|
||||
/**
|
||||
* A comma separated list of items group names to be displayed in the context
|
||||
* menu. The items order will reflect the order in this list if no priority
|
||||
* has been definted in the groups.
|
||||
* @type String
|
||||
* @default 'clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea'
|
||||
* @example
|
||||
* config.menu_groups = 'clipboard,table,anchor,link,image';
|
||||
*/
|
||||
CKEDITOR.config.menu_groups =
|
||||
'clipboard,' +
|
||||
'form,' +
|
||||
|
||||
@@ -5,7 +5,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
|
||||
CKEDITOR.plugins.add( 'menubutton',
|
||||
{
|
||||
requires : [ 'button' ],
|
||||
requires : [ 'button', 'contextmenu' ],
|
||||
beforeInit : function( editor )
|
||||
{
|
||||
editor.ui.addHandler( CKEDITOR.UI_MENUBUTTON, CKEDITOR.ui.menuButton.handler );
|
||||
|
||||
@@ -55,5 +55,11 @@ CKEDITOR.plugins.add( 'newpage',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The HTML to load in the editor when the "new page" command is executed.
|
||||
* @type String
|
||||
* @default ''
|
||||
* @example
|
||||
* config.newpage_html = '<p>Type your text here.</p>';
|
||||
*/
|
||||
CKEDITOR.config.newpage_html = '';
|
||||
|
||||
@@ -78,7 +78,8 @@ CKEDITOR.ui.panel.prototype =
|
||||
output.push(
|
||||
'<div class="', editor.skinClass ,'"' +
|
||||
' lang="', editor.langCode, '"' +
|
||||
' style="z-index:' + ( editor.config.baseFloatZIndex + 1 ) + '">' +
|
||||
// iframe loading need sometime, keep the panel hidden(#4186).
|
||||
' style="display:none;z-index:' + ( editor.config.baseFloatZIndex + 1 ) + '">' +
|
||||
'<div' +
|
||||
' id=', id,
|
||||
' dir=', editor.lang.dir,
|
||||
@@ -133,7 +134,6 @@ CKEDITOR.ui.panel.prototype =
|
||||
className = parentDiv.getParent().getAttribute( 'class' ),
|
||||
langCode = parentDiv.getParent().getAttribute( 'lang' ),
|
||||
doc = iframe.getFrameDocument();
|
||||
|
||||
// Initialize the IFRAME document body.
|
||||
doc.$.open();
|
||||
|
||||
@@ -141,13 +141,21 @@ CKEDITOR.ui.panel.prototype =
|
||||
if ( CKEDITOR.env.isCustomDomain() )
|
||||
doc.$.domain = document.domain;
|
||||
|
||||
var onLoad = CKEDITOR.tools.addFunction( CKEDITOR.tools.bind( function( ev )
|
||||
{
|
||||
this.isLoaded = true;
|
||||
if ( this.onLoad )
|
||||
this.onLoad();
|
||||
}, this ) );
|
||||
|
||||
doc.$.write(
|
||||
'<!DOCTYPE html>' +
|
||||
'<html dir="' + dir + '" class="' + className + '_container" lang="' + langCode + '">' +
|
||||
'<head>' +
|
||||
'<style>.' + className + '_container{visibility:hidden}</style>' +
|
||||
'</head>' +
|
||||
'<body class="cke_' + dir + ' cke_panel_frame ' + CKEDITOR.env.cssClass + '" style="margin:0;padding:0">' +
|
||||
'<body class="cke_' + dir + ' cke_panel_frame ' + CKEDITOR.env.cssClass + '" style="margin:0;padding:0"' +
|
||||
' onload="( window.CKEDITOR || window.parent.CKEDITOR ).tools.callFunction(' + onLoad + ');">' +
|
||||
'</body>' +
|
||||
// It looks strange, but for FF2, the styles must go
|
||||
// after <body>, so it (body) becames immediatelly
|
||||
@@ -161,14 +169,6 @@ CKEDITOR.ui.panel.prototype =
|
||||
// Register the CKEDITOR global.
|
||||
win.$.CKEDITOR = CKEDITOR;
|
||||
|
||||
win.on( 'load', function( ev )
|
||||
{
|
||||
this.isLoaded = true;
|
||||
if ( this.onLoad )
|
||||
this.onLoad();
|
||||
},
|
||||
this);
|
||||
|
||||
doc.on( 'keydown', function( evt )
|
||||
{
|
||||
var keystroke = evt.data.getKeystroke();
|
||||
|
||||
+20
-8
@@ -18,11 +18,20 @@ CKEDITOR.dialog.add( 'pastefromword', function( editor )
|
||||
+ 'document.designMode = "on";'
|
||||
+ 'var iframe = new window.parent.CKEDITOR.dom.element( frameElement );'
|
||||
+ 'var dialog = iframe.getCustomData( "dialog" );'
|
||||
+ ''
|
||||
+ 'iframe.getFrameDocument().on( "keydown", function( e )\
|
||||
{\
|
||||
if ( e.data.getKeystroke() == 27 )\
|
||||
dialog.hide();\
|
||||
});'
|
||||
+ 'dialog.fire( "iframeAdded", { iframe : iframe } );'
|
||||
+ '};'
|
||||
+ '</script><style>body { margin: 3px; height: 95%; } </style><body></body>',
|
||||
cleanWord : function( editor, html, ignoreFont, removeStyles )
|
||||
{
|
||||
// Remove comments [SF BUG-1481861].
|
||||
html = html.replace(/<\!--[\s\S]*?-->/g, '' ) ;
|
||||
|
||||
html = html.replace(/<o:p>\s*<\/o:p>/g, '') ;
|
||||
html = html.replace(/<o:p>[\s\S]*?<\/o:p>/g, ' ') ;
|
||||
|
||||
@@ -30,8 +39,8 @@ CKEDITOR.dialog.add( 'pastefromword', function( editor )
|
||||
html = html.replace( /\s*mso-[^:]+:[^;"]+;?/gi, '' ) ;
|
||||
|
||||
// Remove margin styles.
|
||||
html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*;/gi, '' ) ;
|
||||
html = html.replace( /\s*MARGIN: 0cm 0cm 0pt\s*"/gi, "\"" ) ;
|
||||
html = html.replace( /\s*MARGIN: 0(?:cm|in) 0(?:cm|in) 0pt\s*;/gi, '' ) ;
|
||||
html = html.replace( /\s*MARGIN: 0(?:cm|in) 0(?:cm|in) 0pt\s*"/gi, "\"" ) ;
|
||||
|
||||
html = html.replace( /\s*TEXT-INDENT: 0cm\s*;/gi, '' ) ;
|
||||
html = html.replace( /\s*TEXT-INDENT: 0cm\s*"/gi, "\"" ) ;
|
||||
@@ -88,9 +97,6 @@ CKEDITOR.dialog.add( 'pastefromword', function( editor )
|
||||
// Remove Tags with XML namespace declarations: <o:p><\/o:p>
|
||||
html = html.replace(/<\/?\w+:[^>]*>/gi, '' ) ;
|
||||
|
||||
// Remove comments [SF BUG-1481861].
|
||||
html = html.replace(/<\!--[\s\S]*?-->/g, '' ) ;
|
||||
|
||||
html = html.replace( /<(U|I|STRIKE)> <\/\1>/g, ' ' ) ;
|
||||
|
||||
html = html.replace( /<H\d>\s*<\/H\d>/gi, '' ) ;
|
||||
@@ -227,6 +233,11 @@ CKEDITOR.dialog.add( 'pastefromword', function( editor )
|
||||
if ( CKEDITOR.env.ie )
|
||||
this.getParentEditor().document.getBody().$.contentEditable = 'true';
|
||||
},
|
||||
onLoad : function()
|
||||
{
|
||||
if ( ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) && editor.lang.dir == 'rtl' )
|
||||
this.parts.contents.setStyle( 'overflow', 'hidden' );
|
||||
},
|
||||
contents :
|
||||
[
|
||||
{
|
||||
@@ -236,7 +247,7 @@ CKEDITOR.dialog.add( 'pastefromword', function( editor )
|
||||
[
|
||||
{
|
||||
type : 'html',
|
||||
style : 'white-space: normal;',
|
||||
style : 'white-space:normal;width:346px;display:block',
|
||||
onShow : function()
|
||||
{
|
||||
/*
|
||||
@@ -279,12 +290,13 @@ CKEDITOR.dialog.add( 'pastefromword', function( editor )
|
||||
type : 'checkbox',
|
||||
id : 'ignoreFontFace',
|
||||
label : editor.lang.pastefromword.ignoreFontFace,
|
||||
'default' : true
|
||||
'default' : editor.config.pasteFromWordIgnoreFontFace
|
||||
},
|
||||
{
|
||||
type : 'checkbox',
|
||||
id : 'removeStyle',
|
||||
label : editor.lang.pastefromword.removeStyle
|
||||
label : editor.lang.pastefromword.removeStyle,
|
||||
'default' : editor.config.pasteFromWordRemoveStyle
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,6 +22,33 @@ CKEDITOR.plugins.add( 'pastefromword',
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* Whether the "Ignore font face definitions" checkbox is enabled by default in
|
||||
* the Paste from Word dialog.
|
||||
* @type Boolean
|
||||
* @default true
|
||||
* @example
|
||||
* config.pasteFromWordIgnoreFontFace = false;
|
||||
*/
|
||||
CKEDITOR.config.pasteFromWordIgnoreFontFace = true;
|
||||
|
||||
/**
|
||||
* Whether the "Remove styles definitions" checkbox is enabled by default in
|
||||
* the Paste from Word dialog.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
* @example
|
||||
* config.pasteFromWordRemoveStyle = true;
|
||||
*/
|
||||
CKEDITOR.config.pasteFromWordRemoveStyle = false;
|
||||
|
||||
/**
|
||||
* Whether to keep structure markup (<h1>, <h2>, etc.) or replace
|
||||
* it with elements that create more similar pasting results when pasting
|
||||
* content from Microsoft Word into the Paste from Word dialog.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
* @example
|
||||
* config.pasteFromWordKeepsStructure = true;
|
||||
*/
|
||||
CKEDITOR.config.pasteFromWordKeepsStructure = false;
|
||||
|
||||
@@ -46,8 +46,11 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
editor.on( 'beforePaste', function( event )
|
||||
{
|
||||
setTimeout( function() { command.exec(); }, 0 );
|
||||
event.cancel();
|
||||
if ( editor.mode == "wysiwyg" )
|
||||
{
|
||||
setTimeout( function() { command.exec(); }, 0 );
|
||||
event.cancel();
|
||||
}
|
||||
},
|
||||
null, null, 20 );
|
||||
}
|
||||
@@ -127,4 +130,13 @@ CKEDITOR.editor.prototype.insertText = function( text )
|
||||
this.insertHtml( text );
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether to force all pasting operations to insert on plain text into the
|
||||
* editor, loosing any formatting information possibly available in the source
|
||||
* text.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
* @example
|
||||
* config.forcePasteAsPlainText = true;
|
||||
*/
|
||||
CKEDITOR.config.forcePasteAsPlainText = false;
|
||||
|
||||
@@ -113,7 +113,20 @@ CKEDITOR.plugins.removeformat =
|
||||
}
|
||||
};
|
||||
|
||||
// Only inline elements are valid.
|
||||
/**
|
||||
* A comma separated list of elements to be removed when executing the "remove
|
||||
" format" command. Note that only inline elements are allowed.
|
||||
* @type String
|
||||
* @default 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var'
|
||||
* @example
|
||||
*/
|
||||
CKEDITOR.config.removeFormatTags = 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var';
|
||||
|
||||
/**
|
||||
* A comma separated list of elements attributes to be removed when executing
|
||||
* the "remove format" command.
|
||||
* @type String
|
||||
* @default 'class,style,lang,width,height,align,hspace,valign'
|
||||
* @example
|
||||
*/
|
||||
CKEDITOR.config.removeFormatAttributes = 'class,style,lang,width,height,align,hspace,valign';
|
||||
|
||||
@@ -69,8 +69,47 @@ CKEDITOR.plugins.add( 'resize',
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* The minimum editor width, in pixels, when resizing it with the resize handle.
|
||||
* @type Number
|
||||
* @default 750
|
||||
* @example
|
||||
* config.resize_minWidth = 500;
|
||||
*/
|
||||
CKEDITOR.config.resize_minWidth = 750;
|
||||
|
||||
/**
|
||||
* The minimum editor height, in pixels, when resizing it with the resize handle.
|
||||
* @type Number
|
||||
* @default 250
|
||||
* @example
|
||||
* config.resize_minHeight = 600;
|
||||
*/
|
||||
CKEDITOR.config.resize_minHeight = 250;
|
||||
|
||||
/**
|
||||
* The maximum editor width, in pixels, when resizing it with the resize handle.
|
||||
* @type Number
|
||||
* @default 3000
|
||||
* @example
|
||||
* config.resize_maxWidth = 750;
|
||||
*/
|
||||
CKEDITOR.config.resize_maxWidth = 3000;
|
||||
|
||||
/**
|
||||
* The maximum editor height, in pixels, when resizing it with the resize handle.
|
||||
* @type Number
|
||||
* @default 3000
|
||||
* @example
|
||||
* config.resize_maxHeight = 600;
|
||||
*/
|
||||
CKEDITOR.config.resize_maxHeight = 3000;
|
||||
|
||||
/**
|
||||
* Whether to enable the resizing feature. If disabed the resize handler will not be visible.
|
||||
* @type Boolean
|
||||
* @default true
|
||||
* @example
|
||||
* config.resize_enabled = false;
|
||||
*/
|
||||
CKEDITOR.config.resize_enabled = true;
|
||||
|
||||
@@ -8,374 +8,17 @@ CKEDITOR.dialog.add( 'scaytcheck', function( editor )
|
||||
var firstLoad = true,
|
||||
captions,
|
||||
doc = CKEDITOR.document,
|
||||
fckLang = 'en';
|
||||
tags = [],
|
||||
i,
|
||||
contents = [],
|
||||
userDicActive = false;
|
||||
var dic_buttons = [
|
||||
// [0] contains buttons for creating
|
||||
"dic_create,dic_restore",
|
||||
// [1] contains buton for manipulation
|
||||
"dic_rename,dic_delete"
|
||||
];
|
||||
|
||||
var init_with_captions = function()
|
||||
{
|
||||
var dialog = this,
|
||||
lang_list = dialog.data.scayt.getLangList(),
|
||||
buttons = [ 'dic_create','dic_delete','dic_rename','dic_restore' ],
|
||||
labels = [ 'mixedCase','mixedWithDigits','allCaps','ignoreDomainNames' ],
|
||||
i;
|
||||
|
||||
// Add buttons titles
|
||||
for ( i in buttons )
|
||||
{
|
||||
var button = buttons[ i ];
|
||||
doc.getById( button ).setHtml( '<span class="cke_dialog_ui_button">' + captions[ 'button_' + button] +'</span>' );
|
||||
}
|
||||
doc.getById( 'dic_info' ).setHtml( captions[ 'dic_info' ] );
|
||||
|
||||
// Fill options and dictionary labels.
|
||||
for ( i in labels )
|
||||
{
|
||||
var label = 'label_' + labels[ i ],
|
||||
labelElement = doc.getById( label );
|
||||
|
||||
if ( 'undefined' != typeof labelElement
|
||||
&& 'undefined' != typeof captions[ label ]
|
||||
&& 'undefined' != typeof dialog.options[labels[ i ]] )
|
||||
{
|
||||
labelElement.setHtml( captions[ label ] );
|
||||
var labelParent = labelElement.getParent();
|
||||
labelParent.$.style.display = "block";
|
||||
}
|
||||
}
|
||||
|
||||
var about = '<p>' + captions[ 'about_throwt_image' ] + '</p>'+
|
||||
'<p>' + captions[ 'version' ] + dialog.data.scayt.version.toString() + '</p>' +
|
||||
'<p>' + captions[ 'about_throwt_copy' ] + '</p>';
|
||||
|
||||
doc.getById( 'scayt_about' ).setHtml( about );
|
||||
|
||||
// Create languages tab.
|
||||
var createOption = function( option, list )
|
||||
{
|
||||
var label = doc.createElement( 'label' );
|
||||
label.setAttribute( 'for', 'cke_option' + option );
|
||||
label.setHtml( list[ option ] );
|
||||
|
||||
if ( dialog.sLang == option ) // Current.
|
||||
dialog.chosed_lang = option;
|
||||
|
||||
var div = doc.createElement( 'div' );
|
||||
var radio = CKEDITOR.dom.element.createFromHtml( '<input id="cke_option' +
|
||||
option + '" type="radio" ' +
|
||||
( dialog.sLang == option ? 'checked="checked"' : '' ) +
|
||||
' value="' + option + '" name="scayt_lang" />' );
|
||||
|
||||
radio.on( 'click', function()
|
||||
{
|
||||
this.$.checked = true;
|
||||
dialog.chosed_lang = option;
|
||||
});
|
||||
|
||||
div.append( radio );
|
||||
div.append( label );
|
||||
|
||||
return {
|
||||
lang : list[ option ],
|
||||
code : option,
|
||||
radio : div
|
||||
};
|
||||
};
|
||||
|
||||
var langList = [];
|
||||
for ( i in lang_list.rtl )
|
||||
langList[ langList.length ] = createOption( i, lang_list.ltr );
|
||||
|
||||
for ( i in lang_list.ltr )
|
||||
langList[ langList.length ] = createOption( i, lang_list.ltr );
|
||||
|
||||
langList.sort( function( lang1, lang2 )
|
||||
{
|
||||
return ( lang2.lang > lang1.lang ) ? -1 : 1 ;
|
||||
});
|
||||
|
||||
var fieldL = doc.getById( 'scayt_lcol' ),
|
||||
fieldR = doc.getById( 'scayt_rcol' );
|
||||
for ( i=0; i < langList.length; i++ )
|
||||
{
|
||||
var field = ( i < langList.length / 2 ) ? fieldL : fieldR;
|
||||
field.append( langList[ i ].radio );
|
||||
}
|
||||
|
||||
// user dictionary handlers
|
||||
var dic = {};
|
||||
dic.dic_create = function( el, dic_name , dic_buttons )
|
||||
{
|
||||
// comma separated button's ids include repeats if exists
|
||||
var all_buttons = dic_buttons[0] + ',' + dic_buttons[1];
|
||||
|
||||
var err_massage = captions["err_dic_create"];
|
||||
var suc_massage = captions["succ_dic_create"];
|
||||
//console.info("--plugin ");
|
||||
|
||||
scayt.createUserDictionary(dic_name,
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_create callback called with args" , arg );
|
||||
hide_dic_buttons ( all_buttons );
|
||||
display_dic_buttons ( dic_buttons[1] );
|
||||
suc_massage = suc_massage.replace("%s" , arg.dname );
|
||||
dic_success_message (suc_massage);
|
||||
},
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_create errorback called with args" , arg )
|
||||
err_massage = err_massage.replace("%s" ,arg.dname );
|
||||
dic_error_message ( err_massage + "( "+ (arg.message || "") +")");
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
dic.dic_rename = function( el, dic_name , dic_buttons )
|
||||
{
|
||||
//
|
||||
// try to rename dictionary
|
||||
// @TODO: rename dict
|
||||
//console.info ( captions["err_dic_rename"] )
|
||||
var err_massage = captions["err_dic_rename"] || "";
|
||||
var suc_massage = captions["succ_dic_rename"] || "";
|
||||
scayt.renameUserDictionary(dic_name,
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_rename callback called with args" , arg );
|
||||
suc_massage = suc_massage.replace("%s" , arg.dname );
|
||||
set_dic_name( dic_name );
|
||||
dic_success_message ( suc_massage );
|
||||
},
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_rename errorback called with args" , arg )
|
||||
err_massage = err_massage.replace("%s" , arg.dname );
|
||||
set_dic_name( dic_name );
|
||||
dic_error_message( err_massage + "( " + ( arg.message || "" ) + " )" );
|
||||
});
|
||||
};
|
||||
|
||||
dic.dic_delete = function ( el, dic_name , dic_buttons )
|
||||
{
|
||||
var all_buttons = dic_buttons[0] + ',' + dic_buttons[1];
|
||||
var err_massage = captions["err_dic_delete"];
|
||||
var suc_massage = captions["succ_dic_delete"];
|
||||
|
||||
// try to delete dictionary
|
||||
// @TODO: delete dict
|
||||
scayt.deleteUserDictionary(
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_delete callback " , dic_name ,arg );
|
||||
suc_massage = suc_massage.replace("%s" , arg.dname );
|
||||
hide_dic_buttons ( all_buttons );
|
||||
display_dic_buttons ( dic_buttons[0] );
|
||||
set_dic_name( "" ); // empty input field
|
||||
dic_success_message( suc_massage );
|
||||
},
|
||||
function(arg)
|
||||
{
|
||||
//console.info( " dic_delete errorback called with args" , arg )
|
||||
err_massage = err_massage.replace("%s" , arg.dname );
|
||||
dic_error_message(err_massage);
|
||||
});
|
||||
};
|
||||
|
||||
dic.dic_restore = dialog.dic_restore || function ( el, dic_name , dic_buttons )
|
||||
{
|
||||
// try to restore existing dictionary
|
||||
var all_buttons = dic_buttons[0] + ',' + dic_buttons[1];
|
||||
var err_massage = captions["err_dic_restore"];
|
||||
var suc_massage = captions["succ_dic_restore"];
|
||||
|
||||
scayt.restoreUserDictionary(dic_name,
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_restore callback called with args" , arg );
|
||||
suc_massage = suc_massage.replace("%s" , arg.dname );
|
||||
hide_dic_buttons ( all_buttons );
|
||||
display_dic_buttons(dic_buttons[1]);
|
||||
dic_success_message( suc_massage );
|
||||
},
|
||||
function(arg)
|
||||
{
|
||||
//console.info( " dic_restore errorback called with args" , arg )
|
||||
err_massage = err_massage.replace("%s" , arg.dname );
|
||||
dic_error_message( err_massage );
|
||||
});
|
||||
};
|
||||
|
||||
// ** bind event listeners
|
||||
var arr_buttons = ( dic_buttons[0] + ',' + dic_buttons[1] ).split( ',' ),
|
||||
l;
|
||||
|
||||
for ( i = 0, l = arr_buttons.length ; i < l ; i += 1 )
|
||||
{
|
||||
var dic_button = doc.getById(arr_buttons[i]);
|
||||
|
||||
dic_button.on( 'click', function ()
|
||||
{
|
||||
var dic_name = doc.getById('dic_name').getValue();
|
||||
if ( !dic_name )
|
||||
{
|
||||
dic_error_message(" Dictionary name should not be empty. ");
|
||||
return false;
|
||||
}
|
||||
//apply handler
|
||||
dic[ this.getId() ].apply( null, [ this, dic_name, dic_buttons ] );
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
};
|
||||
var reload = function()
|
||||
{
|
||||
var dialog = this;
|
||||
|
||||
// Animate options.
|
||||
for ( var i in dialog.options )
|
||||
{
|
||||
var checkbox = doc.getById( i );
|
||||
if ( checkbox )
|
||||
{
|
||||
checkbox.removeAttribute( 'checked' );
|
||||
if ( dialog.options[ i ] == 1 )
|
||||
checkbox.setAttribute( 'checked', 'checked' );
|
||||
|
||||
// Bind events. Do it only once.
|
||||
if ( firstLoad )
|
||||
{
|
||||
checkbox.on( 'click', function()
|
||||
{
|
||||
dialog.options[ this.getId() ] = this.$.checked ? 1 : 0 ;
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// * user dictionary
|
||||
scayt.getNameUserDictionary(
|
||||
function( o )
|
||||
{
|
||||
var dic_name = o.dname;
|
||||
if ( dic_name )
|
||||
{
|
||||
doc.getById( 'dic_name' ).setValue(dic_name);
|
||||
display_dic_buttons( dic_buttons[1] );
|
||||
}
|
||||
else
|
||||
display_dic_buttons( dic_buttons[0] );
|
||||
|
||||
},
|
||||
function ()
|
||||
{
|
||||
doc.getById( 'dic_name' ).setValue("");
|
||||
});
|
||||
|
||||
dic_success_message("");
|
||||
};
|
||||
|
||||
function dic_error_message ( m )
|
||||
{
|
||||
doc.getById('dic_message').setHtml('<span style="color:red;">' + m + '</span>' );
|
||||
}
|
||||
function dic_success_message ( m )
|
||||
{
|
||||
doc.getById('dic_message').setHtml('<span style="color:blue;">' + m + '</span>') ;
|
||||
}
|
||||
function display_dic_buttons ( sIds )
|
||||
{
|
||||
|
||||
sIds = new String( sIds );
|
||||
var aIds = sIds.split(',');
|
||||
for ( var i=0, l = aIds.length; i < l ; i+=1)
|
||||
{
|
||||
doc.getById( aIds[i] ).$.style.display = "inline";
|
||||
}
|
||||
|
||||
}
|
||||
function hide_dic_buttons ( sIds )
|
||||
{
|
||||
sIds = new String( sIds );
|
||||
var aIds = sIds.split(',');
|
||||
for ( var i = 0, l = aIds.length; i < l ; i += 1 )
|
||||
{
|
||||
doc.getById( aIds[i] ).$.style.display = "none";
|
||||
}
|
||||
}
|
||||
function set_dic_name ( dic_name )
|
||||
{
|
||||
doc.getById('dic_name').$.value= dic_name;
|
||||
}
|
||||
|
||||
return {
|
||||
title : editor.lang.scayt.title,
|
||||
minWidth : 340,
|
||||
minHeight : 200,
|
||||
onShow : function()
|
||||
{
|
||||
var dialog = this;
|
||||
dialog.data = editor.fire( 'scaytDialog', {} );
|
||||
dialog.options = dialog.data.scayt_control.option();
|
||||
dialog.sLang = dialog.data.scayt_control.sLang;
|
||||
|
||||
if ( !dialog.data || !dialog.data.scayt || !dialog.data.scayt_control )
|
||||
{
|
||||
alert( 'Error loading application service' );
|
||||
dialog.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
var stop = 0;
|
||||
if ( firstLoad )
|
||||
{
|
||||
dialog.data.scayt.getCaption( 'en', function( caps )
|
||||
{
|
||||
if ( stop++ > 0 ) // Once only
|
||||
return;
|
||||
captions = caps;
|
||||
init_with_captions.apply( dialog );
|
||||
reload.apply( dialog );
|
||||
firstLoad = false;
|
||||
});
|
||||
}
|
||||
else
|
||||
reload.apply( dialog );
|
||||
|
||||
dialog.selectPage( dialog.data.tab );
|
||||
},
|
||||
onOk : function()
|
||||
{
|
||||
var scayt_control = this.data.scayt_control,
|
||||
o = scayt_control.option(),
|
||||
c = 0;
|
||||
|
||||
// Set up options if any was set.
|
||||
for ( var oN in this.options )
|
||||
{
|
||||
if (o[oN] != this.options[ oN ] && c === 0 )
|
||||
{
|
||||
scayt_control.option( this.options );
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup languge if it was changed.
|
||||
var csLang = this.chosed_lang;
|
||||
if ( csLang && this.data.sLang != csLang )
|
||||
{
|
||||
scayt_control.setLang( csLang );
|
||||
c++;
|
||||
}
|
||||
if ( c > 0 )
|
||||
scayt_control.refresh();
|
||||
},
|
||||
contents : [
|
||||
var tags_contents = [
|
||||
{
|
||||
id : 'options',
|
||||
label : editor.lang.scayt.optionsTab,
|
||||
@@ -463,6 +106,389 @@ CKEDITOR.dialog.add( 'scaytcheck', function( editor )
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
];
|
||||
var dialogDefiniton = {
|
||||
title : editor.lang.scayt.title,
|
||||
minWidth : 340,
|
||||
minHeight : 200,
|
||||
onShow : function()
|
||||
{
|
||||
var dialog = this;
|
||||
dialog.data = editor.fire( 'scaytDialog', {} );
|
||||
dialog.options = dialog.data.scayt_control.option();
|
||||
dialog.sLang = dialog.data.scayt_control.sLang;
|
||||
|
||||
if ( !dialog.data || !dialog.data.scayt || !dialog.data.scayt_control )
|
||||
{
|
||||
alert( 'Error loading application service' );
|
||||
dialog.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
var stop = 0;
|
||||
if ( firstLoad )
|
||||
{
|
||||
dialog.data.scayt.getCaption( 'en', function( caps )
|
||||
{
|
||||
if ( stop++ > 0 ) // Once only
|
||||
return;
|
||||
captions = caps;
|
||||
init_with_captions.apply( dialog );
|
||||
reload.apply( dialog );
|
||||
firstLoad = false;
|
||||
});
|
||||
}
|
||||
else
|
||||
reload.apply( dialog );
|
||||
|
||||
dialog.selectPage( dialog.data.tab );
|
||||
},
|
||||
onOk : function()
|
||||
{
|
||||
var scayt_control = this.data.scayt_control,
|
||||
o = scayt_control.option(),
|
||||
c = 0;
|
||||
|
||||
// Set up options if any was set.
|
||||
for ( var i in this.options )
|
||||
{
|
||||
if (o[i] != this.options[ i ] && c === 0 )
|
||||
{
|
||||
scayt_control.option( this.options );
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup languge if it was changed.
|
||||
var csLang = this.chosed_lang;
|
||||
if ( csLang && this.data.sLang != csLang )
|
||||
{
|
||||
scayt_control.setLang( csLang );
|
||||
c++;
|
||||
}
|
||||
if ( c > 0 )
|
||||
scayt_control.refresh();
|
||||
},
|
||||
contents : contents
|
||||
};
|
||||
|
||||
var scayt_control = CKEDITOR.plugins.scayt.getScayt( editor );
|
||||
if ( scayt_control )
|
||||
{
|
||||
tags = scayt_control.uiTags;
|
||||
}
|
||||
|
||||
for ( i in tags ) {
|
||||
if ( tags[ i ] == 1 )
|
||||
contents[ contents.length ] = tags_contents[ i ];
|
||||
}
|
||||
if ( tags[2] == 1 )
|
||||
userDicActive = true;
|
||||
|
||||
function onDicButtonClick()
|
||||
{
|
||||
var dic_name = doc.getById('dic_name').getValue();
|
||||
if ( !dic_name )
|
||||
{
|
||||
dic_error_message(" Dictionary name should not be empty. ");
|
||||
return false;
|
||||
}
|
||||
//apply handler
|
||||
window.dic[ this.getId() ].apply( null, [ this, dic_name, dic_buttons ] );
|
||||
|
||||
return true;
|
||||
}
|
||||
var init_with_captions = function()
|
||||
{
|
||||
var dialog = this,
|
||||
lang_list = dialog.data.scayt.getLangList(),
|
||||
buttons = [ 'dic_create','dic_delete','dic_rename','dic_restore' ],
|
||||
labels = [ 'mixedCase','mixedWithDigits','allCaps','ignoreDomainNames' ],
|
||||
i;
|
||||
|
||||
// Add buttons titles
|
||||
if (userDicActive)
|
||||
{
|
||||
for ( i in buttons )
|
||||
{
|
||||
var button = buttons[ i ];
|
||||
doc.getById( button ).setHtml( '<span class="cke_dialog_ui_button">' + captions[ 'button_' + button] +'</span>' );
|
||||
}
|
||||
doc.getById( 'dic_info' ).setHtml( captions[ 'dic_info' ] );
|
||||
}
|
||||
|
||||
|
||||
// Fill options and dictionary labels.
|
||||
for ( i in labels )
|
||||
{
|
||||
var label = 'label_' + labels[ i ],
|
||||
labelElement = doc.getById( label );
|
||||
|
||||
if ( 'undefined' != typeof labelElement
|
||||
&& 'undefined' != typeof captions[ label ]
|
||||
&& 'undefined' != typeof dialog.options[labels[ i ]] )
|
||||
{
|
||||
labelElement.setHtml( captions[ label ] );
|
||||
var labelParent = labelElement.getParent();
|
||||
labelParent.$.style.display = "block";
|
||||
}
|
||||
}
|
||||
|
||||
var about = '<p>' + captions[ 'about_throwt_image' ] + '</p>'+
|
||||
'<p>' + captions[ 'version' ] + dialog.data.scayt.version.toString() + '</p>' +
|
||||
'<p>' + captions[ 'about_throwt_copy' ] + '</p>';
|
||||
|
||||
doc.getById( 'scayt_about' ).setHtml( about );
|
||||
|
||||
// Create languages tab.
|
||||
var createOption = function( option, list )
|
||||
{
|
||||
var label = doc.createElement( 'label' );
|
||||
label.setAttribute( 'for', 'cke_option' + option );
|
||||
label.setHtml( list[ option ] );
|
||||
|
||||
if ( dialog.sLang == option ) // Current.
|
||||
dialog.chosed_lang = option;
|
||||
|
||||
var div = doc.createElement( 'div' );
|
||||
var radio = CKEDITOR.dom.element.createFromHtml( '<input id="cke_option' +
|
||||
option + '" type="radio" ' +
|
||||
( dialog.sLang == option ? 'checked="checked"' : '' ) +
|
||||
' value="' + option + '" name="scayt_lang" />' );
|
||||
|
||||
radio.on( 'click', function()
|
||||
{
|
||||
this.$.checked = true;
|
||||
dialog.chosed_lang = option;
|
||||
});
|
||||
|
||||
div.append( radio );
|
||||
div.append( label );
|
||||
|
||||
return {
|
||||
lang : list[ option ],
|
||||
code : option,
|
||||
radio : div
|
||||
};
|
||||
};
|
||||
|
||||
var langList = [];
|
||||
for ( i in lang_list.rtl )
|
||||
langList[ langList.length ] = createOption( i, lang_list.ltr );
|
||||
|
||||
for ( i in lang_list.ltr )
|
||||
langList[ langList.length ] = createOption( i, lang_list.ltr );
|
||||
|
||||
langList.sort( function( lang1, lang2 )
|
||||
{
|
||||
return ( lang2.lang > lang1.lang ) ? -1 : 1 ;
|
||||
});
|
||||
|
||||
var fieldL = doc.getById( 'scayt_lcol' ),
|
||||
fieldR = doc.getById( 'scayt_rcol' );
|
||||
for ( i=0; i < langList.length; i++ )
|
||||
{
|
||||
var field = ( i < langList.length / 2 ) ? fieldL : fieldR;
|
||||
field.append( langList[ i ].radio );
|
||||
}
|
||||
|
||||
// user dictionary handlers
|
||||
var dic = {};
|
||||
dic.dic_create = function( el, dic_name , dic_buttons )
|
||||
{
|
||||
// comma separated button's ids include repeats if exists
|
||||
var all_buttons = dic_buttons[0] + ',' + dic_buttons[1];
|
||||
|
||||
var err_massage = captions["err_dic_create"];
|
||||
var suc_massage = captions["succ_dic_create"];
|
||||
//console.info("--plugin ");
|
||||
|
||||
window.scayt.createUserDictionary(dic_name,
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_create callback called with args" , arg );
|
||||
hide_dic_buttons ( all_buttons );
|
||||
display_dic_buttons ( dic_buttons[1] );
|
||||
suc_massage = suc_massage.replace("%s" , arg.dname );
|
||||
dic_success_message (suc_massage);
|
||||
},
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_create errorback called with args" , arg )
|
||||
err_massage = err_massage.replace("%s" ,arg.dname );
|
||||
dic_error_message ( err_massage + "( "+ (arg.message || "") +")");
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
dic.dic_rename = function( el, dic_name )
|
||||
{
|
||||
//
|
||||
// try to rename dictionary
|
||||
// @TODO: rename dict
|
||||
//console.info ( captions["err_dic_rename"] )
|
||||
var err_massage = captions["err_dic_rename"] || "";
|
||||
var suc_massage = captions["succ_dic_rename"] || "";
|
||||
window.scayt.renameUserDictionary(dic_name,
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_rename callback called with args" , arg );
|
||||
suc_massage = suc_massage.replace("%s" , arg.dname );
|
||||
set_dic_name( dic_name );
|
||||
dic_success_message ( suc_massage );
|
||||
},
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_rename errorback called with args" , arg )
|
||||
err_massage = err_massage.replace("%s" , arg.dname );
|
||||
set_dic_name( dic_name );
|
||||
dic_error_message( err_massage + "( " + ( arg.message || "" ) + " )" );
|
||||
});
|
||||
};
|
||||
|
||||
dic.dic_delete = function ( el, dic_name , dic_buttons )
|
||||
{
|
||||
var all_buttons = dic_buttons[0] + ',' + dic_buttons[1];
|
||||
var err_massage = captions["err_dic_delete"];
|
||||
var suc_massage = captions["succ_dic_delete"];
|
||||
|
||||
// try to delete dictionary
|
||||
// @TODO: delete dict
|
||||
window.scayt.deleteUserDictionary(
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_delete callback " , dic_name ,arg );
|
||||
suc_massage = suc_massage.replace("%s" , arg.dname );
|
||||
hide_dic_buttons ( all_buttons );
|
||||
display_dic_buttons ( dic_buttons[0] );
|
||||
set_dic_name( "" ); // empty input field
|
||||
dic_success_message( suc_massage );
|
||||
},
|
||||
function(arg)
|
||||
{
|
||||
//console.info( " dic_delete errorback called with args" , arg )
|
||||
err_massage = err_massage.replace("%s" , arg.dname );
|
||||
dic_error_message(err_massage);
|
||||
});
|
||||
};
|
||||
|
||||
dic.dic_restore = dialog.dic_restore || function ( el, dic_name , dic_buttons )
|
||||
{
|
||||
// try to restore existing dictionary
|
||||
var all_buttons = dic_buttons[0] + ',' + dic_buttons[1];
|
||||
var err_massage = captions["err_dic_restore"];
|
||||
var suc_massage = captions["succ_dic_restore"];
|
||||
|
||||
window.scayt.restoreUserDictionary(dic_name,
|
||||
function(arg)
|
||||
{
|
||||
//console.info( "dic_restore callback called with args" , arg );
|
||||
suc_massage = suc_massage.replace("%s" , arg.dname );
|
||||
hide_dic_buttons ( all_buttons );
|
||||
display_dic_buttons(dic_buttons[1]);
|
||||
dic_success_message( suc_massage );
|
||||
},
|
||||
function(arg)
|
||||
{
|
||||
//console.info( " dic_restore errorback called with args" , arg )
|
||||
err_massage = err_massage.replace("%s" , arg.dname );
|
||||
dic_error_message( err_massage );
|
||||
});
|
||||
};
|
||||
|
||||
// ** bind event listeners
|
||||
var arr_buttons = ( dic_buttons[0] + ',' + dic_buttons[1] ).split( ',' ),
|
||||
l;
|
||||
|
||||
for ( i = 0, l = arr_buttons.length ; i < l ; i += 1 )
|
||||
{
|
||||
var dic_button = doc.getById(arr_buttons[i]);
|
||||
if ( dic_button )
|
||||
dic_button.on( 'click', onDicButtonClick, this );
|
||||
}
|
||||
};
|
||||
|
||||
var reload = function()
|
||||
{
|
||||
var dialog = this;
|
||||
|
||||
// Animate options.
|
||||
for ( var i in dialog.options )
|
||||
{
|
||||
var checkbox = doc.getById( i );
|
||||
if ( checkbox )
|
||||
{
|
||||
checkbox.removeAttribute( 'checked' );
|
||||
if ( dialog.options[ i ] == 1 )
|
||||
checkbox.setAttribute( 'checked', 'checked' );
|
||||
|
||||
// Bind events. Do it only once.
|
||||
if ( firstLoad )
|
||||
{
|
||||
checkbox.on( 'click', function()
|
||||
{
|
||||
dialog.options[ this.getId() ] = this.$.checked ? 1 : 0 ;
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// * user dictionary
|
||||
if ( userDicActive ){
|
||||
window.scayt.getNameUserDictionary(
|
||||
function( o )
|
||||
{
|
||||
var dic_name = o.dname;
|
||||
if ( dic_name )
|
||||
{
|
||||
doc.getById( 'dic_name' ).setValue(dic_name);
|
||||
display_dic_buttons( dic_buttons[1] );
|
||||
}
|
||||
else
|
||||
display_dic_buttons( dic_buttons[0] );
|
||||
|
||||
},
|
||||
function ()
|
||||
{
|
||||
doc.getById( 'dic_name' ).setValue("");
|
||||
});
|
||||
dic_success_message("");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function dic_error_message ( m )
|
||||
{
|
||||
doc.getById('dic_message').setHtml('<span style="color:red;">' + m + '</span>' );
|
||||
}
|
||||
function dic_success_message ( m )
|
||||
{
|
||||
doc.getById('dic_message').setHtml('<span style="color:blue;">' + m + '</span>') ;
|
||||
}
|
||||
function display_dic_buttons ( sIds )
|
||||
{
|
||||
|
||||
sIds = String( sIds );
|
||||
var aIds = sIds.split(',');
|
||||
for ( var i=0, l = aIds.length; i < l ; i+=1)
|
||||
{
|
||||
doc.getById( aIds[i] ).$.style.display = "inline";
|
||||
}
|
||||
|
||||
}
|
||||
function hide_dic_buttons ( sIds )
|
||||
{
|
||||
sIds = String( sIds );
|
||||
var aIds = sIds.split(',');
|
||||
for ( var i = 0, l = aIds.length; i < l ; i += 1 )
|
||||
{
|
||||
doc.getById( aIds[i] ).$.style.display = "none";
|
||||
}
|
||||
}
|
||||
function set_dic_name ( dic_name )
|
||||
{
|
||||
doc.getById('dic_name').$.value= dic_name;
|
||||
}
|
||||
|
||||
return dialogDefiniton;
|
||||
});
|
||||
|
||||
@@ -11,23 +11,34 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
(function()
|
||||
{
|
||||
var commandName = 'scaytcheck',
|
||||
sc_on_cssclass = 'scayt_enabled',
|
||||
sc_off_cssclass = 'scayt_disabled',
|
||||
openPage = '';
|
||||
|
||||
var onEngineLoad = function()
|
||||
{
|
||||
var editor = this;
|
||||
dojo.requireLocalization( 'scayt', 'caption', '', 'ROOT' );
|
||||
|
||||
var createInstance = function() // Create new instance every time Document is created.
|
||||
{
|
||||
// Initialise Scayt instance.
|
||||
var oParams = CKEDITOR.config.scaytParams || {};
|
||||
var oParams = {};
|
||||
oParams.srcNodeRef = editor.document.getWindow().$.frameElement; // Get the iframe.
|
||||
// syntax : AppName.AppVersion@AppRevision
|
||||
oParams.assocApp = "CKEDITOR." + CKEDITOR.version + "@" + CKEDITOR.revision;
|
||||
var scayt_control = new scayt( oParams );
|
||||
|
||||
oParams.customerid = editor.config.scayt_customerid || "1:11111111111111111111111111111111111111";
|
||||
oParams.customDictionaryName = editor.config.scayt_customDictionaryName;
|
||||
oParams.userDictionaryName = editor.config.scayt_userDictionaryName;
|
||||
oParams.defLang = editor.scayt_defLang;
|
||||
|
||||
if ( CKEDITOR._scaytParams )
|
||||
{
|
||||
for ( var k in CKEDITOR._scaytParams )
|
||||
{
|
||||
oParams[ k ] = CKEDITOR._scaytParams[ k ];
|
||||
}
|
||||
}
|
||||
|
||||
var scayt_control = new window.scayt( oParams );
|
||||
|
||||
// Copy config.
|
||||
var lastInstance = plugin.instances[ editor.name ];
|
||||
@@ -67,13 +78,14 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
|
||||
editor.on( 'beforeCommandExec', function( ev ) // Disable SCAYT before Source command execution.
|
||||
{
|
||||
if ( ev.data.name == 'source' && editor.mode == 'wysiwyg' )
|
||||
if ( (ev.data.name == 'source' || ev.data.name == 'newpage') && editor.mode == 'wysiwyg' )
|
||||
{
|
||||
var scayt = plugin.getScayt( editor );
|
||||
if ( scayt )
|
||||
var scayt_instanse = plugin.getScayt( editor );
|
||||
if ( scayt_instanse )
|
||||
{
|
||||
scayt.paused = !scayt.disabled;
|
||||
scayt.setDisabled( true );
|
||||
scayt_instanse.paused = !scayt_instanse.disabled;
|
||||
scayt_instanse.destroy();
|
||||
delete plugin.instances[ editor.name ];
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -85,12 +97,31 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
plugin.getScayt( editor ).refresh();
|
||||
});
|
||||
|
||||
// Reload spell-checking for current word after insertion completed.
|
||||
editor.on( 'insertElement', function()
|
||||
{
|
||||
var scayt_instance = plugin.getScayt( editor );
|
||||
if ( plugin.isScaytEnabled( editor ) )
|
||||
{
|
||||
// Unlock the selection before reload, SCAYT will take
|
||||
// care selection update.
|
||||
if ( CKEDITOR.env.ie )
|
||||
editor.getSelection().unlock( true );
|
||||
|
||||
// Swallow any SCAYT engine errors.
|
||||
try{
|
||||
scayt_instance.refresh();
|
||||
}catch( er )
|
||||
{}
|
||||
}
|
||||
}, this, null, 50 );
|
||||
|
||||
editor.on( 'scaytDialog', function( ev ) // Communication with dialog.
|
||||
{
|
||||
ev.data.djConfig = djConfig;
|
||||
ev.data.djConfig = window.djConfig;
|
||||
ev.data.scayt_control = plugin.getScayt( editor );
|
||||
ev.data.tab = openPage;
|
||||
ev.data.scayt = scayt;
|
||||
ev.data.scayt = window.scayt;
|
||||
});
|
||||
|
||||
var dataProcessor = editor.dataProcessor,
|
||||
@@ -124,18 +155,17 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
instances : {},
|
||||
getScayt : function( editor )
|
||||
{
|
||||
var instance = this.instances[ editor.name ];
|
||||
return instance;
|
||||
return this.instances[ editor.name ];
|
||||
},
|
||||
isScaytReady : function( editor )
|
||||
{
|
||||
return this.engineLoaded === true &&
|
||||
'undefined' !== typeof scayt && this.getScayt( editor );
|
||||
'undefined' !== typeof window.scayt && this.getScayt( editor );
|
||||
},
|
||||
isScaytEnabled : function( editor )
|
||||
{
|
||||
var scayt = this.getScayt( editor );
|
||||
return ( scayt ) ? scayt.disabled === false : false;
|
||||
var scayt_instanse = this.getScayt( editor );
|
||||
return ( scayt_instanse ) ? scayt_instanse.disabled === false : false;
|
||||
},
|
||||
loadEngine : function( editor )
|
||||
{
|
||||
@@ -154,21 +184,17 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
0 ); // First to run.
|
||||
|
||||
this.engineLoaded = -1; // Loading in progress.
|
||||
// assign diojo configurable vars
|
||||
var parseUrl = function(data)
|
||||
{
|
||||
var m = data.match(/(.*)[\/\\]([^\/\\]+\.\w+)$/);
|
||||
return { path: m[1], file: m[2] };
|
||||
};
|
||||
|
||||
// compose scayt url
|
||||
var protocol = document.location.protocol;
|
||||
var baseUrl = "svc.spellchecker.net/spellcheck/lf/scayt/scayt.js";
|
||||
var scaytUrl = editor.config.scaytParams.srcScayt ||
|
||||
(protocol + "//" + baseUrl);
|
||||
var scaytConfigBaseUrl = parseUrl(scaytUrl).path + "/";
|
||||
// Default to 'http' for unknown.
|
||||
protocol = protocol.search( /https?:/) != -1? protocol : 'http:';
|
||||
var baseUrl = "svc.spellchecker.net/spellcheck/lf/scayt/scayt1.js";
|
||||
|
||||
djScaytConfig =
|
||||
var scaytUrl = editor.config.scayt_srcUrl || ( protocol + "//" + baseUrl );
|
||||
var scaytConfigBaseUrl = plugin.parseUrl( scaytUrl ).path + "/";
|
||||
|
||||
CKEDITOR._djScaytConfig =
|
||||
{
|
||||
baseUrl: scaytConfigBaseUrl,
|
||||
addOnLoad:
|
||||
@@ -193,6 +219,14 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
);
|
||||
|
||||
return null;
|
||||
},
|
||||
parseUrl : function ( data )
|
||||
{
|
||||
var match;
|
||||
if ( data.match && ( match = data.match(/(.*)[\/\\](.*?\.\w+)$/) ) )
|
||||
return { path: match[1], file: match[2] };
|
||||
else
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -311,9 +345,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
}
|
||||
});
|
||||
|
||||
// Disabling it on IE for now, as it's blocking the browser (#3802).
|
||||
if ( !CKEDITOR.env.ie )
|
||||
{
|
||||
editor.ui.add( 'Scayt', CKEDITOR.UI_MENUBUTTON,
|
||||
{
|
||||
label : editor.lang.scayt.title,
|
||||
@@ -321,17 +352,17 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
className : 'cke_button_scayt',
|
||||
onRender: function()
|
||||
{
|
||||
command.on( 'state', function()
|
||||
{
|
||||
this.setState( command.state );
|
||||
},
|
||||
this);
|
||||
},
|
||||
onMenu : function()
|
||||
{
|
||||
var isEnabled = plugin.isScaytEnabled( editor );
|
||||
command.on( 'state', function()
|
||||
{
|
||||
this.setState( command.state );
|
||||
},
|
||||
this);
|
||||
},
|
||||
onMenu : function()
|
||||
{
|
||||
var isEnabled = plugin.isScaytEnabled( editor );
|
||||
|
||||
editor.getMenuItem( 'scaytToggle' ).label = editor.lang.scayt[ isEnabled ? 'disable' : 'enable' ];
|
||||
editor.getMenuItem( 'scaytToggle' ).label = editor.lang.scayt[ isEnabled ? 'disable' : 'enable' ];
|
||||
|
||||
return {
|
||||
scaytToggle : CKEDITOR.TRISTATE_OFF,
|
||||
@@ -341,25 +372,24 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If the "contextmenu" plugin is loaded, register the listeners.
|
||||
if ( editor.contextMenu && editor.addMenuItems )
|
||||
{
|
||||
editor.contextMenu.addListener( function( element, selection )
|
||||
editor.contextMenu.addListener( function( element )
|
||||
{
|
||||
var scayt_control = plugin.getScayt( editor );
|
||||
if ( !plugin.isScaytEnabled( editor ) || !element || !element.$ )
|
||||
if ( !( plugin.isScaytEnabled( editor ) && element ) )
|
||||
return null;
|
||||
|
||||
var word = scayt_control.getWord( element.$ );
|
||||
var scayt_control = plugin.getScayt( editor ),
|
||||
word = scayt_control.getWord( element.$ );
|
||||
|
||||
if ( !word )
|
||||
return null;
|
||||
|
||||
var sLang = scayt_control.getLang(),
|
||||
_r = {},
|
||||
items_suggestion = scayt.getSuggestion( word, sLang );
|
||||
items_suggestion = window.scayt.getSuggestion( word, sLang );
|
||||
if (!items_suggestion || !items_suggestion.length )
|
||||
return null;
|
||||
// Remove unused commands and menuitems
|
||||
@@ -384,7 +414,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
var exec = ( function( el, s )
|
||||
{
|
||||
return {
|
||||
exec: function( editor )
|
||||
exec: function()
|
||||
{
|
||||
scayt_control.replace(el, s);
|
||||
}
|
||||
@@ -438,7 +468,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
exec: function()
|
||||
{
|
||||
scayt.addWordToUserDictionary( element.$ );
|
||||
window.scayt.addWordToUserDictionary( element.$ );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -454,11 +484,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
mainSuggestions[ 'scayt_ignore_all' ] = CKEDITOR.TRISTATE_OFF;
|
||||
mainSuggestions[ 'scayt_add_word' ] = CKEDITOR.TRISTATE_OFF;
|
||||
|
||||
// ** ahow ads entry point
|
||||
// ** hide ads listener register
|
||||
// try{
|
||||
//scayt_control.showBanner( editor )
|
||||
// }catch(err){}
|
||||
if ( scayt_control.fireOnContextMenu )
|
||||
scayt_control.fireOnContextMenu( editor );
|
||||
|
||||
return mainSuggestions;
|
||||
});
|
||||
@@ -480,6 +507,5 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
});
|
||||
})();
|
||||
|
||||
CKEDITOR.config.scaytParams = CKEDITOR.config.scaytParams || {};
|
||||
CKEDITOR.config.scayt_maxSuggestions = 5;
|
||||
CKEDITOR.config.scayt_maxSuggestions = 5;
|
||||
CKEDITOR.config.scayt_autoStartup = false;
|
||||
|
||||
@@ -133,7 +133,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
saveSelection();
|
||||
});
|
||||
|
||||
editor.window.on( 'blur', function()
|
||||
// Check document selection before 'blur' fired, this
|
||||
// will prevent us from breaking text selection somewhere
|
||||
// else on the host page.(#3909)
|
||||
editor.document.on( 'beforedeactivate', function()
|
||||
{
|
||||
// Disable selections from being saved.
|
||||
saveEnabled = false;
|
||||
@@ -488,7 +491,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
}
|
||||
|
||||
testRange.setEndPoint( 'StartToStart', range );
|
||||
var distance = testRange.text.length;
|
||||
// IE report line break as CRLF with range.text but
|
||||
// only LF with textnode.nodeValue, normalize them to avoid
|
||||
// breaking character counting logic below. (#3949)
|
||||
var distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length;
|
||||
|
||||
while ( distance > 0 )
|
||||
distance -= siblings[ --i ].nodeValue.length;
|
||||
@@ -777,7 +783,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
if ( this.isLocked )
|
||||
{
|
||||
var range = new CKEDITOR.dom.range();
|
||||
var range = new CKEDITOR.dom.range( this.document );
|
||||
range.setStartBefore( element );
|
||||
range.setEndAfter( element );
|
||||
|
||||
@@ -855,7 +861,20 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
var range = ranges[ i ];
|
||||
var nativeRange = this.document.$.createRange();
|
||||
nativeRange.setStart( range.startContainer.$, range.startOffset );
|
||||
var startContainer = range.startContainer;
|
||||
|
||||
// In FF2, if we have a collapsed range, inside an empty
|
||||
// element, we must add something to it otherwise the caret
|
||||
// will not be visible.
|
||||
if ( range.collapsed &&
|
||||
( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 ) &&
|
||||
startContainer.type == CKEDITOR.NODE_ELEMENT &&
|
||||
!startContainer.getChildCount() )
|
||||
{
|
||||
startContainer.appendText( '' );
|
||||
}
|
||||
|
||||
nativeRange.setStart( startContainer.$, range.startOffset );
|
||||
nativeRange.setEnd( range.endContainer.$, range.endOffset );
|
||||
|
||||
// Select the range.
|
||||
@@ -927,10 +946,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
CKEDITOR.dom.range.prototype.select =
|
||||
CKEDITOR.env.ie ?
|
||||
// V2
|
||||
function()
|
||||
function( forceExpand )
|
||||
{
|
||||
var collapsed = this.collapsed;
|
||||
var isStartMakerAlone;
|
||||
var isStartMarkerAlone;
|
||||
var dummySpan;
|
||||
|
||||
var bookmark = this.createBookmark();
|
||||
@@ -963,19 +982,11 @@ CKEDITOR.dom.range.prototype.select =
|
||||
}
|
||||
else
|
||||
{
|
||||
// The isStartMakerAlone logic comes from V2. It guarantees that the lines
|
||||
// will expand and that the cursor will be blinking on the right place.
|
||||
// Actually, we are using this flag just to avoid using this hack in all
|
||||
// situations, but just on those needed.
|
||||
|
||||
// But, in V3, somehow it is not interested on working whe hitting SHIFT+ENTER
|
||||
// inside text. So, let's jsut leave the hack happen always.
|
||||
|
||||
// I'm still leaving the code here just in case. We may find some other IE
|
||||
// weirdness and uncommenting this stuff may be useful.
|
||||
|
||||
// isStartMakerAlone = ( !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) ) )
|
||||
// && !startNode.hasNext();
|
||||
// The isStartMarkerAlone logic comes from V2. It guarantees that the lines
|
||||
// will expand and that the cursor will be blinking on the right place.
|
||||
// Actually, we are using this flag just to avoid using this hack in all
|
||||
// situations, but just on those needed.
|
||||
isStartMarkerAlone = forceExpand || !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) );
|
||||
|
||||
// Append a temporary <span></span> before the selection.
|
||||
// This is needed to avoid IE destroying selections inside empty
|
||||
@@ -986,14 +997,14 @@ CKEDITOR.dom.range.prototype.select =
|
||||
dummySpan.setHtml( '' ); // Zero Width No-Break Space (U+FEFF). See #1359.
|
||||
dummySpan.insertBefore( startNode );
|
||||
|
||||
// if ( isStartMakerAlone )
|
||||
// {
|
||||
if ( isStartMarkerAlone )
|
||||
{
|
||||
// To expand empty blocks or line spaces after <br>, we need
|
||||
// instead to have any char, which will be later deleted using the
|
||||
// selection.
|
||||
// \ufeff = Zero Width No-Break Space (U+FEFF). (#1359)
|
||||
this.document.createText( '\ufeff' ).insertBefore( startNode );
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the markers (reset the position, because of the changes in the DOM tree).
|
||||
@@ -1002,8 +1013,8 @@ CKEDITOR.dom.range.prototype.select =
|
||||
|
||||
if ( collapsed )
|
||||
{
|
||||
// if ( isStartMakerAlone )
|
||||
// {
|
||||
if ( isStartMarkerAlone )
|
||||
{
|
||||
// Move the selection start to include the temporary \ufeff.
|
||||
ieRange.moveStart( 'character', -1 );
|
||||
|
||||
@@ -1011,9 +1022,9 @@ CKEDITOR.dom.range.prototype.select =
|
||||
|
||||
// Remove our temporary stuff.
|
||||
this.document.$.selection.clear();
|
||||
// }
|
||||
// else
|
||||
// ieRange.select();
|
||||
}
|
||||
else
|
||||
ieRange.select();
|
||||
|
||||
dummySpan.remove();
|
||||
}
|
||||
|
||||
@@ -142,4 +142,12 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
});
|
||||
} )();
|
||||
|
||||
/**
|
||||
* Whether to automaticaly enable the "show block" command when the editor
|
||||
* loads.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
* @example
|
||||
* config.startupOutlineBlocks = true;
|
||||
*/
|
||||
CKEDITOR.config.startupOutlineBlocks = false;
|
||||
|
||||
@@ -7,7 +7,7 @@ CKEDITOR.dialog.add( 'smiley', function( editor )
|
||||
{
|
||||
var config = editor.config,
|
||||
images = config.smiley_images,
|
||||
columns = config.smiley_columns,
|
||||
columns = 8,
|
||||
i;
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,13 +19,56 @@ CKEDITOR.plugins.add( 'smiley',
|
||||
}
|
||||
} );
|
||||
|
||||
CKEDITOR.config.smiley_path = CKEDITOR.basePath + '_source/plugins/smiley/images/';
|
||||
/**
|
||||
* The base path used to build the URL for the smiley images. It must end with
|
||||
* a slash.
|
||||
* @type String
|
||||
* @default {@link CKEDITOR.basePath} + 'plugins/smiley/images/'
|
||||
* @example
|
||||
* config.smiley_path = 'http://www.example.com/images/smileys/';
|
||||
* @example
|
||||
* config.smiley_path = '/images/smileys/';
|
||||
*/
|
||||
CKEDITOR.config.smiley_path = CKEDITOR.basePath +
|
||||
'plugins/smiley/images/';
|
||||
|
||||
CKEDITOR.config.smiley_images = [ 'regular_smile.gif','sad_smile.gif','wink_smile.gif','teeth_smile.gif','confused_smile.gif','tounge_smile.gif',
|
||||
/**
|
||||
* The file names for the smileys to be displayed. These files must be
|
||||
* contained inside the URL path defined with the
|
||||
* {@link CKEDITOR.config.smiley_path} setting.
|
||||
* @type Array
|
||||
* @default (see example)
|
||||
* @example
|
||||
* // This is actually the default value.
|
||||
* config.smiley_images = [
|
||||
* 'regular_smile.gif','sad_smile.gif','wink_smile.gif','teeth_smile.gif','confused_smile.gif','tounge_smile.gif',
|
||||
* 'embaressed_smile.gif','omg_smile.gif','whatchutalkingabout_smile.gif','angry_smile.gif','angel_smile.gif','shades_smile.gif',
|
||||
* 'devil_smile.gif','cry_smile.gif','lightbulb.gif','thumbs_down.gif','thumbs_up.gif','heart.gif',
|
||||
* 'broken_heart.gif','kiss.gif','envelope.gif'];
|
||||
*/
|
||||
CKEDITOR.config.smiley_images = [
|
||||
'regular_smile.gif','sad_smile.gif','wink_smile.gif','teeth_smile.gif','confused_smile.gif','tounge_smile.gif',
|
||||
'embaressed_smile.gif','omg_smile.gif','whatchutalkingabout_smile.gif','angry_smile.gif','angel_smile.gif','shades_smile.gif',
|
||||
'devil_smile.gif','cry_smile.gif','lightbulb.gif','thumbs_down.gif','thumbs_up.gif','heart.gif',
|
||||
'broken_heart.gif','kiss.gif','envelope.gif'];
|
||||
|
||||
CKEDITOR.config.smiley_descriptions = [ ':)', ':(', ';)', ':D', ':/', ':P', '', '', '', '', '', '', '', ';(', '', '', '', '', ':kiss', '' ];
|
||||
|
||||
CKEDITOR.config.smiley_columns = 8;
|
||||
/**
|
||||
* The description to be used for each of the smileys defined in the
|
||||
* {@link CKEDITOR.config.smiley_images} setting. Each entry in this array list
|
||||
* must match its relative pair in the {@link CKEDITOR.config.smiley_images}
|
||||
* setting.
|
||||
* @type Array
|
||||
* @default (see example)
|
||||
* @example
|
||||
* // This is actually the default value.
|
||||
* config.smiley_descriptions = [
|
||||
* ':)', ':(', ';)', ':D', ':/', ':P',
|
||||
* '', '', '', '', '', '',
|
||||
* '', ';(', '', '', '', '',
|
||||
* '', ':kiss', '' ];
|
||||
*/
|
||||
CKEDITOR.config.smiley_descriptions = [
|
||||
':)', ':(', ';)', ':D', ':/', ':P',
|
||||
'', '', '', '', '', '',
|
||||
'', ';(', '', '', '', '',
|
||||
'', ':kiss', '' ];
|
||||
|
||||
@@ -39,7 +39,8 @@ CKEDITOR.plugins.add( 'sourcearea',
|
||||
|
||||
var styles =
|
||||
{
|
||||
width : '100%',
|
||||
// IE7 has overflow the <textarea> from wrapping table cell.
|
||||
width : CKEDITOR.env.ie7Compat ? '99%' : '100%',
|
||||
height : '100%',
|
||||
resize : 'none',
|
||||
outline : 'none',
|
||||
@@ -124,6 +125,9 @@ CKEDITOR.plugins.add( 'sourcearea',
|
||||
|
||||
if ( onResize )
|
||||
editor.removeListener( 'resize', onResize );
|
||||
|
||||
if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 )
|
||||
holderElement.removeStyle( 'position' );
|
||||
},
|
||||
|
||||
focus : function()
|
||||
|
||||
@@ -257,12 +257,12 @@ CKEDITOR.dialog.add( 'specialchar', function( editor )
|
||||
if ( chars[ i ] )
|
||||
{
|
||||
html.push(
|
||||
'<td class="cke_dark_background">' +
|
||||
'<a href="javascript: void(0);" style="display: block; height: 1.25em; margin-top: 0.25em; text-align: center;" title="', chars[i].replace( /&/g, '&' ), '"' +
|
||||
'<td class="cke_dark_background" style="cursor: default">' +
|
||||
'<a href="javascript: void(0);" style="cursor: inherit; display: block; height: 1.25em; margin-top: 0.25em; text-align: center;" title="', chars[i].replace( /&/g, '&' ), '"' +
|
||||
' onkeydown="CKEDITOR.tools.callFunction( ' + onKeydown + ', event, this )"' +
|
||||
' onclick="CKEDITOR.tools.callFunction(' + onClick + ', this); return false;"' +
|
||||
' tabindex="-1">' +
|
||||
'<span style="margin: 0 auto;">' +
|
||||
'<span style="margin: 0 auto;cursor: inherit">' +
|
||||
chars[i] +
|
||||
'</span></a>');
|
||||
}
|
||||
|
||||
@@ -197,7 +197,11 @@ CKEDITOR.STYLE_OBJECT = 3;
|
||||
{
|
||||
if ( attName == '_length' )
|
||||
continue;
|
||||
if ( attribs[attName] == element.getAttribute( attName ) )
|
||||
|
||||
var elementAttr = element.getAttribute( attName );
|
||||
if ( attribs[attName] ==
|
||||
( attName == 'style' ?
|
||||
normalizeCssText( elementAttr, false ) : elementAttr ) )
|
||||
{
|
||||
if ( !fullMatch )
|
||||
return true;
|
||||
@@ -315,7 +319,8 @@ CKEDITOR.STYLE_OBJECT = 3;
|
||||
// Probably the document end is reached, we need a marker node.
|
||||
if ( !lastNode )
|
||||
{
|
||||
lastNode = document.createText( '' );
|
||||
var marker;
|
||||
lastNode = marker = document.createText( '' );
|
||||
lastNode.insertAfter( range.endContainer );
|
||||
}
|
||||
// The detection algorithm below skips the contents inside bookmark nodes, so
|
||||
@@ -336,7 +341,7 @@ CKEDITOR.STYLE_OBJECT = 3;
|
||||
// simpler.
|
||||
if ( !lastNode )
|
||||
{
|
||||
lastNode = document.createText( '' );
|
||||
lastNode = marker = document.createText( '' );
|
||||
lastNode.insertAfter( firstNode );
|
||||
}
|
||||
}
|
||||
@@ -443,7 +448,7 @@ CKEDITOR.STYLE_OBJECT = 3;
|
||||
{
|
||||
if ( parent.getName() == elementName )
|
||||
{
|
||||
for ( var attName in def.attribs )
|
||||
for ( var attName in def.attributes )
|
||||
{
|
||||
if ( styleNode.getAttribute( attName ) == parent.getAttribute( attName ) )
|
||||
styleNode.removeAttribute( attName );
|
||||
@@ -497,8 +502,8 @@ CKEDITOR.STYLE_OBJECT = 3;
|
||||
}
|
||||
}
|
||||
|
||||
// this._FixBookmarkStart( startNode );
|
||||
|
||||
// Remove the temporary marking node.(#4111)
|
||||
marker && marker.remove();
|
||||
range.moveToBookmark( bookmark );
|
||||
}
|
||||
|
||||
@@ -662,12 +667,13 @@ CKEDITOR.STYLE_OBJECT = 3;
|
||||
}
|
||||
|
||||
range.moveToBookmark( bookmark );
|
||||
}
|
||||
}
|
||||
|
||||
function applyBlockStyle( range )
|
||||
{
|
||||
// Bookmark the range so we can re-select it after processing.
|
||||
var bookmark = range.createBookmark();
|
||||
// Serializible bookmarks is needed here since
|
||||
// elements may be merged.
|
||||
var bookmark = range.createBookmark( true );
|
||||
|
||||
var iterator = range.createIterator();
|
||||
iterator.enforceRealBlocks = true;
|
||||
@@ -678,42 +684,186 @@ CKEDITOR.STYLE_OBJECT = 3;
|
||||
|
||||
while( ( block = iterator.getNextParagraph() ) ) // Only one =
|
||||
{
|
||||
// Create the new node right before the current one.
|
||||
var newBlock = getElement( this, doc );
|
||||
|
||||
// Check if we are changing from/to <pre>.
|
||||
// var newBlockIsPre = newBlock.nodeName.IEquals( 'pre' );
|
||||
// var blockIsPre = block.nodeName.IEquals( 'pre' );
|
||||
|
||||
// var toPre = newBlockIsPre && !blockIsPre;
|
||||
// var fromPre = !newBlockIsPre && blockIsPre;
|
||||
|
||||
// Move everything from the current node to the new one.
|
||||
// if ( toPre )
|
||||
// newBlock = this._ToPre( doc, block, newBlock );
|
||||
// else if ( fromPre )
|
||||
// newBlock = this._FromPre( doc, block, newBlock );
|
||||
// else // Convering from a regular block to another regular block.
|
||||
block.moveChildren( newBlock );
|
||||
|
||||
// Replace the current block.
|
||||
newBlock.insertBefore( block );
|
||||
block.remove();
|
||||
|
||||
// Complete other tasks after inserting the node in the DOM.
|
||||
// if ( newBlockIsPre )
|
||||
// {
|
||||
// if ( previousPreBlock )
|
||||
// this._CheckAndMergePre( previousPreBlock, newBlock ) ; // Merge successive <pre> blocks.
|
||||
// previousPreBlock = newBlock;
|
||||
// }
|
||||
// else if ( fromPre )
|
||||
// this._CheckAndSplitPre( newBlock ) ; // Split <br><br> in successive <pre>s.
|
||||
replaceBlock( block, newBlock );
|
||||
}
|
||||
|
||||
range.moveToBookmark( bookmark );
|
||||
}
|
||||
|
||||
// Replace the original block with new one, with special treatment
|
||||
// for <pre> blocks to make sure content format is well preserved, and merging/splitting adjacent
|
||||
// when necessary.(#3188)
|
||||
function replaceBlock( block, newBlock )
|
||||
{
|
||||
var newBlockIsPre = newBlock.is( 'pre' );
|
||||
var blockIsPre = block.is( 'pre' );
|
||||
|
||||
var isToPre = newBlockIsPre && !blockIsPre;
|
||||
var isFromPre = !newBlockIsPre && blockIsPre;
|
||||
|
||||
if ( isToPre )
|
||||
newBlock = toPre( block, newBlock );
|
||||
else if ( isFromPre )
|
||||
// Split big <pre> into pieces before start to convert.
|
||||
newBlock = fromPres( splitIntoPres( block ), newBlock );
|
||||
else
|
||||
block.moveChildren( newBlock );
|
||||
|
||||
newBlock.replace( block );
|
||||
|
||||
if ( newBlockIsPre )
|
||||
{
|
||||
// Merge previous <pre> blocks.
|
||||
mergePre( newBlock );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a <pre> block with a previous sibling if available.
|
||||
*/
|
||||
function mergePre( preBlock )
|
||||
{
|
||||
var previousBlock;
|
||||
if ( !( ( previousBlock = preBlock.getPreviousSourceNode( true, CKEDITOR.NODE_ELEMENT ) )
|
||||
&& previousBlock.is
|
||||
&& previousBlock.is( 'pre') ) )
|
||||
return;
|
||||
|
||||
// Merge the previous <pre> block contents into the current <pre>
|
||||
// block.
|
||||
//
|
||||
// Another thing to be careful here is that currentBlock might contain
|
||||
// a '\n' at the beginning, and previousBlock might contain a '\n'
|
||||
// towards the end. These new lines are not normally displayed but they
|
||||
// become visible after merging.
|
||||
var mergedHtml = replace( previousBlock.getHtml(), /\n$/, '' ) + '\n\n' +
|
||||
replace( preBlock.getHtml(), /^\n/, '' ) ;
|
||||
|
||||
// Krugle: IE normalizes innerHTML from <pre>, breaking whitespaces.
|
||||
if ( CKEDITOR.env.ie )
|
||||
preBlock.$.outerHTML = '<pre>' + mergedHtml + '</pre>';
|
||||
else
|
||||
preBlock.setHtml( mergedHtml );
|
||||
|
||||
previousBlock.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Split into multiple <pre> blocks separated by double line-break.
|
||||
* @param preBlock
|
||||
*/
|
||||
function splitIntoPres( preBlock )
|
||||
{
|
||||
// Exclude the ones at header OR at tail,
|
||||
// and ignore bookmark content between them.
|
||||
var duoBrRegex = /(\S\s*)\n(?:\s|(<span[^>]+_fck_bookmark.*?\/span>))*\n(?!$)/gi,
|
||||
blockName = preBlock.getName(),
|
||||
splitedHtml = replace( preBlock.getOuterHtml(),
|
||||
duoBrRegex,
|
||||
function( match, charBefore, bookmark )
|
||||
{
|
||||
return charBefore + '</pre>' + bookmark + '<pre>';
|
||||
} );
|
||||
|
||||
var pres = [];
|
||||
splitedHtml.replace( /<pre>([\s\S]*?)<\/pre>/gi, function( match, preContent ){
|
||||
pres.push( preContent );
|
||||
} );
|
||||
return pres;
|
||||
}
|
||||
|
||||
// Wrapper function of String::replace without considering of head/tail bookmarks nodes.
|
||||
function replace( str, regexp, replacement )
|
||||
{
|
||||
var headBookmark = '',
|
||||
tailBookmark = '';
|
||||
|
||||
str = str.replace( /(^<span[^>]+_fck_bookmark.*?\/span>)|(<span[^>]+_fck_bookmark.*?\/span>$)/gi,
|
||||
function( str, m1, m2 ){
|
||||
m1 && ( headBookmark = m1 );
|
||||
m2 && ( tailBookmark = m2 );
|
||||
return '';
|
||||
} );
|
||||
return headBookmark + str.replace( regexp, replacement ) + tailBookmark;
|
||||
}
|
||||
/**
|
||||
* Converting a list of <pre> into blocks with format well preserved.
|
||||
*/
|
||||
function fromPres( preHtmls, newBlock )
|
||||
{
|
||||
var docFrag = new CKEDITOR.dom.documentFragment( newBlock.getDocument() );
|
||||
for ( var i = 0 ; i < preHtmls.length ; i++ )
|
||||
{
|
||||
var blockHtml = preHtmls[ i ];
|
||||
|
||||
// 1. Trim the first and last line-breaks immediately after and before <pre>,
|
||||
// they're not visible.
|
||||
blockHtml = blockHtml.replace( /(\r\n|\r)/g, '\n' ) ;
|
||||
blockHtml = replace( blockHtml, /^[ \t]*\n/, '' ) ;
|
||||
blockHtml = replace( blockHtml, /\n$/, '' ) ;
|
||||
// 2. Convert spaces or tabs at the beginning or at the end to
|
||||
blockHtml = replace( blockHtml, /^[ \t]+|[ \t]+$/g, function( match, offset, s )
|
||||
{
|
||||
if ( match.length == 1 ) // one space, preserve it
|
||||
return ' ' ;
|
||||
else if ( !offset ) // beginning of block
|
||||
return CKEDITOR.tools.repeat( ' ', match.length - 1 ) + ' ';
|
||||
else // end of block
|
||||
return ' ' + CKEDITOR.tools.repeat( ' ', match.length - 1 );
|
||||
} ) ;
|
||||
|
||||
// 3. Convert \n to <BR>.
|
||||
// 4. Convert contiguous (i.e. non-singular) spaces or tabs to
|
||||
blockHtml = blockHtml.replace( /\n/g, '<br>' ) ;
|
||||
blockHtml = blockHtml.replace( /[ \t]{2,}/g,
|
||||
function ( match )
|
||||
{
|
||||
return CKEDITOR.tools.repeat( ' ', match.length - 1 ) + ' ' ;
|
||||
} ) ;
|
||||
|
||||
var newBlockClone = newBlock.clone();
|
||||
newBlockClone.setHtml( blockHtml );
|
||||
docFrag.append( newBlockClone );
|
||||
}
|
||||
return docFrag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converting from a non-PRE block to a PRE block in formatting operations.
|
||||
*/
|
||||
function toPre( block, newBlock )
|
||||
{
|
||||
// First trim the block content.
|
||||
var preHtml = block.getHtml();
|
||||
|
||||
// 1. Trim head/tail spaces, they're not visible.
|
||||
preHtml = replace( preHtml, /(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, '' );
|
||||
// 2. Delete ANSI whitespaces immediately before and after <BR> because
|
||||
// they are not visible.
|
||||
preHtml = preHtml.replace( /[ \t\r\n]*(<br[^>]*>)[ \t\r\n]*/gi, '$1' );
|
||||
// 3. Compress other ANSI whitespaces since they're only visible as one
|
||||
// single space previously.
|
||||
// 4. Convert to spaces since is no longer needed in <PRE>.
|
||||
preHtml = preHtml.replace( /([ \t\n\r]+| )/g, ' ' );
|
||||
// 5. Convert any <BR /> to \n. This must not be done earlier because
|
||||
// the \n would then get compressed.
|
||||
preHtml = preHtml.replace( /<br\b[^>]*>/gi, '\n' );
|
||||
|
||||
// Krugle: IE normalizes innerHTML to <pre>, breaking whitespaces.
|
||||
if ( CKEDITOR.env.ie )
|
||||
{
|
||||
var temp = block.getDocument().createElement( 'div' );
|
||||
temp.append( newBlock );
|
||||
newBlock.$.outerHTML = '<pre>' + preHtml + '</pre>';
|
||||
newBlock = temp.getFirst().remove();
|
||||
}
|
||||
else
|
||||
newBlock.setHtml( preHtml );
|
||||
|
||||
return newBlock;
|
||||
}
|
||||
|
||||
// Removes a style from an element itself, don't care about its subtree.
|
||||
function removeFromElement( style, element )
|
||||
{
|
||||
@@ -1032,13 +1182,25 @@ CKEDITOR.STYLE_OBJECT = 3;
|
||||
return overrides;
|
||||
}
|
||||
|
||||
function normalizeCssText( unparsedCssText )
|
||||
function normalizeCssText( unparsedCssText, nativeNormalize )
|
||||
{
|
||||
// Injects the style in a temporary span object, so the browser parses it,
|
||||
// retrieving its final format.
|
||||
var temp = new CKEDITOR.dom.element( 'span' );
|
||||
temp.setAttribute( 'style', unparsedCssText );
|
||||
return temp.getAttribute( 'style' );
|
||||
var styleText;
|
||||
if ( nativeNormalize !== false )
|
||||
{
|
||||
// Injects the style in a temporary span object, so the browser parses it,
|
||||
// retrieving its final format.
|
||||
var temp = new CKEDITOR.dom.element( 'span' );
|
||||
temp.setAttribute( 'style', unparsedCssText );
|
||||
styleText = temp.getAttribute( 'style' );
|
||||
}
|
||||
else
|
||||
styleText = unparsedCssText;
|
||||
|
||||
// Shrinking white-spaces around colon and semi-colon (#4147).
|
||||
// Compensate tail semi-colon.
|
||||
return styleText.replace( /\s*([;:])\s*/, '$1' )
|
||||
.replace( /([^\s;])$/, '$1;')
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
function applyStyle( document, remove )
|
||||
|
||||
@@ -272,4 +272,24 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* The "styles definition set" to load into the styles combo. The styles may
|
||||
* be defined in the page containing the editor, or can be loaded on demand
|
||||
* from an external file when opening the styles combo for the fist time. In
|
||||
* the second case, if this setting contains only a name, the styles definition
|
||||
* file will be loaded from the "styles" folder inside the stylescombo plugin
|
||||
* folder. Otherwise, this setting has the "name:url" syntax, making it
|
||||
* possible to set the URL from which loading the styles file.
|
||||
* @type string
|
||||
* @default 'default'
|
||||
* @example
|
||||
* // Load from the stylescombo styles folder (mystyles.js file).
|
||||
* config.stylesCombo_stylesSet = 'mystyles';
|
||||
* @example
|
||||
* // Load from a relative URL.
|
||||
* config.stylesCombo_stylesSet = 'mystyles:/editorstyles/styles.js';
|
||||
* @example
|
||||
* // Load from a full URL.
|
||||
* config.stylesCombo_stylesSet = 'mystyles:http://www.example.com/editorstyles/styles.js';
|
||||
*/
|
||||
CKEDITOR.config.stylesCombo_stylesSet = 'default';
|
||||
|
||||
@@ -256,9 +256,9 @@ CKEDITOR.dom.element.prototype.focusPrevious = function( ignoreChildren )
|
||||
|
||||
/**
|
||||
* Intructs the editor to add a number of spaces (&nbsp;) to the text when
|
||||
* hitting the TAB key. If set to zero, the TAB key will have its default
|
||||
* behavior instead (like moving out of the editor).
|
||||
* @type {Number}
|
||||
* hitting the TAB key. If set to zero, the TAB key will be used to move the
|
||||
* cursor focus to the next element in the page, out of the editor focus.
|
||||
* @type Number
|
||||
* @default 0
|
||||
* @example
|
||||
* config.tabSpaces = 4;
|
||||
|
||||
@@ -314,17 +314,15 @@ CKEDITOR.dialog.add( 'cellProperties', function( editor )
|
||||
],
|
||||
onShow : function()
|
||||
{
|
||||
// Get the selected table cell.
|
||||
var startElement = editor.getSelection().getStartElement();
|
||||
this.cell = startElement.getAscendant( 'td', true ) || startElement.getAscendant( 'th', true );
|
||||
|
||||
// Call setupContent().
|
||||
this.setupContent( this.cell );
|
||||
this.cells = CKEDITOR.plugins.tabletools.getSelectedCells(
|
||||
this._.editor.getSelection() );
|
||||
this.setupContent( this.cells[ 0 ] );
|
||||
},
|
||||
onOk : function()
|
||||
{
|
||||
// Call commitContent().
|
||||
this.commitContent( this.cell );
|
||||
var cells = this.cells;
|
||||
for ( var i = 0 ; i < cells.length ; i++ )
|
||||
this.commitContent( cells[ i ] );
|
||||
}
|
||||
};
|
||||
} );
|
||||
|
||||
@@ -416,7 +416,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
}
|
||||
}
|
||||
|
||||
CKEDITOR.plugins.add( 'tabletools',
|
||||
// Context menu on table caption incorrect (#3834)
|
||||
var contextMenuTags = { thead : 1, tbody : 1, tfoot : 1, td : 1, tr : 1, th : 1 };
|
||||
|
||||
CKEDITOR.plugins.tabletools =
|
||||
{
|
||||
init : function( editor )
|
||||
{
|
||||
@@ -544,12 +547,11 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
getItems : function()
|
||||
{
|
||||
var cells = getSelectedCells( editor.getSelection() );
|
||||
|
||||
return {
|
||||
tablecell_insertBefore : CKEDITOR.TRISTATE_OFF,
|
||||
tablecell_insertAfter : CKEDITOR.TRISTATE_OFF,
|
||||
tablecell_delete : CKEDITOR.TRISTATE_OFF,
|
||||
tablecell_properties : cells.length == 1 ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED
|
||||
tablecell_properties : cells.length > 0 ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED
|
||||
};
|
||||
}
|
||||
},
|
||||
@@ -674,9 +676,9 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
if ( !element )
|
||||
return null;
|
||||
|
||||
var isCell = !element.is( 'table' ) && element.hasAscendant( 'table' ) ;
|
||||
|
||||
if ( isCell )
|
||||
while ( element )
|
||||
{
|
||||
if ( element.getName() in contextMenuTags )
|
||||
{
|
||||
return {
|
||||
tablecell : CKEDITOR.TRISTATE_OFF,
|
||||
@@ -684,10 +686,16 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
tablecolumn : CKEDITOR.TRISTATE_OFF
|
||||
};
|
||||
}
|
||||
element = element.getParent();
|
||||
}
|
||||
|
||||
return null;
|
||||
return null;
|
||||
} );
|
||||
}
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
getSelectedCells : getSelectedCells
|
||||
|
||||
};
|
||||
CKEDITOR.plugins.add( 'tabletools', CKEDITOR.plugins.tabletools );
|
||||
})();
|
||||
|
||||
@@ -65,6 +65,8 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
* comma. It must match definitions loaded with the templates_files setting.
|
||||
* @type String
|
||||
* @default 'default'
|
||||
* @example
|
||||
* config.templates = 'my_templates';
|
||||
*/
|
||||
CKEDITOR.config.templates = 'default';
|
||||
|
||||
@@ -72,6 +74,13 @@ CKEDITOR.config.templates = 'default';
|
||||
* The list of templates definition files to load.
|
||||
* @type (String) Array
|
||||
* @default [ 'plugins/templates/templates/default.js' ]
|
||||
* @example
|
||||
* config.templates_files =
|
||||
* [
|
||||
* '/editor_templates/site_default.js',
|
||||
* 'http://www.example.com/user_templates.js
|
||||
* ];
|
||||
*
|
||||
*/
|
||||
CKEDITOR.config.templates_files =
|
||||
[
|
||||
@@ -80,9 +89,11 @@ CKEDITOR.config.templates_files =
|
||||
];
|
||||
|
||||
/**
|
||||
* Whether replace the current document content OR insert current
|
||||
* editing position.
|
||||
* Whether the "Replace actual contents" checkbox is checked by default in the
|
||||
* Templates dialog.
|
||||
* @type Boolean
|
||||
* @default true
|
||||
* @example
|
||||
* config.templates_replaceContent = false;
|
||||
*/
|
||||
CKEDITOR.config.templates_replaceContent = true;
|
||||
|
||||
@@ -127,8 +127,17 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
|
||||
for ( var r = 0 ; r < toolbar.length ; r++ )
|
||||
{
|
||||
var row = toolbar[ r ],
|
||||
toolbarId = 'cke_' + CKEDITOR.tools.getNextNumber(),
|
||||
var row = toolbar[ r ];
|
||||
|
||||
// It's better to check if the row object is really
|
||||
// available because it's a common mistake to leave
|
||||
// an extra comma in the toolbar definition
|
||||
// settings, which leads on the editor not loading
|
||||
// at all in IE. (#3983)
|
||||
if ( !row )
|
||||
continue;
|
||||
|
||||
var toolbarId = 'cke_' + CKEDITOR.tools.getNextNumber(),
|
||||
toolbarObj = { id : toolbarId, items : [] };
|
||||
|
||||
if ( groupStarted )
|
||||
@@ -302,20 +311,51 @@ CKEDITOR.config.toolbarLocation = 'top';
|
||||
/**
|
||||
* The toolbar definition. It is an array of toolbars (strips),
|
||||
* each one being also an array, containing a list of UI items.
|
||||
* Note that this setting is composed by "toolbar_" added by the toolbar name,
|
||||
* which in this case is called "Basic". This second part of the setting name
|
||||
* can be anything. You must use this name in the
|
||||
* {@link CKEDITOR.config.toolbar} setting, so you instruct the editor which
|
||||
* toolbar_(name) setting to you.
|
||||
* @type Array
|
||||
* @example
|
||||
* // Defines a toolbar with only one strip containing the "Source" button, a
|
||||
* // separator and the "Bold" and "Italic" buttons.
|
||||
* <b>CKEDITOR.config.toolbar_Basic =
|
||||
* <b>config.toolbar_Basic =
|
||||
* [
|
||||
* [ 'Source', '-', 'Bold', 'Italic' ]
|
||||
* ]</b>;
|
||||
* config.toolbar = 'Basic';
|
||||
*/
|
||||
CKEDITOR.config.toolbar_Basic =
|
||||
[
|
||||
['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink','-','About']
|
||||
];
|
||||
|
||||
/**
|
||||
* This is the default toolbar definition used by the editor. It contains all
|
||||
* editor features.
|
||||
* @type Array
|
||||
* @default (see example)
|
||||
* @example
|
||||
* // This is actually the default value.
|
||||
* config.toolbar_Full =
|
||||
* [
|
||||
* ['Source','-','Save','NewPage','Preview','-','Templates'],
|
||||
* ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'],
|
||||
* ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
|
||||
* ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
|
||||
* '/',
|
||||
* ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
|
||||
* ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
|
||||
* ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
|
||||
* ['Link','Unlink','Anchor'],
|
||||
* ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],
|
||||
* '/',
|
||||
* ['Styles','Format','Font','FontSize'],
|
||||
* ['TextColor','BGColor'],
|
||||
* ['Maximize', 'ShowBlocks','-','About']
|
||||
* ];
|
||||
*/
|
||||
CKEDITOR.config.toolbar_Full =
|
||||
[
|
||||
['Source','-','Save','NewPage','Preview','-','Templates'],
|
||||
@@ -326,7 +366,8 @@ CKEDITOR.config.toolbar_Full =
|
||||
['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
|
||||
['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
|
||||
['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
|
||||
['Link','Unlink','Anchor'], ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],
|
||||
['Link','Unlink','Anchor'],
|
||||
['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],
|
||||
'/',
|
||||
['Styles','Format','Font','FontSize'],
|
||||
['TextColor','BGColor'],
|
||||
@@ -334,20 +375,38 @@ CKEDITOR.config.toolbar_Full =
|
||||
];
|
||||
|
||||
/**
|
||||
* The toolbox (alias toolbar) definition. It is a toolbar name or an array of toolbars (strips),
|
||||
* each one being also an array, containing a list of UI items.
|
||||
* @type Array or String
|
||||
* The toolbox (alias toolbar) definition. It is a toolbar name or an array of
|
||||
* toolbars (strips), each one being also an array, containing a list of UI items.
|
||||
* @type Array|String
|
||||
* @default 'Full'
|
||||
* @example
|
||||
* // Defines a toolbar with only one strip containing the "Source" button, a
|
||||
* // separator and the "Bold" and "Italic" buttons.
|
||||
* <b>CKEDITOR.config.toolbar =
|
||||
* config.toolbar =
|
||||
* [
|
||||
* [ 'Source', '-', 'Bold', 'Italic' ]
|
||||
* ]</b>;
|
||||
* ];
|
||||
* @example
|
||||
* // Load toolbar_Name where Name = Basic.
|
||||
* <b>CKEDITOR.config.toolbar = 'Basic';
|
||||
* config.toolbar = 'Basic';
|
||||
*/
|
||||
CKEDITOR.config.toolbar = 'Full';
|
||||
|
||||
/**
|
||||
* Whether the toolbar can be collapsed by the user. If disabled, the collapser
|
||||
* button will not be displayed.
|
||||
* @type Boolean
|
||||
* @default true
|
||||
* @example
|
||||
* config.toolbarCanCollapse = false;
|
||||
*/
|
||||
CKEDITOR.config.toolbarCanCollapse = true;
|
||||
|
||||
/**
|
||||
* Whether the toolbar must start expanded when the editor is loaded.
|
||||
* @type Boolean
|
||||
* @default true
|
||||
* @example
|
||||
* config.toolbarStartupExpanded = false;
|
||||
*/
|
||||
CKEDITOR.config.toolbarStartupExpanded = true;
|
||||
|
||||
@@ -13,7 +13,7 @@ CKEDITOR.dialog.add( 'uicolor', function( editor )
|
||||
{
|
||||
// Convert HEX representation to RGB, stripping # char.
|
||||
if ( /^#/.test( color ) )
|
||||
color = YAHOO.util.Color.hex2rgb( color.substr( 1 ) );
|
||||
color = window.YAHOO.util.Color.hex2rgb( color.substr( 1 ) );
|
||||
picker.setValue( color, true );
|
||||
// Refresh picker UI.
|
||||
picker.refresh( 'cke_uicolor_picker' );
|
||||
@@ -41,7 +41,7 @@ CKEDITOR.dialog.add( 'uicolor', function( editor )
|
||||
);
|
||||
|
||||
// Create new color picker widget.
|
||||
picker = new YAHOO.widget.ColorPicker( "cke_uicolor_picker",
|
||||
picker = new window.YAHOO.widget.ColorPicker( "cke_uicolor_picker",
|
||||
{
|
||||
showhsvcontrols : true,
|
||||
showhexcontrols : true,
|
||||
@@ -81,6 +81,10 @@ CKEDITOR.dialog.add( 'uicolor', function( editor )
|
||||
{
|
||||
dialog = this;
|
||||
this.setupContent();
|
||||
|
||||
// #3808
|
||||
if ( CKEDITOR.env.ie7Compat )
|
||||
dialog.parts.contents.setStyle( 'overflow', 'hidden' );
|
||||
},
|
||||
contents : [
|
||||
{
|
||||
|
||||
@@ -69,30 +69,28 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
undoManager.save();
|
||||
});
|
||||
|
||||
// Registering keydown on every document recreation.(#3844)
|
||||
editor.on( 'contentDom', function()
|
||||
{
|
||||
editor.document.on( 'keydown', function( event )
|
||||
{
|
||||
// Do not capture CTRL hotkeys.
|
||||
if ( !event.data.$.ctrlKey && !event.data.$.metaKey )
|
||||
undoManager.type( event );
|
||||
});
|
||||
});
|
||||
|
||||
// Always save an undo snapshot - the previous mode might have
|
||||
// changed editor contents.
|
||||
editor.on( 'beforeModeUnload', function()
|
||||
{
|
||||
editor.mode == 'wysiwyg' && undoManager.save( true );
|
||||
});
|
||||
|
||||
// Make the undo manager available only in wysiwyg mode.
|
||||
editor.on( 'mode', function()
|
||||
{
|
||||
if ( editor.mode == 'wysiwyg' )
|
||||
{
|
||||
if ( !undoManager.enabled )
|
||||
{
|
||||
undoManager.enabled = true;
|
||||
|
||||
editor.document.on( 'keydown', function( event )
|
||||
{
|
||||
// Do not capture CTRL hotkeys.
|
||||
if ( !event.data.$.ctrlKey && !event.data.$.metaKey )
|
||||
undoManager.type( event );
|
||||
});
|
||||
|
||||
// Always save an undo snapshot - the previous mode might have changed
|
||||
// editor contents.
|
||||
undoManager.save( true );
|
||||
}
|
||||
}
|
||||
else
|
||||
undoManager.enabled = false;
|
||||
|
||||
undoManager.enabled = editor.mode == 'wysiwyg';
|
||||
undoManager.onChange();
|
||||
});
|
||||
|
||||
@@ -481,4 +479,12 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* The number of undo steps to be saved. The higher this setting value the more
|
||||
* memory is used for it.
|
||||
* @type Number
|
||||
* @default 20
|
||||
* @example
|
||||
* config.undoStackSize = 50;
|
||||
*/
|
||||
CKEDITOR.config.undoStackSize = 20;
|
||||
|
||||
@@ -22,21 +22,22 @@ function doLoadScript( url )
|
||||
return true ;
|
||||
}
|
||||
|
||||
var opener;
|
||||
function tryLoad()
|
||||
{
|
||||
var opener = window.parent;
|
||||
opener = window.parent;
|
||||
|
||||
// get access to global parameters
|
||||
var oParams = window.opener.oldFramesetPageParams ;
|
||||
// get access to global parameters
|
||||
var oParams = window.opener.oldFramesetPageParams;
|
||||
|
||||
// make frameset rows string prepare
|
||||
var sFramesetRows = ( parseInt( oParams.firstframeh, 10 ) || '30') + ",*," + ( parseInt( oParams.thirdframeh, 10 ) || '150' ) + ',0' ;
|
||||
document.getElementById( 'itFrameset' ).rows = sFramesetRows ;
|
||||
// make frameset rows string prepare
|
||||
var sFramesetRows = ( parseInt( oParams.firstframeh, 10 ) || '30') + ",*," + ( parseInt( oParams.thirdframeh, 10 ) || '150' ) + ',0' ;
|
||||
document.getElementById( 'itFrameset' ).rows = sFramesetRows ;
|
||||
|
||||
// dynamic including init frames and crossdomain transport code
|
||||
// from config sproxy_js_frameset url
|
||||
var addScriptUrl = oParams.sproxy_js_frameset ;
|
||||
doLoadScript( addScriptUrl ) ;
|
||||
// dynamic including init frames and crossdomain transport code
|
||||
// from config sproxy_js_frameset url
|
||||
var addScriptUrl = oParams.sproxy_js_frameset ;
|
||||
doLoadScript( addScriptUrl ) ;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -55,7 +55,7 @@ CKEDITOR.dialog.add( 'checkspell', function( editor )
|
||||
initAndSpell( dialog );
|
||||
}
|
||||
else if ( i++ == 180 ) // Timeout: 180 * 250ms = 45s.
|
||||
_cancelOnError( errorMsg );
|
||||
window._cancelOnError( errorMsg );
|
||||
};
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ CKEDITOR.dialog.add( 'checkspell', function( editor )
|
||||
|
||||
// global var is used in FCK specific core
|
||||
// change on equal var used in fckplugin.js
|
||||
gFCKPluginName = 'wsc';
|
||||
window.gFCKPluginName = 'wsc';
|
||||
|
||||
LangComparer.setDefaulLangCode( editor.config.defaultLanguage );
|
||||
|
||||
|
||||
@@ -166,8 +166,9 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
var children = fixedBlock.getChildren(),
|
||||
count = children.count(),
|
||||
firstChild,
|
||||
previousElement = fixedBlock.getPrevious( true ),
|
||||
nextElement = fixedBlock.getNext( true ),
|
||||
whitespaceGuard = CKEDITOR.dom.walker.whitespaces( true ),
|
||||
previousElement = fixedBlock.getPrevious( whitespaceGuard ),
|
||||
nextElement = fixedBlock.getNext( whitespaceGuard ),
|
||||
enterBlock;
|
||||
if ( previousElement && previousElement.getName
|
||||
&& !( previousElement.getName() in nonExitableElementNames ) )
|
||||
@@ -176,20 +177,21 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
&& !( nextElement.getName() in nonExitableElementNames ) )
|
||||
enterBlock = nextElement;
|
||||
|
||||
// Not all blocks are editable, e.g. <hr />, further checking it.(#3994)
|
||||
if( ( !count
|
||||
|| ( firstChild = children.getItem( 0 ) ) && firstChild.is && firstChild.is( 'br' ) )
|
||||
&& enterBlock )
|
||||
&& enterBlock
|
||||
&& range.moveToElementEditStart( enterBlock ) )
|
||||
{
|
||||
fixedBlock.remove();
|
||||
range.moveToElementEditStart( enterBlock );
|
||||
range.select();
|
||||
}
|
||||
}
|
||||
|
||||
// Inserting the padding-br before body if it's preceded by an
|
||||
// unexitable block.
|
||||
var lastNode = body.getLast( true );
|
||||
if ( lastNode.getName && ( lastNode.getName() in nonExitableElementNames ) )
|
||||
var lastNode = body.getLast( CKEDITOR.dom.walker.whitespaces( true ) );
|
||||
if ( lastNode && lastNode.getName && ( lastNode.getName() in nonExitableElementNames ) )
|
||||
{
|
||||
var paddingBlock = editor.document.createElement(
|
||||
( CKEDITOR.env.ie && enterMode != CKEDITOR.ENTER_BR ) ?
|
||||
@@ -210,9 +212,11 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
editor.on( 'editingBlockReady', function()
|
||||
{
|
||||
var mainElement,
|
||||
fieldset,
|
||||
iframe,
|
||||
isLoadingData,
|
||||
isPendingFocus,
|
||||
frameLoaded,
|
||||
fireMode;
|
||||
|
||||
// Support for custom document.domain in IE.
|
||||
@@ -223,40 +227,50 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
if ( iframe )
|
||||
iframe.remove();
|
||||
if ( fieldset )
|
||||
fieldset.remove();
|
||||
|
||||
iframe = new CKEDITOR.dom.element( 'iframe' )
|
||||
.setAttributes({
|
||||
frameBorder : 0,
|
||||
tabIndex : -1,
|
||||
allowTransparency : true })
|
||||
.setStyles({
|
||||
width : '100%',
|
||||
height : '100%' });
|
||||
frameLoaded = 0;
|
||||
// The document domain must be set within the src
|
||||
// attribute;
|
||||
// Defer the script execution until iframe
|
||||
// has been added to main window, this is needed for some
|
||||
// browsers which will begin to load the frame content
|
||||
// prior to it's presentation in DOM.(#3894)
|
||||
var src = 'void( '
|
||||
+ ( CKEDITOR.env.gecko ? 'setTimeout' : '' ) + '( function(){' +
|
||||
'document.open();' +
|
||||
( CKEDITOR.env.ie && isCustomDomain ? 'document.domain="' + document.domain + '";' : '' ) +
|
||||
'document.write( window.parent[ "_cke_htmlToLoad_' + editor.name + '" ] );' +
|
||||
'document.close();' +
|
||||
'window.parent[ "_cke_htmlToLoad_' + editor.name + '" ] = null;' +
|
||||
'}'
|
||||
+ ( CKEDITOR.env.gecko ? ', 0 )' : ')()' )
|
||||
+ ' )';
|
||||
|
||||
if ( CKEDITOR.env.ie )
|
||||
{
|
||||
if ( isCustomDomain )
|
||||
{
|
||||
// The document domain must be set within the src
|
||||
// attribute.
|
||||
iframe.setAttribute( 'src',
|
||||
'javascript:void( (function(){' +
|
||||
'document.open();' +
|
||||
'document.domain="' + document.domain + '";' +
|
||||
'document.write( window.parent._cke_htmlToLoad_' + editor.name + ' );' +
|
||||
'document.close();' +
|
||||
'window.parent._cke_htmlToLoad_' + editor.name + ' = null;' +
|
||||
'})() )' );
|
||||
}
|
||||
else
|
||||
// To avoid HTTPS warnings.
|
||||
iframe.setAttribute( 'src', 'javascript:void(0)' );
|
||||
}
|
||||
// Loading via src attribute does not work in Opera.
|
||||
if ( CKEDITOR.env.opera )
|
||||
src = 'void(0);';
|
||||
|
||||
iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' +
|
||||
' style="width:100%;height:100%"' +
|
||||
' frameBorder="0"' +
|
||||
' tabIndex="-1"' +
|
||||
' allowTransparency="true"' +
|
||||
' src="javascript:' + encodeURIComponent( src ) + '"' +
|
||||
'></iframe>' );
|
||||
|
||||
var accTitle = editor.lang.editorTitle.replace( '%1', editor.name );
|
||||
|
||||
if ( CKEDITOR.env.gecko )
|
||||
{
|
||||
// Double checking the iframe will be loaded properly(#4058).
|
||||
iframe.on( 'load', function( ev )
|
||||
{
|
||||
ev.removeListener();
|
||||
contentDomReady( iframe.$.contentWindow );
|
||||
} );
|
||||
|
||||
// Accessibility attributes for Firefox.
|
||||
mainElement.setAttributes(
|
||||
{
|
||||
@@ -277,11 +291,13 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
else if ( CKEDITOR.env.ie )
|
||||
{
|
||||
// Accessibility label for IE.
|
||||
var fieldset = CKEDITOR.dom.element.createFromHtml(
|
||||
fieldset = CKEDITOR.dom.element.createFromHtml(
|
||||
'<fieldset style="height:100%' +
|
||||
( CKEDITOR.env.quirks ? ';position:relative' : '' ) +
|
||||
( CKEDITOR.env.ie && CKEDITOR.env.quirks ? ';position:relative' : '' ) +
|
||||
'">' +
|
||||
'<legend style="position:absolute;left:-10000px">' +
|
||||
'<legend style="display:block;width:0;height:0;overflow:hidden;' +
|
||||
( CKEDITOR.env.ie && CKEDITOR.env.quirks ? 'position:absolute' : '' ) +
|
||||
'">' +
|
||||
CKEDITOR.tools.htmlEncode( accTitle ) +
|
||||
'</legend>' +
|
||||
'</fieldset>'
|
||||
@@ -300,10 +316,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
'<script id="cke_actscrpt" type="text/javascript">' +
|
||||
'window.onload = function()' +
|
||||
'{' +
|
||||
// Remove this script from the DOM.
|
||||
'var s = document.getElementById( "cke_actscrpt" );' +
|
||||
's.parentNode.removeChild( s );' +
|
||||
|
||||
// Call the temporary function for the editing
|
||||
// boostrap.
|
||||
'window.parent.CKEDITOR._["contentDomReady' + editor.name + '"]( window );' +
|
||||
@@ -313,11 +325,20 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
// Editing area bootstrap code.
|
||||
var contentDomReady = function( domWindow )
|
||||
{
|
||||
delete CKEDITOR._[ 'contentDomReady' + editor.name ];
|
||||
if ( frameLoaded )
|
||||
return;
|
||||
|
||||
frameLoaded = 1;
|
||||
|
||||
var domDocument = domWindow.document,
|
||||
body = domDocument.body;
|
||||
|
||||
// Remove this script from the DOM.
|
||||
var script = domDocument.getElementById( "cke_actscrpt" );
|
||||
script.parentNode.removeChild( script );
|
||||
|
||||
delete CKEDITOR._[ 'contentDomReady' + editor.name ];
|
||||
|
||||
body.spellcheck = !editor.config.disableNativeSpellChecker;
|
||||
|
||||
if ( CKEDITOR.env.ie )
|
||||
@@ -342,6 +363,26 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
domWindow = editor.window = new CKEDITOR.dom.window( domWindow );
|
||||
domDocument = editor.document = new CKEDITOR.dom.document( domDocument );
|
||||
|
||||
// Gecko need a key event to 'wake up' the editing
|
||||
// ability when document is empty.(#3864)
|
||||
var firstNode = domDocument.getBody().getFirst();
|
||||
if ( CKEDITOR.env.gecko
|
||||
&& firstNode && firstNode.is
|
||||
&& firstNode.is( 'br' ) && firstNode.hasAttribute( '_moz_editor_bogus_node' ) )
|
||||
{
|
||||
var keyEventSimulate = domDocument.$.createEvent( "KeyEvents" );
|
||||
keyEventSimulate.initKeyEvent( 'keypress', true, true, domWindow.$, false,
|
||||
false, false, false, 0, 32 );
|
||||
domDocument.$.dispatchEvent( keyEventSimulate );
|
||||
var bogusText = domDocument.getBody().getFirst() ;
|
||||
// Compensate the line maintaining <br> if enterMode is not block.
|
||||
if ( editor.config.enterMode == CKEDITOR.ENTER_BR )
|
||||
domDocument.createElement( 'br', { attributes: { '_moz_dirty' : "" } } )
|
||||
.replace( bogusText );
|
||||
else
|
||||
bogusText.remove();
|
||||
}
|
||||
|
||||
// Gecko/Webkit need some help when selecting control type elements. (#3448)
|
||||
if ( !( CKEDITOR.env.ie || CKEDITOR.env.opera) )
|
||||
{
|
||||
@@ -441,14 +482,9 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
{
|
||||
mainElement = holderElement;
|
||||
|
||||
if ( CKEDITOR.env.ie && ( CKEDITOR.env.quirks || CKEDITOR.env.version < 8 ) )
|
||||
if ( CKEDITOR.env.ie && CKEDITOR.env.quirks )
|
||||
holderElement.setStyle( 'position', 'relative' );
|
||||
|
||||
// Create the iframe at load for all browsers
|
||||
// except FF and IE with custom domain.
|
||||
if ( !isCustomDomain || !CKEDITOR.env.gecko )
|
||||
createIFrame();
|
||||
|
||||
// The editor data "may be dirty" after this
|
||||
// point.
|
||||
editor.mayBeDirty = true;
|
||||
@@ -486,26 +522,12 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
'</html>' +
|
||||
activationScript;
|
||||
|
||||
// For custom domain in IE, set the global variable
|
||||
// that will temporarily hold the editor data. This
|
||||
// reference will be used in the ifram src.
|
||||
if ( isCustomDomain )
|
||||
window[ '_cke_htmlToLoad_' + editor.name ] = data;
|
||||
|
||||
window[ '_cke_htmlToLoad_' + editor.name ] = data;
|
||||
CKEDITOR._[ 'contentDomReady' + editor.name ] = contentDomReady;
|
||||
createIFrame();
|
||||
|
||||
// We need to recreate the iframe in FF for every
|
||||
// data load, otherwise the following spellcheck
|
||||
// and execCommand features will be active only for
|
||||
// the first time.
|
||||
// The same is valid for IE with custom domain,
|
||||
// because the iframe src must be reset every time.
|
||||
if ( isCustomDomain || CKEDITOR.env.gecko )
|
||||
createIFrame();
|
||||
|
||||
// For custom domain in IE, the data loading is
|
||||
// done through the src attribute of the iframe.
|
||||
if ( !isCustomDomain )
|
||||
// Opera must use the old method for loading contents.
|
||||
if ( CKEDITOR.env.opera )
|
||||
{
|
||||
var doc = iframe.$.contentWindow.document;
|
||||
doc.open();
|
||||
@@ -568,7 +590,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
|
||||
/**
|
||||
* Disables the ability of resize objects (image and tables) in the editing
|
||||
* area
|
||||
* area.
|
||||
* @type Boolean
|
||||
* @default false
|
||||
* @example
|
||||
@@ -602,11 +624,13 @@ CKEDITOR.config.disableNativeTableHandles = true;
|
||||
* config.disableNativeSpellChecker = false;
|
||||
*/
|
||||
CKEDITOR.config.disableNativeSpellChecker = true;
|
||||
|
||||
/**
|
||||
* The editor will post an empty value ("") if you have just an empty paragraph on it, like this:
|
||||
* Whether the editor must output an empty value ("") if it's contents is made
|
||||
* by an empty paragraph only.
|
||||
* @type Boolean
|
||||
* @default true
|
||||
* @example
|
||||
* <p></p>
|
||||
* <p><br /></p>
|
||||
* <p><b></b></p>
|
||||
* config.ignoreEmptyParagraph = false;
|
||||
*/
|
||||
CKEDITOR.config.ignoreEmptyParagraph = true;
|
||||
|
||||
Reference in New Issue
Block a user