Changeset 7270
- Timestamp:
- 08/04/07 07:20:45 (3 years ago)
- Files:
-
- spinoffs/prototype/trunk/CHANGELOG (modified) (1 diff)
- spinoffs/prototype/trunk/src/dom.js (modified) (15 diffs)
- spinoffs/prototype/trunk/src/event.js (modified) (3 diffs)
- spinoffs/prototype/trunk/test/lib/unittest.js (modified) (1 diff)
- spinoffs/prototype/trunk/test/unit/event.html (copied) (copied from spinoffs/prototype/branches/1-6-0-events/test/unit/event.html)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
spinoffs/prototype/trunk/CHANGELOG
r7265 r7270 1 1 *SVN* 2 3 * Make the eventName and handler arguments to Event.stopObserving optional. If no handler is specified, all handlers for the given event are unregistered. If no event name is specified, all observed events on the element are unregistered. [sam] 4 5 * Add cross-support for the DOMContentLoaded event through a Prototype custom event on document called "contentloaded". The DOMContentLoaded event fires before window.load, when the entire HTML document, but not necessarily its images, stylesheets or other assets, has loaded. Based on [6596]. [sam, Mislav MarohniÄ] 6 Example: 7 document.observe("contentloaded", function() { 8 $$("a").invoke("identify"); // give all <a> tags an ID 9 }); 10 11 * Add Event.fire and Element.Methods.fire for firing custom events. Prototype custom events piggyback on a real DOM event ("ondataavailable"), so they bubble and cancel. You can fire custom events from any element, or fire global events on the document object. Observe custom events just as you'd observe a regular DOM event. [sam, Seth Dillingham] 12 13 * Extend the event object with methods from Event.Methods and normalize it in IE. [sam, Mislav MarohniÄ] 14 15 * Remove support for observing the capturing phase of DOM events, since we can't support it in all browsers. [sam] 2 16 3 17 * Add Ajax.Response object which supports the following methods: responseJSON, headerJSON, getHeader, getAllHeaders and handles browser discrepancies in the other response methods. Add sanitizeJSON, evalJS and evalJSON to Ajax.Request. Closes #8122, #8006, #7295. [Tobie Langel] spinoffs/prototype/trunk/src/dom.js
r7231 r7270 23 23 /*--------------------------------------------------------------------------*/ 24 24 25 if (!window.Node) 26 var Node = { }; 27 28 Object.extend(Node, { 29 ELEMENT_NODE: 1, 30 ATTRIBUTE_NODE: 2, 31 TEXT_NODE: 3, 32 CDATA_SECTION_NODE: 4, 33 ENTITY_REFERENCE_NODE: 5, 34 ENTITY_NODE: 6, 35 PROCESSING_INSTRUCTION_NODE: 7, 36 COMMENT_NODE: 8, 37 DOCUMENT_NODE: 9, 38 DOCUMENT_TYPE_NODE: 10, 39 DOCUMENT_FRAGMENT_NODE: 11, 40 NOTATION_NODE: 12 41 }); 42 25 43 (function() { 26 44 var element = this.Element; 27 45 this.Element = function(tagName, attributes) { 28 attributes = attributes || { };46 attributes = attributes || { }; 29 47 tagName = tagName.toLowerCase(); 30 48 var cache = Element.cache; … … 37 55 return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); 38 56 }; 39 Object.extend(this.Element, element || { });57 Object.extend(this.Element, element || { }); 40 58 }).call(window); 41 59 42 Element.cache = { };60 Element.cache = { }; 43 61 44 62 Element.Methods = { … … 128 146 element = $(element); 129 147 if (Object.isElement(wrapper)) 130 $(wrapper).writeAttribute(attributes || { });148 $(wrapper).writeAttribute(attributes || { }); 131 149 else if (typeof wrapper == 'string') wrapper = new Element(wrapper, attributes); 132 150 else wrapper = new Element('div', wrapper); … … 260 278 writeAttribute: function(element, name, value) { 261 279 element = $(element); 262 var attributes = { }, t = Element._attributeTranslations.write;280 var attributes = { }, t = Element._attributeTranslations.write; 263 281 264 282 if (typeof name == 'object') attributes = name; … … 314 332 return element[element.hasClassName(className) ? 315 333 'removeClassName' : 'addClassName'](className); 316 },317 318 observe: function() {319 Event.observe.apply(Event, arguments);320 return $A(arguments).first();321 },322 323 stopObserving: function() {324 Event.stopObserving.apply(Event, arguments);325 return $A(arguments).first();326 334 }, 327 335 … … 586 594 offsetTop: 0, 587 595 offsetLeft: 0 588 }, arguments[2] || { });596 }, arguments[2] || { }); 589 597 590 598 // find page position of source … … 664 672 htmlFor: 'for' 665 673 }, 666 values: { }674 values: { } 667 675 } 668 676 }; … … 869 877 element.appendChild(n); 870 878 element.removeChild(n); 871 } catch (e) { }879 } catch (e) { } 872 880 873 881 return element; … … 1020 1028 }; 1021 1029 1022 Element.Methods.ByTag = { };1030 Element.Methods.ByTag = { }; 1023 1031 1024 1032 Object.extend(Element, Element.Methods); … … 1026 1034 if (!Prototype.BrowserFeatures.ElementExtensions && 1027 1035 document.createElement('div').__proto__) { 1028 window.HTMLElement = { };1036 window.HTMLElement = { }; 1029 1037 window.HTMLElement.prototype = document.createElement('div').__proto__; 1030 1038 Prototype.BrowserFeatures.ElementExtensions = true; … … 1035 1043 return Prototype.K; 1036 1044 1037 var Methods = { }, ByTag = Element.Methods.ByTag;1045 var Methods = { }, ByTag = Element.Methods.ByTag; 1038 1046 1039 1047 var extend = Object.extend(function(element) { … … 1094 1102 } 1095 1103 1096 if (!tagName) Object.extend(Element.Methods, methods || { });1104 if (!tagName) Object.extend(Element.Methods, methods || { }); 1097 1105 else { 1098 1106 if (Object.isArray(tagName)) tagName.each(extend); … … 1103 1111 tagName = tagName.toUpperCase(); 1104 1112 if (!Element.Methods.ByTag[tagName]) 1105 Element.Methods.ByTag[tagName] = { };1113 Element.Methods.ByTag[tagName] = { }; 1106 1114 Object.extend(Element.Methods.ByTag[tagName], methods); 1107 1115 } … … 1137 1145 if (window[klass]) return window[klass]; 1138 1146 1139 window[klass] = { };1147 window[klass] = { }; 1140 1148 window[klass].prototype = document.createElement(tagName).__proto__; 1141 1149 return window[klass]; … … 1159 1167 1160 1168 if (Element.extend.refresh) Element.extend.refresh(); 1161 Element.cache = { };1169 Element.cache = { }; 1162 1170 }; spinoffs/prototype/trunk/src/event.js
r6825 r7270 1 if (!window.Event) { 2 var Event = new Object(); 3 } 1 if (!window.Event) var Event = { }; 4 2 5 3 Object.extend(Event, { … … 17 15 KEY_PAGEUP: 33, 18 16 KEY_PAGEDOWN: 34, 19 17 KEY_INSERT: 45, 18 19 DOMEvents: ['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 20 'mousemove', 'mouseout', 'keypress', 'keydown', 'keyup', 21 'load', 'unload', 'abort', 'error', 'resize', 'scroll', 22 'select', 'change', 'submit', 'reset', 'focus', 'blur', 23 'DOMFocusIn', 'DOMFocusOut', 'DOMActivate', 24 'DOMSubtreeModified', 'DOMNodeInserted', 25 'NodeInsertedIntoDocument', 'DOMAttrModified', 26 'DOMCharacterDataModified'], 27 28 relatedTarget: function(event) { 29 var element; 30 switch(event.type) { 31 case 'mouseover': element = event.fromElement; break; 32 case 'mouseout': element = event.toElement; break; 33 default: return null; 34 } 35 return Element.extend(element); 36 } 37 }); 38 39 Event.Methods = { 20 40 element: function(event) { 21 return $(event.target || event.srcElement); 41 var node = event.target; 42 return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node); 43 }, 44 45 findElement: function(event, expression) { 46 var element = Event.element(event); 47 return element.match(expression) ? element : element.up(expression); 22 48 }, 23 49 … … 27 53 }, 28 54 29 pointerX: function(event) { 30 return event.pageX || (event.clientX + 31 (document.documentElement.scrollLeft || document.body.scrollLeft)); 32 }, 33 34 pointerY: function(event) { 35 return event.pageY || (event.clientY + 36 (document.documentElement.scrollTop || document.body.scrollTop)); 37 }, 55 pointer: function(event) { 56 return { 57 x: event.pageX || (event.clientX + 58 (document.documentElement.scrollLeft || document.body.scrollLeft)), 59 y: event.pageY || (event.clientY + 60 (document.documentElement.scrollTop || document.body.scrollTop)) 61 }; 62 }, 63 64 pointerX: function(event) { return Event.pointer(event).x }, 65 pointerY: function(event) { return Event.pointer(event).y }, 38 66 39 67 stop: function(event) { 40 if (event.preventDefault) { 41 event.preventDefault(); 42 event.stopPropagation(); 68 event.preventDefault(); 69 event.stopPropagation(); 70 } 71 }; 72 73 Event.extend = (function() { 74 var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { 75 m[name] = Event.Methods[name].methodize(); 76 return m; 77 }); 78 79 if (Prototype.Browser.IE) { 80 Object.extend(methods, { 81 stopPropagation: function() { this.cancelBubble = true }, 82 preventDefault: function() { this.returnValue = false }, 83 inspect: function() { return "[object Event]" } 84 }); 85 86 return function(event) { 87 if (!event) return false; 88 if (event._extendedByPrototype) return event; 89 90 event._extendedByPrototype = Prototype.emptyFunction; 91 var pointer = Event.pointer(event); 92 Object.extend(event, { 93 target: event.srcElement, 94 relatedTarget: Event.relatedTarget(event), 95 pageX: pointer.x, 96 pageY: pointer.y 97 }); 98 return Object.extend(event, methods); 99 }; 100 101 } else { 102 Event.prototype = Event.prototype || document.createEvent("Events").__proto__; 103 Object.extend(Event.prototype, methods); 104 return Prototype.K; 105 } 106 })(); 107 108 Object.extend(Event, (function() { 109 var cache = { }; 110 111 function getEventID(element) { 112 if (element._eventID) return element._eventID; 113 arguments.callee.id = arguments.callee.id || 1; 114 return element._eventID = ++arguments.callee.id; 115 } 116 117 function getDOMEventName(eventName) { 118 if (!Event.DOMEvents.include(eventName)) return "dataavailable"; 119 return { keypress: "keydown" }[eventName] || eventName; 120 } 121 122 function getCacheForID(id) { 123 return cache[id] = cache[id] || { }; 124 } 125 126 function getWrappersForEventName(id, eventName) { 127 var c = getCacheForID(id); 128 return c[eventName] = c[eventName] || []; 129 } 130 131 function createWrapper(id, eventName, handler) { 132 var c = getWrappersForEventName(id, eventName); 133 if (c.pluck("handler").include(handler)) return false; 134 135 var wrapper = function(event) { 136 if (event.eventName && event.eventName != eventName) 137 return false; 138 139 Event.extend(event); 140 handler.call(event.target, event); 141 }; 142 143 wrapper.handler = handler; 144 c.push(wrapper); 145 return wrapper; 146 } 147 148 function findWrapper(id, eventName, handler) { 149 var c = getWrappersForEventName(id, eventName); 150 return c.find(function(wrapper) { return wrapper.handler == handler }); 151 } 152 153 function destroyWrapper(id, eventName, handler) { 154 var c = getCacheForID(id), name = getDOMEventName(eventName); 155 if (!c[name]) return false; 156 c[name] = c[name].without(findWrapper(id, eventName, handler)); 157 } 158 159 function destroyCache() { 160 for (var id in cache) 161 for (var eventName in cache[id]) 162 cache[id][eventName] = null; 163 } 164 165 if (window.attachEvent) { 166 window.attachEvent("onunload", destroyCache); 167 } 168 169 return { 170 observe: function(element, eventName, handler) { 171 element = $(element); 172 var id = getEventID(element), name = getDOMEventName(eventName); 173 174 var wrapper = createWrapper(id, eventName, handler); 175 if (!wrapper) return false; 176 177 if (element.addEventListener) { 178 element.addEventListener(name, wrapper, false); 179 } else { 180 element.attachEvent("on" + name, wrapper); 181 } 182 }, 183 184 stopObserving: function(element, eventName, handler) { 185 element = $(element); 186 var id = getEventID(element), name = getDOMEventName(eventName); 187 188 if (!handler && eventName) { 189 return getWrappersForEventName(id, eventName).each(function(wrapper) { 190 element.stopObserving(eventName, wrapper.handler); 191 }) && false; 192 193 } else if (!eventName) { 194 return Object.keys(getCacheForID(id)).each(function(eventName) { 195 element.stopObserving(eventName); 196 }) && false; 197 } 198 199 var wrapper = findWrapper(id, eventName, handler); 200 if (!wrapper) return false; 201 202 if (element.removeEventListener) { 203 element.removeEventListener(name, wrapper, false); 204 } else { 205 element.detachEvent("on" + name, wrapper); 206 } 207 }, 208 209 fire: function(element, eventName, memo) { 210 element = $(element); 211 if (element == document && document.createEvent && !element.dispatchEvent) 212 element = document.documentElement; 213 214 if (document.createEvent) { 215 var event = document.createEvent("Events"); 216 event.initEvent("dataavailable", true, true); 217 } else { 218 var event = document.createEventObject(); 219 event.eventType = "ondataavailable"; 220 } 221 222 event.eventName = eventName; 223 event.memo = memo || {}; 224 225 if (document.createEvent) { 226 element.dispatchEvent(event); 227 } else { 228 element.fireEvent(event.eventType, event); 229 } 230 231 return element; 232 } 233 }; 234 })()); 235 236 Object.extend(Event, Event.Methods); 237 238 Element.addMethods({ 239 fire: function() { 240 Event.fire.apply(Event, arguments); 241 return $A(arguments).first(); 242 }, 243 244 observe: function() { 245 Event.observe.apply(Event, arguments); 246 return $A(arguments).first(); 247 }, 248 249 stopObserving: function() { 250 Event.stopObserving.apply(Event, arguments); 251 return $A(arguments).first(); 252 } 253 }); 254 255 Object.extend(document, { 256 fire: Element.Methods.fire.methodize(), 257 observe: Element.Methods.observe.methodize(), 258 stopObserving: Element.Methods.stopObserving.methodize() 259 }); 260 261 (function() { 262 /* Support for the DOMContentLoaded event is based on work by Dan Webb, 263 Matthias Miller, Dean Edwards and John Resig. */ 264 265 var timer, fired = false; 266 267 function fireContentLoadedEvent() { 268 if (fired) return; 269 if (timer) window.clearInterval(timer); 270 document.fire("contentloaded"); 271 fired = true; 272 } 273 274 if (document.addEventListener) { 275 if (Prototype.Browser.WebKit) { 276 timer = window.setInterval(function() { 277 if (/loaded|complete/.test(document.readyState)) 278 fireContentLoadedEvent(); 279 }, 0); 280 281 Event.observe(window, "load", fireContentLoadedEvent); 282 43 283 } else { 44 event.returnValue = false; 45 event.cancelBubble = true; 284 document.addEventListener("DOMContentLoaded", fireContentLoadedEvent, false); 46 285 } 47 }, 48 49 findElement: function(event, expression) { 50 var element = Event.element(event); 51 return element.match(expression) ? element : element.up(expression); 52 }, 53 54 observers: false, 55 56 _observeAndCache: function(element, name, observer, useCapture) { 57 if (!this.observers) this.observers = []; 58 if (element.addEventListener) { 59 this.observers.push([element, name, observer, useCapture]); 60 element.addEventListener(name, observer, useCapture); 61 } else if (element.attachEvent) { 62 this.observers.push([element, name, observer, useCapture]); 63 element.attachEvent('on' + name, observer); 64 } 65 }, 66 67 unloadCache: function() { 68 if (!Event.observers) return; 69 for (var i = 0, length = Event.observers.length; i < length; i++) { 70 Event.stopObserving.apply(this, Event.observers[i]); 71 Event.observers[i][0] = null; 72 } 73 Event.observers = false; 74 }, 75 76 observe: function(element, name, observer, useCapture) { 77 element = $(element); 78 useCapture = useCapture || false; 79 80 if (name == 'keypress' && 81 (Prototype.Browser.WebKit || element.attachEvent)) 82 name = 'keydown'; 83 84 Event._observeAndCache(element, name, observer, useCapture); 85 }, 86 87 stopObserving: function(element, name, observer, useCapture) { 88 element = $(element); 89 useCapture = useCapture || false; 90 91 if (name == 'keypress' && 92 (Prototype.Browser.WebKit || element.attachEvent)) 93 name = 'keydown'; 94 95 if (element.removeEventListener) { 96 element.removeEventListener(name, observer, useCapture); 97 } else if (element.detachEvent) { 98 try { 99 element.detachEvent('on' + name, observer); 100 } catch (e) {} 101 } 102 } 103 }); 104 105 /* prevent memory leaks in IE */ 106 if (Prototype.Browser.IE) 107 Event.observe(window, 'unload', Event.unloadCache, false); 286 287 } else { 288 var dummy = location.protocol == "https:" ? "https://javascript:void(0)" : "javascript:void(0)"; 289 document.write("<script id=__onDOMContentLoaded defer src='" + dummy + "'><\/script>"); 290 $("__onDOMContentLoaded").onreadystatechange = function() { 291 if (this.readyState == "complete") { 292 this.onreadystatechange = null; 293 fireContentLoadedEvent(); 294 } 295 }; 296 } 297 })(); spinoffs/prototype/trunk/test/lib/unittest.js
r7265 r7270 166 166 this.currentTest = 0; 167 167 this.logger = new Test.Unit.Logger(this.options.testLog); 168 setTimeout(this.runTests.bind(this), 1000); 168 Event.observe(window, "load", function() { 169 setTimeout(this.runTests.bind(this), 100); 170 }.bind(this)); 169 171 }, 170 172 parseResultsURLQueryParameter: function() {