1 /*
  2 Copyright (c) 2003-2012, 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,dd:1, legend:1,caption: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,form:1,fieldset: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 	/**
 31 	 * @class
 32 	 */
 33 	CKEDITOR.dom.elementPath = function( lastNode )
 34 	{
 35 		var block = null;
 36 		var blockLimit = null;
 37 		var elements = [];
 38 
 39 		var e = lastNode;
 40 
 41 		while ( e )
 42 		{
 43 			if ( e.type == CKEDITOR.NODE_ELEMENT )
 44 			{
 45 				if ( !this.lastElement )
 46 					this.lastElement = e;
 47 
 48 				var elementName = e.getName();
 49 
 50 				if ( !blockLimit )
 51 				{
 52 					if ( !block && pathBlockElements[ elementName ] )
 53 						block = e;
 54 
 55 					if ( pathBlockLimitElements[ elementName ] )
 56 					{
 57 						// DIV is considered the Block, if no block is available (#525)
 58 						// and if it doesn't contain other blocks.
 59 						if ( !block && elementName == 'div' && !checkHasBlock( e ) )
 60 							block = e;
 61 						else
 62 							blockLimit = e;
 63 					}
 64 				}
 65 
 66 				elements.push( e );
 67 
 68 				if ( elementName == 'body' )
 69 					break;
 70 			}
 71 			e = e.getParent();
 72 		}
 73 
 74 		this.block = block;
 75 		this.blockLimit = blockLimit;
 76 		this.elements = elements;
 77 	};
 78 })();
 79 
 80 CKEDITOR.dom.elementPath.prototype =
 81 {
 82 	/**
 83 	 * Compares this element path with another one.
 84 	 * @param {CKEDITOR.dom.elementPath} otherPath The elementPath object to be
 85 	 * compared with this one.
 86 	 * @returns {Boolean} "true" if the paths are equal, containing the same
 87 	 * number of elements and the same elements in the same order.
 88 	 */
 89 	compare : function( otherPath )
 90 	{
 91 		var thisElements = this.elements;
 92 		var otherElements = otherPath && otherPath.elements;
 93 
 94 		if ( !otherElements || thisElements.length != otherElements.length )
 95 			return false;
 96 
 97 		for ( var i = 0 ; i < thisElements.length ; i++ )
 98 		{
 99 			if ( !thisElements[ i ].equals( otherElements[ i ] ) )
100 				return false;
101 		}
102 
103 		return true;
104 	},
105 
106 	contains : function( tagNames )
107 	{
108 		var elements = this.elements;
109 		for ( var i = 0 ; i < elements.length ; i++ )
110 		{
111 			if ( elements[ i ].getName() in tagNames )
112 				return elements[ i ];
113 		}
114 
115 		return null;
116 	}
117 };
118