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à trong hộp cát.

Thời gian hoàn thành bước này ước tính là 10 phút.
Để xem trước những việc bạn sẽ hoàn thành trong 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ữ nội dung đó trong trải nghiệm ứng dụng. Ví dụ: một trang web 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 bằng tất cả định dạng, hình ảnh và hành vi của trang web gốc. Đối với các mục đích sử dụng này và các mục đích 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 webview

Triển khai thẻ webview

Cập nhật ứng dụng Todo để tìm kiế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 bạn nhấp vào đường liên kết, một cửa sổ Ứng dụng Chrome mới (không phải thẻ trình duyệt) sẽ mở ra với một webview hiển thị nội dung.

Cập nhật quyền

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

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

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

Tạo một tệp mới trong thư mục gốc của dự án và đặt tên 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, hãy 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);

Bất cứ khi nào tìm thấy một chuỗi bắt đầu bằng "http://" hoặc "https://", một thẻ neo HTML sẽ được tạo để bao bọc 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ự cho 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ã để 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ở một cửa sổ Ứng dụng Chrome mới thông qua chrome.app.window.create() với webview.html làm 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 chế độ xem 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 chuột 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 giao diện 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 chuyển sang bước tiếp theo chưa? Chuyển đến Bước 5 – Thêm hình ảnh từ web »