X-Git-Url: https://scm.cri.ensmp.fr/git/ckeditor.git/blobdiff_plain/871bad8291b6dbc29d489d95d185458caab25158..14d450d78a2d67ec1decd64c928151851961dd36:/_source/core/dom/walker.js diff --git a/_source/core/dom/walker.js b/_source/core/dom/walker.js deleted file mode 100644 index 7f430b8..0000000 --- a/_source/core/dom/walker.js +++ /dev/null @@ -1,462 +0,0 @@ -/* -Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. -For licensing, see LICENSE.html or http://ckeditor.com/license -*/ - -(function() -{ - // This function is to be called under a "walker" instance scope. - function iterate( rtl, breakOnFalse ) - { - // Return null if we have reached the end. - if ( this._.end ) - return null; - - var node, - range = this.range, - guard, - userGuard = this.guard, - type = this.type, - getSourceNodeFn = ( rtl ? 'getPreviousSourceNode' : 'getNextSourceNode' ); - - // This is the first call. Initialize it. - if ( !this._.start ) - { - this._.start = 1; - - // Trim text nodes and optmize the range boundaries. DOM changes - // may happen at this point. - range.trim(); - - // A collapsed range must return null at first call. - if ( range.collapsed ) - { - this.end(); - return null; - } - } - - // Create the LTR guard function, if necessary. - if ( !rtl && !this._.guardLTR ) - { - // Gets the node that stops the walker when going LTR. - var limitLTR = range.endContainer, - blockerLTR = limitLTR.getChild( range.endOffset ); - - this._.guardLTR = function( node, movingOut ) - { - return ( ( !movingOut || !limitLTR.equals( node ) ) - && ( !blockerLTR || !node.equals( blockerLTR ) ) - && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || node.getName() != 'body' ) ); - }; - } - - // Create the RTL guard function, if necessary. - if ( rtl && !this._.guardRTL ) - { - // Gets the node that stops the walker when going LTR. - var limitRTL = range.startContainer, - blockerRTL = ( range.startOffset > 0 ) && limitRTL.getChild( range.startOffset - 1 ); - - this._.guardRTL = function( node, movingOut ) - { - return ( ( !movingOut || !limitRTL.equals( node ) ) - && ( !blockerRTL || !node.equals( blockerRTL ) ) - && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || node.getName() != 'body' ) ); - }; - } - - // Define which guard function to use. - var stopGuard = rtl ? this._.guardRTL : this._.guardLTR; - - // Make the user defined guard function participate in the process, - // otherwise simply use the boundary guard. - if ( userGuard ) - { - guard = function( node, movingOut ) - { - if ( stopGuard( node, movingOut ) === false ) - return false; - - return userGuard( node, movingOut ); - }; - } - else - guard = stopGuard; - - if ( this.current ) - node = this.current[ getSourceNodeFn ]( false, type, guard ); - else - { - // Get the first node to be returned. - - if ( rtl ) - { - node = range.endContainer; - - if ( range.endOffset > 0 ) - { - node = node.getChild( range.endOffset - 1 ); - if ( guard( node ) === false ) - node = null; - } - else - node = ( guard ( node, true ) === false ) ? - null : node.getPreviousSourceNode( true, type, guard ); - } - else - { - node = range.startContainer; - node = node.getChild( range.startOffset ); - - if ( node ) - { - if ( guard( node ) === false ) - node = null; - } - else - node = ( guard ( range.startContainer, true ) === false ) ? - null : range.startContainer.getNextSourceNode( true, type, guard ) ; - } - } - - while ( node && !this._.end ) - { - this.current = node; - - if ( !this.evaluator || this.evaluator( node ) !== false ) - { - if ( !breakOnFalse ) - return node; - } - else if ( breakOnFalse && this.evaluator ) - return false; - - node = node[ getSourceNodeFn ]( false, type, guard ); - } - - this.end(); - return this.current = null; - } - - function iterateToLast( rtl ) - { - var node, last = null; - - while ( ( node = iterate.call( this, rtl ) ) ) - last = node; - - return last; - } - - CKEDITOR.dom.walker = CKEDITOR.tools.createClass( - { - /** - * Utility class to "walk" the DOM inside a range boundaries. If - * necessary, partially included nodes (text nodes) are broken to - * reflect the boundaries limits, so DOM and range changes may happen. - * Outside changes to the range may break the walker. - * - * The walker may return nodes that are not totaly included into the - * range boundaires. Let's take the following range representation, - * where the square brackets indicate the boundaries: - * - * [<p>Some <b>sample] text</b> - * - * While walking forward into the above range, the following nodes are - * returned: <p>, "Some ", <b> and "sample". Going - * backwards instead we have: "sample" and "Some ". So note that the - * walker always returns nodes when "entering" them, but not when - * "leaving" them. The guard function is instead called both when - * entering and leaving nodes. - * - * @constructor - * @param {CKEDITOR.dom.range} range The range within which walk. - */ - $ : function( range ) - { - this.range = range; - - /** - * A function executed for every matched node, to check whether - * it's to be considered into the walk or not. If not provided, all - * matched nodes are considered good. - * If the function returns "false" the node is ignored. - * @name CKEDITOR.dom.walker.prototype.evaluator - * @property - * @type Function - */ - // this.evaluator = null; - - /** - * A function executed for every node the walk pass by to check - * whether the walk is to be finished. It's called when both - * entering and exiting nodes, as well as for the matched nodes. - * If this function returns "false", the walking ends and no more - * nodes are evaluated. - * @name CKEDITOR.dom.walker.prototype.guard - * @property - * @type Function - */ - // this.guard = null; - - /** @private */ - this._ = {}; - }, - -// statics : -// { -// /* Creates a CKEDITOR.dom.walker instance to walk inside DOM boundaries set by nodes. -// * @param {CKEDITOR.dom.node} startNode The node from wich the walk -// * will start. -// * @param {CKEDITOR.dom.node} [endNode] The last node to be considered -// * in the walk. No more nodes are retrieved after touching or -// * passing it. If not provided, the walker stops at the -// * <body> closing boundary. -// * @returns {CKEDITOR.dom.walker} A DOM walker for the nodes between the -// * provided nodes. -// */ -// createOnNodes : function( startNode, endNode, startInclusive, endInclusive ) -// { -// var range = new CKEDITOR.dom.range(); -// if ( startNode ) -// range.setStartAt( startNode, startInclusive ? CKEDITOR.POSITION_BEFORE_START : CKEDITOR.POSITION_AFTER_END ) ; -// else -// range.setStartAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_AFTER_START ) ; -// -// if ( endNode ) -// range.setEndAt( endNode, endInclusive ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START ) ; -// else -// range.setEndAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_BEFORE_END ) ; -// -// return new CKEDITOR.dom.walker( range ); -// } -// }, -// - proto : - { - /** - * Stop walking. No more nodes are retrieved if this function gets - * called. - */ - end : function() - { - this._.end = 1; - }, - - /** - * Retrieves the next node (at right). - * @returns {CKEDITOR.dom.node} The next node or null if no more - * nodes are available. - */ - next : function() - { - return iterate.call( this ); - }, - - /** - * Retrieves the previous node (at left). - * @returns {CKEDITOR.dom.node} The previous node or null if no more - * nodes are available. - */ - previous : function() - { - return iterate.call( this, 1 ); - }, - - /** - * Check all nodes at right, executing the evaluation fuction. - * @returns {Boolean} "false" if the evaluator function returned - * "false" for any of the matched nodes. Otherwise "true". - */ - checkForward : function() - { - return iterate.call( this, 0, 1 ) !== false; - }, - - /** - * Check all nodes at left, executing the evaluation fuction. - * @returns {Boolean} "false" if the evaluator function returned - * "false" for any of the matched nodes. Otherwise "true". - */ - checkBackward : function() - { - return iterate.call( this, 1, 1 ) !== false; - }, - - /** - * Executes a full walk forward (to the right), until no more nodes - * are available, returning the last valid node. - * @returns {CKEDITOR.dom.node} The last node at the right or null - * if no valid nodes are available. - */ - lastForward : function() - { - return iterateToLast.call( this ); - }, - - /** - * Executes a full walk backwards (to the left), until no more nodes - * are available, returning the last valid node. - * @returns {CKEDITOR.dom.node} The last node at the left or null - * if no valid nodes are available. - */ - lastBackward : function() - { - return iterateToLast.call( this, 1 ); - }, - - reset : function() - { - delete this.current; - this._ = {}; - } - - } - }); - - /* - * Anything whose display computed style is block, list-item, table, - * table-row-group, table-header-group, table-footer-group, table-row, - * table-column-group, table-column, table-cell, table-caption, or whose node - * name is hr, br (when enterMode is br only) is a block boundary. - */ - var blockBoundaryDisplayMatch = - { - block : 1, - 'list-item' : 1, - table : 1, - 'table-row-group' : 1, - 'table-header-group' : 1, - 'table-footer-group' : 1, - 'table-row' : 1, - 'table-column-group' : 1, - 'table-column' : 1, - 'table-cell' : 1, - 'table-caption' : 1 - }; - - CKEDITOR.dom.element.prototype.isBlockBoundary = function( customNodeNames ) - { - var nodeNameMatches = customNodeNames ? - CKEDITOR.tools.extend( {}, CKEDITOR.dtd.$block, customNodeNames || {} ) : - CKEDITOR.dtd.$block; - - // Don't consider floated formatting as block boundary, fall back to dtd check in that case. (#6297) - return this.getComputedStyle( 'float' ) == 'none' && blockBoundaryDisplayMatch[ this.getComputedStyle( 'display' ) ] - || nodeNameMatches[ this.getName() ]; - }; - - CKEDITOR.dom.walker.blockBoundary = function( customNodeNames ) - { - return function( node , type ) - { - return ! ( node.type == CKEDITOR.NODE_ELEMENT - && node.isBlockBoundary( customNodeNames ) ); - }; - }; - - CKEDITOR.dom.walker.listItemBoundary = function() - { - return this.blockBoundary( { br : 1 } ); - }; - - /** - * Whether the to-be-evaluated node is a bookmark node OR bookmark node - * inner contents. - * @param {Boolean} contentOnly Whether only test againt the text content of - * bookmark node instead of the element itself(default). - * @param {Boolean} isReject Whether should return 'false' for the bookmark - * node instead of 'true'(default). - */ - CKEDITOR.dom.walker.bookmark = function( contentOnly, isReject ) - { - function isBookmarkNode( node ) - { - return ( node && node.getName - && node.getName() == 'span' - && node.data( 'cke-bookmark' ) ); - } - - return function( node ) - { - var isBookmark, parent; - // Is bookmark inner text node? - isBookmark = ( node && !node.getName && ( parent = node.getParent() ) - && isBookmarkNode( parent ) ); - // Is bookmark node? - isBookmark = contentOnly ? isBookmark : isBookmark || isBookmarkNode( node ); - return !! ( isReject ^ isBookmark ); - }; - }; - - /** - * Whether the node is a text node containing only whitespaces characters. - * @param isReject - */ - CKEDITOR.dom.walker.whitespaces = function( isReject ) - { - return function( node ) - { - var isWhitespace = node && ( node.type == CKEDITOR.NODE_TEXT ) - && !CKEDITOR.tools.trim( node.getText() ); - 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. we're checking here - // 'offsetHeight' instead of 'offsetWidth' for properly excluding - // all sorts of empty paragraph, e.g.
. - var isInvisible = whitespace( node ) || node.is && !node.$.offsetHeight; - return !! ( isReject ^ isInvisible ); - }; - }; - - CKEDITOR.dom.walker.nodeType = function( type, isReject ) - { - return function( node ) - { - return !! ( isReject ^ ( node.type == type ) ); - }; - }; - - var tailNbspRegex = /^[\t\r\n ]*(?: |\xa0)$/, - isWhitespaces = CKEDITOR.dom.walker.whitespaces(), - isBookmark = CKEDITOR.dom.walker.bookmark(), - toSkip = function( node ) - { - return isBookmark( node ) - || isWhitespaces( node ) - || node.type == CKEDITOR.NODE_ELEMENT - && node.getName() in CKEDITOR.dtd.$inline - && !( node.getName() in CKEDITOR.dtd.$empty ); - }; - - // Check if there's a filler node at the end of an element, and return it. - CKEDITOR.dom.element.prototype.getBogus = function() - { - // Bogus are not always at the end, e.g.

text

(#7070). - var tail = this; - do { tail = tail.getPreviousSourceNode(); } - while ( toSkip( tail ) ) - - if ( tail && ( !CKEDITOR.env.ie ? tail.is && tail.is( 'br' ) - : tail.getText && tailNbspRegex.test( tail.getText() ) ) ) - { - return tail; - } - return false; - }; - -})();