~ubuntu-branches/ubuntu/oneiric/moin/oneiric-security

« back to all changes in this revision

Viewing changes to wiki/htdocs/applets/FCKeditor/editor/_source/commandclasses/fckindentcommands.js

  • Committer: Bazaar Package Importer
  • Author(s): Jamie Strandboge
  • Date: 2010-03-30 12:55:34 UTC
  • mfrom: (0.1.17 sid)
  • Revision ID: james.westby@ubuntu.com-20100330125534-4c2ufc1rok24447l
Tags: 1.9.2-2ubuntu1
* Merge from Debian testing (LP: #521834). Based on work by Stefan Ebner.
  Remaining changes:
 - Remove python-xml from Suggests field, the package isn't anymore in
   sys.path.
 - Demote fckeditor from Recommends to Suggests; the code was previously
   embedded in moin, but it was also disabled, so there's no reason for us
   to pull this in by default currently. Note: This isn't necessary anymore
   but needs a MIR for fckeditor, so postpone dropping this change until
   lucid+1
* debian/rules:
  - Replace hardcoded python2.5 with python* and hardcore python2.6 for ln
* debian/control.in: drop versioned depends on cdbs

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
3
 
 * Copyright (C) 2003-2009 Frederico Caldeira Knabben
4
 
 *
5
 
 * == BEGIN LICENSE ==
6
 
 *
7
 
 * Licensed under the terms of any of the following licenses at your
8
 
 * choice:
9
 
 *
10
 
 *  - GNU General Public License Version 2 or later (the "GPL")
11
 
 *    http://www.gnu.org/licenses/gpl.html
12
 
 *
13
 
 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
14
 
 *    http://www.gnu.org/licenses/lgpl.html
15
 
 *
16
 
 *  - Mozilla Public License Version 1.1 or later (the "MPL")
17
 
 *    http://www.mozilla.org/MPL/MPL-1.1.html
18
 
 *
19
 
 * == END LICENSE ==
20
 
 *
21
 
 * FCKIndentCommand Class: controls block indentation.
22
 
 */
23
 
 
24
 
var FCKIndentCommand = function( name, offset )
25
 
{
26
 
        this.Name = name ;
27
 
        this.Offset = offset ;
28
 
        this.IndentCSSProperty = FCKConfig.ContentLangDirection.IEquals( 'ltr' ) ? 'marginLeft' : 'marginRight' ;
29
 
}
30
 
 
31
 
FCKIndentCommand._InitIndentModeParameters = function()
32
 
{
33
 
        if ( FCKConfig.IndentClasses && FCKConfig.IndentClasses.length > 0 )
34
 
        {
35
 
                this._UseIndentClasses = true ;
36
 
                this._IndentClassMap = {} ;
37
 
                for ( var i = 0 ; i < FCKConfig.IndentClasses.length ;i++ )
38
 
                        this._IndentClassMap[FCKConfig.IndentClasses[i]] = i + 1 ;
39
 
                this._ClassNameRegex = new RegExp( '(?:^|\\s+)(' + FCKConfig.IndentClasses.join( '|' ) + ')(?=$|\\s)' ) ;
40
 
        }
41
 
        else
42
 
                this._UseIndentClasses = false ;
43
 
}
44
 
 
45
 
 
46
 
FCKIndentCommand.prototype =
47
 
{
48
 
        Execute : function()
49
 
        {
50
 
                // Save an undo snapshot before doing anything.
51
 
                FCKUndo.SaveUndoStep() ;
52
 
 
53
 
                var range = new FCKDomRange( FCK.EditorWindow ) ;
54
 
                range.MoveToSelection() ;
55
 
                var bookmark = range.CreateBookmark() ;
56
 
 
57
 
                // Two cases to handle here: either we're in a list, or not.
58
 
                // If we're in a list, then the indent/outdent operations would be done on the list nodes.
59
 
                // Otherwise, apply the operation on the nearest block nodes.
60
 
                var nearestListBlock = FCKDomTools.GetCommonParentNode( range.StartNode || range.StartContainer ,
61
 
                                range.EndNode || range.EndContainer,
62
 
                                ['ul', 'ol'] ) ;
63
 
                if ( nearestListBlock )
64
 
                        this._IndentList( range, nearestListBlock ) ;
65
 
                else
66
 
                        this._IndentBlock( range ) ;
67
 
 
68
 
                range.MoveToBookmark( bookmark ) ;
69
 
                range.Select() ;
70
 
 
71
 
                FCK.Focus() ;
72
 
                FCK.Events.FireEvent( 'OnSelectionChange' ) ;
73
 
        },
74
 
 
75
 
        GetState : function()
76
 
        {
77
 
                // Disabled if not WYSIWYG.
78
 
                if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow )
79
 
                        return FCK_TRISTATE_DISABLED ;
80
 
 
81
 
                // Initialize parameters if not already initialzed.
82
 
                if ( FCKIndentCommand._UseIndentClasses == undefined )
83
 
                        FCKIndentCommand._InitIndentModeParameters() ;
84
 
 
85
 
                // If we're not in a list, and the starting block's indentation is zero, and the current
86
 
                // command is the outdent command, then we should return FCK_TRISTATE_DISABLED.
87
 
                var startContainer = FCKSelection.GetBoundaryParentElement( true ) ;
88
 
                var endContainer = FCKSelection.GetBoundaryParentElement( false ) ;
89
 
                var listNode = FCKDomTools.GetCommonParentNode( startContainer, endContainer, ['ul','ol'] ) ;
90
 
 
91
 
                if ( listNode )
92
 
                {
93
 
                        if ( this.Name.IEquals( 'outdent' ) )
94
 
                                return FCK_TRISTATE_OFF ;
95
 
                        var firstItem = FCKTools.GetElementAscensor( startContainer, 'li' ) ;
96
 
                        if ( !firstItem || !firstItem.previousSibling )
97
 
                                return FCK_TRISTATE_DISABLED ;
98
 
                        return FCK_TRISTATE_OFF ;
99
 
                }
100
 
                if ( ! FCKIndentCommand._UseIndentClasses && this.Name.IEquals( 'indent' ) )
101
 
                        return FCK_TRISTATE_OFF;
102
 
 
103
 
                var path = new FCKElementPath( startContainer ) ;
104
 
                var firstBlock = path.Block || path.BlockLimit ;
105
 
                if ( !firstBlock )
106
 
                        return FCK_TRISTATE_DISABLED ;
107
 
 
108
 
                if ( FCKIndentCommand._UseIndentClasses )
109
 
                {
110
 
                        var indentClass = firstBlock.className.match( FCKIndentCommand._ClassNameRegex ) ;
111
 
                        var indentStep = 0 ;
112
 
                        if ( indentClass != null )
113
 
                        {
114
 
                                indentClass = indentClass[1] ;
115
 
                                indentStep = FCKIndentCommand._IndentClassMap[indentClass] ;
116
 
                        }
117
 
                        if ( ( this.Name == 'outdent' && indentStep == 0 ) ||
118
 
                                        ( this.Name == 'indent' && indentStep == FCKConfig.IndentClasses.length ) )
119
 
                                return FCK_TRISTATE_DISABLED ;
120
 
                        return FCK_TRISTATE_OFF ;
121
 
                }
122
 
                else
123
 
                {
124
 
                        var indent = parseInt( firstBlock.style[this.IndentCSSProperty], 10 ) ;
125
 
                        if ( isNaN( indent ) )
126
 
                                indent = 0 ;
127
 
                        if ( indent <= 0 )
128
 
                                return FCK_TRISTATE_DISABLED ;
129
 
                        return FCK_TRISTATE_OFF ;
130
 
                }
131
 
        },
132
 
 
133
 
        _IndentBlock : function( range )
134
 
        {
135
 
                var iterator = new FCKDomRangeIterator( range ) ;
136
 
                iterator.EnforceRealBlocks = true ;
137
 
 
138
 
                range.Expand( 'block_contents' ) ;
139
 
                var commonParents = FCKDomTools.GetCommonParents( range.StartContainer, range.EndContainer ) ;
140
 
                var nearestParent = commonParents[commonParents.length - 1] ;
141
 
                var block ;
142
 
 
143
 
                while ( ( block = iterator.GetNextParagraph() ) )
144
 
                {
145
 
                        // We don't want to indent subtrees recursively, so only perform the indent operation
146
 
                        // if the block itself is the nearestParent, or the block's parent is the nearestParent.
147
 
                        if ( ! ( block == nearestParent || block.parentNode == nearestParent ) )
148
 
                                continue ;
149
 
 
150
 
                        if ( FCKIndentCommand._UseIndentClasses )
151
 
                        {
152
 
                                // Transform current class name to indent step index.
153
 
                                var indentClass = block.className.match( FCKIndentCommand._ClassNameRegex ) ;
154
 
                                var indentStep = 0 ;
155
 
                                if ( indentClass != null )
156
 
                                {
157
 
                                        indentClass = indentClass[1] ;
158
 
                                        indentStep = FCKIndentCommand._IndentClassMap[indentClass] ;
159
 
                                }
160
 
 
161
 
                                // Operate on indent step index, transform indent step index back to class name.
162
 
                                if ( this.Name.IEquals( 'outdent' ) )
163
 
                                        indentStep-- ;
164
 
                                else if ( this.Name.IEquals( 'indent' ) )
165
 
                                        indentStep++ ;
166
 
                                indentStep = Math.min( indentStep, FCKConfig.IndentClasses.length ) ;
167
 
                                indentStep = Math.max( indentStep, 0 ) ;
168
 
                                var className = block.className.replace( FCKIndentCommand._ClassNameRegex, '' ) ;
169
 
                                if ( indentStep < 1 )
170
 
                                        block.className = className ;
171
 
                                else
172
 
                                        block.className = ( className.length > 0 ? className + ' ' : '' ) +
173
 
                                                FCKConfig.IndentClasses[indentStep - 1] ;
174
 
                        }
175
 
                        else
176
 
                        {
177
 
                                // Offset distance is assumed to be in pixels for now.
178
 
                                var currentOffset = parseInt( block.style[this.IndentCSSProperty], 10 ) ;
179
 
                                if ( isNaN( currentOffset ) )
180
 
                                        currentOffset = 0 ;
181
 
                                currentOffset += this.Offset ;
182
 
                                currentOffset = Math.max( currentOffset, 0 ) ;
183
 
                                currentOffset = Math.ceil( currentOffset / this.Offset ) * this.Offset ;
184
 
                                block.style[this.IndentCSSProperty] = currentOffset ? currentOffset + FCKConfig.IndentUnit : '' ;
185
 
                                if ( block.getAttribute( 'style' ) == '' )
186
 
                                        block.removeAttribute( 'style' ) ;
187
 
                        }
188
 
                }
189
 
        },
190
 
 
191
 
        _IndentList : function( range, listNode )
192
 
        {
193
 
                // Our starting and ending points of the range might be inside some blocks under a list item...
194
 
                // So before playing with the iterator, we need to expand the block to include the list items.
195
 
                var startContainer = range.StartContainer ;
196
 
                var endContainer = range.EndContainer ;
197
 
                while ( startContainer && startContainer.parentNode != listNode )
198
 
                        startContainer = startContainer.parentNode ;
199
 
                while ( endContainer && endContainer.parentNode != listNode )
200
 
                        endContainer = endContainer.parentNode ;
201
 
 
202
 
                if ( ! startContainer || ! endContainer )
203
 
                        return ;
204
 
 
205
 
                // Now we can iterate over the individual items on the same tree depth.
206
 
                var block = startContainer ;
207
 
                var itemsToMove = [] ;
208
 
                var stopFlag = false ;
209
 
                while ( stopFlag == false )
210
 
                {
211
 
                        if ( block == endContainer )
212
 
                                stopFlag = true ;
213
 
                        itemsToMove.push( block ) ;
214
 
                        block = block.nextSibling ;
215
 
                }
216
 
                if ( itemsToMove.length < 1 )
217
 
                        return ;
218
 
 
219
 
                // Do indent or outdent operations on the array model of the list, not the list's DOM tree itself.
220
 
                // The array model demands that it knows as much as possible about the surrounding lists, we need
221
 
                // to feed it the further ancestor node that is still a list.
222
 
                var listParents = FCKDomTools.GetParents( listNode ) ;
223
 
                for ( var i = 0 ; i < listParents.length ; i++ )
224
 
                {
225
 
                        if ( listParents[i].nodeName.IEquals( ['ul', 'ol'] ) )
226
 
                        {
227
 
                                listNode = listParents[i] ;
228
 
                                break ;
229
 
                        }
230
 
                }
231
 
                var indentOffset = this.Name.IEquals( 'indent' ) ? 1 : -1 ;
232
 
                var startItem = itemsToMove[0] ;
233
 
                var lastItem = itemsToMove[ itemsToMove.length - 1 ] ;
234
 
                var markerObj = {} ;
235
 
 
236
 
                // Convert the list DOM tree into a one dimensional array.
237
 
                var listArray = FCKDomTools.ListToArray( listNode, markerObj ) ;
238
 
 
239
 
                // Apply indenting or outdenting on the array.
240
 
                var baseIndent = listArray[lastItem._FCK_ListArray_Index].indent ;
241
 
                for ( var i = startItem._FCK_ListArray_Index ; i <= lastItem._FCK_ListArray_Index ; i++ )
242
 
                        listArray[i].indent += indentOffset ;
243
 
                for ( var i = lastItem._FCK_ListArray_Index + 1 ; i < listArray.length && listArray[i].indent > baseIndent ; i++ )
244
 
                        listArray[i].indent += indentOffset ;
245
 
 
246
 
                /* For debug use only
247
 
                var PrintArray = function( listArray, doc )
248
 
                {
249
 
                        var s = [] ;
250
 
                        for ( var i = 0 ; i < listArray.length ; i++ )
251
 
                        {
252
 
                                for ( var j in listArray[i] )
253
 
                                {
254
 
                                        if ( j != 'contents' )
255
 
                                                s.push( j + ":" + listArray[i][j] + "; " ) ;
256
 
                                        else
257
 
                                        {
258
 
                                                var docFrag = doc.createDocumentFragment() ;
259
 
                                                var tmpNode = doc.createElement( 'span' ) ;
260
 
                                                for ( var k = 0 ; k < listArray[i][j].length ; k++ )
261
 
                                                        docFrag.appendChild( listArray[i][j][k].cloneNode( true ) ) ;
262
 
                                                tmpNode.appendChild( docFrag ) ;
263
 
                                                s.push( j + ":" + tmpNode.innerHTML + "; ") ;
264
 
                                        }
265
 
                                }
266
 
                                s.push( '\n' ) ;
267
 
                        }
268
 
                        alert( s.join('') ) ;
269
 
                }
270
 
                PrintArray( listArray, FCK.EditorDocument ) ;
271
 
                */
272
 
 
273
 
                // Convert the array back to a DOM forest (yes we might have a few subtrees now).
274
 
                // And replace the old list with the new forest.
275
 
                var newList = FCKDomTools.ArrayToList( listArray ) ;
276
 
                if ( newList )
277
 
                        listNode.parentNode.replaceChild( newList.listNode, listNode ) ;
278
 
 
279
 
                // Clean up the markers.
280
 
                FCKDomTools.ClearAllMarkers( markerObj ) ;
281
 
        }
282
 
} ;