diff options
Diffstat (limited to 'node_modules/montage/core/event/mutable-event.js')
-rwxr-xr-x | node_modules/montage/core/event/mutable-event.js | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/node_modules/montage/core/event/mutable-event.js b/node_modules/montage/core/event/mutable-event.js new file mode 100755 index 00000000..edf56951 --- /dev/null +++ b/node_modules/montage/core/event/mutable-event.js | |||
@@ -0,0 +1,234 @@ | |||
1 | /* <copyright> | ||
2 | This file contains proprietary software owned by Motorola Mobility, Inc.<br/> | ||
3 | No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> | ||
4 | (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. | ||
5 | </copyright> */ | ||
6 | /** | ||
7 | @module montage/core/event/mutable-event | ||
8 | @requires montage | ||
9 | @requires montage/core/enum | ||
10 | */ | ||
11 | var Montage = require("montage").Montage, | ||
12 | Enum = require("core/enum").Enum; | ||
13 | |||
14 | var ChangeTypes = exports.ChangeTypes = Enum.create().initWithMembers("MODIFICATION", "ADDITION", "REMOVAL"); | ||
15 | |||
16 | var _eventConstructorsByType = {}; | ||
17 | var _changeEventConstructor = null; | ||
18 | var nullDescriptor = {value: null}; | ||
19 | |||
20 | var wrapProperty = function(obj, key) { | ||
21 | |||
22 | var storageKey = "_" + key; | ||
23 | |||
24 | Montage.defineProperty(obj, storageKey, {value: undefined}); | ||
25 | |||
26 | Montage.defineProperty(obj, key, { | ||
27 | get:(function(key, storageKey) { | ||
28 | return function() { | ||
29 | return this.hasOwnProperty(storageKey) ? this[storageKey] : (this._event ? this._event[key] : undefined); | ||
30 | }; | ||
31 | })(key, storageKey), | ||
32 | |||
33 | set: (function(storageKey) { | ||
34 | return function(value) { | ||
35 | this[storageKey] = value; | ||
36 | }; | ||
37 | })(storageKey) | ||
38 | }); | ||
39 | }; | ||
40 | /** | ||
41 | @class module:montage/core/event/mutable-event.MutableEvent | ||
42 | */ | ||
43 | var MutableEvent = exports.MutableEvent = Montage.create(Montage,/** @lends module:montage/core/event/mutable-event.MutableEvent# */ { | ||
44 | /** | ||
45 | @function | ||
46 | @param {Event} event The original event. | ||
47 | @returns newEvent | ||
48 | */ | ||
49 | fromEvent: { | ||
50 | value: function(event) { | ||
51 | var type = event.type, | ||
52 | constructor = _eventConstructorsByType[type], | ||
53 | newEvent; | ||
54 | if (!constructor) { | ||
55 | constructor = function() { | ||
56 | }; | ||
57 | constructor.prototype = MutableEvent.create()._initPrototypeWithEvent(event); | ||
58 | _eventConstructorsByType[type] = constructor; | ||
59 | } | ||
60 | newEvent = new constructor(); | ||
61 | newEvent._initWithEvent(event); | ||
62 | return newEvent; | ||
63 | } | ||
64 | }, | ||
65 | |||
66 | // Same arguments as initEvent & initCustomEvent | ||
67 | |||
68 | /** | ||
69 | @function | ||
70 | @param {Event} type TODO | ||
71 | @param {Event} canBubbleArg TODO | ||
72 | @param {Event} cancelableArg TODO | ||
73 | @param {Event} data TODO | ||
74 | @returns this.fromEvent(anEvent) | ||
75 | */ | ||
76 | fromType: { | ||
77 | value: function(type, canBubbleArg, cancelableArg, data) { | ||
78 | var anEvent = document.createEvent("CustomEvent"); | ||
79 | anEvent.initEvent(type, canBubbleArg, cancelableArg, data); | ||
80 | return this.fromEvent(anEvent); | ||
81 | } | ||
82 | }, | ||
83 | |||
84 | /** | ||
85 | @function | ||
86 | @returns new _changeEventConstructor() | ||
87 | */ | ||
88 | changeEvent: { | ||
89 | value: function() { | ||
90 | return new _changeEventConstructor(); | ||
91 | } | ||
92 | }, | ||
93 | |||
94 | /** | ||
95 | @function | ||
96 | @param {Event} key TODO | ||
97 | @param {Event} minus TODO | ||
98 | @returns changeEvent | ||
99 | */ | ||
100 | changeEventForKeyAndValue: { | ||
101 | value: function(key, minus) { | ||
102 | var changeEvent = new _changeEventConstructor(); | ||
103 | changeEvent.type = "change@" + key; | ||
104 | changeEvent.minus = minus; | ||
105 | changeEvent.propertyChange = ChangeTypes.MODIFICATION; | ||
106 | return changeEvent; | ||
107 | } | ||
108 | }, | ||
109 | |||
110 | /** | ||
111 | @function | ||
112 | @param {String} plus TODO | ||
113 | @returns itself | ||
114 | */ | ||
115 | withPlusValue: { | ||
116 | value: function(plus) { | ||
117 | this.plus = plus; | ||
118 | return this; | ||
119 | } | ||
120 | }, | ||
121 | /** | ||
122 | @private | ||
123 | */ | ||
124 | _initPrototypeWithEvent: { | ||
125 | value: function(event) { | ||
126 | var key; | ||
127 | |||
128 | for (key in event) { | ||
129 | |||
130 | // Don't overwrite keys we have installed | ||
131 | if (this[key]) { | ||
132 | continue; | ||
133 | } | ||
134 | |||
135 | // Skip methods, the ones we care about have been wrapped already | ||
136 | // TODO actually wrap all known functions generically | ||
137 | //if (typeof this[key] === "function") { | ||
138 | // continue; | ||
139 | //} | ||
140 | |||
141 | // TODO ok, maybe it would be quicker to not make this a function, but I really hate duplicated code | ||
142 | wrapProperty(this, key); | ||
143 | } | ||
144 | |||
145 | wrapProperty(this, "replayed"); | ||
146 | |||
147 | return this; | ||
148 | } | ||
149 | }, | ||
150 | /** | ||
151 | @private | ||
152 | */ | ||
153 | _initWithEvent: { | ||
154 | value: function(event) { | ||
155 | this._event = event; | ||
156 | return this; | ||
157 | } | ||
158 | }, | ||
159 | /** | ||
160 | @function | ||
161 | */ | ||
162 | preventDefault: { | ||
163 | value: function() { | ||
164 | this._event.preventDefault(); | ||
165 | } | ||
166 | }, | ||
167 | /** | ||
168 | @function | ||
169 | */ | ||
170 | stopImmediatePropagation: { | ||
171 | value: function() { | ||
172 | this._event.stopImmediatePropagation(); | ||
173 | // TODO only if the event is cancellable? | ||
174 | this.propagationStopped = true; | ||
175 | } | ||
176 | }, | ||
177 | /** | ||
178 | @type {Property} | ||
179 | @default {Boolean} false | ||
180 | */ | ||
181 | propagationStopped: { | ||
182 | value: false | ||
183 | }, | ||
184 | /** | ||
185 | @type {Property} | ||
186 | @default {Boolean} true | ||
187 | */ | ||
188 | mutable: { | ||
189 | value: true | ||
190 | }, | ||
191 | /** | ||
192 | @type {Property} | ||
193 | @default {Element} null | ||
194 | */ | ||
195 | target: { | ||
196 | value: null | ||
197 | }, | ||
198 | /** | ||
199 | @function | ||
200 | */ | ||
201 | stopPropagation: { | ||
202 | value: function() { | ||
203 | this._event.stopPropagation(); | ||
204 | // TODO only if the event is cancellable? | ||
205 | this.propagationStopped = true; | ||
206 | } | ||
207 | }, | ||
208 | /** | ||
209 | @function | ||
210 | */ | ||
211 | stop: { | ||
212 | value: function() { | ||
213 | this.preventDefault(); | ||
214 | this.stopPropagation(); | ||
215 | } | ||
216 | } | ||
217 | |||
218 | }); | ||
219 | /** | ||
220 | @private | ||
221 | */ | ||
222 | _changeEventConstructor = function() { | ||
223 | }; | ||
224 | /** | ||
225 | @private | ||
226 | */ | ||
227 | _changeEventConstructor.prototype = MutableEvent.create()._initPrototypeWithEvent(document.createEvent("CustomEvent").initCustomEvent("change", true, false, null)); | ||
228 | // TODO this shouldn't be necessary; initWithCustomEvent should be setting the type to "change" but that doesn't seem to be the case | ||
229 | // TODO should file a bug on this with some test reduction | ||
230 | /** | ||
231 | @private | ||