Bước 4: Mở đường liên kết ngoài bằng WebView

Trong bước này, bạn sẽ tìm hiểu:

  • Cách hiển thị nội dung web bên ngoài bên trong ứng dụng của bạn một cách an toàn và có hộp cát.

Thời gian ước tính để hoàn tất bước này: 10 phút.
Để xem trước những nội dung bạn sẽ hoàn tất ở bước này, hãy chuyển xuống cuối trang này ↓.

Tìm hiểu về thẻ WebView

Một số ứng dụng cần hiển thị nội dung web bên ngoài trực tiếp cho người dùng nhưng vẫn giữ chúng bên trong trải nghiệm ứng dụng. Ví dụ: một đơn vị tổng hợp tin tức có thể muốn nhúng tin tức từ các trang web bên ngoài với tất cả định dạng, hình ảnh và hành vi của trang web gốc. Đối với các trường hợp sử dụng này và các trường hợp sử dụng khác, Ứng dụng Chrome có một thẻ HTML tuỳ chỉnh có tên là webview.

Ứng dụng Todo sử dụng chế độ xem web

Triển khai thẻ WebView

Cập nhật ứng dụng Việc cần làm để tìm URL trong văn bản của mục việc cần làm và tạo siêu liên kết. Khi được nhấp vào, đường liên kết này sẽ mở ra một cửa sổ Ứng dụng Chrome mới (không phải thẻ trình duyệt) với chế độ xem web trình bày nội dung.

Cập nhật quyền

Trong tệp manifest.json, hãy yêu cầu quyền webview:

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

Tạo trang trình nhúng chế độ xem web

Tạo một tệp mới trong thư mục gốc của thư mục dự án và đặt tên tệp là webview.html. Tệp này là một trang web cơ bản có một thẻ <webview>:

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

Phân tích cú pháp URL trong các mục việc cần làm

Ở cuối controller.js, thêm một phương thức mới có tên là _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);

Mỗi khi tìm thấy một chuỗi bắt đầu bằng "http://" hoặc "https://", một thẻ ký tự liên kết HTML sẽ được tạo để bao quanh URL.

Tìm showAll() trong controller.js. Cập nhật showAll() để phân tích cú pháp các đường liên kết bằng cách sử dụng phương thức _parseForURLs() đã thêm trước đó:

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

Làm tương tự đối với showActive()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));
};

Cuối cùng, hãy thêm _parseForURLs() vào 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);
  ...
}

Vẫn trong editItem(), hãy sửa mã để sử dụng innerText của nhãn thay vì innerHTML của nhãn:

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

Mở cửa sổ mới chứa webview

Thêm phương thức _doShowUrl() vào controller.js. Phương thức này mở ra một cửa sổ Ứng dụng Chrome mới thông qua chrome.app.window.create(), trong đó webview.html là nguồn cửa sổ:

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

Trong lệnh gọi lại chrome.app.window.create(), hãy lưu ý cách đặt URL của khung hiển thị web thông qua thuộc tính thẻ src.

Cuối cùng, hãy thêm trình nghe sự kiện nhấp vào bên trong hàm khởi tạo Controller để gọi doShowUrl() khi người dùng nhấp vào một đường liên kết:

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

Chạy ứng dụng Todo đã hoàn thiện

Bạn đã hoàn tất Bước 4! Nếu tải lại ứng dụng và thêm một mục việc cần làm có URL đầy đủ bắt đầu bằng http:// hoặc https://, bạn sẽ thấy nội dung như sau:

Thông tin khác

Để biết thêm thông tin chi tiết về một số API được giới thiệu trong bước này, hãy tham khảo:

Bạn đã sẵn sàng để tiếp tục bước tiếp theo? Chuyển tới Bước 5 – Thêm hình ảnh từ web »