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