1 | void (function(){var _ion_runtime_ForInOfStatement_ = function(module,exports,require){'use strict';
|
2 | var ion = require('../'), Statement = require('./Statement'), DynamicExpression = require('./DynamicExpression');
|
3 | var ForInOfStatement = ion.defineClass({
|
4 | name: 'ForInOfStatement',
|
5 | properties: {
|
6 | toKey: function (name) {
|
7 | if (this.type === 'ForOfStatement') {
|
8 | return parseInt(name);
|
9 | } else {
|
10 | return name;
|
11 | }
|
12 | },
|
13 | forEach: function (collection, callback) {
|
14 | if (this.type === 'ForOfStatement') {
|
15 | for (var key = 0; key < collection.length; key++) {
|
16 | var value = collection[key];
|
17 | callback(key, value);
|
18 | }
|
19 | } else {
|
20 | for (var key in collection) {
|
21 | var value = collection[key];
|
22 | callback(key, value);
|
23 | }
|
24 | }
|
25 | },
|
26 | activate: function () {
|
27 | ForInOfStatement.super.prototype.activate.apply(this, arguments);
|
28 | if (!(this.statements != null)) {
|
29 | this.statements = {};
|
30 | this.valueName = this.left.declarations[this.type === 'ForOfStatement' ? 0 : 1] != null ? this.left.declarations[this.type === 'ForOfStatement' ? 0 : 1].id.name : void 0;
|
31 | this.keyName = this.left.declarations[this.type === 'ForOfStatement' ? 1 : 0] != null ? this.left.declarations[this.type === 'ForOfStatement' ? 1 : 0].id.name : void 0;
|
32 | }
|
33 | this.collectionExpression = this.collectionExpression != null ? this.collectionExpression : this.context.createRuntime(this.right);
|
34 | this.collectionExpression.watch(this.collectionWatcher = this.collectionWatcher != null ? this.collectionWatcher : ion.bind(function (collection) {
|
35 | if (this.collection !== collection) {
|
36 | if (this.collection != null) {
|
37 | this.forEach(this.collection, ion.bind(function (key, value) {
|
38 | this.removeItem(key, value);
|
39 | }, this));
|
40 | ion.unobserve(this.collection, this.collectionObserver);
|
41 | }
|
42 | this.collection = collection;
|
43 | if (this.collection != null) {
|
44 | this.forEach(this.collection, ion.bind(function (key, value) {
|
45 | this.addItem(key, value);
|
46 | }, this));
|
47 | ion.observe(this.collection, this.collectionObserver = this.collectionObserver != null ? this.collectionObserver : this.applyChanges.bind(this));
|
48 | }
|
49 | }
|
50 | }, this));
|
51 | },
|
52 | deactivate: function () {
|
53 | ForInOfStatement.super.prototype.deactivate.apply(this, arguments);
|
54 | this.collectionExpression.unwatch(this.collectionWatcher);
|
55 | },
|
56 | addItem: function (key, value, activate) {
|
57 | if (activate == null)
|
58 | activate = true;
|
59 | if (value !== void 0) {
|
60 | var newContext = this.context.newContext();
|
61 | if (this.valueName != null) {
|
62 | newContext.setVariableExpression(this.valueName, new DynamicExpression({ value: value }));
|
63 | }
|
64 | if (this.keyName != null) {
|
65 | newContext.setVariableExpression(this.keyName, new DynamicExpression({ value: key }));
|
66 | }
|
67 | var statement = newContext.createRuntime(this.body);
|
68 | this.statements[key] = statement;
|
69 | if (activate) {
|
70 | statement.activate();
|
71 | }
|
72 | return statement;
|
73 | }
|
74 | },
|
75 | removeItem: function (key, value) {
|
76 | var statement = this.statements[key];
|
77 | if (statement != null) {
|
78 | this.disposeStatement(statement);
|
79 | }
|
80 | delete this.statements[key];
|
81 | return statement;
|
82 | },
|
83 | disposeStatement: function (statement) {
|
84 | if (this.remove != null) {
|
85 | var removeStatement = statement.context.createRuntime(this.remove);
|
86 | removeStatement.activate();
|
87 | }
|
88 | statement.deactivate();
|
89 | },
|
90 | summarize: function (changes) {
|
91 | var ignoreProperty = ion.bind(function (name) {
|
92 | if (!(name != null)) {
|
93 | return true;
|
94 | }
|
95 | if (name[0] === '_') {
|
96 | return true;
|
97 | }
|
98 | if (name === 'length' && this.type === 'ForOfStatement') {
|
99 | return true;
|
100 | }
|
101 | return false;
|
102 | }, this);
|
103 | var map = new Map();
|
104 | for (var _i = 0; _i < changes.length; _i++) {
|
105 | var _ref = changes[_i];
|
106 | var type = _ref.type;
|
107 | var object = _ref.object;
|
108 | var name = _ref.name;
|
109 | var oldValue = _ref.oldValue;
|
110 | if (!ignoreProperty(name)) {
|
111 | if (!map.has(name)) {
|
112 | map.set(name, {
|
113 | type: type,
|
114 | object: object,
|
115 | name: name,
|
116 | oldValue: oldValue
|
117 | });
|
118 | } else {
|
119 | var change = map.get(name);
|
120 | change.type = type;
|
121 | }
|
122 | }
|
123 | }
|
124 | var array = [];
|
125 | map.forEach(function (change, name, object) {
|
126 | var newValue = change.object[name];
|
127 | if (newValue !== change.oldValue) {
|
128 | delete change.object;
|
129 | array.push(change);
|
130 | }
|
131 | });
|
132 | return array;
|
133 | },
|
134 | applyChanges: function (changes) {
|
135 | changes = this.summarize(changes);
|
136 | if (changes.length === 0) {
|
137 | return;
|
138 | }
|
139 | var recyclableStatements = new Map();
|
140 | var getRecycleKey = ion.bind(function (key, value) {
|
141 | return this.type === 'ForOfStatement' ? value : key;
|
142 | }, this);
|
143 | var activateStatements = [];
|
144 | for (var _i2 = 0; _i2 < changes.length; _i2++) {
|
145 | var _ref2 = changes[_i2];
|
146 | var name = _ref2.name;
|
147 | var oldValue = _ref2.oldValue;
|
148 | var key = this.toKey(name);
|
149 | if (oldValue !== void 0) {
|
150 | var rkey = getRecycleKey(key, oldValue);
|
151 | var statement = this.statements[key];
|
152 | if (statement != null) {
|
153 | delete this.statements[key];
|
154 | recyclableStatements.set(rkey, statement);
|
155 | }
|
156 | }
|
157 | }
|
158 | for (var _i3 = 0; _i3 < changes.length; _i3++) {
|
159 | var _ref3 = changes[_i3];
|
160 | var name = _ref3.name;
|
161 | var oldValue = _ref3.oldValue;
|
162 | var newValue = this.collection[name];
|
163 | var key = this.toKey(name);
|
164 | if (newValue !== void 0) {
|
165 | var rkey = getRecycleKey(key, newValue);
|
166 | var statement = recyclableStatements.get(rkey);
|
167 | if (statement != null) {
|
168 | if (this.type === 'ForOfStatement') {
|
169 | if (this.keyName != null) {
|
170 | statement.context.variables[this.keyName].setValue(key);
|
171 | }
|
172 | } else {
|
173 | if (this.valueName != null) {
|
174 | statement.context.variables[this.valueName].setValue(newValue);
|
175 | }
|
176 | }
|
177 | this.statements[key] = statement;
|
178 | recyclableStatements.delete(rkey);
|
179 | } else {
|
180 | statement = this.addItem(key, newValue, false);
|
181 | if (statement != null) {
|
182 | activateStatements.push(statement);
|
183 | }
|
184 | }
|
185 | }
|
186 | }
|
187 | recyclableStatements.forEach(ion.bind(function (statement) {
|
188 | this.disposeStatement(statement);
|
189 | }, this));
|
190 | for (var _i4 = 0; _i4 < activateStatements.length; _i4++) {
|
191 | var statement = activateStatements[_i4];
|
192 | statement.activate();
|
193 | }
|
194 | }
|
195 | }
|
196 | }, Statement);
|
197 | module.exports = exports = ForInOfStatement;
|
198 | }
|
199 | if (typeof require === 'function') {
|
200 | if (require.register)
|
201 | require.register('ion/runtime/ForInOfStatement',_ion_runtime_ForInOfStatement_);
|
202 | else
|
203 | _ion_runtime_ForInOfStatement_.call(this, module, exports, require);
|
204 | }
|
205 | else {
|
206 | _ion_runtime_ForInOfStatement_.call(this);
|
207 | }
|
208 | }).call(this)
|
209 |
|
\ | No newline at end of file |