Thursday, April 25, 2013

Using the ACE Code Editor with Dart

‹prev | My Chain | next›

Having built the ICE Code Editor out into separate, reusable classes, I have learned much. Mostly I have learned that I really do not enjoy building large applications in JavaScript. I have to compile it constantly into a single downloadable file. While developing, I have to be sure to load all of the individual files in the right order. I have to be picky about the libraries that I pull in. Coding OO JavaScript is just ugly. And forget about testing. So I wonder, how easy would it be to do this in Dart?

Part of the trouble with Dart is that I really do not want to reimplement the actual editor part of ICE:



That comes from the ACE project and it way more work than I want to get into right now. But then again, there is the js-interop package—maybe that will let me interact with ACE, while still enjoying the benefits of Dart.

In the scripts sub-directory, I create a pubspec.yaml:
name: Testing ICE, ICE, Dart
dependencies:
  unittest: any
  js: any
Then I can pub install to get:
➜  scripts git:(master) ✗ pub install
Resolving dependencies...
Downloading meta 0.5.0+1...
Downloading browser 0.5.0+1...
Downloading unittest 0.5.0+1...
Downloading js 0.0.22...
Dependencies installed!
I start with a simple web page:
<head>
  <script type="application/dart" src="scripts/ice.dart"></script>
  <script>
  navigator.webkitStartDart();
  </script>
</head>
<h1>Hello</h1>
Unfortunately, even with a very simple ice.dart script file:
import 'dart:html';
import 'package:js/js.dart' as js;

main() {
  var context = js.context;
}
I run into a slew of problems in the console of Dartium:
Uncaught ReferenceError: ReceivePortSync is not defined localhost/:54
Exception: The null object does not have a method 'callSync'.

NoSuchMethodError : method not found: 'callSync'
Receiver: null
Arguments: [GrowableObjectArray]
Stack Trace: #0      Object.noSuchMethod (dart:core-patch:1907:25)
#1      _enterScope (http://localhost:8000/scripts/packages/js/js.dart:749:35)
#2      _enterScopeIfNeeded (http://localhost:8000/scripts/packages/js/js.dart:728:28)
#3      context (http://localhost:8000/scripts/packages/js/js.dart:717:22)
#4      main (http://localhost:8000/scripts/ice.dart:5:20)
 
It takes me a bit to realize that I cannot use my simple navigator.webkitStartDart(). Instead, I should rely on one of the dependencies that was installed to do this for me. So I remove that line and source dart.js from the browser package:
<head>
  <script src="scripts/ace/ace.js" type="text/javascript" charset="utf-8"></script>
  <script type="application/dart" src="scripts/ice.dart"></script>
  <script src="scripts/packages/browser/dart.js"></script>
</head>
<h1>Hello</h1>
With that, I am ready to roll.

So, back in ice.dart I tell the JavaScript context to start ACE:
import 'dart:html';
import 'package:js/js.dart' as js;

main() {
  var context = js.context;

  context.ace.edit('ace');
}
And it works!



Well, not entirely. The actual editor does not show up, but the ACE DOM elements are very much there. Satisfied that this seems doable, I call it a night here. I will pick back up tomorrow with actually showing the editor and maybe even doing ICE-like stuff with it.

Update figured it out. I had a typo in the style attribute for the ACE <div>. This fixes the problem:
<head>
  <script src="scripts/ace/ace.js" type="text/javascript" charset="utf-8"></script>
  <script type="application/dart" src="scripts/ice.dart"></script>
  <script src="scripts/packages/browser/dart.js"></script>
</head>
<h1>Hello</h1>
<div style="width:600px; height: 400px" id="ace"></div>
With that, I have Dart pulling ACE into Dartium:




Day #732

No comments:

Post a Comment