diff options
author | Jose Antonio Marquez | 2012-05-16 15:42:37 -0700 |
---|---|---|
committer | Jose Antonio Marquez | 2012-05-16 15:42:37 -0700 |
commit | 857aafee732b6a85fa155ff4a05d1b8fde48f09d (patch) | |
tree | e06d330caee280aa05aec46391979e9abdcf974c /node_modules/montage/ui/repetition.reel/repetition.js | |
parent | 5cc5d29736d8bf253e3a168cdd6443e839ffb23c (diff) | |
parent | fd54dabad7cbc27a0efb0957155c00d578912909 (diff) | |
download | ninja-857aafee732b6a85fa155ff4a05d1b8fde48f09d.tar.gz |
Merge branch 'refs/heads/Ninja-DOM-Architecture' into Document
Diffstat (limited to 'node_modules/montage/ui/repetition.reel/repetition.js')
-rwxr-xr-x | node_modules/montage/ui/repetition.reel/repetition.js | 711 |
1 files changed, 512 insertions, 199 deletions
diff --git a/node_modules/montage/ui/repetition.reel/repetition.js b/node_modules/montage/ui/repetition.reel/repetition.js index 95790bc3..c278e84d 100755 --- a/node_modules/montage/ui/repetition.reel/repetition.js +++ b/node_modules/montage/ui/repetition.reel/repetition.js | |||
@@ -16,7 +16,106 @@ var Montage = require("montage").Montage, | |||
16 | Template = require("ui/template").Template, | 16 | Template = require("ui/template").Template, |
17 | logger = require("core/logger").logger("repetition"), | 17 | logger = require("core/logger").logger("repetition"), |
18 | Gate = require("core/gate").Gate, | 18 | Gate = require("core/gate").Gate, |
19 | ChangeTypeModification = require("core/event/mutable-event").ChangeTypes.MODIFICATION; | 19 | ChangeNotification = require("core/change-notification").ChangeNotification, |
20 | PropertyChangeNotification = require("core/change-notification").PropertyChangeNotification; | ||
21 | |||
22 | var FakeObjects = Montage.create(Object.prototype, { | ||
23 | _repetition: {value: null}, | ||
24 | _fakeIndex: {value: null}, | ||
25 | _unusedIndexes: {value: null}, | ||
26 | |||
27 | initWithRepetition: { | ||
28 | value: function(repetition) { | ||
29 | this._repetition = repetition; | ||
30 | this._fakeIndex = []; | ||
31 | this._unusedIndexes = []; | ||
32 | return this; | ||
33 | } | ||
34 | }, | ||
35 | |||
36 | automaticallyDispatchPropertyChangeListener: { | ||
37 | value: function() { | ||
38 | return false; | ||
39 | } | ||
40 | }, | ||
41 | |||
42 | undefinedGet: { | ||
43 | value: function(propertyName) { | ||
44 | if (this._repetition.objects) { | ||
45 | return this._repetition.objects[this._fakeIndex.indexOf(propertyName)]; | ||
46 | } | ||
47 | } | ||
48 | }, | ||
49 | |||
50 | // This is to catch a two-way binding on | ||
51 | "0": { | ||
52 | // This is to catch two way bindings | ||
53 | set: function() { | ||
54 | throw("You cannot use a two-way binding on the \"objectAtCurrentIteration\" or \"current\" property."); | ||
55 | }, | ||
56 | get: function() { | ||
57 | if (this._repetition.objects) { | ||
58 | return this._repetition.objects[this._fakeIndex.indexOf("0")]; | ||
59 | } | ||
60 | } | ||
61 | }, | ||
62 | |||
63 | addFakeObjectAtPosition: { | ||
64 | value: function(position) { | ||
65 | var index; | ||
66 | |||
67 | if (this._unusedIndexes.length > 0) { | ||
68 | index = this._unusedIndexes.pop(); | ||
69 | } else { | ||
70 | index = String(this._fakeIndex.length); | ||
71 | } | ||
72 | |||
73 | this._fakeIndex.splice(position, 0, index); | ||
74 | return index; | ||
75 | } | ||
76 | }, | ||
77 | resetFakeObjects: { | ||
78 | value: function() { | ||
79 | var objects = this._repetition.objects; | ||
80 | |||
81 | this._fakeIndex.length = 0; | ||
82 | if (objects) { | ||
83 | for (var i = 0, l = objects.length; i < l; i++) { | ||
84 | this._fakeIndex[i] = String(i); | ||
85 | } | ||
86 | } | ||
87 | } | ||
88 | }, | ||
89 | removeFakeObjectAtPosition: { | ||
90 | value: function(position) { | ||
91 | var index; | ||
92 | |||
93 | this._unusedIndexes.unshift(this._fakeIndex.splice(position, 1)[0]); | ||
94 | |||
95 | return this._unusedIndexes[0]; | ||
96 | } | ||
97 | }, | ||
98 | _dispatchFakePropertyChange: { | ||
99 | value: function(propertyName, minus) { | ||
100 | var descriptor, | ||
101 | notification; | ||
102 | |||
103 | descriptor = ChangeNotification.getPropertyChangeDescriptor(this, propertyName); | ||
104 | if (descriptor) { | ||
105 | notification = Object.create(PropertyChangeNotification); | ||
106 | |||
107 | notification.target = this; | ||
108 | notification.propertyPath = propertyName; | ||
109 | notification.minus = minus; | ||
110 | notification.plus = this.undefinedGet(propertyName); | ||
111 | if (minus !== notification.plus) { | ||
112 | descriptor.handleChange(notification); | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | }); | ||
118 | |||
20 | /** | 119 | /** |
21 | @class module:"montage/ui/repetition.reel".Repetition | 120 | @class module:"montage/ui/repetition.reel".Repetition |
22 | @extends module:montage/ui/component.Component | 121 | @extends module:montage/ui/component.Component |
@@ -29,24 +128,72 @@ var Repetition = exports.Repetition = Montage.create(Component, /** @lends modul | |||
29 | 128 | ||
30 | didCreate: { | 129 | didCreate: { |
31 | value: function() { | 130 | value: function() { |
32 | this.addEventListener("change@objects", this._onObjectsChange, false); | 131 | var self = this; |
132 | |||
133 | this.addPropertyChangeListener("objects", this); | ||
134 | this._fakeObjects = Object.create(FakeObjects).initWithRepetition(this); | ||
33 | } | 135 | } |
34 | }, | 136 | }, |
35 | 137 | ||
36 | _onObjectsChange: { | 138 | _emptyFunction: {value: function(){}}, |
37 | enumerable: false, | 139 | |
38 | value: function(event) { | 140 | _updateItems: { |
39 | if(event._event.propertyChange !== ChangeTypeModification) { | 141 | value: function(minus, plus, index) { |
40 | this.selectedIndexes = null; | 142 | var fakeObjects = this._fakeObjects, |
41 | this._mappedObjects = null; | 143 | fakeIndex, |
144 | minusCount = minus ? minus.length : 0, | ||
145 | plusCount = plus ? plus.length : 0, | ||
146 | max, min, delta; | ||
147 | |||
148 | max = Math.max(minusCount, plusCount); | ||
149 | min = Math.min(minusCount, plusCount); | ||
150 | delta = plusCount - minusCount; | ||
151 | |||
152 | //console.log("Going to change " + min + " iterations", fakeObjects._fakeIndex); | ||
42 | 153 | ||
43 | if (this._isComponentExpanded) { | 154 | // send updates for the elements that were just replaced by new ones |
44 | this._refreshItems(); | 155 | for (var i = 0; i < min; i++) { |
156 | //console.log("Going to change " + (index+i), minus[index+i]); | ||
157 | fakeObjects._dispatchFakePropertyChange(fakeObjects._fakeIndex[index+i], minus[index+i]); | ||
158 | } | ||
159 | |||
160 | // add new objects, no need to send updates on this one, they're new! | ||
161 | if (delta > 0) { | ||
162 | //console.log("Going to add " + (max-i) + " iterations"); | ||
163 | this._expectedChildComponentsCount += (this._iterationChildComponentsCount||1) * delta; | ||
164 | this.canDrawGate.setField("iterationLoaded", false); | ||
165 | for (; i < max; i++) { | ||
166 | //console.log("New item " + (index+i) + " " + plus[index+i].uuid); | ||
167 | fakeObjects.addFakeObjectAtPosition(index + i); | ||
168 | this._addItem({index: index + i, insertionIndex: index + i}); | ||
45 | } | 169 | } |
170 | } else if (delta < 0) { // remove elements and send updates | ||
171 | //console.log("Going to remove " + (max-i) + " iterations"); | ||
172 | // this index is fixed because we're changing the array at each iteration of the for loop | ||
173 | removeIndex = index + min; | ||
174 | for (; i < max; i++) { | ||
175 | //console.log("Going to remove " + (index+i), minus[i], min); | ||
176 | fakeIndex = fakeObjects.removeFakeObjectAtPosition(removeIndex); | ||
177 | fakeObjects._dispatchFakePropertyChange(fakeIndex, minus[i]); | ||
178 | this._deleteItem(removeIndex); | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | }, | ||
183 | |||
184 | handleChange: { | ||
185 | enumerable: false, | ||
186 | value: function(notification) { | ||
187 | if (this._isComponentExpanded) { | ||
188 | this._updateItems(notification.minus, notification.plus, notification.index || 0); | ||
46 | } | 189 | } |
47 | } | 190 | } |
48 | }, | 191 | }, |
49 | 192 | ||
193 | _fakeObjects: { | ||
194 | value: null | ||
195 | }, | ||
196 | |||
50 | /** | 197 | /** |
51 | @private | 198 | @private |
52 | */ | 199 | */ |
@@ -182,15 +329,15 @@ var Repetition = exports.Repetition = Montage.create(Component, /** @lends modul | |||
182 | @default null | 329 | @default null |
183 | */ | 330 | */ |
184 | objects: { | 331 | objects: { |
185 | dependencies: ["indexMap"], | 332 | dependencies: ["indexMap", "indexMapEnabled"], |
186 | enumerable: false, | 333 | enumerable: false, |
187 | get: function() { | 334 | get: function() { |
188 |