1. مقدمة والإعداد
إمكانات الويب
نريد سد فجوة الإمكانات بين الويب والتطبيقات الأصلية وتسهيل مهمة المطوّرين في إنشاء تجارب رائعة على الويب المفتوح. نحن نؤمن بشدة بأنّه يجب أن يتمكّن كل مطوّر من الوصول إلى الإمكانات التي يحتاج إليها لتقديم تجربة رائعة على الويب، ونحن ملتزمون بتوفير ويب أكثر فعالية.
ومع ذلك، تتوفّر بعض الإمكانات، مثل الوصول إلى نظام الملفات ورصد عدم النشاط، في التطبيقات الأصلية ولكنّها غير متاحة على الويب. ويعني عدم توفّر هذه الإمكانات أنّه لا يمكن عرض بعض أنواع التطبيقات على الويب، أو أنّها أقل فائدة.
سنصمّم هذه الإمكانات الجديدة ونطوّرها بطريقة مفتوحة وشفافة، وذلك باستخدام العمليات الحالية لمعايير المنصة المفتوحة على الويب، مع الحصول على ملاحظات مبكرة من المطوّرين ومورّدي المتصفحات الآخرين أثناء تكرار عملية التصميم، وذلك لضمان تصميم قابل للتشغيل التفاعلي.
ما ستنشئه
في هذا الدرس العملي، ستتعرّف على عدد من واجهات برمجة التطبيقات الجديدة أو المتاحة فقط من خلال علامة. لذلك، يركّز هذا الدرس التطبيقي على واجهات برمجة التطبيقات نفسها وعلى حالات الاستخدام التي تتيحها هذه الواجهات، بدلاً من التركيز على إنشاء منتج نهائي محدّد.
ما ستتعلمه
سيعلّمك هذا الدرس التطبيقي حول الترميز الآليات الأساسية للعديد من واجهات برمجة التطبيقات الحديثة. يُرجى العِلم أنّ هذه الآليات ليست نهائية بعد، ونقدّر كثيرًا ملاحظاتك حول مسار المطوّر.
المتطلبات
بما أنّ واجهات برمجة التطبيقات المعروضة في هذا الدرس التطبيقي حول الترميز هي في الواقع في مرحلة التطوير المتقدّمة، تختلف متطلبات كل واجهة برمجة تطبيقات. يُرجى الحرص على قراءة معلومات التوافق في بداية كل قسم بعناية.
كيفية الاستفادة من جلسة التدريب العملي
ليس من الضروري إكمال هذا الدرس التطبيقي العملي بالتسلسل. يمثّل كل قسم واجهة برمجة تطبيقات مستقلة، لذا يمكنك الاختيار الدقيق لما يهمّك أكثر.
2. Badging API
تهدف Badging API إلى لفت انتباه المستخدمين إلى الأحداث التي تجري في الخلفية. لتبسيط العرض التوضيحي في هذا الدرس العملي، لنستخدِم واجهة برمجة التطبيقات لجذب انتباه المستخدمين إلى حدث يقع في المقدّمة. يمكنك بعد ذلك إجراء عملية النقل الذهني إلى الأشياء التي تحدث في الخلفية.
تثبيت تطبيق Airhorner
لكي تعمل واجهة برمجة التطبيقات هذه، تحتاج إلى تثبيت تطبيق ويب تقدّمي على الشاشة الرئيسية، لذا فإنّ الخطوة الأولى هي تثبيت تطبيق ويب تقدّمي، مثل airhorner.com الشهير. انقر على الزر تثبيت في أعلى يسار الصفحة أو استخدِم قائمة النقاط الثلاث لتثبيت التطبيق يدويًا.

سيؤدي ذلك إلى ظهور رسالة تأكيد، انقر على تثبيت.

يظهر الآن رمز جديد في شريط التطبيقات بنظام التشغيل. انقر عليه لتشغيل تطبيق الويب التقدّمي. سيكون له نافذة تطبيق خاصة وسيتم تشغيله في وضع التطبيق المستقل.
|
|
ضبط شارة
بعد تثبيت تطبيق ويب تقدّمي، تحتاج إلى بعض البيانات الرقمية (يمكن أن تحتوي الشارات على أرقام فقط) لعرضها على شارة. أحد الأمور الواضحة التي يمكن احتسابها في تطبيق The Air Horner هو، تنهيدة، عدد المرات التي تم فيها استخدام البوق. في الواقع، بعد تثبيت تطبيق Airhorner، جرِّب إطلاق صوت البوق وتحقَّق من الشارة. ويتم احتساب نقطة واحدة في كل مرة تستخدم فيها البوق.

كيف تعمل هذه الميزة؟ في الأساس، تكون التعليمة البرمجية على النحو التالي:
let hornCounter = 0;
const horn = document.querySelector('.horn');
horn.addEventListener('click', () => {
navigator.setExperimentalAppBadge(++hornCounter);
});
أطلِق صوت البوق عدة مرات وتحقّق من رمز تطبيق الويب التقدّمي: سيتم تحديثه في كل مرة يُسمع فيها صوت البوق. الأمر بهذه البساطة.

محو شارة
يصل العداد إلى 99 ثم يبدأ من جديد. يمكنك أيضًا إعادة ضبطه يدويًا. افتح علامة التبويب "وحدة التحكّم" في "أدوات مطوّري البرامج"، والصق السطر أدناه، ثم اضغط على Enter.
navigator.setExperimentalAppBadge(0);
بدلاً من ذلك، يمكنك أيضًا إزالة الشارة من خلال محوها بشكل صريح كما هو موضّح في المقتطف التالي. من المفترض أن يظهر رمز تطبيق الويب التقدّمي (PWA) الآن مرة أخرى كما كان في البداية، أي واضحًا وبدون شارة.
navigator.clearExperimentalAppBadge();

الملاحظات
ما رأيك في واجهة برمجة التطبيقات هذه؟ يُرجى مساعدتنا من خلال الردّ باختصار على هذا الاستطلاع:
هل كان استخدام واجهة برمجة التطبيقات هذه سهلاً؟
هل تمكّنت من تشغيل المثال؟
هل لديك المزيد من الملاحظات؟ هل كانت هناك ميزات مفقودة؟ يُرجى تقديم ملاحظات سريعة في هذا الاستطلاع. شكرًا
3- Native File System API
تتيح واجهة Native File System API للمطوّرين إنشاء تطبيقات ويب فعّالة تتفاعل مع الملفات على جهاز المستخدم المحلي. بعد أن يمنح المستخدم تطبيق ويب إذن الوصول، تتيح واجهة برمجة التطبيقات هذه لتطبيقات الويب قراءة التغييرات أو حفظها مباشرةً في الملفات والمجلدات على جهاز المستخدم.
قراءة ملف
تتمثّل الخطوة الأولى في استخدام Native File System API في قراءة ملف محلي والحصول على محتواه. أنشئ ملفًا عاديًا .txt وأدخِل بعض النصوص. بعد ذلك، انتقِل إلى أي موقع إلكتروني آمن (أي موقع إلكتروني معروض عبر HTTPS) مثل example.com وافتح وحدة تحكّم "أدوات مطوّري البرامج". ألصِق مقتطف الرمز أدناه في وحدة التحكّم. بما أنّ واجهة Native File System API تتطلّب إجراءً من المستخدم، فإنّنا نرفق معالجًا للنقر المزدوج بالمستند. سنحتاج إلى معرّف الملف لاحقًا، لذا سنحوّله إلى متغير عام.
document.ondblclick = async () => {
window.handle = await window.chooseFileSystemEntries();
const file = await handle.getFile();
document.body.textContent = await file.text();
};

عند النقر مرّتين على أي مكان في صفحة example.com، سيظهر أداة اختيار الملفات.

اختَر ملف .txt الذي أنشأته سابقًا. سيتم بعد ذلك استبدال محتوى body الفعلي في example.com بمحتوى الملف.

حفظ ملف
بعد ذلك، نريد إجراء بعض التغييرات. لذلك، لنعدّل body من خلال لصق مقتطف الرمز البرمجي أدناه. يمكنك الآن تعديل النص كما لو كان المتصفّح محرّر نصوص.
document.body.contentEditable = true;

الآن، نريد إعادة كتابة هذه التغييرات في الملف الأصلي. لذلك، نحتاج إلى برنامج كتابة على معرّف الملف، ويمكننا الحصول عليه من خلال لصق المقتطف أدناه في وحدة التحكّم. مرة أخرى، نحتاج إلى إيماءة مستخدم، لذا ننتظر هذه المرة نقرة على المستند الرئيسي.
document.onclick = async () => {
const writer = await handle.createWriter();
await writer.truncate(0);
await writer.write(0, document.body.textContent);
await writer.close();
};

عند النقر الآن (وليس النقر المزدوج) على المستند، ستظهر رسالة تطلب منك منح الإذن. عند منح الإذن، سيكون محتوى الملف هو أي محتوى عدّلته في body من قبل. تحقَّق من التغييرات عن طريق فتح الملف في محرر مختلف (أو ابدأ العملية مرة أخرى بالنقر المزدوج على المستند ثم إعادة فتح الملف).


تهانينا! لقد أنشأت للتو أصغر محرّر نصوص في العالم [citation needed].
الملاحظات
ما رأيك في واجهة برمجة التطبيقات هذه؟ يُرجى مساعدتنا من خلال الردّ باختصار على هذا الاستطلاع:
هل كان استخدام واجهة برمجة التطبيقات هذه سهلاً؟
هل تمكّنت من تشغيل المثال؟
هل لديك المزيد من الملاحظات؟ هل كانت هناك ميزات مفقودة؟ يُرجى تقديم ملاحظات سريعة في هذا الاستطلاع. شكرًا
4. Shape Detection API
توفّر واجهة برمجة التطبيقات Shape Detection API إمكانية الوصول إلى أدوات رصد الأشكال السريعة (مثل وجوه الأشخاص) وتعمل على الصور الثابتة و/أو خلاصات الصور المباشرة. تتضمّن أنظمة التشغيل أدوات رصد ميزات عالية الأداء ومحسّنة بشكل كبير، مثل FaceDetector في Android. تتيح واجهة برمجة التطبيقات Shape Detection API عمليات التنفيذ الأصلية هذه وتعرضها من خلال مجموعة من واجهات JavaScript.
في الوقت الحالي، تشمل الميزات المتوافقة التعرّف على الوجوه من خلال واجهة FaceDetector، والتعرّف على الرموز الشريطية من خلال واجهة BarcodeDetector، والتعرّف على النصوص (التعرّف الضوئي على الحروف) من خلال واجهة TextDetector.
التعرّف على الوجوه
من الميزات الرائعة في Shape Detection API ميزة التعرّف على الوجوه. لاختبار هذه الميزة، نحتاج إلى صفحة تتضمّن وجوهًا. هذه الصفحة التي تعرض صورة المؤلف هي بداية جيدة. سيظهر بالشكل الموضّح في لقطة الشاشة أدناه. في متصفّح متوافق، سيتم التعرّف على المربّع المحيط بالوجه وعلامات الوجه.
يمكنك الاطّلاع على مقدار الرمز الصغير الذي كان مطلوبًا لتنفيذ ذلك من خلال إعادة مزج مشروع Glitch أو تعديله، خاصةً ملف script.js.

إذا أردت استخدام ميزة ديناميكية بالكامل وليس فقط وجه المؤلف، انتقِل إلى صفحة نتائج البحث على Google هذه المليئة بالوجوه في علامة تبويب خاصة أو في وضع الضيف. الآن، في تلك الصفحة، افتح "أدوات مطوّري برامج Chrome" من خلال النقر بزر الماوس الأيمن في أي مكان ثم النقر على فحص. بعد ذلك، في علامة التبويب "وحدة التحكّم"، الصِق المقتطف أدناه. ستعمل التعليمة البرمجية على تمييز الوجوه التي تم رصدها بمربّع أحمر شبه شفاف.
document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
try {
const faces = await new FaceDetector().detect(img);
faces.forEach(face => {
const div = document.createElement('div');
const box = face.boundingBox;
const computedStyle = getComputedStyle(img);
const [top, right, bottom, left] = [
computedStyle.marginTop,
computedStyle.marginRight,
computedStyle.marginBottom,
computedStyle.marginLeft
].map(m => parseInt(m, 10));
const scaleX = img.width / img.naturalWidth;
const scaleY = img.height / img.naturalHeight;
div.style.backgroundColor = 'rgba(255, 0, 0, 0.5)';
div.style.position = 'absolute';
div.style.top = `${scaleY * box.top + top}px`;
div.style.left = `${scaleX * box.left + left}px`;
div.style.width = `${scaleX * box.width}px`;
div.style.height = `${scaleY * box.height}px`;
img.before(div);
});
} catch(e) {
console.error(e);
}
});
ستلاحظ ظهور بعض الرسائل DOMException، وعدم معالجة جميع الصور. يرجع ذلك إلى أنّ الصور في الجزء الظاهر من الصفحة مضمّنة كمعرّفات URI خاصة بالبيانات، وبالتالي يمكن الوصول إليها، في حين أنّ الصور في الجزء غير الظاهر من الصفحة تأتي من نطاق مختلف لم يتم إعداده لدعم CORS. لأغراض العرض التوضيحي، لا داعي للقلق بشأن ذلك.
رصد مواضع الوجه
بالإضافة إلى الوجوه فقط، يتيح نظام التشغيل macOS أيضًا رصد معالم الوجه. لاختبار رصد معالم الوجه، الصِق المقتطف التالي في "وحدة التحكّم". تذكير: لا يمكننا ضمان دقة ترتيب المعالم بسبب الخطأ crbug.com/914348، ولكن يمكنك الاطّلاع على الهدف من هذه الميزة ومدى فعاليتها.
document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
try {
const faces = await new FaceDetector().detect(img);
faces.forEach(face => {
const div = document.createElement('div');
const box = face.boundingBox;
const computedStyle = getComputedStyle(img);
const [top, right, bottom, left] = [
computedStyle.marginTop,
computedStyle.marginRight,
computedStyle.marginBottom,
computedStyle.marginLeft
].map(m => parseInt(m, 10));
const scaleX = img.width / img.naturalWidth;
const scaleY = img.height / img.naturalHeight;
div.style.backgroundColor = 'rgba(255, 0, 0, 0.5)';
div.style.position = 'absolute';
div.style.top = `${scaleY * box.top + top}px`;
div.style.left = `${scaleX * box.left + left}px`;
div.style.width = `${scaleX * box.width}px`;
div.style.height = `${scaleY * box.height}px`;
img.before(div);
const landmarkSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
landmarkSVG.style.position = 'absolute';
landmarkSVG.classList.add('landmarks');
landmarkSVG.setAttribute('viewBox', `0 0 ${img.width} ${img.height}`);
landmarkSVG.style.width = `${img.width}px`;
landmarkSVG.style.height = `${img.height}px`;
face.landmarks.map((landmark) => {
landmarkSVG.innerHTML += `<polygon class="landmark-${landmark.type}" points="${
landmark.locations.map((point) => {
return `${scaleX * point.x},${scaleY * point.y} `;
}).join(' ')
}" /></svg>`;
});
div.before(landmarkSVG);
});
} catch(e) {
console.error(e);
}
});
رصد الرموز الشريطية
الميزة الثانية في Shape Detection API هي رصد الرموز الشريطية. كما في السابق، نحتاج إلى صفحة تتضمّن رموزًا شريطية، مثل هذه الصفحة. عند فتحها في متصفّح، ستظهر رموز الاستجابة السريعة المختلفة التي تم فك تشفيرها. يمكنك إنشاء ريمكس أو تعديل مشروع Glitch، خاصةً ملف script.js، لمعرفة كيفية تنفيذ ذلك.

إذا كنت تريد شيئًا أكثر ديناميكية، يمكننا استخدام "بحث صور Google" مرة أخرى. في هذه المرة، انتقِل في المتصفّح إلى صفحة نتائج البحث هذه على Google في علامة تبويب خاصة أو في وضع الضيف. الآن، الصِق المقتطف أدناه في علامة التبويب "وحدة تحكّم أدوات مطوّري البرامج في Chrome". بعد لحظات قليلة، ستتم إضافة تعليقات توضيحية إلى الرموز الشريطية التي تم التعرّف عليها تتضمّن القيمة الأولية ونوع الرمز الشريطي.
document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
try {
const barcodes = await new BarcodeDetector().detect(img);
barcodes.forEach(barcode => {
const div = document.createElement('div');
const box = barcode.boundingBox;
const computedStyle = getComputedStyle(img);
const [top, right, bottom, left] = [
computedStyle.marginTop,
computedStyle.marginRight,
computedStyle.marginBottom,
computedStyle.marginLeft
].map(m => parseInt(m, 10));
const scaleX = img.width / img.naturalWidth;
const scaleY = img.height / img.naturalHeight;
div.style.backgroundColor = 'rgba(255, 255, 255, 0.75)';
div.style.position = 'absolute';
div.style.top = `${scaleY * box.top + top}px`;
div.style.left = `${scaleX * box.left - left}px`;
div.style.width = `${scaleX * box.width}px`;
div.style.height = `${scaleY * box.height}px`;
div.style.color = 'black';
div.style.fontSize = '14px';
div.textContent = `${barcode.rawValue}`;
img.before(div);
});
} catch(e) {
console.error(e);
}
});
رصد النص
الميزة الأخيرة في Shape Detection API هي رصد النصوص. أنت على دراية بالخطوات المطلوبة: نحتاج إلى صفحة تتضمّن صورًا تحتوي على نص، مثل هذه الصفحة التي تعرض نتائج عمليات المسح الضوئي في "كتب Google". في المتصفحات المتوافقة، سيظهر النص الذي تم التعرّف عليه وسيتم رسم مربّع إحاطة حول مقاطع النص. يمكنك إنشاء ريمكس أو تعديل مشروع Glitch، خاصةً ملف script.js، لمعرفة كيفية تنفيذ ذلك.

لاختبار ذلك بشكلٍ ديناميكي، انتقِل إلى صفحة نتائج البحث هذه في علامة تبويب خاصة أو في وضع الضيف. الآن، الصِق المقتطف أدناه في علامة التبويب "وحدة تحكّم أدوات مطوّري البرامج في Chrome". بعد الانتظار قليلاً، سيتم التعرّف على بعض النص.
document.querySelectorAll('img[alt]:not([alt=""])').forEach(async (img) => {
try {
const texts = await new TextDetector().detect(img);
texts.forEach(text => {
const div = document.createElement('div');
const box = text.boundingBox;
const computedStyle = getComputedStyle(img);
const [top, right, bottom, left] = [
computedStyle.marginTop,
computedStyle.marginRight,
computedStyle.marginBottom,
computedStyle.marginLeft
].map(m => parseInt(m, 10));
const scaleX = img.width / img.naturalWidth;
const scaleY = img.height / img.naturalHeight;
div.style.backgroundColor = 'rgba(255, 255, 255, 0.75)';
div.style.position = 'absolute';
div.style.top = `${scaleY * box.top + top}px`;
div.style.left = `${scaleX * box.left - left}px`;
div.style.width = `${scaleX * box.width}px`;
div.style.height = `${scaleY * box.height}px`;
div.style.color = 'black';
div.style.fontSize = '14px';
div.innerHTML = text.rawValue;
img.before(div);
});
} catch(e) {
console.error(e);
}
});
الملاحظات
ما رأيك في واجهة برمجة التطبيقات هذه؟ يُرجى مساعدتنا من خلال الردّ باختصار على هذا الاستطلاع:
هل كان استخدام واجهة برمجة التطبيقات هذه سهلاً؟
هل تمكّنت من تشغيل المثال؟
هل لديك المزيد من الملاحظات؟ هل كانت هناك ميزات مفقودة؟ يُرجى تقديم ملاحظات سريعة في هذا الاستطلاع. شكرًا
5- Web Share Target API
تتيح Web Share Target API لتطبيقات الويب المثبَّتة التسجيل في نظام التشغيل الأساسي كهدف مشاركة لتلقّي المحتوى المشترَك من Web Share API أو أحداث النظام، مثل زر المشاركة على مستوى نظام التشغيل.
تثبيت تطبيق ويب تقدّمي (PWA) للمشاركة فيه
في الخطوة الأولى، تحتاج إلى تطبيق ويب تقدّمي يمكنك مشاركته. في هذه الحالة، لن يفي تطبيق Airhorner بالغرض (لحسن الحظ)، ولكن تطبيق Web Share Target التجريبي سيساعدك. ثبِّت التطبيق على الشاشة الرئيسية لجهازك.

مشاركة محتوى مع تطبيق الويب التقدّمي
بعد ذلك، تحتاج إلى محتوى لمشاركته، مثل صورة من "صور Google". استخدِم زر المشاركة واختَر تطبيق Scrapbook كهدف للمشاركة.

عند النقر على رمز التطبيق، سيتم نقلك مباشرةً إلى تطبيق الويب التقدّمي "دفتر القصاصات"، وستظهر الصورة هناك.

كيف تعمل هذه الميزة؟ لمعرفة ذلك، استكشِف بيان تطبيق الويب الخاص بتطبيق Scrapbook PWA. يقع إعداد Web Share Target API في السمة "share_target" من البيان الذي يشير في الحقل "action" إلى عنوان URL يتم تزيينه بالمعلمات كما هو موضّح في "params".
بعد ذلك، يملأ الطرف المشارِك نموذج عنوان URL هذا وفقًا لذلك (إما من خلال إجراء مشاركة، أو يتم التحكّم فيه آليًا من قِبل المطوّر باستخدام Web Share API)، حتى يتمكّن الطرف المستلِم من استخراج المَعلمات واستخدامها، مثل عرضها.
{
"action": "/_share-target",
"enctype": "multipart/form-data",
"method": "POST",
"params": {
"files": [{
"name": "media",
"accept": ["audio/*", "image/*", "video/*"]
}]
}
}
الملاحظات
ما رأيك في واجهة برمجة التطبيقات هذه؟ يُرجى مساعدتنا من خلال الردّ باختصار على هذا الاستطلاع:
هل كان استخدام واجهة برمجة التطبيقات هذه سهلاً؟
هل تمكّنت من تشغيل المثال؟
هل لديك المزيد من الملاحظات؟ هل كانت هناك ميزات مفقودة؟ يُرجى تقديم ملاحظات سريعة في هذا الاستطلاع. شكرًا
6. Wake Lock API
لتجنُّب استنزاف البطارية، تنتقل معظم الأجهزة بسرعة إلى وضع السكون عند تركها غير نشطة. على الرغم من أنّ هذا الإجراء مناسب في معظم الأوقات، تحتاج بعض التطبيقات إلى إبقاء الشاشة أو الجهاز نشطًا لإكمال عملها. توفّر واجهة برمجة التطبيقات Wake Lock طريقة لمنع الجهاز من تعتيم الشاشة وقفلها أو من الانتقال إلى وضع السكون. تتيح هذه الإمكانية تجارب جديدة كانت تتطلّب حتى الآن تطبيقًا أصليًا.
إعداد شاشة الاستراحة
لاختبار Wake Lock API، عليك أولاً التأكّد من أنّ جهازك سينتقل إلى وضع السكون. لذلك، في جزء الإعدادات المفضَّلة لنظام التشغيل، فعِّل شاشة استراحة من اختيارك وتأكَّد من أنّها تبدأ بعد دقيقة واحدة. تأكَّد من أنّها تعمل من خلال ترك جهازك بمفرده لمدة هذا الوقت بالضبط (أعلم أنّ ذلك صعب). تعرض لقطات الشاشة أدناه نظام التشغيل macOS، ولكن يمكنك بالطبع تجربة ذلك على جهاز Android الجوّال أو أي نظام أساسي متوافق على الكمبيوتر.

ضبط قفل التنشيط للشاشة
بعد التأكّد من أنّ شاشة التوقف تعمل، ستستخدم قفل التنشيط من النوع "screen" لمنع شاشة التوقف من أداء وظيفتها. انتقِل إلى تطبيق العرض التوضيحي لقفل التنشيط وانقر على تفعيل .
screen مربّع الاختيار قفل التنشيط

بدءًا من تلك اللحظة، يصبح قفل التنشيط نشطًا. إذا صبرت بما يكفي لترك جهازك بدون لمس لمدة دقيقة، ستلاحظ الآن أنّ شاشة التوقف لم تبدأ.
كيف يمكن إجراء ذلك؟ للاطّلاع على ذلك، انتقِل إلى مشروع Glitch لتطبيق Wake Lock التجريبي واطّلِع على script.js. يمكنك الاطّلاع على خلاصة الرمز في المقتطف أدناه. افتح علامة تبويب جديدة (أو استخدِم أي علامة تبويب مفتوحة) والصِق الرمز أدناه في وحدة تحكّم "أدوات مطوّري برامج Chrome". عند النقر على النافذة، من المفترض أن يظهر لك قفل التنشيط نشطًا لمدة 10 ثوانٍ بالضبط (راجِع سجلّات وحدة التحكّم)، ويجب ألا تبدأ شاشة الاستراحة.
if ('wakeLock' in navigator && 'request' in navigator.wakeLock) {
let wakeLock = null;
const requestWakeLock = async () => {
try {
wakeLock = await navigator.wakeLock.request('screen');
wakeLock.addEventListener('release', () => {
console.log('Wake Lock was released');
});
console.log('Wake Lock is active');
} catch (e) {
console.error(`${e.name}, ${e.message}`);
}
};
requestWakeLock();
window.setTimeout(() => {
wakeLock.release();
}, 10 * 1000);
}

الملاحظات
ما رأيك في واجهة برمجة التطبيقات هذه؟ يُرجى مساعدتنا من خلال الردّ باختصار على هذا الاستطلاع:
هل كان استخدام واجهة برمجة التطبيقات هذه سهلاً؟
هل تمكّنت من تشغيل المثال؟
هل لديك المزيد من الملاحظات؟ هل كانت هناك ميزات مفقودة؟ يُرجى تقديم ملاحظات سريعة في هذا الاستطلاع. شكرًا
7. Contact Picker API
إحدى واجهات برمجة التطبيقات التي نتطلّع إليها بشغف هي Contact Picker API. تتيح هذه الواجهة لتطبيق الويب الوصول إلى جهات الاتصال من أداة إدارة جهات الاتصال الأصلية على الجهاز، ما يتيح لتطبيق الويب الوصول إلى أسماء جهات الاتصال وعناوين بريدها الإلكتروني وأرقام هواتفها. يمكنك تحديد ما إذا كنت تريد جهة اتصال واحدة أو عدّة جهات، وما إذا كنت تريد كل الحقول أو مجموعة فرعية فقط من الأسماء وعناوين البريد الإلكتروني وأرقام الهواتف.
اعتبارات الخصوصية
بعد فتح أداة الاختيار، يمكنك اختيار جهات الاتصال التي تريد مشاركتها. ستلاحظ أنّه لا يتوفّر خيار "اختيار الكل"، وهذا مقصود لأنّنا نريد أن تكون المشاركة قرارًا مدروسًا. وبالمثل، لا تكون إمكانية الوصول مستمرة، بل هي قرار يُتّخذ لمرة واحدة.
الوصول إلى جهات الاتصال
الوصول إلى جهات الاتصال هو مهمة بسيطة. قبل فتح أداة الاختيار، يمكنك تحديد الحقول التي تريدها (الخيارات هي name وemail وtelephone)، وما إذا كنت تريد الوصول إلى جهات اتصال متعددة أو جهة اتصال واحدة فقط. يمكنك اختبار واجهة برمجة التطبيقات هذه على جهاز Android من خلال فتح التطبيق التجريبي. إنّ القسم ذي الصلة من الرمز المصدر هو بشكل أساسي المقتطف أدناه:
getContactsButton.addEventListener('click', async () => {
const contacts = await navigator.contacts.select(
['name', 'email'],
{multiple: true});
if (!contacts.length) {
// No contacts were selected, or picker couldn't be opened.
return;
}
console.log(contacts);
});

8. Async Clipboard API
نسخ النص ولصقه
حتى الآن، لم تكن هناك طريقة لنسخ الصور ولصقها آليًا في حافظة النظام. أضفنا مؤخرًا إمكانية استخدام الصور إلى Async Clipboard API،
وبالتالي يمكنك الآن نسخ الصور ولصقها في أي مكان. الجديد هو أنّه يمكنك أيضًا كتابة الصور إلى الحافظة. تتيح واجهة برمجة التطبيقات غير المتزامنة للحافظة نسخ النصوص ولصقها منذ فترة. يمكنك نسخ النص إلى الحافظة من خلال استدعاء navigator.clipboard.writeText() ثم لصق هذا النص لاحقًا من خلال استدعاء navigator.clipboard.readText().
نسخ الصور ولصقها
يمكنك الآن أيضًا كتابة الصور إلى الحافظة. لكي يعمل ذلك، تحتاج إلى بيانات الصورة كملف ثنائي كبير (BLOB) ثم تمرِّرها إلى أداة إنشاء عنصر الحافظة. أخيرًا، يمكنك بعد ذلك نسخ عنصر الحافظة هذا من خلال استدعاء navigator.clipboard.write().
// Copy: Writing image to the clipboard
try {
const imgURL = 'https://developers.google.com/web/updates/images/generic/file.png';
const data = await fetch(imgURL);
const blob = await data.blob();
await navigator.clipboard.write([
new ClipboardItem(Object.defineProperty({}, blob.type, {
value: blob,
enumerable: true
}))
]);
console.log('Image copied.');
} catch(e) {
console.error(e, e.message);
}
يبدو أنّ لصق الصورة مرة أخرى من الحافظة يتطلّب خطوات كثيرة، ولكنّه في الواقع يتضمّن فقط استرداد البيانات الثنائية الكبيرة من عنصر الحافظة. بما أنّه يمكن أن يكون هناك عدة أذونات، عليك تكرارها إلى أن تحصل على الإذن الذي يهمّك. لأسباب تتعلّق بالأمان، يقتصر ذلك حاليًا على صور PNG، ولكن قد يتم توفير المزيد من تنسيقات الصور في المستقبل.
async function getClipboardContents() {
try {
const clipboardItems = await navigator.clipboard.read();
for (const clipboardItem of clipboardItems) {
try {
for (const type of clipboardItem.types) {
const blob = await clipboardItem.getType(type);
console.log(URL.createObjectURL(blob));
}
} catch (e) {
console.error(e, e.message);
}
}
} catch (e) {
console.error(e, e.message);
}
}
يمكنك الاطّلاع على طريقة عمل واجهة برمجة التطبيقات هذه في تطبيق تجريبي، كما أنّ المقتطفات ذات الصلة من رمز المصدر مضمّنة أعلاه. يمكن نسخ الصور إلى الحافظة بدون إذن، ولكن يجب منح الإذن باللصق من الحافظة.

بعد منح الإذن بالوصول، يمكنك قراءة الصورة من الحافظة ولصقها في التطبيق باتّباع الخطوات التالية:

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