الخطوة 4: فتح الروابط الخارجية باستخدام WebView

في هذه الخطوة، ستتعرف على:

  • كيفية عرض محتوى الويب الخارجي داخل تطبيقك بطريقة آمنة وفي وضع الحماية

الوقت المقدّر لإكمال هذه الخطوة: 10 دقائق.
لمعاينة ما ستُكمله في هذه الخطوة، انتقِل إلى أسفل هذه الصفحة ↓.

مزيد من المعلومات عن علامة WebView

تحتاج بعض التطبيقات إلى تقديم محتوى ويب خارجي إلى المستخدم مباشرةً مع إبقائه ضمن تجربة المستخدم. على سبيل المثال، قد يرغب موقع تجميع الأخبار في تضمين الأخبار من مصادر خارجية المواقع التي تحتوي على جميع تنسيقات الموقع الأصلي وصوره وسلوكه. بالنسبة إلى هذه العناصر وغيرها الخاص بك، تشتمل تطبيقات Chrome على علامة HTML مخصصة تسمى webview.

تطبيق Todo باستخدام webview

تنفيذ علامة webview

حدِّث تطبيق Todo للبحث عن عناوين URL في نص عنصر المهام وإنشاء رابط تشعّبي. الرابط، عندما يؤدي النقر عليها إلى فتح نافذة جديدة لتطبيق Chrome (وليس علامة تبويب متصفّح) مع WebView يعرض المحتوى.

تحديث الأذونات

في ملف manifest.json، اطلب إذن webview على النحو التالي:

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

إنشاء صفحة مضمّن في WebView

أنشئ ملفًا جديدًا في جذر مجلد المشروع وأدخِل اسمًا له webview.html. هذا الملف عبارة عن صفحة ويب أساسية بعلامة <webview> واحدة:

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

تحليل عناوين URL في عناصر المهام

في نهاية controller.js، أضف طريقة جديدة باسم _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);

عندما تبدأ سلسلة بـ "http:// " أو "https:// " فسيتم إنشاء علامة ارتساء HTML التفاف حول عنوان URL.

ابحث عن showAll() في controller.js. عدِّل showAll() لتحليل الروابط باستخدام طريقة _parseForURLs() التي تمت إضافتها سابقًا:

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

نفِّذ الإجراء نفسه مع 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));
};

وأخيرًا، إضافة _parseForURLs() إلى 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);
  ...
}

لا تزال في اللغة editItem()، أصلح الرمز بحيث يستخدم innerText للتصنيف بدلاً من innerHTML للتصنيف:

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

فتح نافذة جديدة تحتوي على WebView

أضِف طريقة _doShowUrl() إلى controller.js. تفتح هذه الطريقة نافذة جديدة لتطبيق Chrome عبر chrome.app.window.create() باستخدام webview.html كمصدر النافذة:

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

في معاودة الاتصال chrome.app.window.create()، لاحظ كيفية ضبط عنوان URL لـ webview باستخدام علامة src .

أخيرًا، يمكنك إضافة أداة معالجة أحداث النقر داخل الدالة الإنشائية Controller لطلب doShowUrl() عند ينقر المستخدم على رابط:

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

فتح تطبيق Todo المكتمل

لقد انتهيت من الخطوة 4! في حال إعادة تحميل التطبيق وإضافة عنصر مهام بعنوان URL كامل يبدأ بـ http:// أو https:// .

لمزيد من المعلومات

لمزيد من المعلومات التفصيلية حول بعض واجهات برمجة التطبيقات التي تم تقديمها في هذه الخطوة، راجع:

هل أنت مستعد للانتقال إلى الخطوة التالية؟ انتقل إلى الخطوة 5 - إضافة صور من الويب »