tag:blogger.com,1999:blog-74986774596749544852024-02-19T07:26:09.219-05:00Like bricks in the skyPatrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.comBlogger20125tag:blogger.com,1999:blog-7498677459674954485.post-90271165857430360492014-04-27T13:32:00.002-04:002014-04-27T13:46:56.859-04:00Extending JavaScript Maps (or other built-in objects)Finally another technical post, this one is about my adventures in attempting to extend the built-in <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map">Map</a> object in JavaScript to extend the functionality. As background, there are two reasons we'd want this:<br />
<ol>
<li>In the chat backend we currently use JavaScript <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">objects</a> ({}) as hashes/maps to keep track of various things (i.e. there's a <a href="https://mxr.mozilla.org/comm-central/source/chat/protocols/irc/irc.js#789">hash of conversations</a> which map from conversation name to prplIConversation objects in the IRC code). Whenever checking to see if something is in this map we have to use <a href="https://mxr.mozilla.org/comm-central/source/chat/protocols/irc/irc.js#1509">hasOwnProperty</a>. This has to be the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty">version from Obj<span id="goog_1256573606"></span><span id="goog_1256573607"></span>ect.prototype</a> in case the map has a conversation named hasOwnProperty. This is <a href="https://mxr.mozilla.org/comm-central/source/chat/modules/imXPCOMUtils.jsm#166">super simple code</a>, but annoying:<br />
<pre class="brush: javascript">// Similar to Object.hasOwnProperty, but doesn't fail if the object
// has a hasOwnProperty property set.
function hasOwnProperty(aObject, aPropertyName)
Object.prototype.hasOwnProperty.call(aObject, aPropertyName)
</pre>
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=955366">Replacing these custom objects with a Map</a> would alleviate this funky dance.<br />
</li>
<li>Frequently in the chat backend we have to "normalize"[1] strings (e.g. #INsTanTBIrd and #instantbird are the same on IRC[2]). This is almost always done for sane storage of data received from the network (or from the user). I figured it'd be great if, instead of having to <a href="https://mxr.mozilla.org/comm-central/source/chat/protocols/irc/irc.js#1510">manually</a> <a href="https://mxr.mozilla.org/comm-central/source/chat/protocols/irc/irc.js#1514">handle</a> <a href="https://mxr.mozilla.org/comm-central/source/chat/protocols/irc/irc.js#1528">this</a> normalization each time we tried to access data, the keys were magically normalized when accessing the data.<br />(Note that although normalization is generally more complicated, just consider to be <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase">String.prototype.toLowerCase()</a> for the rest of this post!)</li>
</ol>
This has been explored before by <a href="http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/">others</a>, but generally in the context of web sites / cross browser compatibility. Which are concerns that don't really limit us for backend code.<br />
<ol>
</ol>
<h2>
Goals </h2>
<ol>
<li>Replace objects with Maps for safe access. This is pretty easily fixed by switching all <span style="font-family: "Courier New",Courier,monospace;">obj["foo"]</span> calls to <span style="font-family: "Courier New",Courier,monospace;">obj.get("foo")</span> (or the appropriate other method: set, delete, etc.)</li>
<li>Automatically "normalize" keys in the some user defined way, e.g. such that <span style="font-family: "Courier New",Courier,monospace;">obj.get("foo")</span> and <span style="font-family: "Courier New",Courier,monospace;">obj.get("FoO")</span> return the same value.</li>
</ol>
<h2>
First Approach (setting __proto__ to Map.prototype)</h2>
My first naive approach was to create an object with <span style="font-family: "Courier New",Courier,monospace;">__proto__</span> set to Map.prototype and overwrite anything that uses keys to appropriately call a normalization function.<br />
<br />
<pre class="brush: javascript">function NormalizedMap() { }
NormalizedMap.prototype = {
__proto__: Map.prototype,
_normalize: function(aStr) aStr.toLowerCase(),
get: function(aStr) Map.prototype.get.call(this, this._normalize(aStr)),
set: function(aStr, aVal) Map.prototype.set.call(this, this._normalize(aStr), aVal)
};
let m = new NormalizedMap();
m.set("foo", 1) // Throws TypeError: set method called on incompatible Object
m instanceof Map; // true . . . wat . . .
</pre>
<br />
This throws an error and does not work. <span class="coMULTI">Apparently there are plans to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=838540">support something like this</a>. The totally fun thing, in my opinion, is that m is an instance of a Map!</span><br />
<h2>
Second Approach (modifying __proto__ after instance creation)</h2>
My second approach was to generate a real Map and then override the __proto__ to give it the properties I wanted:<br />
<br />
<pre class="brush: javascript">function NormalizedMap() {
let m = new Map();
m.__proto__ = NormalizedMap.prototype;
return m;
}
NormalizedMap.prototype = {
__proto__: Map.prototype,
_normalize: function(aStr) aStr.toLowerCase(),
get: function(aStr) Map.prototype.get.call(this, this._normalize(aStr)),
set: function(aStr, aVal) Map.prototype.set.call(this, this._normalize(aStr), aVal)
};
let m = new NormalizedMap();
m.set("foo", 1)
m.get("FOO"); // 1
m instanceof Map; // true
</pre>
<br />
This actually works! But will <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=963519">throw a warning</a> each time it is created since changing an objects __proto__ is generally a bad idea. I also thought of overriding individual methods, but this seemed cumbersome and would increase the time in the constructor calls. (Which occur during the start up of each account and is generally a resource constrained time. No, I didn't profile this, it just seemed like bad design.)<br />
<h2>
Solution (wrapping a Map)</h2>
Finally I settled on the simple solution of just wrapping the Map in a custom object. Initially I thought this would be frustrating to re-declare every function (and prone to breakage in the future if new methods are added), but there's a nice magic method <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/noSuchMethod">__noSuchMethod__</a> that fixes this! (Note that this is a non-standard feature of SpiderMonkey.) __noSuchMethod__ allows an object to intercept a call to a non-existent method (and in this case call that same method on the internal Map object).<br />
<br />
Below is the final version that seems to act magically like a Map when necessary (e.g. iterating the map works, all functions and properties exist, the constructor works[3]). I need to thank aleth (another chat developer) who helped out quite a bit with this (and will ultimately be reviewing this code)!<br />
<br />
<pre class="brush: javascript">// A Map that automatically normalizes keys before accessing the values.
function NormalizedMap(aNormalizeFunction, aIt = []) {
if (typeof(aNormalizeFunction) != "function")
throw "NormalizedMap must have a normalize function!";
this._normalize = aNormalizeFunction;
this._map = new Map([[this._normalize(key), val] for ([key, val] of aIt)]);
}
NormalizedMap.prototype = {
_map: null,
// The function to apply to all keys.
_normalize: null,
// Anything that accepts a key as an input needs to be manually overridden.
delete: function(aKey) this._map.delete(this._normalize(aKey)),
get: function(aKey) this._map.get(this._normalize(aKey)),
has: function(aKey) this._map.has(this._normalize(aKey)),
set: function(aKey, aValue) this._map.set(this._normalize(aKey), aValue),
// Properties must be manually forwarded.
get size() this._map.size,
// Here's where the magic happens. If a method is called that isn't defined
// here, just pass it to the internal _map object.
__noSuchMethod__: function(aId, aArgs) this._map[aId].apply(this._map, aArgs)
}
</pre>
<br />
The one downside of see of this is that properties must be declared manually to forward to the internal _map object. Maybe there is a matching __noSuchProperty__ method I'm missing? Overall, I'm happy with this solution, but please leave a comment if you can think of an easier / better way to do this! (Or see a glaring way this will break!)<br />
<br />
<span style="font-size: x-small;">[1] This is always a little bit of a sore subject in <a href="irc://irc.mozilla.org/#instantbird">#instantbird</a> since we've had a variety of issues with this over the years. I think we've fixed most of them at this point though!</span><br />
<span style="font-size: x-small;">[2] As I've <a href="http://clokep.blogspot.com/2011/03/so-called-irc-specifications.html">written before</a>, IRC tends to have crazy specifications. In IRC, <a href="https://tools.ietf.org/html/rfc2812#section-2.2">the characters of A-Z[]\~ are considered the upper case of a-z{}|^</a> ("because of IRC's Scandinavian origin"). Oh, also this can change based on an <a href="http://tools.ietf.org/html/draft-brocklesby-irc-isupport-03#section-3.1">ISUPPORT response</a> from the server to pure ASCII or RFC 1459 casemapping (A-Z[]\ map to a-z{}|). It seems like this could theoretically change at any point on a live server too, although that would be INSANE and I hope no one ever does that.</span><br />
<span style="font-size: x-small;">[3] I wrote some xpcshell tests to ensure these properties work as expected, but they're uhh...not up anywhere yet though. Oops. </span>Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com2tag:blogger.com,1999:blog-7498677459674954485.post-57612788360662682852013-10-06T09:18:00.000-04:002013-10-06T21:33:49.861-04:00Yahoo Protocol Google Summer of Code Round-upI have to apologize to my student, <a href="http://phaseshiftsoftware.com/blog/">Quentin</a> (aka qheaden on IRC), for taking so long to write this...but anyway: Google Summer of Code 2013 is over! Quentin has done a great job working at implementing the Yahoo Protocol for Instantbird (and Thunderbird) in JavaScript (henceforth called "JS-Yahoo"). It's at the point where it has mostly reached feature-parity with the libpurple plug-in. Before <a href="https://bugzilla.instantbird.org/show_bug.cgi?id=2135">turning this on as default</a> there are a few minor bugs that still need to be fixed, but most of them have patches that just need another couple iterations.<br />
<br />
<b>Where do we go from here?</b> Once the last few bugs are fixed we'll enable Yahoo by default in the nightly builds and, assuming we have no issues, it will be enabled by default in the upcoming Instantbird 1.5. If there are no major issues in 1.5, we'll remove the libpurple Yahoo implementation for Instantbird 1.next.<br />
<br />
<b>How do I try this now?!</b> You can already easily enable JS-Yahoo in <a href="http://nightly.instantbird.im/">Instantbird nightly builds</a>:<br />
<ol>
<li>Type /about config in a conversation tab's textbox</li>
<li>Type "forcePurple" in the search box</li>
<li>Remove "prpl-yahoo" and "prpl-yahoojp" from this comma separated list of values (you can also remove prpl-jabber if you want to always use the JS-XMPP implementation from GSoC 2011! Note that this doesn't support <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=14328">DNS SRV</a>, however.)</li>
<li>Restart Instantbird!</li>
</ol>
You should now be using the JS-Yahoo protocol. Hopefully you don't notice anything different, but <a href="https://bugzilla.instantbird.org/">PLEASE file bugs</a> if you see any issues.<br />
<br />
<b>How come I can't use this in Thunderbird?!</b> Because Instantbird and comm-central development don't happen in the same Mercurial repository. I'm working on <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=920801">syncing the chat/ folder of these repositories</a> currently and JS-Yahoo should be in Daily soon to be included in the next Thunderbird release (i.e. Thunderbird 31).<br />
<br />
The whole Instantbird community has been super happy with the progress Quentin made and we hope that Quentin has learned a lot! Thanks for a great summer qheaden and hopefully we'll see you around still!Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com2tag:blogger.com,1999:blog-7498677459674954485.post-17483534311084578912013-06-28T18:05:00.000-04:002013-10-06T21:33:24.045-04:00Mentoring Google Summer of Code 2013I'm officially a mentor this year for <a href="http://www.google-melange.com/gsoc/homepage/google/gsoc2013">2013's Google Summer of Code</a>. I'm a bit late on posting this, but oh well! My student this year is <a href="http://phaseshiftsoftware.com/">Quentin Headen</a> who is <a href="http://www.google-melange.com/gsoc/project/google/gsoc2013/qheaden/26001">working on</a> a <a href="http://en.wikipedia.org/wiki/Yahoo!_Messenger_Protocol">Yahoo! Messenger protocol</a> for the Instantbird chat/ backend (so it'll also be usable via Thunderbird). You can see <a href="http://phaseshiftsoftware.com/blog/category/gsoc-2013-logs/">an account of his trials, successes and trepidations</a> (<a href="http://phaseshiftsoftware.com/blog/category/gsoc-2013-logs/feed/">RSS</a>) or follow his <a href="https://bitbucket.org/qheaden/instantbird-gsoc-2013">code repository</a>. He's made great progress so far and is able to connect, download all the buddies and start private conversations! Not too bad for a few weeks of work! We've been keeping a <a href="https://etherpad.mozilla.org/ELTNA6O44F">TODO list</a> of things to be supported, please don't edit it without discussing it with us first.<br />
<br />
Our hope is to get this checked into Instantbird by the end of summer and run it in parallel (behind an about:config preference) with the current libpurple Yahoo implementation. Once we're satisified that it has feature parity we'll remove the libpurple version and enable this by default! <br />
<br />
Instantbird is also supporting two other projects:<br />
<ul>
<li>The <a href="http://www.google-melange.com/gsoc/project/google/gsoc2013/nhnt11/7001">"Awesometab"</a> is being done by <a href="http://awesometab.blogspot.com/">Nihanth Subramanya</a> (<a href="http://awesometab.blogspot.com/feeds/posts/default?alt=rss">RSS</a>) and being mentored by Benedikt Pfeifer, his code is <a href="https://bitbucket.org/nhnt11/instantbird-addons">available</a> and some has already been <a href="http://hg.instantbird.org/instantbird/rev/55009d68c4ec">checked</a> <a href="http://hg.instantbird.org/instantbird/rev/46ee5c836e48">into</a> <a href="http://hg.instantbird.org/instantbird/rev/52401d522970">Instantbird</a> <a href="http://hg.instantbird.org/instantbird/rev/ea36babac4be">nightlies</a>!</li>
<li><a href="http://www.google-melange.com/gsoc/project/google/gsoc2013/atuljangra/68001">FileLinks in IM</a> is being worked on by <a href="http://atuljangra.tumblr.com/">Atul Jangra</a> (or <a href="http://gsoc-mozilla.tumblr.com/">maybe</a>) (<a href="http://atuljangra.tumblr.com/rss">RSS</a> / <a href="http://gsoc-mozilla.tumblr.com/rss">RSS</a>) and being mentored by Florian Quèze, check out the <a href="https://bitbucket.org/atuljangra/instantbird-gsoc-2013">repository</a>.</li>
</ul>
You can find any of us in #instantbird on irc.mozilla.org, my nick is clokep, Quentin's is qheaden, Nihanth's: nhnt11, Atul's: atuljangra, Benedikt goes by Mic and Florian goes by something starting with "flo".<br />
<br />
Thanks also go out to Mozilla for letting us participate in Google Summer of Code with them again! You can see all of the accepted projects in <a href="http://blog.gerv.net/2013/06/gsoc-2013-project-list/">Gerv's blogpost</a>. <br />
<ul>
</ul>
Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com0tag:blogger.com,1999:blog-7498677459674954485.post-3192889604542192962013-05-20T16:45:00.000-04:002013-10-06T21:33:59.854-04:00Instantbird 1.4 Released!After a bunch of l10n build problems, we've finally released Instantbird 1.4, which includes updates to libpurple 2.10.7 and Mozilla 20. In particular this includes:<br />
<ul>
<li>Updated Twitter code that uses v1.1 of their API (v1.0 will be disabled on June 11th, 2013).</li>
<li>Better character counter for Twitter (it now takes into account if URLs are embedded). </li>
<li>Updated log viewer which organizes logs by date (and nests them by week, month, etc.)</li>
<li>Better support for IRC bouncers.</li>
<li>Support for overriding self-signed/invalid/out-of-date certificates for IRC.</li>
</ul>
If you've been using some other instant messaging client (e.g. Pidgin or Adium); I'd highly suggest giving Instantbird a try, especially if you also go on IRC. Instantbird has great IRC support! (And...if you do have issues, feel free to ping me in #instantbird on irc.mozilla.org and let me know what your issue is.) <br />
<br />
You can download it <a href="http://www.instantbird.com/download-all.html">here</a>, or view the full <a href="http://www.instantbird.com/release-notes.html">release notes</a>.Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com2tag:blogger.com,1999:blog-7498677459674954485.post-9609195092727606462012-11-28T23:11:00.002-05:002012-11-28T23:11:40.941-05:00JavaScript typed arrays painIf you've ever tried to deal with binary data in JavaScript you know it isn't much fun and you usually resort to using strings lots of charCodeAt and related functions. <a href="https://developer.mozilla.org/en-US/docs/JavaScript_typed_arrays">Typed arrays</a> are supposed to solve this though! The typed array API consists of creating a buffer of bytes (called an <a href="https://developer.mozilla.org/en-US/docs/JavaScript_typed_arrays/ArrayBuffer">ArrayBuffer</a>) and then manipulating those bytes via different views (<a href="https://developer.mozilla.org/en-US/docs/JavaScript_typed_arrays/ArrayBufferView">ArrayBufferView</a>s). You can have multiple views of the same buffer, starting at different offsets, of different lengths and types...which is all neat from a technical point of view, but is it really useful? It is kind of nice working with the views as if they were normal arrays though.<br />
<br />
I've been playing with these ArrayBuffers quite a bit as I'm working on an implementation of the <a href="http://en.wikipedia.org/wiki/OSCAR_protocol">OSCAR protocol</a> (used for <a href="http://en.wikipedia.org/wiki/AOL_Instant_Messenger">AOL Instant Messenger</a> and <a href="http://en.wikipedia.org/wiki/ICQ">ICQ</a>) in the chat backend (for Instantbird / Thunderbird). (As an aside, the OSCAR protocol Wikipedia page has surprisingly good documentation of some of the underlying data structures of the protocol...) I started by writing some test code using ArrayBuffers and views, which have been around a while: since Gecko 2.0 in fact! I quickly ran into some tedious issues with repetitive code such as:<br />
<br />
<pre class="brush: javascript">/*
* A TLV (Type, Length and Value) data structure:
* Unsigned Short type Describes what the value represents.
* Unsigned Short length The length of the data block.
* Bytes value The raw payload.
*
* The overall length of a TlvBlock is length + 4.
*
* The inputs to this are:
* aType The type of the TLV Block.
* aValue An ArrayBuffer containing the data.
*/
function TlvBlock(aType, aValue) {
let data = new ArrayBuffer(aValue.byteLength + 4);
// The first two bytes are unsigned shorts.
let view = new Uint16Array(data, 0, 2);
view[0] = aType;
view[1] = aValue.byteLength;
// The rest just gets the data copied into it.
view = new Uint8Array(data, 4);
view.set(new Uint8Array(aValue));
return data;
}
</pre>
<br />
This actually illustrates two annoying issues I have:<br />
<ol>
<li>I end up with extra lines of code defining a new view every time I switch data types.</li>
<li>There's no simple way to copy an ArrayBuffer into a part of an ArrayBuffer. In the above example I create a Uint8Array view of the target location, a Uint8Array view of the source location and then set the source to the target. Seems simple once you figure it out, but it took a while to figure out.</li>
</ol>
(As an aside, some of you might find the following function helpful, it is essentially a <a href="http://en.cppreference.com/w/cpp/string/byte/memcpy">memcpy</a> for ArrayBuffers...this isn't really tested heavily at all, however.)<br />
<pre class="brush: javascript">/*
* aTarget / aSource are ArrayBuffers
*/
function copyBytes(aTarget, aSource, aTargetOffset = 0, aSourceOffset = 0, aLength = aSource.byteLength) {
// The rest just gets the data copied into it.
let view = new Uint8Array(aTarget, aTargetOffset);
view.set(new Uint8Array(aSource, aSourceOffset, aLength));
}
</pre>
<br />
OK, so typed arrays seem good, but kind of annoying, right? Wrong...the OSCAR protocol is a "network order" protocol (aka it is big endian). At this point you're probably thinking "OK, so the ArrayBuffer constructor must take an endianess flag!" Wrong, it does no such thing. "Hmmm...Well do the ArrayBufferViews take an endianess flag?" Nope, wrong again. The only way to specify the endianess of the data is to use a <a href="https://developer.mozilla.org/en-US/docs/JavaScript_typed_arrays/DataView">DataView</a>, a slightly different interface to the underlying bytes. It offers an API to individually set different data elements via their offset and endianess. (If you're too lazy to read the documentation all the way through, DataView assumes big endian: makes my life easier!)<br />
<br />
For the curious, JavaScript typed arrays use the system endianess, which in my opinion is pretty much useless (at least if you plan on sharing data) since you can never guarantee the endianess to be either big or little endian. (The fun part is that this isn't even documented, I found it on <a href="http://stackoverflow.com/questions/7869752/javascript-typed-arrays-and-endianness">Stack Overflow</a> and verified.)<br />
<br />
So, in summary...if you plan on networking at all with ArrayBuffers, don't use ArrayBufferViews, use DataViews. (Although Uint8Arrays and Int8Arrays should work fine!)<br />
<br />
And to not rant the <i>entire</i> time, working with typed arrays certainly does beat strings + charCodeAt! Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com0tag:blogger.com,1999:blog-7498677459674954485.post-51066184715773618312012-11-16T06:42:00.002-05:002012-11-16T06:42:46.447-05:00Instantbird 1.3 Released!!!Well we finally got our release process down a bit better and were able to do a quicker release (from 1.2 to 1.3, compared to our previous few releases). This is great news, as it gives incremental changes to our users faster! There's some new features available, which are mostly covered on the <a href="http://blog.instantbird.org/2012/11/instantbird-1-3-released/">Instantbird blog</a>, but quickly:<br />
<ul>
<li>IRC now supports SASL authentication, which is required by Freenode when connecting from Tor or certain IP ranges.</li>
<li>Long messages over IRC are now smartly chopped and sent as multiple messages (instead of being truncated).</li>
<li>The "Show Nick" add-on was integrated: this allows styling of a mentioned nick in a conversation (and is extremely useful for following multiple conversations).</li>
<li>Various other minor improvements...</li>
</ul>
Instantbird 1.3 is based off of Mozilla 16.0.2, but I believe we're hoping to update to mozilla-central soon in order to benefit from cool new technologies, like WebRTC! You should <a href="http://www.instantbird.com/download-all.html">check out Instantbird</a> now! Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com0tag:blogger.com,1999:blog-7498677459674954485.post-19968922729225563592012-10-16T21:33:00.001-04:002012-10-16T21:33:29.075-04:00On StatusSomething that comes up often about Instantbird is why we only support three statuses: Available, Unavailable and Offline. (We do actually support a fourth one too, Idle, but that is set automatically, not chosen by the user.) Frequently this discussion is in the context of wanting an "Invisible" status, but I'll get to that later...<br />
<br />
Many users have talked to us on IRC, email or via bugs and complained about wanting an "Away" status or a "Do Not Disturb" status. There's a few issues with this:<br />
<ol>
<li>What's really the difference between "Unavailable", "Away" and "Do Not Disturb"? Do you really need to choose them individually? (Other things that fit into here: "Not at my desk", "on the phone", "busy", "stepped out". It is amazing how some protocols have so many ways to describe being unavailable!)</li>
<li>A technical issue that we often run into is trying to shoehorn different protocol implementations into our abstract protocol interface. (We already have some fairly complicated interfaces around joining chat rooms, creating different account, etc. because of this.)</li>
<li>Setting yourself as "Away" or "Invisible" is a lie. Perhaps this is me being overly idealistic, but why would you set yourself as "Away"? It seems that this is something that should be done automatically (when you lock your display, perhaps?). You can't be "Away" and using your computer at the same time!<br />Again, perhaps being idealistic, but what is the point of the "Invisible" status? If you wish to be hidden from someone (everyone?) why not just block those users. Or ignore them when they send you a message. If you are busy, set yourself to "Unavailable" and people should understand that they should not talk to you...if they don't, well...do you really want them talking to you ever? (Are they really your friend? I guess you don't get to choose your co-workers, but still.) Now, perhaps this is just my opinion as being someone who never really hard an "Invisible" status (I actually remember it being added to the AIM client at some point).</li>
</ol>
At this point you probably don't believe me that there's really <i>that</i> many different protocol statuses out there, so I figured I'd illustrate a few protocols in a matrix. Note that this isn't meant to be exhaustive, just to show how complicated of a situation this really is. All protocols can obviously be "offline" as well, but that's not shown in the table.<br />
<br />
<table border="1" cellpadding="0" cellspacing="3" style="border: outset 1.5pt; margin-left: 50px; margin-right: 50px;">
<tbody>
<tr>
<td></td>
<th>Available</th>
<th>Unavailable</th>
<th>Phone</th>
<th>Invisible</th>
</tr>
<tr>
<td>Oscar (AIM/ICQ)</td>
<td>Online</td>
<td>Away</td>
<td></td>
<td>Invisible</td>
</tr>
<tr>
<td>IRC</td>
<td>Online</td>
<td>Away</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Microsoft Lync</td>
<td>Online</td>
<td>Busy<br />
Away<br />
In a meeting</td>
<td>In a call</td>
<td></td>
</tr>
<tr>
<td>Yahoo!</td>
<td>Available</td>
<td>Busy<br />
Stepped out<br />
Be right back<br />
Not at my desk</td>
<td>On the phone</td>
<td>Invisible</td>
</tr>
<tr>
<td>Windows Live Messenger</td>
<td>Online</td>
<td>Busy<br />
Away<br />
Be Right Back<br />
Out to lunch</td>
<td>On the phone</td>
<td>Appear offline</td>
</tr>
<tr>
<td>XMPP (Google Talk)</td>
<td>Available</td>
<td>Busy</td>
<td></td>
<td>Invisible</td>
</tr>
</tbody></table>
Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com5tag:blogger.com,1999:blog-7498677459674954485.post-47847538603856085162012-08-08T13:08:00.000-04:002013-10-06T21:34:23.600-04:00Instantbird 1.2 Released (with awesome new IRC features)!If you haven't seen the announcement...<a href="http://blog.instantbird.org/2012/08/instantbird-1-2-released/">Instantbird 1.2 has been released</a>! It's got a ton of great new features that I'm excited for: <a href="http://blog.instantbird.org/2012/08/tab-completion-in-instantbird-1-2/">better tab complete</a>, a marker showing the last viewed messages, support for Bonjour and more. But the most exciting bits to me are our JavaScript implementations of <a href="http://lxr.instantbird.org/instantbird/source/chat/protocols/xmpp/">XMPP</a> (used for <a href="http://lxr.instantbird.org/instantbird/source/chat/protocols/facebook/">Facebook Chat</a> and <a href="http://lxr.instantbird.org/instantbird/source/chat/protocols/gtalk/">GTalk</a>, so far) and <a href="http://lxr.instantbird.org/instantbird/source/chat/protocols/irc/">IRC</a>!<br />
<br />
Why am I so excited for them? Mostly because they're extendable! (Well...and I guess because I wrote most of the IRC code.) I've <a href="http://clokep.blogspot.com/2012/06/irc-auto-performs.html">written</a> a bit about this before for IRC...but it will let add-ons do whatever they want to the IRC protocol. You should check out the implementations (links above), they're very hackable. Hopefully we can remove libpurple XMPP and fully switch to Instantbird's XMPP for the next release, once a few <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=14328">Mozilla bugs</a> are fixed.<br />
<br />
Did I also mention that these implementations (including the raw XMPP and Twitter, which Instantbird has supported since 1.0) are going to be included in <a href="http://www.mozilla.org/en-US/thunderbird/">Thunderbird </a>15, as part of it's new <a href="https://wiki.mozilla.org/Modules/Chat">chat feature</a>? Florian has done a great job of integrating our chat code there and it gives quite a different user experience than Instantbird, so don't be worried about Instantbird going away!<br />
<br />
Now of course, we always think of the future here (after all, releasing itself isn't really exciting when most of the features have been in nightly builds...forever), so we started making a list of some of the stuff we'd like to implement in future Instantbirds, you can check it out <a href="https://etherpad.mozilla.org/ib-1-3">here</a>. Some of them are very exciting, feel free to grab one and work on it.Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com3tag:blogger.com,1999:blog-7498677459674954485.post-47873347423618299082012-06-11T22:25:00.002-04:002012-12-03T11:22:30.307-05:00IRC Auto-PerformsThere have been a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=742675">few</a> <a href="https://bugzilla.instantbird.org/show_bug.cgi?id=1101">requests</a> to support "auto-performs" (sending commands to the IRC server after connection that the user types into a box or whatever). Personally I find this to be:<br />
<ol>
<li>A fairly awful user experience.</li>
<li>Confusing to new users.</li>
<li>Unnecessary.</li>
</ol>
I additionally don't like this idea since it requires us to have commands for all the common tasks you'd want to do in an auto-perform (or support sending absolutely raw messages to the server, which we actually do already in the /quote command). Essentially what I just described is writing our own scripting language...that seems pointless (and frankly, I have better things to do). I'm hoping to convince you with this post (and maybe a series of posts) that auto-performs aren't necessary and a trivial restartless extension can replace them.<br />
<br />
<h2>
Design</h2>
Part of the desire to <a href="http://clokep.blogspot.com/2011/04/why-rewrite-irc-protocol-plugin-part-2.html">replace the libpurple IRC protocol plugin</a> with a new JavaScript one built specifically for Instantbird (which is also now used in Thunderbird!) was to make the protocol fully extensible. There are <a href="http://clokep.blogspot.com/2011/03/so-called-irc-specifications.html">many revisions and unofficial extensions to IRC</a> and we might not necessarily want to support them all (especially if they only apply to a single network). Allowing all parts of the protocol implementation to be touched and extended seemed like a great way to handle this.<br />
<br />
Initially I tried to do this by making the IRC account into an XPCOM component (well it is one already, it's an prplIAccount, but I meant an IRC specific one: implementing ircIAccount, if you will). Unfortunately, this seemed to have a lot of overhead and got complicated extremely quickly. Anything I'd want to touch from a message handler (wait, wait...what's a handler?! I'll get back to that) would need to have methods written and exposed to access internal data of the account...does that sound very extensible to you? Well, it doesn't to me...<br />
<br />
Onto design two! (Well actually my first design...) Lots of JavaScript objects! The entire protocol is implemented as a set of JavaScript objects and the handlers directly touch and modify the account's data (of course there's methods for abstraction, etc.). This means that an extension has absolutely FULL access to every about an account...this also means an extension could seriously mess with and cause the protocol to stop working or do really crazy things, etc. Unfortunately there isn't really a way to avoid that. Hopefully people write good code.<br />
<br />
<h2>
Messages </h2>
I'm going to go into an aside about messages right now, even though it doesn't quite seem relevent yet. It will. IRC has a bunch of sub-protocols embedded within the IRC protocol (see the link above about unofficial extensions). We attempt to parse all the string messages and make pretty JavaScript objects out of them. I've actually identified five (yes, count that: five) different sub-"protocols" within IRC that we deal:<br />
<ol>
<li>IRC itself (i.e. <a href="http://tools.ietf.org/html/rfc1459">RFC 1459</a> / <a href="http://tools.ietf.org/html/rfc2812">RFC 2812</a> / various numeric extensions)</li>
<li><a href="http://www.irchelp.org/irchelp/rfc/ctcpspec.html">CTCP (the Client-to-Client Protocol)</a>,embedded in PRIVMSG commands of IRC</li>
<li>DCC (Direct Client-to-Client), a subprotocol of CTCP</li>
<li><a href="http://tools.ietf.org/html/draft-brocklesby-irc-isupport-03">ISUPPORT</a> (also known as Numeric 005), a method of negotiating capabilities between a client and server</li>
<li>And finally, handling of IRC Services (there's a lot of them and no specification, but we treat them specially)</li>
</ol>
Briefly what happens when we receive a raw message over the wire, we create an <a href="http://hg.instantbird.org/instantbird/file/b8d8b6e60aef/chat/protocols/irc/irc.js#l14">ircMessage object out of it using a variety of regular expressions</a>. This object has a variety of fields (see the link for details), including the command, who sent the message and the parameters.<br />
<br />
If the message is identified as a CTCP message, we then morph the ircMessage into a <a href="http://hg.instantbird.org/instantbird/file/b8d8b6e60aef/chat/protocols/irc/ircCTCP.jsm#l44">CTCPMessage</a>, which can be morphed into a <a href="http://hg.instantbird.org/instantbird/file/b8d8b6e60aef/chat/protocols/irc/ircDCC.jsm#l20">DCCMessage</a>. Additionally, a 005 reply can be parsed into a <a href="http://hg.instantbird.org/instantbird/file/b8d8b6e60aef/chat/protocols/irc/ircISUPPORT.jsm#l22">isupportMessage</a>. And last, but not least, a received PRIVMSG can also be parsed into a <a href="http://hg.instantbird.org/instantbird/file/b8d8b6e60aef/chat/protocols/irc/ircServices.jsm#l19">ServiceMessage</a>. Each of these extends the IRC message without destroying information. (Yes, I'm realizing now that my choice of whether to use capitals is all messed up...) <br />
<br />
Well, why do we care...? By preparsing the strings into objects (as defined by any "specifications" that exist), we keep extensions from having to parse messages over and over again from strings.<br />
<br />
<h2>
Handlers</h2>
A handler is simply what I call the object that contains the methods to deal with an incoming message. Pretty much, you get to say "Only send me ISUPPORT messages!" or "Only send me CTCP messages!" and voila, you only get that type of message. Each message type has a field that is used to choose the method to run (for the IRC messages, the "command", for CTCP the "CTCP command", ISUPPORT the "parameter", etc.) This sounds a lot more complicated than it is, I think a brief <a href="https://bitbucket.org/clokep/irc-extras/src/6f778f17172a/example/bootstrap.js">example</a> is in order:<br />
<pre class="brush: javascript">
var ircSimpleExample = {
// The name here is really only used in error messages.
name: "IRC Simple Example",
// Slightly above the default priority so we run before the main IRC handler.
priority: ircHandlers.DEFAULT_PRIORITY + 10,
// Run this for all accounts (note that the 'this' object in this method is
// the JavaScript account object.
isEnabled: function() true,
// The commands we want to handle. For each of these, the account object is
// bound to 'this' and the single parameter is of the type that you've
// registered your handle.
commands: {
"001": function(aMessage) {
// At the 001 response we've successfully connected to the server.
// Send an IDENTIFY command to NickServ.
this.sendMessage("PRIVMSG", ["NickServ", "IDENTIFY <your password>"]);
// Return false so the default handler still runs.
return false;
}
}
}</pre>
<br />
Just like that we've designed a handler! Whenever the 001 method is received from the server, this function will run and attempt to identify with the NickServ (of course this could use a bit more security on it, but it's to demonstrate the possibilities). (The sendMessage function takes the command to send and an array of parameters to send.)<br />
<br />
As this is already a long post, I think I'll cut this off now and continue this at another time, but I hope I'm beginning to convince you that allowing directy access to the account and protocol implementation is a more powerful (and even simpler in many ways, in my opinion) alternative to "auto-performs". The one major downside I see to this, is that it requires a bit more understanding of the actual protocol level implementation, I don't feel that knowing you need to use "PRIVMSG" as a command instead of /msg is a huge issue, however.Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com1tag:blogger.com,1999:blog-7498677459674954485.post-8545418873742094012012-01-15T10:00:00.000-05:002012-12-03T11:20:50.541-05:00Instantbird Contact List Hack #2There was a <span id="goog_1986241120"></span><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=987">request</a> <span id="goog_1986241121"></span>on the Instantbird Bugzilla to always show contacts in the contact list as the "big" contact (as shown when a contact is selected). Similarly to my <a href="http://clokep.blogspot.com/2011/10/instantbird-contact-list-hack.html">last post</a>, this can easily be done with userChrome.css. See the post if you don't know what userChrome.css is.<br />
<br />
Again, we're simply going to always apply a specific CSS style to the contacts, namely we'll be modifying the behavior of <a href="http://lxr.instantbird.org/instantbird/source/instantbird/content/blist.css#38">blist.css</a>. I'm sure you don't really care about that and just want the code, well I'll oblige:<br />
<br />
<pre class="brush: css">/* Expand all contacts to the big contact. */
contact {
-moz-binding: url("chrome://instantbird/content/contact.xml#contact-big") !important;
-moz-box-orient: vertical !important;
-moz-box-align: stretch !important;
}
</pre>
And that's it! Restart Instantbird and you should always have big contacts. I haven't seen any issues of using this (missing or wrong behavior), but of course your mileage might vary. Have fun!Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com5tag:blogger.com,1999:blog-7498677459674954485.post-22161578029775408612011-10-31T20:20:00.001-04:002013-04-27T09:30:58.070-04:00Instantbird Contact List HackA friend of mine asked me if there was a way to have selected contacts in the contact list NOT expand to two lines (where the status goes onto the second line) in Instantbird.<br />
<br />
There's actually no option to do this in Instantbird, but with a little <a href="http://www-archive.mozilla.org/unix/customizing.html">userChrome</a> tweak, we can easily get this behavior (although with a couple caveats). You should be able to add a new folder <a href="http://instantbird.com/faq.html#profilefolder">inside your profile</a> called chrome. Inside of this make a new file called <span style="font-family: "Courier New",Courier,monospace;">userChrome.css</span> and place the following:<br />
<pre class="brush: css">#buddylistbox:focus > contact[selected] {
-moz-binding: url("chrome://instantbird/content/contact.xml#contact") !important;
-moz-box-orient: horizontal !important;
}</pre>
Save the file and restart...and that's it! Now your selected contacts should be on one line, just like your unselected contacts.<br />
<br />
I did mention there was a caveat though! If you want to expand a contact (to see all the protocols, etc. that you've merged together) you'll need to use the arrow keys: right arrow expands a contact, left arrow collapses a contact. (You need to do this since the chevron icon that lets you expand/collapse isn't shown on a non-selected contact.) <br />
<br />
(Some more technical details: we're forcing the standard contact template to be used instead of the contact-big template, even when the contact is expanded; i.e. we're overwriting the command given <a href="http://lxr.instantbird.org/instantbird/source/instantbird/content/blist.css#44">blist.css</a>.)Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com1tag:blogger.com,1999:blog-7498677459674954485.post-34476429795421163082011-09-03T10:31:00.000-04:002011-09-03T10:31:20.343-04:00Adding a protocol to Instantbird (Part 2)I had <a href="http://clokep.blogspot.com/2011/06/adding-new-protocol-sipeoffice.html">previously talked about adding a protocol to Instantbird</a>, that focused on adding SIPE (Microsoft Office Communicator support). Since then I've been slowly working on defeating SIPE. Fortunately I found a few flags that help us compile it easily in Instantbird: we can declare that we do <i>not</i> have gmime and the standard libpurple MIME functions will be used (they might not be as good, but it keeps from adding >10 MB of source to Instantbird).<br />
<br />
Some modifications to the SIPE source were made to compile it in Instantbird (note that most of the changes were probably more based on using MSVC, than having to do with Instantbird). The code is also broken up into a few different sections the core, api, and purple are ones we care about (they're working on making a general Office Communicator protocol library, so the purple folder contains the libpurple bindings that use the api, while the core is private).<br />
<br />
<br />
<b>Purple</b><br />
Changes to purple consisted mostly of ifdefs that remove some header files not supported on Windows. For example, I encountered a few of:<br />
#include <unistd.h><br />
Luckily there was already a define HAVE_UNISTD_H, so I just needed to add:<br />
#ifdef HAVE_UNISTD_H<br />
#include <unistd.h><br />
#endif<br />
<br />
Easy! There were also a couple other issues, but those were rather trivial.<br />
<br />
<b>Core</b><br />
There isn't a specific issue in the core I'd like to highlight, it did use a few glib functions which we didn't have (we removed the files, as they were unused), they were all reimplemented in libpurple though, so we were able to just define the function calls to the libpurple variants.<br />
<b> </b><br />
<b> API</b><br />
This had similar issues the core (in particular, there was a function which used g_usleep, which is blocking and a definite no-no for a protocol plug-in, I've removed that...hopefully it doesn't break anything!) In addition to that, we needed to use the libpurple l10n system instead of glib's gi18n.h, this was easily copied from libpurple's internal API though.<br />
<br />
So at this point...I have a copy of SIPE compiled! Unfortunately since I'm using Visual Studio Express I cannot compile on my computer and deploy to other computers for testing (a Mozilla issue with how it uses some of the header files, etc., I believe). I'm looking into trying to get this to work though, apparently using the exact same copy of MSVC Redistributable might help. Once this is tested, hopefully it'll land in Instantbird for use!<br />
<br />
<b>Sametime support</b><br />
Unrelated to SIPE, but recently I landed a patch in Instantbird to add back Sametime support (Sametime is Lotus Notes' equivalent to Office Communicator). You can see the gory details in <a href="https://bugzilla.instantbird.org/show_bug.cgi?id=102">bug 102</a>, but in general it's similar to what I've (not gone into great detail about) here.<b> </b> Most of getting Sametime to work was rewriting some C code that doesn't compile in MSVC. There's also a <a href="https://bugzilla.instantbird.org/attachment.cgi?id=797&action=diff">diff </a>of all the changes I made to the libpurple Sametime plugin and the external library (called <a href="http://meanwhile.sourceforge.net/">Meanwhile</a>) to get it to work. Once I get Monotone (a version control system) set up I'll look into getting these changes pushed back to libpurple to avoid diverging code bases.Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com3tag:blogger.com,1999:blog-7498677459674954485.post-76332029119261894402011-06-18T09:53:00.000-04:002011-06-18T09:53:58.924-04:00Adding a new protocol (SIPE/Office Communicator) to Instantbird (part 1)<a href="http://en.wikipedia.org/wiki/Office_Communicator">Microsoft Office Communicator</a> is an instant messaging client that integrates into the <a href="http://en.wikipedia.org/wiki/Microsoft_Exchange_Server">Exchange Messaging Server</a> (the protocol behind it is an extended version of SIP/SIMPLE). Anyway, there's a <a href="http://developer.pidgin.im/wiki/WhatIsLibpurple">libpurple</a> (i.e. the backend of <a href="http://instantbird.com/">Instantbird</a> and <a href="http://pidgin.im/">Pidgin</a>) protocol plug-in for OCS (Office Communicator Server) called <a href="http://sipe.sourceforge.net/">SIPE</a>. (It's also striving for a generic library to connect to OCS, but that's not quite there yet.)<br />
<br />
I've been interested in getting this to compile in the Instantbird framework for a while now, adding a new protocol to Instantbird. First of course I need the SIPE source, I chose to grab a release <a href="http://sourceforge.net/projects/sipe/files/sipe/pidgin-sipe-1.11.2/">source bundle</a> instead of using the <a href="git+ssh://mob@repo.or.cz/srv/git/siplcs.git">git repository</a>, just for ease moving files around, etc. There's a rather vague <a href="http://sourceforge.net/apps/mediawiki/sipe/index.php?title=Windows_Build">Windows build</a> page on the wiki that I started with, says I need:<br />
<ul><li>libpurple >2.4.0 (we have 2.7.11)</li>
<li>libglib >2.12.0 (we have 2.28.6)</li>
<li>libxml2 (we have this)</li>
<li>gmime >2.4 (not currently used)</li>
</ul>So great, <a href="https://wiki.instantbird.org/Instantbird:Third_party_code">we have most of the dependencies</a>! We just need one more. So I go grab, <a href="http://developer.gnome.org/gmime/">gmime </a>from the GNOME website (2.5.7, which is the newest stable, currently), again as a source bundle and put the necessary files in purple/libraries/gmime and edit the makefile so it will (attempt) to compile. But great -- it requires <a href="http://www.gnu.org/software/libiconv/">libiconv</a>, which apparently is very difficult to compile, especially on Windows. Luckily for me there's a Windows version (not a port, but one that uses the native Win32 APIs with the same interface): <a href="http://code.google.com/p/win-iconv/">win-iconv</a>. This compiled like a champ when added as purple/libraries/iconv.<br />
<br />
Unfortunately when I went back to compiling gmime, it attempts to access parts of glib we're not using (gio, in particular) and thus is not in our source code. I can grab the <a href="http://developer.gnome.org/glib/">glib</a> source (2.28.6 to match, of course) and add the gio subfolder, but first we should check if this part of gmime is even used by SIPE! (My guess is that it is <i>not</i>, but that's where I'm at now. I'll post back when I get further.Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com0tag:blogger.com,1999:blog-7498677459674954485.post-29244633319547906472011-05-16T21:30:00.001-04:002011-05-17T06:36:08.536-04:00Compiling InstantbirdIn the past I've tried to compile a few different programs that use the Mozilla toolkit to various levels of success. I've tried to compile Thunderbird, Songbird and Instantbird at various points. I got Thunderbird to compile, but it only worked sporadically (although I think that was Firefox moving so fast that Thunderbird couldn't keep up), Songbird I gave up on rather quickly and Instantbird I've tried a few times.<br />
<br />
Last summer I had Instantbird compiling on my old laptop (a Lenovo T60), which is >5 years old at this point and has had the heatsink / fan replaced twice -- a known issue with that model laptop. Needless to say, that laptop didn't like compiling something on Windows that took approximately an hour with a large number of reads and writes to the hard drive. This mixed with it being an old dual core + a 5400 RPM meant I'd be waiting a LONG time for my code to compile. I got a Thinkpad X201 this past summer, so I finally got around to setting up a development environment on it and was able to get Instantbird to compile fully today. I've outlined the steps I've followed: kind of to mirror the <a href="https://developer.mozilla.org/En/Simple_Thunderbird_build">Simple Thunderbird Build</a> page on MDC.<br />
<br />
I've done this using Microsoft Windows 7 Professional (64-bit) with Service Pack 1. (4.00 GB of RAM, Intel Core i7 M620 2.67 GHz). Throughout these steps, the defaults locations and options are used in the installers.<br />
<br />
<span style="font-size: large;"><b>Build Requirements:</b></span><br />
<b>Visual Studio Express:</b><br />
We need to install Visual Studio Express, specifically VC8 (2005) with Service Pack 1. (Mozilla compiles with VC9 and VC10 to various degrees, but it seems libpurple only compiles with VC8, also this is what's on the Instantbird buildbot, so I like having the same version.) I couldn't find this on Microsoft's website but I found it on <a href="http://www.softpedia.com/get/Programming/Other-Programming-Files/Microsoft-Visual-C-Toolkit.shtml">Softpedia</a> (which is a legitimate site). Anyway, download the installer and install it (which will download the actual compiler from Microsoft), ensure that you also install the IDE (which is checked by default).<br />
<br />
This will only install VC8, the initial release. We also need to install <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=7b0b0339-613a-46e6-ab4d-080d4d4a8c4e">Service Pack 1</a>. I personally did this using Windows Update, but one of the installers from there should also work.<br />
<br />
<b>Microsoft Windows SDK:</b><br />
Specifically we need the <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c17ba869-9671-4330-a63e-1fd44e0e2505&displaylang=en">Windows 7 SDK</a> (for Jumplist, Aero, etc. support). Download and install the SDK, this one took a while for me to install. I ate dinner while it was installing (pasta, if you're curious -- I already had sauce made).<br />
<br />
There's a linker error when using VC8 and the Windows 7 SDK, so we'll need to install a <a href="http://support.microsoft.com/kb/949009/">hotfix </a>for that (I tried without it and I ran into the issue). I had to download the "VS80sp1-KB949009-IA64-INTL.exe" version (there's also an X86 and an X64 version). Choose the one that works.<br />
<br />
<b>Microsoft Macro Assembler:</b><br />
In order to properly assemble the code we need to <a href="http://www.microsoft.com/downloads/en/details.aspx?familyid=7A1C9DA0-0510-44A2-B042-7EF370530C64&displaylang=en">install MASM</a> (which I think will eventually be included in MozillaBuild, but it isn't currently). Again, just install it with the defaults.<br />
<br />
<b>MozillaBuild:</b><br />
Almost there, I promise. In order to get a *nix type shell to run make, etc. in we'll use a package from Mozilla that includes MSYS, make, Mercurial, etc. Download and <a href="http://ftp.mozilla.org/pub/mozilla.org/mozilla/libraries/win32/MozillaBuildSetup-Latest.exe">install MozillaBuild</a>, the latest should work fine.<br />
<br />
Now, an unknown step: you might require the <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a5c84275-3b97-4ab7-a40d-3802b2af5fc2&displaylang=en">Microsoft Visual C++ 2008 SP1 Redistributable Package</a>. I don't know if you need this or not since I <i>already</i> had it, most likely from a previous program I've installed.<br />
<br />
We should be ready to build now pretty much. For some more information for this stuff you can check out the Mozilla Developer Network pages I used to get this information: <a href="https://developer.mozilla.org/En/Developer_Guide/Build_Instructions">Build Instructions</a>, <a href="https://developer.mozilla.org/En/Developer_Guide/Build_Instructions/Windows_Prerequisites">Windows Build Prerequisites</a> and <a href="https://developer.mozilla.org/cn/VC8_Build_Instructions">MSVC8 Build Instructions</a>.<br />
<br />
<b><span style="font-size: large;">Checkout the Code:</span></b><br />
We need to checkout the code. I originally checked out the code with TortoiseHg (which is what I normally use), but the version of Mercurial included is significantly greater than the one included in MozillaBuild and this caused me issues later on. Thus, we'll check out the code on the command line. Start by launching the bash shell, which is at C:\mozilla-build\start-msvc8.bat (don't use the x64 version). There's a version here which corresponds to each version of VS.<br />
<br />
Once this finishes loading you'll be in the home directory (which is in the root of your user's documents and settings folder, i.e. for me: C:\Users\clokep). You'll want to do the following:<br />
<span style="font-family: "Courier New",Courier,monospace;">hg clone https://hg.instantbird.org/instantbird</span><br />
<br />
This might take a few minutes depending on how good your internet connection is. (The Instantbird source isn't THAT big though, it shouldn't take too long.)<br />
<br />
Then we'll need to change into the instantbird directory that was just created and download the Mozilla source code:<br />
<span style="font-family: "Courier New",Courier,monospace;">cd instantbird</span><br />
<span style="font-family: "Courier New",Courier,monospace;">python client.py checkout</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span>Now this step? This one is gonna take a while. It took me like a couple of hours. It pulls the Mozilla source code, which is large and has many changesets. Just let it go, it'll give you progress occasionally (changes, manifests, files, etc.)<br />
<br />
<span style="font-size: large;"><b>Compiling Instantbird:</b></span><br />
<b> </b>We need to set up the options we want to build with. These are read from a .mozconfig (don't miss the "." in the front!). The contents of the .mozconfig that worked for me are:<br />
<span style="font-family: "Courier New",Courier,monospace;">ac_add_options --enable-application=instantbird</span><br />
<span style="font-family: "Courier New",Courier,monospace;">mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-ib-release</span><br />
<span style="font-family: "Courier New",Courier,monospace;">ac_add_options --disable-accessibility</span><br />
<br />
The first option says to build Instantbird, the second gives an output directory and the third <a href="https://developer.mozilla.org/en/atlbase.h">disables accessibility</a> (not really sure why we need to do this, but we'll get that error at that link otherwise).<br />
<br />
Finally (back in the bash shell) type:<br />
<span style="font-family: "Courier New",Courier,monospace;">make -f client.mk build</span><br />
<br />
<br />
Now sit back and relax. My build took about an hour to finish, maybe a bit less -- I wasn't fully paying attention. Once it's done you should see something like:<br />
<span style="font-family: "Courier New",Courier,monospace;">Processed 1 file, writing output:</span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">Output: "c:\Users\clokep\instantbird\objdir-ib-release\instantbird\installer\win</span><br />
<span style="font-family: "Courier New",Courier,monospace;">dows\instgen\helper.exe"</span><br />
<span style="font-family: "Courier New",Courier,monospace;">Install: 2 pages (128 bytes), 1 section (16416 bytes), 2579 instructions (72212</span><br />
<span style="font-family: "Courier New",Courier,monospace;">bytes), 369 strings (10198 bytes), 1 language table (230 bytes).</span><br />
<span style="font-family: "Courier New",Courier,monospace;">Uninstall: 5 pages (320 bytes),</span><br />
<span style="font-family: "Courier New",Courier,monospace;">1 section (16416 bytes), 2063 instructions (57764 bytes), 388 strings (10828 byt</span><br />
<span style="font-family: "Courier New",Courier,monospace;">es), 1 language table (314 bytes).</span><br />
<span style="font-family: "Courier New",Courier,monospace;">Datablock optimizer saved 123940 bytes (~17.6%).</span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">Using zlib compression.</span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">EXE header size: 63488 / 39424 bytes</span><br />
<span style="font-family: "Courier New",Courier,monospace;">Install code: 99564 / 99560 bytes</span><br />
<span style="font-family: "Courier New",Courier,monospace;">Install data: 118002 / 241950 bytes</span><br />
<span style="font-family: "Courier New",Courier,monospace;">Uninstall code+data: 398654 / 398646 bytes</span><br />
<span style="font-family: "Courier New",Courier,monospace;">CRC (0x062AF3F5): 4 / 4 bytes</span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">Total size: 679712 / 779584 bytes (87.1%)</span><br />
<span style="font-family: "Courier New",Courier,monospace;">c:/Users/clokep/instantbird/objdir-ib-release/mozilla/config/nsinstall.exe -D ..</span><br />
<span style="font-family: "Courier New",Courier,monospace;">/../../mozilla/dist/bin/uninstall</span><br />
<span style="font-family: "Courier New",Courier,monospace;">cp instgen/helper.exe ../../../mozilla/dist/bin/uninstall</span><br />
<span style="font-family: "Courier New",Courier,monospace;">make[5]: Leaving directory `/c/Users/clokep/instantbird/objdir-ib-release/instan</span><br />
<span style="font-family: "Courier New",Courier,monospace;">tbird/installer/windows'</span><br />
<span style="font-family: "Courier New",Courier,monospace;">make[4]: Leaving directory `/c/Users/clokep/instantbird/objdir-ib-release/instan</span><br />
<span style="font-family: "Courier New",Courier,monospace;">tbird'</span><br />
<span style="font-family: "Courier New",Courier,monospace;">make[3]: Leaving directory `/c/Users/clokep/instantbird/objdir-ib-release'</span><br />
<span style="font-family: "Courier New",Courier,monospace;">make[2]: Leaving directory `/c/Users/clokep/instantbird/objdir-ib-release'</span><br />
<span style="font-family: "Courier New",Courier,monospace;">make[1]: Leaving directory `/c/Users/clokep/instantbird/objdir-ib-release'</span><br />
Now, to test that the build actually worked we can browse to the compiled executable and run it:<br />
<div style="font-family: "Courier New",Courier,monospace;">cd objdir-ib-release/mozilla/dist/bin</div><div style="font-family: "Courier New",Courier,monospace;">instantbird.exe -P dev -no-remote</div><br />
The -P option specifies a profile name (dev), the second option (-no-remote) allows you to run a second Instantbird instance (since I assume you use Instantbird to IM...you probably want to be able to run a second one, if you don't use it...shame on you. Try not to close the wrong Instantbird when you're working on stuff).<br />
<br />
Hopefully this will help someone else get started on hacking Instantbird. There's other good ways you can hack too if your computer can't handle compiling, including unpacking omni.jar.<br />
<br />
One last tidbit is to possibly add the option to your .mozconfig:<br />
<div style="font-family: "Courier New",Courier,monospace;">--<span id="summary_alias_container"><span id="short_desc_nonedit_display">enable-chrome-format=flat</span></span></div><br />
<span id="summary_alias_container"><span id="short_desc_nonedit_display">This will not package anything in JARs (which pretty much just get in the way while developing). See <a href="https://developer.mozilla.org/en/JAR_Packaging">here</a> for more info.</span></span><br />
<br />
<span id="summary_alias_container"><span id="short_desc_nonedit_display">Edit: Fixed the path to the executable thanks to Florian. And fixed a spelling error in the title. </span></span>Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com2tag:blogger.com,1999:blog-7498677459674954485.post-48217994382097689422011-04-30T13:01:00.000-04:002011-04-30T13:01:29.625-04:00Why rewrite the IRC protocol plugin? (Part 2)I <a href="http://clokep.blogspot.com/2010/12/why-rewrite-irc-into-javascript.html">previously wrote about</a> why I'm rewriting the libpurple IRC implementation into a JavaScript implementation for Instantbird. This is kind of a follow up, but more focused on what I hope to accomplish feature wise for IRC in Instantbird. A good overview to look at is the <a href="https://bugzilla.instantbird.org/showdependencygraph.cgi?id=507&display=web&rankdir=LR">dependencies of bug 507</a> (implement IRC in JavaScript) -- you'll want to look to the left of bug 507, these are the bugs that depend on 507 (as opposed to blocking 507).<br />
<br />
My overall hope is to make Instantbird the easiest and simplest IRC client to use. I've found that most IRC clients tend to depend a great deal on commands and essentially being a very thin GUI layer on top of the protocol. I don't really see the reason for this, we should attempt to hide the protocol as much as possible from the users. This means fitting the IRC command responses into the GUI wherever possible and possibly "losing" some features compared to other IRC clients, although I think that's a matter of perspective. (For example, there's often an IRC command to list all the channels available, I <i>do not</i> think this should be implemented as a text command, but it should be available via the join chat GUI).<br />
<br />
Now some more specific plans:<br />
<ul><li>Support for IRC services would be pretty awesome, I'm not sure whether this would be part of the main protocol or as an extension, but it should be able to handle NickServ mostly autonomously (possibly even automatically registering the nick, etc.). MemoServ could be implemented as a message service once there is UI for that in Instantbird. I'm not sure how ChanServ could be handled in the UI, but I'll think more about this. See <a href="https://bugzilla.instantbird.org/show_bug.cgi?id=720">bug 720</a> for more info. (And yes, there are multiple versions of IRC services, but we can attempt to support a subset and otherwise just leave it up to the user. Ideally servers would have supported this stuff...but that's not how IRC works.)</li>
<li>The UI should be more responsive to the modes of the user and to the channel. For example, if the user does not have permission to edit the topic, it should not be editable in the UI (<a href="https://bugzilla.instantbird.org/show_bug.cgi?id=318">bug 318</a>). Also, if a user is a (half-)operator, there should be UI to have cause other users to be given (h)op (<a href="https://bugzilla.instantbird.org/show_bug.cgi?id=597">bug 597</a>). In terms of channel modes, there could be UI to show the channel is invite only or that it's a hidden channel.</li>
</ul>There's some not as user visible improvements I'd like to make:<br />
<ul><li>Supporting more authentication methods in IRC (<a href="https://bugzilla.instantbird.org/show_bug.cgi?id=719">bug 719</a>).</li>
</ul>There's also a few "bugs" in the libpurple implementation that this will fix:<br />
<ul><li>The <span style="font-family: "Courier New",Courier,monospace;">/msg</span> command doesn't show outgoing messages (<a href="https://bugzilla.instantbird.org/show_bug.cgi?id=188">bug 188</a>). I believe this is actually already fixed.</li>
<li>IRC channels should automatically rejoin on reconnect (<a href="https://bugzilla.instantbird.org/show_bug.cgi?id=385">bug 385</a>).</li>
<li>Chats with other users should show whether they are available or not (<a href="https://bugzilla.instantbird.org/show_bug.cgi?id=613">bug 613</a>).</li>
</ul>These are just some ideas and it's a long ways off for feature parity with libpurple even. (Although since Instantbird doesn't support all the features of Pidgin, feature-parity in this case doesn't include things like DCC transfer, etc. until Instantbird itself supports those.)<br />
<br />
Right now, the code is mostly usable (and I'm finally catching any exceptions that are thrown so the code shouldn't crash anymore), and works fine. The one issue I'm having is sometimes I'm unable to reconnect when the connection is lost, but I think I've finally fixed that issue and reconnection should happen automatically!<br />
<br />
One last quick note, if you happen to have the <a href="https://hg.instantbird.org/experiments">repository</a> checked out, you'll want to update on the default branch from now on as I've merged the separate branches together under subfolders.<br />
<ul></ul>Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com0tag:blogger.com,1999:blog-7498677459674954485.post-31048750209382050692011-03-08T22:20:00.000-05:002011-03-08T22:20:20.104-05:00The so-called IRC "specifications"In a <a href="http://clokep.blogspot.com/2010/12/why-rewrite-irc-into-javascript.html">previous post</a> I had briefly gone over the "history of IRC" as I know it. I'm going to expand on this a bit as I've come to understand it a bit more while reading through documentation. (Hopefully it won't sound too much like a rant, as it is all driving me crazy!)<br />
<br />
<b>IRC Specifications</b> <br />
So there's the original specification (<a href="http://tools.ietf.org/html/rfc1459">RFC 1459</a>) in May 1993; this was expanded and replaced by four different specifications (<a href="http://tools.ietf.org/html/rfc2810">RFC 2810</a>, <a href="http://tools.ietf.org/html/rfc2811">2811</a>, <a href="http://tools.ietf.org/html/rfc2812">2812</a>, <a href="http://tools.ietf.org/html/rfc2813">2813</a>) in April 2000. Seems pretty straightforward, right?<br />
<br />
<b>DCC/CTCP</b> <br />
Well, kind of...there's also the DCC/CTCP specifications, which is a separate protocol embedded/hidden within the IRC protocol (e.g. they're sent as IRC messages and parsed specially by clients, the server sees them as normal messages). DCC/CTCP is used to send files as well as other particular messages (ACTION commands for roleplaying, SED for encrypting conversations, VERSION to get client information, etc.). Anyway, this get's a bit more complicated -- it starts with the <a href="http://www.irchelp.org/irchelp/rfc/dccspec.html">DCC specification</a>. This was replaced/updated by the <a href="http://www.irchelp.org/irchelp/rfc/ctcpspec.html">CTCP specification</a> (which fully includes the DCC specification) in 1994. An <a href="http://www.invlogic.com/irc/ctcp.html">"updated" CTCP specification</a> was released in February 1997. There's also a <a href="http://www.invlogic.com/irc/ctcp2_intro.html">CTCP/2 specification</a> from October 1998, which was meant to reformulate a lot of the previous three versions. And <i>finally</i>, there's the DCC2 specification (two parts: <a href="http://tools.ietf.org/html/draft-smith-irc-dcc2-negotiation-00">connection negotiation</a> and <a href="http://www.dcc2.org/files/dcc2/draft-smith-irc-dcc2-files-00.txt">file transfers</a>) from April 2004.<br />
<br />
But wait! I lied...that's not really the end of DCC/CTCP, there's also a bunch of extensions to it: <a href="http://www.visualirc.net/tech-tdcc.php">Turbo DCC</a>, <a href="http://xa.bi/files/irc/xdcc.3.3.0b.irc">XDCC (eXtended DCC)</a> in 1993, <a href="http://www.visualirc.net/tech-wboard.php">DCC Whiteboard</a>, and a few other variations of this: RDCC (Reverse DCC), SDD (Secure DCC), DCC Voice, etc. Wikipedia has a <a href="http://en.wikipedia.org/wiki/Direct_Client-to-Client">good summary</a>.<br />
<br />
Something else to note about the whole DCC/CTCP mess...parts of it just <i>don't</i> have any documentation. There's <i>none </i>at all for SED (at least that I've found, I'd love to be proved wrong) and very little (really just a mention) for DCC Voice.<br />
<br />
So, we're about halfway through now. There's a bunch of extensions to the IRC protocol specifications that add new commands to the actual protocol.<br />
<br />
<b>Authentication</b> <br />
Originally IRC had no authentication ability except the PASS command, which very few servers seem to use, a variety of mechanisms have replaced this, including <a href="http://hg.atheme.org/atheme/atheme/raw-file/tip/doc/SASL">SASL authentication</a> (both PLAIN and BLOWFISH methods, although BLOWFISH isn't documented); and SASL itself is covered by at least <a href="http://tools.ietf.org/html/rfc2222">four</a> <a href="http://tools.ietf.org/html/rfc4422">RFCs</a> <a href="http://tools.ietf.org/html/rfc2595">in this</a> <a href="http://tools.ietf.org/html/rfc4616">situation</a>. There also seems to be a method called "Auth" which I haven't been able to pin down, as well as Ident (which is a more general protocol authentication method I haven't looked into yet).<br />
<br />
<b>Extension Support</b><br />
This includes a few that generally add a way by which servers are able to tell their clients exactly what a server supports. The first of these was RPL_ISUPPORT, which was defined as a <a href="http://tools.ietf.org/html/draft-brocklesby-irc-isupport-03">draft specification</a> in January 2004, and <a href="http://tools.ietf.org/html/draft-hardy-irc-isupport-00">updated</a> in January of 2005.<br />
<br />
A similar concept was defined as <a href="http://tools.ietf.org/html/draft-mitchell-irc-capabilities-01">IRC Capabilities</a> in March 2005.<br />
<br />
<b>Protocol Extensions</b><br />
IRCX, a Microsoft extension to IRC used (at one point) for some of it's instant messaging products <a href="http://tools.ietf.org/html/draft-pfenning-irc-extensions-04">exists as a draft</a> from June 1998.<br />
<br />
There's also:<br />
<ul><li>The <a href="http://hg.atheme.org/charybdis/charybdis/raw-file/tip/doc/monitor.txt">MONITOR</a> command.</li>
<li><a href="http://hg.atheme.org/charybdis/charybdis/raw-file/tip/doc/modeg.txt">User mode +g</a>.</li>
<li><a href="http://hg.atheme.org/charybdis/charybdis/raw-file/tip/doc/services.txt">Services compatibility modes</a>.</li>
<li><a href="http://hg.atheme.org/charybdis/charybdis/raw-file/tip/doc/account-notify.txt">Account-notify client capability</a>.</li>
<li><a href="http://hg.atheme.org/charybdis/charybdis/raw-file/tip/doc/tgchange.txt">Target change for messages</a>.</li>
</ul><b>Services</b> <br />
To fill in some of the missing features of IRC, services were created (Wikipedia has a good <a href="http://en.wikipedia.org/wiki/Internet_Relay_Chat_services">summary</a> again). This commonly includes ChanServ, NickServ, OperServ, and MemoServ. Not too hard, but different server packages include different services (or even the same services that behave differently), one of more common ones is <a href="http://www.anope.org/docgen/1.8/en_us/">Anope</a>, however (plus they have awesome documentation, so they get a link).<br />
<br />
There was an attempt to standardize how to interact with services called IRC+, which included three specifications: <a href="http://www.irc-plus.org/specs/confctrl-draft.html">conference control protocol</a>, <a href="http://www.irc-plus.org/specs/identity-draft.html">identity protocol</a> and <a href="http://www.irc-plus.org/specs/subscriptions-draft.html">subscriptions protocol</a>. I don't believe this are supported widely (if at all).<br />
<br />
<b>IRC URL Scheme</b><br />
Finally this brings us to the IRC URL scheme of which there are a few versions. A draft from August 1996 defines the original <a href="http://tools.ietf.org/html/draft-mirashi-url-irc-01">irc: URL scheme</a>. This was updated/replaced by <a href="http://tools.ietf.org/html/draft-butcher-irc-url-04">another draft</a> which defines irc: and ircs: URL schemes.<br />
<br />
As of right now that's all that I've found...an awful lot. Plus it's not all compatible with each other (and sometimes out right contradicts each other). Often newer specifications say not to support older specifications, but who knows what servers/clients you'll end up talking to! It's difficult to know what's used in practice, especially since there's an awful lot of <a href="http://en.wikipedia.org/wiki/Comparison_of_IRC_daemons">IRC servers</a> out there. Anyway, if someone does know of another specification, etc. that I missed please let me know!Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com0tag:blogger.com,1999:blog-7498677459674954485.post-85246334542386933592011-02-17T19:21:00.000-05:002011-02-17T19:21:32.273-05:00Status Update - February 17, 2011Another month has gone by so it's time for another status update. Unfortunately not as much got done this month as I was hoping, but here's a quick update of what I've worked on: <br />
<ul><li><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=690">Bug 690</a> - <span id="summary_alias_container"> <span id="short_desc_nonedit_display">jsProtoHelper could help registering commands</span></span></li>
<li><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=661">Bug 661</a> - <span id="summary_alias_container"> <span id="short_desc_nonedit_display">JavaScript accounts do not automatically set containsNick field on messages</span></span></li>
<li><span id="summary_alias_container"><span id="short_desc_nonedit_display"><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=686">Bug 686</a> -</span></span><span id="summary_alias_container"> <span id="short_desc_nonedit_display">Implement default chat name for getChatRoomDefaultFieldValues for js-proto</span></span></li>
</ul><span id="summary_alias_container"><span id="short_desc_nonedit_display">Florian also implemented a few things that are really helpful for JavaScript protocols:</span></span><br />
<ul><li><span id="summary_alias_container"><span id="short_desc_nonedit_display"> </span></span><span id="summary_alias_container"><span id="short_desc_nonedit_display"></span></span><span id="summary_alias_container"><span id="short_desc_nonedit_display"><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=649">Bug 649</a> - </span></span> <span id="summary_alias_container"> <span id="short_desc_nonedit_display">purple proxies should not be in the way of JavaScript protocols</span></span></li>
<li><span id="summary_alias_container"><span id="short_desc_nonedit_display"><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=118">Bug 118</a> - </span></span> <span id="summary_alias_container"> <span id="short_desc_nonedit_display">Extensions should be able to register commands.</span></span><span id="summary_alias_container"><span id="short_desc_nonedit_display"> </span></span></li>
</ul><span id="summary_alias_container"><span id="short_desc_nonedit_display">In addition, Twitter support was added to nightly builds as a JavaScript protocol (<a href="https://bugzilla.instantbird.org/show_bug.cgi?id=598">bug 598</a>).</span></span><br />
<span id="summary_alias_container"><span id="short_desc_nonedit_display"><br />
</span></span><br />
<span id="summary_alias_container"><span id="short_desc_nonedit_display">Hopefully next I'll implement most of the commands for IRC (within the next week) at which point I'll release a sample extension (which will overwrite the libpurple IRC implementation), allowing people to test without needing to make a new account, etc.</span></span>Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com0tag:blogger.com,1999:blog-7498677459674954485.post-89714534792161241752011-01-18T23:17:00.002-05:002011-01-18T23:20:39.120-05:00Status Update - January 18, 2011I haven't had an update in a few weeks (since early December) actually, so I thought I would post a bit about what I've worked on. I've fixed a bunch of bugs in the backend of Instantbird that allow work on JavaScript IRC protocol to continue:<br />
<ul><li><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=519">Bug 519</a> - <span id="summary_alias_container"> <span id="short_desc_nonedit_display">Extend jsProtoHelper to implement purpleIConvChat</span></span> (<a href="http://hg.instantbird.org/instantbird/rev/0166084ce2ae">check-in</a>) </li>
<li><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=495">Bug 495</a> - <span id="summary_alias_container"> <span id="short_desc_nonedit_display">purpleIAccount cannot access preferences via JavaScript protocol (<a href="http://hg.instantbird.org/instantbird/rev/a188a5cc3ff1">check-in)</a></span></span></li>
<li><span id="summary_alias_container"><span id="short_desc_nonedit_display"><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=648">Bug 648</a> - </span></span>Provide a default JS implementation of purpleIChatRoomField <span id="summary_alias_container"><span id="short_desc_nonedit_display">(<a href="http://hg.instantbird.org/instantbird/rev/61fc80a569d3">check-in</a>)</span></span></li>
<li><span id="summary_alias_container"><span id="short_desc_nonedit_display">[Reviewed] <a href="https://bugzilla.instantbird.org/show_bug.cgi?id=647">Bug 647</a> -</span></span> <span id="summary_alias_container"> <span id="short_desc_nonedit_display">Username split for JavaScript protocols</span></span><span id="summary_alias_container"><span id="short_desc_nonedit_display"> (<a href="http://hg.instantbird.org/instantbird/rev/a6c8fbf77e10">check-in</a>) </span></span></li>
<li><span id="summary_alias_container"><span id="short_desc_nonedit_display">[Reviewed] <no bug> - </span></span>Share the nsIClassInfo implementation between all the objects implemented in jsProtoHelper<span id="summary_alias_container"><span id="short_desc_nonedit_display"> (<a href="http://hg.instantbird.org/instantbird/rev/035f7d8d7f78">check-in</a>)</span></span><span id="summary_alias_container"> </span></li>
</ul>Also a few other random bugs I've worked on: <br />
<ul><li><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=625">Bug 625</a> - <span id="summary_alias_container"> <span id="short_desc_nonedit_display">Findbar broken on Windows in Conversation window</span></span> (<a href="http://hg.instantbird.org/instantbird/rev/2e8af77af2f2">check-in</a>)</li>
<li><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=629">Bug 629</a> - <span id="summary_alias_container"> <span id="short_desc_nonedit_display">Remove workaround for bug 503048</span></span> (<a href="http://hg.instantbird.org/instantbird/rev/ba4b9401791b">check-in</a>) </li>
<li><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=473">Bug 473</a> - <span id="summary_alias_container"> <span id="short_desc_nonedit_display">JS Logger line breaks don't play well on Windows</span></span> <a href="http://hg.instantbird.org/instantbird/rev/6a600b8a32c9">(check-in</a>)</li>
<li><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=593">Bug 593</a> - <span id="summary_alias_container"> <span id="short_desc_nonedit_display">JavaScript component does not have a method named: "onBeforeLinkTraversal"</span></span> (<a href="http://hg.instantbird.org/instantbird/rev/1b75f9fa4859">check-in</a>) </li>
</ul>Although none of these are really things that weren't working a few weeks ago, there are now real APIs for these for JavaScript protocols, allowing other protocols to use them and to <i>FULLY</i> implement them instead of hard coding values. In addition, a lot of the purplexpcom layer is now hidden from JavaScript protocols.<br />
<br />
There's a few things left to do for the JavaScript protocol layer:<br />
<ul><li><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=118">Bug 118</a> - <span id="summary_alias_container"> <span id="short_desc_nonedit_display">Extensions should be able to register commands.</span></span></li>
<li><span id="summary_alias_container"><span id="short_desc_nonedit_display"><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=650">Bug 650</a> - </span></span> <span id="summary_alias_container"> <span id="short_desc_nonedit_display">JavaScript accounts must be notified of status changes (a sketchy patch that exists that will work, but a better patch to core should be done)</span></span></li>
<li><span id="summary_alias_container"><span id="short_desc_nonedit_display"><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=623">Bug 623</a> - </span></span> <span id="summary_alias_container"> <span id="short_desc_nonedit_display">Auto-Join option field is hard coded for certain protocols (not <i>really</i> necessary, since it's still IRC, but it should be fixed)</span></span></li>
<li><span id="summary_alias_container"><span id="short_desc_nonedit_display"><a href="https://bugzilla.instantbird.org/show_bug.cgi?id=649">Bug 649</a> -</span></span> <span id="summary_alias_container"> <span id="short_desc_nonedit_display">Proxy should be available to JavaScript protocols (hopefully being handled by Florian)</span></span></li>
</ul><span id="summary_alias_container"><span id="short_desc_nonedit_display">A good summary of this is <a href="https://bugzilla.instantbird.org/showdependencygraph.cgi?id=507&display=web&rankdir=LR">the dependency graph of bug 507</a> (</span></span><span id="summary_alias_container"><span id="short_desc_nonedit_display">Implement IRC in JavaScript</span></span><span id="summary_alias_container"><span id="short_desc_nonedit_display">). Note that the IRC JavaScript work blocks <i>a lot</i> of UI work done for IRC. In particular Mook has been working on implementing notifications (i.e. Invites, and perhaps a few other commands), see <a href="https://bugzilla.instantbird.org/show_bug.cgi?id=628">Bug 628</a>. For other bugs, see the link above -- and if there's a strange UI feature that you think should be added, please file a bug and let us know about it!</span></span><br />
<br />
<span id="summary_alias_container"><span id="short_desc_nonedit_display">I've also worked a bit on sending outgoing text with rich formatting (bold, italics, underline, text size, etc.), this work is being tracked in <a href="https://bugzilla.instantbird.org/show_bug.cgi?id=634">Bug 634</a>. There's a proof on concept, but a lot of work needs to be done for it, but it's sort of working right now.</span></span><span id="summary_alias_container"><span id="short_desc_nonedit_display"> </span></span><br />
<br />
<span id="summary_alias_container"><span id="short_desc_nonedit_display">As I alluded to in my last blog post, the JavaScript protocols would be used to implement Twitter. Work for this is occurring in <a href="https://bugzilla.instantbird.org/show_bug.cgi?id=598">Bug 598</a>, where Florian has implemented (very) basic Twitter support.</span></span><br />
<br />
<span id="summary_alias_container"><span id="short_desc_nonedit_display">My plans for the next bit:</span></span><br />
<ul><li><span id="summary_alias_container"><span id="short_desc_nonedit_display">I'm hoping to finish up some of the work blocking JavaScript protocols so IRC can be put into a state that needs alpha/beta testers (if you're interested in testing/hacking please drop me a line here, on IRC or via email).</span></span></li>
<li><span id="summary_alias_container"><span id="short_desc_nonedit_display">Move into my new apartment</span></span></li>
<li><span id="summary_alias_container"><span id="short_desc_nonedit_display">Start my new job</span></span></li>
<li><span id="summary_alias_container"><span id="short_desc_nonedit_display">Work on richtext messages a bit more</span></span></li>
</ul>Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com0tag:blogger.com,1999:blog-7498677459674954485.post-8382374032706336112010-12-08T14:29:00.001-05:002010-12-08T20:01:17.590-05:00Why Rewrite IRC into JavaScript? (vs. libpurple's vs. ChatZilla's) I had a request on IRC (from Mic) to write an in-depth blog post about <a href="https://bugzilla.instantbird.org/show_bug.cgi?id=507">IRC in JavaScript</a>:<br />
<blockquote>"Maybe we could ask clokep if he'd like to write something about js-irc? Why it is done, what the advantages are once it's done, how he is working on it (going through the specs), putting the jsProtocol code to test and adding missing pieces?" -- <a href="http://log.bezut.info/instantbird/101208/#m54">Mic</a></blockquote><b>Wait a second, what is IRC?</b><br />
I guess this is a good first question, I'll steal from <a href="http://en.wikipedia.org/wiki/IRC">Wikipedia</a>:<br />
<blockquote><u>Internet Relay Chat (IRC)</u> is a form of real-time [...] chat [...] It is mainly designed for group communication [...]<a href="http://en.wikipedia.org/wiki/IRC#cite_note-1"></a> but also allows [...for...] private message as well as chat and data transfers.</blockquote>Awesome, what's that really mean? It's an instant messaging protocol with an actual specification (i.e. it's not owned by some large, unnamed company), with open-source libraries for clients and servers. It's usually used by more computer-oriented types of people and centers around group conversation. Personally most of what I use it for is open-source software I use (I'm almost always in <a href="irc://irc.mozilla.org/#instantbird">#instantbird</a>, <a href="irc://irc.mozilla.org/#maildev">#maildev</a>, and <a href="irc://irc.mozilla.org/#songbird">#songbird</a> on <a href="http://irc.mozilla.org/">Mozilla's IRC servers</a>.)<br />
<br />
<b>Why it is done? What advantages are there once this is done?</b><br />
I touched upon this a little in my <a href="http://clokep.blogspot.com/2010/12/javascript-irc-in-instantbird.html">last post</a>. In terms of Instantbird: there's an idea of switching some / all of the protocols (eventually) to be JavaScript protocols instead of the libpurple versions (libpurple is written mostly in C and is cross-platform, but recent gains in speed in JavaScript allow this advantage of libpurple to not matter as much). This would unfortunately mean we need to maintain a lot more code, but it would allow us to integrate protocols in any way that we see fit, instead of only using APIs / methods provided by libpurple. Hopefully this would allow us to <a href="https://bugzilla.instantbird.org/showdependencytree.cgi?id=507&maxdepth=2&hide_resolved=1">enhance our IRC implementation</a> a bit.<br />
<br />
Also, Instantbird (nightlies) currently have limited support for generating a protocol plug-in in JavaScript. A couple of "test" protocols have be done, but nothing in "real" (in particular, none that used a multi-user chat). This would allow us to iron out <a href="https://bugzilla.instantbird.org/show_bug.cgi?id=519">some</a> <a href="https://bugzilla.instantbird.org/show_bug.cgi?id=118">bugs</a> in the implementation of JavaScript protocols.<br />
<br />
<i>[Edit: Florian suggested another question that wasn't originally covered, which some people more familiar with Mozilla code might be wondering.]</i><br />
<b>Why aren't you using the code from ChatZilla?</b><br />
This was a tough one. Honestly when I first wanted a parsing algorithm, I looked at the ChatZilla code, I used it. Then rewrote it in a fourth as many lines (<a href="http://hg.mozilla.org/chatzilla/file/tip/js/lib/irc.js#l1250">93</a> vs. <a href="https://hg.instantbird.org/experiments/file/IRC-JavaScript/components/ircProtocol.js#l208">20</a>). Simply said, the code in ChatZilla is <i>old</i>, it doesn't use many of the features available only in newer versions of JavaScript. To that point, the ChatZilla code hasn't been updated in over a year! The last check-in was: 2009-10-03, below is a <a href="http://hg.mozilla.org/chatzilla/log/tip/js/lib/irc.js">quick summary</a> of the number of check-ins per year:<br />
<ul><li>2010: 0</li>
<li> 2009: 5</li>
<li>2008: 15</li>
<li>2007: 11</li>
<li>2006: 18</li>
</ul>There's been a pretty steady decline in check-ins. I could take this code and attempt to whip it into shape and make huge sweeping changes and commit them back to ChatZilla, but honestly it was easier to start over for me. Regardless of ease, I'm not sure it would work any: especially since the ChatZilla code seems overly complicated and overly specific (since it wasn't really built as a library as far as I can see), especially since all the code is meant to deal only with IRC. The Instantbird code needs to be protocol agnostic to a degree, while is why it interfaces to purplexpcom.<br />
<br />
A quick example of this is: ChatZilla uses a CIRCUser object, but for Instantbird I need to create either an imIContact or a purpleIAccountBuddy (depending on the situation). It's possible that's can be abstracted and code shared -- but I'm not sure it would be worth the effort. After all this, I should probably look more into the ChatZilla code, perhaps more of it could be used.<br />
<br />
(If someone familiar with the ChatZilla code base -- I don't know who/if there's a maintainer -- is interested in talking with me, please get in contact here or on #instantbird. It's possible we could align some of what I've been working on, but I'm not sure how much could be shared besides the parsing algorithm).<br />
<i>[End edit]</i><br />
<br />
<b>What are the specific advantages for an end-user?</b><br />
In terms of the IRC protocol itself, there shouldn't be any, my goal is for it to be a drop in replacement for the libpurple implementation with automatic account migration, etc. For end-users we can hopefully solve <a href="https://bugzilla.instantbird.org/showdependencytree.cgi?id=574&maxdepth=1&hide_resolved=1">a few annoying IRC UI issues</a>.<br />
<br />
<b>What about for developers? Anything cool there?</b> <br />
Well, I'm hoping to be able to test this replacement via an extension that replaces the libpurple IRC to dogfood it before eventual inclusion in Instantbird. I'm not sure if that counts as "cool." though. If nothing else there will be an example of how to write a protocol in JavaScript (using sockets). So hopefully other people can make some other cool protocols off of that example. You might wonder what else we have planned for JavaScript protocols; there are plans to make at least a Twitter protocol.<br />
<br />
<b>How is this being done?</b><br />
Well I said up above IRC has a specification, right? Well, yes. There's the <a href="http://tools.ietf.org/html/rfc1459">original specification</a>, this was superseded by <a href="http://tools.ietf.org/html/rfc2810">four</a> <a href="http://tools.ietf.org/html/rfc2811">different</a> <a href="http://tools.ietf.org/html/rfc2812">specification</a> <a href="http://tools.ietf.org/html/rfc2813">documents</a>. Of which we only really care about one: <a href="http://tools.ietf.org/html/rfc2812">the client protocol</a>. So we have this updated specification (try reading it, it's rather painful), which is good. It's relatively straightforward set of commands and responses/errors. It's a bit more confusing than that though since there are a couple of extensions, etc. This is summarized below:<br />
<ul><li><strike>RFC 1459</strike></li>
<ul><li> Extended with <a href="http://www.irchelp.org/irchelp/rfc/dccspec.html"><strike>DCC specification ("direct client-to-client")</strike></a><br />
</li>
<ul><li>Replaced with <strike><a href="http://www.irchelp.org/irchelp/rfc/dccspec.html">CTCP ("client-to-client protocol")</a></strike></li>
<ul><li><a href="http://www.invlogic.com/irc/ctcp.html">Draft for a formalized CTCP</a></li>
</ul><li>(Apparently some people are working on a <a href="http://www.dcc2.org/">DCC2</a>)</li>
</ul><li>Officially replaced with RFCs 2810, 2811, <u>2812</u>, 2813</li>
</ul></ul>A lot of this is being done by reading the specifications and finding the proper responses, etc. I've also used <a href="http://www.wireshark.org/download.html">Wireshark</a> a bit to see how libpurple sends IRC commands (in particular, in what order it sends them in). A lot of my development is happening on live IRC servers, which isn't really best practice, but I'm mostly sending commands by hand to see the responses since a bunch of non-standard responses and extensions have developed beyond the above. I have been using <a href="http://ircd.bircd.org/">beware irc</a> to run a daemon on my own machine, however.<br />
<br />
<b>So how far along are you?</b><br />
I've started implementing RFC 2812 and have a variety of commands done (the login sequence occurs automatically, the server connection is kept alive, messages can be sent to a channel and are parsed when received, a lot of the initial server information is displayed but unparsed). But there's a lot more to do! As my last post outlined, I recently was able to successfully get a chat to work in Instantbird from a silly bug I had been having.<br />
<br />
It's rather slow going since I'll start to implement something from the IRC side, and then realize the <a href="http://hg.instantbird.org/instantbird/file/tip/purple/purplexpcom/src/jsProtoHelper.jsm">Instantbird layer</a> (the jsProtocol module) is missing a component I need. One of the major parts of working on this is extending the Instantbird layer to contain the proper functions and objects needed to implement chats via JavaScript. This is usually the slowest going part of my code, since it involves interfacing with Instantbird / <a href="http://hg.instantbird.org/instantbird/file/tip/purple/purplexpcom/public/">purplexpcom</a>. Luckily Florian, the main developer of Instantbird, has been a big help with this (as have other participants of #instantbird -- in particular I know Mic helped track down a few syntax type bugs).<br />
<br />
<b>What's next?</b><br />
Now that have the basics of chat working, I need to start handling the QUIT, PART and JOIN commands for when other users enter & leave chat rooms. Once these are complete it should be quite usable, although the entire preference system still doesn't exist, including notifying the UI of what options are available. In addition, I need to look into doing SSL sockets.<br />
<br />
Once the protocol plug-in is done, we plan to abstract sections of it that will be useful for other protocols (in particular the socket connection aspects).<br />
<br />
<b>Where can I see this stuff...?</b><br />
My work is kept in the "<a href="https://hg.instantbird.org/experiments/file/IRC-JavaScript/">experiments</a>" repository on Instantbird's <a href="http://mercurial.selenic.com/">Mercurial</a> repository. There's also a variety of bugs open (they're listed above, I'm not going to re-list them), although not a ton is happening in them.<br />
<br />
<b>How can I help?!</b><br />
Well you can of course feel free to download the code and hack on it, let me know (via IRC or any of the bugs most likely) if you have a patch you'd like me to apply. Or if you just found something that doesn't work you can feel free to let me know, although I probably just haven't gotten around to fixing it yet.<br />
<br />
Also, if you've ever found something annoying / broken in the IRC implementation in Instantbird / libpurple please let us know (through any of the above contact sources).<br />
<br />
Hopefully that's a bit of a better explanation of why we're spending time to rewrite the IRC protocol implementation into JavaScript -- we definitely think it's worth it and can lead to a bunch of new unique protocol plug-ins for Instantbird.Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com2tag:blogger.com,1999:blog-7498677459674954485.post-457190935736687292010-12-04T17:24:00.000-05:002010-12-04T23:23:48.581-05:00JavaScript IRC in InstantbirdI've been working on rewriting the IRC plugin for <a href="http://www.instantbird.com/">Instantbird</a> since the summer (sometime in August, I can't seem to find the exact date -- at least since Sept. 10th though).<br />
<br />
Since <a href="http://developer.pidgin.im/wiki/WhatIsLibpurple">libpurple</a> (used in Pidgin, Adium, etc.) provides the IRC protocol that we currently use, why do this? One reason is to iron out (and find) some of the bugs left in implementing protocols in JavaScript and part of it is so I can learn to code better. Unfortunately during this semester I was not able to get as much done as I had hoped and almost everything that had been done was finished in August/September<br />
<br />
Some big milestones I've completed (with dates if I have them):<br />
<ol><li>Connected to server via sockets in JavaScript</li>
<li>Generate a conversation that works as a raw connection to the server (i.e. as if you had opened a telnet connection to the server)</li>
<li>Parsing messages and automatic ponging when the server pings</li>
<li>Joining a channel (2010/12/04, i.e. today!)</li>
</ol>There had been a bunch of small bugs I had been having in getting this to work: one error, (which I found quickly) one of the other developers (<a href="http://queze.net/">Florian</a>) was able to help me out with, was that I was not initiating a <b>new</b> object. And after learning a bit above observers I was able to get the UI to respond. I even threw in support for op/half-op/voice After today's work I was able to generate the following screenshot:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0XpZkMbKBS-hKxDODWBtj3BW2Y3NI4ELHYSqVsvSzeEBzo2nJV2SeeQC3XWO9uZd6w04joZ7F-vCaDFYcS3yV8ymCUnhPsQErAweW1QxrvM4GrXioz-ks_7G6TQLncBWlo1KZ9w4_Wwrr/s1600/IRCworking2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="297" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0XpZkMbKBS-hKxDODWBtj3BW2Y3NI4ELHYSqVsvSzeEBzo2nJV2SeeQC3XWO9uZd6w04joZ7F-vCaDFYcS3yV8ymCUnhPsQErAweW1QxrvM4GrXioz-ks_7G6TQLncBWlo1KZ9w4_Wwrr/s320/IRCworking2.png" width="320" /></a></div>This build would be almost fully usable by those who do very little on IRC (i.e. if you just want to go and chat, it'd work well), but there's a lot more work to be done. The code can be viewed in the <a href="https://hg.instantbird.org/experiments/file/IRC-JavaScript/">Experiments repository</a>. (Check it out, there's a 600+ line switch statement.)Patrick Clokehttp://www.blogger.com/profile/09518646916687340144noreply@blogger.com0