ActionScript 3 URL validator class

2/02/2009

A fairly common task in ActionScript projects is to deal with URLs in dynamically loaded text. Whenever I faced this prospect I usually ended up with some half-assed searching for “http://” and then indexOf(” “) to determine when the URL had ended and then smacked a <a href> on either side. Which pretty much meant that “http://___||/**.tasty_cheese_omelete” would be acceptable while “google.com” would not.

Hence I always promised myself that next time I’d write a proper class to deal with URLs so that this bullshit wouldn’t pass anymore.

Regular Expressions have always scared the bejeezus out of me, but I realized there was probably no other option when looking for something that has a valid URL structure. It was surprisingly easy to find some fairly good examples for what I wanted to achieve, and surprisingly difficult to get any of them to work in ActionScript. I’m blaming it on the AS implementation of RegExp, and I’m sure ActionScript is blaming it on my implementation of dumb.

After some swearing though I managed to determine whather a string had the proper structure of a URL but it still wasn’t perfect. I wanted my class to be intelligent enough to accept all valid Top Level Domains (there’s 267 in use) but reject any invalid attempt to pass as a valid TLD. IE: egypt.eg should pass, but breakfast.egg should not. The solution ended up being storing all the TLDs in a Vector and parsing through them to check if the domain was valid.

All in all the class now does a pretty good job, although there are probably still holes in it (let me know about them when you find them).

Check it out and grab it below, and then post a comment explaining to me slowly and carefully that I can achieve this exact functionality with the

1
String.giveMeAllTheURLs();

method or something similar, which I’m sure is what will happen. ;)

The code is freely available here. I would appreciate any credit and that you share whatever improvements you make with me and the rest of the world, but I have neither time nor energy surplus to actually do any enforcing, so knock yourself out.

14 Comments

Better (AS3) imports in TextMate

1/12/2008
Summary: In which Martin has concocted a hack to make importing packages in TextMate a wee bit easier.

TextMate TextMate TextMate. I might as well make this a pure TextMate blog soon, but I can’t help it. My love for this app is overwhelming.

I spend a lot of my time writing ActionScript, and one thing I’ve always envied users of Flex Builder (Which I avoid if I can) and FlashDevelop (which isn’t available on the Mac) is the auto-importing of classes, I.E. when you type

1
var s:Sprite;

the IDE checks whether that class is already imported, and if not imports it.

Now, what I’ve managed to do still isn’t even close to that functionality and let me say right away that the meat of this trick is the excellent work by the creator of the ActionScript 3 bundle for TextMate; Simon Gregory et al.

Simon has in his bundle included a ‘Auto complete imports’ command which searches both the packages in your project and the packages included from Adobe (flash.*) which makes it easy to get completion for any class you’d want to import.

Like so:

  • You want to import the
    1
    flash.net.URLLoaderDataFormat;

    class, which is a long-ass line to type out.

  • Instead you type ‘URL’ and trigger the auto-complete command. You’ll get a drop-down with all classes starting with “URL” and then choose the proper one.
  • 1
    import flash.net.URLLoaderDataFormat;

    is typed out for you. Yay!

However, now you have to copy that text, move on up to your import statements, paste it and then find your way back to where you were.

Boy do I wish I knew Ruby well enough to actually just augment that command to make it obey my wishes, but alas; My ruby-Fu is weak and so I turned to the weapon of the feeble TextMate hacker; Macros.

Basically the workflow now is:

  • Perform the steps as mentioned above to get the completion for your import. However; This time the output would be
    1
    import flash.net.URLLoaderDataFormat; move

    . The ‘move’ at the end there will work as a tab trigger for the macro, so the next step is to press tab, and then (hopefully) the import statement is moved up to it’s brethren, and you end up back where you were. Here’s how it works.

  • When you press tab you trigger the macro which will perform the following steps:
  • Select the line with the import and cut it.
  • Enter the word ‘asdf’ in place of the import statement.
  • Search for the last occurrence of the word ‘import’ in the document.
  • Move to the line below said last import.
  • Paste the import statement from the clipboard and indent it properly.
  • Search for ‘asdf’ in the document and delete it, leaving the caret at the position it was when you launched the macro.

Like I said; It’s more of a hack than anything else and if someone comes up with a proper solution please let me know. The main weaknesses here are:

  • You can’t just hit the combo in the process of typing out a statement. If you trigger the auto completion at the word ‘Sprite’ in
    1
    var s:Sprite = new Sprite();

    The line

    1
    import flash.display.Sprite;

    will end up in the middle of the statement. Likewise if you trigger the combo on the same line as any other code, that code will end up with the imports. The command must be triggered on a line of it’s own.

  • Dependencies: If you want to change the tab trigger to something else than ‘move’ you’ll have to change the output from the auto-complete as well.
  • Not really all that elegant. Having to do two actions (even though one is just pressing tab) seems a hassle.

With all that out of the way: Grab it if you want it!
Zip here.
Please note: I didn’t really want to distribute a modified version of Simons work, so if you want to output the ‘move’ keyword for the tab trigger you need to go into the ‘Auto Complete Imports’ command of the ActionScript 3 bundle in the Bundle Editor and make a miniscule edit at the bottom of the code.

1
2
3
4
5
6
7
8
#Change
else
  print "import " + choice + ";"
end
#to
else
  print "import " + choice + "; move"
end

That’s all folks.

2 Comments

Tracing to Firebug in AS3

24/09/2008

I realize that I’m late to the party with this, but so far all the examples I’ve seen have been a bit overkill for my needs, so I’m putting this out there in case someone else might have some use for it.

Of course,

1
trace();

is a Flash developers best friend. Hell, I sometimes feel I’d be happier if I never had to go beyond the output panel, but that’s neither here nor there. The trace statement however, as beautiful as it may be, doesn’t help you a lot when you’re debugging the project in the browser, and therefore Adobe created

1
ExternalInterface

to let you output the traces to Firebug. But calling

1
ExternalInterface.call("console.log", args);

every time you want to output something is a pain in the ass, and going through your code to change all your trace calls to ExternalInterface calls is an even bigger pain in the ass, and therefore developers created various methods to ease the pain. Here is the very lightweight solution I use myself.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package no.martinjacobsen.utils {

  import flash.external.ExternalInterface;

  public class XTrace {

  public static var enabled:Boolean = true;

  public function XTrace(){ /*...*/  }

  public static function log(...args:*) : void {

  if(enabled == true) {
    if(ExternalInterface.available){
      trace("ExternalInterface is available")
      for (var i:uint = 0; i< args.length; i++){
      ExternalInterface.call("console.log", args[i]);
      trace(args[i]);
      }

    } else {
      trace("ExternalInterface is not available")
      for (var j:uint = 0; j< args.length; j++){
      trace(args[j]);
      }
    }
  } else {
    trace("Set 'XTRace.enabled = true;' to enable traces.");
  }
    }
  }
}

As you see this class simply checks whether ExternalInterface is available, and if so traces the output to the console. If ExternalInterface is not available the statement will just be traced. As a bonus you can also set

1
XTrace.enabled = false

to disable all traces if you don’t want to go through your code to remove traces, or go into the publish settings to strip them out.

Usage is extremely simplistic:

1
2
3
4
5
import no.martinjacobsen.utils.XTrace;

XTrace.log("Hello World", 42, false, myObject);

XTrace.enabled = false; //Disable all traces
1 Comment

Hug a developer day

11/09/2008

No Comments

Banner ad Fail

28/08/2008

I know these things aren’t really supposed to be difficult, but at least have your Flash guy take out the trace statements before you publish.

I was just surfing as I noticed something funny going on in FlashTracer. Like I said, no biggie, but may serve as a warning for other Flash devs.

No Comments