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