Tuesday, September 24, 2013

Getting Started with Polymer (.dart)


I messed around with Web UI components a while back. Since they have been replaced by Polymer, and since I have need of a custom component, this seems an opportune time to play around with both.

A week or so ago, we got faux-<script> support added to ICE Code Editor. The tag looked like:
<script type="text/ice-code" src="embed_a.html" data-line-number="49"></script>
A little bit of Dart code scanned the HTML for text/ice-code <script> tags, replacing them with embedded versions of the code. This seems an ideal application of Polymer.

Instead of faux-<script> tags, I would like a real <ice-code-editor> tag along the lines of:
<ice-code-editor src="embed_a.html" line-number="49"></ice-code-editor>
So...

First, I add polymer as a dependency for the ICE:
name: ice_code_editor
# ...
dependencies:
  # ...
  polymer: any
Then install the newly added dependency:
➜  ice-code-editor git:(embedded) ✗ pub install
Resolving dependencies.................................................................................
Downloading polymer 0.7.3+1 from hosted...
Downloading barback 0.7.3+1 from hosted...
Downloading csslib 0.7.3+1 from hosted...
Downloading shadow_dom 0.7.3+1 from hosted...
Downloading polymer_expressions 0.7.3+1 from hosted...
Downloading observe 0.7.3+1 from hosted...
Downloading yaml 0.7.3+1 from hosted...
Downloading html5lib 0.7.3+1 from hosted...
Downloading html_import 0.7.3+1 from hosted...
Downloading mutation_observer 0.7.3+1 from hosted...
Downloading source_maps 0.7.3+1 from hosted...
Downloading utf 0.7.3+1 from hosted...
Downloading mdv 0.7.3+1 from hosted...
Downloading custom_element 0.7.3+1 from hosted...
Dependencies installed!
Polymer requires two things to work. The HTML <polymer-element> template, which I create in a separate ice_code_editor.html file:
<polymer-element name="ice-code-editor" attributes="src,line-number">
  <template>
    <h1>The src is {{src}}</h1>
    <content></content>
  </template>
  <script type="application/dart" src="ice_polymer.dart"></script>
</polymer-element>
I then create the referenced ice_polymer.dart file as:
import 'package:polymer/polymer.dart';
import 'dart:html';
import 'package:ice_code_editor/ice.dart' as ICE;

@CustomTag('ice-code-editor')
class IceCodeEditorElement extends PolymerElement with ObservableMixin {
  @observable String src;

  void created() {
    super.created();

    var container = new DivElement()
      ..style.width = '600px'
      ..style.height = '400px';

    print('here: ${src}');
    print(host.text);
    host.children.add(container);
    // create ice here
  }
}
The observable stuff should give me access to the necessary src and line-number attributes. Except they don't.

When I try to use my custom element from my main web page:
<head>
  <link rel="import" href="ice_code_editor.html">
  <script src="packages/polymer/boot.js"></script>
</head>
<body>

<p>
asdf asdf as df sadf as df asdf
</p>

<ice-code-editor src="embed_a.html" line-number="49"></ice-code-editor>

<p>
asdfsadfasd sadf asdf  sdf asdf a sdfsfd
</p>

</body>
I get an empty value for the src.



This is apparently a known bug in Polymer.dart. Unfortunately, it is something of a show stopper for me in this case.

I can kinda-sorta make it work by embedding the attributes in the content of my custom tag:
<ice-code-editor>src="embed_a.html" line-number="49"</ice-code-editor>
I can then parse that information out in the create() method of my PolymerElement:
@CustomTag('ice-code-editor')
class IceCodeEditorElement extends PolymerElement with ObservableMixin {
  @observable String src;

  void created() {
    super.created();
    // ...
    Map attrs = {};
    host.text.split(" ").forEach((attr) {
      var pair = attr.split('=');
      attrs[pair[0]] = pair[1];
    });
    // Setup ICE here...
  }
}
But that's pretty ugly. Bother.

Somewhat frustrated, I call it a night here. I am unsure if there is much point in pushing further with this until that bug is resolved. It seems close to what I want, but it may be best to wait for resolution of that issue before making any final decisions.


Day #884

2 comments:

  1. what happens if src has a default value; I remember seeing the examples and a comment on initialising observable with values; but I could be going crazy

    ReplyDelete
    Replies
    1. Instead of null, I get the value to which it was initialized, but not the value set in the custom element attribute.

      I think I saw that example somewhere as well, but it may have been a patch for polymer.dart. I'm gonna see if I can dig that up tonight and give it a try.

      Delete