WebComponentsとPolymerコード比較


仕事でPolymerを使うことになりました。
まずは、どこがwebcomponentsで、どこがPolymerがやってくれてることなのかを把握するためにwebcomponentsで書いた場合とPolymerで書いた場合のコードを比較したいと思います。

[Quick tour of Polymer](https://www.polymer-project.org/1.0/docs/start/quick-tour.html)をWebComponentsで書いてみて比較します。

# Register an element

まずはwebcomponents.   
[動作確認](http://plnkr.co/hSZOhr)

```html
<!DOCTYPE html>
<script>

var ProtoElement = Object.create(HTMLElement.prototype);
 
ProtoElement.createdCallback = function () {
  this.textContent = "I'm a proto-element. Check out my prototype!"
};  
 
document.registerElement('proto-element', {
  prototype: ProtoElement
});

</script>
```

次にPolymer   

```html
<!DOCTYPE html>
<link rel="import"
      href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html">

<script>
  // register a new element called proto-element
  Polymer({
    is: "proto-element",
    // add a callback to the element's prototype
    ready: function() {
      this.textContent = "I'm a proto-element. Check out my prototype!"
    }
  });
</script>
```

まだメリットを感じない。

# Add local DOM

webcomponents   
[動作確認](http://plnkr.co/skyimj)

```html
<!DOCTYPE html>

<template id="dom-element">
<p>I'm a DOM element.This is a Shadow DOM!</p>
</template>    

<script>

var DomElement = Object.create(HTMLElement.prototype);
var doc = this.document.currentScript.ownerDocument;

DomElement.createdCallback = function () {
  var shadowRoot = this.createShadowRoot();
  var template = doc.querySelector('#dom-element');
  var clone = document.importNode(template.content, true);
  shadowRoot.appendChild(clone);
};  
 
document.registerElement('dom-element', {
  prototype: DomElement
});

</script>
```

Polymer   


```html
<!DOCTYPE html>
<link rel="import"
      href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html">

<dom-module id="dom-element">

  <template>
    <p>I'm a DOM element. This is my local DOM!</p>
  </template>

  <script>
    Polymer({
      is: "dom-element"
    });
  </script>

</dom-module>
```

Shadow Domを使おうとすると途端にPolymerが簡単になります。

# Compose with local DOM

webcomponents   
[動作確認](http://plnkr.co/F26lWN)

```picture-frame.html
<!DOCTYPE html>

<template id="picture-frame">
  <!-- scoped CSS for this element -->
  <style>
    div {
      display: inline-block;
      background-color: #ccc;
      border-radius: 8px;
      padding: 4px;
    }
  </style>

  <div>
    <!-- any children are rendered here -->
    <content></content>
  </div>
</template>    

<script>

var DomElement = Object.create(HTMLElement.prototype);
var doc = this.document.currentScript.ownerDocument;

DomElement.createdCallback = function () {
  var shadowRoot = this.createShadowRoot();
  var template = doc.querySelector('#picture-frame');
  var clone = document.importNode(template.content, true);
  shadowRoot.appendChild(clone);
};  
 
document.registerElement('picture-frame', {
  prototype: DomElement
});
</script>
```

```index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <link rel="import" href="picture-frame.html">
  </head>
  <body>
    <picture-frame>
      <img src="https://www.polymer-project.org/images/logos/p-logo-32.png">      
    </picture-frame>
  </body>
</html>
```

Polymer   

```picture-frame.html
<link rel="import"
      href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html">
<dom-module id="picture-frame">

  <!-- scoped CSS for this element -->
  <style>
    div {
      display: inline-block;
      background-color: #ccc;
      border-radius: 8px;
      padding: 4px;
    }
  </style>

  <template>
    <div>
      <!-- any children are rendered here -->
      <content></content>
    </div>
  </template>

  <script>
    Polymer({
      is: "picture-frame",
    });
  </script>

</dom-module>
```

```index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.min.js"></script>
    <link rel="import" href="picture-frame.html">
  </head>
  <body>
    <picture-frame>
      <img src="https://www.polymer-project.org/images/logos/p-logo-32.png">
    </picture-frame>
  </body>
</html>
```

```<content>``` タグを使ってもさほど変わらない。結局、Shadow Domの部分が楽になる

# Use data binding

data bindingはwebcomponetsにはないのでPolymer偉いです。   

例えば双方向バインディングはこんな感じです。

```html
<link rel="import"
      href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html">
<!-- import the iron-input custom element -->
<link rel="import"
      href="http://www.polymer-project.org/1.0/samples/components/iron-input/iron-input.html">

<dom-module id="editable-name-tag">

  <template>
    <p>
    This is a <strong>{{owner}}</strong>'s editable-name-tag.
    </p>
    <!-- iron-input exposes a two-way bindable input value -->
    <input is="iron-input" bind-value="{{owner}}"
      placeholder="Your name here...">
  </template>

  <script>
    Polymer({
      is: "editable-name-tag",
      properties: {
        owner: {
          type: String,
          value: "Daniel"
        }
      }
    });
  </script>

</dom-module>
```