source: gs3-extensions/seaweed-debug/trunk/src/actions/DemoteItemAction.js@ 25160

Last change on this file since 25160 was 25160, checked in by sjm84, 12 years ago

Initial cut at a version of seaweed for debugging purposes. Check it out live into the web/ext folder

File size: 5.3 KB
Line 
1/*
2 * file: DemoteItemAction.js
3 *
4 * @BEGINLICENSE
5 * Copyright 2010 Brook Novak (email : [email protected])
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 * @ENDLICENSE
18 */
19
20// @DEPENDS: UndoMan
21bootstrap.provides("actions.DemoteItemAction");
22
23_registerAction("DemoteItem", {
24
25 exec : function(startNode, endNode) {
26
27 var t = this;
28
29 // Auto-set range if not provided.
30 if (!startNode) {
31
32 if (!t.selBefore)
33 return; // Nothing to promote
34
35 if (t.selBefore.endNode) {
36 startNode = t.selBeforeOrdered.startNode;
37 endNode = t.selBeforeOrdered.endNode;
38 } else
39 startNode = endNode = t.selBefore.startNode;
40
41 }
42
43 debug.assert(endNode, "Supplied start node but not the end node");
44
45 var ca = _findAncestor(_getCommonAncestor(startNode, endNode, 1), docBody, function(testNode) {
46 var nn = _nodeName(testNode);
47 return nn == "li" || nn == "ol" || nn == "ul";
48 }, 1);
49
50 // Found a list item / list container in the given range?
51 if (ca) {
52
53 // Get all list items in the given range
54 var listItems = [];
55 if (_nodeName(ca) == "li")
56 listItems.push(ca);
57 else {
58 _visitAllNodes(ca, startNode, true, function(domNode){
59 if (_nodeName(domNode) == "li") listItems.push(domNode);
60 return domNode != endNode;
61 });
62 // The traversal above will skip the start node's li
63 var li = _findAncestor(startNode, ca, function(testNode) {return _nodeName(testNode) == "li";}, 1);
64 if (li)
65 listItems.push(li);
66 }
67
68 // TODO: REFACTOR: ALL ABOVE IS IDENTICLE TO PROMOTE ACTION
69
70 // Demote LI: Top => down
71 for (var i in listItems) {
72 demoteLI(listItems[i]);
73 }
74
75 }
76
77 t.selAfter = t.selBefore;
78
79 function demoteLI(li){
80
81 // Can this list item be demoted? Its list container must be within a list container
82 var targetLICon = li.parentNode.parentNode;
83 if (_nodeName(targetLICon) == "ul" || _nodeName(targetLICon) == "ol") {
84
85 // Is there a following list item at the same level
86 var nextLI = li.nextSibling, prevLI = li.previousSibling; // lis, uls or ols,
87 while (prevLI && prevLI.nodeType == Node.TEXT_NODE) {
88 prevLI = prevLI.previousSibling;
89 }
90 while (nextLI && nextLI.nodeType == Node.TEXT_NODE) {
91 nextLI = nextLI.nextSibling;
92 }
93
94 var insertIndex;
95
96 if (nextLI && prevLI) { // List item to demote surrounded by others
97
98 // Split the contain in two
99 var lowerSplit = li.parentNode.cloneNode(false);
100 _execOp(_Operation.INSERT_NODE, lowerSplit, targetLICon, _indexInParent(li.parentNode) + 1);
101
102 // Move following list items into split
103 while (nextLI) {
104 var migrant = nextLI;
105 nextLI = nextLI.nextSibling;
106 _execOp(_Operation.REMOVE_NODE, migrant);
107 _execOp(_Operation.INSERT_NODE, migrant, lowerSplit);
108 }
109
110 insertIndex = _indexInParent(lowerSplit);
111
112 } else if (nextLI) { // List item to demote contains another afterwards
113
114 insertIndex = _indexInParent(li.parentNode);
115
116 } else if (prevLI) { // List item to demote contains another before
117
118 insertIndex = _indexInParent(li.parentNode) + 1;
119
120 } else { // List item to demote on its own
121
122 insertIndex = _indexInParent(li.parentNode);
123
124 // Remove the container
125 _execOp(_Operation.REMOVE_NODE, li.parentNode);
126
127 }
128
129 // Remove the li
130 _execOp(_Operation.REMOVE_NODE, li);
131
132 // Add it to the parent container
133 _execOp(_Operation.INSERT_NODE, li, targetLICon, insertIndex);
134
135 }
136
137 }
138
139 }
140});
141
Note: See TracBrowser for help on using the repository browser.