wip: blocking nested transformations from being pushed on undo stack
[fnpeditor.git] / src / wlxml / extensions / list / list.js
1 define(function(require) {
2
3 'use strict';
4
5
6 var wlxml = require('wlxml/wlxml'),
7     extension = {documentTransformations: [], classMethods: {}};
8
9
10 extension.classMethods['list'] = {
11     itemIndex: function(listItem) {
12         var toret = -1;
13         this.contents('.item').some(function(item, index) {
14             if(item.sameNode(listItem)) {
15                 toret = index;
16                 return true; // break
17             }
18         });
19         return toret;
20     },
21     getItem: function(index) {
22         return this.contents('.item')[index];
23     }
24 }
25
26 extension.documentTransformations.push({
27     name: 'createList',
28     impl: function(params) {          
29         var parent = params.node1.parent(),
30             parentContents = parent.contents(),
31             nodeIndexes = [params.node1.getIndex(), params.node2.getIndex()].sort(),
32             nodesToWrap = [],
33             listNode = params.node1.document.createDocumentNode({tagName: 'div', attrs: {'class': 'list.items'}}),
34             node, i;
35
36         for(i = nodeIndexes[0]; i <= nodeIndexes[1]; i++) {
37             node = parentContents[i];
38             if(node.nodeType === Node.TEXT_NODE) {
39                 node = node.wrapWith({tagName: 'div', attrs: {'class': 'item'}}); //t
40             } else {
41                 node.setClass('item'); //t
42             }
43             nodesToWrap.push(node);
44         }
45
46         var toInsert;
47         if(parent.is('list') && parent.object.itemIndex(nodesToWrap[0]) > 0) { // object api
48             // var prevItem = parent.object.getItem(parent.object.itemIndex(nodesToWrap[0])-1); // object api
49             // prevItem.append(listNode); //t
50             toInsert = listNode.wrapWith({tagName: 'div', attrs: {'class': 'item'}});
51         } else {
52             //nodesToWrap[0].before(listNode); //t
53             toInsert = listNode;
54         }  
55
56         params.node1.before(toInsert);
57
58         nodesToWrap.forEach(function(node) {
59             listNode.append(node); //t
60         });
61     },
62     getChangeRoot: function() {
63         return this.args.node1.parent();
64     },
65     isAllowed: function() {
66         return this.args.node1.parent().sameNode(this.args.node2.parent());
67     }
68 });
69
70 extension.documentTransformations.push({
71     name: 'extractItems',
72     impl: function(params) {
73         params = _.extend({}, {merge: true}, params);
74         var list = params.item1.parent(),
75             indexes = [params.item1.getIndex(), params.item2.getIndex()].sort(),
76             precedingItems = [],
77             extractedItems = [],
78             succeedingItems = [],
79             items = list.contents(), // lub list.object.items()
80             listIsNested = list.parent().is('item'),
81             i;
82         
83         items.forEach(function(item, idx) {
84             if(idx < indexes[0]) {
85                 precedingItems.push(item);
86             }
87             else if(idx >= indexes[0] && idx <= indexes[1]) {
88                 extractedItems.push(item);
89             }
90             else {
91                 succeedingItems.push(item);
92             }
93         });
94
95         var reference = listIsNested ? list.parent() : list;
96         if(succeedingItems.length === 0) {
97             var reference_orig = reference;
98             extractedItems.forEach(function(item) {
99                 reference.after(item); //t
100                 reference = item;
101                 if(!listIsNested) {
102                     item.setClass(null); //t
103                 }
104             });
105             if(precedingItems.length === 0)
106                 reference_orig.detach(); //t
107         } else if(precedingItems.length === 0) {
108             extractedItems.forEach(function(item) {
109                 reference.before(item); //t
110                 if(!listIsNested) {
111                     item.setClass(null); //t
112                 }
113             });
114         } else {
115             extractedItems.forEach(function(item) {
116                 reference.after(item); //t
117                 if(!listIsNested)
118                     item.setClass(null); //t
119                 reference = item;
120             });
121             var secondList = params.item1.document.createDocumentNode({tagName: 'div', attrs: {'class':'list'}}),
122                 toAdd = secondList;
123             
124             if(listIsNested) {
125                 toAdd = secondList.wrapWith({tagName: 'div', attrs: {'class':'item'}});
126             }
127             succeedingItems.forEach(function(item) {
128                 secondList.append(item);
129             });
130
131             reference.after(toAdd);
132         }
133         if(!params.merge && listIsNested) {
134             debugger;
135             return this.transform('extractItems', {item1: extractedItems[0], item2: extractedItems[extractedItems.length-1]});
136         }
137         return true;
138     },
139     isAllowed: function() {
140         var parent = this.args.nodel1.parent();
141         return parent.is('list') && parent.sameNode(this.args.node2.parent());
142     }
143 });
144
145 wlxml.registerExtension(extension);
146
147 });