summaryrefslogtreecommitdiff
path: root/_source/core/dom
diff options
context:
space:
mode:
Diffstat (limited to '_source/core/dom')
-rw-r--r--_source/core/dom/comment.js32
-rw-r--r--_source/core/dom/document.js17
-rw-r--r--_source/core/dom/documentfragment.js2
-rw-r--r--_source/core/dom/domobject.js2
-rw-r--r--_source/core/dom/element.js89
-rw-r--r--_source/core/dom/elementpath.js2
-rw-r--r--_source/core/dom/event.js2
-rw-r--r--_source/core/dom/node.js2
-rw-r--r--_source/core/dom/nodelist.js2
-rw-r--r--_source/core/dom/range.js131
-rw-r--r--_source/core/dom/text.js2
-rw-r--r--_source/core/dom/walker.js50
-rw-r--r--_source/core/dom/window.js2
13 files changed, 260 insertions, 75 deletions
diff --git a/_source/core/dom/comment.js b/_source/core/dom/comment.js
new file mode 100644
index 0000000..9e9c9b7
--- /dev/null
+++ b/_source/core/dom/comment.js
@@ -0,0 +1,32 @@
+/*
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.dom.comment} class, which represents
+ * a DOM comment node.
+ */
+
+CKEDITOR.dom.comment = CKEDITOR.tools.createClass(
+{
+ base : CKEDITOR.dom.node,
+
+ $ : function( text, ownerDocument )
+ {
+ if ( typeof text == 'string' )
+ text = ( ownerDocument ? ownerDocument.$ : document ).createComment( text );
+
+ this.base( text );
+ },
+
+ proto :
+ {
+ type : CKEDITOR.NODE_COMMENT,
+
+ getOuterHtml : function()
+ {
+ return '<!--' + this.$.nodeValue + '-->';
+ }
+ }
+});
diff --git a/_source/core/dom/document.js b/_source/core/dom/document.js
index dfe9a3c..0575338 100644
--- a/_source/core/dom/document.js
+++ b/_source/core/dom/document.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
@@ -52,6 +52,21 @@ CKEDITOR.tools.extend( CKEDITOR.dom.document.prototype,
}
},
+ appendStyleText : function( cssStyleText )
+ {
+ if ( this.$.createStyleSheet )
+ {
+ var styleSheet = this.$.createStyleSheet( "" );
+ styleSheet.cssText = cssStyleText ;
+ }
+ else
+ {
+ var style = new CKEDITOR.dom.element( 'style', this );
+ style.append( new CKEDITOR.dom.text( cssStyleText, this ) );
+ this.getHead().append( style );
+ }
+ },
+
createElement : function( name, attribsAndStyles )
{
var element = new CKEDITOR.dom.element( name, this );
diff --git a/_source/core/dom/documentfragment.js b/_source/core/dom/documentfragment.js
index ed04202..69bc70e 100644
--- a/_source/core/dom/documentfragment.js
+++ b/_source/core/dom/documentfragment.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
/**
diff --git a/_source/core/dom/domobject.js b/_source/core/dom/domobject.js
index 983f523..a2964b8 100644
--- a/_source/core/dom/domobject.js
+++ b/_source/core/dom/domobject.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
diff --git a/_source/core/dom/element.js b/_source/core/dom/element.js
index 5a96a0f..2f58326 100644
--- a/_source/core/dom/element.js
+++ b/_source/core/dom/element.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
@@ -256,15 +256,15 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype,
* @param {CKEDITOR.dom.element} parent The anscestor element to get broken.
* @example
* // Before breaking:
- * // <b>This <i>is some<span /> sample</i> test text</b>
- * // If "element" is <span /> and "parent" is <i>:
- * // <b>This <i>is some</i><span /><i> sample</i> test text</b>
+ * // &lt;b&gt;This &lt;i&gt;is some&lt;span /&gt; sample&lt;/i&gt; test text&lt;/b&gt;
+ * // If "element" is &lt;span /&gt; and "parent" is &lt;i&gt;:
+ * // &lt;b&gt;This &lt;i&gt;is some&lt;/i&gt;&lt;span /&gt;&lt;i&gt; sample&lt;/i&gt; test text&lt;/b&gt;
* element.breakParent( parent );
* @example
* // Before breaking:
- * // <b>This <i>is some<span /> sample</i> test text</b>
- * // If "element" is <span /> and "parent" is <b>:
- * // <b>This <i>is some</i></b><span /><b><i> sample</i> test text</b>
+ * // &lt;b&gt;This &lt;i&gt;is some&lt;span /&gt; sample&lt;/i&gt; test text&lt;/b&gt;
+ * // If "element" is &lt;span /&gt; and "parent" is &lt;b&gt;:
+ * // &lt;b&gt;This &lt;i&gt;is some&lt;/i&gt;&lt;/b&gt;&lt;span /&gt;&lt;b&gt;&lt;i&gt; sample&lt;/i&gt; test text&lt;/b&gt;
* element.breakParent( parent );
*/
breakParent : function( parent )
@@ -328,7 +328,9 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype,
*/
getHtml : function()
{
- return this.$.innerHTML;
+ var retval = this.$.innerHTML;
+ // Strip <?xml:namespace> tags in IE. (#3341).
+ return CKEDITOR.env.ie ? retval.replace( /<\?[^>]*>/g, '' ) : retval;
},
getOuterHtml : function()
@@ -425,8 +427,16 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype,
break;
case 'checked':
- return this.$.checked;
- break;
+ {
+ var attr = this.$.attributes.getNamedItem( name ),
+ attrValue = attr.specified ? attr.nodeValue // For value given by parser.
+ : this.$.checked; // For value created via DOM interface.
+
+ return attrValue ? 'checked' : null;
+ }
+
+ case 'hspace':
+ return this.$.hspace;
case 'style':
// IE does not return inline styles via getAttribute(). See #2947.
@@ -627,6 +637,7 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype,
/**
* Gets the first child node of this element.
+ * @param {Function} evaluator Filtering the result node.
* @returns {CKEDITOR.dom.node} The first child node or null if not
* available.
* @example
@@ -634,10 +645,14 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype,
* var first = <b>element.getFirst()</b>;
* alert( first.getName() ); // "b"
*/
- getFirst : function()
+ getFirst : function( evaluator )
{
- var $ = this.$.firstChild;
- return $ ? new CKEDITOR.dom.node( $ ) : null;
+ var first = this.$.firstChild,
+ retval = first && new CKEDITOR.dom.node( first );
+ if ( retval && evaluator && !evaluator( retval ) )
+ retval = retval.getNext( evaluator );
+
+ return retval;
},
/**
@@ -722,8 +737,8 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype,
for ( i = 0 ; i < otherLength ; i++ )
{
attribute = otherAttribs[ i ];
-
- if ( ( !CKEDITOR.env.ie || ( attribute.specified && attribute.nodeName != '_cke_expando' ) ) && attribute.nodeValue != thisAttribs.getAttribute( attribute.nodeName ) )
+ if ( attribute.specified && attribute.nodeName != '_cke_expando'
+ && attribute.nodeValue != this.getAttribute( attribute.nodeName ) )
return false;
}
}
@@ -739,7 +754,24 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype,
*/
isVisible : function()
{
- return this.$.offsetWidth && ( this.$.style.visibility != 'hidden' );
+ var isVisible = !!this.$.offsetHeight && this.getComputedStyle( 'visibility' ) != 'hidden',
+ elementWindow,
+ elementWindowFrame;
+
+ // Webkit and Opera report non-zero offsetHeight despite that
+ // element is inside an invisible iframe. (#4542)
+ if ( isVisible && ( CKEDITOR.env.webkit || CKEDITOR.env.opera ) )
+ {
+ elementWindow = this.getWindow();
+
+ if ( !elementWindow.equals( CKEDITOR.document.getWindow() )
+ && ( elementWindowFrame = elementWindow.$.frameElement ) )
+ {
+ isVisible = new CKEDITOR.dom.element( elementWindowFrame ).isVisible();
+ }
+ }
+
+ return isVisible;
},
/**
@@ -971,10 +1003,9 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype,
*/
removeStyle : function( name )
{
+ this.setStyle( name, '' );
if ( this.$.style.removeAttribute )
this.$.style.removeAttribute( CKEDITOR.tools.cssStyleToDomStyle( name ) );
- else
- this.setStyle( name, '' );
if ( !this.$.style.cssText )
this.removeAttribute( 'style' );
@@ -1306,16 +1337,22 @@ CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype,
{
var attribute = attributes[n];
+ // Lowercase attribute name hard rule is broken for
+ // some attribute on IE, e.g. CHECKED.
+ var attrName = attribute.nodeName.toLowerCase(),
+ attrValue;
+
+ // We can set the type only once, so do it with the proper value, not copying it.
+ if ( attrName in skipAttributes )
+ continue;
+
+ if( attrName == 'checked' && ( attrValue = this.getAttribute( attrName ) ) )
+ dest.setAttribute( attrName, attrValue );
// IE BUG: value attribute is never specified even if it exists.
- if ( attribute.specified ||
- ( CKEDITOR.env.ie && attribute.nodeValue && attribute.nodeName.toLowerCase() == 'value' ) )
+ else if ( attribute.specified ||
+ ( CKEDITOR.env.ie && attribute.nodeValue && attrName == 'value' ) )
{
- var attrName = attribute.nodeName;
- // We can set the type only once, so do it with the proper value, not copying it.
- if ( attrName in skipAttributes )
- continue;
-
- var attrValue = this.getAttribute( attrName );
+ attrValue = this.getAttribute( attrName );
if ( attrValue === null )
attrValue = attribute.nodeValue;
diff --git a/_source/core/dom/elementpath.js b/_source/core/dom/elementpath.js
index df75554..74641ae 100644
--- a/_source/core/dom/elementpath.js
+++ b/_source/core/dom/elementpath.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
diff --git a/_source/core/dom/event.js b/_source/core/dom/event.js
index 41cbd48..24b75d0 100644
--- a/_source/core/dom/event.js
+++ b/_source/core/dom/event.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
diff --git a/_source/core/dom/node.js b/_source/core/dom/node.js
index a32e45a..24e3894 100644
--- a/_source/core/dom/node.js
+++ b/_source/core/dom/node.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
diff --git a/_source/core/dom/nodelist.js b/_source/core/dom/nodelist.js
index c0f4087..155f0ad 100644
--- a/_source/core/dom/nodelist.js
+++ b/_source/core/dom/nodelist.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
diff --git a/_source/core/dom/range.js b/_source/core/dom/range.js
index cd7ba9d..d3ad684 100644
--- a/_source/core/dom/range.js
+++ b/_source/core/dom/range.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
@@ -278,7 +278,7 @@ CKEDITOR.dom.range = function( document )
if ( CKEDITOR.tools.trim( node.getText() ).length )
return false;
}
- else
+ else if( node.type == CKEDITOR.NODE_ELEMENT )
{
// If there are non-empty inline elements (e.g. <img />), then we're not
// at the start.
@@ -308,6 +308,15 @@ CKEDITOR.dom.range = function( document )
|| node.getParent().hasAttribute( '_fck_bookmark' );
}
+ var whitespaceEval = new CKEDITOR.dom.walker.whitespaces(),
+ bookmarkEval = new CKEDITOR.dom.walker.bookmark();
+
+ function nonWhitespaceOrBookmarkEval( node )
+ {
+ // Whitespaces and bookmark nodes are to be ignored.
+ return !whitespaceEval( node ) && !bookmarkEval( node );
+ }
+
CKEDITOR.dom.range.prototype =
{
clone : function()
@@ -1183,7 +1192,8 @@ CKEDITOR.dom.range = function( document )
this.setStartAt(
blockBoundary,
!blockBoundary.is( 'br' ) &&
- ( !enlargeable || blockBoundary.contains( enlargeable ) ) ?
+ ( !enlargeable && this.checkStartOfBlock()
+ || enlargeable && blockBoundary.contains( enlargeable ) ) ?
CKEDITOR.POSITION_AFTER_START :
CKEDITOR.POSITION_AFTER_END );
@@ -1208,8 +1218,8 @@ CKEDITOR.dom.range = function( document )
// the document position of it with 'enlargeable' node.
this.setEndAt(
blockBoundary,
- !blockBoundary.is( 'br' ) &&
- ( !enlargeable || blockBoundary.contains( enlargeable ) ) ?
+ ( !enlargeable && this.checkEndOfBlock()
+ || enlargeable && blockBoundary.contains( enlargeable ) ) ?
CKEDITOR.POSITION_BEFORE_END :
CKEDITOR.POSITION_BEFORE_START );
// We must include the <br> at the end of range if there's
@@ -1457,18 +1467,7 @@ CKEDITOR.dom.range = function( document )
}
else
{
- // Extract the contents of the block from the selection point to the end
- // of its contents.
- this.setEndAt( startBlock, CKEDITOR.POSITION_BEFORE_END );
- var documentFragment = this.extractContents();
-
- // Duplicate the block element after it.
- endBlock = startBlock.clone( false );
-
- // Place the extracted contents into the duplicated block.
- documentFragment.appendTo( endBlock );
- endBlock.insertAfter( startBlock );
- this.moveToPosition( startBlock, CKEDITOR.POSITION_AFTER_END );
+ endBlock = this.splitElement( startBlock );
// In Gecko, the last child node must be a bogus <br>.
// Note: bogus <br> added under <ul> or <ol> would cause
@@ -1488,6 +1487,33 @@ CKEDITOR.dom.range = function( document )
},
/**
+ * Branch the specified element from the collapsed range position and
+ * place the caret between the two result branches.
+ * Note: The range must be collapsed and been enclosed by this element.
+ * @param {CKEDITOR.dom.element} element
+ * @return {CKEDITOR.dom.element} Root element of the new branch after the split.
+ */
+ splitElement : function( toSplit )
+ {
+ if ( !this.collapsed )
+ return null;
+
+ // Extract the contents of the block from the selection point to the end
+ // of its contents.
+ this.setEndAt( toSplit, CKEDITOR.POSITION_BEFORE_END );
+ var documentFragment = this.extractContents();
+
+ // Duplicate the element after it.
+ var clone = toSplit.clone( false );
+
+ // Place the extracted contents into the duplicated element.
+ documentFragment.appendTo( clone );
+ clone.insertAfter( toSplit );
+ this.moveToPosition( toSplit, CKEDITOR.POSITION_AFTER_END );
+ return clone;
+ },
+
+ /**
* Check whether current range is on the inner edge of the specified element.
* @param {Number} checkType ( CKEDITOR.START | CKEDITOR.END ) The checking side.
* @param {CKEDITOR.dom.element} element The target element to check.
@@ -1579,34 +1605,69 @@ CKEDITOR.dom.range = function( document )
},
/**
- * Moves the range boundaries to the first editing point inside an
+ * Moves the range boundaries to the first/end editing point inside an
* element. For example, in an element tree like
* "&lt;p&gt;&lt;b&gt;&lt;i&gt;&lt;/i&gt;&lt;/b&gt; Text&lt;/p&gt;", the start editing point is
* "&lt;p&gt;&lt;b&gt;&lt;i&gt;^&lt;/i&gt;&lt;/b&gt; Text&lt;/p&gt;" (inside &lt;i&gt;).
- * @param {CKEDITOR.dom.element} targetElement The element into which
- * look for the editing spot.
+ * @param {CKEDITOR.dom.element} el The element into which look for the
+ * editing spot.
+ * @param {Boolean} isMoveToEnd Whether move to the end editable position.
*/
- moveToElementEditStart : function( targetElement )
+ moveToElementEditablePosition : function( el, isMoveToEnd )
{
- var editableElement;
+ var isEditable;
- while ( targetElement && targetElement.type == CKEDITOR.NODE_ELEMENT )
+ while ( el && el.type == CKEDITOR.NODE_ELEMENT )
{
- if ( targetElement.isEditable() )
- editableElement = targetElement;
- else if ( editableElement )
- break ; // If we already found an editable element, stop the loop.
+ isEditable = el.isEditable();
- targetElement = targetElement.getFirst();
- }
+ // If an editable element is found, move inside it.
+ if ( isEditable )
+ this.moveToPosition( el, isMoveToEnd ?
+ CKEDITOR.POSITION_BEFORE_END :
+ CKEDITOR.POSITION_AFTER_START );
+ // Stop immediately if we've found a non editable inline element (e.g <img>).
+ else if ( CKEDITOR.dtd.$inline[ el.getName() ] )
+ {
+ this.moveToPosition( el, isMoveToEnd ?
+ CKEDITOR.POSITION_AFTER_END :
+ CKEDITOR.POSITION_BEFORE_START );
+ return true;
+ }
- if ( editableElement )
- {
- this.moveToPosition(editableElement, CKEDITOR.POSITION_AFTER_START);
- return true;
+ // Non-editable non-inline elements are to be bypassed, getting the next one.
+ if ( CKEDITOR.dtd.$empty[ el.getName() ] )
+ el = el[ isMoveToEnd ? 'getPrevious' : 'getNext' ]( nonWhitespaceOrBookmarkEval );
+ else
+ el = el[ isMoveToEnd ? 'getLast' : 'getFirst' ]( nonWhitespaceOrBookmarkEval );
+
+ // Stop immediately if we've found a text node.
+ if ( el && el.type == CKEDITOR.NODE_TEXT )
+ {
+ this.moveToPosition( el, isMoveToEnd ?
+ CKEDITOR.POSITION_AFTER_END :
+ CKEDITOR.POSITION_BEFORE_START );
+ return true;
+ }
}
- else
- return false;
+
+ return isEditable;
+ },
+
+ /**
+ *@see {CKEDITOR.dom.range.moveToElementEditablePosition}
+ */
+ moveToElementEditStart : function( target )
+ {
+ return this.moveToElementEditablePosition( target );
+ },
+
+ /**
+ *@see {CKEDITOR.dom.range.moveToElementEditablePosition}
+ */
+ moveToElementEditEnd : function( target )
+ {
+ return this.moveToElementEditablePosition( target, true );
},
/**
diff --git a/_source/core/dom/text.js b/_source/core/dom/text.js
index 1f8b192..407c47f 100644
--- a/_source/core/dom/text.js
+++ b/_source/core/dom/text.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
diff --git a/_source/core/dom/walker.js b/_source/core/dom/walker.js
index 766eaa2..2010078 100644
--- a/_source/core/dom/walker.js
+++ b/_source/core/dom/walker.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
@@ -47,7 +47,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
{
return ( ( !movingOut || !limitLTR.equals( node ) )
&& ( !blockerLTR || !node.equals( blockerLTR ) )
- && ( node.type != CKEDITOR.NODE_ELEMENT || node.getName() != 'body' ) );
+ && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || node.getName() != 'body' ) );
};
}
@@ -62,7 +62,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
{
return ( ( !movingOut || !limitRTL.equals( node ) )
&& ( !blockerRTL || !node.equals( blockerRTL ) )
- && ( node.type != CKEDITOR.NODE_ELEMENT || node.getName() != 'body' ) );
+ && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || node.getName() != 'body' ) );
};
}
@@ -78,7 +78,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
if ( stopGuard( node, movingOut ) === false )
return false;
- return userGuard( node );
+ return userGuard( node, movingOut );
};
}
else
@@ -396,7 +396,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
};
/**
- * Whether the node contains only white-spaces characters.
+ * Whether the node is a text node containing only whitespaces characters.
* @param isReject
*/
CKEDITOR.dom.walker.whitespaces = function( isReject )
@@ -408,4 +408,44 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
return isReject ^ isWhitespace;
};
};
+
+ /**
+ * Whether the node is invisible in wysiwyg mode.
+ * @param isReject
+ */
+ CKEDITOR.dom.walker.invisible = function( isReject )
+ {
+ var whitespace = CKEDITOR.dom.walker.whitespaces();
+ return function( node )
+ {
+ // Nodes that take no spaces in wysiwyg:
+ // 1. White-spaces but not including NBSP;
+ // 2. Empty inline elements, e.g. <b></b> we're checking here
+ // 'offsetHeight' instead of 'offsetWidth' for properly excluding
+ // all sorts of empty paragraph, e.g. <br />.
+ var isInvisible = whitespace( node ) || node.is && !node.$.offsetHeight;
+ return isReject ^ isInvisible;
+ };
+ };
+
+ var tailNbspRegex = /^[\t\r\n ]*(?:&nbsp;|\xa0)$/,
+ isNotWhitespaces = CKEDITOR.dom.walker.whitespaces( true ),
+ isNotBookmark = CKEDITOR.dom.walker.bookmark( false, true ),
+ fillerEvaluator = function( element )
+ {
+ return isNotBookmark( element ) && isNotWhitespaces( element );
+ };
+
+ // Check if there's a filler node at the end of an element, and return it.
+ CKEDITOR.dom.element.prototype.getBogus = function ()
+ {
+ var tail = this.getLast( fillerEvaluator );
+ if ( tail && ( !CKEDITOR.env.ie ? tail.is && tail.is( 'br' )
+ : tail.getText && tailNbspRegex.test( tail.getText() ) ) )
+ {
+ return tail;
+ }
+ return false;
+ };
+
})();
diff --git a/_source/core/dom/window.js b/_source/core/dom/window.js
index 813a799..c9fb002 100644
--- a/_source/core/dom/window.js
+++ b/_source/core/dom/window.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/