1 /*
  2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
  3 For licensing, see LICENSE.html or http://ckeditor.com/license
  4 */
  5
  6 (function()
  7 {
  8 	// Elements that may be considered the "Block boundary" in an element path.
  9 	var pathBlockElements = { address:1,blockquote:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,li:1,dt:1,de:1 };
 10
 11 	// Elements that may be considered the "Block limit" in an element path.
 12 	var pathBlockLimitElements = { body:1,div:1,table:1,tbody:1,tr:1,td:1,th:1,caption:1,form:1 };
 13
 14 	// Check if an element contains any block element.
 15 	var checkHasBlock = function( element )
 16 	{
 17 		var childNodes = element.getChildren();
 18
 19 		for ( var i = 0, count = childNodes.count() ; i < count ; i++ )
 20 		{
 21 			var child = childNodes.getItem( i );
 22
 23 			if ( child.type == CKEDITOR.NODE_ELEMENT && CKEDITOR.dtd.$block[ child.getName() ] )
 24 				return true;
 25 		}
 26
 27 		return false;
 28 	};
 29
 30 	CKEDITOR.dom.elementPath = function( lastNode )
 31 	{
 32 		var block = null;
 33 		var blockLimit = null;
 34 		var elements = [];
 35
 36 		var e = lastNode;
 37
 38 		while ( e )
 39 		{
 40 			if ( e.type == CKEDITOR.NODE_ELEMENT )
 41 			{
 42 				if ( !this.lastElement )
 43 					this.lastElement = e;
 44
 45 				var elementName = e.getName();
 46 				if ( CKEDITOR.env.ie && e.$.scopeName != 'HTML' )
 47 					elementName = e.$.scopeName.toLowerCase() + ':' + elementName;
 48
 49 				if ( !blockLimit )
 50 				{
 51 					if ( !block && pathBlockElements[ elementName ] )
 52 						block = e;
 53
 54 					if ( pathBlockLimitElements[ elementName ] )
 55 					{
 56 						// DIV is considered the Block, if no block is available (#525)
 57 						// and if it doesn't contain other blocks.
 58 						if ( !block && elementName == 'div' && !checkHasBlock( e ) )
 59 							block = e;
 60 						else
 61 							blockLimit = e;
 62 					}
 63 				}
 64
 65 				elements.push( e );
 66
 67 				if ( elementName == 'body' )
 68 					break;
 69 			}
 70 			e = e.getParent();
 71 		}
 72
 73 		this.block = block;
 74 		this.blockLimit = blockLimit;
 75 		this.elements = elements;
 76 	};
 77 })();
 78
 79 CKEDITOR.dom.elementPath.prototype =
 80 {
 81 	/**
 82 	 * Compares this element path with another one.
 83 	 * @param {CKEDITOR.dom.elementPath} otherPath The elementPath object to be
 84 	 * compared with this one.
 85 	 * @returns {Boolean} "true" if the paths are equal, containing the same
 86 	 * number of elements and the same elements in the same order.
 87 	 */
 88 	compare : function( otherPath )
 89 	{
 90 		var thisElements = this.elements;
 91 		var otherElements = otherPath && otherPath.elements;
 92
 93 		if ( !otherElements || thisElements.length != otherElements.length )
 94 			return false;
 95
 96 		for ( var i = 0 ; i < thisElements.length ; i++ )
 97 		{
 98 			if ( !thisElements[ i ].equals( otherElements[ i ] ) )
 99 				return false;
100 		}
101
102 		return true;
103 	}
104 };
105