ステップ 5: ウェブから画像を追加する

このステップでは、次のことを学習します。

  • アプリの外部からリソースを読み込み、XHR と ObjectURL を使用して DOM に追加する方法。

このステップの推定所要時間は 20 分です。
このページの一番下に移動 ↓ すると、この手順を完了できます。

CSP が外部リソースの使用に与える影響

Chrome アプリ プラットフォームでは、アプリはコンテンツ セキュリティ ポリシー(CSP)に完全に準拠するようになります。 Chrome アプリ パッケージの外部から画像、フォント、CSS などの DOM リソースを直接読み込むことはできません。

外部画像をアプリに表示する場合は、XMLHttpRequest を介して外部画像をリクエストし、Blob に変換して、ObjectURL を作成する必要があります。この ObjectURL は、アプリのコンテキストでメモリ内アイテムを参照するため、DOM に追加できます。

ToDo アイテムのサムネイル画像を表示する

ToDo アイテムで画像の URL を検索するようにアプリを変更してみましょう。URL が画像のような形式(末尾が .png、.jpg、.svg、.gif など)の場合、上記のプロセスを適用すると、URL の横に画像のサムネイルを表示できます。

許可を更新

Chrome アプリでは、マニフェストでドメインを指定すれば、任意の URL に対して XMLHttpRequest 呼び出しを行うことができます。ユーザーが入力する画像の URL は事前にわからないため、"<all_urls>" にリクエストを送信する権限をリクエストします。

manifest.json で、「」権限をリクエストします。

"permissions": ["storage", "alarms", "notifications",
                "webview", "<all_urls>"],

ObjectURL を作成、クリアする

controller.js で、_createObjectURL() メソッドを追加して、Blob から ObjectURL を作成します。

Controller.prototype._createObjectURL = function(blob) {
  var objURL = URL.createObjectURL(blob);
  this.objectURLs = this.objectURLs || [];
  this.objectURLs.push(objURL);
  return objURL;
};

ObjectURL はメモリを保持するため、ObjectURL が不要になった場合は取り消す必要があります。この _clearObjectURL() メソッドを controller.js に追加して処理します。

Controller.prototype._clearObjectURL = function() {
  if (this.objectURLs) {
    this.objectURLs.forEach(function(objURL) {
      URL.revokeObjectURL(objURL);
    });
    this.objectURLs = null;
  }
};

XHR リクエストを行う

_requestRemoteImageAndAppend() メソッドを追加して、指定された画像 URL で XMLHttpRequest を実行します。

Controller.prototype._requestRemoteImageAndAppend = function(imageUrl, element) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', imageUrl);
  xhr.responseType = 'blob';
  xhr.onload = function() {
    var img = document.createElement('img');
    img.setAttribute('data-src', imageUrl);
    img.className = 'icon';
    var objURL = this._createObjectURL(xhr.response);
    img.setAttribute('src', objURL);
    element.appendChild(img);
  }.bind(this);
  xhr.send();
};

XHR の読み込み時に、このメソッドは XHR のレスポンスから ObjectURL を作成し、この ObjectURL を持つ <img> 要素を DOM に追加します。

ToDo アイテム内の画像 URL を解析する

次に、_parseForImageURLs() メソッドを追加します。このメソッドは、まだ処理されていないリンクをすべて検出し、画像を確認します。画像のように見える各 URL に対して、_requestRemoteImageAndAppend() を実行します。

Controller.prototype._parseForImageURLs = function () {
  // remove old blobs to avoid memory leak:
  this._clearObjectURL();
  var links = this.$todoList.querySelectorAll('a[data-src]:not(.thumbnail)');
  var re = /\.(png|jpg|jpeg|svg|gif)$/;
  for (var i = 0; i<links.length; i++) {
    var url = links[i].getAttribute('data-src');
    if (re.test(url)) {
      links[i].classList.add('thumbnail');
      this._requestRemoteImageAndAppend(url, links[i]);
    }
  }
};

ToDo リストでサムネイルをレンダリングする

showAll()showActive()showCompleted() から _parseForImageURLs() を呼び出します。

/**
 * An event to fire on load. Will get all items and display them in the
 * todo-list
 */
Controller.prototype.showAll = function () {
  this.model.read(function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

/**
 * Renders all active tasks
 */
Controller.prototype.showActive = function () {
  this.model.read({ completed: 0 }, function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

/**
 * Renders all completed tasks
 */
Controller.prototype.showCompleted = function () {
  this.model.read({ completed: 1 }, function (data) {
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
    this._parseForImageURLs();
  }.bind(this));
};

editItem() についても同様にします。

Controller.prototype.editItem = function (id, label) {
  ...
  var onSaveHandler = function () {
    ...
    if (value.length && !discarding) {
      ...
      label.innerHTML = this._parseForURLs(value);
      this._parseForImageURLs();
    } else if (value.length === 0) {
  ...
}

表示される画像のサイズを制限する

最後に、_bowercomponents/todomvc-common/base.css で、画像のサイズを制限する CSS ルールを追加します。

.thumbnail img[data-src] {
  max-width: 100px;
  max-height: 28px;
}

完成した ToDo アプリを起動する

これでステップ 5 は完了です。アプリを再読み込みし、オンラインでホストされている画像への URL を含む ToDo アイテムを追加します。使用できる URL は http://goo.gl/nqHMF#.jpghttp://goo.gl/HPBGR#.png などです。

自然言語処理についてや、

この手順で導入する API の詳細については、以下をご覧ください。

次のステップに進む準備はできましたか?ステップ 6 - ToDo をファイル システムにエクスポートする » に進みます。