June 19, 2013

Chris Strom (new tag)

Don't Use a Regular Expression When a String Will Do

‹prev | My Chain | next›

It is deadline-day for 3D Game Programming for Kids, so today's post may be briefer than normal. But the gods of the chain who have been so very good to me require their offering and an offering they shall have.

Not coincidentally, the ICE Code Editor, which is used exclusively in the book is nearing a milestone deadline as well: the it-has-to-work-for-the-book deadline. Fortunately, most of the major issues have been cleared up. In fact, there are only two issues still outstanding: a project sharing features that one of my collaborators has nearly finished and a minor bug. Saaay… minor bug sounds perfect tonight!

In the ICE Code Editor, we work hard to ensure that none of the actions overwrites an existing projects. This is a new feature of the Dart version of ICE. I believe that it was possible to overwrite existing projects in the JavaScript version by creating a new project, renaming a project, making a copy, opening a shared project or looking funny at a project. Maybe not the last one.

The feature that prevents overwriting projects in the Dart version is not so much thanks to Dart as it is thanks to the ease of Dart's unit testing library. As with any tool, it is only as good as the person wielding it and I seem to have overlooked something.

Existing tests verify that copied projects get the copy number placed in parentheses:
    test("copied project includes copy number in parentheses", (){
helpers.createProject('Project #1');

helpers.click('button', text: '☰');
helpers.click('li', text: 'Make a Copy');

expect(
query('.ice-dialog input[type=text]').value,
equals("Project #1 (1)")
);
});
The problem facing me tonight is that projects ending with parentheses are not creating copies correctly. Or, in unit-test-ese:
    test("project name ending in parens", (){
helpers.createProject('projectNamedForFunction()');

helpers.click('button', text: '☰');
helpers.click('li', text: 'Make a Copy');

expect(
query('.ice-dialog input[type=text]').value,
equals("projectNamedForFunction() (1)")
);
});
Thankfully, that fails:
Exception: Bad state: No elements dart:core-patch/growable_array.dart:152
List.last dart:core-patch/growable_array.dart:152
Store.nextProjectNamed package:ice_code_editor/store.dart:119
CopyDialog._copiedProjectName package:ice_code_editor/full/copy_dialog.dart:30
CopyDialog.open package:ice_code_editor/full/copy_dialog.dart:12
MenuItem.el.<anonymous closure>
If that had not failed, then I would have been forced to determine what was different between my test case and the live application before I could get down to fixing the bug. As it is, I have another bit of good news: the bug appears to be on line 119 of the store.dart code file. In other words, I only have to solve this bug in one place for it to be solved anywhere that is trying to use this copy-number functionality.

I eventually track this down to the code that finds the list of all projects with the same base name:
    // ...
RegExp copy_number_re = new RegExp(r"\s+\((\d+)\)$");
var title = original_title.replaceFirst(copy_number_re, "");

var same_base = values.where((p) {
return new RegExp("^" + title + r"(?:\s+\(\d+\))?$").hasMatch(p['filename']);
});

// ...
The problem is that the title in there is projectNamedForFunction()The parentheses in there are interpreted as regular expression syntax instead of literal strings that should match. I could go through and replace parentheses with their escaped counterparts (e.g. '\\('), but then what about project names with square brackets or curly braces?

And then it hits me. Why am I using a regular expression to match literal strings when a simple literal string comparison will do? So instead, I determine the list of projects with the same base name by asking for all projects that start with the base:
    // ...
RegExp copy_number_re = new RegExp(r"\s+\((\d+)\)$");
var title = original_title.replaceFirst(copy_number_re, "");

var same_base = values.where((p) {
return p['filename'].startsWith(title);
});
// ...
And that does the trick:
PASS: Copy Dialog project name ending in parens
I have no idea why I would have used the regular expression in the first place, but my test suite confirms that the simpler string works. With that bug squashed, I can safely return to the last few fixes in 3D Game Programming for Kids. Wish me luck…


Day #786

by Chris Strom (noreply@blogger.com) at June 19, 2013 03:57 AM

June 18, 2013

Chris Strom (new tag)

Triggering Not-So-Custom UI Events in Dart

‹prev | My Chain | next›

I still have not decided if I want to keep last night's focus tests. I wrote a bunch of tests for the ICE Code Editor, but only ended up verifying that most everything worked already. Admittedly this was more of a noticeable problem in the old JavaScript version of ICE, but I had expected more trouble than I found.

I do not think it is so much Dart that made things better as being more consistent in the approach that I took towards buttons, menus and dialogs. Of course, Dart's static typing encourages consistency, but then again so does a strong #pairwithme partner and I have been blessed with many.

At any rate, I did leave off last night with a single failing focus test:
ERROR: Focus- editor has focus after closing a dialog
Focus- editor has focus after closing a dialog: Test setup failed: Expected: TextAreaElement:<textarea>
But: was BodyElement:<body>.
Unlike most of the other tests from yesterday, this was a “good” one in that it reproduced buggy behavior that I can see in the application.

My initial instinct for fixing the bug was to add an ice.focus() call in the hideDialog method:
_hideDialog() {
queryAll('.ice-menu').forEach((e)=> e.remove());
queryAll('.ice-dialog').forEach((e)=> e.remove());
ice.focus();
}
If that was all that was necessary to fix it, I would have been done with it last night. The trouble is that the _hideDialog() method is not so much a method on the full-screen version of ICE as it is a helper function. In other words, it does not have access to an instance of ICE nor do the calling contexts always have access.

So to make this pass, I think that I have to have _hideDialog() trigger an event on the main DOM element that holds the editor. The constructor for the full-screen version of the editor creates an #ice <div>:
Full({enable_javascript_mode: true}) {
el = new Element.html('<div id=ice>');
document.body.nodes.add(el);

ice = new Editor('#ice', enable_javascript_mode: enable_javascript_mode);
store = new Store();
// ...
}
So sending a focus event to the #ice element seems the best course of action:
_hideDialog() {
queryAll('.ice-menu').forEach((e)=> e.remove());
queryAll('.ice-dialog').forEach((e)=> e.remove());
query('#ice').focus();
}
A listener on the onFocus event stream should then do the trick:
      el.onFocus.listen((e)=> ice.focus());
It ought to work (at least in my mind), but it does not. The on-focus event is never fired. I could rail against the focus() method failing to generate a focus event, but that will get me no closer to solving my problem.

Instead of telling the element to focus, perhaps I can send a custom event? Or better yet, I try sending a focus event since that is really what I am trying to do:
_hideDialog() {
queryAll('.ice-menu').forEach((e)=> e.remove());
queryAll('.ice-dialog').forEach((e)=> e.remove());
query('#ice').dispatchEvent(new UIEvent('focus'));
}
That is an uglyish constructor signature, but it does the trick. The event is received by the <div id=ice> element, which in turns tells the underlying ICE editor that it has focus. Yesterday's work, which turns out to not be a complete waste after all, ensures that the proper part of ICE—the code editor or the preview layer—gets focus. The bottom line is that I have a passing test:
PASS: Focus- editor has focus after closing a dialog
PASS: Focus- hiding code after update preview has focus
I do believe that closes another issues on the ICE Code Editor tracker, which is a fine stopping point for tonight.


Day #785

by Chris Strom (noreply@blogger.com) at June 18, 2013 03:59 AM

June 17, 2013

Chris Strom (new tag)

Driving Focus Tests

‹prev | My Chain | next›

I have enjoyed refactoring my ICE Code Editor tests over the last few days. I have an even better understanding of how to test in Dart and how to make those tests as readable and robust as possible. I am sorely tempted to continue mucking about with the test suite itself, but the most pressing issue that I need to answer tonight is an actual feature. More specifically, I need to figure out how to test when different pieces of ICE are visible.

One of the few remaining issues in the so-called 3D Game Programming for Kids milestone is giving ICE focus after dialogs and menus have closed. Since the milestone gets its name because it is blocking a release for the 3D Game Programming for Kids book, it seems worth making it a priority.

I need to start by adding a feature to the core Editor class, which is responsible for synchronizing the ACE code editor with a preview layer for the visualizations. Currently, there is no way to focus anything in the core editor, so I need to drive that feature.

I start with the setup for the new focus group in the editor_test.dart file:
  group("focus", (){
var editor;

setUp((){
document.body.nodes.
add(new Element.html('<div id=ice-${currentTestCase.id}>'));

editor = new Editor(
'#ice-${currentTestCase.id}',
enable_javascript_mode: false
);

return editor.editorReady;
});
// Test will go here...
});
Since this is a core editor test, I have to manually create a <div> to hold the editor. In the full-screen class, this is done automatically, but this is a lower level test, hence the greater manual effort. I add the editor to that element and return a future as I learned last night.

With that, I am ready to test. The first test simply verifies default state—that the code editor is visible:
    test('code is visibile by default', (){
var el = document.
query('#ice-${currentTestCase.id}').
query('.ice-code-editor-editor');

expect(el.style.visibility, isNot('hidden'));
});
After some debate, we opted to hide the code editor with CSS visibility rather than via z-index hackery of setting the display to none. I am still not sold on this, but it does make this test easy. And, not unexpectedly, this test passes. In fact, all of the tests for the low-level editor pass. The focus seems to naturally go to the correct location. Well, that and it seems that I had inadvertently copied some focus code from the JavaScript version when I was first getting started on the Dart version:
  showCode() {
_editor_el.style.visibility = 'visible';
query('.ace_print-margin').style.visibility = 'visible';

_ace.renderer.onResize();
_ace.focus();
}
(again ACE is the actual code editor piece of ICE, which is incorporated via #pairwithme js-interop)

Once I am done with the core editor, I work my way out to the Full screen IDE-lite class, Full. That actually works as well except in the case in which the code is edited, then hidden before the preview layer has a chance to update itself. Immediately after the code is hidden, the preview has focus, but the updated iframe is enough to lose focus.

I drive the test as usual:
  solo_group("Focus", (){
var editor;

setUp((){
editor = new Full(enable_javascript_mode: false)
..store.storage_key = "ice-test-${currentTestCase.id}";

var preview_ready = new Completer();
editor.onPreviewChange.listen((e){
if (preview_ready.isCompleted) return;
preview_ready.complete();
});
return preview_ready.future;
});
// tests here
});
But, instead of writing a test, I add another group with more async setup (I really love that newly discovered feature):
    group("hiding code after update", (){
setUp((){
editor.ice.focus();
editor.content = '<h1>Force Update</h1>';
helpers.click('button', text: 'Hide Code');

var preview_ready = new Completer();
editor.onPreviewChange.listen((e){
preview_ready.complete();
});
return preview_ready.future;
});

test("preview has focus", (){
var el = document.query('iframe');

expect(document.activeElement, el);
});
});
Making that pass is a simple matter of adding a discrete focus() call.

In the end it is a lot of work to verify that most everything is working as desired. Still, it is worth the trouble to have the assurance of a stronger test suite.

I end the night by driving the feature that started this adventure
    test("editor has focus after closing a dialog", (){
helpers.click('button', text: '☰');
helpers.click('li', text: 'Make a Copy');
helpers.hitEscape();

var el = document.
query('.ice-code-editor-editor').
query('textarea.ace_text-input');

expect(document.activeElement, el);
});
That gets met the expected error:
ERROR: Focus editor has focus after closing a dialog
Focus editor has focus after closing a dialog: Test setup failed: Expected: TextAreaElement:<textarea>
But: was BodyElement:<body>.
That may end up being a little trickier than expected since the menu options lack direct access to ICE to manipulate focus. I think it best to leave that for tomorrow. I always appreciate being able to start work with a failing test. It makes it so easy to jump right in.


Day #784

by Chris Strom (noreply@blogger.com) at June 17, 2013 03:54 AM

June 16, 2013

Diving into Dart

This Week In Dart #1

There's been a number of interesting Dart related projects and resources springing up this week. Here are a few highlights.

The Dart Cheat Sheet
is a very handy reference to bookmark. Has anyone managed to print it neatly?

Angular.js has announced a port to Dart:

Pluralsight have published a Dart Web Applications online course.

Finally the Dart Editor/SDK had its usual weekly update to R23799 - with refactoring and editor improvements. More details in the Change Log.

by Davy Mitchell (noreply@blogger.com) at June 16, 2013 07:31 AM

Chris Strom (new tag)

Async Test Setup in Dart

‹prev | My Chain | next›

At this point, I think it's safe to say that I am huge Dart testing fan. I have hundreds of tests covering Dart for Hipsters (many of which are broken at the moment). I have another 100+ covering ICE Code Editor (which is being written to support 3D Game Programming for Kids, which in turn is blocking me from updating Dart for Hipsters). Bottom line: I love Dart tests.

I have gotten quite adept at writing them—regular, asynchronous, client-side, server-side. It's all good. But there is still lots that I do not know. Some stuff that I do not know is stuff I do not even know that I do not know—the stuff that will bite me when my current abstractions break down as I try new things. One thing that I know that I don't know is asynchronous test setup.

(I really enjoyed writing the above paragraph and I think it almost makes sense)

The unittest documentation for setUp(), concludes with:
The setupTest function can be asynchronous; in this case it must return a Future.
I do not really understand what it means for a setupTest to be asynchronous. I know from bitter experience that the tests within a group() sharing a setUp are asynchronous, but how can a setUp() itself be asynchronous and how does it help?

It so happens that many of the tests in the ICE Code Editor have a Future floating around. We use the editorReady future to indicate when all of the associated JavaScript has finished loading. To enable this to work in tests, we wrap the actual test in a function that will not be invoked until the expected asynchronous call from the future is made.

In one of the download tests, it looks something like:
    test("it downloads the source as a file", (){
_test(_) {
// actual test expectations go here
}
editor.editorReady.then(expectAsync1(_test));
});
The expectAsync1 is built into Dart's unittest. It prevents the test from passing until it is called (with one argument). Instead of using it to test an asynchronous operation, I am using it to poll for the JavaScript libraries to finish loading before running an unrelated test. I do this a lot in ICE—in well over 50% of the tests I would guess.

But it now occurs to me that the editorReady is a Future. What if I move it up into the setUp() test to be returned?
    setUp((){
editor = new Full(/* ... */);
return editor.editorReady;
});
Does that mean that I can get rid of my abuse of expectAsync? Indeed it does. I remove the expectAsyncs from both of the tests in the Download feature:
  group("Download", () {
setUp((){
editor = new Full(/* ... */);
return editor.editorReady;
});

test("it downloads the source as a file", (){
// Just test code now
});

test("closes the main menu", () {
// Just test code now
});
});
And the tests still pass:
unittest-suite-wait-for-done
PASS: Download it downloads the source as a file
PASS: Download closes the main menu
All 2 tests passed.
unittest-suite-success
If I comment out the return of the editor.editorReady, then both tests fail because pieces of the underlying editor are not ready (are null):
unittest-suite-wait-for-done

FAIL: Download it downloads the source as a file
Caught The null object does not have a getter 'value'.

NoSuchMethodError : method not found: 'value'
Receiver: null
Arguments: []
...

FAIL: Download closes the main menu
Caught NoSuchMethodError : method not found: 'ace'
Receiver: Instance of 'Proxy'
Arguments: []
...

0 PASSED, 2 FAILED, 0 ERRORS
Exception: Exception: Some tests failed.
Holy cow. Without that expectAsync code, the intent of my tests are 100% clearer. I am amused by my own arrogance in thinking that I knew Dart testing. Clearly there is still much to learn. I find that a very exciting prospect.

But before finding any new stuff, I have roughly 50 tests that need to be cleansed of unnecessary expectAsync calls.


Day #783

by Chris Strom (noreply@blogger.com) at June 16, 2013 01:49 AM

June 13, 2013

Dartcasts.com

Episode 15: WebStorm + Dart Downloading and setting up...



Episode 15: WebStorm + Dart

  • Downloading and setting up WebStorm
  • Building command-line Dart applications
  • Setting up Dartium
  • Compiling Dart into JavaScript
  • Using WebUI

June 13, 2013 01:04 PM

June 12, 2013

Seth Ladd

Create unified interfaces across dart:io and dart:html

Dart runs on the client, thanks to dart:html, and on the command line, thanks to dart:io. However, like oil and water, those two libraries just don't mix. Your web apps can't use dart:io, and your server apps can't use dart:html. Normally, this isn't a problem, because the two different targets are oh so very different. However, some concepts are common, such as Web sockets or HTTP requests. Wouldn't it be nice to have a unified interface to Web sockets that works with either dart:io or dart:html? I'll spare you the suspense: Yes!

This post shows you one strategy to design a high-level interface for functionality that exists in both dart:io and dart:html. While the Dart team has the concept of configurability on their radar, not much concrete action has happened. In the meantime, try this strategy and you too can experiment with unifying interfaces and APIs. Code reuse FTW!

(This post was inspired by Mark Bennett's original question who is trying to build a more unified Web Socket interface.)

Step 1: Create a library and an interface

Design the interface that unifies something from dart:html and dart:io.

library shared; abstract class BaseFoo { common(); }

Step 2: Implement the interface for dart:html

In another library, implement the interface with dart:html:

library html_thing; import 'dart:html'; import 'shared_interface.dart'; class Foo extends BaseFoo { common() { print('from html'); } }

Step 3: Implement the interface for dart:io

In another library, implement the interface with dart:io.

library io_thing; import 'dart:io'; import 'shared_interface.dart'; class Foo extends BaseFoo { common() { print('from io'); } }

Step 4: Package it up

All of the previous code can go into the same pub package.

Pick a library to use

The consumer of your pub package must decide which library to import. For example, a dart:io app might look like this:

import 'dart:io'; import 'package:sharedinterfacetest/io_version.dart'; main() { var foo = new Foo(); foo.common(); }

Hope that helps! All the code for this example is found at Github.

by Seth Ladd (noreply@blogger.com) at June 12, 2013 10:16 PM

Dartlang

Angular.js announces port for Dart

The Angular team recently announced a Dart port of the popular Angular.js framework.

Large parts of Angular functionalitycomponents like $compiler and $scope, basic directives like ngBind and ngRepeathave already been ported over to Dart and can be used today.  Other critical Angular parts like Dependency Injection and Routes are being ported now. Karma, the Angular test runner, already works with Dart.

Angular team members Brad Green and Igor Minar provide details in the video from the AngularJS meetup this week. The Dart-specific discussion begins at the 40 minute mark.





by Shailen Tuli (noreply@blogger.com) at June 12, 2013 05:32 PM

Notes From the June 4 Dart Language Design Meeting

The incomporable Bob Nystrom fills us in on the language design discussions taking place amongst Dart engineers. Here are his notes from the June 4th language meeting:

Here's my notes. As usual all mistakes are my own:

are boxed doubles identical?

There is a bug where doubles with the same value may return false for identical() because they have been boxed to different objects.

Lars said it's been discussed. For doubles, identical() should return true based on value. We don't want the language spec to have to mention boxing so that the VM is free to optimize how it wants.

Gilad asked if NaN is identical to NaN?

Lars says yes. It's identical but not equal. Gilad will fix the spec.

change uninitialized field error to warning?

Uninitialized final fields are currently an error in the language. Kasper suggests making it a warning. It seems in line with other stuff in language. It's easy to associate some value with an uninitialized final.

Gilad says we can do this and asked why Kasper ran into it. Kasper saw some bugs where implementations behaved differently in some related corner cases.

Lars doesn't have a problem with it.

const instance variables

Gilad's view is that they should work like statics except for scoping. Apparently, though, it's complicating the VM implementation of instance metadata. Three solutions:

1. No const instance fields.
2. Metadata is statically scoped.
3. Try to do it correctly.

Lars likes 1. I say 1 simplifies things for users. Right now, people get confused with static final const etc. Gilad is OK with 1.

I asked if the syntax would be "static const" or just "const"? Users get confused when having to do "static" with constants.

Lars says they are confused because they don't understand the system. Requiring "static" will help them understand what's going on.

what liberties can editor take with type system

[I didn't have a lot of context here, so I'm fuzzy on the details.]

Dan Rubel asked how flexible the analyzer can be with the Dart type system and how it can extend it.

Gilad is OK with things like type inference for auto-complete. What other things should we allow?

Lars says step one is to do exactly what the spec says. Going beyond that and helping user with refactoring and stuff is great. Using it for warnings gets strange. If you go from the Editor to command line, you would get different warnings.

Dan's concern is more about false positives. We should look at code and see if they use constructs like guarded type promotion.

Lars says if users are using these constructs a lot, we should change the language to support them. If you want to have a type guard match thing we should have a different construct. But for now, the analyzer should go with the current spec.

Kasper says we have to be careful if we report fewer warnings because users will get used to that and then get confused if other tools follow the spec more closely and have more warnings.

stack traces

Lars had lots of discussions back and forth with some internal Dart users. One issue is about catching exceptions and capturing stack traces and how its painful for some. Lars is OK if severe errors like noSuchMethod automatically get a stack trace.

Kasper says that would mean two ways to access stack traces. I note that with async, it's three. Lars says Florian has some idea of a constant flag to enable/disable stack trace capturing.

Gilad asks if the spec would have to lay out which errors get stack traces and which don't? Lars says they'll come up with a proposal.

Cheers!

As always, view the changelog for the full list of changes, and to get started with the Editor see our tutorial.

by Shailen Tuli (noreply@blogger.com) at June 12, 2013 03:39 AM

June 11, 2013

Seth Ladd

Call JavaScript from Dart - First Look

You can use Dart to access existing JavaScript code, thanks to the Dart-JS Interop package. Call JavaScript functions from Dart, send Dart callbacks to JavaScript, and more!



The Dart core libraries have a lot of functionality provided out of the box (collections, querying the DOM, dates and times, math, and more), so you can get quite far with just the Dart SDK and the many pub packages. However, there are plenty of useful JavaScript libraries that can really help enhance Dart web apps. Luckily, Dart can synchronously talk to JavaScript!

Step 1: Install the js package

Add the following to your pubspec.yaml file:

dependencies:
  js: any

Step 2: Get a JavaScript library

Hugs make you feel better, let's use the hugs.js library:

function Hug(strength) {
  this.strength = strength;
}

Hug.prototype.embrace = function(length) {
  return 'Thanks, that was a good hug for ' + length + ' minutes!';
}

Hug.prototype.patBack = function(onDone) {
  onDone('All done.');
}

Be sure to include the JavaScript file in your main HTML file:

<script src="hugs.js"></script>

Step 3: Write Dart code

import 'dart:html';
import 'package:js/js.dart' as js;

void main() {
  // Grab the context from JS land.
  var context = js.context;
  
  // Use the [] notation to let --minify work.
  // See https://github.com/dart-lang/js-interop/issues/86
  
  // Get a proxy to the JS object.
  var hug = new js.Proxy(context['Hug']);
  
  // Call the embrace method and pass in 10.
  var result = hug['embrace'](10);
  
  query('#output').text = result;
  
  // Call the patBack method and pass in a callback.
  hug['patBack'](new js.Callback.once((msg) {
    query('#output').appendText(' This just in: $msg');
  }));

}

The hug instance is accessed via a js.Proxy object. You can even pass a Dart function as a callback to a JavaScript function!

Summary

Use the Dart-JS interop library to access the billions of existing JavaScript libraries from Dart. Read the article for more details and see examples that use the Twitter API, Google Maps API, and the Google Charts API from Dart. The pub package is open source on Github, and is maintained by Googlers and engineers from the community.


Photo Credit: Gloson cc

by Seth Ladd (noreply@blogger.com) at June 11, 2013 08:40 PM

June 10, 2013

Diving into Dart

Dartclass Got Types! (Optionally)

My first live Web UI app, 'Dartclass' has had a little update. It has Type Declarations which are, of course, optional in true Dart style.

Properties/Observables - String.name="daftspaniel" becomes String name = "daftspaniel";

Methods - int.getAge becomes int getAge(){}

The notation of int.getAge is a bit funny but it allows spaces to separate the list of items and is easy to type. I'd welcome feedback on that choice and any other aspect of the tool. It would be easy to add an alternative character. I first consider an underscore but it requires the SHIFT key on my keyboard. Hope this helps you get started coding some great ideas.

Next for Dartclass, I'd like it to generate a basic HTML file for Web Components.

by Davy Mitchell (noreply@blogger.com) at June 10, 2013 09:14 PM

Pub Deploy Bug To Be Aware Of

Dart is still maturing as an environment, so if you start working in it you should expect the odd issue.

Dart has a command 'Pub Deploy' to create a regular JS web deployable version of your project. It works great for a first release of such a big feature. Unless you are using GIT. 10983: Pub deploy fails if out/ is in .gitignore.

Easy enough to get .gitignore out the way, deploy and then put it back. A fairly painless workaround. Enough of a frustrating GOTCHA to be worth highlighting. Makes me wonder where they are going long term with this tool. I don't think DEPLOY should depend on a particular VCS. Odd.

by Davy Mitchell (noreply@blogger.com) at June 10, 2013 11:42 AM

June 06, 2013

Seth Ladd

Forms, HTTP servers, and Web Components with Dart

Dart can be used on the client and the server. This post shows how to:
  • build a form as a custom element
  • bind input fields to a Dart object
  • build a Dart HTTP server
  • handle and parse a form submit


For lots more examples, and more context and details, be sure to check out the Dart Tutorials. You can find the code for this post at my Github account.

Step 1: Install the Web UI package

Open up pubspec.yaml (used by the pub package manager) and add the dependencies for Web UI.

dependencies:
  browser: any
  web_ui: any

Step 2: Create the model class

This class is for our "business object". It is bound to the form, so we make it observable.

library person;

import 'package:web_ui/web_ui.dart';

@observable
class Person {
  String firstName;
  String lastName;
  double age = 0.0// not an int because web ui loves doubles
}

Step 3: Create the custom element HTML

This custom element, polyfilled by Web UI, wraps the form and makes it easy to reuse. The custom element is bound to an instance of Person, our model class. The <template> tag contains the structure of this custom element. Notice the submit event runs the submit() method of this custom component (see in the next step). The $event object, representing the submit event, is passed to submit().


    <element name="person-form" constructor="PersonForm" extends="div">
      <template>
        <div id="message"></div>
        <form method="post" on-submit="submit($event)">
          <input type="text" bind-value="person.firstName" name="firstName">
          <input type="text" bind-value="person.lastName" name="lastName">
          <input type="number" bind-value-as-number="person.age" name="age">
          <input type="submit">
        </form>
      </template>
      <script type="application/dart" src="personform.dart"></script>
    </element>

Step 4: Create the custom element Dart code

If a custom element needs custom behavior, you can implement it with Dart. Each custom element tag you use on the page as an instance of its corresponding class. The submit() method is called when the form is submitted (see the on-submit binding from Step 3). The person and action fields of the PersonForm class get initialized by attribute and data bindings from the usage of the custom element tag.

In this case, we disable the default behavior of form submission so we don't incur a page reload. We use HttpRequest to submit the form data, and update a div inside our custom element with the response text.

import 'package:web_ui/web_ui.dart';
import 'person.dart';
import 'dart:html';

class PersonForm extends WebComponent {
  Person person;
  String action;
  
  submit(Event e) {
    e.preventDefault();
    
    FormElement form = e.target as FormElement;
    form.action = action;
    
    HttpRequest.request(form.action,
          method:form.method,
          sendData:new FormData(form))
        .then((HttpRequest req) {
          host.query('#message').text = req.responseText;
        })
        .catchError((e) => print(e));
  }
}

Step 5: Import and use the custom element

Use a <link> tag to import the custom element. Use the custom element with is="person-form" attribute on a <div>. An instance of person (created in the next step) is bound to the custom element. The action attribute on div is used to set the action via static data binding.

<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="parse_form_submit.css">
    <link rel="import" href="personform.html">
  </head>
  <body>
    <h1>Forms</h1>
    
    <div action="http://localhost:8888/submit" is="person-form" person="{{person}}"></div>

    <script type="application/dart" src="parse_form_submit.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

Step 6: Create the app's main code

All this app needs is one instance of Person. The instance defined here is visible to the page, and is the same as used in the custom element from Step 5 (person="{{person}}"). The main() method is empty, because Web UI handles all the binding, initialization, etc.

import 'person.dart';

Person person = new Person();

main() { }

Step 7: Write the server

Dart's dart:io library help you write command-line and server-side application. We use the builtin HTTP server functionality to listen for POST requests, parse the form data into a Map, enable CORS headers (so pages from any origin can submit to this server), and send back a string version of the original form data.

import 'dart:io';

main() {
  HttpServer.bind('0.0.0.0', 8888).then((HttpServer server) {
    server.listen((HttpRequest req) {
      if (req.uri.path == '/submit' && req.method == 'POST') {
        print('received submit');
        HttpBodyHandler.processRequest(req).then((HttpBody body) {
          print(body.body.runtimeType); // Map
          req.response.headers.add('Access-Control-Allow-Origin', '*');
          req.response.headers.add('Content-Type', 'text/plain');
          req.response.statusCode = HttpStatus.CREATED;
          req.response.write(body.body.toString());
          req.response.close();
        });
      }
    });
  });
}

Summary

Ta da! You've just used Dart to create a live, data-bound form and wrapped it up in a web component. Then, you wrote a Dart server to parse the form data and return a simple response. Be sure to checkout the Github repo for this post for all the code (as I left out a few things). Is this the best we can do? Probably not, you probably want a more full-featured server-side framework. There are a few in pub.dartlang.org for you to explore.

Learning more

To learn more about Dart, try these resources:

Photo Credit: jasleen_kaur

by Seth Ladd (noreply@blogger.com) at June 06, 2013 02:27 AM

June 05, 2013

Diving into Dart

Class Wizard

I like the editor that comes with the SDK but I hate the look of a new blank file! So I wrote this little tool to generate the basic code of a class. I find it good for working on ideas too. Feedback appreciated!

Dart Class Wizard Tool - Update Should really have the BETA tag on this :-) There's various small updates being published to this URL. Should settle down soon.

Code is on GitHub

by Davy Mitchell (noreply@blogger.com) at June 05, 2013 06:15 PM

June 04, 2013

Dartlang

Faster is Better: New Article on Numeric Computation in Dart

"Performance matters to everyone", says Dart engineer John McCutchan. His new article, "Numeric Computation", tells you how to get "50-100% speed improvements" with just a few simple rules.

John covers integers, doubles, boxing, typed lists, and more. He also covers various considerations for Dart code that is compiled to JavaScript.

Boxing requires a memory allocation and a store. Unboxing requires a load.
If you write code that works with numbers, and that's pretty much everyone, you should read this article. Please join us for discussion in our Dartisans community. Thanks for trying Dart!

by Seth Ladd (noreply@blogger.com) at June 04, 2013 06:24 PM

May 30, 2013

Dartlang

Dart project co-founders answer your questions

The Dart team received a lot of great feedback from the community in response to our various Dart presentations at Google I/O. We asked Lars Bak and Kasper Lund, Dart project co-founders, to help answer your questions. Here's what they shared. Enjoy!




Q01: Are there any plans for to use Dart as an alternative or replacement to Java for Android app development (native APK apps)? James Wendel, United States

A01: The current focus for Dart is web applications. Your best bet is to talk to the Android team about this.



Q02: In some benchmarks the DartVM is now outperforming the JVM. Do you you think it will be possible for the DartVM to outperform the JVM for most code? Are there specific areas where the JVM's design will allow it to perform better than the DartVM? Greg, Wellingtron

A02: For programs like numeric computations Java will always have a performance advantage over the Dart VM. The reason is that Dart code is dynamically typed whereas Java has built-in basic types like byte, int, and double. However, for object oriented application code we see no reason for not matching or exceeding the speed of JVMs. We will continue to push performance of the Dart VM since performance is a key driver for web application innovation.



Q03: Few years back GWT was heavily promoted by Google. Now Google is promoting Dart for the future web development. How could I convince my company towards those technology for the longer run? and what are benefits would I get if I choose? Thamizharasu, Chennai

A03: Dart is on track to get into Google Chrome, is used by critical internal projects, and has a growing community. Dart has commitment from Chrome, has a large and experienced team working on it, and the team is investigating how to place Dart into a standards organization.



Q04: In which ways the requirement of Javascript as a compilation target for compatibility affected Dart? What would you make different if this requirement wasn't there? mdakin, Zurich

A04: To ensure compatibility with all modern browsers, we only added language featured to Dart that could be translated into efficient JavaScript. One useful feature we abandoned was "non-local returns" that requires unwinding of stack activations. In JavaScript you can implement a non-local return by throwing an exception. However, this turns out to be extremely slow on most JavaScript engines.



Q05: How much faster than Javascript can Dart get? Nik Graf, San Francisco

A05: The Dart team's goal is be at least 2X faster than V8. See dartlang.org/performance for some benchmarks and results.



Q06: Can you share some details on language support for asynchronous programming? It's a huge pain in JavaScript and Dart can make a real difference here. Ladislav Thon

A06: We expect to take another look at what language features might help with async programming, but not until after 1.0 launch.



Q07: Any hints about possible future language features that could be added after 1.0 is released? Greg, Wellingtron

A07: We expect to implement enums. We also expect to explore features for async.



Q08: Today Google introduced new Android Studio. Is there a plan for releasing something similar for Dart? Valeriy, Ukraine

A08: We're happy that JetBrains has a Dart plugin for IntelliJ and WebStorm. The Dart team supports this effort, and collaborates with JetBrains. Also, you can try our Dart Editor.



Q09: Can you outline the distinctions between Dart and GO on the server side? Will Dart in the future compete with GO on the server side? thien bui, Berlin

A09: There are many distinctions between Go and Dart. Go is a structurally typed language, requires a compiler, has goroutines for concurrency, and is designed for lower-level systems programming. Dart is nominally types, does not require a compiler, uses isolates for concurrency, and is designed for modern web apps (that run on client and server). Dart has been designed to compile to JavaScript, Go has been designed to compile to efficient server-side code. Go is more mature, and has more tools than Dart right now.



Q10: Are there plans to extend SIMD support by adding new features like AVX and add GPU programming support to language and VM? mdakin, Zurich

A10: There are plans to take advantage of the new AVX instruction set. One example, would be adding Float32x8 type which fits inside the new 256-bit wide registers. Another example would be to use the new gather and permute instructions. There are no plans to add GPU programming support to Dart at this time.



Q11: EcmaScript 6 is taking shape - offers classes, modules, block scoped vars (let/const), iterators and other good stuff. asm.js offers performance. Why use Dart - especially if the DartVM is not built into Chrome(OS)/Blink and Android. kc, UK

A11: We're excited to see JavaScript continue to evolve. Dart is a more ambitious effort to take a fresh look at web programming, and thus doesn't need to deal with all the backwards-compatibility issues facing ES6. For example, Dart has many new features like string interpolation, mixins, isolates, lexical this, ints and doubles, named constructors, named optional parameters with default values, real libraries, tree shaking, no undefined (only null), simple truthy/falsey values (only true is true), and of course optional type annotations. Dart is a more toolable, statically analyzable language and thus it's easier to be more correct about refactoring, warnings and errors, code navigation, tree shaking, and more. People use Dart because they like the performance and productivity. (Note: asm.js only accelerates a narrow type of programming, which is dealing with numbers. The Dart VM optimizes programs you'd author by hand.)



Q12: What are the advantages/disadvantages of a sourcecode VM, such as Dart, versus a bytecode VM, such as the JVM? Greg, Wellingtron

A12: Productivity comes to mind. With a source code VM, you don't need to first compile code before running the app. Thus, the iteration cycles are much faster. Just edit and reload! This is important for web developers who want to iterate quickly. Note that the Dart VM internally generates machine code from the source code, via its optimizing compiler.

Also, a real disadvantage of a bytecode VM is the VM needs to verify the integrity of the bytecodes before they can be executed. This adds complexity and opens up for security problems.



Q13: For now Google is the only one embracing Dart on Chrome. I don't see Mozilla, Apple and any other browser embracing Dart sonner. Using pure JavaScript to solve this issue won't let Dart survive forever. So how to make sure that Dart would survive? ghabrianis@gmail.com, Tunisia

A13: Dart is designed to be a productive programming language that compiles to JavaScript. Because developers can write apps with Dart and deploy across the modern web today, the future of Dart is determined by developer adoption.



Q14: If I develop a WebGL game, will I ever be able to target iOS and leverage the performance of the Dart VM or native compilation? Filipe Morgado, Portugal

A14: It is currently an outstanding research project to determine how to port Dart apps to iOS and still remain performant. Luckily, Dart is open source so we look forward to the community exploring this area.



Q15: Are there plans to introduce shared state concurrency and parallelism? Filipe Morgado, Portugal

A15: No, we’re not planning on supporting general shared state concurrency. Having said that, we are very interested in improving our support for concurrent and parallel algorithms.



Q16: Will SIMD support make it into V8? b, sf

A16: V8 implements the ECMAscript standard, so the question is really “will SIMD support make it into ECMAscript” and that is best answered by the ECMAscript committee.



Q17: Will there be an option to see the generated code along with actual Dart code in the editor in future? mdakin, Zurich

A17: That is a very good idea and certainly worth filing a feature request issue on http://dartbug.com/ for. In the meantime, you can output the generated code that the VM produces with this command:

dart --disassemble_optimized --code_comments

You can also try http://web.irhydra.googlecode.com/git/hydra.html to view the output from the Dart VM compiler.



Q18: Can you explain Dart to a six-year old? Ruudjah, Netherlands

A18: It is hard to explain any programming language to a six-year old, but maybe you could tell him/her that Dart is a tool that might make the next web version of Angry Birds have more pigs and angrier birds?

by Seth Ladd (noreply@blogger.com) at May 30, 2013 04:49 PM

May 26, 2013

Daniele Salatti

What’s New in Dart: Your First-class Upgrade to Web Development

Yet another video from Google I/O 2013.

Come see what’s new in Dart with its comprehensive, open-source ecosystem for the modern web developer. Learn how to be more productive with a new language: future-based DOM, package manager, JS-interop, a tree-shaking compiler to JavaScript, SIMD, Web Components, a rich editor, and much more. You’ll leave this talk all caught up with Dart and ready to make the web awesome.

by Daniele Salatti at May 26, 2013 04:06 PM

May 23, 2013

Dartwatch

Win-win for developers and users: Dart @ Google I/O 2013

Win-win for developers and users: Dart @ Google I/O 2013

Google I/O 2013 is now over, and Dart had a pretty good showing, with three Dart talks and a codelab.
Performance was a big theme throughout Google I/O, especially with Chrome and Mobile in mind. Mobile apps running with a touch screen need to be more responsive than ever to create a good user experience (when you're physically touching a widget, you expect it to respond immediately to your touch), and there was lots of discussion about the target 60 fps refresh rate on mobile.

Win 1: Great performance for users.

Lars Bak and Kasper Lund's talk on VM Performance highlighted some of the problems that they face when designing a VM. They've designed VMs in the past (including Hotspot VM and Chrome's V8), and although V8 made great leaps initially (an initial benchmark in Firefox ran at "100" when V8 was being invented. Now, the same benchmark runs at around "~16,000"), the rate of improvement is slow. In order to get the next "leap" in performance, they need to address some of the problems with the actual language (JavaScript). An example given in their talk is that V8 optimizes based upon known executions of a block of code up to that point. If, however, that code changes (such as inserting a new property into the prototype), the optimizer has to back-out the optimizations until it's ready to optimize again. All this has an overhead.

By designing a language that is designed to make it easy to optimize a VM for, Dart's is already ahead of V8 in terms of performance (after only about 2 years of development, compared to 7 years of V8).
enter image description here
Image courtesy Stephen Shankland / cnet
There are (currently broken) instructions on the Dart wiki about building a VM on ARM, and it has to be thought that a long-term goal must be to get the Dart VM (integrated with chrome?) running on Android. This has twin benefits for users: better application performance, and longer battery life (as there is less work done).

By making use of advance chip technologies, such as SIMD (Single Instruction, Multiple Data) the Dart VM is able to leverage the maximum power available. A great demo of this was the 3d demo of monsters - only around 35 were visible with SIMD turned off in the VM (at 60fps), but when SIMD turned on, 60fps was maintained with ~120 monsters.
enter image description here
Image courtesy Stephen Shankland / cnet

Win 2: Great experience for developers.

I also spent some time on the Dart stand in the sandbox talking to web developers about Dart, and went to the Dart codelab. As a developer, it's awesome to be able to leverage Web Components combined with Dart's well known language features (libraries, functional, unsurprising and familiar classes, optional typing), all wrapped up with with great tools such as package management, IDE, Debugger and type checker. Developers that I was talking to at the Dart stand seemed suitably impressed with what Dart currently had to offer (especially as many hadn't looked at it since its initial release).
"It can't really be this easy?"
In the Codelab, which used Web Components to build a multi-file, offline document editor, the other developers sat around me had positive views, with one even saying "It can't really be this easy? - It almost feels like cheating." - Yes, Dart really is productive. Give the codelab a try and see for yourself.

That quote summed up the current state of Dart for me, when I go around doing talks on Dart, and showing Dart to fellow developers, they are often surprised to see the great developer story and productivity gains. When combined with the improved performance of apps with the Dart VM, they start to see how it can help to move web applications on to the next level.

On JavaScript future.

Because Dart also targets JavaScript, any advances made in JavaScript to allow better JavaScript optimizations will also benefit developers and users. Developers still get the same great Dart development story, and users will benefit from increased performance of their JavaScript version of the Dart app. Of course, browsers that contain the Dart VM will likely to continue to remain faster running native Dart than the equivalent JavaScript.

The Sessions from I/O

Images from cnet article "Dart will rescue browsers from JavaScript"

by Chris Buckett (noreply@blogger.com) at May 23, 2013 03:52 PM

May 22, 2013

Daniele Salatti

Web Components & Polymer

A couple of really interesting videos from Google I/O 2013.

Web Components are here to fundamentally change the way we think, build, and consume our web apps. This session will prepare you for the future of the web platform by discussing the lower level technologies that form the basis of Web Components (Shadow DOM, custom elements, MDV, new CSS primitives). Many of these tools have already landed in a modern browser near you!

This session builds on technologies and concepts discussed in a previous session, “”Web Components: a tectonic shift for web development”". This year web development gets a whole lot better thanks to the incredible power of Web Components. Our goal in this session is to show you how to use polyfills to help you realize tomorrow’s web platform today. As browsers implement these new specifications, that shim layer gets smaller, better, and faster over time. We’ll talk about shadow DOM, custom elements, declarative data/event binding, touch input, smooth animations, and how you can combine them to create awesome apps. Write less boilerplate, target every platform, and be more productive by using the next generation of the web platform.

by Daniele Salatti at May 22, 2013 03:09 PM

Seth Ladd

Watch the video from What's New in Dart from Google I/O 2013

Google I/O was a blast, and Dart had a great time. For posterity, check out the video of my talk with co-presenter Justin Fagnani. We covered what's new across the Dartosphere, including language features, libraries, tools, and ecosystem.



Like what you see? Head on over to dartlang.org to download the SDK and check out our docs and tutorials. You can always find us in our Dartisans G+ community. Stop by and say hi!

by Seth Ladd (noreply@blogger.com) at May 22, 2013 03:41 AM

May 15, 2013

Future Perfect

When Does a Completer Complete?

In the future, of course. It sounds obvious, but when this change was first announced, I wasn’t immediately sure how to cope with it in my undone library.

Undone is an asynchronous library, as I talked about in my last post, so you may want to read that first for some background on why I’m working with Completers. In developing my library I’ve sort of grown up with dart:async and things have started to stabilize now. It was non-trivial for me to do, and I have been responsible for the development of asynchronous processing libraries in other systems in the past. Many of the challenges to exposing an asynchronous API in Dart are well known and oft talked about in the community, so I don’t want to dwell on them in this post. I really like dart:async and I am confident the tools we’ll have for working with it will continue to advance and improve over time.

Warning, Don’t Use a Completer!

Its true, you really don’t want to use these unless you need to. Knowing when to pull one out of your async toolbag can be tricky, especially when you are new to Dart. When I first started designing async APIs in Dart, I always started out with a function body skeleton like the following:

Future task() {
  final completer = new Completer();

  // Complete some async task

  return completer.future;
}

This is 100% legitimate Dart code, and a careful investigator of my undone library will tell me that the majority of its functions still use this pattern. It is true, but undone is somewhat exceptional when compared to the majority of async libraries I have written in Dart. The majority of them use futures in their signatures in order to make calls to other async functions. This is the contagion that is async programming. If your code is async mostly because of interoperation with other async code, then you likely can and should avoid using completers.

There are a lot of ways to construct a Future these days, which is a good thing. There weren’t always as many options, but the API has matured since its inception. I don’t want to try and break it all down here for fear of veering way off topic, and there is plenty of official documentation and examples to get you started. Returning futures directly from the different branches of your code means that all the plumbing of how the values (and errors) propagate through the chain is managed for you, which is very helpful. When you use a completer, you are breaking that chain and you are now responsible for the propagation of both values and errors from the async code you call into back to the callee of your code.

Please Just Tell Me When They Complete

Okay, so you’re using a completer and you’re pretty sure that you should be (or you just don’t believe me and want to see for yourself!). That’s cool, I use them too sometimes. Up until very recently I was abusing them though, and that is the subject of this post - when do they complete?

Let’s consider the following small program:

import 'dart:async';

main() {
  int i = 42;  
  incrementAsync(i)
    .then((result) => squareAsync(result))
    .then((result) => print('result: $result'));    
}

Future incrementAsync(int value) {
  final completer = new Completer();
  int result = value + 1;
  runAsync(() {        
    completer.complete(result);
    print('$result');
  });
  return completer.future;
}

Future squareAsync(int value) {
  final completer = new Completer();
  int result = value * value;
  runAsync(() {
    completer.complete(result);
    print('$result');
  });
  return completer.future;
}

The above program has two async functions, incrementAsync and squareAsync, which both perform some async work (using the runAsync utility) on an integer value and complete the future result using a completer. In the main function, we start with the value 42 and we chain a computation interlaced with print calls to log the intermediate values. It is in the ordering of the print output where we can observe the recent change in completer behavior.

First, consider the output of this program using the Dart SDK 0.5.5_r22416:

43
result: 1849
1849

In order to understand the order of operations, we break down the computation into 3 microtasks, where (1) and (2) correspond to the anonymous closures that we pass to the runAsync function. We can then visualize better the sequence of events that leads to the printed output:

main            |   (1)             |   (2)       
incrementAsync  |   complete [43]   |   complete [1849]
runAsync(1)     |   then            |   then
                |   squareAsync     |   print [result: 1849]
                |   runAsync(2)     |   print [1849]
                |   print [43]      |

As we see in the microtask (1) above, there are three function calls that come between the call to completer.complete(result) with the value 43 from inside the scope of incrementAsync and the call to print('$result') with the value 43 from the next line of code in that same function. The reason for this is that the call to completer.complete(result) was synchronous in that version (and all prior versions) of the Dart SDK.

Next, consider the output of this program as of the Dart SDK 0.5.7_r22611:

43
1849
result: 1849

Whoa! Let’s break this into microtasks again before anyone panics:

main                |   (1)               |   (2)         
incrementAsync      |   complete [43](2)  |   then        
runAsync(1)         |   print [43]        |   squareAsync
                    |                     |   runAsync(3)
-------------------------------------------------------------
(3)                 |   (4)
complete [1849](4)  |   then
print [1849]        |   print [result: 1849]

As we can see above, we have two more microtasks than before. This is because each call to completer.complete(result) is now internally using runAsync to do its work. The result is that now our calls to print('$result') are called before the completer’s complete, and the output of our program has changed.

I think that this change is the right thing to do. Before, I was being lazy in some ways by relying on the synchronous behavior of the completer. Worse than that, however, is that my library was not robust because of it. I was assuming that when I completed the future to the caller of my API, that they would do all of their work synchronously. If the user had chained any futures with more async work onto the completer’s future, my old code would have blown up because I was assuming that everything was said and done when the call to completer.complete(value) returned. So I am very happy this change was made because it prompted me to dig in further and to perform this analysis.

Okay, so I hope that it is clear what behavior has changed. But, in undone I really need to do some cleanup work at a point in time where I know that the completer has completed. This includes the work of any other futures that the user might have chained onto my completer’s future. How can we know for certain that the sequence of async computations initiated by completing the completer has completed?!

The answer is by careful use of the whenComplete method on the completer’s future. Let’s hook this into our async example functions as follows:

...
Future incrementAsync(int value) {
  final completer = new Completer();
  int result = value + 1;
  runAsync(() {  
    completer.future.whenComplete(() => print('$result'));
    completer.complete(result);
  });
  return completer.future;
}
...

By changing incrementAsync and squareAsync as shown above, the output of our program returns to what we had originally:

43
result: 1849
1849

One subtle point regarding whenComplete is when we call it. Remember, our function returns the completer.future to the caller, who is free to chain other async computations onto that future. If we call whenComplete before we return to the caller, we will be at the front of the future chain. This might be desired in some situations, but for undone I want to be at the end of the future chain in order to cleanup internally. By calling whenComplete right before we call completer.complete(result) we can ensure that no other code can chain on after us.

That is my story of when the completer’s complete. The dart:async library is very powerful, but working with it requires a fair amount of patience. Hang in there, as I’m hopeful that the debugging story will improve and maybe we’ll even get some language support for this in future versions of Dart. Please do leave me comments or feedback, and don’t be overly harsh on my microtask charts; I know that they are far from scientific :)

by Ross Smith at May 15, 2013 12:00 AM

May 13, 2013

Dartwatch

Lots of new ways to keep up with #dartlang changes

The Dartisans community has grown, with currently >2000 members on the +Dartisans group, and >1500 subscribers to the Dart Weekly newsletter.  Keeping up with the latest changes can be tricky.

Google's Andrei Mouravski has just posted this on the mailing lists:




tl;dr: We have some new discussion groups. Sign up for announce@dartlang.org.
For a quick summary, read the Guidelines section below.


Hello Dartisans!

As our community has grown, so has discussion around Dart, so we have created four new discussion groups, and updated a few others.

New Groups:

announce@dartlang.org : Dart Announcements
This group is for official announcement for the Dart project. This will be product releases, breaking changes, major events, press briefs, and other important messages for the entire Dart community. For now, the group will remain limited to a select group of individuals who manage specific parts of the Dart project.
I recommend signing up for this group today, as it is a low volume way to stay up to date with Dart on a day-to-day level.
---

Note: Replies to announcements in this group should go to dart...@dartlang.org to keep the announce list noise-free, but still provide a forum for discussion.

For the time being, posts to
anno...@dartlang.org will be forwarded to mi...@dartlang.org.
In a few weeks we will remove the forward to misc@dartlang.org to prevent unnecessary duplicate e-mails, so sign up now!



dart-dev@dartlang.org : Dart Core Project and Libraries Development
This is the list to go to if you want to discuss the development of the Dart open source project. As the project continues to grow, it’s important to be able to stay connected with state of the core of Dart itself.

This is a good place to talk about core library APIs, discuss breaking changes, and interact with the Dart engineering team. If you’re thinking of contributing to the Dart project, let us know in this group!

This list will be more technical than some of the other lists, so keep that in mind when subscribing. You should subscribe to this list if you’re interested in keeping up with day to day Dart development and engineering.

---

Note: If your discussion is about a project you’ve created, broad feature requests such as other languages’ features you’d like to see in Dart, the state of the web/JavaScript/html5/etc., news, links, or events, then please post to misc@dartlang.org. See the guidelines below.



html-dev@dartlang.org : Dart DOM/HTML Libraries Development
If you want to keep up with the latest developments to the HTML/DOM libraries, here’s where to go! The libraries in question are: dart:html, dart:svg, dart:web_audio, dart:web_gl, dart:indexed_db, dart:web_sql, and dart:chrome, but it’s possible there will be more. This is the group to follow to hear about changes to DOM bindings.
I recommend signing up for this group, as it is a medium volume way to stay up to date with anything changing in the main DOM libraries. If you build client applications, or just care about the modern web, stay tuned!

editor@dartlang.org : Dart Editor and Plugin Development and Discussion
If you use the Dart Editor to write Dart code, or debug Dart applications, or for any reason at all, this is the group for you. The Editor team loves, probably more than any other team, receiving feedback. This list is a great place to talk about what you want to see in the Editor, and discuss the state of the Dart IDE.

---


Other groups:

Just a reminder about the other groups we have:

misc@dartlang.org : Miscellaneous Discussion
vm-dev@dartlang.org : Dart VM Development
compiler-dev@dartlang.org : dart2js Development
web-ui@dartlang.org : Dart Web UI Package Discussion

The following groups are read-only, as their posts are auto-generated:

commits@dartlang.org : Commits to the Dart Repository
bugs@dartlang.org : Dart Issue Tracker Updates
reviews@dartlang.org : Dart Code Review Updates

---

And just to be clear, here are guidelines for posting to any of the groups:

Guidelines

by Chris Buckett (noreply@blogger.com) at May 13, 2013 12:55 PM

May 10, 2013

Shannon -jj Behrens

Personal: Links to My G+ and Twitter Accounts

If you enjoy my blog posts on Python, Ruby, Dart, etc., and you're looking for a new way to follow me now that Google Reader is going away, here are my Twitter and G+ accounts:

by Shannon Behrens (noreply@blogger.com) at May 10, 2013 06:15 PM

May 08, 2013

Christian Grobmeier

Review: Dart in Action

"Dart in Action" by Chris BuckettRecently I read “Dart in Action” by Chris Buckett. I know Chris from the early days of the Dart language. We both joined the community almost instantly. At the day of Darts arrival, he founded Dartwatch.com and blogs on all aspects of the language. Chris is definitely one of these guys who knows what he writes. After one year, a lot of blog posts, countless e-mails to the Dart mailing lists and doing a lot of other community related things, he finished a book on Dart.

A book? This alone is impressive. Dart is a kind of moving target. There is a lot of man-power behind its development and every day there are a lots of changes to Darts codebase. Dart arrived as a technical preview and as such it was allowed to have breaking changes. Chris was not only confronted with learning a language by looking at its specification and find out about hidden features in the bug trackers; he also had to rewrite whole sections over and over again just because the language changed. A simple example: suddenly the + operator for string concatenations was removed. A more complicated example: the whole library/import thing changed.

Still Chris kept on writing. Finally Dart became more stable in its core, and the book was released. What I got was a book from a dedicated and passionate Dart-developer, who knows the language, its ecosystem and the community from day 1.

The book itself reads like that. It’s a fantastic book which takes you by hand and leads you through the whole world of Dart. With that I mean it doesn’t stop at just explaining some grammar or how to use API $x. Dart is not “only a language”. Dart is a whole ecosystem consisting of language, APIs AND tools. Chris shows from the beginning where you need to look at, like using the Dart Editor or how to deal with third party dependencies.

You almost do not recognize how you get into all these new technologies. While he explains how to write code, he also shows how to debug it or what you can do with it in practice. It is far from boring grammar descriptions or rephrased API docs as one can often find in books. You can work on your program while reading this book. It’s for people like me, who do not want to read through 500 pages with boring examples just to make up something cool after the memorized all of the thousand keywords. This book shows you what you can do, how you do it, and what you should be aware of. It’s easy to connect the books content with your real-life-problems.

The writing style is clear, precise and well balanced. An easy read. The tune is one of a colleague who did find some great new toy to play with and now explains it to you. It is a motivating and inspiring text and very enjoyable. There was not a single chapter which made me bored or drifting away.

The content is a great mix of everything important in Dart.

You will learn about running Dart from the Browser but also how to run it from the shell, maybe when building your backend with Dart. You learn how you can write test driven code. Unit testing with Dart is especially something which I did not know much about before. In the early days of Dart it was not so much a topic, and due to work I did not follow it to closely later. Chris sent me back on track. Now I even know how to do browser testing, which is big win for me.

He explains on how properly to use classes, interfaces and constructors. Also he looks into libraries and shows possibilities here. What I like much is the fact he is also explaining best practices. Not only Darts best practice, but general ones. These are experiences he made maybe from his time as GWT developer. They are very helpful if you just start with your programming career.

In general, the core part of this book feels complete and balanced. There is even a part describing Futures and Completers. Both are heavily used async concepts in todays browser programming world, and with “Dart in Action” it is easy to get into them. Another bonus point is he is explaining how you can test asynchronous code. As this is a very difficult matter, I have not expected that.

The chapters on client development are also very good. One can first find a great introduction into single-page web apps. I wished I would have read this before a long time now. It also gives you a great view how you can actually build your Dart app. If you are coming from the classic approach of maintaining multiple pages, you might find this section very useful. He is also writing on how to use Cookies and Data Storage. Especially the browser db part I found very interesting.

One often asked question is how to interact with JavaScript from Dart and vice versa. You will find an answer in this book. Even more: Chris describes how to make apps for the Chrome web store. With this, you already have enough knowledge to start with your App, integrate it to existing libs and finally deploy it to its final destination. A complete cycle. But there is even more.

The book closes with looking at server side Dart. It’s shown how to interact with Apache CouchDB as data store and how one can serve HTTP requests with Dart. Everybody who is into Node.js knows that it is a great feeling to just use the same language for frontend and backend. Finally he looks into Isolates, one of my favorite topics. Even when I know a lot on Isolates (some kind of multithreading in Dart), I found this is a very competent introduction into it and  I did not regret to have it read.

My conclusion is this a great book. Usually I do not read books on programming languages anymore. They tend to be boring and quickly out of date. But this book is different. It shows you more than just grammar and APIs. It shows you how to move in the Dart world. How you solve things. It’s an enjoyable read from a very competent Dart programmer. If you want to learn Dart you already have the great docs on the website. But if you would like to get even more quickly into Dartlang, then you should definitely look at this book. Despite the language is still evolving, most of its content will be true for a long time. If not, then the author can be found in one of the Dart communities.

You can buy this book on Amazon.com or on Amazon.de (affiliate links).

by Christian Grobmeier at May 08, 2013 12:02 PM

May 07, 2013

Dartwatch

Campaign to use real logging (instead of print) in your libraries and apps

Summary of "Campaign to use real logging in Dart" (via tldr.io)
  • Using print() statements for debugging in your libraries means that everyone gets your print() output.
  • The Dart SDK has a "logging" package built in (that lets you write into a logging framework), but nothing to output those log messages.
  • The "logging_handlers" package adds those missing handlers, letting you output to the console (like print), filesystem (server side), and a webui component.
  • Now you (and I) can control the logging output from different libraries by varying the logging level different libraries.

Stop Using print(msg) start using info(msg)

When you use print(), other users of your code have to see all your internal debug logging (I know I'm guilty of this, too).
The logging_handlers package lets you use proper logging in your client-side or server side Dart application.

Why?

When I use your library (or when you use my library), I want to control the amount of logging output from your debug messages (and, I hope, you want to do the same for my debug messages). By using the Dart logging framework, we can both be happy.

There are two parts involved in logging:

  1. Sending log messages into a logging framework
  2. Outputting the log messages somewhere (eg, to the stdout, a file, the browser).
Dart's print() sort of covers both of these use cases, and the quick'n'dirty alternative described below also does the same thing. It's not the best way, but at least it means that log messages can be output somewhere other than the console (such as a file).

First, some background about logging

Dart's logging pub package, that forms part of the Dart SDK, covers use-case 1, in other words, it lets you send log messages into a logging framework.
This framework lets you attach handlers to that framework that can listen to the stream of log messages.
This package, logging_handlers provides some default handlers that lets you output messages to a variety of locations, in a variety of formats.
At the moment, you can output a log message as a tab delimited String or a JSONableMap, and you can output a log message to the console similar to print(), to a server-side file, or to a client-side web-ui component (or a mixture).

The quickest (and dirtiest) way to replace print()

This is not the best way, but it's certainly better than print().
  1. Add logging_handlers package to pubspec.yaml
  2. import 'package:logging_handlers/logging_handlers_shared.dart';
  3. Use debug(msg)info(msg)warn(msg)error(msg) as appropriate.
  4. Somewhere in your initialization code (start of your unit tests, main() or other initialization code), call startQuickLogging()
For example:
import 'package:logging_handlers/logging_handlers_shared.dart';

main() {
    startQuickLogging();
    info("Hello World");
}
will output to the console:
2013-05-06 16:42:42.593     [INFO]: Quick'n'Dirty logging is enabled.  It's better to do it properly, though.
2013-05-06 16:42:42.604     [INFO]: Hello World
Note: Dart's logging has more fine grained logging levels - the top-level functions above are shorthand for some of these:
             FINEST // highly detailed tracing
             FINER // fairly detailed tracing 
debug(msg) = FINE // tracing information
             CONFIG // static configuration messages
info(msg)  = INFO // informational messages
warn(msg)  = WARNING // potential problems
error(msg) = SEVERE // serious failures
             SHOUT // extra debugging loudness
But see below for better ways that allow users of your code more control over what actually gets output, and let you have finer-grained control over logging.

The a slightly better way (but still a bit quick'n'dirty) to replace print()

Let users of your code filter out your specific log messages by giving your log messages a name. The best name is the name of your library. for example:
library my_library; 
import 'package:logging_handlers/logging_handlers_shared.dart';

class Foo() {
  Foo() {
    debug("Foo is created", "my_library"); // calls debug with your library name
  }
}

main() {
  startQuickLogging();
  new Foo(); 
}
this outputs:
2013-05-06 16:42:42.593     [INFO]: Quick'n'Dirty logging is enabled.  It's better to do it properly, though.
2013-05-06 16:42:42.604 my_library      [FINE]: Foo is created
When you include your library name in your log messages, other users of your code can filter your log messages out (more on that later).

The best way to implement logging in your libraries

Create a Logger instance in your library, and give it the name of your library:
library my_library;
import 'package:logging_handlers/logging_handlers_shared.dart';

final _logger = new Logger("my_library");

class MyClass {
    MyClass() {
       _logger.fine("MyClass created");
    }

    foo() {
      _logger.error("Something bad has happened");
    }
}
You can have as many loggers as you need, and they can be hierarchical (using a . to separate). For example, you might have a top-level logger, and individual loggers for specific classes:
library my_library;
import 'package:logging_handlers/logging_handlers_shared.dart';

final _libraryLogger = new Logger("my_library"); // top level logger

class MyClass {

  // MyClass logger is a child of my_library logger
  static final _logger = new Logger("my_library.MyClass");

  MyClass() {
     MyClass._logger.fine("MyClass created"); // using class logger
  }

  foo() {
    _libraryLogger.error("Something bad has happened"); // using top-level logger
  }
}
When you use hierarchical logging, you (and your code's users) can start to take control over what actually gets output, and to where (such as outputting ALL logging for MyClass, but only WARNING, SEVERE and SHOUT logging for the library).
Now that you've seen how to emit log messages into a framework, let's take a look at how to control where those messages go

Controlling log message output

The code in your classes and libraries don't actually run until you pull them into a Dart application (or unit test) via the top-level main() function.
In the main() function, you need to initialize the logging framework with a logging handler. The simplest version of this is the PrintHandler, which outputs log messages to the console in the same way that print() does.
Let's assume that you've implemented logging using "the best way" which contains your logger name.
// the SDK logging framework
import 'package:logging/logging.dart'; 
// Handlers that are shared between client and server
import 'package:logging_handlers/logging_handlers_shared.dart'; 
// your library, from above...
import 'my_library';

main() {
  Logger.root.onRecord.listen(new PrintHandler()); // default PrintHandler
  var myclass = new MyClass(); // from above - outputs log message
}
If you're on the server-side, and you want to log to a file, the logging_handlers package includes a very simple (synchronous) filesystem log file handler: SyncFileLoggingHandler.
// the SDK logging framework
import 'package:logging/logging.dart'; 
// Handlers that run server-side
import 'package:logging_handlers/server_logging_handlers.dart'; 
// your library, from above...
import 'my_library';

main() {
  Logger.root.onRecord.listen(new SyncFileLoggingHandler("myLogFile.txt")); 
  var myclass = new MyClass(); // from above - outputs log message
}
And if you're on the client side, there's a handy (and incredibly basic) web component<x-loggerui> to output log messages on screen.
In your Web UI enabled application, your HTML will look something like this:
<html>
  <head>
    <!-- import the loggerui component -->
    <link rel="import" href="package:logging_handlers/src/client/loggerui.html">
  </head>

  <body>   
    <!-- other content... -->

    <x-loggerui></x-loggerui>  <!-- Logger widget -->

    <!-- standard app scripts -->
    <script type="application/dart" src="test.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>
And in your app's main() function, you call attachXLoggerUi() like this:
import 'package:logging_handlers/browser_logging_handlers.dart';

main() {
  attachXLoggerUi(); // lives in the browser_logging_handlers library
}
The attachXLoggerUi function runs in the next event loop iteration after main (usingTimer.run), so any startup logging won't appear. This is because the web component's themselves aren't available until the next event loop.
Here is a running example:

Attaching multiple handlers
Sometimes, you want to attach multiple handlers. That's fine, because the logging framework uses Streams, so you just need to use asBroadcastStream():
main() {
  var loggerStream = Logger.root.onRecord.asBroadcastStream();
  // attach the PrintHandler and the File logging handler
  loggerStream.listen(new PrintHandler()); 
  loggerStream.listen(new SyncFileLoggingHandler("myLogFile.txt"));       
}
Note At present, the implementations of the client and server handlers are fairly basic, but given time (and your help?), they should get greater functionality. Ideas include: Allowing the x-loggerui to filter based on level.
or creating an async version of the server side logger.

Getting more control over the output

Now you have seen what can be output, let's take a look at how you customize that.
Each of the handlers (LoggerUiSyncFileLoggingHandler and PrintHandler) implement aBaseLoggingHandler interface. These have a LogRecordTransformer instance, that transforms an SDK LogRecord into some other format.
The logging_handlers package contains two transformers that implementLogRecordTransformerStringTransformer and MapTransformer. All three handlers use a default implementation of a StringTransformer, but you can pass an alternative transformer into the constructor of both the PrintHandler or SyncFileLoggingHandler.
StringTransformer
The StringTransformer lets you control the fields that get output, for example:
main() {
  var fileHandler = 
      new SyncFileLoggingHandler("logfile.txt", transformer: new StringTransformer("%m"));
  Logger.root.onRecord.listen(fileHandler); // default 
  var myclass = new MyClass(); // from above - outputs log message
}
The StringTransformer allows formatting strings to specify the output. %m is just the message without all the other information, and replicates the print command.
The full list of formatting strings is shown below:
%p = Outputs LogRecord.level
%m = Outputs LogRecord.message
%n = Outputs the Logger.name
%t = Outputs the timestamp according to the Date Time Format specified
%s = Outputs the logger sequence 
%x = Outputs the exception
%e = Outputs the exception message
The default formatting strings are shown below (with \t for tab separation):
DEFAULT_MESSAGE_FORMAT = "%t\t%n\t[%p]:\t%m";
DEFAULT_EXCEPTION_FORMAT = "\n%e\n%x";
DEFAULT_DATE_TIME_FORMAT = "yyyy.mm.dd HH:mm:ss.SSS Z";
You can customize all of these when you create a logger handler.

Replacing the print() command

Now that you have seen some of the formatting available, let's see how you can actually replace the print() command:
main() {
  // simulate existing print command by only outputting the message
  Logger.root.onRecord.listen(new PrintHandler(messageFormat:"%m")); 
}

Taking control: Logging levels and heirarchical loggers

Let's suppose that you are using my library.
We have your_library and my_library
You don't want to see my logging when you test your library.
How can you control it?
Let's look at some code that outputs logging from your_library but not my_library:
import 'package:my_library/my_library.dart'; // don't want to see logging here
import 'your_library.dart';  // Show logging from this library please :)

import 'package:logging/logging.dart'; 
import 'package:logging_handlers/logging_handlers_shared.dart';

main() {
  hierarchicalLoggingEnabled = true; // set this to true - its part of Logging SDK

  // now control the logging.
  // Turn off all logging first
  Logger.root.level = Level.OFF;
  Logger.root.onRecord.listen(new PrintHandler());

  // create a logger for your library 
  // (there will be a single instance for each logger with the same name)
  // and set the level to ALL
  new Logger("your_library")..level = Level.ALL;

  doSomethingInYourLibrary(); // logging is output to console
  doSomethingInMyLibrary(); // logging is not be output      
}
Now let's use the hierarchy to use different logging for a specific class (assuming that you have a class logger created for your_library.YourClass):
main() {
  hierarchicalLoggingEnabled = true; // set this to true - its part of Logging SDK

  // now control the logging.
  // Turn off all logging first
  Logger.root.level = Level.OFF;
  Logger.root.onRecord.listen(new PrintHandler());

  // create a logger for your library 
  // (there is only a single instance for each logger with the same name)
  // and set the level to ALL
  new Logger("your_library")..level = Level.INFO;
  new Logger("your_library.YourClass")..level = Level.ALL;

  doSomethingInYourLibrary(); // Only INFO logging is output to console
  new YourClass(); // All logging output to the console
  doSomethingInMyLibrary(); // logging is not be output      
}

Quick Reference

Logging best practice
  1. Add logging and logging_handlers to pubspec
  2. Import the logging SDK where you want to write log messages
    import 'package:logging/logging.dart';
  3. Create a logger (or loggers), and use them
    ``` final _libraryLogger = new Logger("my_library");
    doSomething() { _libraryLogger.info("Something is done") }
    class MyClass { final _classLogger = new Logger("my_library.MyClass")
    MyClass() { _classLogger.fine("MyClass is constructed"); } } ```
  4. When you use your library / class, and want to output some logging, create an instance of a LoggingHandler and attach it to the root logger
    ``` import 'package:logging_handlers/logging_handlers_shared.dart'; import 'your_library';
    main() { Logger.root.onRecord.listen(new PrintHandler()); } ```
  5. When you want finer control over what get's output, use hierarchical loggin and set levels
    ``` import 'package:logging_handlers/logging_handlers_shared.dart'; import 'your_library'; import 'package:my_library/my_library.dart';
    main() { Logger.root.onRecord.listen(new PrintHandler()); Logger.root.level = Level.OFF; // log nothing by default new Logger("your_library")..level = Level.ALL; // log all in your library
    } ```
Server handlers are found here:
import 'package:logging_handlers/server_logging_handlers.dart';
Client logging handlers are found here:
import 'package:logging_handlers/browser_logging_handlers.dart';
Web UI component is here:
<link rel="import" href="package:logging_handlers/src/client/loggerui.html">
...
<x-loggerui></x-loggerui>

... 
// and in your script, call:
import 'package:logging/logging.dart'; 
import 'package:logging_handlers/browser_logging_handlers.dart';

main() {
  hierarchicalLoggingEnabled = true;
  attachXLoggerUi();
}

Caveats

The Logger framework (as at M4), has a TODO about logging exceptions. At the moment it doesn't. If you want to log exceptions, add the exception text to the log message.
If you find any problems or errors, then please let me know. This was current as at r21823

by Chris Buckett (noreply@blogger.com) at May 07, 2013 07:17 PM

May 06, 2013

May 05, 2013

Daniele Salatti

Dart links and resources

Here is a list of resources you may want to look at if you are just starting with Dart. Well, it’s also for my reference…

 

by Daniele Salatti at May 05, 2013 06:25 PM

April 30, 2013

Dartwatch

Try out Dart in your browser at http://trydart.dartwatch.com

Now you can try out Dart code snippets in your browser at http://trydart.dartwatch.com.

 Features: 

  •  Link to a shortcode of your Dart snippets 
  •  Embed runnable snippets in your blogs (like below).

At the moment it doesn't support pub packages, dart:io, dart:html, so it's only for trying out dart language snippets. Let me know if you use it, (or if you manage to break it :).

by Chris Buckett (noreply@blogger.com) at April 30, 2013 11:35 AM

April 27, 2013

Daniele Salatti

Dart Language Specification

For version 0.40 as of April 22, 2013.

Here‘s the official page.

by Daniele Salatti at April 27, 2013 08:54 PM

April 22, 2013

April 03, 2013

Adam Coding @ Github

gplus quickstart with dart

Tonights mash-up was taking the gplus-quickstart-dart and wiring it up for server side support. Similar to the gplus-quickstart-java, the client will use the gplus login button to do the OAuth2WebServer flow and send the code over to the server. The server can then verify and make calls on behalf of the client since an ‘offline’ token was requested. This demo just features the server side and what was used to put it together. Yulian Kuncheff has been the primary developer behind fukiya which is an express like framework for dart. The thing I liked most about fukiya was how simple and easy it was to setup URL handlers.

First off, setting up some dependencies.

1
2
3
4
5
6
dependencies:
  google_plus_v1_api: any
  browser: any
  fukiya: '>=0.0.11'
  html5lib: ">=0.4.1 <0.4.2"
  logging: ">=0.4.3+5"

A quick outline of what URLs fukiya handles. Dead simple to setup!

1
2
3
4
5
6
7
8
9
10
11
12
void main() {
  new Fukiya()
  ..get('/', getIndexHandler)
  ..get('/index.html', getIndexHandler)
  ..get('/index', getIndexHandler)
  ..post('/connect', postConnectDataHandler)
  ..get('/people', getPeopleHandler)
  ..post('/disconnect', postDisconnectHandler)
  ..staticFiles('./web')
  ..use(new FukiyaJsonParser())
  ..listen('127.0.0.1', 3333);
}

The index handler is special cause we needed to inject a state token into the page and HTTP session. The state token is then verified on the /connect post. The one-time token helps avoid any Confused_deputy_problems.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void getIndexHandler(FukiyaContext context) {
  // Create a state token. 
  context.request.session["state_token"] = _createStateToken();

  // Readin the index file and add state token into the meta element. 
  var file = new File(INDEX_HTML);
  file.exists().then((bool exists) {
    if (exists) {
      file.readAsString().then((String indexDocument) {
        Document doc = new Document.html(indexDocument);
        Element metaState = new Element.html('<meta name="state_token" content="${context.request.session["state_token"]}">');
        doc.head.children.add(metaState);
        context.response.writeBytes(doc.outerHtml.codeUnits);
        context.response.done.catchError((e) => serverLogger.fine("File Response error: ${e}"));
        context.response.close();
      }, onError: (error) => serverLogger.fine("error = $error"));
    } else {
      context.response.statusCode = 404;
      context.response.close();
    }
  });
}

On the /connect post we will expect a gplus id to be passed to the query parameters and some token data posted. We can then verify the state token and use the token data for accessing the Google APIs.

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
void postConnectDataHandler(FukiyaContext context) {
  serverLogger.fine("postConnectDataHandler");
  String tokenData = context.request.session.containsKey("access_token") ? context.request.session["access_token"] : null; // TODO: handle missing token
  String stateToken = context.request.session.containsKey("state_token") ? context.request.session["state_token"] : null;
  String queryStateToken = context.request.queryParameters.containsKey("state_token") ? context.request.queryParameters["state_token"] : null;

  // Check if the token already exists for this session. 
  if (tokenData != null) {
    context.send("Current user is already connected.");
    return;
  }

  // Check if any of the needed token values are null or mismatched.
  if (stateToken == null || queryStateToken == null || stateToken != queryStateToken) {
    context.response.statusCode = 401;
    context.send("Invalid state parameter.");
    return;
  }

  // Normally the state would be a one-time use token, however in our
  // simple case, we want a user to be able to connect and disconnect
  // without reloading the page.  Thus, for demonstration, we don't
  // implement this best practice.
  context.request.session.remove("state_token");

  String gPlusId = context.request.queryParameters["gplus_id"];
  StringBuffer sb = new StringBuffer();
  // Read data from request.
  context.request
  .transform(new StringDecoder())
  .listen((data) => sb.write(data), onDone: () {
    serverLogger.fine("context.request.listen.onDone = ${sb.toString()}");
    Map requestData = JSON.parse(sb.toString());

    Map fields = {
              "grant_type": "authorization_code",
              "code": requestData["code"],
              // http://www.riskcompletefailure.com/2013/03/postmessage-oauth-20.html
              "redirect_uri": "postmessage",
              "client_id": CLIENT_ID,
              "client_secret": CLIENT_SECRET
    };

    http.Client _httpClient = new http.Client();
    _httpClient.post(TOKEN_ENDPOINT, fields: fields).then((http.Response response) {
      // At this point we have the token and refresh token.
      var credentials = JSON.parse(response.body);
      _httpClient.close();

      var verifyTokenUrl = '${TOKENINFO_URL}?access_token=${credentials["access_token"]}';
      new http.Client()
      ..get(verifyTokenUrl).then((http.Response response)  {
        serverLogger.fine("response = ${response.body}");

        var verifyResponse = JSON.parse(response.body);
        String userId = verifyResponse.containsKey("user_id") ? verifyResponse["user_id"] : null;
        String accessToken = credentials.containsKey("access_token") ? credentials["access_token"] : null;
        if (userId != null && userId == gPlusId && accessToken != null) {
          context.request.session["access_token"] = accessToken;
          context.send("POST OK");
        } else {
          context.response.statusCode = 401;
          context.send("POST FAILED ${userId} != ${gPlusId}");
        }
      });
    });
  });
}

Now the HTTP session has the full ability to make calls on behalf of the user. The /people method will be called from the client to retrieve the list of visible friends of that user.

1
2
3
4
5
6
7
8
9
10
void getPeopleHandler(FukiyaContext context) {
  String accessToken = context.request.session.containsKey("access_token") ? context.request.session["access_token"] : null;
  SimpleOAuth2 simpleOAuth2 = new SimpleOAuth2()..credentials = new console_auth.Credentials(accessToken);
  plus.Plus plusclient = new plus.Plus(simpleOAuth2);
  plusclient.makeAuthRequests = true;
  plusclient.people.list("me", "visible").then((plus.PeopleFeed people) {
    serverLogger.fine("/people = $people");
    context.send(people.toString());
  });
}

The final responsibility we can bestow upon the server is allowing the client to disconnect by revoking OAuth access.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void postDisconnectHandler(FukiyaContext context) {
  String tokenData = context.request.session.containsKey("access_token") ? context.request.session["access_token"] : null;
  if (tokenData == null) {
    context.response.statusCode = 401;
    context.send("Current user not connected.");
    return;
  }

  final String revokeTokenUrl = "${TOKEN_REVOKE_ENDPOINT}?token=${tokenData}";
  context.request.session.remove("access_token");

  new http.Client()..get(revokeTokenUrl).then((http.Response response) {
    context.request.session["state_token"] = _createStateToken();
    Map data = {
                "state_token": context.request.session["state_token"],
                "message" : "Successfully disconnected."
                };
    context.send(JSON.stringify(data));
  });
}

Thats about it, Happy Dart Hacking! Special thanks to Gerwin Sturm for putting together the original example for client side. Full source code can be found at gplus-quickstart-dart in the server folder. Please replace your own keys cause mine will be removed at some point.

April 03, 2013 02:25 AM

March 22, 2013

Adam Coding @ Github

Dart Multi Touch Canvas With Realtime APIs

Google has made the realtime api available for developers. Realtime api provides operational transformation on strings, lists, maps and custom objects. The application data gets stored on Google Drive and is available from any supported browser. This is going to be the tooling of the future for collaborative applications.

I took some time to see what it would take for implementing a sample realtime application in dart. Also wanted to make sure my sample could run on mobile chrome.

Since realtime api is new, dart bindings don’t really exist. Lucky for us we have js-interop library. The js-interop library provides communications to existing javascript code from dart. I consider this mostly a quick hack to get started with the realtime api until a more native interface exists.

The sample realtime_touch_canvas demonstrates a multi touch canvas surface that updates in realtime with all clients that have the application open.

Most of the heavy lifting is done by rtclient.dart. I ported the code from the javascript version. Its enough code to get started right away but a more structured solution should be done. The main class is RealTimeLoader used for realtime loading.

1
2
3
4
5
  rtl = new RealTimeLoader(clientId: 'CLIENTID.apps.googleusercontent.com', apiKey: 'KEY');
  rtl.start().then((bool isComplete) {
    /* RealTimeLoader has authenticated the application and is ready to load a file */
    loadRealTimeFile(fileId, model.onFileLoaded, model.initializeModel);
  });

model.onFileLoaded and model.initializeModel handle the creating of model data and loading of model data.

In the realtime_touch_canvas, model data was a simple list of json strings. The ticky part here is you need to remember that your working with the realtime api within the javascript vm. So an array needs to be allocated from js-interop.

1
2
3
4
  void _createNewModel(js.Proxy model) {
    var list = model.createList(js.array(_defaultLines));
    model.getRoot().set(_linesName, list);
  }

After the model is created we then get called to load the file. Loading the file for our purposes is binding the collaborative objects. Some tricky things to note here is we are retaining the javascript objects so we can access them after exit of the callback. Also the callbacks have to be wrapped within js-interop js.Callback.many proxy object. The callbacks _linesOnAddValuesChangedEvent and _linesOnRemovedValuesChangedEvent are fired off when the collaborative list object has items added or removed.

1
2
3
4
5
6
7
8
9
10
11
12
  js.Proxy _doc;
  String _linesName = "lines";
  js.Proxy _lines;

  void _bindModel(js.Proxy doc) {
    _doc = doc;
    js.retain(_doc);
    _lines = doc.getModel().getRoot().get(_linesName);
    _lines.addEventListener(gapi.drive.realtime.EventType.VALUES_ADDED, new js.Callback.many(_linesOnAddValuesChangedEvent));
    _lines.addEventListener(gapi.drive.realtime.EventType.VALUES_REMOVED, new js.Callback.many(_linesOnRemovedValuesChangedEvent));
    js.retain(_lines);
  }

When the callback is called the data would be in the javascript virtual machine so we can parse it and store in our native dart code. This is more of a convenience then a must do, that way we can expose plan old dart objects to our other parts of the dart application.

1
2
3
4
5
  void _linesOnAddValuesChangedEvent(addedValue) {
    var insertedLine = _lines.get(addedValue.index);
    var line = new Line.fromJson(insertedLine);
    realtimeTouchCanvas.move(line, line.moveX, line.moveY);
  }

Now when we want to store a line in the application we simply convert it to json and push it into the collaborative list. The little tick here is to make sure we are scoped when accessing the _lines object since it lives in the javascript virtual machine.

1
2
3
4
5
  void addLine(Line line) {
    js.scoped(() {
      _lines.push(line.toJson());
    });
  }

The realtime_touch_canvas is live on github gh-pages and realtime_touch_canvas source is available.

March 22, 2013 01:19 AM

Future Perfect

Undone, Not a Song About Sweaters

“If you want to destroy my sweater”… Yup, that was a great song.
But this post is about other greatness: the command pattern. More specifically, its application to undo and redo.

I’ve implemented undo and redo a few times. The idea is pretty simple to grasp, but there are some subtleties that can lead to problematic implementations.
When I started to think about it again in Dart, I decided to develop the functionality in a standalone Pub package from the start so that I could share my experience and get collaborators to help me improve upon it.

Why Asynchronous?

Most of the implementations of undo and redo that I have seen have been purely synchronous. Undone deviates from that norm. User interfaces need to remain responsive, which means expensive work needs to be offloaded from the ui thread.
In Dart there can be only one… thread per isolate. This is true in any Dart environment, not just the browser. Undone is written to use the facilities provided in the platform-agnostic dart:async library.

Authors of synchronous undo would likely argue that ui actions should be very fast and that there is no need to perform them asynchronously. I agree wholeheartedly with that principle, but my experience has been that you will inevitably encounter an expensive operation that you need to wrap in an undoable action. Also, if you start to consider using your undo system for something other than ui actions, you will very likely encounter things that are asynchronous in nature. We are, after all, in the browser here!

Okay, so we may need to do some actions asynchronously, what are the ramifications? The thing about async code is that as soon as one thing is async, it tends to have a ripple effect on everything around it. This holds true for undo. Let’s look closer at how undone works to understand.

One of the core concepts in undo and redo is that of a history list, also known as an undo stack, etc… This is a data structure that keeps track of your undoable actions and the order in which they are done. In a sychronous world, the code to manage such a data structure can be quite minimal. When things go async, it is another beast. Undone is designed around the notion of a schedule.

The goal of the schedule is to minimize the impact of the async world on the user of the undo library. Just like how the word ‘schedule’ is both a noun and a verb, the Schedule type is both a class and a function. As a class, it is the type that contains the history of actions and as a function, it can be called to do an action.

Undone provides a top-level schedule getter. Actions are also functions, and if you call an action it will call itself on the top-level schedule. That probably sounds complicated to you now, but the end result is that it makes your life easy. Let’s look at some fictional example code:

...
incrementAsync();
square();
...

Above, we assume that we have two action instances named incrementAsync and square that perform calculations on a shared argument. Since they are functions, we can call them using () just like any Dart function. The first action incrementAsync will perform its work asynchronously, and the second action square will perform its work synchronously. Both calls are sent to the top-level schedule, and square will be queued internally while incrementAsync executes, and then executed after. In a synchronous implementation, square would likely be executed immediately when it is called, which is during the executon of incrementAsync. The result would be a corrupt history list, an incorrect calculation, and any number of other problems. The asynchronous schedule allows this to be a valid program, and abstracts away a lot of the pain.

If I’ve managed to convince you of why I’ve built in support for async actions, I hope that you may now appreciate how the schedule helps alleviate some of the pain. The schedule is implemented as a state machine; as a user of the schedule you should not need to care about that often. Actions can be scheduled at any time (during any state) and the schedule will take care of making sure things are done in the right order. Much of the API returns futures, and this allows you to chain continuations onto method calls. The schedule will make sure your continuations happen at all the right times. Let’s look again at our fictional example:

...
var arg = { 'value' : 42};
var incrementAsync = new Increment(arg);
var square = new Square(arg);
...
incrementAsync().then((result) => print('$result'));
square.then((result) => print('$result'));
...

We see now that incrementAsync and square are both action instances that we construct from custom action types. Both instances take the same argument, and let’s assume that they are both implemented to manipulate the argument’s ‘value’ in a manner their names suggest. When the above program is run, the printed output will be:

43
1849

Everything happens at the time you naturally expect. You may call new actions from within the continuations and the schedule will make sure to execute them in the order you call them.

The schedule will always report that it is busy in a continuation, or at any time when it is not idle. Although you may always call a new action on a schedule at any time, it is important to know that you may not call methods such as undo that modify the schedule if it is busy. In the above example, we cannot allow the continuation on incrementAsync to perform an undo, because we need to make sure that the square gets done first.

Binding to Undo and Redo

Most of the code in your program will only care about calling actions, and the schedule will make sure to execute them in the order you call them.

Invoking undo and redo is really an entirely separate path in your code. Typically, you will want to bind these methods to user gestures such as the keyboard input ctrl+z and ctrl+y:

// Bind undo / redo to keyboard events.
document.onKeyUp.listen((e) {    
  if (e.ctrlKey) {
    if (e.keyCode == KeyCode.Z)           undo();
    else if (e.keyCode == KeyCode.Y)      redo();
  }
});

The Schedule type also provides getters for canUndo and canRedo. If you are using a data-binding framework such as web-ui, you can use these directly in bindings to enable button controls, etc… If you don’t have data-binding, then this is one scenario when you may want to observe the states of a schedule, in order to refresh your controls:

// Listen to state changes in the schedule to refresh the ui.
schedule.states.listen((state) {
  if (state == Schedule.STATE_IDLE) {
    undoButton.disabled = !schedule.canUndo;
    redoButton.disabled = !schedule.canRedo;
  }
});

Transactions made Simple

Another common scenario is to merge together more than one action into a Transaction. All of the actions in the transaction will be done and undone together as a single ‘atomic’ unit. This library provides an easy way to build transactions using the top-level transact method:

transact(() {
  cut();
  paste();
});

In the example above, the calls to the actions cut and paste occur within an anonymous closure. The transact function will invoke this closure, and all actions that are called within its scope are added to a new Transaction.
After the anonymous function returns, the Transaction will be called on the top-level schedule. Cut and paste is a real world example, as you normally want these actions to be executed together as one. If something goes awry during paste, you want to rollback to the initial state by undoing the cut.

Call me Back!

Undone is in the early stages. I’m trying to tailor it to dart, and to the real needs of modern ui applications. I would love to get feedback from others in the community and to get people using it and collaborating. Please drop me a note with your feedback!

by Ross Smith at March 22, 2013 12:00 AM

March 14, 2013

Shannon -jj Behrens

Irrduino: A Sprinkler System Built Using Arduino, Android, Google App Engine, Python, and Dart

Cross-posted from Dart News & Updates.



Developers frequently ask me if Dart is ready for the real world. Well, of course, that depends on the application. Check out this short video in which Joe Fernandez and I not only show that Dart can be used in the real world, we also show that it can be used to take the tedium out of watering your lawn!



The Dart code for Lawnville was originally written in January of 2012, a mere three months after Dart was launched as a "technology preview". That was six months before Dart's M1 release, so it's been updated a few times along the way. However, the code really hasn't fundamentally changed that much since the beginning.

Perhaps the most interesting piece of code is the use of a Queue (from the dart:collection library) to schedule watering tasks. You can click on different parts of the lawn, and the droid will fly over and water each section for a short amount of time:

_actionQueue = new Queue();
...
_actionQueue.add({'action': 'water', 'zone': el.id});
...
void _executeActionQueue() {
if (_actionQueue.isEmpty) {
_waitingForTimer = false;
_idle();
} else {
var action = _actionQueue.removeFirst();
_doAction(action);
_waitingForTimer = true;
new Timer(new Duration(milliseconds: TIMER_INTERVAL),
_executeActionQueue);
}
}
A Timer and window.requestAnimationFrame are used to control animations:

void _repositionDroid(int x, int y, [Callback callback = null]) {
x -= (HALF * DROID_WIDTH).toInt();
y -= DROID_HEIGHT;
_droid.src = "/static/images/droid-jetpack-on-front.png";
_droid.style.left = "${x}px";
_droid.style.top = "${y}px";
new Timer(new Duration(milliseconds: REPOSITION_DURATION), () {
if (callback != null) {
callback();
} else {
_droid.src = "/static/images/droid-waiting-front.png";
}
});
}

void _startAnimationLoop() {
_animationStartTime = new DateTime.now().millisecondsSinceEpoch;
window.requestAnimationFrame(_animationLoop);
}

void _animationLoop(int timestamp) {
_animationProgress = timestamp - _animationStartTime;
for (Callback callback in _animationCallbacks.values) {
callback();
}
window.requestAnimationFrame(_animationLoop);
}
An HttpRequest is used to send commands to IrrduinoServer which in turn sends commands to IrrduinoController in order to control the sprinkler system:

void _waterRpc(int zone) {
var req = new HttpRequest();
int secs = (TIMER_INTERVAL * SECS_PER_MS).toInt();
req.open("POST", "/?water-zone=true&zone=${zone}&secs=${secs}", true);
req.onReadyStateChange.listen((Event e) {
if (req.readyState == 4) {
if (req.status == 200) {
window.console.log("Watering was successful");
} else {
window.console.log("Watering was unsuccessful");
}
}
});
req.send();
}
In total, the complete Dart code is about 110 lines long, not counting comments and closing braces.

You might wonder why I chose to use Dart so soon after its release, especially since I wasn't even on the Dart team at the time. I've always gotten a kick out of coding in new languages. At the time, I figured that as long as I could talk to the DOM and make XMLHttpRequests, I could do almost anything. These days, Dart is a lot more useful thanks to the growing selection of pub packages available, but even before these things existed, Dart had enough functionality to help water a lawn ;)

If you want to download the complete source code for Irrduino, you can get it from bit.ly/waterjoeslawn.

by Shannon Behrens (noreply@blogger.com) at March 14, 2013 06:08 PM

March 09, 2013

Adam Coding @ Github

rikulo stream on heroku

Tonights hacking was with stream and heroku. Stream is a Dart web server supporting request routing, filtering, template technology, file-based static resources and MVC design pattern. I just planned on serving static content from heroku using full dart based web server.

First setup the dart build pack

shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
adam@Adams-MacBook-Air:~/dart
$ mkdir stream_todomvc

adam@Adams-MacBook-Air:~/dart/stream_todomvc
$ cd stream_todomvc

adam@Adams-MacBook-Air:~/dart/stream_todomvc
$ heroku create stream-todomvc

adam@Adams-MacBook-Air:~/dart/stream_todomvc
$ heroku config:add BUILDPACK_URL=https://github.com/igrigorik/heroku-buildpack-dart.git

adam@Adams-MacBook-Air:~/dart/stream_todomvc
$ git init

adam@Adams-MacBook-Air:~/dart/stream_todomvc
$ git remote add heroku git@heroku.com:stream-todomvc.git

Creating a new project called stream-todomvc. Going to use the todomvc from the web-ui project as our content for the stream server. First thing that should be done is adding the dependencies to the pubspec.yaml file.

pubspec.yaml
1
2
3
4
5
6
7
name: stream_todomvc
description: A sample WebUI application
dependencies:
  browser: any
  js: any
  web_ui: 0.4.1+7
  stream: 0.5.5+1

Next I simply compied the existing todomvc project out into my stream-todomvc project.

shell
1
2
adam@Adams-MacBook-Air:~/dart/stream_todomvc
$ cp ~/dart/web-ui/example/todomvc/* ./web/

stream intro documentation goes over some basic configurations and settings. I’m just going to use them for now to get something running right away. The key to note when serving code from the web/ folder in dart projects is having the stream server code in web/webapp/. That way stream can find all your resources with little configuration. With very little dart code we can have static web server going.

web/webapp/server.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
library server;

import 'dart:io';
import "package:stream/stream.dart";

void main() {
  var port = Platform.environment.containsKey('PORT') ? int.parse(Platform.environment['PORT']) : 8080;
  var host = '0.0.0.0';
  var streamServer = new StreamServer();
  streamServer
  ..port = port
  ..host = host
  ..start();
}

Since this was a web-ui project we need to have a build.dart file help us with transforming the polyfill web components.

build.dart
1
2
3
4
import 'dart:io';
import 'package:web_ui/component_build.dart';

main() => build(new Options().arguments, ['web/index.html']);

The heroku environment requires a procfile configuration to let the service know the type of commands to run.

Procfile
1
web: ./dart-sdk/bin/dart --package-root=./packages/ web/webapp/server.dart

Next we build all the static data for our webapp to function. This will include calling build.dart and dart2js. The second step of calling dart2js helps with clients that do not have the dartvm built in.

shell
1
2
3
4
5
6
7
8
9
10
11
12
13
adam@Adams-MacBook-Air:~/dart/stream_todomvc
$ pub install
Resolving dependencies...
Dependencies installed!

adam@Adams-MacBook-Air:~/dart/stream_todomvc
$ dart build.dart
Total time spent on web/index.html                           -- 839 ms
Total time                                                   -- 863 ms

adam@Adams-MacBook-Air:~/dart/stream_todomvc
$ dart2js -oweb/out/index.html_bootstrap.dart.js web/out/index.html_bootstrap.dart
Using snapshot /Users/adam/Documents/DartEditor/dart/dart-sdk/lib/_internal/compiler/implementation/dart2js.dart.snapshot

Now everything should be ready for deployment.

shell
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
adam@Adams-MacBook-Air:~/dart/stream_todomvc
$ git add -a -m "ready for deploy"

adam@Adams-MacBook-Air:~/dart/stream_todomvc
$ git push -v --set-upstream heroku master:master
Pushing to git@heroku.com:stream-todomvc.git
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 283 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)

-----> Fetching custom git buildpack... done
-----> Dart app detected
-----> Installing Dart VM, build: latest
-----> Copy Dart binaries to app root
-----> Install packages
*** Found pubspec.yaml in .
Resolving dependencies...
Dependencies installed!
Fixed web symlink
-----> Discovering process types
       Procfile declares types -> web

-----> Compiled slug size: 8.9MB
-----> Launching... done, v7
       http://stream-todomvc.herokuapp.com deployed to Heroku

To git@heroku.com:stream-todomvc.git
   042f1f4..b35984b  master -> master
updating local tracking ref 'refs/remotes/heroku/master'

Deploying to heroku in this style is just a good starting point. web-ui and dart in general is still working on a deployment story. The URL for the stream-todomvc will contain out in its location, not very desirable. In the future a buildtool will aid the deployment story for dart.

Check out the live version of stream-todomvc with full source code available at the stream-todomvc github project.

March 09, 2013 03:16 PM

March 08, 2013

Future Perfect

We Built This Site On Drone.io

I have been using drone.io since I encountered it as a Dartisan and I must say I have been nothing but pleased with it. It has risen up as the solution for continuous integration in the Dart community. As I was working on improving this site, I discovered another way in which drone.io can bring me joy.

Like many others these days, I host this site with Github Pages and use Jekyll to statically generate the content. You can read more about that here, but in this post I’m going to assume you are already familiar with the basics of this setup.

A common issue that developers face with this setup, is that Github Pages runs Jeykll with the following options:

$ jekyll --pygments --no-lsi --safe

It is that last option above, --safe, which can cause a lot of heartache. It makes sense for Github, as allowing plugins to execute on their servers exposes an obvious security loophole. However, as a hacker with good intentions who wants all the joy of executing plugins such as sass conversion, this may cause you sadness. I spent some time researching what others were doing to circumvent this, and I found the following solutions:

  1. Simply perform plugin tasks offline and submit the processed files to Github Pages.
  2. Create a source branch in your repo where you submit your source content (the input to Jekyll) and then push the processed files to master for publishing; use a .nojekyll file on master to prevent Github Pages from re-running Jekyll.

Option #1 is pretty simple and self-explanatory. If you don’t publish very often or you don’t mind the manual curation required, it isn’t such a bad option. It seems that many people are doing it this way.

Option #2 was more intruiging to me; I like the clean separation of input files and output files on the two branches. I found that people are using a variety of different solutions to get the input from their source branch to the output on their master branch. Mostly, it seems they are doing this ‘offline’ with different shell scripts, batch files, commit hooks, etc… I was looking for something similar, but I wanted an automated process that would consume my source content, run Jekyll unshackled, and then produce my master content. That is when I thought of drone.io.

I checked and saw that drone.io supports ruby and knew that it might just work. Drone supports a Repository -> Branch Filter setting, so I setup my source branch to be the default branch for my repo in Github and then I also added source to the Branch Filter in my drone.io settings. This means that drone will only monitor commits to my source branch to trigger builds, which is what I want. Drone will automatically do a git checkout on the source branch based on these settings, so my build commands start from that point:

sudo easy_install Pygments
bundle install
bundle exec jekyll
git checkout master
cd _site/
cp -r . ..
cd ../
git add -A
git commit -m"auto commit from drone"
git remote set-url origin git@github.com:rmsmith/rmsmith.github.com.git
git push origin master  

First, we make sure that Pygments is installed. Jekyll uses Pygments, which is installed as a Python egg, for syntax highlighting. If you don’t need that, you can skip that command. Next we run bundle install, which is going to install all of the Ruby Gems in your Gemfile. This is important, you’ll need to have a Gemfile in your source branch of your repo that contains Jekyll at a minimum:

source :rubygems

gem "jekyll", "~> 0.11.2" # we need at least this version so jekyll will use Ruby 1.9.2
gem "sass", "~> 3.2.6"

You’ll notice that my Gemfile also includes ‘sass’, since the sass to css converter plugin is my motivation for this entire exercise.

After running Jekyll, we see the shell commands to copy the contents of the _site/ directory to the top-level directory of the master branch. The _site/ directory is in my .gitignore file so that is never pushed to either branch. This means that it will only exist locally on the build server as the output of running Jekyll. We then use git commands to add and commit the output files on the master branch. Before we can push the commit back to origin, we need to make sure that SSH is setup.

To allow drone.io to push back to your Github repo, you’ll need to set up SSH. In drone, you can find the SSH key under Repository -> View Key. Then, in Github go to your Account Settings -> SSH Keys and add this as a new key. This can only be configured in Github at the granularity of your entire user / organization account, so be aware that this gives drone.io push access to all of your repositories.

With SSH keys configured, the last two commands do the git magic to push the commits from drone.io on the master branch back up to the origin Github repository.

Now you can add the drone.io badge to your site’s README file like I did, and be filled with joy as you work exclusively on your source branch with your source content.

by Ross Smith at March 08, 2013 12:00 AM

February 28, 2013

Shannon -jj Behrens

Dart on a Chromebook: Success!

I finally have a viable approach to editing Dart directly on a Chromebook running ChromeOS! The usual approach to developing Dart code on a Chromebook is to use Chrome Remote Desktop to connect to another development machine. However, I wanted an approach that would let me develop in Dart while offline, for instance if I'm giving a talk on Dart and my internet connection goes down.

Crouton is a set of scripts based around debootstrap that bundle up into an easy-to-use, Chromium OS-centric Ubuntu chroot generator. Using Crouton, I was able to create a chroot running a basic Ubuntu setup. Within the chroot, I was able to install a JDK and then Dart Editor. Everything works, as you can see in the picture. I can switch back and forth between XFCE and ChromeOS's desktop using a key combination, and everything still runs at native speed since it's just a simple chroot.

I got everything working on my wife's Samsung Series 5 Chromebook running an Intel Atom processor. I have a newer ARM-based Chromebook, but there is currently no ARM port of the Dart VM. I used the 32-bit version of the JDK and the 32-bit version of Dart Editor.

I'm pretty excited that this works because this is one of the few things that was preventing me from fully switching to a Chromebook :) Now, all I need to do is get my hands on a Chromebook Pixel!

by Shannon Behrens (noreply@blogger.com) at February 28, 2013 06:57 AM

February 25, 2013

Trials (and Errors) in Dart

New Dart:io hotness!

It's been a very long time since my last post for which I apologize. I hope to get back into Dart blogging again soon. A recent announcement on the dartlang mailing list got me excited. BREAKING CHANGE: New version of dart:io. I've been waiting for this to finally land in bleeding_edge. As a lot of my work is with command line applications. It's great seeing dart:io finally getting some love.

Now there were a few surprises that cropped up with the new version of the library. I'm going to note a couple of them I've come across so far that I've noticed. I won't get into details about ones covered in the mailing list announcement. There are a number of others that were too small to be covered there. One big thing I noticed was the removal of HttpServer.addRequestHandler as that was a quick and dirty way of setting up the basics of routing in the server. Now all requests are sent to HttpServer.listen. Similarly, server isn't started by creating a new HttpServer instance and then running listen on it, rather use a static method, HttpServer.bind on the HttpServer class which returns a Future which provides the server instance.

All of this is because the dart:io is being converted to Futures and Streams. And it is a change for the best, making the libraries consistent across libraries and API's. This has also made for some changes to some of the other classes in dart:io and just some clean up which makes sense as well.

Lets start with our eventHandler. In the past adding a RequestHandler to the HttpServer would take two arguments. An HttpRequest and an HttpResponse. The first being the request to the server and the latter being the response back from the server to the client. However, I cannot think of a situation where these two objects would not be intertwined. Apparently the dart developers felt the same way. Now, the new version of a requestHandler (see above), only accepts an HttpRequest. The corresponding HttpResponse object is a property of the HttpRequest, and can be accessed like so: HttpResponse res = httpRequest.response;

Also in HttpRequest, the uri property is no longer a string but returns a URI object. As such, the path property of HttpRequest has been removed in favour of: httpRequest.uri.path. Similarly, session is no longer a method but rather returns a full session object directly. This means that it no longer accepts an init callback to preform a specialized initialization of the session but I'm not aware of that functionality being used very frequently.

[Edit:]
One aspect that I neglected to mention earlier is that writing to the HttpResponse stream is a little easier now as well. In the past we would need to use httpResponse.outputStream.write(...) whereas now, we write directly to the httpResponse itself. For example:

var res = httpRequest.response;
res.addString(...);
// Alternatively we can also use add(List data)
// or addStream(Stream> data).
Check out the API for HttpResponse.[/Edit]

As an experiment with the new library, in particular with the HttpServer and related functionality, I created a very basic webserver example. This sample is not production usable, or even complete in any way. But I think it does provide a good introduction into how the new libraries are used and how extend the Stream interfaces to implement a very basic routing mechanism into the server. The source is available on github: sample_server. This is the basic premise that I'm now implementing in a project that I'm working on at the moment. With any luck I'll be able to extend the functionality of the server and abstract it away from the core logic I'm working on to be able to release the library for others if they are interested. In the mean time the sample_server should help you to get up and running.

One thing I do have to mention, is it was extremely easy to implement my own stream with the route by extending Stream, and just using a StreamController to provide most of the functionality. Only needed to implement the listen() method which in itself passes it on to the controller anyways. Love it!

Note: Currently this requires a bleeding_edge version, as these changes have not yet been added to the stable build. They were written with version: 0.1.2_r18836 and tested with version: 0.1.2_r18968. Details may change prior to stable release.The latest stable version of the Dart SDK has just been released and supports this API. It can be found in version: 0.4.0_r18915.

by Matthew Butler (noreply@blogger.com) at February 25, 2013 03:09 PM

February 21, 2013

Christian Grobmeier

A free book. Dart: Up and Running

Recently I got the book “Dart: Up and Running” written by Kathy Walrath and Seth Ladd. Both authors are well-known in the Dart community. Kathy is responsible for so much great docs on dartlang.org and Seth was the Dart-Ambassador since the language first faced the world (or even earlier, who knows). Definitely you want to meet at least one of them in your favorite coffee shop when you are running into Dart related trouble.

dartupandrunning

The Book itself is one of the first of its kind. Currently I know about two more Books on Dart, but thats it. As the language still progresses and changes are flowing in every day, it is a difficult matter to write a books about Dart. Kathy and Seth decided to write a short but valuable book, tailored for the busy developer who wants to get an overview on the Dart eco system. With that in mind most of the content will be valid for quite a while.

Actually you can read everything you need to get started quickly. After a brief introduction of the “whats hot” kind you’ll be introduced into the Dart syntax. You’ll see a lot of the great language features Dart supports, like named Constructors or the Cascade Operator.
The second chapter is a tour through the current Dart libraries, like for working with Isolates, HTML manipulation or I/O. It is a brief read which shows you what you can do with it, but doesn’t exhaust all possibilities. Of course a chapter on the great Dart toolset is not missing. If you ever wondered why people are so excited on Dart, this one of the reasons: the Editor and Dependency Resolver (aka Pub) is already built-in. The chapter introduces all of them and points you into the right direction when you are just starting. Finally the book ends with an example chapter.

This book is one of the kind you need to have on your desk until you know it from mind. It is an easy to read, easy to understand book which helps you to get started quickly. Don’t expect Kathy & Seth will explain object oriented paradigmas to you: it is really focused on the language itself.

If you are curious and would like to read more on the book I have some good – no GREAT – news for you. The whole book can be read online and free of charge. Just head on to the “Dart: Up and running website” and start hacking today. I also would like to mention that the books text and all source code examples are available on GitHub. You see, there is no excuse anymore. ;-)

buyfromamazoncomKindle Version


buyfromamazonde
Kindle Version

by Christian Grobmeier at February 21, 2013 08:57 AM

February 19, 2013

Shannon -jj Behrens

Dart with Google Web Toolkit

Cross-posted from Dart News & Updates.

In this episode of Dartisans, I'm going to show you a variety of ways to use Dart with Google Web Toolkit. I know that there are a lot of GWT developers out there who would like to give Dart a shot, but they aren't sure how because they already have a large, successful app that's written in GWT. I'm going to show you ways to integrate Dart into your existing GWT application without having to rewrite it from scratch.

To do this, I've built a sample application that uses both GWT and Dart. I'll show you how to setup a development environment so that you can work with both technologies. Then, I'll show you a variety of ways in which you can get GWT and Dart to interoperate, such as:
  • Using GWT and Dart to manage different parts of the same page
  • Using Dart to retrieve JSON from a Java servlet
  • Using window.postMessage and JSNI to pass messages between GWT and Dart
  • Using JavaScript, JSNI, and Dart's js package for synchronous interoperability between GWT and Dart
  • Using CustomEvent objects and Elemental to pass messages between GWT and Dart
Rather than show you a one-size-fits-all solution, I decided to show you a bunch of approaches so that you could pick the right tool for the job. Each of them has stengths and weaknesses, and I'll cover those along the way as well.

Aside from watching the video, you can also download the source code or view the video transcript.



As always, we invite you to join the discussion on the Dart mailing list, and ask us questions on Stack Overflow. Your feedback is important. Thanks for checking out Dart!

by Shannon Behrens (noreply@blogger.com) at February 19, 2013 08:38 PM

February 12, 2013

On Dart (Dzenan Ridjanovic)

February 08, 2013

Adam Coding @ Github

Dart Google Client Apis Now Available On Pub

The dart-gde team now brings you not only a generator to create google client apis but also pub.dartlang.org hosted packages. Lot of thanks goes to Gerwin Sturm for all of his hard work over the last few weeks developing discovery_api_dart_client_generator and dart-google-oauth2-library.

We plan to keep the client libraries up to date with uploader.dart script. Still somewhat a manual process, future automation could happen when/if we have the ability to get notified about google api changes. For now we will push updates when appropriate. This will ensure that we can push the latest versions of the apis to pub and still have previous revisions available. Some of the more intricate parts of this script include auto version incrementing pubspec files and syncing to github, then pushing to pub.

Would you want to contribute to this project? Please feel free to ping us Adam Singer/Gerwin Sturm on g+, we’re definitely looking to refactor some parts and test others. Our main focus for this release was to get something out the door that is pleasantly usable.

Many hours of testing and development was done to have a simple and easy way to use the google client apis in dart! We hope you enjoy and look forward to seeing what you build. To get started with client api examples check out dart_api_client_examples. The github hosted source code can be found at dart-google-apis

Full list of available Google client apis on pub.dartlang.org

February 08, 2013 10:18 PM

February 06, 2013

Kevin Moore

Dart is a great language for shell programming, too


I asked Twitter nicely yesterday. The only response:


I don't dislike writing bash scripts. I hate it. I also hate the lack of portability, as pointed out by +Daniel Steigerwald:


Great idea, +Daniel Steigerwald, but why use NodeJS when I could use Dart?

If you fetch the latest version of the Dart Bag-of-Tricks, you'll notice a new binary bin/bench.

If you're running bash and dart is in your path you can execute this directly. Otherwise run it through dart: dart bin/bench.

If you add bot.dart/bin to your path you can do things like this:
There is also a paramater -r, --run_count    (defaults to "20")

Dart is more than just a good tool for web apps.

Happy hacking.

by Kevin Moore (noreply@blogger.com) at February 06, 2013 05:32 PM

February 01, 2013

Kevin Moore

Headless Browser Testing: Dart, DumpRenderTree, drone.io

When writing any software, even for the web, I try to do as much testing as possible outside the browser.

A lot of great testing can be done of algorithms, data models, and business logic without booting up Chrome.

Node.js enabled this with Javascript. Dart has had an out-of-browser--read console--story since day one.

But some things you must test in a browser.

The Dart Bag of Tricks (BOT) has had browser tests since the beginning. There are only a few tests that must be run in the browser, but I make sure to run all tests both on the console and in the browser if they can run both places.

Browser tests are great, but they don't fit well into a build workflow or a continuous integration tool.

For that you need a way to run and control a browser (or a browser-like thing) via the console and get results out. Enter DumpRenderTree.

DumpRenderTree - Chrome without the chrome

DumpRenderTree (DRT) is a great little tool hidden in the guts of WebKit.

By default, DRT prints out an obscure text format representing the hierarchy of elements on the provided page.

Here's the output for DumpRenderTree example/fract/fract_demo.html

Content-Type: text/plain
layer at (0,0) size 808x820
  RenderView at (0,0) size 800x600
layer at (0,0) size 800x820
  RenderBlock {HTML} at (0,0) size 800x820
    RenderBody {BODY} at (8,8) size 784x804
      RenderHTMLCanvas {CANVAS} at (0,0) size 800x800 [bgcolor=#808080]
      RenderText {#text} at (0,0) size 0x0
#EOF
#EOF

DRT is controlled mostly through Javascript in the test page by via window.testRunner.

Here's the script block that lives in test/harness_browser.html:

<script>
// only run if testRunner is defined -- we're in DRT
if (window.testRunner) {

// Don't dump the structure. Just the text of the output plus console output
testRunner.dumpAsText();

// Don't finish when layout is done. Instead, wait to be notified
testRunner.waitUntilDone();

// listen for messages from the test harness
window.addEventListener("message", receiveMessage, false);

// listen for unhandled exceptions
window.addEventListener('error', onError);
}

// if there is an unhandled exception, tell DRT we're done
function onError(event) {
testRunner.notifyDone();
}

// if the test harness sends a done message, tell DRT we're done
function receiveMessage(event) {
if(event.data == 'unittest-suite-done') {
testRunner.notifyDone();
}
}
</script>

And since everything is keyed off the existence of window.testRunner, none of this affects the behavior of tests running normally in a browser.

Here's the first few lines of output from DumpRenderTree test/harness_browser.html:

Content-Type: text/plain
PASS
All 109 tests passed
Collapse All
bot
 
(4/4)
bot - Enumerable
 
(19/19)
bot - Enumerable - group

Compare to the content running the tests in the browser:


Getting DumpRenderTree

DRT is part of Linux and Windows builds of the Dart Editor now (look in the chromium) directory. It will be part of builds for Mac soon.

If you want to get DRT that is compatible with the latest integration build of Dart - 0.3.2.0 (r17657) - grab this guy.

Just make sure the DumpRenderTree executable is on your path when running tests.

Bringing it all together

drone.io supports DumpRenderTree for Dart projects. Read about it here.

The trick is creating a script that returns an exit code of zero for success and not zero (1 is pretty standard) for failure.

Check out the script I created for BOT.

And let me know how it goes for you.

Happy hacking.

by Kevin Moore (noreply@blogger.com) at February 01, 2013 03:29 AM

January 25, 2013

Future Perfect

Webview

This is a story about Webview, my first published web component. I have been exploring the new Chrome Apps and I took an interesting in the <webview> element for embedding web content in Chrome applications. This custom element (which actually is a web component already!) interests me because I see a number of compelling use cases. The Chrome team themselves have put forth use cases such as the embedding of widgets (Google+, etc…) within applications. I’ll leave you and your imagination to consider the realm of possibilities!

Dart Exposure

My Webview package has one clear and simple objective: to expose this element and its API as a Dart type; a web component to be precise. Being a web component allows you to use this element just like you would use the native <webview> element in your html, only with a slight twist to the tag name:

<x-webview src="http://news.google.com/"></x-webview>

You can query the element from your Dart scripts to obtain an instance of the Webview type, and then listen to custom events and call methods to control the embedded content:

var webview = document.query('x-webview').xtag;
webview.reload();

Now, of course, you could do all of this in javascript with the <webview> element, so there is nothing spectacular going on here. What I’ve done is to simply enable this technology in Dart so that Dart developers can be filled with the joys of writing Chrome Apps with web ui, without everyone wrestling with the js interop themselves. Speaking of javascript, let’s consider more how this works.

Who Stripped my Element?

Okay, so you are probably thinking to yourself “Didn’t he say that <webview> is already a web component? Do I really need this extra layer?” Good question! I am hoping that someday this wrapper may not be necessary. It is within their reach for the Dart team to include a library within the Dart SDK to expose the Chrome Apps API, and some recent submits indicate that preliminary work on this may have already begun. But as of this writing, if you try this:

var webview = document.query('webview')

You will be given an instance of UnknownElement. Any events or methods that are unique to <webview> will not be available, and an attempt to invoke such a method will throw NoSuchMethodError.

Our only option for interacting with this element is therefore javascript. This presented me with my first chance to look closely at the js interop library, which is the Dart team’s official solution for this sort of thing. Overall, I think it is a nice solution. One hitch with using it for Chrome Apps is in regard to Content Security Policy (CSP). Namely, the js interop library will first check if it has been loaded into the global context, and if not then it will inject itself as inline script. It is this last part, the inline script injection, that violates CSP. The workaround is to include the js portion of the js interop library directly in your Chrome App <html>:

<script type="text/javascript" 
        src="packages/js/dart_interop.js"></script>

With the above script included in your document, you’ll be up and running.

So after getting to this point, I thought it was going to be a piece of cake to wrap the javascript API behind my <x-webview> component. My thought was that now I could simply query the <webview> child of my <x-webview> to obtain a js.Proxy in my Dart Webview class, and then forward method calls to the proxy:

    
class Webview extends WebComponent {
  js.Proxy _proxy;

  void inserted() {
    _proxy = js.retain(
        js.context.document.querySelector('webview'));
  }
     
  void back() => js.scoped(() => _proxy.back());    
  ...
}

The hiccup with the above comes from my initial assumptions about this call:

js.context.document.querySelector('webview')

A cursory reading of the documentation for the js interop library yields:

“Note, parameters and return values are intuitively passed by value for primitives and by reference for non-primitives. In the latter case, the references are automatically wrapped and unwrapped as proxies by the library.”

After reading the above, I was inclined to expect the method call to querySelector('webview') to return an instance of Proxy. However, if we print the object that is returned by the query we see that was a false assumption:

Instance of 'UnknownElement'

As it turns out, the js interop library is treating elements as primitives in regards to parameters and return values that cross the language boundary. This makes sense and is what we’d want in most cases, but it is not overly clear from the documentation. So, instead of a proxy to the <webview> element (which would allow us to use its API) we are presented with an object of type UnknownElement, which is more or less worthless to us for our use case.

Getting Dirty in Javascript

I’ll start this paragraph with a confession: I have never written any javascript before embarking on this project. So I apologize in advance if my usage of said language brings tears to the eyes of the js veterans out there! But I knew that to get this job done I was going to have to roll up my sleeves. My goal was to define a wrapper type in javascript for my <webview> element, so that I could get a proxy to the wrapper in my Dart code and use that to forward method calls to the element in the javascript.

I knew people had invented various patterns to define classes in javascript, and after reading this article and thinking a bit I went with their option 1.2, methods added to the prototype of a top-level function:

function Webview(e, url, onEvent) {  
  this.e = e;  
  this.e.addEventListener('exit', onEvent);
  ...
  this.e.src = url;
}

Webview.prototype.back = function() { this.e.back(); }
...

As we see above, my constructor function takes an element (the <webview>), an url to set the initial src of the webview, and an onEvent callback to forward all of the element’s custom events to. I then add all of the methods to the prototype of this function. Et voila, that’s pretty much all there is to it! With this code in place, we can construct a proxy in our Dart web component to interact with the <webview> element. We do this from the inserted() lifecycle method of our component:

void inserted() {
  _inject(() {
    js.scoped(() {
      _onEvent = new js.Callback.many(_dispatch);
      _webview = js.retain(new js.Proxy(js.context.Webview, 
          children[1], _src, _onEvent));
    });
    ...
  });
}

Above, children[1] is the <webview> that is a child of the <x-webview> (our Dart web component). We handle all of the proxied custom events in a private method called _dispatch, which basically just re-dispatches them as custom events on the <x-webview> element. The _inject(f) method above is where things get interesting.

Injecting the Script

As we just saw above, in the inserted() method of the web component we are passing an anonymous function to a method named _inject. Why are we doing this? Simply put, we need to ensure that the javascript we wrote in the last section gets injected in the document and evaluated before we can construct a proxy or make any calls to that javascript.

We could just force all users of <x-webview> to add the following to their application’s html:

<script type="text/javascript" 
        src="packages/webview/webview.js"></script>

That would work, and in fact I do want to support this use case. You’ll see that this is what I do in the Messaging example. But, I felt that I should try to encapsulate this implementation detail of the <x-webview> component.

My first instinct was to simply include the <script type="text/javascript"> element directly in the html template for my web component. However, this does not work because the contents of the element’s <template> is injected into the document using innerHtml and thus the script is not evaluated. Placing the <script> anywhere else in the <element> of the web component’s html results in its removal by the dwc compiler, so at this point I felt stuck and wrote a bug report.

The solution actually came to me after browsing some other issues in the web ui project and seeing how they were planning to reference the dart.js script from the new browser package. I realized I could simply inject such a <script> element into the document from the Dart code of my <x-webview> if necessary, and using the src="packages/webview/webview.js" means it should resolve correctly from any entry point that is using Pub, which is pretty much every Dart application these days.

Warning I do my work on Windows 7, 64-bit. I have seen others mention that perhaps symlinks (e.g. packages/) do not resolve in Chrome Apps developer mode on some platforms (linux, osx). I do not have any means to confirm or deny this, but I can say that they do work on Windows (with junctions).

The implementation of our _inject(then) method follows as:

// First we check if the javascript is already injected
...
// Webview.js is not yet injected, so append it to body.
var script = new ScriptElement();
script.type = "text/javascript";
script.src = "packages/webview/webview.js";
script.on.load.add((e) {
  // Script loaded, check support and continue.
  _supported = js.scoped(() => 
  js.context.isWebviewSupported());
  then();
});    
document.body.append(script);

Notice that we first check if the javascript is already injected. This covers two different cases:

1) The user instantiates more than one instance of <x-webview>; We only need a single javascript for n instances of our component.

2) The user explicitly adds the <script> to their html <body>; This is a valid use case, especially if the user wants to ensure the script is available immediately. As we see above in the implementation of _inject, appending the <script> to the <body> is an asynchronous operation and the continuation then() is not invoked until the script finishes loading. So the API of the <x-webview> may not be available until some time after the web component is inserted in the document, unless the user takes this measure.

No more magic, the rest of the component’s implementation should be straightforward to follow.

A Pattern to Follow or Bugs to File?

I hope that this article has provoked some thought in both the reader and the writer about whether or not all of this was a good idea. I’m not sure I would like to promote any of the workarounds in this article as generally good patterns to follow, but this may help if you are in a pinch to add some javascript behavior to a Dart web component. I think some of this may translate into issue tracker reports, but i’m not sure what plans the Dart team might have up their sleeves regarding Chrome Apps; it is possible this exercise might only be a short term solution. The use case of attaching some javascript behavior to a Dart web component may or may not be useful in other contexts. I believe many other cases are solveable directly with the js interop library.

I’d love to get feedback from others who have faced or solved similar problems. Enjoy all the goodness of Dart, Chrome Apps, and web ui!

by Ross Smith at January 25, 2013 12:00 AM

January 22, 2013

On Dart (Dzenan Ridjanovic)

Membership Web Components

I have created a simple membership application to explore web components in the Web UI package of Dart.

by Dzenan Ridjanovic at January 22, 2013 10:55 PM

January 11, 2013

Kevin Moore

Dart Widgets Dev Journal 1 - Basic Animations


tl;dr: Implementing features similar to Bootstrap is hard without basic animation support in Dart. Basic animation support is not as easy as you'd think. I've made a stab. Check out the demo.
I've started a new Dart project - Dart Widgets. The inspiration is Bootstrap, but with a focus on features that map cleanly to Web Components.

While digging into Bootstrap, I realized that there was a heavy dependency on jQuery--specifically the show/hide/toggle functionality. This is critical for expanders, menus, modals, pretty much everything.

Show, hide, toggle

It turns out implementing show/hide/toggle is not as easy as one might guess.

One could naively toggle display: none; in an element's style attribute and call it a day, but a lot of edge cases would be missed.

Throw in the ability to optionally animate the show/hide behavior and things get a lot more complicated.

A short list of the cases to ponder:

  • Element with a non-standard display value. (e.g. a div inherited a display of inline-block)
  • Element with a local display of none 
  • Element inherited a display of none
  • Show is called while an element is hiding and vice versa
  • Toggle is called 10 times before the first animation finishes
  • Show is called on an element with effect A while effect B is hiding it.
Huge props to the jQuery and jQuery-ui folks for tackling this problem. Their code served a great starting spot. I feel bad that they had to implement this logic in Javascript.

Test

I can't tell you how valuable test-driven development was in getting this project off the ground. It would have been next to impossible to ensure all of the edge cases were handled cleanly.

I need to write another post about how my approach to testing in Dart has evolved. Let's just say I didn't code up 939 tests by hand.
After a lot of head scratching, I think I ended up with pretty clean, extensible model.

As proof, I offer the code for doing a open/close door effect:

class DoorEffect extends Css3TransitionEffect {
DoorEffect() : super(
'-webkit-transform',
'perspective(1000px) rotateY(90deg)',
'perspective(1000px) rotateY(0deg)',
{'-webkit-transform-origin': '0% 50%'}
);
}

There are still a few things I'd like to get working--get tests working in Firefox, find a way to handle browser prefixes cleanly--but generally I'm happy with progress.

Check out the demo.

Check out the code.

Let me know what you think.

by Kevin Moore (noreply@blogger.com) at January 11, 2013 05:50 PM

January 01, 2013

Shailen Tuli

A first app with web components using Dart and Web UI library

Its time to finally create a simple hello world app using web components and the dart Web UI library.

There is already a ton of literature out there on why web components are a tremendously good idea and I won’t try to do a huge ‘sell’ here. If you are completely new to web components, I can recommend this really good introductory blog post by Seth Ladd

Or, if you are impatient, here’s an (almost) tweet sized summary: web components allow developers to encapsulate their UI elements as easily reusable components. You can define templates with markup that is inert until activated later, apply decorators to enhance the look of those templates, create custom elements and play with the shadow DOM. In this little app, we will not be tikering with decorators or the shadow DOM; we will be creating templates and defining our own custom element.

The app is called bookstore and you can find the code at https://github.com/shailen/bookstore.

Since I am new to web components and the Dart Web UI library, I am going to keep this simple. In its current iteration, the app will show the user the list of books in the bookstore and let the user add books to the collection. The plan is to start with something minimal and over the next few weeks and months build something a little bit elaborate (add Authors, Publishers, more attributes to our Book class, reviews, etc) while preserving the one-page feel of the app.

Important Files

There are a few important files in bookstore’s web directory that are worth discussing now:

lib/models.dart contains code for a Book class

web/books.html contains the basic markup for the app

web/books.dart contains the Dart code that goes with that markup

web/book_component.html contains the markup for our web component

web/book_component.dart contains the Dart code for our web component

build.dart helps use compile our code so that it can be run

We’ll discuss each of these files in detail soon.

lib/models.dart

We’re going to be creating books. This file defines a simple Book class. Our books only have 1 attribute for now, a title (I told you this was simple ;).

library models;

class Book {
  String title;
  Book(this.title);
}

web/books.html

Here is the entirety of teh web/books.html file. Consider this an entry point into the app:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Books</title>
    <link rel="components" href="book_component.html">
  </head>
  <body>
    <h1>Books</h1>

    <input id="new-book" type="text" placeholder="add another title">
    <button on-click="createNewBook()">Add Book</button>

    <ul id="books">
      <template iterate="book in books">
        <x-book-item book="{{ book }}"></x-book-item>
      </template>
    </ul>

    <!-- this is the non web-component way to create the <li>s
    <ul>
      <template iterate='book in books'>
        <li>{{ book.title }}</li>
      </template>
    </ul>
    -->

    <script type="application/dart" src="books.dart"></script>
    <script type="text/javascript" src="https://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/dart.js"></script>

  </body>
</html>

A few things to notice here:

<link rel="components" href="book_component.html">

is the way you access the contents of our web component from this file.

We create an input where the user enters the name of a book and an accompanying button:

<input id="new-book" type="text" placeholder="add another title">
<button on-click="createNewBook()">Add Book</button>

Notice the on-click? That is the way we inline an event listener: when the button is clicked, createNewBook() fires (we’ll get to that function soon)

And finally the code that actually deals with the web component:

<ul id="books">
  <template iterate="book in books">
    <x-book-item book="{{ book }}"></x-book-item>
  </template>
</ul>

A few things to note here. We define a <template> tag; we loop over our collection of books (stored in a variable books in web/books.dart); we instantiate our web component (<x-book-item></x-book-item>) and we pass each book in the loop as a template variable when we instantiate the web component.

There’s a lot going on here. Make sure you understand the above paragraph!

web/books.dart

web/books.html has a link to a Dart file at the bottom:

<script type="application/dart" src="books.dart"></script>

And here is what books.dart looks like:

import 'dart:html';
import 'package:bookstore/models.dart';

List<Book> books = [];

// binding created auto-magically!
void createNewBook() {
  var input = query("#new-book");
  books.add(new Book(input.value));
  input.value = "";
}

main() {
  // create some data so the page doesn't look empty
  ["War and Peace", "The Idiot", "Crime and Punishment"].forEach((title) {
    books.add(new Book(title));
  });
} 

It is pretty straightforward stuff: we import models.dart, the file that contains the Book class; we create a books variable to store our collection. We define createNewBook() to add a book to books, and we define a main() function.

This Dart file MUST contain a main(), even an empty one will do. In our case, we will add a few books to our books collection, so that there is some data to display.

web/book_component.html

This contains the code that defines our web component:

<!DOCTYPE html>
<html>
  <body>
    <element name="x-book-item" constructor="BookComponent" extends="li">
      <template> 
        <li>{{ book.title }}</li>
      </template>

      <script type="application/dart" src="book_component.dart"></script>
    </element>
  </body>
</html>

A few things to understand here: we create a custom <element>; we give it a name, x-book-item (all element names must begin with an x-); we call a constructor, BookComponent (defined in web/book_componenet.dart, we’ll get to that file shortly) and we declare that our custom element extends and li.

Inside our <element>, we create a <template> that stores the <li> that contains a book’s title.

And finally, we link to the accompanying Dart file, book_component.dart.

web/book_component.dart

Here we get to define our BookComponent class (remember that we declared that the <element> we created in book_componenet.html use this constructor?):

import 'package:web_ui/web_ui.dart';
import 'package:bookstore/models.dart';

class BookComponent extends WebComponent {
  Book book;
}

BookComponent extends WebComponent (this is the only option for subclassing at the moment; that may change in the future) and contains a book attribute (this can be set using the book = syntax when the web component is initialized). That’s it.

build.dart

import 'package:web_ui/component_build.dart';
import 'dart:io';

void main() {
  build(new Options().arguments, ['web/books.html']);
}

To actually build the project, run build.dart (this will create an out directory); then run web/out/books.html.

pubspec.yaml

The app only has a single pub dependency, web_ui:

name: bookstore
description: A sample app to demonstrate the use of a web component

dependencies:
    web_ui

Summary

This is a fair bit of code for a simple hello-world caliber app. Is all this web component stuff really necessary, or is it overkill?

We’re just starting out, so this may seem like too much of a production given what the needs of our app. But we have already established a pretty important development principle: our UI elements can be nicely ENCAPSULATED (!) and then used as necessary. We have taken the first baby steps towards creating a widget that displays the content of each book. As our application grows in complexity, our ‘widget’ will become more elaborate and we will want to use it in all sorts of different contexts in our app. A composable, encapsulated UI component - a web component - that can be instantiated with varying arguments will then prove to be quite useful.

January 01, 2013 01:54 AM

December 31, 2012

Shailen Tuli

setting up continuous integration for dart using drone.io

Creating a dummy project

I created a very simple project, droneDemo, to show how to set up Continuous Integration on drone.io for Dart projects. The code can be found here on Github.

droneDemo defines just two methods, add() and multiply(). These can be found in lib/. Tests for these methods can be found in test/. The pubspec.yaml file needs to declare a unittest dependency for these tests to work.

This is about as simple a project as you can have and there is little need for explanation. But it is worth delving into 2 points:

1) You should add packages to your .gitignore. This is to tell git not to commit the symlinks created by pub to version control. These symlinks are meaningful in the context of your filesystem but will trip drone.io.

If you already started your demo project and ended up with the symlinks, remove them.

2) drone.io needs a way to run all your tests. So far, Dart does not ship with a test runner, so you’ll have to cobble together something yourself.

Here’s what I did: my tests live in 2 different files, test/add_test.dart and test/multiply_test.dart. I declared both files as libraries (see the library add_test; and the library multiply_test; declaration at the top of each file) and imported components from them into test/test_runner.dart.

import “package:unittest/unittest.dart”; import “add_test.dart” as add_test; import “multiply_test.dart” as multiply_test;

void main() {

 add_test.main();
 multiply_test.main();

}

So, calling dart test/add_test.dart or dart test/multiply_test.dart runs only one test; calling dart/test_runner.dart runs both the tests.

With this out of the way, we can shift our attention to drone.io.

Drone.io: Basic Setup

Set up account at https://drone.io/signup.

On your dashboard, click on the New Project on the top right.

Pick Dart as the project language.

Pick Git as your Repository type.

Add the project name (I added droneDemo).

Add the Repository URL (mine was https://github.com/shailen/droneDemo.git). Make sure your github repo is set to use the http method, not the ssh method.

Press Create.

Configuring your Build

After you press Create, you will be redirected to the script/config page. Here, you will have to tell drone.io how to run your tests.

In the Commands section, type the following:

pub install
dart test/test_runner.dart

Remember test/test_runner.dart was our consolidating test runner? This is where the trouble we went through sewing our tests together pays off.

Press Save and when you get the message that tells you the build was successfully saved, press the blue Build Now button at the top.

A popup will appear with a Build Output link. Click that link.

Voila! You are swimming in a sea of green!

My build output can be seen at: https://drone.io/shailen/droneDemo/1

Setting up Continuous Build

Click on settings for your drone.io project

Click on General in the left column. You will see a couple of links under Build Hooks. Copy the top one.

Now, go back to your project on github. Mine is at https://github.com/shailen/droneDemo.

Click on Settings.

Click on Service Hooks (left column).

Click on the WebHook Urls link at the top.

Paste the build hook you had copied earlier in the text input box provided and press Update Settings.

From now on, every time you commit to your project on github, drone.io will run all your tests.

I changed one of my tests so that it was failing and pushed to github. No surprise, the build now show Failed (https://drone.io/shailen/droneDemo).

December 31, 2012 10:58 PM

December 24, 2012

Dart: Terra Incognita (Ladislav Thon)

Surprise me!

Looks like I’m clearly unable to write often (or at least more often :-) ), so I’ll instead try to focus on interesting stuff. Today, let’s take a look at some features in Dart that might be surprising. And since I wrote about the cool features earlier, today I’ll write about those that are … not so cool. Or bad, actually. Yes, each programming language that tries to hit the mainstream has to make compromises, which obviously leads to some kind of language smell (is there such a thing?). And Dart has particularly bad starting position, because it wants to compile to efficient JavaScript – and that is really huge constraint. So here comes the disclaimer: I’m writing this to point out some potential pain points, not to offend anyone (and especially not to say that Dart is bad, other languages would have much longer list!). Always remember the constraints Dart needs to fit into when judging.

All that said, let’s start.

Strings

What? Oh yeah, strings. Strings in Dart used to be sequences of Unicode code points. If that doesn’t make sense to you, that’s fine, it doesn’t have to. It essentially means that strings were comprised of characters. This was even in the M1 version of the specification (0.12).

It isn’t true anymore. It was changed, as you can find in revision 14357 and in the M2 version of the spec (0.20). Right now, strings are sequences of UTF-16 code units. What does that mean? If you imagine a string as a sequence of integers (which it essentially is, under the hood), the original version meant that single character was always represented by a single integer (Dart VM was clever about it and if all the characters fit into 8-bit integers, it used 8-bit integers for that; if not, then maybe 16-bit integers, and if even that wasn’t enough, then 32-bit integers). And this isn’t correct anymore – single character can still be a single integer (when the character belongs to the Basic Multilingual Plane), but it can also be two integers (characters from Supplementary Planes). These two integers together form a so called surrogate pair, and everytime you work with strings, you need to remember about them. Which is obviously a major source of programming errors – and I honestly believe that programmers making these errors shouldn’t be blamed. Who is guilty is the Unicode Consortium, which created the major abomination that UTF-16 is. It should really never have seen the light of day.

But sadly, it’s here witht us, and a lot of legacy software use it (Java, JavaScript, WebKit etc.). I was very sad to see this coming to Dart as well, but it was necessary for two reasons: compilation to JavaScript (otherwise Dart would need to implement strings on its own, which would probably perform badly) and integration of Dart VM with WebKit (before this change, each interaction with the DOM resulted in string conversions, again hurting performance).

Integers

Not really?! Oh yes. Dart has arbitrary precision integers, which is a very cool thing (you can work with arbitrarily big integers, as long as they fit into the heap) and also a big pain when compiling to JavaScript. You see, JavaScript only has one numeric type – double precision floating point (see IEEE 754). Which means that Dart doubles map naturally to JavaScript numbers, but Dart ints must somehow be implemented on top of them. And this implementation … is incomplete right now. It is probably the biggest difference between native Dart VM and Dart compiled to JavaScript, so take care.

Booleans

Now I’m surely kidding, right?! No, I’m not. Dart has a distinct bool type with two values, true and false, all nice and dandy, but it also features a boolean conversion. That is an infamous thing in a lot of dynamic programming languages, even those strongly typed, and I’d argue that it’s essentially bad. But in most languages that have it, it is actually useful – truthy and falsy values just make sense (the number zero, empty string, null, maybe empty list or map, all those can be used as a falsy value, anything else is truthy). Not in Dart. Dart only has one truthy value – the object true. Everything else is false. Which essentially means that the boolean conversion is useless – but it’s still there (apparently because it makes compilation to JavaScript easier). Just forget about it and you’ll be safe, but I’d wish it just disappeared. It doesn’t make any sense.

Collections

Am I trying to say something terrible about each of the basic types? I’m not, it just so happens. What is the problem with Collections? Their equality (and hash code). Or actually, the lack thereof.

If you think about it for a minute, it’s actually pretty hard to sensibly define equality and hash code for lists that can change its content during their lifetime. (What if you put an object to a map and use a mutable list as a key? If you later change that list, you won’t be able to use it again to lookup the object back from the map.) So Dart library designers decided not to base equality and hash code of collections on their content, but only on their identity. It has one tiny drawback, though: 1 == 1 is true, but [1] == [1] isn’t. That’s just plain wrong. The same applies to maps and sets.

Luckily, the library will probably contain functions to compare collections according to their content. So that’s at least something.

Nulls

That’s a joke, really. null is just fine in Dart. It doesn’t even throw the infamous NullPointerException but the nice old NoSuchMethodError.

Oh, and Merry Christmas to all Dartisans! :-)

December 24, 2012 08:00 AM

December 10, 2012

Shailen Tuli

Randomness in Dart: nextBool(), nextInt(), and nextDouble()

The Random class in dart:math contains 3 methods, nextBool(), nextInt() and nextDouble(). To use Random, you will need a import 'dart:math in your code.

nextBool()

simply returns true or false at random. Here is a little function, randUpcase() that demonstrates randBool() use. randUpcase() takes a string as an argument, and converts each character in the string to uppercase if random.nextBool() is true and leaves it untouched if it is false.

String randUpcase(String s) {
  Random random = new Random();
  List<String> chars = s.split('');
  return Strings.join(chars.map(
    (char) => random.nextBool() ? char.toUpperCase() : char), '');
}

And here is some sample usage:

var herbs = ["parsley", "sage", "rosemary", "thyme"];
print(herbs.map((herb) => randUpcase(herb))); // [pARslEY, SaGE, roSEMaRY, tHYME]

nextInt()

takes a max int argument and generates a positive int between 0 (inclusive) and max, exclusive.

To generate a random int within a range, you can do something like this:

int randRange(int min, int max) {
  var random = new Random();
  return min + random.nextInt(max - min);
}

You can also use nextInt() to randomly shuffle a list (using the familiar Fisher-Yates-Knuth algorithm):

List shuffle(List items) {
  var random = new Random();
  for (var i = items.length - 1; i > 0; i--) {
    var j = random.nextInt(i);
    var temp = items[i];
    items[i] = items[j];
    items[j] = temp;
  }
  return items;
}

You can use it like this:

var items = ["fee", "fi", "fo", "fum", "smell", "Englishman"];
print(shuffle(items)); // [fo, smell, fum, Englishman, fee, fi]

nextDouble()

generates a random floating point value distributed between 0.0 and 1.0. Here is a little function to simulate a biased coin toss; the percent argument alters the percent a coin will return heads (‘H’). This is pretty much cribbed from this discussion on Stack Overflow:

String flip(num percent) {
  Random random = new Random();
  return random.nextDouble() < percent ? 'H' : 'T';
}

And here is some code to test that it works:

int n = 1000;
int heads = 0;
for (var i = 0; i < 1000; i++) {
  if(flip(.20) == "H") heads++;
}
print(heads/n); // 0.209, 0.196, etc.

December 10, 2012 10:36 PM

December 08, 2012

Dart: Terra Incognita (Ladislav Thon)

Getting Dart from Git

I originally started to write this as a post on Google+, but I quickly found out that it’s a little longer and that it maybe warrants a full blog post. Here it is.

A small confession first: I have always been frustrated with building Dart from source.

First, Subversion is dead. Noone can expect me to participate on a project with Subversion. I want git and I want it now. Fortunately, the official page with instructions for getting the source also mentions git svn.

Second, git svn is a terrible idea. Every now and then, git svn fetch && git merge git-svn ended horribly for me and I really couldn’t repair the checkout. Luckily, we have two git mirrors of Dart: the primary one in Chromium Git repository and even one on GitHub (which is actually mirrored from the Chromium Git repository).

Third, Dart uses Google-specific tools for getting dependencies (Depot Tools) and building the code (GYP for generating makefiles + some hand-written scripts to invoke them). And in case of Dart, their configuration expects the SVN structure. Which means that if I clone Dart repo from one of those Git mirrors, I’m screwed. The structure doesn’t match. I have to live with those tools somehow, if I don’t want to create a new build system for Dart (which I don’t).

I got really fed up with this and spent few hours today (yes, hours!) trying to make a stream-lined process for getting Dart from Git and building it without issues, without higher-order wizardry and without special custom scripts. And I believe I’ve got one. Only a single, one-time, small and localized change… not bad. Here’s the process.

Initial setup

  1. git clone https://git.chromium.org/git/external/dart/bleeding_edge.git repo (if you forked Dart on GitHub, use a GitHub URL)

  2. cd repo

  3. gclient config http://dart.googlecode.com/svn/branches/bleeding_edge/deps/all.deps

  4. The previous command will create a .gclient file with a tiny configuration. Make this small change:

     @@ -4,6 +4,7 @@
          "deps_file"   : "DEPS",
          "managed"     : True,
          "custom_deps" : {
     +      "dart": None
          },
          "safesync_url": "",
        },

    Doing this, I’m overriding one of the instructions in the original DEPS file that says to clone the dart directory from SVN. I don’t need to do that, I’ve already got it from Git. All the other dependencies will still get cloned from SVN, but I don’t really care about those.

  5. gclient sync

Everytime I want to update

In the repo directory:

  1. git pull (or git fetch and git merge, you know know the drill)
  2. gclient sync && gclient runhooks

Building it is simple then

Just run ./tools/build.py in the repo/dart directory. No changes in this.

I wish I wouldn’t have to do all the crazy dance, but I think I can live with it. Nice thing is that this procedure is pretty similar to the official one.

P.S.: for easier work, I just added these entries to .git/info/exclude:

/.gclient
/.gclient_entries
/all.deps/

December 08, 2012 08:00 AM

December 07, 2012

Shailen Tuli

Running Only Some of Your Dart Tests with filterTests()

The Dart unittest library allows you to run just a single test; to do so, just change the call for that test form test() to solo_test().

Another way to run a subset of your tests is by using the filterTests() function. filterTests() takes a String or a RegExp argument and matches it against each test description; if the description matches, the test runs, otherwise, it doesn’t.

Before you use filterTests(), you need to disable the automatic running of tests (set autoStart to false) and ensure that the your configuration is initialized.

You can do this by creating a custom configuration:

import "package:unittest/unittest.dart";
import "package:args/args.dart";

class FilterTests extends Configuration {
  get autoStart => false;
}

void useFilteredTests() {
  configure(new FilterTests());
  ensureInitialized();  
}

Then, you can call useFilteredTests() in your main(), define all your tests, call filteredTests() with a string or regexp argument and run your tests using runTests():

void main() {
  useFilteredTests();

  // your tests go here

  filterTests(some_string_or_regexp);
  runTests();
}

Here is a little working example:

void main() {
  useFilteredTests();

  test("one test", () {
    expect(1, equals(1));
  }); 

  test("another test", () {
    expect(2, equals(2));
  });

  test("and another", () {
    expect(3, equals(3));
  });

  filterTests('test');
  // filterTests('another');

  runTests();
}

filterTests('test') will run the first 2 tests; filterTests('another') will run the last 2 tests.

It is easy to make this considerably more useful by getting the argument to filterTests() from the command line. That way, you can control what subset of tests to run without having to change the code in your test suite. Here is a slightly expanded version of the same example:

void main() {
  useFilteredTests();
  ArgParser argParser = new ArgParser();
  Options options = new Options();
  ArgResults results = argParser.parse(options.arguments);
  List<String> args = results.rest; // get the args from the command line

  test("one test", (){
    expect(1, equals(1));
  }); 

  test("another test", (){
    expect(2, equals(2));
  });

  test("and another", (){
    expect(3, equals(3));
  });

  // we add a group() to show how we can easily run just the tests
  // contained in it
  group("foo", () {
    test("this", (){
      expect('bar', equals('bar'));
    }); 

    test("that", (){
      expect('baz', equals('baz'));
    });
  });

  if (!args.isEmpty) {
    filterTests(args[0]);
  }
  runTests();
}

You can run the tests from the command line by using the

`dart name_of_file.dart [keyword]`

syntax. If the keyword is this, only one test will run. If the keyword is foo, all tests in the group() with the description of foo will run. If you do not provide a keyword, all 5 tests will run.

December 07, 2012 06:00 PM

November 26, 2012

Christian Grobmeier

Dart talk in Stuttgart – the Slides

On 22.11.2012 I was guest of the Java Usergroup in Stuttgart. It was a fun evening, with a lot of discussion on Dart. Here are the slides which I used:

What have I learned from that evening?

Not everybody likes JavaScript

First, there are still a lot of people who don’t like JavaScript. OK, I asked Java developers who are not known for their love to JavaScript. But after all, this group contains a lot of people. Some might say, they have not understood JavaScript very well and can’t judge. Well, that might be true. But this is not what counts. People often don’t have the time, the energy or the budget to learn things for which they need to make a complete refactoring of their minds. And this is often the case if you have programmed Java for a long while and suddenly turn to JavaScript. It happened to me back then, I know what I am speaking of.

JavaScript has its benefits – I myself like JavaScript meanwhile (except the quirks of course). I have invested a lot of time to learn about it. Still I am not a master, but I can survive. That’s fine. But it took me a lot of time and sometimes I was near to grief. Lucky me, I have found Stoyan Stefanovs excellent book “JavaScript Design Patterns” which is not only well written but also helped me to really get started.

Dart addresses the heavy learning curve. It seemed to me the audience liked the new flexibility which comes with Dart, compared to Java. And that they could still think in “old patterns” and use for example Classes. And that the syntax was so freaking familiar.

People don’t like experiments so much

Second, people were concerned whether Dartlang is an approach one needs to follow or if is just an experiment among thousand others.

JavaScript is everywhere. Why should one learn about Dart? It is easy to learn but you still need to read some docs and play around with the language – it costs you time.

There is a dart2js compiler, which lets you build your Apps right now. If Dart would become accepted by the masses is unknown to me. But I suspect there will be something “happen” in combination with Android.

Jochen Wiedmann summed up what I think on Android thing:

Had the pleasure to attend an interesting talk, organized by +JUG Stuttgart and given by +Christian Grobmeier on #Dart . Most appealing, in particular, a theory proposed by Christian: In order to resolve the chicken and egg problem that Dart’s not in widespread use, because the Browsers don’t support it natively, and vice versa, (and for a number of other reasons), Google might make Dart a first-class-citizen of Android: In other words, create a bridge between Dart and Dalvik that would allow to write Android Apps in Dart.

Well, that MIGHT be true. But I am not a Googler nor do I have insider information. It just makes… sense.

Using dart2js is not so elegant as running Dart in a native browser VM. With Roadcrew.js I found out that the generated JavaScript would take 200kb space, while writing JavaScript on my own + the jQuery library would only take only 100kb.

But Dart is still young and dart2js will optimize with time. And for just 100kb more (web fetishists will say its unbelievable huge and not acceptable) you get readable, maintainable code with great tooling which even the Java developers in your team can understand.

Java Usergroup Stuttgart - Dart Talk

Java Usergroup Stuttgart – Dart Talk

At the moment I do not use Dart in production. It is still changing to much. While the base syntax might be “pretty” stable, the libraries are undergoing a refactoring at the time of this writing which last for – i am guessing – 1 year or so. But once Dart is stable, I will surely start using it in production. Let us hope it this date is not so far away.

A nice evening

All speculations. What is real and fact: the evening was nice! The whole usergroup is organized in an excellent way. You would even get some snacks. And the location is wonderful. I simply decided that I will need to visit this beautiful city at daylight. Here is an unsharp photo of it. Sorry, but my Android phone wouldn’t make it better. For sure I will visit Stuttgart again – it is a great community over there.

NOTE: I have been asked if there was only one or two persons attending. That photo has been taken BEFORE the talk :-) In fact, around 40 people were there.

by Christian Grobmeier at November 26, 2012 08:32 AM

November 23, 2012

John Evans

Buckshot Now Supports Namespaces

Following on the recent mini-announcement on G+ that Buckshot is now a multi-platform library , I'm happy to also announce that Buckshot templates now support namespaces (in fact they require it).  Using namespaces provides several benefits:

  • Better visual identification of the template's target platform.
  • Element name collision avoidance.
  • The framework can better help identify misuse of elements within a template (namespace mismatch).
  • Sets up eventual support for multi-platform targetting withing the same application (HTML + SVG for example).

Introducing the "Template" Element

The addition of namespaces also introduces a new core element to the framework: "Template".  Template is essentially a non-visual element that is used to declare namespaces.  Yes you can declare namespaces directly on elements themselves, but this can get a bit messy.  "Template" provides a uniform way of declaring namespaces and is quite useful in a few specific scenarios.  Let's take a look at how this works:


Now lets say we have a library which defines some custom elements, and these belong to a namespace called 'http://buckshotui.org/sprockets'. We can include these elements using a named namespace declaration:


Ok, But Why?

To illustrate one example of the usefulness of namespaces, lets switch platforms and show a template from the (still experimental) SVG platform:

The default namespace tells Buckshot template engine to only accept elements in the template that are part of the SVG platform library.  This also gives a good visual indicator to anyone looking at the template that, aha, this is targetting SVG.

Other Places to Use Namespaces

Essentially any time you want to declare a template using platform-specific elements (non-core elements), you will need to also declare a namespace.  This applies to deferred templates such as the ItemsTemplate component of an CollectionPresenter.  Let's see what that looks like:

You might ask why the namespace for the ItemsTemplate isn't implicit since the template is declared within an CollectionPresenter. Good question! For now, explicit namespacing is required for deferred templates, but this may change in the future.

Go Get It!

Namespace support is now available in the Buckshot core library and in the HTML and SVG (still experimental at the time of this post) platform libraries.  Give it a try and let me know what you think.  Here are the links:



by John Evans (noreply@blogger.com) at November 23, 2012 10:46 PM

November 16, 2012

Kevin Moore

Excited to see dart2js minified output getting smaller (real world numbers below)



I noticed r15005 turns on more renaming in dart2js with --minify so I thought I'd see the impact on Pop, Pop, Win!

The last time I did a build and deploy of PPW was on r14873.

Here are the sizes of game.dart.js

dart2js617,201 bytes
closure compiler621.07KB
gzip (via http)107.7KB

Notes:
  • dart2js is running with the --minify flag
  • I'm using the closure-compiler with default settings. Build from 17 Sept, 2012
  • Notice how the output is bigger from closure? This is because output is optimized for gzip. Not intuitive, until you see the network panel in Chrome Dev Tools.
  • gzip is the size Chrome sees over the wire. Most servers gzip payloads. It's critical to pay attention to this number and not just the size on disk.


Now with the bleeding edge build r15005

dart2js451,183 bytes~33% smaller
closure compiler388.71 KB~37% smaller
gzip (via http)90.2KB~16% smaller


Notes:
  • The output from dart2js is substantially smaller. This is just the work from the dart2js guys recently. Amazing.
  • This time the output from the closure is smaller than the input (~12%). I can only speculate why. Perhaps the new minified output is more optimizable?
  • The gain with gzip is not as big (~16%). I'm not surprised by this. PPW is a pretty big game. The json that stores the texture data alone is huge.

Keep in mind, the Dart source for the game is 1.5 MB as reported by dart2js.
info: compiled 1576654 bytes Dart -> 451183 bytes JavaScript in web/game.dart.js
Is it fair to say we're getting ~94% smaller output? It depends on how valid one considers the the Dart code size reported by dart2js.

But I certainly don't feel I need to justify the javascript output size for non-trivial apps anymore.

Great work folks!

by Kevin Moore (noreply@blogger.com) at November 16, 2012 02:58 PM

Christian Grobmeier

Roadcrew.js – Page switching like a Boss.

When I started with mobile development I had only limited time available. The app should run on Android and iOS phones at the same time and therefore I looked into Apache Cordova and jQuery mobile. While the first one is enabling you to do mobile development with JavaScript and HTML5 in general (including hardware access), jQuery mobile is more or less a Widget factory and a framework to build your Apps. While jQuery mobile looked pretty nice it had one major drawback: it was slow as hell and way to complex to develop (for what it does). I need to add that I have used the versions before 1.0 and everything might be better meanwhile. But back than, it was like that.

There were two things I loved on jQuery mobile. One was it’s look. And the other thing was the “single page” approach. It meant, you have all your App HTML basically in one file, showing only the parts which are necessary.

When replacing jQuery mobile I used Twitter Bootstrap. Today I would probably look into Ratchet.

For the page switching I didn’t find anything, so I decided to write some code myself. Because I listened to “We are the Roadcrew” from the great Rock’n'Roll band Motörhead and “Roadcrew” is a pretty great name for mobile things, I simply named it like that: Roadcrew.

You can find more information on the official Roadcrew-Website. Or you start with cloning Roadcrew from Github.

How does it work?

It is pretty simple: include the Roadcrew.js files and make up your HTML, like for example:

<div class="page start" id="login">
...
</div>
<div class="page" id="content">
...
</div>

Every div which is a page, gets the “page” class. A page is basically the div which is shown on your mobile. You could also say “view” to it. Every page gets an ID. This is used to navigate between your pages. For example, if you want to show the “content” page, you would make up an link like:

<a href="#content">Leads to content</a>

To make this basic navigation work, you only need to make an instance of Roadcrew:

$(document).ready( function() {
   var roadcrew = new Roadcrew();
}

This is jQuery code. And in fact Roadcrew.js uses jQuery. I will try to reduce the dependencies to a minimum in future and hopefully I can make it work with Zepto.js. But for now you have to live with jQuery, which is said to be slower on mobiles than Zepto. Patches welcome!

Intercepting – show a loading page

On thing which really didn’t work well with jQuery mobile was to show a loading page. This is dead simple usually, but was forced to waste a lot of time to deal with it. In Roadcrew it’s pretty simple. You simply need to create an interceptor – something which is done before the actual target page is called.

It could look like that:

roadcrew.intercept('#interceptingPage', function(dispatch) {
   roadcrew.flip('#loadingPage');
   $.post('ajax/test.html', function(data) {
      dispatch();
   });
});

While the “flip” method just “flips” pages around, bypassing every potential interceptor, the dispatch() function argument is what you can think of “showing the actual target page”. With the code above you would show the loading page which is then visible until $.post is ready and calls the dispatch() function.

Call to arms: Error Handling

If your interceptor causes an error, you might want to have an error handler waiting for you. You can pass it on when registering your interceptor.

roadcrew.intercept('#troublePage', function(dispatch) {
   throw new RoadcrewError("I made trouble");
}, function(error) {
   $('#errorPage').find('.error').html(error.message);
   roadcrew.flip('#errorPage');
});

As you can see, I throw an error in my dispatcher. The second function is my error handler which will work with the error handler.

There is also a chance to define a global error handler, which deals with every error.

Dart port available

I ported Roadcrew to Dart. Dart is a great new language for the web. It is still a pretty young language and not so widely spread yet. Consider this port an experiment. If you want to compare JavaScript to Dart Code you might find this interesting too.

I will create a blog post on Roadcrew.dart and my experiences on the port when I find some time.

Future

The current implementation is pretty small and it gives me everything I need. But I have already seen some things which might be useful for others. For example, there is no transition animation so far. It should be pretty easy to implement such a thing, I just didn’t do it. If you want to help me, send me a patch.

As already mentioned I would like to support Zepto.js.

There is now way to load new divs by AJAX. Currently I am unsure if this would just blow up the code or if it is really useful.

And finally I need to say that there is always room to improve the current code itself.

That all said, I hope that you’ll find it useful. If you have some feedback, let me know – either by mail or – if appropriate as feature wish or issue in the issue tracker.

by Christian Grobmeier at November 16, 2012 11:02 AM

Dart Logo

Last updated: June 19, 2013 11:30 AM UTC

Dartosphere channels