إدارة النوافذ

يدير تطبيق الويب التقدّمي خارج المتصفّح نافذته الخاصة. تعرَّف على واجهات برمجة التطبيقات والإمكانات المتاحة لإدارة نافذة ضمن نظام التشغيل.

يوفّر تشغيل التطبيق في نافذته الخاصة، والتي يديرها تطبيق الويب التقدّمي، كل مزايا ومسؤوليات أي نافذة في نظام التشغيل هذا، مثل:

  • إمكانية نقل النافذة وتغيير حجمها في أنظمة التشغيل التي تتيح استخدام نوافذ متعددة، مثل Windows أو ChromeOS
  • مشاركة الشاشة مع نوافذ تطبيقات أخرى، كما هو الحال في وضع تقسيم الشاشة في iPadOS أو Android
  • الظهور في أشرطة الإرساء وأشرطة المهام وفي قائمة alt-tab على أجهزة الكمبيوتر، وفي قوائم نوافذ المهام المتعددة على الأجهزة الجوّالة
  • القدرة على تصغير النافذة ونقلها بين الشاشات وأجهزة الكمبيوتر المكتبي وإغلاقها في أي وقت

نقل النافذة وتغيير حجمها

يمكن أن يكون حجم نافذة تطبيق الويب التقدّمي أي حجم، ويمكن وضعها في أي مكان على الشاشة على أنظمة تشغيل أجهزة الكمبيوتر. عندما يفتح المستخدم تطبيق الويب التقدّمي للمرة الأولى بعد تثبيته، يحصل تطبيق الويب التقدّمي تلقائيًا على حجم نافذة تلقائي بنسبة مئوية من الشاشة الحالية، وبدقة قصوى تبلغ 1920×1080 بكسل في أعلى يسار الشاشة.

يمكن للمستخدم نقل النافذة وتغيير حجمها، وسيتذكّر المتصفّح آخر إعداد مفضّل. في المرة التالية التي يفتح فيها المستخدم التطبيق، سيحتفظ التطبيق بحجم النافذة وموضعها من الاستخدام السابق.

لا تتوفّر طريقة لتحديد الحجم والموضع المفضّلين لتطبيق الويب التقدّمي ضمن البيان. يمكنك تغيير موضع النافذة وحجمها باستخدام واجهة برمجة التطبيقات JavaScript فقط. من خلال الرمز البرمجي، يمكنك نقل نافذة تطبيق الويب التقدّمي وتغيير حجمها باستخدام الدالتَين moveTo(x, y) و resizeTo(x, y) الخاصتَين بالكائن window.

على سبيل المثال، يمكنك تغيير حجم نافذة تطبيق الويب التقدّمي ونقلها عند تحميل تطبيق الويب التقدّمي باستخدام:

document.addEventListener("DOMContentLoaded", event => {
   // we can move only if we are not in a browser's tab
   isBrowser = matchMedia("(display-mode: browser)").matches;
   if (!isBrowser) {
      window.moveTo(16, 16);
      window.resizeTo(800, 600);
   }
});

يمكنك طلب البحث عن حجم الشاشة وموضعها الحاليَّين باستخدام العنصر window.screen، ويمكنك رصد وقت تغيير حجم النافذة باستخدام الحدث resize من العنصر window. لا يتوفّر حدث لتسجيل عملية نقل النافذة، لذا يمكنك الاستعلام عن الموضع بشكل متكرّر.

بدلاً من نقل النافذة وتغيير حجمها بشكل مطلق، يمكنك نقلها وتغيير حجمها بشكل نسبي باستخدام moveBy() وresizeBy().

تصفُّح مواقع إلكترونية أخرى

إذا أردت توجيه المستخدم إلى موقع إلكتروني خارجي لا يندرج ضمن نطاق تطبيق الويب التقدّمي، يمكنك إجراء ذلك باستخدام عنصر <a href> HTML عادي. استخدِم location.href أو افتح نافذة جديدة على المنصات المتوافقة.

عند الانتقال إلى عنوان URL خارج نطاق ملف البيان، يعرض محرك المتصفح الخاص بتطبيق الويب التقدّمي متصفحًا داخل التطبيق ضمن سياق النافذة.

متصفّح داخل التطبيق على تطبيق PWA متوافق مع الكمبيوتر المكتبي عند تصفّح عنوان URL خارج النطاق

في ما يلي بعض ميزات المتصفّحات داخل التطبيق:

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

أثناء ظهور المتصفّح داخل التطبيق على الشاشة، ينتظر تطبيق الويب التقدّمي في الخلفية، كما لو كانت نافذة أخرى تحجبه.

متصفّح داخل التطبيق على جهاز iPhone عند تصفّح عنوان URL خارج النطاق ضمن تطبيق ويب تقدّمي مستقل
متصفّح داخل التطبيق على Android عند تصفّح عنوان URL خارج النطاق ضمن تطبيق ويب تقدّمي (PWA) مستقل

مسارات التفويض

تتطلّب العديد من عمليات المصادقة والترخيص على الويب إعادة توجيه المستخدم إلى عنوان URL مختلف على مصدر مختلف للحصول على رمز مميّز يعود إلى مصدر تطبيق الويب التقدّمي، كما هو الحال مع OAuth 2.0.

في هذه الحالات، يتّبع المتصفّح داخل التطبيق العملية التالية:

  1. يفتح المستخدم تطبيق الويب التقدّمي وينقر على "تسجيل الدخول".
  2. تعيد تطبيقات الويب التقدّمية (PWA) توجيه المستخدم إلى عنوان URL خارج نطاق تطبيق الويب التقدّمي، ما يؤدي إلى فتح محرك العرض متصفحًا داخل التطبيق ضمن تطبيق الويب التقدّمي.
  3. يمكن للمستخدم إلغاء المتصفّح داخل التطبيق والعودة إلى تطبيق الويب التقدّمي في أي وقت.
  4. يسجّل المستخدم الدخول إلى المتصفّح داخل التطبيق. يعيد خادم المصادقة توجيه المستخدم إلى مصدر تطبيق الويب التقدّمي، ويرسل الرمز المميّز كمعلَمة.
  5. يتم إغلاق المتصفّح داخل التطبيق تلقائيًا عند رصد عنوان URL يندرج ضمن نطاق تطبيق الويب التقدّمي.
  6. يعيد المحرّك توجيه التنقّل في نافذة تطبيق الويب التقدّمي الرئيسية إلى عنوان URL الذي انتقل إليه خادم المصادقة أثناء استخدام المتصفّح داخل التطبيق.
  7. يحصل تطبيق الويب التقدّمي على الرمز المميّز ويخزّنه ويعرضه.

فرض التنقّل في المتصفّح

إذا أردت فرض فتح المتصفّح باستخدام عنوان URL وليس متصفّحًا داخل التطبيق، يمكنك استخدام _blank كهدف لعناصر <a href>. تعمل هذه الميزة على تطبيقات الويب التقدّمية على أجهزة الكمبيوتر فقط. على الأجهزة الجوّالة، لا يتوفّر خيار فتح متصفّح باستخدام عنوان URL.

function openBrowser(url) {
    window.open("url", "_blank", "");
}

فتح نوافذ جديدة

على أجهزة الكمبيوتر، يمكن للمستخدمين فتح أكثر من نافذة واحدة للتطبيق التقدّمي نفسه. تحتوي كل نافذة على عناصر تنقّل مختلفة للرمز start_url نفسه، كما لو كنت تفتح علامتي تبويب في المتصفّح لعنوان URL نفسه. من القائمة في تطبيق الويب التقدّمي، يمكن للمستخدمين النقر على ملف ثم على نافذة جديدة. من خلال رمز تطبيق الويب التقدّمي، يمكنك فتح نافذة جديدة باستخدام الدالة open().

function openNewWindow() {
    window.open("/", "new-window", "width=600,height=600");
}

تطبيق الويب التقدّمي نفسه مثبّتًا مع فتح عدة نوافذ على نظام تشغيل كمبيوتر

عند طلب open() ضمن نافذة تطبيق ويب تقدّمي على iOS أو iPadOS، يتم عرض null ولا يتم فتح نافذة. يؤدي فتح نوافذ جديدة على Android إلى إنشاء متصفّح جديد داخل التطبيق لعنوان URL، حتى إذا كان عنوان URL ضِمن نطاق تطبيق الويب التقدّمي، وهذا لا يؤدي عادةً إلى بدء تجربة تصفّح خارجية.

عنوان النافذة

كان يتم استخدام العنصر <title> في المقام الأول لأغراض تحسين محركات البحث، لأنّ المساحة المتاحة ضمن علامة تبويب المتصفّح محدودة. عند الانتقال من المتصفّح إلى نافذتك في تطبيق ويب تقدّمي، يصبح كل مساحة شريط العناوين متاحة لك.

يمكنك تحديد محتوى شريط العنوان:

  • بشكل ثابت في عنصر <title> في HTML
  • تغيير سمة السلسلة document.title بشكل ديناميكي في أي وقت

في تطبيقات الويب التقدّمية على أجهزة الكمبيوتر، يكون العنوان ضروريًا ويُستخدم في شريط عنوان النافذة، وأحيانًا في &quot;مدير المهام&quot; أو في خيار &quot;تحديد المهام المتعددة&quot;. إذا كان لديك تطبيق من صفحة واحدة، قد تحتاج إلى تعديل العنوان في كل مسار.

وضع التبويب

وضع علامات التبويب هو ميزة تجريبية تتيح لتطبيق الويب التقدّمي (PWA) أن يتضمّن تصميمًا يستند إلى علامات التبويب، على غرار متصفّح الويب. في هذه الحالة، يمكن للمستخدم فتح عدة علامات تبويب في تطبيق الويب التقدّمي نفسه، ولكن يتم ربطها كلها في نافذة نظام التشغيل نفسها.

يمكنك الاطّلاع على مزيد من المعلومات حول هذه الميزة التجريبية في وضع التطبيق ذي علامات التبويب لتطبيقات الويب التقدّمية.

تراكب عناصر التحكّم في النوافذ

لقد ذكرنا أنّه يمكنك تغيير عنوان النافذة من خلال تحديد قيمة العنصر <title> أو السمة document.title. ولكنّها تكون دائمًا قيمة سلسلة. ماذا لو كان بإمكاننا تصميم شريط العنوان باستخدام HTML وCSS والصور؟ قد تساعدك ميزة "تراكب عناصر التحكّم في النافذة"، وهي ميزة تجريبية في Microsoft Edge وGoogle Chrome لتطبيقات الويب التقدّمية على أجهزة الكمبيوتر.

يمكنك الاطّلاع على مزيد من المعلومات حول هذه الإمكانية في مقالة تخصيص طريقة عرض عناصر التحكم في النوافذ على شريط العناوين في تطبيق الويب التقدّمي (PWA).

باستخدام Window Controls Overlay، يمكنك عرض المحتوى في شريط العناوين.

إدارة النوافذ

عند استخدام شاشات متعددة، يريد المستخدمون الاستفادة من كل المساحة المتاحة لهم. على سبيل المثال:

  • يمكن لأدوات تحرير الرسومات المتعددة النوافذ، مثل Gimp، وضع أدوات التحرير المختلفة في نوافذ محددة المواضع بدقة.
  • يمكن أن تعرض منصات التداول الافتراضية مؤشرات السوق في نوافذ متعددة يمكن عرض أي منها في وضع ملء الشاشة.
  • يمكن لتطبيقات العروض التقديمية عرض ملاحظات المحاضر على الشاشة الداخلية الأساسية والعرض التقديمي على جهاز عرض خارجي.

تتيح واجهة برمجة التطبيقات Window Management API لتطبيقات الويب التقدّمية (PWA) تنفيذ ذلك وأكثر.

الحصول على تفاصيل الشاشة

تضيف Window Management API طريقة جديدة، window.getScreenDetails()، تعرض عنصرًا يتضمّن شاشات على شكل مصفوفة غير قابلة للتغيير من الشاشات المرفقة. يتوفّر أيضًا عنصر نشط يمكن الوصول إليه من ScreenDetails.currentScreen، وهو يتوافق مع window.screen الحالي.

يُطلق العنصر الذي تم إرجاعه أيضًا حدث screenschange عند تغيير مصفوفة screens. (لا يحدث ذلك عند تغيير السمات على شاشات فردية). تعرض الشاشات الفردية، سواء window.screen أو شاشة في مصفوفة screens، أيضًا حدث change عند تغيير سماتها.

// Request an object with a screen objects
const screenDetails = await window.getScreenDetails();
screenDetails.screens[0].isPrimary;  // e.g. true
screenDetails.screens[0].isInternal;  // e.g. true
screenDetails.screens[0].label;  // e.g. 'Samsung Electric Company 28"'

// Access the live object corresponding to the current `window.screen`.
// The object is updated on cross-screen window placements or device changes.
screenDetails.currentScreen;
screenDetails.addEventListener('screenschange', function() {
 // NOTE: Does not fire on changes to attributes of individual screens.
  const screenCount = screenDetails.screens.length;
  const currentScreen screenDetails.currentScreen.id;
});

إذا نقل المستخدم أو نظام التشغيل نافذة تطبيق الويب التقدّمي من شاشة إلى أخرى، سيتم أيضًا تنشيط حدث currentscreenchange من عنصر تفاصيل الشاشة.

عملية قفل تنشيط الشاشة

تخيَّل هذا. أنت في المطبخ وتتّبع وصفة طعام على جهازك اللوحي. لقد انتهيت للتو من تحضير المكوّنات. يديك متسختان، وتعود إلى جهازك لقراءة الخطوة التالية. كارثة! الشاشة سوداء! توفّر لك Screen Wake Lock API إمكانية منع تطبيقات الويب التقدّمية من تعتيم الشاشات أو وضعها في وضع السكون أو قفلها، ما يتيح للمستخدمين إيقاف المحتوى وبدءه ومغادرته والرجوع إليه بدون قلق.

// Request a screen wake lock
const wakeLock = await navigator.wakeLock.request();

// Listen for wake lock release
wakeLock.addEventListener('release', () => {
 console.log(`Screen Wake Lock released: ${wakeLock.released}`);
});
// Manually release the wake lock
wakeLock.release();

لوحة المفاتيح الافتراضية

توفّر الأجهزة التي تعمل باللمس، مثل الهواتف والأجهزة اللوحية، لوحة مفاتيح افتراضية على الشاشة ليتمكّن المستخدم من الكتابة عندما تكون عناصر النموذج في تطبيق الويب التقدّمي قيد التركيز.

باستخدام VirtualKeyboard API، يمكن لتطبيق PWA التحكّم بشكل أكبر في لوحة المفاتيح على المنصات المتوافقة باستخدام واجهة navigator.virtualKeyboard.

  • إظهار لوحة المفاتيح الافتراضية وإخفاؤها باستخدام navigator.virtualKeyboard.show() وnavigator.virtualKeyboard.hide()
  • أخبِر المتصفّح بأنّك ستغلق لوحة المفاتيح الافتراضية بنفسك من خلال ضبط قيمة navigator.virtualKeyboard.overlaysContent على true.
  • يمكنك معرفة وقت ظهور لوحة المفاتيح واختفائها باستخدام حدث geometrychange.
  • اضبط سياسة لوحة المفاتيح الافتراضية على تعديل عناصر المضيف من خلال ضبط contenteditable على auto أو manual، باستخدام سمة virtualkeyboardpolicy HTML. تتيح لك السياسة تحديد ما إذا كنت تريد أن يتولّى المتصفّح (auto) معالجة لوحة المفاتيح الافتراضية تلقائيًا أو أن يتولّى النص البرمجي (manual) معالجتها.
  • استخدِم متغيّرات بيئة CSS للحصول على معلومات حول مظهر لوحة المفاتيح الافتراضية، مثل keyboard-inset-height وkeyboard-inset-top.

يمكنك الاطّلاع على مزيد من المعلومات حول واجهة برمجة التطبيقات هذه في مقالة التحكّم الكامل باستخدام VirtualKeyboard API.