Passaggio 4: apri i link esterni con un componente WebView

In questo passaggio, scoprirai:

  • Come mostrare contenuti web esterni all'interno dell'app in modo sicuro e con sandbox.

Tempo stimato per completare questo passaggio: 10 minuti.
Per visualizzare l'anteprima di ciò che completerai in questo passaggio, vai alla fine di questa pagina ↓.

Scopri di più sul tag WebView

Alcune applicazioni devono presentare i contenuti web esterni direttamente all'utente, ma mantenerli all'interno un'esperienza d'uso generale. Ad esempio, un aggregatore di notizie potrebbe voler incorporare le notizie provenienti da fonti esterne. siti con la formattazione, le immagini e il comportamento del sito originale. Per questi e altri , le app di Chrome hanno un tag HTML personalizzato chiamato webview.

App Todo con una WebView

Implementare il tag WebView

Aggiorna l'app Da fare per cercare URL nel testo dell'elemento da fare e creare un link ipertestuale. Il link, quando selezionato, si apre una nuova finestra dell'app Chrome (non una scheda del browser) con una WebView in cui vengono presentati i contenuti.

Aggiorna autorizzazioni

In manifest.json, richiedi l'autorizzazione webview:

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

Crea una pagina di incorporamento di WebView

Crea un nuovo file nella radice della cartella del progetto e denominalo webview.html. Questo file è un pagina web di base con un tag <webview>:

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

Analizza gli URL negli elementi di promemoria

Alla fine di controller.js, aggiungi un nuovo metodo chiamato _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);

Ogni volta che una stringa che inizia con "http://" o "https://" viene trovato, viene creato un anchor tag HTML intorno all'URL.

Trova showAll() in controller.js. Aggiorna showAll() per analizzare i link utilizzando la proprietà _parseForURLs() metodo aggiunto in precedenza:

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

Fai lo stesso per showActive() e 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));
};

Infine, aggiungi _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);
  ...
}

Sempre in editItem(), correggi il codice in modo che utilizzi il innerText dell'etichetta al posto della innerHTML dell'etichetta:

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

Apri una nuova finestra contenente WebView

Aggiungi un metodo _doShowUrl() a controller.js. Questo metodo apre una nuova finestra dell'app Chrome tramite chrome.app.window.create() con webview.html come origine della finestra:

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

Nel callback chrome.app.window.create(), nota come viene impostato l'URL di WebView tramite il tag src. .

Infine, aggiungi un listener di eventi di clic all'interno del costruttore Controller per chiamare doShowUrl() quando una l'utente fa clic su un link:

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

Lancia l'app delle cose da fare completata

Hai completato il passaggio 4. Se ricarichi l'app e aggiungi un'attività con un URL completo che inizia con http:// o https://, il codice dovrebbe essere simile al seguente:

Per maggiori informazioni

Per informazioni più dettagliate su alcune delle API introdotte in questo passaggio, fai riferimento a:

Vuoi andare al passaggio successivo? Vai al Passaggio 5 - Aggiungi immagini dal Web »