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