Help us understand the problem. What is going on with this article?

Polymer 1.1 リリース

More than 5 years have passed since last update.

こんにちは、lacoです。Google I/OでのPolymer 1.0リリースから2ヶ月半あまり、ようやく1.1がリリースされました。1.0から1.1へのアップデートではある一つの仕様が追加されました。公式ブログの内容をかいつまんでまとめます。

アップデート概要

今回のアップデートはただひとつの仕様追加だけを行うマイナーアップデートであり、破壊的変更は一切ありません。

This is a relatively small, minor release - no breaking changes, and only one feature addition:

追加される仕様には明確な名前は付けられていませんが、本稿では便宜上 include記法 と呼びます。include記法により、これまでPolymerの課題であった「elementをまたいだスタイリング(theming)」が容易に実現できるようになります。

使用例

アプリケーション全体で共通して使いたいスタイルがあるとします。例えば次のようなwarningクラスのような汎用的なクラスです

.warning {
    color: red;
    font-weight: bold;
}

ここで<x-hoge></x-hoge><x-fuga></x-fuga>というPolymerElementがあるとします。x-hogeとx-fugaはタグ名が違うだけで中身は同じです。

x-hoge.html
<link rel="import" href="../bower_components/polymer/polymer.html"/>

<dom-module id="x-hoge"> <!-- "x-fuga" -->
  <template>

    <p class="warning">{{ message }}</p>
  </template>
  <script>
    Polymer({
      is: "x-hoge", // x-fuga

      properties: {
        message: {
          type: String,
          value: "Hoge!" // "Fuga!"
        }
      }
    });
  </script>
</dom-module>

そしてこれらを配置したindex.htmlがあります。

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
  <script src="bower_components/webcomponentsjs/webcomponents-lite.js"></script>
  <link rel="import" href="elements/x-hoge.html"/>
  <link rel="import" href="elements/x-fuga.html"/>
</head>
<body>
  <x-hoge></x-hoge>
  <x-fuga></x-fuga>
</body>
</html>

kobito.1439561108.454657.png

Polymer 1.0ではこの2つの要素に.warningを適用するのに次のような方法がありました。

Shady DOMの場合

1.0ではデフォルトでShady DOMが使用されるため、意識せずにこの方法を使っている場合が多いです。Shady DOMは外から内への一方通行の特殊なCSS Scopeを持ちますので、index.htmlで宣言してしまえばすべてに適用されます

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
  <script src="bower_components/webcomponentsjs/webcomponents-lite.js"></script>
  <link rel="import" href="elements/x-hoge.html"/>
  <link rel="import" href="elements/x-fuga.html"/>
  <style>
    .warning {
      color: red;
      font-weight: bold;
    }
  </style>
</head>
<body>
  <x-hoge></x-hoge>
  <x-fuga></x-fuga>
</body>
</html>

kobito.1439561305.789145.png

直感的で特に何の難点もない方法ですが、将来的にShady DOMはオプショナルに
なり、デフォルトがShadow DOMになることは明言されているため、一時凌ぎの解決策ともいえます。また、element側から自身に影響するCSSが把握できません。

Shadow DOMの場合

Shadow DOMは内外のCSS Scopeが完全に断絶しているため、上記のスタイリングは機能しません。そのため、.warningのスタイリングは各PolymerElementに宣言するしかありませんでした。

x-hoge.html
<link rel="import" href="../bower_components/polymer/polymer.html"/>
<dom-module id="x-hoge">
  <style>
    .warning {
      color: red;
      font-weight: bold;
    }
  </style>
  <template>
    <p class="warning">{{ message }}</p>
  </template>
  <script>
    Polymer({
      is: "x-hoge",

      properties: {
        message: {
          type: String,
          value: "Hoge!"
        }
      }
    });
  </script>
</dom-module>

kobito.1439562825.928220.png

これではCSSがすべての要素にハードコードされてしまうので、外部CSSファイルをインポートするのが現実的です。

x-fuga.html
<link rel="import" href="../bower_components/polymer/polymer.html"/>

<dom-module id="x-fuga">
  <link rel="import" type="css" href="../style.css"/>
  <template>
    <p class="warning">{{ message }}</p>
  </template>
  <script>
    Polymer({
      is: "x-fuga",

      properties: {
        message: {
          type: String,
          value: "Fuga!"
        }
      }
    });
  </script>
</dom-module>

この方法はlink[rel="import"][type="css"]を使いますが、これはWeb Componentsの仕様の範囲外であり、直感的でもないため改善すべきという声が挙がっていました。

In Polymer 1.1

そこでPolymer 1.1ではelementを跨いで使うスタイルのための仕組みを新しく追加しました。
まず対象のCSSをx-style.htmlにPolymerElementとして宣言します。

x-style.html
<dom-module id="x-style">
  <template>
    <style>
      .warning {
        color: red;
        font-weight: bold;
      }
    </style>
  </template>
</dom-module>

そして、このx-style.htmlをx-hoge、x-fugaそれぞれで include します。

x-hoge.html
<link rel="import" href="../bower_components/polymer/polymer.html"/>
<link rel="import" href="../x-style.html"/>

<dom-module id="x-hoge">

  <template>
    <style include="x-style"></style>
    <p class="warning">{{ message }}</p>
  </template>
  <script>
    Polymer({
      is: "x-hoge",

      properties: {
        message: {
          type: String,
          value: "Hoge!"
        }
      }
    });
  </script>
</dom-module>

kobito.1439568262.827427.png

PolymerElementとしてスタイルを扱うことでソースコード内のインポート文に一貫性が生まれてわかりやすくなります。x-style.htmlもHTMLファイルではありますが中身はほとんどCSSファイルと変わらないため、デザイナーとの分業も容易でしょう。

include記法によるスタイリングが新しく導入されますが、これまでどおり<link rel="import" type="css">によるインポートもサポートされています。しかしいずれは削除される予定ですので早めにinclude記法に切り替えるべきでしょう。

しかしこのアップデートのポイントは <style>タグは<template>の中に配置すべき という明確な指針が生まれたところです。これまで<template>の外でも中でも挙動に違いはなく、デベロッパーガイドでは外に書かれていました。しかしPolymer 1.1からはtemplateタグの内部に配置することが推奨となり、Shadow DOMへのstyleタグの展開において最適化が行われるようになります。今後PaperElements等の公式PolymerElementsもこの指針に従ってアップデートされます。

まとめ

若干の見切り発車感が否めなかったPolymer 1.0ですが、世界中のデベロッパーからのフィードバックにより新しい機能が追加され、より実用的になりました。あやふやだったコーディングスタイルも推奨される形が少しずつ定まってきています。今後のアップデートにも期待が持てますね。

lacolaco
I play Angular and pray for Angular. No Breaking Changes, No Life.
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away