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, desplázate hasta 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 de la experiencia de la aplicación. Por ejemplo, un agregador de noticias puede querer incorporar las noticias de sitios externos con todo el formato, las imágenes y el comportamiento del sitio original. Para estos y otros usos, las Apps de Chrome tienen una etiqueta HTML personalizada llamada webview.
Implementa la etiqueta de WebView
Actualiza la app de Todo para buscar URLs en el texto de la tarea y crear un hipervínculo. Cuando se hace clic en el vínculo, se abre una nueva ventana de la app de Chrome (no una pestaña del navegador) con una vista web que presenta el contenido.
Actualizar permisos
En manifest.json, solicita el permiso webview
:
"permissions": [
"storage",
"alarms",
"notifications",
"webview"
],
Crea una página de incorporación 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 una 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>
Analiza las URLs en los 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);
Cada vez que se encuentra una cadena que comienza con "http://" o "https://", se crea una etiqueta de anclaje HTML para unir la URL.
Renderiza hipervínculos en la lista de tareas pendientes
Busca showAll()
en controller.js. Actualiza showAll()
para analizar vínculos con el método _parseForURLs()
que agregaste 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;
...
}
Abre una ventana nueva que contenga WebView.
Agrega un método _doShowUrl()
a controller.js. Este método abre una nueva ventana de la app de Chrome a través de 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 de chrome.app.window.create()
, observa cómo se establece la URL del WebView a través del atributo de etiqueta src
.
Por último, agrega un objeto de escucha de eventos de clic dentro del constructor Controller
para llamar a doShowUrl()
cuando un usuario haga 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
Completaste el paso 4. Si vuelves a cargar la app y agregas una tarea con una URL completa que comienza con http:// o https://, deberías ver algo similar a lo siguiente:
Más información
Para obtener información más detallada sobre algunas de las APIs que se presentan en este paso, consulta los siguientes recursos:
¿Todo listo para continuar con el siguiente paso? Ve al Paso 5: Agrega imágenes de la Web »