Étape 4: Ouvrir des liens externes avec une WebView

Au cours de cette étape, vous allez apprendre à:

  • Comment afficher du contenu Web externe dans votre application de manière sécurisée et en bac à sable.

Temps estimé pour effectuer cette étape: 10 minutes
Pour afficher un aperçu de cette étape, accédez au bas de la page ↓.

En savoir plus sur la balise WebView

Certaines applications doivent présenter du contenu Web externe directement à l'utilisateur, tout en les conservant dans le dans votre application. Par exemple, un agrégateur d'actualités peut vouloir intégrer des actualités provenant de sources externes des sites avec la mise en forme, les images et le comportement du site d'origine. Pour celles-ci et d'autres , les applications Chrome comportent une balise HTML personnalisée appelée webview.

L'application Todo avec WebView

Implémenter la balise WebView

Mettez à jour l'application Todo pour rechercher des URL dans le texte de la tâche et créer un lien hypertexte. Le lien, quand ouvre une nouvelle fenêtre de l'application Chrome (et non un onglet de navigateur) avec une WebView présentant le contenu.

Modifier les autorisations

Dans le fichier manifest.json, demandez l'autorisation webview:

"permissions": [
  "storage",
  "alarms",
  "notifications",
  "webview"
],

Créer une page d'intégration WebView

Créez un fichier à la racine du dossier de votre projet et nommez-le webview.html. Ce fichier est un page Web de base avec une balise <webview>:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <webview style="width: 100%; height: 100%;"></webview>
</body>
</html>

Analyser les URL dans les tâches

À la fin de controller.js, ajoutez une méthode appelée _parseForURLs():

  Controller.prototype._getCurrentPage = function () {
    return document.location.hash.split('/')[1];
  };

  Controller.prototype._parseForURLs = function (text) {
    var re = /(https?:\/\/[^\s"<>,]+)/g;
    return text.replace(re, '<a href="$1" data-src="$1">$1</a>');
  };

  // Export to window
  window.app.Controller = Controller;
})(window);

Chaque fois qu'une chaîne commençant par "http://" ou "https://" est détectée, une balise d'ancrage HTML est créée pour encapsuler l'URL.

Recherchez showAll() dans controller.js. Mettez à jour showAll() pour analyser les liens à l'aide de la méthode Méthode _parseForURLs() ajoutée précédemment:

/**
 * 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.view.show(data);
    this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
  }.bind(this));
};

Procédez de la même manière pour showActive() et showCompleted():

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

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

Enfin, ajoutez _parseForURLs() à editItem():

Controller.prototype.editItem = function (id, label) {
  ...
  var onSaveHandler = function () {
    ...
      // Instead of re-rendering the whole view just update
      // this piece of it
      label.innerHTML = value;
      label.innerHTML = this._parseForURLs(value);
    ...
  }.bind(this);
  ...
}

Toujours dans editItem(), corrigez le code pour qu'il utilise le innerText du libellé au lieu du innerHTML du libellé:

Controller.prototype.editItem = function (id, label) {
  ...
  // Get the innerHTML of the label instead of requesting the data from the
  // Get the innerText of the label instead of requesting the data from the
  // ORM. If this were a real DB this would save a lot of time and would avoid
  // a spinner gif.
  input.value = label.innerHTML;
  input.value = label.innerText;
  ...
}

Ouvrir une nouvelle fenêtre contenant WebView

Ajoutez une méthode _doShowUrl() au fichier controller.js. Cette méthode ouvre une nouvelle fenêtre de l'application Chrome via chrome.app.window.create() avec webview.html comme source de la fenêtre:

  Controller.prototype._parseForURLs = function (text) {
    var re = /(https?:\/\/[^\s"<>,]+)/g;
    return text.replace(re, '<a href="$1" data-src="$1">$1</a>');
  };

  Controller.prototype._doShowUrl = function(e) {
    // only applies to elements with data-src attributes
    if (!e.target.hasAttribute('data-src')) {
      return;
    }
    e.preventDefault();
    var url = e.target.getAttribute('data-src');
    chrome.app.window.create(
     'webview.html',
     {hidden: true},   // only show window when webview is configured
     function(appWin) {
       appWin.contentWindow.addEventListener('DOMContentLoaded',
         function(e) {
           // when window is loaded, set webview source
           var webview = appWin.contentWindow.
                document.querySelector('webview');
           webview.src = url;
           // now we can show it:
           appWin.show();
         }
       );
     });
  };

  // Export to window
  window.app.Controller = Controller;
})(window);

Dans le rappel chrome.app.window.create(), notez comment l'URL de la WebView est définie via la balise src. .

Enfin, ajoutez un écouteur d'événements de clic dans le constructeur Controller pour appeler doShowUrl() lorsqu'une l'utilisateur clique sur un lien:

function Controller(model, view) {
  ...
  this.router = new Router();
  this.router.init();

  this.$todoList.addEventListener('click', this._doShowUrl);

  window.addEventListener('load', function () {
    this._updateFilterState();
  }.bind(this));
  ...
}

Lancer l'application Todo terminée

Vous avez terminé l'étape 4 ! Si vous actualisez votre application et ajoutez une tâche avec une URL complète commençant par http:// ou https://, un résultat semblable au suivant doit s'afficher:

Pour en savoir plus

Pour en savoir plus sur certaines des API présentées lors de cette étape, consultez les pages suivantes:

Prêt à passer à l'étape suivante ? Passez à l'étape 5 : Ajoutez des images depuis le Web »