-
Notifications
You must be signed in to change notification settings - Fork 602
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- W3CWebSocket: Use just one or two arguments (fixes #173)
- Loading branch information
Showing
1 changed file
with
19 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,32 @@ | ||
var _global = (function() { return this; })(); | ||
var nativeWebSocket = _global.WebSocket || _global.MozWebSocket; | ||
|
||
|
||
/** | ||
* W3CWebSocket constructor. | ||
* Expose a W3C WebSocket class with just one or two arguments. | ||
*/ | ||
var W3CWebSocket = _global.WebSocket || _global.MozWebSocket; | ||
function W3CWebSocket(uri, protocols) { | ||
var instance; | ||
|
||
if (protocols) { | ||
instance = new nativeWebSocket(uri, protocols); | ||
} | ||
else { | ||
instance = new nativeWebSocket(uri); | ||
} | ||
|
||
return instance; | ||
} | ||
|
||
if (nativeWebSocket) { | ||
W3CWebSocket.prototype = nativeWebSocket.prototype; | ||
} | ||
|
||
|
||
/** | ||
* Module exports. | ||
*/ | ||
module.exports = { | ||
'w3cwebsocket' : W3CWebSocket ? W3CWebSocket : null, | ||
'w3cwebsocket' : nativeWebSocket ? W3CWebSocket : null, | ||
'version' : require('./version') | ||
}; |
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, why can't we just directly return
nativeWebSocket
here?12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, when using the
W3CWebSocket
function as a constructor, you can't returninstance
to change the object that is constructed. I really don't see the purpose of this?12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I see, it's to be able to accept a third non-standard options object that will be ignored in the browser.
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still, if used in the manner below, I can't imagine how this could possibly work:
By the time we attach the onmessage handler, it theoretically wouldn't attach to the "real" native WebSocket implementation, it would attach to an instance of our fake class-factory wrapper because you can't implement the class-factory pattern using constructors in JavaScript. When you return another object from a constructor in JavaScript, that's just ignored and it returns
this
anyway.12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure in Chrome/Firefox (I should have tested this more) but in Android WebView (using Cordova) the WebSocket constructor fails if it's given with more than two arguments. So we need to "filter" them. For that I added a "faked" constructor (
w3cwebsoket.nativeWebSocket
) which takes the first one or two arguments and pass them to the realWebSocket
class (which in this case is the browser's nativeWebSocket
implementation).The instance is not changed but just returned.
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trick here is in the last line:
Here the full prototype of the native
WebSocket
class is set into theW3CWebSocket
class-factory wrapper.12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is tested:
;)
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it turns out I'm wrong! Sweet! 😁
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Being honest I don't like this "workaround" but I cannot figure out a better one. And given that
ws
uses the same for long time (and nobody has reported that it fails) I accept it as a "valid" solution.12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was pretty certain that you couldn't override the object that was returned from a constructor with another object. The fact that you can opens up a lot of possibilities. It's nice to be proven wrong once in a while! I get to learn! 😀
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm also annoyed by the fact that a constructor can return something different than
this
... But you know: this is JavaScript, anything is possible.12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wrong. The wrapper constructor does not return
instance
. I'll prove it in 2 minutes.12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I was right. Demonstration:
Wrong (since
C1Wrapper
does not returnc1
):Output:
Correct
Just add
return c1
in theC1Wrapper
constructor.Output:
"Love" JavaScript...
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
http://codepen.io/theturtle32/pen/xbwMKX?editors=101
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proved now :)
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I released v1.0.14 btw.
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For funny, change this:
Don't ask me about why it happens what it happens...
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! time to update libraries!
12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW I've realized that the line
W3CWebSocket.prototype = nativeWebSocket.prototype;
is not needed at all (it works without it). It makes sense given that the returned instance of the wrapper-class is in fact an instance of the original class.12a32d9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More about returning stuff in a constructor: http://www.bennadel.com/blog/2522-providing-a-return-value-in-a-javascript-constructor.htm