import rt 3.8.7
[freeside.git] / rt / share / html / NoAuth / RichText / FCKeditor / editor / _source / internals / fcklisthandler.js
1 /*\r
2  * FCKeditor - The text editor for Internet - http://www.fckeditor.net\r
3  * Copyright (C) 2003-2009 Frederico Caldeira Knabben\r
4  *\r
5  * == BEGIN LICENSE ==\r
6  *\r
7  * Licensed under the terms of any of the following licenses at your\r
8  * choice:\r
9  *\r
10  *  - GNU General Public License Version 2 or later (the "GPL")\r
11  *    http://www.gnu.org/licenses/gpl.html\r
12  *\r
13  *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")\r
14  *    http://www.gnu.org/licenses/lgpl.html\r
15  *\r
16  *  - Mozilla Public License Version 1.1 or later (the "MPL")\r
17  *    http://www.mozilla.org/MPL/MPL-1.1.html\r
18  *\r
19  * == END LICENSE ==\r
20  *\r
21  * Tool object to manage HTML lists items (UL, OL and LI).\r
22  */\r
23 \r
24 var FCKListHandler =\r
25 {\r
26         OutdentListItem : function( listItem )\r
27         {\r
28                 var eParent = listItem.parentNode ;\r
29 \r
30                 // It may happen that a LI is not in a UL or OL (Orphan).\r
31                 if ( eParent.tagName.toUpperCase().Equals( 'UL','OL' ) )\r
32                 {\r
33                         var oDocument = FCKTools.GetElementDocument( listItem ) ;\r
34                         var oDogFrag = new FCKDocumentFragment( oDocument ) ;\r
35 \r
36                         // All children and successive siblings will be moved to a a DocFrag.\r
37                         var eNextSiblings = oDogFrag.RootNode ;\r
38                         var eHasLiSibling = false ;\r
39 \r
40                         // If we have nested lists inside it, let's move it to the list of siblings.\r
41                         var eChildList = FCKDomTools.GetFirstChild( listItem, ['UL','OL'] ) ;\r
42                         if ( eChildList )\r
43                         {\r
44                                 eHasLiSibling = true ;\r
45 \r
46                                 var eChild ;\r
47                                 // The extra () is to avoid a warning with strict error checking. This is ok.\r
48                                 while ( (eChild = eChildList.firstChild) )\r
49                                         eNextSiblings.appendChild( eChildList.removeChild( eChild ) ) ;\r
50 \r
51                                 FCKDomTools.RemoveNode( eChildList ) ;\r
52                         }\r
53 \r
54                         // Move all successive siblings.\r
55                         var eSibling ;\r
56                         var eHasSuccessiveLiSibling = false ;\r
57                         // The extra () is to avoid a warning with strict error checking. This is ok.\r
58                         while ( (eSibling = listItem.nextSibling) )\r
59                         {\r
60                                 if ( !eHasLiSibling && eSibling.nodeType == 1 && eSibling.nodeName.toUpperCase() == 'LI' )\r
61                                         eHasSuccessiveLiSibling = eHasLiSibling = true ;\r
62 \r
63                                 eNextSiblings.appendChild( eSibling.parentNode.removeChild( eSibling ) ) ;\r
64 \r
65                                 // If a sibling is a incorrectly nested UL or OL, consider only its children.\r
66                                 if ( !eHasSuccessiveLiSibling && eSibling.nodeType == 1 && eSibling.nodeName.toUpperCase().Equals( 'UL','OL' ) )\r
67                                         FCKDomTools.RemoveNode( eSibling, true ) ;\r
68                         }\r
69 \r
70                         // If we are in a list chain.\r
71                         var sParentParentTag = eParent.parentNode.tagName.toUpperCase() ;\r
72                         var bWellNested = ( sParentParentTag == 'LI' ) ;\r
73                         if ( bWellNested || sParentParentTag.Equals( 'UL','OL' ) )\r
74                         {\r
75                                 if ( eHasLiSibling )\r
76                                 {\r
77                                         var eChildList = eParent.cloneNode( false ) ;\r
78                                         oDogFrag.AppendTo( eChildList ) ;\r
79                                         listItem.appendChild( eChildList ) ;\r
80                                 }\r
81                                 else if ( bWellNested )\r
82                                         oDogFrag.InsertAfterNode( eParent.parentNode ) ;\r
83                                 else\r
84                                         oDogFrag.InsertAfterNode( eParent ) ;\r
85 \r
86                                 // Move the LI after its parent.parentNode (the upper LI in the hierarchy).\r
87                                 if ( bWellNested )\r
88                                         FCKDomTools.InsertAfterNode( eParent.parentNode, eParent.removeChild( listItem ) ) ;\r
89                                 else\r
90                                         FCKDomTools.InsertAfterNode( eParent, eParent.removeChild( listItem ) ) ;\r
91                         }\r
92                         else\r
93                         {\r
94                                 if ( eHasLiSibling )\r
95                                 {\r
96                                         var eNextList = eParent.cloneNode( false ) ;\r
97                                         oDogFrag.AppendTo( eNextList ) ;\r
98                                         FCKDomTools.InsertAfterNode( eParent, eNextList ) ;\r
99                                 }\r
100 \r
101                                 var eBlock = oDocument.createElement( FCKConfig.EnterMode == 'p' ? 'p' : 'div' ) ;\r
102                                 FCKDomTools.MoveChildren( eParent.removeChild( listItem ), eBlock ) ;\r
103                                 FCKDomTools.InsertAfterNode( eParent, eBlock ) ;\r
104 \r
105                                 if ( FCKConfig.EnterMode == 'br' )\r
106                                 {\r
107                                         // We need the bogus to make it work properly. In Gecko, we\r
108                                         // need it before the new block, on IE, after it.\r
109                                         if ( FCKBrowserInfo.IsGecko )\r
110                                                 eBlock.parentNode.insertBefore( FCKTools.CreateBogusBR( oDocument ), eBlock ) ;\r
111                                         else\r
112                                                 FCKDomTools.InsertAfterNode( eBlock, FCKTools.CreateBogusBR( oDocument ) ) ;\r
113 \r
114                                         FCKDomTools.RemoveNode( eBlock, true ) ;\r
115                                 }\r
116                         }\r
117 \r
118                         if ( this.CheckEmptyList( eParent ) )\r
119                                 FCKDomTools.RemoveNode( eParent, true ) ;\r
120                 }\r
121         },\r
122 \r
123         CheckEmptyList : function( listElement )\r
124         {\r
125                 return ( FCKDomTools.GetFirstChild( listElement, 'LI' ) == null ) ;\r
126         },\r
127 \r
128         // Check if the list has contents (excluding nested lists).\r
129         CheckListHasContents : function( listElement )\r
130         {\r
131                 var eChildNode = listElement.firstChild ;\r
132 \r
133                 while ( eChildNode )\r
134                 {\r
135                         switch ( eChildNode.nodeType )\r
136                         {\r
137                                 case 1 :\r
138                                         if ( !eChildNode.nodeName.IEquals( 'UL','LI' ) )\r
139                                                 return true ;\r
140                                         break ;\r
141 \r
142                                 case 3 :\r
143                                         if ( eChildNode.nodeValue.Trim().length > 0 )\r
144                                                 return true ;\r
145                         }\r
146 \r
147                         eChildNode = eChildNode.nextSibling ;\r
148                 }\r
149 \r
150                 return false ;\r
151         }\r
152 } ;\r