<charliedigital /> Programming, Politics, and uhh…pineapples

4Dec/090

More WebSequenceDiagrams.com Awesomeness

Posted by Charles Chen

As I've been working with a client which has demanded rigorous sequence diagrams as deliverables for the design phase of the project, I've started to use WebSequenceDiagrams.com more and more.

I've blogged about it previously, but I've only come to truly appreciate it after having to use Visio for a few days before I convinced the client that I could deliver the content faster and in an easier to maintain format (well, text) using WSD.

What Visio Gets Wrong


I ran out of connection points. Yes, it's possible; for a long activation sequence, you can actually run out of connection points. One could argue that this calls for a refactoring of the diagram in the first place, but then I would say that you've never tried to actually refactor a Visio diagram...I still find it hard to believe: the activation box ran out of connection points; I wouldn't have believed it if I didn't see it myself:

I kept having to resize the page. By default, you can't really fit much on the page. But as I started to build my sequence up, I found that I had to keep toggling around with the paper size just so that I would have a grid. This was annoying since it also involved then zooming out so that I could select everything and reposition it to the top left corner of the page then zooming back in. You'd think that Visio would be smart enough to do this, but it isn't...

I kept having to move elements around. Want to add a new step? What about introducing a new actor in between two existing actors? Prepare for some carpal tunnel my friend. There's simply no easy way to do it aside from zooming out, grabbing everything to the right and shifting it around while counting gridlines and getting your result some 10-20 clicks later. What's worse is that you end up having to scroll around horizontally (reordering actors) and vertically (reordering steps) while dragging a bunch of stuff around.

I kept having to fix connection lines. This was absolutely mindboggling: if I extended an activation, it would cause the first connection on the activation to jump, which would then require me to manually drag the connection back to where it belonged. I probably spent a good 10% of my time simply fixing these connection points as a adjusted activations:

This is an incomprehensible design flaw; I have no idea how people work around this in Visio since I adjust activations multiple times as I'm working through a diagram.

There was no representation of alternate paths or optional steps. I ended up having to draw a rectangle and manually managing the size of it as I changed steps and added more steps. What made this even more annoying was that having the rectangle, even though I sent it to the back, then made it difficult to select elements that were enclosed by the rectangle like a message line or a connection point or a note; I'd end up selecting this stupid rectangle instead.

I had to keep managing the location of notes. The notes don't seem to anchor to anything and it's not clear to me how that's supposed to work. That meant that I had to keep moving notes around as I changed activations and modified connection points.

The lifelines didn't synchronize. For the life of me, I couldn't figure out how to get the lifelines to synchronize in length so I didn't have to manually go back and drag each one down to the same length. You can't actually CTRL+click two lifelines, as one would think you'd be able to do, and drag them both to extend them simultaneously. I mean, this seamed like pretty basic stuff to me.

So yeah, all in all, I'm not sure why anyone would want to subject themselves to the pain of creating sequence diagrams in Visio. Maybe if it's a final product and you don't plan on touching it ever again and you've already done most of the work on paper or something, but it's a terrible tool if you're just trying to think an idea out and see it visually.

What WebSequenceDiagrams.com Gets Right


I can't speak to the console program or the DLL (yet), but I decided that the only way that I could do this right was to do it in WSD first and then just use Visio to render the final output. While doing it in the browser is fine, I found it much easier to do it in EditPlus, my text editor of choice.

The first step was to create a syntax and auto-complete file so that it was a little more user-friendly.

Here's my .stx syntax file:

#TITLE=WSD

#DELIMITER=,(){}[]+*%/="'~!&|<?:;.
#QUOTATION1="
#LINECOMMENT=note
#CASE=y

#KEYWORD=Activate
activate

#KEYWORD=Deactivate
deactivate
destroy

#KEYWORD=Alias
as
participant

#KEYWORD=Notes
note
over
right
left

#KEYWORD=Control
alt
else
end
opt

#KEYWORD=Newline
\n

#KEYWORD=Transition
->
-->
#

And my .acp auto-complete file:

#TITLE=WSD

#CASE=y

#T=act
activate ^!
#T=de
deactivate ^!
#T=pa
participant ^!
#T=alt
alt ^!

else

end
#T=opt
opt ^!

end
#

What I get from this is:

I know what you're thinking: Chuck, that looks like code! By golly, it does! And -- at least to me -- that's the beauty; all of a sudden, a frustrating, time consuming, mouse-centric activity becomes a keyboard-centric, coding-like activity. Moving objects around becomes a matter of moving lines of text. Reordering actors involves moving your participant declarations around. Notes stay in their context if you add a step since everything gets pushed down. There's no manual resizing of anything. There's no fixing connection points. There's no stupid. It actually makes working with sequence diagrams, beyond just whiteboarding, much more useful and much more productive as it lets you kind of think out the code by actually writing pseudocode.

I highly recommend downloading EditPlus (you can keep using it for free, perpetually, if you're a cheap bastard or pony up the $20 for such an awesome editor). For me, EditPlus is a perfect pairing for WSD due to the easy to create language syntax/autocomplete files and the handy split-document feature so you can easily reference your participants at the top.

Simply create a new file type and add the .stx and .acp files I defined:

Now the downside of this whole affair is that you have an extra step of having to copy out the text and pasting it into the browser, but even with that extra little bit of annoyance, the time and frustration saved over working with Visio is more than worth it.

The next step, once I get my hands on the command line tool, is to hook it up to the external tools feature of EditPlus for a quick hit. I'm also considering writing an integration for Visual Studio for custom rendering within VS or at least something quick-and-dirty like an add-in.

One additional note is that WSD has an HTML/Javascript API whereby you can render a diagram inline with your HTML by simply using a set of <pre></pre> tags and a reference to a Javascript file.

What's cool about this is that now you can use the standard CTRL+B/CTRL+E shortcut keys to preview without a copy/paste step! For free! That's pretty awesome.

Of course, the downside is that using this method, there is a limit to the size of the sequence that you can send up as well as the fact that you need some additional hijinks to make the syntax highlighting work (I gave up on that part :-D ) . But if were doing it in the browser to begin with or using notepad and you don't care for the syntax highlighting, then this is a huge upgrade.

Conclusion: stop using Visio :-D Now I'm just looking forward to WebERDiagrams.com, WebStateMachineDiagram.com, and....well, you get the idea.

My EditPlus .stx and .acp files for anyone that wants 'em: wsd-files.zip (.52 KB)

Filed under: Awesome, DevTools No Comments
28Sep/092

SharePoint? Is That You?

Posted by Charles Chen

Weird discovery of the day: Recovery.gov is SharePoint (check the source or try a search).


Cool.

8Jul/090

Leveraging The Windows Forms WebBrowser Control (For The Win)

Posted by Charles Chen

I've been working on a little utility to experiment with the XMPP protocol.  The idea was to write a tool that would allow me to send, receive, and display the XML stream and XML stanza messages at the core of XMPP.


Of course, I could have implemented it using a simple multi-line text box for the XML entry, but that would mean that I wouldn't have nice things like syntax highlighting (for XML) and nice (auto) indentation.


On the desktop, I'm not familiar with any free Windows Forms editor controls that are capable of syntax highlighting.  But on the web side, there are several free, open source script libraries at our disposal.  For example, CodePress, EditArea, and CodeMirror.


I chose CodeMirror for this application as it was the simplest library that met my needs.



There really aren't any tricks to this aside from getting the URL correct.  In this case, I have my static HTML content in a directory in my project:



And I set the content files to "Copy always" in the properties pane for the files so that they get copied to the output directory of the project.  To set the correct path, I find the executing directory of the application and set the URL properly:


protected override void OnLoad(EventArgs e)
{
if (!DesignMode)
{
string path = Path.Combine(
Environment.CurrentDirectory,
"HTML/input-page.html");
path = path.Replace('\\', '/');

_inputBrowser.Url = new Uri(path);
}

base.OnLoad(e);
}


Note that I check if the control is in design mode (the designer throws an error if you don't do this since the path points to Visual Studio's runtime directory instead of your applications output).  Now all that's left is to get the script and style references correct in your HTML page:


<script src="../HTML/CodeMirror/js/codemirror.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="../HTML/CodeMirror/css/docs.css" />

And in your script:


<script type="text/javascript">
var editor = CodeMirror.fromTextArea('code', {
height: "210px",
parserfile: "parsexml.js",
stylesheet: "../HTML/CodeMirror/css/xmlcolors.css",
path: "../HTML/CodeMirror/js/",
continuousScanning: 500,
lineNumbers: true,
textWrapping: false
});
</script>

The final part is getting your Windows forms code talking to the Javascript in the browser.  In this case, I've written some simple Javascript that interacts with the editor control:


<script type="text/javascript">
var $g = document.getElementById;

function resize(height) {
var textArea = $g("code");

// Get the iframe.
var editor = textArea.nextSibling.firstChild;

editor.style.height = (height - 1) + "px";
}

function reset() {
editor.setCode("");
}

function addContent(data) {
var code = editor.getCode();

editor.setCode(code + data);

editor.reindent();
}

function setContent(data) {
editor.setCode(data);

editor.reindent();

// Scroll to bottom.
editor.selectLines(editor.lastLine(), 0);
}

function getContents() {
return editor.getCode();
}
</script>


From the application code, we can call these script functions using the InvokeScript method:


private void AddStreamMessageInternal(string data)
{
if (_streamBrowser.Document != null)
{
// Get the contents
string code = (string) _streamBrowser.Document.InvokeScript(
"getContents", new object[] {});

code = code + data;

code = code.Replace("><", ">\r\n<");

_streamBrowser.Document.InvokeScript(
"setContent", new object[] {code});
}
}

private void AdjustSize()
{
// Call a resize method to change the HTML editor size.
if (_streamBrowser.Document != null)
{
_streamBrowser.Document.InvokeScript(
"resize", new object[] {_streamBrowser.ClientSize.Height});
}
}

public void RefreshBrowserContents()
{
if (_streamBrowser.Document != null)
{
_streamBrowser.Document.InvokeScript(
"reset", new object[] {});
}
}


Awesome! You can see that I can both pass arguments into the Javascript functions and read the return data from the Javascript function as well.  The big win is that now you can take advantage of your favorite Javascript utilities in your Windows Forms applications.

Filed under: .Net, Awesome No Comments
4Jun/090

QOTD

Posted by Charles Chen

A friend passed along a quote the other day:



So I just picked up this book today....and found this quote in the forward: "The truth of the matter is, if you need to “save” your job, I can’t help you. This book isn’t about struggling to maintain the level of mediocrity required not to get fired. It’s about being awesome. It’s about winning. You don’t win a race by trying not to lose. And you don’t win at life by trying not to suck. Fortunately, the content of the book has never been about trying not to suck. I can’t think that way, and neither should you."


Thanks, Dan!

Filed under: Awesome, DevLife, QOTD No Comments
28May/090

Visitor Pattern In C# 4.0

Posted by Charles Chen

I've blogged about the Visitor pattern previously and using double dispatch to resolve .NET's inherent inability to resolve methods by parameter type at runtime.

As I was reading about C# 4.0's dynamic types, I started to wonder if this would mean that we could finally get a more concise implementation of the pattern.  My hunch was correct.

Here is the updated code listing (key changes bolded):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace VisitorPatternConsole
{
    public class Program
    {
        private static void Main(string[] args)
        {
            // NOTE: Using dynamic collections.
            Collection<dynamic> visitors 
				= new Collection<dynamic>();
            Collection<dynamic> pets 
				= new Collection<dynamic>();

            // Initialize the pets
            pets.Add(new Fish());
            pets.Add(new Dog());

            // Initialize the visitors
            visitors.Add(new Feeder());
            visitors.Add(new Walker());

            // Visit each of the pets.
            foreach (dynamic pet in pets)
            {
                foreach (dynamic visitor in visitors)
                {
                    visitor.Visit(pet);
                }
            }

            // Check the results.
            foreach (Pet pet in pets)
            {
                Console.Out.WriteLine(pet.GetType().Name);
                foreach (String note in pet.Visitors)
                {
                    Console.Out.WriteLine("\t{0}", note);
                }
            }
        }
    }

    /// <summary>
    /// Handles the base cases.
    /// </summary>
    public abstract class AbstractVisitor
    {
        public void Visit(Pet pet)
        {
            pet.Visitors.Add(
                "Not supported for this type of pet...");
        }
    }

    /// <summary>
    /// Concrete visitor, a pet feeder.
    /// </summary>
    public class Feeder : AbstractVisitor
    {
        public void Visit(Dog dog)
        {
            // Feed the dog
            dog.Visitors.Add("Fed the dog");
        }

        public void Visit(Fish fish)
        {
            // Feed the fish
            fish.Visitors.Add("Fed the fish");
        }
    }

    /// <summary>
    /// Concrete visitor, a pet walker.
    /// </summary>
    public class Walker : AbstractVisitor
    {
        public void Visit(Dog dog)
        {
            dog.Visitors.Add("Walked the dog");
        }

        // Fish can't be walked!
    }

    /// <summary>
    /// Base class for pets.
    /// </summary>
    public abstract class Pet
    {
        private readonly Collection<string> visitors;

        public Collection<string> Visitors
        {
            get { return visitors; }
        }

        protected Pet()
        {
            visitors = new Collection<string>();
        }
    }

    /// <summary>
    /// A pet fish.
    /// </summary>
    public class Fish : Pet { }

    /// <summary>
    /// A pet dog.
    /// </summary>
    public class Dog : Pet { }
}

Here is the output:

Wow, just when I thought dynamic was going to suck :-D

What is somewhat interesting is that both collections have to be declared of type dynamic; I'm still mulling this over, but it's not clear why it doesn't work if only one of the collections is declared dynamic (I figured that it should have worked if the visitors collection alone was declared dynamic).

Filed under: .Net, Awesome No Comments
27May/090

Random DevTools Entry #017

Posted by Charles Chen

In software development, it's incredibly useful to be able to visualize your code interactions using sequence diagrams and data flow diagrams and what not.  Not only is the visualization a plus, the act of generating one helps tremendously in terms of working out the outline of the logic that you need to implement.  One of the biggest problems I've come across in this area are the tools: they're simply too heavy and too complex for general diagram drawing tasks in addition to being generally rigid as well.


Today, as I was about to download and install Visio, I decided to spend a few minutes checking to see if there was a web alternative.  Enter websequencediagrams.  This is an all around awesome little tool to add to your toolbox.  Not only is it free (free is always awesome), it's text based.  At first blush, this seems terrible; there's a whole syntax to learn and lots of typing.  But the syntax is incredibly easy and simple while powerful and easy to understand.


Here's an example (I've bolded the syntax to make it easier to distinguish):



Browser->App: HandleSearchClickEvent()
App->Service: ExecuteSearch(keyword)
activate Service
Service-->App: (return results)
deactivate Service
App->App: RenderResults(reseults)
note right of App:
    render URL with
    keyword in query string.
end note
App-->Browser: HTML
Browser-->Office: click:
http://../name.docx?term=keyword
Office->AddIn: ThisAddIn_Startup()
AddIn->AddIn: Check for search term
note left of AddIn:
    ActiveDocument.FullName will
    contain the query string.  This
    can be extracted with a regular
    expression
end note
AddIn->AddIn: Execute find


And here is the result:



There are also a variety of pre-defined styles you can choose to render your diagram.  It's all sorts of awesome and a real time-saver compared to traditional tools.  I personally love that it's text based; I've found that when working with Visio (and other such tools), more than half of my time is spent arranging things just to get them to line up.  A text based approach works well for sequence diagrams and gets rid of that layer of unnecessary complexity.

Filed under: Awesome, DevTools No Comments
11Mar/092

Integrating NaturalDocs With SyntaxHighlighter (For The Win!)

Posted by Charles Chen

In working on some SDK-style developer documentation for FirstPoint, it occurred to me that we needed a way to create some all encompasing documentation which covered not only our code base, but also our markup, our JavaScript controls, CSS, and so on. We currently have most of this stuff in Trac wiki pages, which is a great place to put them, but our Trac deployment is going away and being replaced by Jira...or so I'm told.

In light of this, we needed a way to create portable, useful, developer documentation which included a mix of some auto-generated content and hand crafted documents as well (how-to's and stuff, which would be really terse if placed in code comment). There aren't really any do-it-all tools, but I stumbled across NaturalDocs which seemed to be the most well rounded tool of the ones I looked into (i.e. JSDocs, YUI Doc, a few others - it started off as a search for a tool for documenting UI conventions, markup, and script usage for our team) because of the fact that it allowed for the inclusion of loose .txt files which would essentially be treated like wiki pages.

You can see an example of the output at the MapQuest API documentation site.

One of the main reasons I liked NaturalDocs is because of the support for code blocks and how easy it is to write them in the loose text files. However, the downside is that the generated output is pretty...boring. Here's an example:

You can see that it has no intelligence with regards to the language. Doing a little digging around the 'Net, I found a ticket for a request for support for syntax highlighting. So I ended up rolling my sleeves up and solving this myself. I decided to integrate against the SyntaxHighlighter JavaScript library since I've used it previously and I like the output :-) .

Here is the end result:

I hadn't touched Perl in quite some time (since college), so I had to dig around in there for a bit but I was able to integrate it after a few hours of flailing.

The steps required are as follows (these steps assume you use framed mode):

In the file FramedHTML.pm, you will need to add the following lines to the method BuildFile after the call to $self->ClosingBrowserStyles():

. '<script language="javascript" src="' . $self->MakeRelativeURL($outputFile, $self->HighlighterShCore(), 1) . '"></script>'
. '<script language="javascript" src="' . $self->MakeRelativeURL($outputFile, $self->HighlighterShBrushCSharp(), 1) . '"></script>'
. '<script language="javascript" src="' . $self->MakeRelativeURL($outputFile, $self->HighlighterShBrushXml(), 1) . '"></script>'
. '<script language="javascript" src="' . $self->MakeRelativeURL($outputFile, $self->HighlighterShBrushCss(), 1) . '"></script>'
. '<script language="javascript" src="' . $self->MakeRelativeURL($outputFile, $self->HighlighterShBrushJs(), 1) . '"></script>'
. '<script language="javascript" src="' . $self->MakeRelativeURL($outputFile, $self->HighlighterShBrushSql(), 1) . '"></script>'
. '<script language="javascript">'
. 'SyntaxHighlighter.config.clipboardSwf = "' . $self->MakeRelativeURL($outputFile, $self->HighlighterClipboard(), 1) . '";'
. 'SyntaxHighlighter.all();'
. '</script>'

Next, to support the new getters, you will need to modify HTMLBase.pm and add the following lines:

sub HighlighterShCore
	{
	my $self = shift;
	return NaturalDocs::File->JoinPaths($self->JavaScriptDirectory(), 'shCore.js' );
	};

sub HighlighterShBrushCSharp
	{
	my $self = shift;
	return NaturalDocs::File->JoinPaths($self->JavaScriptDirectory(), 'shBrushCSharp.js' );
	};

sub HighlighterShBrushXml
	{
	my $self = shift;
	return NaturalDocs::File->JoinPaths($self->JavaScriptDirectory(), 'shBrushXml.js' );
	};

sub HighlighterClipboard
	{
	my $self = shift;
	return NaturalDocs::File->JoinPaths($self->JavaScriptDirectory(), 'clipboard.swf' );
	};

sub HighlighterShBrushCss
	{
	my $self = shift;
	return NaturalDocs::File->JoinPaths($self->JavaScriptDirectory(), 'shBrushCss.js' );
	};

sub HighlighterShBrushJs
	{
	my $self = shift;
	return NaturalDocs::File->JoinPaths($self->JavaScriptDirectory(), 'shBrushJScript.js' );
	};

sub HighlighterShBrushSql
	{
	my $self = shift;
	return NaturalDocs::File->JoinPaths($self->JavaScriptDirectory(), 'shBrushSql.js' );};

You should add more to handle whatever syntaxes you need to handle.

By default, the code blocks are generated as <blockquote><pre></pre></blockquote>. To support SyntaxHighlighter, we'll need to change this to allow customizing the class name on the <pre> tag. I decided to use the suggested syntax for including this in the markup: (start code <language>). For example: (start code js). The first module that we have to modify to support this is Native.pm. In the method FormatBody, I made the following change to support the extra token:

# If the line looks like a code tag...
# [CHUCK] ORIGINAL: elsif ($commentLines->[$index] =~ /^\( *(?:(?:start|begin)? +)?(?:table|code|example|diagram) *\)$/i)
elsif ($commentLines->[$index] =~ /^\( *(?:(?:start|begin)? +)?(?:table|code|example|diagram) *((?:\w+)?) *\)$/i)
	{
	if (defined $textBlock)
		{
		$output .= $self->RichFormatTextBlock($textBlock);
		$textBlock = undef;
		};
	# [CHUCK] ORIGINAL: $output .= $tagEnders{$topLevelTag} . '<code>';
	$output .= $tagEnders{$topLevelTag} . "<code class=$1>";
	$topLevelTag = TAG_TAGCODE;
	}

You can see that I've introduced a capturing group to the regular expression to grab the language type (matching SyntaxHighlighter's language strings). The next step is to modify the generation of the intermediate <code> tag to include a class attribute.

If you stop here, the output generation doesn't work correctly since this only affects the intermediate output. We need to jump to HTMLBase.pm and modify the method NDMarkupToHTML so that we can generate the proper tag structure. Here are my modifications:

# [CHUCK] ORIGINAL: my @splitText = split(/(<\/?code>)/, $text);
my @splitText = split(/(<\/?code *(?:class=[^\>]+)?>)/, $text);

while (scalar @splitText)
	{
	$text = shift @splitText;

	if ($text =~ m/^(?:<code *(?:class=([^\>]*))?>)$/i)
		{
		$output .= "<blockquote><pre class=\"brush: $1\">";
		$inCode = 1;
		}

You can see that here, I changed the regular expression used to split the intermediate output into chunks to properly split on the new markup structure. In the if-statement, I changed the eq comparison to a regular expressoin match with a capturing group and inserted that into the output <pre> tag (for the win!).

Now be warned: this is not a complete fix. While this addresses the major issue, generation of the proper output, I did not make changes to copy the image files and JavaScript files required by SyntaxHighlighter (sorry, you're going to have to do that yourself :-P ). The next set of steps are to:

  1. Copy the images associated with SyntaxHighlighter to the \output\styles directory (or whereever you like).
  2. Copy the scripts required for SyntaxHighlighter to the \output\javascript directory.
  3. Modify the paths in the CSS for the icons used with SyntaxHighlighter (in the shCore.css file).

Of course, the themes and CSS files are easy to include since you can specify those at the command line.

That's all there is to it! Happy documenting! I've attached sample files (including the modified source) for SyntaxHighlighter 1.5 and 2.0.

natural-doc-sh2.0.7z (315.01 KB)
natural-doc-sh1.5.7z (281.7 KB)

Filed under: Awesome, Dev, DevTools 2 Comments
7Jan/090

The Coolest Thing I’ve Read This Year

Posted by Charles Chen

Well, so far anyways:

http://www.telegraph.co.uk/scienceandtechnology/science/sciencenews/3981697/Scientists-plan-to-ignite-tiny-man-made-star.html

While it has seemed an impossible goal for nearly 100 years, scientists now believe that they are on brink of cracking one of the biggest problems in physics by harnessing the power of nuclear fusion, the reaction that burns at the heart of the sun.
In the spring, a team will begin attempts to ignite a tiny man-made star inside a laboratory and trigger a thermonuclear reaction.

As a side note:

Until now, such fusion has only been possible inside nuclear weapons and highly unstable plasmas created in incredibly strong magnetic fields. The work at Livermore could change all this.

The sense of excitement at the facility is clear. In the city itself, people on the street are speaking about the experiment and what it could bring them. Until now Livermore has had only the dubious honour of being home of the US government’s nuclear weapons research laboratories which are on the same site as the NIF.

Filed under: Awesome, News No Comments
6Nov/080

44

Posted by Charles Chen

One of my favorite quotes from the news coverage:



"[Barack Obama] is the first 21st century president."


- Chuck Todd, MSNBC


What our peers across the pond think:



They did it. They really did it. So often crudely caricatured by others, the American people yesterday stood in the eye of history and made an emphatic choice for change for themselves and the world. Though bombarded by a blizzard of last-minute negative advertising that should shame the Republican party, American voters held their nerve and elected Barack Obama as their new president to succeed George Bush. Elected him, what is more, by a clearer majority than one of those bitter narrow margins that marked the last two elections.


Check out the comments, too. 


jigan:




Truly a beautiful moment. I feel like I have witnessed a historic moment that, unlike 9/11 and the invasion of Iraq, is actually very positive.


I think in many ways it transcends the politics of Democratic/Republican and race. It's a repudiation of the "spend a little time on the dark side" years of Cheney.


As a Brit ex-pat living in the US, I'm finally tempted into exploring citizenship. Hey, maybe there's even a God...?


sidewaysantelope:




Congratulations, America, I'm truly in envy of your country right now. Oh to be so politically energised, so motivated, so...ready to do something about the world, and not in a Daily Mail, let's sack all comedians kind of way. Positive energy. I'd almost forgotten humans were capable of it, and I don't say that with any exaggeration.


Worth staying up for.


EssemD:



bloody hell... what a country.. after all these years living here as an ex-pat, 28, I actually want to be an American. It's 10 pm.. the kids stayed up to watch Obama's speech... my teen and i just sat there and let out tears flow.. even my 6 yr was moved to tears....


boywithaproblem:



From Adelaide, South Australia I congratulate all of those who voted for Obama. I'm inspired by this and it's made me reassess my perception of the US. I had tears in my eyes today. A historic day for the US and the rest of the world. Wonderful.


Mervo:




Obama's election gives rise to a depressing thought: his brilliance as a candidate is nowhere to be found in British politics. Our election in whenever is going to be a gloomy event.


Nevertheless, today is a good day. Congratulations America.


Holiver:



Sometimes I wish I was an American, in those moments where they seem to stand apart from us. Their endless optimism and their endless desire for change and movement and history. They make history, where as an English woman I feel I am just you know in it. I don't know that much about life, or what it takes to be a successful adult because well I am just a student, full of that optimism and promise and you know I like to watch Jeremy Kyle. I sat up and watched Obama become the 44th American President, I watched Americans cry and I cried and I believed in him and his words and the fact that really, this is going to have an impact on us all and to say that we are not involved is really fruitless.


Derk:



For all the bad things people say about American there are moments in there history where the prove they are the greatest country in the world. When you see that the UK may vote for posh Eton toff as our next leader and their are less ethnic MP's in Parliment than the percentage of enthic people in the country, then the UK can no longer claim to be more developed than the USA.


The USA is changing from a fist to brain. Good choice America.


I think the world just let out a huge sigh of relief; we can finally move forward and really move into the 21st century as a leader not by our might, but by the power of our example.

Filed under: Awesome, News No Comments
29May/080

Awesome News For Web UI Developers

Posted by Charles Chen

Google's new AJAX Libraries API should help quite a bit with developing web UIs.  From Dion Almer:

I just got to announce the Google AJAX Libraries API which exists to make Ajax applications that use popular frameworks such as Prototype, Script.aculo.us, jQuery, Dojo, and MooTools faster and easier for developers.
Whenever I wrote an application that uses one of these frameworks, I would picture a user accessing my application, having 33 copies of prototype.js, and yet downloading yet another one from my site. It would make me squirm. What a waste!
When I joined Google I realised that we could help out here. What if we hosted these files?

Read more about it here.

By the way, I caught this little tagline from ajaxian:

Because after 10 years, we're still hand-coding.

There's a lot to be said for the productivity gained from drag-&-drop RAD tools, but ultimately, software engineering is still at a stage where craftsmanship matters (a lot) and there is no substitute for a skilled craftsman.

Filed under: Awesome, Dev No Comments