|
1 /* |
|
2 YUI 3.10.3 (build 2fb5187) |
|
3 Copyright 2013 Yahoo! Inc. All rights reserved. |
|
4 Licensed under the BSD License. |
|
5 http://yuilibrary.com/license/ |
|
6 */ |
|
7 |
|
8 (function() { |
|
9 |
|
10 var stateChangeListener, |
|
11 GLOBAL_ENV = YUI.Env, |
|
12 config = YUI.config, |
|
13 doc = config.doc, |
|
14 docElement = doc && doc.documentElement, |
|
15 EVENT_NAME = 'onreadystatechange', |
|
16 pollInterval = config.pollInterval || 40; |
|
17 |
|
18 if (docElement.doScroll && !GLOBAL_ENV._ieready) { |
|
19 GLOBAL_ENV._ieready = function() { |
|
20 GLOBAL_ENV._ready(); |
|
21 }; |
|
22 |
|
23 /*! DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller/Diego Perini */ |
|
24 // Internet Explorer: use the doScroll() method on the root element. |
|
25 // This isolates what appears to be a safe moment to manipulate the |
|
26 // DOM prior to when the document's readyState suggests it is safe to do so. |
|
27 if (self !== self.top) { |
|
28 stateChangeListener = function() { |
|
29 if (doc.readyState == 'complete') { |
|
30 GLOBAL_ENV.remove(doc, EVENT_NAME, stateChangeListener); |
|
31 GLOBAL_ENV.ieready(); |
|
32 } |
|
33 }; |
|
34 GLOBAL_ENV.add(doc, EVENT_NAME, stateChangeListener); |
|
35 } else { |
|
36 GLOBAL_ENV._dri = setInterval(function() { |
|
37 try { |
|
38 docElement.doScroll('left'); |
|
39 clearInterval(GLOBAL_ENV._dri); |
|
40 GLOBAL_ENV._dri = null; |
|
41 GLOBAL_ENV._ieready(); |
|
42 } catch (domNotReady) { } |
|
43 }, pollInterval); |
|
44 } |
|
45 } |
|
46 |
|
47 })(); |
|
48 YUI.add('event-base-ie', function (Y, NAME) { |
|
49 |
|
50 /* |
|
51 * Custom event engine, DOM event listener abstraction layer, synthetic DOM |
|
52 * events. |
|
53 * @module event |
|
54 * @submodule event-base |
|
55 */ |
|
56 |
|
57 function IEEventFacade() { |
|
58 // IEEventFacade.superclass.constructor.apply(this, arguments); |
|
59 Y.DOM2EventFacade.apply(this, arguments); |
|
60 } |
|
61 |
|
62 /* |
|
63 * (intentially left out of API docs) |
|
64 * Alternate Facade implementation that is based on Object.defineProperty, which |
|
65 * is partially supported in IE8. Properties that involve setup work are |
|
66 * deferred to temporary getters using the static _define method. |
|
67 */ |
|
68 function IELazyFacade(e) { |
|
69 var proxy = Y.config.doc.createEventObject(e), |
|
70 proto = IELazyFacade.prototype; |
|
71 |
|
72 // TODO: necessary? |
|
73 proxy.hasOwnProperty = function () { return true; }; |
|
74 |
|
75 proxy.init = proto.init; |
|
76 proxy.halt = proto.halt; |
|
77 proxy.preventDefault = proto.preventDefault; |
|
78 proxy.stopPropagation = proto.stopPropagation; |
|
79 proxy.stopImmediatePropagation = proto.stopImmediatePropagation; |
|
80 |
|
81 Y.DOM2EventFacade.apply(proxy, arguments); |
|
82 |
|
83 return proxy; |
|
84 } |
|
85 |
|
86 |
|
87 var imp = Y.config.doc && Y.config.doc.implementation, |
|
88 useLazyFacade = Y.config.lazyEventFacade, |
|
89 |
|
90 buttonMap = { |
|
91 0: 1, // left click |
|
92 4: 2, // middle click |
|
93 2: 3 // right click |
|
94 }, |
|
95 relatedTargetMap = { |
|
96 mouseout: 'toElement', |
|
97 mouseover: 'fromElement' |
|
98 }, |
|
99 |
|
100 resolve = Y.DOM2EventFacade.resolve, |
|
101 |
|
102 proto = { |
|
103 init: function() { |
|
104 |
|
105 IEEventFacade.superclass.init.apply(this, arguments); |
|
106 |
|
107 var e = this._event, |
|
108 x, y, d, b, de, t; |
|
109 |
|
110 this.target = resolve(e.srcElement); |
|
111 |
|
112 if (('clientX' in e) && (!x) && (0 !== x)) { |
|
113 x = e.clientX; |
|
114 y = e.clientY; |
|
115 |
|
116 d = Y.config.doc; |
|
117 b = d.body; |
|
118 de = d.documentElement; |
|
119 |
|
120 x += (de.scrollLeft || (b && b.scrollLeft) || 0); |
|
121 y += (de.scrollTop || (b && b.scrollTop) || 0); |
|
122 |
|
123 this.pageX = x; |
|
124 this.pageY = y; |
|
125 } |
|
126 |
|
127 if (e.type == "mouseout") { |
|
128 t = e.toElement; |
|
129 } else if (e.type == "mouseover") { |
|
130 t = e.fromElement; |
|
131 } |
|
132 |
|
133 // fallback to t.relatedTarget to support simulated events. |
|
134 // IE doesn't support setting toElement or fromElement on generic |
|
135 // events, so Y.Event.simulate sets relatedTarget instead. |
|
136 this.relatedTarget = resolve(t || e.relatedTarget); |
|
137 |
|
138 // which should contain the unicode key code if this is a key event. |
|
139 // For click events, which is normalized for which mouse button was |
|
140 // clicked. |
|
141 this.which = // chained assignment |
|
142 this.button = e.keyCode || buttonMap[e.button] || e.button; |
|
143 }, |
|
144 |
|
145 stopPropagation: function() { |
|
146 this._event.cancelBubble = true; |
|
147 this._wrapper.stopped = 1; |
|
148 this.stopped = 1; |
|
149 }, |
|
150 |
|
151 stopImmediatePropagation: function() { |
|
152 this.stopPropagation(); |
|
153 this._wrapper.stopped = 2; |
|
154 this.stopped = 2; |
|
155 }, |
|
156 |
|
157 preventDefault: function(returnValue) { |
|
158 this._event.returnValue = returnValue || false; |
|
159 this._wrapper.prevented = 1; |
|
160 this.prevented = 1; |
|
161 } |
|
162 }; |
|
163 |
|
164 Y.extend(IEEventFacade, Y.DOM2EventFacade, proto); |
|
165 |
|
166 Y.extend(IELazyFacade, Y.DOM2EventFacade, proto); |
|
167 IELazyFacade.prototype.init = function () { |
|
168 var e = this._event, |
|
169 overrides = this._wrapper.overrides, |
|
170 define = IELazyFacade._define, |
|
171 lazyProperties = IELazyFacade._lazyProperties, |
|
172 prop; |
|
173 |
|
174 this.altKey = e.altKey; |
|
175 this.ctrlKey = e.ctrlKey; |
|
176 this.metaKey = e.metaKey; |
|
177 this.shiftKey = e.shiftKey; |
|
178 this.type = (overrides && overrides.type) || e.type; |
|
179 this.clientX = e.clientX; |
|
180 this.clientY = e.clientY; |
|
181 this.keyCode = // chained assignment |
|
182 this.charCode = e.keyCode; |
|
183 this.which = // chained assignment |
|
184 this.button = e.keyCode || buttonMap[e.button] || e.button; |
|
185 |
|
186 for (prop in lazyProperties) { |
|
187 if (lazyProperties.hasOwnProperty(prop)) { |
|
188 define(this, prop, lazyProperties[prop]); |
|
189 } |
|
190 } |
|
191 |
|
192 if (this._touch) { |
|
193 this._touch(e, this._currentTarget, this._wrapper); |
|
194 } |
|
195 }; |
|
196 |
|
197 IELazyFacade._lazyProperties = { |
|
198 target: function () { |
|
199 return resolve(this._event.srcElement); |
|
200 }, |
|
201 relatedTarget: function () { |
|
202 var e = this._event, |
|
203 targetProp = relatedTargetMap[e.type] || 'relatedTarget'; |
|
204 |
|
205 // fallback to t.relatedTarget to support simulated events. |
|
206 // IE doesn't support setting toElement or fromElement on generic |
|
207 // events, so Y.Event.simulate sets relatedTarget instead. |
|
208 return resolve(e[targetProp] || e.relatedTarget); |
|
209 }, |
|
210 currentTarget: function () { |
|
211 return resolve(this._currentTarget); |
|
212 }, |
|
213 |
|
214 wheelDelta: function () { |
|
215 var e = this._event; |
|
216 |
|
217 if (e.type === "mousewheel" || e.type === "DOMMouseScroll") { |
|
218 return (e.detail) ? |
|
219 (e.detail * -1) : |
|
220 // wheelDelta between -80 and 80 result in -1 or 1 |
|
221 Math.round(e.wheelDelta / 80) || ((e.wheelDelta < 0) ? -1 : 1); |
|
222 } |
|
223 }, |
|
224 |
|
225 pageX: function () { |
|
226 var e = this._event, |
|
227 val = e.pageX, |
|
228 doc, bodyScroll, docScroll; |
|
229 |
|
230 if (val === undefined) { |
|
231 doc = Y.config.doc; |
|
232 bodyScroll = doc.body && doc.body.scrollLeft; |
|
233 docScroll = doc.documentElement.scrollLeft; |
|
234 |
|
235 val = e.clientX + (docScroll || bodyScroll || 0); |
|
236 } |
|
237 |
|
238 return val; |
|
239 }, |
|
240 pageY: function () { |
|
241 var e = this._event, |
|
242 val = e.pageY, |
|
243 doc, bodyScroll, docScroll; |
|
244 |
|
245 if (val === undefined) { |
|
246 doc = Y.config.doc; |
|
247 bodyScroll = doc.body && doc.body.scrollTop; |
|
248 docScroll = doc.documentElement.scrollTop; |
|
249 |
|
250 val = e.clientY + (docScroll || bodyScroll || 0); |
|
251 } |
|
252 |
|
253 return val; |
|
254 } |
|
255 }; |
|
256 |
|
257 |
|
258 /** |
|
259 * Wrapper function for Object.defineProperty that creates a property whose |
|
260 * value will be calulated only when asked for. After calculating the value, |
|
261 * the getter wll be removed, so it will behave as a normal property beyond that |
|
262 * point. A setter is also assigned so assigning to the property will clear |
|
263 * the getter, so foo.prop = 'a'; foo.prop; won't trigger the getter, |
|
264 * overwriting value 'a'. |
|
265 * |
|
266 * Used only by the DOMEventFacades used by IE8 when the YUI configuration |
|
267 * <code>lazyEventFacade</code> is set to true. |
|
268 * |
|
269 * @method _define |
|
270 * @param o {DOMObject} A DOM object to add the property to |
|
271 * @param prop {String} The name of the new property |
|
272 * @param valueFn {Function} The function that will return the initial, default |
|
273 * value for the property. |
|
274 * @static |
|
275 * @private |
|
276 */ |
|
277 IELazyFacade._define = function (o, prop, valueFn) { |
|
278 function val(v) { |
|
279 var ret = (arguments.length) ? v : valueFn.call(this); |
|
280 |
|
281 delete o[prop]; |
|
282 Object.defineProperty(o, prop, { |
|
283 value: ret, |
|
284 configurable: true, |
|
285 writable: true |
|
286 }); |
|
287 return ret; |
|
288 } |
|
289 Object.defineProperty(o, prop, { |
|
290 get: val, |
|
291 set: val, |
|
292 configurable: true |
|
293 }); |
|
294 }; |
|
295 |
|
296 if (imp && (!imp.hasFeature('Events', '2.0'))) { |
|
297 if (useLazyFacade) { |
|
298 // Make sure we can use the lazy facade logic |
|
299 try { |
|
300 Object.defineProperty(Y.config.doc.createEventObject(), 'z', {}); |
|
301 } catch (e) { |
|
302 useLazyFacade = false; |
|
303 } |
|
304 } |
|
305 |
|
306 Y.DOMEventFacade = (useLazyFacade) ? IELazyFacade : IEEventFacade; |
|
307 } |
|
308 |
|
309 |
|
310 }, '3.10.3', {"requires": ["node-base"]}); |