Paso 4: Abre vínculos externos con una WebView

En este paso, aprenderás lo siguiente:

  • Cómo mostrar contenido web externo dentro de tu app de forma segura y en zona de pruebas

Tiempo estimado para completar este paso: 10 minutos
Para obtener una vista previa de lo que completarás en este paso, ve a la parte inferior de esta página ↓.

Más información sobre la etiqueta de WebView

Algunas aplicaciones deben presentar contenido web externo directamente al usuario, pero mantenerlo dentro del la experiencia en la aplicación. Por ejemplo, un agregador de noticias podría querer incorporar las noticias de fuentes sitios con todo el formato, las imágenes y el comportamiento del sitio original. Para estas y otras usos, las Apps de Chrome tienen una etiqueta HTML personalizada llamada WebView.

La app de tareas pendientes con WebView

Implementa la etiqueta de WebView

Actualiza la app de Tareas pendientes para que busque URLs en el texto del elemento de tareas pendientes y crea un hipervínculo. El vínculo, cuando Si haces clic en este botón, se abre una nueva ventana de la app de Chrome (no una pestaña del navegador) con una WebView que presenta el contenido.

Actualizar permisos

En manifest.json, solicita el permiso webview:

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

Cómo crear una página de incorporaciones de WebView

Crea un archivo nuevo en la raíz de la carpeta de tu proyecto y asígnale el nombre webview.html. Este archivo es un página web básica con una etiqueta <webview>:

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

Cómo analizar URLs en elementos de tareas pendientes

Al final de controller.js, agrega un método nuevo llamado _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);

Cuando una cadena que comienza con “http://” o “https://” , se crea una etiqueta de anclaje HTML para que encierran la URL.

Busca showAll() en controller.js. Actualiza showAll() para analizar vínculos con las El método _parseForURLs() se agregó anteriormente:

/**
 * 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));
};

Haz lo mismo para showActive() y 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));
};

Por último, agrega _parseForURLs() a 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);
  ...
}

Aún en editItem(), corrige el código para que use el innerText de la etiqueta en lugar del innerHTML de la etiqueta:

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;
  ...
}

Abrir una ventana nueva con WebView

Agrega un método _doShowUrl() a controller.js. Este método abre una nueva ventana de la App de Chrome mediante chrome.app.window.create() con webview.html como la fuente de la ventana:

  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);

En la devolución de llamada chrome.app.window.create(), observa cómo la URL de WebView se configura a través de la etiqueta src. e.

Por último, agrega un objeto de escucha de eventos de clic dentro del constructor Controller para llamar a doShowUrl() cuando se genere un evento. un usuario hace clic en un vínculo:

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));
  ...
}

Inicia tu app de tareas pendientes terminada

Has completado el paso 4. Si vuelves a cargar la app y agregas un elemento de tareas pendientes con una URL completa que comienza con http:// o https://, deberías ver algo como esto:

Más información

Para obtener información más detallada sobre algunas de las APIs presentadas en este paso, consulta:

¿Todo listo para continuar con el siguiente paso? Ve al Paso 5: Agrega imágenes de la Web »