public/ckeditor/4.4dev/core/dom/range.js
function( mode, selectContents, shrinkOnBlockBoundary ) {
			// Unable to shrink a collapsed range.
			if ( !this.collapsed ) {
				mode = mode || CKEDITOR.SHRINK_TEXT;

				var walkerRange = this.clone();

				var startContainer = this.startContainer,
					endContainer = this.endContainer,
					startOffset = this.startOffset,
					endOffset = this.endOffset;

				// Whether the start/end boundary is moveable.
				var moveStart = 1,
					moveEnd = 1;

				if ( startContainer && startContainer.type == CKEDITOR.NODE_TEXT ) {
					if ( !startOffset )
						walkerRange.setStartBefore( startContainer );
					else if ( startOffset >= startContainer.getLength() )
						walkerRange.setStartAfter( startContainer );
					else {
						// Enlarge the range properly to avoid walker making
						// DOM changes caused by triming the text nodes later.
						walkerRange.setStartBefore( startContainer );
						moveStart = 0;
					}
				}

				if ( endContainer && endContainer.type == CKEDITOR.NODE_TEXT ) {
					if ( !endOffset )
						walkerRange.setEndBefore( endContainer );
					else if ( endOffset >= endContainer.getLength() )
						walkerRange.setEndAfter( endContainer );
					else {
						walkerRange.setEndAfter( endContainer );
						moveEnd = 0;
					}
				}

				var walker = new CKEDITOR.dom.walker( walkerRange ),
					isBookmark = CKEDITOR.dom.walker.bookmark();

				walker.evaluator = function( node ) {
					return node.type == ( mode == CKEDITOR.SHRINK_ELEMENT ? CKEDITOR.NODE_ELEMENT : CKEDITOR.NODE_TEXT );
				};

				var currentElement;
				walker.guard = function( node, movingOut ) {
					if ( isBookmark( node ) )
						return true;

					// Stop when we're shrink in element mode while encountering a text node.
					if ( mode == CKEDITOR.SHRINK_ELEMENT && node.type == CKEDITOR.NODE_TEXT )
						return false;

					// Stop when we've already walked "through" an element.
					if ( movingOut && node.equals( currentElement ) )
						return false;

					if ( shrinkOnBlockBoundary === false && node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary() )
						return false;

					// Stop shrinking when encountering an editable border.
					if ( node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'contenteditable' ) )
						return false;

					if ( !movingOut && node.type == CKEDITOR.NODE_ELEMENT )
						currentElement = node;

					return true;
				};

				if ( moveStart ) {
					var textStart = walker[ mode == CKEDITOR.SHRINK_ELEMENT ? 'lastForward' : 'next' ]();
					textStart && this.setStartAt( textStart, selectContents ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_BEFORE_START );
				}

				if ( moveEnd ) {
					walker.reset();
					var textEnd = walker[ mode == CKEDITOR.SHRINK_ELEMENT ? 'lastBackward' : 'previous' ]();
					textEnd && this.setEndAt( textEnd, selectContents ? CKEDITOR.POSITION_BEFORE_END : CKEDITOR.POSITION_AFTER_END );
				}

				return !!( moveStart || moveEnd );
			}
		}
function( mode, selectContents, shrinkOnBlockBoundary ) {
			// Unable to shrink a collapsed range.
			if ( !this.collapsed ) {
				mode = mode || CKEDITOR.SHRINK_TEXT;

				var walkerRange = this.clone();

				var startContainer = this.startContainer,
					endContainer = this.endContainer,
					startOffset = this.startOffset,
					endOffset = this.endOffset;

				// Whether the start/end boundary is moveable.
				var moveStart = 1,
					moveEnd = 1;

				if ( startContainer && startContainer.type == CKEDITOR.NODE_TEXT ) {
					if ( !startOffset )
						walkerRange.setStartBefore( startContainer );
					else if ( startOffset >= startContainer.getLength() )
						walkerRange.setStartAfter( startContainer );
					else {
						// Enlarge the range properly to avoid walker making
						// DOM changes caused by triming the text nodes later.
						walkerRange.setStartBefore( startContainer );
						moveStart = 0;
					}
				}

				if ( endContainer && endContainer.type == CKEDITOR.NODE_TEXT ) {
					if ( !endOffset )
						walkerRange.setEndBefore( endContainer );
					else if ( endOffset >= endContainer.getLength() )
						walkerRange.setEndAfter( endContainer );
					else {
						walkerRange.setEndAfter( endContainer );
						moveEnd = 0;
					}
				}

				var walker = new CKEDITOR.dom.walker( walkerRange ),
					isBookmark = CKEDITOR.dom.walker.bookmark();

				walker.evaluator = function( node ) {
					return node.type == ( mode == CKEDITOR.SHRINK_ELEMENT ? CKEDITOR.NODE_ELEMENT : CKEDITOR.NODE_TEXT );
				};

				var currentElement;
				walker.guard = function( node, movingOut ) {
					if ( isBookmark( node ) )
						return true;

					// Stop when we're shrink in element mode while encountering a text node.
					if ( mode == CKEDITOR.SHRINK_ELEMENT && node.type == CKEDITOR.NODE_TEXT )
						return false;

					// Stop when we've already walked "through" an element.
					if ( movingOut && node.equals( currentElement ) )
						return false;

					if ( shrinkOnBlockBoundary === false && node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary() )
						return false;

					// Stop shrinking when encountering an editable border.
					if ( node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'contenteditable' ) )
						return false;

					if ( !movingOut && node.type == CKEDITOR.NODE_ELEMENT )
						currentElement = node;

					return true;
				};

				if ( moveStart ) {
					var textStart = walker[ mode == CKEDITOR.SHRINK_ELEMENT ? 'lastForward' : 'next' ]();
					textStart && this.setStartAt( textStart, selectContents ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_BEFORE_START );
				}

				if ( moveEnd ) {
					walker.reset();
					var textEnd = walker[ mode == CKEDITOR.SHRINK_ELEMENT ? 'lastBackward' : 'previous' ]();
					textEnd && this.setEndAt( textEnd, selectContents ? CKEDITOR.POSITION_BEFORE_END : CKEDITOR.POSITION_AFTER_END );
				}

				return !!( moveStart || moveEnd );
			}
		}
function ( mode , selectContents , shrinkOnBlockBoundary ) { // Unable to shrink a collapsed range. if ( ! this . collapsed ) { mode = mode || CKEDITOR . SHRINK_TEXT ; var walkerRange = this . clone ( ) ; var startContainer = this . startContainer , endContainer = this . endContainer , startOffset = this . startOffset , endOffset = this . endOffset ; // Whether the start/end boundary is moveable. var moveStart = 1 , moveEnd = 1 ; if ( startContainer && startContainer . type == CKEDITOR . NODE_TEXT ) { if ( ! startOffset ) walkerRange . setStartBefore ( startContainer ) ; else if ( startOffset >= startContainer . getLength ( ) ) walkerRange . setStartAfter ( startContainer ) ; else { // Enlarge the range properly to avoid walker making // DOM changes caused by triming the text nodes later. walkerRange . setStartBefore ( startContainer ) ; moveStart = 0 ; } } if ( endContainer && endContainer . type == CKEDITOR . NODE_TEXT ) { if ( ! endOffset ) walkerRange . setEndBefore ( endContainer ) ; else if ( endOffset >= endContainer . getLength ( ) ) walkerRange . setEndAfter ( endContainer ) ; else { walkerRange . setEndAfter ( endContainer ) ; moveEnd = 0 ; } } var walker = new CKEDITOR . dom . walker ( walkerRange ) , isBookmark = CKEDITOR . dom . walker . bookmark ( ) ; walker . evaluator = function ( node ) { return node . type == ( mode == CKEDITOR . SHRINK_ELEMENT ? CKEDITOR . NODE_ELEMENT : CKEDITOR . NODE_TEXT ) ; } ; var currentElement ; walker . guard = function ( node , movingOut ) { if ( isBookmark ( node ) ) return true ; // Stop when we're shrink in element mode while encountering a text node. if ( mode == CKEDITOR . SHRINK_ELEMENT && node . type == CKEDITOR . NODE_TEXT ) return false ; // Stop when we've already walked "through" an element. if ( movingOut && node . equals ( currentElement ) ) return false ; if ( shrinkOnBlockBoundary === false && node . type == CKEDITOR . NODE_ELEMENT && node . isBlockBoundary ( ) ) return false ; // Stop shrinking when encountering an editable border. if ( node . type == CKEDITOR . NODE_ELEMENT && node . hasAttribute ( 'contenteditable' ) ) return false ; if ( ! movingOut && node . type == CKEDITOR . NODE_ELEMENT ) currentElement = node ; return true ; } ; if ( moveStart ) { var textStart = walker [ mode == CKEDITOR . SHRINK_ELEMENT ? 'lastForward' : 'next' ] ( ) ; textStart && this . setStartAt ( textStart , selectContents ? CKEDITOR . POSITION_AFTER_START : CKEDITOR . POSITION_BEFORE_START ) ; } if ( moveEnd ) { walker . reset ( ) ; var textEnd = walker [ mode == CKEDITOR . SHRINK_ELEMENT ? 'lastBackward' : 'previous' ] ( ) ; textEnd && this . setEndAt ( textEnd , selectContents ? CKEDITOR . POSITION_BEFORE_END : CKEDITOR . POSITION_AFTER_END ) ; } return ! ! ( moveStart || moveEnd ) ; } }
Descrease the range to make sure that boundaries
always anchor beside text nodes or innermost element.

@param {Number} mode The shrinking mode ({@link CKEDITOR#SHRINK_ELEMENT} or {@link CKEDITOR#SHRINK_TEXT}).

* {@link CKEDITOR#SHRINK_ELEMENT} - Shrink the range boundaries to the edge of the innermost element.
* {@link CKEDITOR#SHRINK_TEXT} - Shrink the range boudaries to anchor by the side of enclosed text
node, range remains if there's no text nodes on boundaries at all.

@param {Boolean} selectContents Whether result range anchors at the inner OR outer boundary of the node.
Descrease the range to make sure that boundaries always anchor beside text nodes or innermost element .