]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/javascript/tiny_mce/plugins/lists/editor_plugin_src.js
Release 6.2.2
[Github/sugarcrm.git] / include / javascript / tiny_mce / plugins / lists / editor_plugin_src.js
1 /**
2  * editor_plugin_src.js
3  *
4  * Copyright 2011, Moxiecode Systems AB
5  * Released under LGPL License.
6  *
7  * License: http://tinymce.moxiecode.com/license
8  * Contributing: http://tinymce.moxiecode.com/contributing
9  */
10
11 (function() {
12         var each = tinymce.each, Event = tinymce.dom.Event, bookmark;
13
14         // Skips text nodes that only contain whitespace since they aren't semantically important.
15         function skipWhitespaceNodes(e, next) {
16                 while (e && (e.nodeType === 8 || (e.nodeType === 3 && /^[ \t\n\r]*$/.test(e.nodeValue)))) {
17                         e = next(e);
18                 }
19                 return e;
20         }
21         
22         function skipWhitespaceNodesBackwards(e) {
23                 return skipWhitespaceNodes(e, function(e) { return e.previousSibling; });
24         }
25         
26         function skipWhitespaceNodesForwards(e) {
27                 return skipWhitespaceNodes(e, function(e) { return e.nextSibling; });
28         }
29         
30         function hasParentInList(ed, e, list) {
31                 return ed.dom.getParent(e, function(p) {
32                         return tinymce.inArray(list, p) !== -1;
33                 });
34         }
35         
36         function isList(e) {
37                 return e && (e.tagName === 'OL' || e.tagName === 'UL');
38         }
39         
40         function splitNestedLists(element, dom) {
41                 var tmp, nested, wrapItem;
42                 tmp = skipWhitespaceNodesBackwards(element.lastChild);
43                 while (isList(tmp)) {
44                         nested = tmp;
45                         tmp = skipWhitespaceNodesBackwards(nested.previousSibling);
46                 }
47                 if (nested) {
48                         wrapItem = dom.create('li', { style: 'list-style-type: none;'});
49                         dom.split(element, nested);
50                         dom.insertAfter(wrapItem, nested);
51                         wrapItem.appendChild(nested);
52                         wrapItem.appendChild(nested);
53                         element = wrapItem.previousSibling;
54                 }
55                 return element;
56         }
57         
58         function attemptMergeWithAdjacent(e, allowDifferentListStyles, mergeParagraphs) {
59                 e = attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs);
60                 return attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs);
61         }
62         
63         function attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs) {
64                 var prev = skipWhitespaceNodesBackwards(e.previousSibling);
65                 if (prev) {
66                         return attemptMerge(prev, e, allowDifferentListStyles ? prev : false, mergeParagraphs);
67                 } else {
68                         return e;
69                 }
70         }
71         
72         function attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs) {
73                 var next = skipWhitespaceNodesForwards(e.nextSibling);
74                 if (next) {
75                         return attemptMerge(e, next, allowDifferentListStyles ? next : false, mergeParagraphs);
76                 } else {
77                         return e;
78                 }
79         }
80         
81         function attemptMerge(e1, e2, differentStylesMasterElement, mergeParagraphs) {
82                 if (canMerge(e1, e2, !!differentStylesMasterElement, mergeParagraphs)) {
83                         return merge(e1, e2, differentStylesMasterElement);
84                 } else if (e1 && e1.tagName === 'LI' && isList(e2)) {
85                         // Fix invalidly nested lists.
86                         e1.appendChild(e2);
87                 }
88                 return e2;
89         }
90         
91         function canMerge(e1, e2, allowDifferentListStyles, mergeParagraphs) {
92                 if (!e1 || !e2) {
93                         return false;
94                 } else if (e1.tagName === 'LI' && e2.tagName === 'LI') {
95                         return e2.style.listStyleType === 'none' || containsOnlyAList(e2);
96                 } else if (isList(e1)) {
97                         return (e1.tagName === e2.tagName && (allowDifferentListStyles || e1.style.listStyleType === e2.style.listStyleType)) || isListForIndent(e2);
98                 } else if (mergeParagraphs && e1.tagName === 'P' && e2.tagName === 'P') {
99                         return true;
100                 } else {
101                         return false;
102                 }
103         }
104         
105         function isListForIndent(e) {
106                 var firstLI = skipWhitespaceNodesForwards(e.firstChild), lastLI = skipWhitespaceNodesBackwards(e.lastChild);
107                 return firstLI && lastLI && isList(e) && firstLI === lastLI && (isList(firstLI) || firstLI.style.listStyleType === 'none'  || containsOnlyAList(firstLI));
108         }
109         
110         function containsOnlyAList(e) {
111                 var firstChild = skipWhitespaceNodesForwards(e.firstChild), lastChild = skipWhitespaceNodesBackwards(e.lastChild);
112                 return firstChild && lastChild && firstChild === lastChild && isList(firstChild);
113         }
114         
115         function merge(e1, e2, masterElement) {
116                 var lastOriginal = skipWhitespaceNodesBackwards(e1.lastChild), firstNew = skipWhitespaceNodesForwards(e2.firstChild);
117                 if (e1.tagName === 'P') {
118                         e1.appendChild(e1.ownerDocument.createElement('br'));
119                 }
120                 while (e2.firstChild) {
121                         e1.appendChild(e2.firstChild);
122                 }
123                 if (masterElement) {
124                         e1.style.listStyleType = masterElement.style.listStyleType;
125                 }
126                 e2.parentNode.removeChild(e2);
127                 attemptMerge(lastOriginal, firstNew, false);
128                 return e1;
129         }
130         
131         function findItemToOperateOn(e, dom) {
132                 var item;
133                 if (!dom.is(e, 'li,ol,ul')) {
134                         item = dom.getParent(e, 'li');
135                         if (item) {
136                                 e = item;
137                         }
138                 }
139                 return e;
140         }
141         
142         tinymce.create('tinymce.plugins.Lists', {
143                 init: function(ed, url) {
144                         var enterDownInEmptyList = false;
145                         function isTriggerKey(e) {
146                                 return e.keyCode === 9 && (ed.queryCommandState('InsertUnorderedList') || ed.queryCommandState('InsertOrderedList'));
147                         }
148                         function isEnterInEmptyListItem(ed, e) {
149                                 var sel = ed.selection, n;
150                                 if (e.keyCode === 13) {
151                                         n = sel.getStart();
152                                         enterDownInEmptyList = sel.isCollapsed() && n && n.tagName === 'LI' && n.childNodes.length === 0;
153                                         return enterDownInEmptyList;
154                                 }
155                         }
156                         function cancelKeys(ed, e) {
157                                 if (isTriggerKey(e) || isEnterInEmptyListItem(ed, e)) {
158                                         return Event.cancel(e);
159                                 }
160                         }
161                         
162                         this.ed = ed;
163                         ed.addCommand('Indent', this.indent, this);
164                         ed.addCommand('Outdent', this.outdent, this);
165                         ed.addCommand('InsertUnorderedList', function() {
166                                 this.applyList('UL', 'OL');
167                         }, this);
168                         ed.addCommand('InsertOrderedList', function() {
169                                 this.applyList('OL', 'UL');
170                         }, this);
171                         
172                         ed.onInit.add(function() {
173                                 ed.editorCommands.addCommands({
174                                         'outdent': function() {
175                                                 var sel = ed.selection, dom = ed.dom;
176                                                 function hasStyleIndent(n) {
177                                                         n = dom.getParent(n, dom.isBlock);
178                                                         return n && (parseInt(ed.dom.getStyle(n, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(n, 'padding-left') || 0, 10)) > 0;
179                                                 }
180                                                 return hasStyleIndent(sel.getStart()) || hasStyleIndent(sel.getEnd()) || ed.queryCommandState('InsertOrderedList') || ed.queryCommandState('InsertUnorderedList');
181                                         }
182                                 }, 'state');
183                         });
184                         
185                         ed.onKeyUp.add(function(ed, e) {
186                                 var n, rng;
187                                 if (isTriggerKey(e)) {
188                                         ed.execCommand(e.shiftKey ? 'Outdent' : 'Indent', true, null);
189                                         return Event.cancel(e);
190                                 } else if (enterDownInEmptyList && isEnterInEmptyListItem(ed, e)) {
191                                         if (ed.queryCommandState('InsertOrderedList')) {
192                                                 ed.execCommand('InsertOrderedList');
193                                         } else {
194                                                 ed.execCommand('InsertUnorderedList');
195                                         }
196                                         n = ed.selection.getStart();
197                                         if (n && n.tagName === 'LI') {
198                                                 // Fix the caret position on IE since it jumps back up to the previous list item.
199                                                 n = ed.dom.getParent(n, 'ol,ul').nextSibling;
200                                                 if (n && n.tagName === 'P') {
201                                                         if (!n.firstChild) {
202                                                                 n.appendChild(ed.getDoc().createTextNode(''));
203                                                         }
204                                                         rng = ed.dom.createRng();
205                                                         rng.setStart(n.firstChild, 1);
206                                                         rng.setEnd(n.firstChild, 1);
207                                                         ed.selection.setRng(rng);
208                                                 }
209                                         }
210                                         return Event.cancel(e);
211                                 }
212                         });
213                         ed.onKeyPress.add(cancelKeys);
214                         ed.onKeyDown.add(cancelKeys);
215                 },
216                 
217                 applyList: function(targetListType, oppositeListType) {
218                         var t = this, ed = t.ed, dom = ed.dom, applied = [], hasSameType = false, hasOppositeType = false, hasNonList = false, actions,
219                                 selectedBlocks = ed.selection.getSelectedBlocks();
220                         
221                         function cleanupBr(e) {
222                                 if (e && e.tagName === 'BR') {
223                                         dom.remove(e);
224                                 }
225                         }
226                         
227                         function makeList(element) {
228                                 var list = dom.create(targetListType), li;
229                                 function adjustIndentForNewList(element) {
230                                         // If there's a margin-left, outdent one level to account for the extra list margin.
231                                         if (element.style.marginLeft || element.style.paddingLeft) {
232                                                 t.adjustPaddingFunction(false)(element);
233                                         }
234                                 }
235                                 
236                                 if (element.tagName === 'LI') {
237                                         // No change required.
238                                 } else if (element.tagName === 'P' || element.tagName === 'DIV' || element.tagName === 'BODY') {
239                                         processBrs(element, function(startSection, br, previousBR) {
240                                                 doWrapList(startSection, br, element.tagName === 'BODY' ? null : startSection.parentNode);
241                                                 li = startSection.parentNode;
242                                                 adjustIndentForNewList(li);
243                                                 cleanupBr(br);
244                                         });
245                                         if (element.tagName === 'P' || selectedBlocks.length > 1) {
246                                                 dom.split(li.parentNode.parentNode, li.parentNode);
247                                         }
248                                         attemptMergeWithAdjacent(li.parentNode, true);
249                                         return;
250                                 } else {
251                                         // Put the list around the element.
252                                         li = dom.create('li');
253                                         dom.insertAfter(li, element);
254                                         li.appendChild(element);
255                                         adjustIndentForNewList(element);
256                                         element = li;
257                                 }
258                                 dom.insertAfter(list, element);
259                                 list.appendChild(element);
260                                 attemptMergeWithAdjacent(list, true);
261                                 applied.push(element);
262                         }
263                         
264                         function doWrapList(start, end, template) {
265                                 var li, n = start, tmp, i;
266                                 while (!dom.isBlock(start.parentNode) && start.parentNode !== dom.getRoot()) {
267                                         start = dom.split(start.parentNode, start.previousSibling);
268                                         start = start.nextSibling;
269                                         n = start;
270                                 }
271                                 if (template) {
272                                         li = template.cloneNode(true);
273                                         start.parentNode.insertBefore(li, start);
274                                         while (li.firstChild) dom.remove(li.firstChild);
275                                         li = dom.rename(li, 'li');
276                                 } else {
277                                         li = dom.create('li');
278                                         start.parentNode.insertBefore(li, start);
279                                 }
280                                 while (n && n != end) {
281                                         tmp = n.nextSibling;
282                                         li.appendChild(n);
283                                         n = tmp;
284                                 }
285                                 if (li.childNodes.length === 0) {
286                                         li.innerHTML = '<br _mce_bogus="1" />';
287                                 }
288                                 makeList(li);
289                         }
290                         
291                         function processBrs(element, callback) {
292                                 var startSection, previousBR, END_TO_START = 3, START_TO_END = 1,
293                                         breakElements = 'br,ul,ol,p,div,h1,h2,h3,h4,h5,h6,table,blockquote,address,pre,form,center,dl';
294                                 function isAnyPartSelected(start, end) {
295                                         var r = dom.createRng(), sel;
296                                         bookmark.keep = true;
297                                         ed.selection.moveToBookmark(bookmark);
298                                         bookmark.keep = false;
299                                         sel = ed.selection.getRng(true);
300                                         if (!end) {
301                                                 end = start.parentNode.lastChild;
302                                         }
303                                         r.setStartBefore(start);
304                                         r.setEndAfter(end);
305                                         return !(r.compareBoundaryPoints(END_TO_START, sel) > 0 || r.compareBoundaryPoints(START_TO_END, sel) <= 0);
306                                 }
307                                 function nextLeaf(br) {
308                                         if (br.nextSibling)
309                                                 return br.nextSibling;
310                                         if (!dom.isBlock(br.parentNode) && br.parentNode !== dom.getRoot())
311                                                 return nextLeaf(br.parentNode);
312                                 }
313                                 // Split on BRs within the range and process those.
314                                 startSection = element.firstChild;
315                                 // First mark the BRs that have any part of the previous section selected.
316                                 var trailingContentSelected = false;
317                                 each(dom.select(breakElements, element), function(br) {
318                                         var b;
319                                         if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
320                                                 return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
321                                         }
322                                         if (isAnyPartSelected(startSection, br)) {
323                                                 dom.addClass(br, '_mce_tagged_br');
324                                                 startSection = nextLeaf(br);
325                                         }
326                                 });
327                                 trailingContentSelected = (startSection && isAnyPartSelected(startSection, undefined));
328                                 startSection = element.firstChild;
329                                 each(dom.select(breakElements, element), function(br) {
330                                         // Got a section from start to br.
331                                         var tmp = nextLeaf(br);
332                                         if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
333                                                 return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
334                                         }
335                                         if (dom.hasClass(br, '_mce_tagged_br')) {
336                                                 callback(startSection, br, previousBR);
337                                                 previousBR = null;
338                                         } else {
339                                                 previousBR = br;
340                                         }
341                                         startSection = tmp;
342                                 });
343                                 if (trailingContentSelected) {
344                                         callback(startSection, undefined, previousBR);
345                                 }
346                         }
347                         
348                         function wrapList(element) {
349                                 processBrs(element, function(startSection, br, previousBR) {
350                                         // Need to indent this part
351                                         doWrapList(startSection, br);
352                                         cleanupBr(br);
353                                         cleanupBr(previousBR);
354                                 });
355                         }
356                         
357                         function changeList(element) {
358                                 if (tinymce.inArray(applied, element) !== -1) {
359                                         return;
360                                 }
361                                 if (element.parentNode.tagName === oppositeListType) {
362                                         dom.split(element.parentNode, element);
363                                         makeList(element);
364                                         attemptMergeWithNext(element.parentNode, false);
365                                 }
366                                 applied.push(element);
367                         }
368                         
369                         function convertListItemToParagraph(element) {
370                                 var child, nextChild, mergedElement, splitLast;
371                                 if (tinymce.inArray(applied, element) !== -1) {
372                                         return;
373                                 }
374                                 element = splitNestedLists(element, dom);
375                                 while (dom.is(element.parentNode, 'ol,ul,li')) {
376                                         dom.split(element.parentNode, element);
377                                 }
378                                 // Push the original element we have from the selection, not the renamed one.
379                                 applied.push(element);
380                                 element = dom.rename(element, 'p');
381                                 mergedElement = attemptMergeWithAdjacent(element, false, ed.settings.force_br_newlines);
382                                 if (mergedElement === element) {
383                                         // Now split out any block elements that can't be contained within a P.
384                                         // Manually iterate to ensure we handle modifications correctly (doesn't work with tinymce.each)
385                                         child = element.firstChild;
386                                         while (child) {
387                                                 if (dom.isBlock(child)) {
388                                                         child = dom.split(child.parentNode, child);
389                                                         splitLast = true;
390                                                         nextChild = child.nextSibling && child.nextSibling.firstChild; 
391                                                 } else {
392                                                         nextChild = child.nextSibling;
393                                                         if (splitLast && child.tagName === 'BR') {
394                                                                 dom.remove(child);
395                                                         }
396                                                         splitLast = false;
397                                                 }
398                                                 child = nextChild;
399                                         }
400                                 }
401                         }
402                         
403                         each(selectedBlocks, function(e) {
404                                 e = findItemToOperateOn(e, dom);
405                                 if (e.tagName === oppositeListType || (e.tagName === 'LI' && e.parentNode.tagName === oppositeListType)) {
406                                         hasOppositeType = true;
407                                 } else if (e.tagName === targetListType || (e.tagName === 'LI' && e.parentNode.tagName === targetListType)) {
408                                         hasSameType = true;
409                                 } else {
410                                         hasNonList = true;
411                                 }
412                         });
413
414                         if (hasNonList || hasOppositeType || selectedBlocks.length === 0) {
415                                 actions = {
416                                         'LI': changeList,
417                                         'H1': makeList,
418                                         'H2': makeList,
419                                         'H3': makeList,
420                                         'H4': makeList,
421                                         'H5': makeList,
422                                         'H6': makeList,
423                                         'P': makeList,
424                                         'BODY': makeList,
425                                         'DIV': selectedBlocks.length > 1 ? makeList : wrapList,
426                                         defaultAction: wrapList
427                                 };
428                         } else {
429                                 actions = {
430                                         defaultAction: convertListItemToParagraph
431                                 };
432                         }
433                         this.process(actions);
434                 },
435                 
436                 indent: function() {
437                         var ed = this.ed, dom = ed.dom, indented = [];
438                         
439                         function createWrapItem(element) {
440                                 var wrapItem = dom.create('li', { style: 'list-style-type: none;'});
441                                 dom.insertAfter(wrapItem, element);
442                                 return wrapItem;
443                         }
444                         
445                         function createWrapList(element) {
446                                 var wrapItem = createWrapItem(element),
447                                         list = dom.getParent(element, 'ol,ul'),
448                                         listType = list.tagName,
449                                         listStyle = dom.getStyle(list, 'list-style-type'),
450                                         attrs = {},
451                                         wrapList;
452                                 if (listStyle !== '') {
453                                         attrs.style = 'list-style-type: ' + listStyle + ';';
454                                 }
455                                 wrapList = dom.create(listType, attrs);
456                                 wrapItem.appendChild(wrapList);
457                                 return wrapList;
458                         }
459                         
460                         function indentLI(element) {
461                                 if (!hasParentInList(ed, element, indented)) {
462                                         element = splitNestedLists(element, dom);
463                                         var wrapList = createWrapList(element);
464                                         wrapList.appendChild(element);
465                                         attemptMergeWithAdjacent(wrapList.parentNode, false);
466                                         attemptMergeWithAdjacent(wrapList, false);
467                                         indented.push(element);
468                                 }
469                         }
470                         
471                         this.process({
472                                 'LI': indentLI,
473                                 defaultAction: this.adjustPaddingFunction(true)
474                         });
475                         
476                 },
477                 
478                 outdent: function() {
479                         var t = this, ed = t.ed, dom = ed.dom, outdented = [];
480                         
481                         function outdentLI(element) {
482                                 var listElement, targetParent, align;
483                                 if (!hasParentInList(ed, element, outdented)) {
484                                         if (dom.getStyle(element, 'margin-left') !== '' || dom.getStyle(element, 'padding-left') !== '') {
485                                                 return t.adjustPaddingFunction(false)(element);
486                                         }
487                                         align = dom.getStyle(element, 'text-align', true);
488                                         if (align === 'center' || align === 'right') {
489                                                 dom.setStyle(element, 'text-align', 'left');
490                                                 return;
491                                         }
492                                         element = splitNestedLists(element, dom);
493                                         listElement = element.parentNode;
494                                         targetParent = element.parentNode.parentNode;
495                                         if (targetParent.tagName === 'P') {
496                                                 dom.split(targetParent, element.parentNode);
497                                         } else {
498                                                 dom.split(listElement, element);
499                                                 if (targetParent.tagName === 'LI') {
500                                                         // Nested list, need to split the LI and go back out to the OL/UL element.
501                                                         dom.split(targetParent, element);
502                                                 } else if (!dom.is(targetParent, 'ol,ul')) {
503                                                         dom.rename(element, 'p');
504                                                 }
505                                         }
506                                         outdented.push(element);
507                                 }
508                         }
509                         
510                         this.process({
511                                 'LI': outdentLI,
512                                 defaultAction: this.adjustPaddingFunction(false)
513                         });
514                         
515                         each(outdented, attemptMergeWithAdjacent);
516                 },
517                 
518                 process: function(actions) {
519                         var t = this, sel = t.ed.selection, dom = t.ed.dom, selectedBlocks, r;
520                         function processElement(element) {
521                                 dom.removeClass(element, '_mce_act_on');
522                                 if (!element || element.nodeType !== 1) {
523                                         return;
524                                 }
525                                 element = findItemToOperateOn(element, dom);
526                                 var action = actions[element.tagName];
527                                 if (!action) {
528                                         action = actions.defaultAction;
529                                 }
530                                 action(element);
531                         }
532                         function recurse(element) {
533                                 t.splitSafeEach(element.childNodes, processElement);
534                         }
535                         function brAtEdgeOfSelection(container, offset) {
536                                 return offset >= 0 && container.hasChildNodes() && offset < container.childNodes.length &&
537                                                 container.childNodes[offset].tagName === 'BR';
538                         }
539                         selectedBlocks = sel.getSelectedBlocks();
540                         if (selectedBlocks.length === 0) {
541                                 selectedBlocks = [ dom.getRoot() ];
542                         }
543
544                         r = sel.getRng(true);
545                         if (!r.collapsed) {
546                                 if (brAtEdgeOfSelection(r.endContainer, r.endOffset - 1)) {
547                                         r.setEnd(r.endContainer, r.endOffset - 1);
548                                         sel.setRng(r);
549                                 }
550                                 if (brAtEdgeOfSelection(r.startContainer, r.startOffset)) {
551                                         r.setStart(r.startContainer, r.startOffset + 1);
552                                         sel.setRng(r);
553                                 }
554                         }
555                         bookmark = sel.getBookmark();
556                         actions.OL = actions.UL = recurse;
557                         t.splitSafeEach(selectedBlocks, processElement);
558                         sel.moveToBookmark(bookmark);
559                         bookmark = null;
560                         // Avoids table or image handles being left behind in Firefox.
561                         t.ed.execCommand('mceRepaint');
562                 },
563                 
564                 splitSafeEach: function(elements, f) {
565                         if (tinymce.isGecko && (/Firefox\/[12]\.[0-9]/.test(navigator.userAgent) ||
566                                         /Firefox\/3\.[0-4]/.test(navigator.userAgent))) {
567                                 this.classBasedEach(elements, f);
568                         } else {
569                                 each(elements, f);
570                         }
571                 },
572                 
573                 classBasedEach: function(elements, f) {
574                         var dom = this.ed.dom, nodes, element;
575                         // Mark nodes
576                         each(elements, function(element) {
577                                 dom.addClass(element, '_mce_act_on');
578                         });
579                         nodes = dom.select('._mce_act_on');
580                         while (nodes.length > 0) {
581                                 element = nodes.shift();
582                                 dom.removeClass(element, '_mce_act_on');
583                                 f(element);
584                                 nodes = dom.select('._mce_act_on');
585                         }
586                 },
587                 
588                 adjustPaddingFunction: function(isIndent) {
589                         var indentAmount, indentUnits, ed = this.ed;
590                         indentAmount = ed.settings.indentation;
591                         indentUnits = /[a-z%]+/i.exec(indentAmount);
592                         indentAmount = parseInt(indentAmount, 10);
593                         return function(element) {
594                                 var currentIndent, newIndentAmount;
595                                 currentIndent = parseInt(ed.dom.getStyle(element, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(element, 'padding-left') || 0, 10);
596                                 if (isIndent) {
597                                         newIndentAmount = currentIndent + indentAmount;
598                                 } else {
599                                         newIndentAmount = currentIndent - indentAmount;
600                                 }
601                                 ed.dom.setStyle(element, 'padding-left', '');
602                                 ed.dom.setStyle(element, 'margin-left', newIndentAmount > 0 ? newIndentAmount + indentUnits : '');
603                         };
604                 },
605                 
606                 getInfo: function() {
607                         return {
608                                 longname : 'Lists',
609                                 author : 'Moxiecode Systems AB',
610                                 authorurl : 'http://tinymce.moxiecode.com',
611                                 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/lists',
612                                 version : tinymce.majorVersion + "." + tinymce.minorVersion
613                         };
614                 }
615         });
616         tinymce.PluginManager.add("lists", tinymce.plugins.Lists);
617 }());