Learn something new every day

July 25th, 2007 § 2 comments § permalink

Until today, I did not realize that any HTTP requests made by a Flash movie (including LoadVars.load(), MovieClip.loadMovie(), Sound.loadSound(), etc) includes cookies — the cookies that would normally be sent by the browser anyway. In retrospect, this makes sense and is perhaps even obvious: since the Flash player asks the browser to make the connection, then it really is the browser doing the requests, so why wouldn’t the browser send and receive cookies as normal? For some reason, though, it was a surprise to me.

What does this mean? It means that it’s much easier for a widget to work in conjuction with PHP sessions, for example: I had been putting the session ID in FlashVars so that the Flash movie could add the cookie manually with addRequestHeader(), but it turns out that that is unnecessary.

Deeper into the rabbit hole: Gmail scripting part 3!

July 13th, 2007 § Comments Off on Deeper into the rabbit hole: Gmail scripting part 3! § permalink

I have discovered that the “reply” editing area is not always named “hc_0” or “ta_0“. No, the number following the underscore can be other numbers — it seems to correspond to the index of message in the conversation.

This gets more complex, because I forgot that more than one reply editing area can be open at the same time! And they can be of different types (i.e. rich or plain text)! So now not only do we have to find the editing area(s), we have to determine which one has the current focus. So far, I’ve not been able to find a way to determine what element has the focus, using JavaScript, on a page I didn’t create. Hmmm…!

More later…

Scripting Gmail part 2

July 6th, 2007 § 1 comment § permalink

UPDATE: Haha, alas this does not work all the time. Yep. See my next post… sigh.

After some time poking around with Firebug, here’s the updated code that also handles the “reply” text-editing area!

/* gmail seems to cycle between frames 'v1', 'v2' and 'v3'. try all */
var success = false;
var editorNames = [ 'hc_compose', 'ta_compose', 'hc_0', 'ta_0' ];
for (var i=1; i< =3 && !success; i++)
{
    /* if the frame is offscreen, it's not the active composing window */
    /* do this with a DOM element */
    var fe = top.main.document.getElementById('v'+i);
    if (fe && fe.offsetLeft >= 0)
    {
        /* the element name of the edit box could be one of 4 values, depending
           on rich text/plain text, as well as whether replying or composing.
           try them all. */
        var d = top.main.frames["v"+i].document; /* note we have to use oldschool frames[] syntax */
        var ed = null;
        for (var j=0; j<editornames .length; j++)
        {
            ed = d.getElementById(editorNames[j]);
            if (ed != null)
            {
                break;
            }
        }
 
        if (ed != null)
        {
            /* found it! rich text? or plain? */
            switch (ed.nodeName)
            {
                case "TEXTAREA":
                {
                    /* plain text */
                    /* do something with 'ed' */
                    success = true;
                    break;
                }
 
                case "IFRAME":
                {
                    /* rich text */
                    /* do something with 'ed' */
                    ed.contentDocument.execCommand( /* something something */ );
                    success = true;
                    break;
                }
            }
        }
    }
}

Phew!

Scripting Gmail with Bookmarklets

July 2nd, 2007 § Comments Off on Scripting Gmail with Bookmarklets § permalink

I am working on some bookmarklets for Gmail. I discovered that targetting any specific element in the Gmail window is a bit tricky, due to Google’s interesting use of frames.

It turns out that Gmail swaps between using frames named “v1” and “v2” to display the main content (at least in Firefox). If I had to guess, I’d mumble something about history and the back button and maybe cacheing :P

Anyway: here is how I find the text-editing area (it’ll be either a textarea or an iframe, depending on whether the user is using rich formatting or not):

/* gmail seems to swap between frames 'v1' and 'v2'. try both */
var success = false;
for (var i=1; i< =2 && !success; i++) {
    var ta = top.main.frames["v"+i].document.getElementById("hc_compose");
    if (ta) {
        /* do something with ta, for example: */
        ta.contentDocument.execCommand(/* something something */);
        success = true;
    }
    else {
        //  try getting the plain text area
        ta = top.main.frames["v"+i].document.getElementById("ta_compose");
        if (ta) {
            /* do something with ta here, a textarea element */
            success = true;
        }
    }
}

I’m certain this could be done more cleanly, but you get the idea. Share and enjoy!

UPDATE: This currently doesn’t work for a “reply” editing area. I will (I hope) update the snippet to cover that case, too.

UPDATE 2: Sorry, this doesn’t work consistently. I should test more before posting :P I am now finding a frame called “v3”. Perhaps Gmail increments this continuously? In any case, I am leaving this post up for research purposes.

UPDATE 3: Got it working reliably (I think). See the fixed version!

Mod_rewrite

June 12th, 2007 § Comments Off on Mod_rewrite § permalink

I’m futzing around with mod_rewrite again (I eventually plan to switch everything over to lighttpd, but until then…), and as I reread the docs, I remember how unhelpful diagrams like this are:

apache's mod_rewrite diagram... it's sooooo clear

Someday when I suss it out I might write my own mod_rewrite guide.

More Facebook Platform applications

June 1st, 2007 § Comments Off on More Facebook Platform applications § permalink

As expected, the ideas I recently wrote about have been implemented (and perhaps already had been before I wrote it). There are at least two “Top friends” applications out there, and two “poke” alternatives, and an adoptable pet application. A search reveals that someone seems to be working on a gift app too. I expect to see lots and lots and lots of duplication and competition in there.

Meanwhile, I suppose I should get moving on putting my own pets into Facebook, even though I have a couple of other priorities first. Perhaps I should shift my priorities and focus on Facebook while things are still exciting? Hmmm!

More cryptic notes to myself about execution order in Flash

May 31st, 2007 § Comments Off on More cryptic notes to myself about execution order in Flash § permalink

When a nested MovieClip with a custom subclass is created, the order is something like this (I think):

  1. the asset is created (as a “plain” MovieClip: it has its name, dimensions, etc, and can be referred to by name from the containing MovieClip, but it has no methods or properties of its ActionScript class)
  2. its constructor is called
  3. any onLoad() handler is called
  4. frame scripts on the MovieClip’s timeline execute

Facebook Platform app ideas

May 26th, 2007 § 1 comment § permalink

I haven’t even started digging into the documentation seriously yet nor have I looked at the sample application, but I’ve been playing with existing Facebook apps and a bunch of ideas are bouncing around in my head. I’m sure a lot of these are pretty common ideas, but since there’s no “search” function that I can find in Facebook’s app directory, I can’t tell if anyone has already done these or not. In any case, I’m going to throw a few ideas out there for anyone else to grab if they want… like I said these are not particularly original, and I may or may not try my hand at any of these myself.

  • MySpace-like “Top 8”. The Facebook API lets an app enumerate a user’s friends, so it should be a simple matter to allow the user to pick their favourite 8 (or whatever number) to be displayed in a custom section on their profile. (At this point I’m not sure if those friends would also need to have the same application added to show up…) I am no fan of “top X” (I like the way Facebook shows a random selection of friends on your profile), but I think this would be funny :P
  • Free Gifts! I know a lot of people grumble about having to pay a dollar to send a virtual gift to someone else. A third-party Facebook app could easily add their own virtual gifts of their own design and enable sending such gifts from one user to another. (I haven’t checked to see if something like this would violate the TOS for Facebook developers though)
  • Super Pokes. Or not just poking, but slapping, spanking, pinching, etc. Since Facebook apps can have “requests” show up in the top part of the right-hand column of a user’s home page, they would be near the existing “poke” messages. I don’t know if you could have the pincher’s name show up there, though… it might have to look like a group or event request (e.g. “3 super pokes” and you’d have to click to see whom they were from)

Nested MovieClip subclass gotcha in ActionScript 2

May 25th, 2007 § 5 comments § permalink

[UPDATE: It looks like Colin Moock‘s excellent book Essential ActionScript 2.0 talks about this very situation, on page 328. His workaround is to use setInterval to poll the object to see if the custom methods/properties have been set up yet.]

This kind of stuff is always a bit difficult to describe clearly, so I might not even try :P So here are some scratched-in notes for myself:

  • Imagine a MovieClip (mc1) which contains another MovieClip inside it (mc2). This nested instance is created in the authoring tool. It would look like this in the Movie Explorer:
    example
  • Both MovieClips have (different) custom class: let’s call them MovieClass1 and MovieClass2.

The constructor for MovieClass1 looks like this:

class MovieClass1 extends MovieClip {
    function MovieClass1()
    {
        trace("MovieClass1 ctor " + this);
    }
}

MovieClass2‘s constructor looks shockingly similar:

class MovieClass2 extends MovieClip {
    function MovieClass2()
    {
        trace("MovieClass2 ctor " + this);
    }
}

Ok. Now we place an instance of MovieClass1 on the stage, name it mc1, and test the movie. Here is the traced output:

MovieClass1 ctor _level0.mc1
MovieClass2 ctor _level0.mc1.mc2

So we know that the constructor for the parent clip is called before the constructor of the child clip.

Note that this is quite unlike C++, for example, where member objects are created before the containing object’s constructor is called (see here for an example), and in fact can cause real issues. For example, suppose MovieClass1‘s constructor wants to call custom methods of MovieClass2. Those calls will fail because mc2 has not yet been initialized! Note that this only applies to methods and properties that exist in the custom class — the MovieClip exists, as a plain old MovieClip, but the custom class hasn’t been associated with it yet.

Example:
MovieClass1.as:

class MovieClass1 extends MovieClip {
    var mc2:MovieClip; /* placed in Flash authoring tool */
    function MovieClass1()
    {
        trace("MovieClass1 ctor " + this);
        mc2.customMethod();
    }
}

MovieClass2.as:

class MovieClass2 extends MovieClip {
    function MovieClass2()
    {
        trace("MovieClass2 ctor " + this);
    }
 
    function customMethod()
    {
        trace("MovieClass2 customMethod()");
    }
}

The results of running this test:

MovieClass1 ctor _level0.mc1
MovieClass2 ctor _level0.mc1.mc2

Yep. customMethod() is never called!

I hope to continue this in a later post… there are more details about the constructor-calling process that are weird and intriguing!

Facebook Platform!

May 25th, 2007 § Comments Off on Facebook Platform! § permalink

I’m pretty excited about the Facebook Platform which was announced yesterday. It goes beyond just “widgets.” It lets you create modules (“Facebook applications”) that run right inside of Facebook. They have access to the user’s data, if users consent to it. Apps can have a box on the user’s profile page, as well as having their own dedicated pages.

The obvious first thing I will try is putting my adoptable pets into Facebook profiles. However, I also would like to create apps that use the Facebook data more deeply. I wonder if someone has already created a “TOP 8 FRIENDS”-type module, a la MySpace ;) If not, I may take a stab at it just for learning purposes.