Whether the add-on you get is mine can be determined by the digitial fingerprint / hashes I've listed near the bottom of this page. As for trusting me:
As I explain below, anyone can look at the entire source code. The meat--overlay.js--is well less than 300 lines without comments. You can see that there are not URLs or IP addresses other than Facebook.com--I'm not sending data anywhere. I'm otherwise not doing anything other than claimed.
As of 2012 (July), the kwynn.com IP address traces to Amazon Web Services (AWS) hosting. The AWS addresses show their corporate offices in Seattle, although my EC2 instance is in US East - Virginia. The point is that my site isn't in one of the hackfest countries. Kwynn.com traces to my physical street address (in the US) through INTERNIC and TuCows.
I'm on Facebook, as much as it pains me. Say hi. Look at my dozens of friends who must be real people--who else would talk that much?
Look around this site. Although I'm not an artist, I hope it's obvious I've spent a lot of time on this. Given the context, I'm probably not spreading malware.
Pushing the security issue to someone else: now that it's free / open source, anyone is welcome to submit it to the AddOns.Mozilla.Org Editors (AMOEs) for review. Previous versions were fully approved by them, but FB complained about trademark issues. My recent versions (1.1.3) should pass muster because "Facebook" has been taken out of user-visible fields. After the FB trouble, the AMOEs said it would be ok without references to FB. I had had enough by that point, though. I'm passing the torch.
The "onload" event fires upon download, but the FB page takes a lot longer to process all the JS. How long the counter takes to kick in and / or how many keystrokes depends on how fast you type and how fast your computer is. The counter won't fire until all the JS has run and then you do one more "input" (keystroke, copy, paste, delete, etc). The counter will only fire on an "input" event. Sometimes you type a bunch of characters (or paste them), pause, and then it's the next key / character that kicks the script into gear. On a computer that was cheap in 2005, I've seen the counter take 50+ characters and probably over 10 seconds before it fires.
The reason it takes at least two characters for "Ask Question" to work is because Facebook's JS is capitalizing the first character. As best I can tell, they are not propagating the keystroke beyond their capitalization code, so my script can't see the first key / letter.
I created a version that uses timers to keep checking for my input and output fields as all the JS runs. It's proably a nicer version, but it never got out due to reasons that would take too long to explain. If someone wants to run with this, I'd be happy to go dig that version up.
A couple of notes to self (and others who are interested):
$ pwd
counter
$ zip -r counter.xpi chrome chrome.manifest icon.png install.rdf
The XPI (add-on) files you get from me and from Mozilla's site (with other add-ons) are just ZIP files. Rename a XPI file to .ZIP, and then your ZIP tools will recognize and unzip the contents. Inside are a handful of text files (source code)--the files have different extensions, but they're all text files except for the icon.png (removed in v1.1.0). Almost all the action takes place inside chrome/content/overlay.js. (See notes below on why the directory is called "chrome.")
When a XPI (AddOn / extension) is installed on your computer, it gets installed to
The Firefox-installed file is identical to what you downloaded. Any OS uses a different name than the file you download from my site because name@dev-first-name.last-name (or .com or other TLD) is the Firefox standard. The counter@kwynn.com name is set in the install.rdf file in the xpi file.
Mine and many add-ons are written in JavaScript (JS). My first version was a GreaseMonkey script. Let me know if you want that.
Myk Melez' tutorial on how to build an AddOn got me from general JavaScript to add-ons.
Here are a few critical lines of code in overlay.js that took me a while to find and figure out:
chrome_level_listener : function() // note on this syntax below
{
var appcontent = document.getElementById("appcontent");
// appcontent = browser, as opposed to mailer or such
if (appcontent) appcontent.addEventListener("load", counter_kwynn_com.myLoad, true);
}
// and the releated line:
window.addEventListener("load", counter_kwynn_com.chrome_level_listener, false);
The window... line above is the only line outside of the object counter_kwynn_com.
Only after chrome_level_listner() calls myLoad() are you within the DOM of a single web page--the normal JS context. (The lines above are before v1.1.3.
They may have changed during 1.1.3.)
The "name : function()" syntax as opposed to "function name()", and related changes, was something else I had to learn. I'd never seen that before. I think it's called object or class syntax or some such. All but one line is contained within a counter_kwynn_com class. This is to prevent global namespace pollution--if "myLoad" weren't contained in a class it would conflict with other add-ons with "myLoad". The AMO upload check tool is still complaining about namespace pollution as of version 0.4.0. I'm not sure what that's about. I think it's a false positive / a bug in their checker tool. The AMOEs didn't complain.
The directory is called Chrome because the innards of Firefox have been called Chrome for years. As far as I know, Google Chrome is a branch of Firefox.
"XPI" is pronounced "zippy." I keep envisioning a small, very energetic dog--"Zippy, fetch!"
Extension Bootcamp: Zero to “Hello world!” In 45(*2) Minutes by Myk Melez — myk@mozilla.org.
Design Challenge — 2009 March 13.
MM video I watched (I think I watched it someplace else or downloaded it. I didn't use an stream-to-download tool, so
I think there's a download out there.)
MM course raw directory. I've referred to the PDF file several
times.
MM blog entry
See the WikiPedia and its references regarding md5, sha1, and sha2. md5 is thoroughly broken / insecure; I won't include it. sha1 doesn't seem to be quite done yet, but it's going.
v1.1.3 XPI file hashes below. This first column is the exact command I use in openssl ("openssl sha1 *").
sha1 | d3a57560c365a8cb8d1c08b28d6ed9ff79a52c3a |
sha224 | d8f46c4961134c1007e65d414e9517646888230809cfb7a68287b2f5 |
sha256 | 964aa2a0922700c9880f9dce5f5d3762d2cf077fa24340f04aa906dd5c0dfaec |
sha512 | 4ab2423c18124222d3f4201e54516e5f19b24383f18fe22b5a0be2b0e031b30856acabcf173f93c57401f7cf73269e76777036ff713b6d0e5609ca7eb353cadf |