Monday, April 29, 2013

Initial Layout for the Dart Version of the ICE Code Editor

‹prev | My Chain | next›

With the big unknowns answered, I am ready to dive into converting the ICE Code Editor to Dart. The unknowns were the ability to interact with JavaScript libraries from Dart (js-interop does this with aplomb) and the ability to read existing localStorage data, which is compressed.

The Dart version of the ICE code editor will be a pub package. I have been messing about in that directory with some exploratory code, but I think now is the time to think about layout. Well, maybe not so much think about it as follow the layout documentation

So I make the sub-directories that I believe that I will need:
➜  ice-code-editor git:(master) ✗ mkdir docs lib packages test example
And create the metadata files:
➜  ice-code-editor git:(master) ✗ touch README.md LICENSE pubspec.yaml

While I am at it, I tell git to ignore the pubspec.lock file as well as the packages directory:
➜  ice-code-editor git:(master) ✗ cat <<-YAML > .gitignore
heredocd> packages
heredocd> pubspec.lock
heredocd> YAML
To sanity check my layout, I start work in the example sub-directory. I create a simple app.dart web server and a public sub-directory underneath that to hold an index.html web page:
<head>
  <script src="js/ace/ace.js" type="text/javascript" charset="utf-8"></script>
  <script src="packages/browser/dart.js"></script>
  <script type="application/dart">
    import 'package:ice_code_editor/ice.dart';
    main() => new ICE.Full('ace');
  </script>

</head>
<h1>Hello</h1>
<div style="width:600px; height: 400px" id="ace"></div>
I will create ice.dart back in the <PACKAGE_ROOT>/lib directory in a bit, but first I struggle with the location for the ACE code editor JavaScript files. I love Dart and all, but there is no way that I am going to attempt to reproduce ACE in Dart. Instead, I will continue to call the JavaScript code from Dart. But where to put the JavaScript code?

The pub documentation would seem to suggest that I put it in <PACKAGE_ROOT>/web, but I have no idea how to source that from a <script> tag if I follow that approach. I table that for now and include the JavaScript directly in <PACKAGE_ROOT>/example/public/js/ace. This is not a long term solution as anyone wanting to use the ICE code would also have to manually copy ACE into their application. Still, this ought to allow me to verify that everything else is in place.

Now, I can switch to <PACKAGE_ROOT>/lib to create the ICE.Full() constructor that is used in the example page. In ice.dart, I add:
import 'package:js/js.dart' as js;

class ICE {
  ICE.Full(el) {
    var context = js.context;
    context.ace.edit(el);
  }
}
With that, I can start the sample app up, load the homepage in Dartium and I see:



Nice! It just works. I have myself a decent start on the overall structure of my package. But where to put those JavaScript files?

The answer to that would seem to come from the browser package, which bundles the dart.js JavaScript file. If the Dart maintainers feel no compunction about including JavaScript directly in <PACKAGE_ROOT>/lib, then why should I? So I move the ace sub-directory under <PACKAGE_ROOT>/lib/ace. This ensures that ACE will be bundled with ICE (and that the ACE JavaScript API will be fixed in the package).

With that, I can modify the example page to point to the bundled ACE:
<head>
  <script src="packages/ice_code_editor/ace/ace.js" type="text/javascript" charset="utf-8"></script>
  <script src="packages/browser/dart.js"></script>
  <script type="application/dart">
    import 'package:ice_code_editor/ice.dart';
    main() => new ICE.Full('ace');
  </script>

</head>
<h1>Hello</h1>
<div style="width:600px; height: 400px" id="ace"></div>
And everything still works.

This seems like a good stopping point for tonight. I will pick back up with some tests tomorrow.


Day #736

No comments:

Post a Comment