diff options
author | Hiroshi Ichikawa <gimite@gmail.com> | 2011-03-06 11:29:11 +0900 |
---|---|---|
committer | Hiroshi Ichikawa <gimite@gmail.com> | 2011-03-06 11:29:11 +0900 |
commit | 7414b2e42d1e6e27b1a297caa17f38212a534dd2 (patch) | |
tree | e92715b345f7518becf73e8b11f2df44beee5f88 | |
parent | 7761b25d125a3425a8daeb90e33d9ed1485d7ca5 (diff) | |
download | web-socket-js-7414b2e42d1e6e27b1a297caa17f38212a534dd2.tar.gz |
Cleaning up event handling.
Passing real event to both onXXX and handlers added by addEventHandler().
Deleting check of cancelBubble which (probably) should not affect.
-rw-r--r-- | web_socket.js | 221 |
1 files changed, 75 insertions, 146 deletions
diff --git a/web_socket.js b/web_socket.js index 70e5fae..c1ce6f7 100644 --- a/web_socket.js +++ b/web_socket.js @@ -37,6 +37,7 @@ WebSocket.__instances[self.__id] = self; self.readyState = WebSocket.CONNECTING; self.bufferedAmount = 0; + self.__events = {}; // Uses setTimeout() to make sure __createFlash() runs after the caller sets ws.onopen etc. // Otherwise, when onopen fires immediately, onopen is called before it is set. setTimeout(function() { @@ -89,19 +90,12 @@ * * @param {string} type * @param {function} listener - * @param {boolean} useCapture !NB Not implemented yet + * @param {boolean} useCapture * @return void */ WebSocket.prototype.addEventListener = function(type, listener, useCapture) { - if (!('__events' in this)) { - this.__events = {}; - } if (!(type in this.__events)) { this.__events[type] = []; - if ('function' == typeof this['on' + type]) { - this.__events[type].defaultHandler = this['on' + type]; - this['on' + type] = this.__createEventHandler(this, type); - } } this.__events[type].push(listener); }; @@ -111,17 +105,15 @@ * * @param {string} type * @param {function} listener - * @param {boolean} useCapture NB! Not implemented yet + * @param {boolean} useCapture * @return void */ WebSocket.prototype.removeEventListener = function(type, listener, useCapture) { - if (!('__events' in this)) { - this.__events = {}; - } if (!(type in this.__events)) return; - for (var i = this.__events.length; i > -1; --i) { - if (listener === this.__events[type][i]) { - this.__events[type].splice(i, 1); + var events = this.__events[type]; + for (var i = events.length - 1; i >= 0; --i) { + if (events[i] === listener) { + events.splice(i, 1); break; } } @@ -130,79 +122,64 @@ /** * Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>} * - * @param {WebSocketEvent} event + * @param {Event} event * @return void */ WebSocket.prototype.dispatchEvent = function(event) { - if (!('__events' in this)) throw 'UNSPECIFIED_EVENT_TYPE_ERR'; - if (!(event.type in this.__events)) throw 'UNSPECIFIED_EVENT_TYPE_ERR'; - - for (var i = 0, l = this.__events[event.type].length; i < l; ++ i) { - this.__events[event.type][i](event); - if (event.cancelBubble) break; - } - - if (false !== event.returnValue && - 'function' == typeof this.__events[event.type].defaultHandler) - { - this.__events[event.type].defaultHandler(event); + var events = this.__events[event.type] || []; + for (var i = 0; i < events.length; ++i) { + events[i](event); } + var handler = this["on" + event.type]; + if (handler) handler(event); }; /** - * Handle an event from Flash. Do any WebSocket-specific - * handling before passing the event off to the event handlers. - * @param {Object} event + * Handles an event from Flash. + * @param {Object} flashEvent */ - WebSocket.prototype.__handleEvent = function(event) { - if ("readyState" in event) { - this.readyState = event.readyState; + WebSocket.prototype.__handleEvent = function(flashEvent) { + if ("readyState" in flashEvent) { + this.readyState = flashEvent.readyState; + } + + var jsEvent; + if (flashEvent.type == "open" || flashEvent.type == "error") { + jsEvent = this.__createSimpleEvent(flashEvent.type); + } else if (flashEvent.type == "close") { + // TODO implement jsEvent.wasClean + jsEvent = this.__createSimpleEvent("close"); + } else if (flashEvent.type == "message") { + var data = decodeURIComponent(flashEvent.message); + jsEvent = this.__createMessageEvent("message", data); + } else { + throw "unknown event type: " + flashEvent.type; } + + this.dispatchEvent(jsEvent); + }; - try { - if (event.type == "open") { - if (this.onopen) this.onopen(); - } else if (event.type == "close") { - if (this.onclose) this.onclose(); - } else if (event.type == "error") { - if (this.onerror) this.onerror(event); - } else if (event.type == "message") { - if (this.onmessage) { - var data = decodeURIComponent(event.message); - var e; - if (window.MessageEvent && !window.opera) { - e = document.createEvent("MessageEvent"); - e.initMessageEvent("message", false, false, data, null, null, window, null); - } else { - // IE and Opera, the latter one truncates the data parameter after any 0x00 bytes. - e = {data: data}; - } - this.onmessage(e); - } - } else { - throw "unknown event type: " + event.type; - } - } catch (e) { - console.error(e); + WebSocket.prototype.__createSimpleEvent = function(type) { + if (window.Event) { + var event = document.createEvent("Event"); + event.initEvent(type, false, false); + return event; + } else { + return {type: type, bubbles: false, cancelable: false}; } }; - /** - * @param {object} object - * @param {string} type - */ - WebSocket.prototype.__createEventHandler = function(object, type) { - return function(data) { - var event = new WebSocketEvent(); - event.initEvent(type, true, true); - event.target = event.currentTarget = object; - for (var key in data) { - event[key] = data[key]; - } - object.dispatchEvent(event, arguments); - }; + WebSocket.prototype.__createMessageEvent = function(type, data) { + if (window.MessageEvent && !window.opera) { + var event = document.createEvent("MessageEvent"); + event.initMessageEvent("message", false, false, data, null, null, window, null); + return event; + } else { + // IE and Opera, the latter one truncates the data parameter after any 0x00 bytes. + return {type: type, data: data, bubbles: false, cancelable: false}; + } }; - + /** * Define the WebSocket readyState enumeration. */ @@ -217,6 +194,16 @@ WebSocket.__nextId = 0; /** + * Load a new flash security policy file. + * @param {string} url + */ + WebSocket.loadFlashPolicyFile = function(url){ + WebSocket.__addTask(function() { + WebSocket.__flash.loadManualPolicyFile(url); + }); + }; + + /** * Loads WebSocketMain.swf and creates WebSocketMain object in Flash. */ WebSocket.__initialize = function() { @@ -269,17 +256,7 @@ }; /** - * Load a new flash security policy file. - * @param {string} url - */ - WebSocket.loadFlashPolicyFile = function(url){ - WebSocket.__addTask(function() { - WebSocket.__flash.loadManualPolicyFile(url); - }); - }; - - /** - * Called by flash to notify js that it's fully loaded and ready + * Called by Flash to notify JS that it's fully loaded and ready * for communication. */ WebSocket.__onFlashInitialized = function() { @@ -297,28 +274,31 @@ }; /** - * Called by flash to dispatch an event to a web socket. - * @param {object} eventObj A web socket event dispatched from flash. + * Called by Flash to notify WebSockets events are fired. */ WebSocket.__onFlashEvent = function() { setTimeout(function() { - // Gets events using receiveEvents() instead of getting it from event object - // of Flash event. This is to make sure to keep message order. - // It seems sometimes Flash events don't arrive in the same order as they are sent. - var events = WebSocket.__flash.receiveEvents(); - for (var i = 0; i < events.length; ++i) { - WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i]); + try { + // Gets events using receiveEvents() instead of getting it from event object + // of Flash event. This is to make sure to keep message order. + // It seems sometimes Flash events don't arrive in the same order as they are sent. + var events = WebSocket.__flash.receiveEvents(); + for (var i = 0; i < events.length; ++i) { + WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i]); + } + } catch (e) { + console.error(e); } }, 0); return true; }; - // called from Flash + // Called by Flash. WebSocket.__log = function(message) { console.log(decodeURIComponent(message)); }; - // called from Flash + // Called by Flash. WebSocket.__error = function(message) { console.error(decodeURIComponent(message)); }; @@ -346,57 +326,6 @@ return mimeType.enabledPlugin.filename.match(/flashlite/i) ? true : false; }; - /** - * Basic implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface">DOM 2 EventInterface</a>} - * - * @class - * @constructor - */ - function WebSocketEvent(){} - - /** - * - * @type boolean - */ - WebSocketEvent.prototype.cancelable = true; - - /** - * - * @type boolean - */ - WebSocketEvent.prototype.cancelBubble = false; - - /** - * - * @return void - */ - WebSocketEvent.prototype.preventDefault = function() { - if (this.cancelable) { - this.returnValue = false; - } - }; - - /** - * - * @return void - */ - WebSocketEvent.prototype.stopPropagation = function() { - this.cancelBubble = true; - }; - - /** - * - * @param {string} eventTypeArg - * @param {boolean} canBubbleArg - * @param {boolean} cancelableArg - * @return void - */ - WebSocketEvent.prototype.initEvent = function(eventTypeArg, canBubbleArg, cancelableArg) { - this.type = eventTypeArg; - this.cancelable = cancelableArg; - this.timeStamp = new Date(); - }; - if (!window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION) { if (window.addEventListener) { window.addEventListener("load", function(){ |