واجهة JavaScript bridge API
المشاركة والحافظة والطباعة
ورقة المشاركة في Android، وحافظة النظام، والنص الذي شاركه تطبيق آخر إلى تطبيقك، ومربع الطباعة.
AppMint.pdf دالة مساعدة (helper)#
AppMint.pdf.fromPage(options) / fromHtml(html, options)
مثال
ينشئ PDF حقيقيًا (نص قابل للتحديد ورسومات متجهية) دون نافذة طباعة: fromPage يحفظ الصفحة كما هي على الشاشة، مرتّبة بحسب CSS الخاص بـ @media print؛ وfromHtml يعرض HTML تمرّره في صفحة غير مرئية على عنوان التطبيق نفسه، فتُحمَّل الصور وأوراق الأنماط والخطوط النسبية كما في صفحتك، وينتظر الخطوط وكل الصور، ثم يحفظه. أما window.print() فما زال يفتح نافذة الطباعة المعتادة.
يُرجع: Promise بـ {ok: true, fileName, pages, bytes, saved, uri?, base64?} أو {ok: false, code, message}، حيث code هو busy (PDF واحد في كل مرة) أو bad-options أو failed أو too-large (base64 فوق 25 MB) أو permission-denied (رُفض التخزين على Android 7-9). يتطلب: لا شيء، فكل إنشاء يملكه. الحفظ في التنزيلات لا يحتاج إذنًا على Android 10+.
الخيارات: fileName (تُضاف ".pdf"؛ الافتراضي: عنوان الصفحة)، pageSize 'A4' (افتراضي) | 'Letter' | 'Legal' | 'A3' | 'A5'، landscape (true/false)، margins بالمليمتر (رقم واحد، أو {top, right, bottom, left}؛ وإن تُرك فقاعدة @page الخاصة بك)، save 'downloads' (افتراضي) | 'share' | 'base64'.
احفظ الصفحة الحالية في التنزيلات:
async function saveInvoice() {
if (!(window.AppMint && AppMint.pdf)) { window.print(); return; } // in a browser
var r = await AppMint.pdf.fromPage({ fileName: 'invoice-1042', pageSize: 'A4', margins: 12 });
if (r.ok) console.log('Saved ' + r.fileName + ' (' + r.pages + ' pages)');
else alert('Could not make the PDF: ' + r.message);
}إيصال مبني من HTML، مباشرة إلى ورقة المشاركة (تُحمَّل الصور والخطوط قبل إنشاء PDF):
async function shareReceipt(order) {
var html = '<style>body{font-family:sans-serif} td{padding:4px 8px}</style>' +
'<img src="img/logo.png" width="120"><h1>Receipt #' + order.id + '</h1><table>' +
order.items.map(function (i) { return '<tr><td>' + i.name + '</td><td>' + i.price + '</td></tr>'; }).join('') +
'</table><p><b>Total ' + order.total + '</b></p>';
var r = await AppMint.pdf.fromHtml(html, { fileName: 'receipt-' + order.id, pageSize: 'Letter', save: 'share' });
if (!r.ok) console.warn(r.code, r.message);
}استرجع البايتات لترفعها بنفسك:
async function uploadReport() {
var r = await AppMint.pdf.fromPage({ landscape: true, margins: { top: 10, right: 8, bottom: 10, left: 8 }, save: 'base64' });
if (!r.ok) return;
var bin = atob(r.base64), buf = new Uint8Array(bin.length);
for (var i = 0; i < bin.length; i++) buf[i] = bin.charCodeAt(i);
await fetch('/api/reports', { method: 'POST', headers: { 'Content-Type': 'application/pdf' }, body: buf });
}الاستدعاءات الخام تأخذ الخيارات كنص JSON ومعرّف استدعاء؛ استخدم الأداة المساعدة أعلاه بدلًا منها:
if (window.WebToApk && typeof window.WebToApk.pdfFromPage === 'function') {
// AppMint.pdf.fromPage wraps: WebToApk.pdfFromPage(JSON.stringify(options), callbackId)
// and AppMint.pdf.fromHtml wraps: WebToApk.pdfFromHtml(html, JSON.stringify(options), callbackId)
AppMint.pdf.fromPage({ save: 'downloads' }).then(function (r) { console.log(r); });
}ملاحظات: أخفِ الأزرار والقوائم من PDF بـ @media print { .no-print { display: none } }. يعرض PDF المنزَّل "تم تنزيل <name> · فتح" كأي تنزيل. fromHtml يشغّل سكربتات HTML (فتظهر المخططات المرسومة بالسكربت) لكن لا وصول له إلى ميزات التطبيق الأصلية. الصفحات الأطول من ورقة واحدة تُقسَّم كما يفعل Chrome؛ استخدم break-before: page للتحكم في مكان القسمة.
window.print معيار الويب#
window.print()
مثال
استدعاء الطباعة القياسي، مهيأ للعمل داخل التطبيق: يفتح شاشة الطباعة في Android حيث يطبع المستخدم على الورق أو يحفظ PDF.
يعيد: لا شيء. يتطلب: لا شيء.
document.getElementById('print-receipt').onclick = function () {
window.print();
};أخفِ عناصر تحكم التطبيق على الورق بورقة أنماط للطباعة:
<style>
@media print {
nav, .toolbar, button { display: none !important; }
body { background: #fff; color: #000; }
}
</style>اطبع ملصق شحن دون الصفحة المحيطة به: iframe بـ srcdoc من النطاق نفسه يطبع مستنده فقط:
function esc(s) {
return String(s).replace(/[&<>"]/g, function (c) {
return { '&': '&', '<': '<', '>': '>', '"': '"' }[c];
});
}
function printLabel(name, address) {
var frame = document.createElement('iframe');
frame.style.cssText = 'position:fixed;width:0;height:0;border:0';
frame.srcdoc = '<title>Label</title><style>body{font:18px sans-serif;margin:24px}</style>' +
'<b>' + esc(name) + '</b><br>' + esc(address).replace(/\n/g, '<br>');
frame.onload = function () {
frame.contentWindow.print();
setTimeout(function () { frame.remove(); }, 1000);
};
document.body.appendChild(frame);
}ملاحظات: window.print() يطبع الصفحة الرئيسية كما هي مرسومة الآن. و<iframe> من النطاق نفسه، وهو إطار iframe المخفي الذي تملؤه مكتبة طباعة بإيصال وتستدعي عليه iframe.contentWindow.print()، أو صفحة iframe تستدعي window.print() الخاص بها، تطبع مستند ذلك الإطار (راجع __printHtml). أما iframe من نطاق آخر فلا يمكن طباعته من الصفحة. البديل موجود قبل أول سكربت في الصفحة. وbeforeprint لا يمكن إلغاؤه (في أي متصفح).
__clipboardRead الجسر (bridge)#
window.WebToApk.__clipboardRead(): String
navigator.clipboard.read(): `{parts:[{type, text|base64}]}`. له نفس مدى readClipboard() في هذا الغلاف (الذي لا يملك بوابة نطاق).
مثال
ناقل داخلي يقف خلف navigator.clipboard.read(). تستخدم الصفحات الواجهة القياسية؛ لا تستدعِ هذا مباشرةً أبدًا - فقد تتغير دوال __ دون إشعار.
يُرجع: {parts:[{type, text|base64}]}، بنفس مدى readClipboard() في هذا التطبيق. يتطلب: لا شيء لتفعيله.
استخدم الواجهة العامة:
canvas.toBlob(async (png) => {
await navigator.clipboard.write([new ClipboardItem({ 'image/png': png })]);
});
const [item] = await navigator.clipboard.read();
if (item && item.types.includes('image/png')) preview(await item.getType('image/png'));الصق نصًا منسّقًا في محرر، مع الإبقاء على التنسيق عندما تحتوي الحافظة على HTML:
async function pasteRich(editor) {
try {
var items = await navigator.clipboard.read();
if (!items.length) { showMessage('The clipboard is empty'); return; }
var item = items[0];
if (item.types.includes('text/html')) {
editor.insertHtml(sanitize(await (await item.getType('text/html')).text()));
} else if (item.types.includes('text/plain')) {
editor.insertText(await (await item.getType('text/plain')).text());
}
} catch (e) {
showMessage('Could not read the clipboard');
}
}الصق أي صورة منسوخة (PNG أو JPEG أو WebP…) كصورة ملف شخصي، وميّز القراءة المرفوضة:
document.getElementById('paste-photo').onclick = async function () {
try {
var items = await navigator.clipboard.read();
var item = items[0];
var type = item && item.types.find(function (t) { return t.indexOf('image/') === 0; });
if (!type) { showMessage('Copy a picture first'); return; }
uploadAvatar(await item.getType(type)); // a Blob of that type
} catch (e) {
if (e.name === 'NotAllowedError') showMessage('This page cannot read the clipboard');
else showMessage('Could not paste the picture');
}
};ملاحظات: يعرض Android 12+ رسالته الخاصة "تم اللصق من الحافظة" عندما يقرأ تطبيق الحافظة.
__clipboardWrite الجسر (bridge)#
window.WebToApk.__clipboardWrite(partsJson: String): Boolean
navigator.clipboard.write(): يكون [partsJson] هو `[{type, text}|{type, base64}]` لعنصر ClipboardItem واحد: text/plain أو text/html أو صورة تُنسخ كـ content URI.
مثال
ناقل داخلي يقف خلف navigator.clipboard.write([ClipboardItem]). تستخدم الصفحات الواجهة القياسية؛ لا تستدعِ هذا مباشرةً أبدًا - فقد تتغير دوال __ دون إشعار.
يُرجع: true عند وضع المقطع. يتطلب: لا شيء لتفعيله.
استخدم الواجهة العامة:
canvas.toBlob(async (png) => {
await navigator.clipboard.write([new ClipboardItem({ 'image/png': png })]);
});
const [item] = await navigator.clipboard.read();
if (item && item.types.includes('image/png')) preview(await item.getType('image/png'));انسخ نصًا منسّقًا ونسخته العادية في عنصر واحد، حتى تحصل المحررات الغنية على الجدول وتحصل الحقول العادية على النص:
async function copyTable(table) {
if (!(navigator.clipboard && navigator.clipboard.write && window.ClipboardItem)) return;
try {
await navigator.clipboard.write([new ClipboardItem({
'text/html': new Blob([table.outerHTML], { type: 'text/html' }),
'text/plain': new Blob([table.innerText], { type: 'text/plain' })
})]);
showMessage('Table copied');
} catch (e) {
showMessage('Could not copy (' + e.name + ')'); // NotAllowedError when the write fails
}
}انسخ صورة تعرضها الصفحة، مثل رمز QR، ليمكن لصقها في محادثة:
async function copyImage(img) {
try {
var blob = await (await fetch(img.src)).blob(); // an image/* type, up to 16 MB
await navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]);
showMessage('Image copied');
} catch (e) {
showMessage('Could not copy the image');
}
}ملاحظات: نص وHTML وصورة واحدة لكل عنصر. تُنسخ الصورة كـ content URI عبر FileProvider الخاص بالتطبيق، فيمكن لصقها في WhatsApp أو Gmail أو Keep.
__printHtml الجسر (bridge)#
window.WebToApk.__printHtml(html: String, baseUrl: String, title: String)
يطبع [html] (مستند iframe من النطاق نفسه بعد تسلسله، يرسله بديل `window.print()` ([PrintShim])) عبر WebView خارج الشاشة على [baseUrl]، لأن محوّل الطباعة في WebView الرئيسي لا يطبع إلا الصفحة كاملة. [title] يسمّي مهمة الطباعة ("<App name> Document" عند تركه فارغًا).
مثال
ناقل داخلي وراء طباعة iframe: يرسل iframe.contentWindow.print() (وwindow.print() الخاص بصفحة iframe) مستند ذلك الإطار إلى هنا، ويطبعه التطبيق عبر شاشة الطباعة في Android. الصفحات تستخدم الاستدعاءات القياسية؛ لا تستدعِ هذا مباشرة.
يعيد: لا شيء. يتطلب: لا شيء.
نمط الإيصال الذي يتيحه هذا: إطار iframe مخفي يُملأ بالإيصال فقط:
function printReceipt(order) {
var frame = document.createElement('iframe');
frame.style.display = 'none';
document.body.appendChild(frame);
var doc = frame.contentWindow.document;
doc.open();
doc.write('<html><head><title>Receipt ' + order.id + '</title>' +
'<style>body{font:14px sans-serif} td{padding:2px 8px}</style></head><body>' +
'<h2>Receipt ' + order.id + '</h2><table>' +
order.lines.map(function (l) { return '<tr><td>' + l.name + '</td><td>' + l.price + '</td></tr>'; }).join('') +
'</table></body></html>');
doc.close();
frame.contentWindow.print(); // prints the RECEIPT, not the page behind it
setTimeout(function () { frame.remove(); }, 1000);
}صفحة تذكرة خاصة بك، محمّلة في iframe مخفي من النطاق نفسه: تُحمَّل أنماطها وصورها، ويسمّي <title> الخاص بها مهمة الطباعة:
function printTicket(id) {
var frame = document.createElement('iframe');
frame.style.cssText = 'position:fixed;width:0;height:0;border:0';
frame.src = 'ticket.html?id=' + encodeURIComponent(id);
frame.onload = function () {
frame.contentWindow.print(); // prints ticket.html's DOM as it stands now
setTimeout(function () { frame.remove(); }, 1000);
};
document.body.appendChild(frame);
}عدّل مستند iframe قبل اللقطة مباشرة بـ beforeprint على نافذة الإطار:
function printWithTimestamp(frame) {
var w = frame.contentWindow;
w.addEventListener('beforeprint', function () {
var p = w.document.createElement('p');
p.textContent = 'Printed ' + new Date().toLocaleString();
w.document.body.appendChild(p);
}, { once: true });
w.print(); // the printed copy includes the line added above
}ملاحظات: الوسائط هي (html, baseUrl, title): مستند iframe بعد تسلسله، والعنوان الذي تُحَل روابطه النسبية عليه (عنوان الصفحة نفسها لإطار about:blank)، واسم مهمة الطباعة (<title> الخاص بالإطار، وإلا عنوان الصفحة). تُؤخذ اللقطة عند استدعاء print()، ولا تعمل السكربتات داخلها مجددًا، وينطلق beforeprint / afterprint على نافذة الإطار حولها. أما iframe من نطاق آخر فلا يمكن طباعته من الصفحة.
copyToClipboard الجسر (bridge)#
window.WebToApk.copyToClipboard(text: String): Boolean
استخدم غلاف الوعد: const r = await AppMint.requestReview(); // {result, openedStore} const r = await AppMint.requestReview({ openStore: true }); // صفحة المتجر إن لم تظهر الورقة r.result: 'shown' | 'not_from_play' | 'quota' | 'error'. راجع RatePrompt.
موصوفة في مجموعتها، ورقة التقييم داخل التطبيق من Google Play، لا بمفردها.
مثال
ينسخ نصًا عاديًا إلى حافظة الهاتف. الصفحات تستخدم عادةً navigator.clipboard.writeText(text) القياسي، الذي يوجّهه الغلاف إلى هنا.
يُرجع: true عند النجاح، وfalse عند الفشل (بشكل متزامن). يتطلب: لا شيء.
الواجهة القياسية أولًا:
document.getElementById('copy-btn').onclick = async function () {
try {
await navigator.clipboard.writeText('PROMO-2026');
showMessage('Copied');
} catch (e) {
showMessage('Could not copy');
}
};الاستدعاء الخام:
if (window.WebToApk && typeof window.WebToApk.copyToClipboard === 'function') {
var ok = window.WebToApk.copyToClipboard('PROMO-2026');
showMessage(ok ? 'Copied' : 'Could not copy');
}زر "نسخ" على كل كتلة شيفرة، مع استخدام الإجابة المتزامنة لتحديث النص:
document.querySelectorAll('pre').forEach(function (pre) {
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.onclick = function () {
var ok = !!(window.WebToApk && typeof window.WebToApk.copyToClipboard === 'function' &&
window.WebToApk.copyToClipboard(pre.innerText));
btn.textContent = ok ? 'Copied' : 'Copy failed';
setTimeout(function () { btn.textContent = 'Copy'; }, 1500);
};
pre.parentNode.insertBefore(btn, pre);
});ملاحظات: نص عادي فقط (لا صور ولا HTML). يعرض Android 13+ معاينة "تم النسخ" الصغيرة الخاصة به، فقد لا تحتاج رسالتك الخاصة هناك.
pdfFromHtml الجسر (bridge)#
window.WebToApk.pdfFromHtml(html: String, optionsJson: String, callbackId: String)
يعرض [html] خارج الشاشة على نطاق التطبيق ويحفظه كـ PDF، استخدم `AppMint.pdf.fromHtml(html, options)`.
مثال
موثَّق مع AppMint.pdf - والمثال هناك يعرض هذا أيضًا.
ينشئ PDF حقيقيًا (نص قابل للتحديد ورسومات متجهية) دون نافذة طباعة: fromPage يحفظ الصفحة كما هي على الشاشة، مرتّبة بحسب CSS الخاص بـ @media print؛ وfromHtml يعرض HTML تمرّره في صفحة غير مرئية على عنوان التطبيق نفسه، فتُحمَّل الصور وأوراق الأنماط والخطوط النسبية كما في صفحتك، وينتظر الخطوط وكل الصور، ثم يحفظه. أما window.print() فما زال يفتح نافذة الطباعة المعتادة.
يُرجع: Promise بـ {ok: true, fileName, pages, bytes, saved, uri?, base64?} أو {ok: false, code, message}، حيث code هو busy (PDF واحد في كل مرة) أو bad-options أو failed أو too-large (base64 فوق 25 MB) أو permission-denied (رُفض التخزين على Android 7-9). يتطلب: لا شيء، فكل إنشاء يملكه. الحفظ في التنزيلات لا يحتاج إذنًا على Android 10+.
الخيارات: fileName (تُضاف ".pdf"؛ الافتراضي: عنوان الصفحة)، pageSize 'A4' (افتراضي) | 'Letter' | 'Legal' | 'A3' | 'A5'، landscape (true/false)، margins بالمليمتر (رقم واحد، أو {top, right, bottom, left}؛ وإن تُرك فقاعدة @page الخاصة بك)، save 'downloads' (افتراضي) | 'share' | 'base64'.
احفظ الصفحة الحالية في التنزيلات:
async function saveInvoice() {
if (!(window.AppMint && AppMint.pdf)) { window.print(); return; } // in a browser
var r = await AppMint.pdf.fromPage({ fileName: 'invoice-1042', pageSize: 'A4', margins: 12 });
if (r.ok) console.log('Saved ' + r.fileName + ' (' + r.pages + ' pages)');
else alert('Could not make the PDF: ' + r.message);
}إيصال مبني من HTML، مباشرة إلى ورقة المشاركة (تُحمَّل الصور والخطوط قبل إنشاء PDF):
async function shareReceipt(order) {
var html = '<style>body{font-family:sans-serif} td{padding:4px 8px}</style>' +
'<img src="img/logo.png" width="120"><h1>Receipt #' + order.id + '</h1><table>' +
order.items.map(function (i) { return '<tr><td>' + i.name + '</td><td>' + i.price + '</td></tr>'; }).join('') +
'</table><p><b>Total ' + order.total + '</b></p>';
var r = await AppMint.pdf.fromHtml(html, { fileName: 'receipt-' + order.id, pageSize: 'Letter', save: 'share' });
if (!r.ok) console.warn(r.code, r.message);
}استرجع البايتات لترفعها بنفسك:
async function uploadReport() {
var r = await AppMint.pdf.fromPage({ landscape: true, margins: { top: 10, right: 8, bottom: 10, left: 8 }, save: 'base64' });
if (!r.ok) return;
var bin = atob(r.base64), buf = new Uint8Array(bin.length);
for (var i = 0; i < bin.length; i++) buf[i] = bin.charCodeAt(i);
await fetch('/api/reports', { method: 'POST', headers: { 'Content-Type': 'application/pdf' }, body: buf });
}الاستدعاءات الخام تأخذ الخيارات كنص JSON ومعرّف استدعاء؛ استخدم الأداة المساعدة أعلاه بدلًا منها:
if (window.WebToApk && typeof window.WebToApk.pdfFromPage === 'function') {
// AppMint.pdf.fromPage wraps: WebToApk.pdfFromPage(JSON.stringify(options), callbackId)
// and AppMint.pdf.fromHtml wraps: WebToApk.pdfFromHtml(html, JSON.stringify(options), callbackId)
AppMint.pdf.fromPage({ save: 'downloads' }).then(function (r) { console.log(r); });
}ملاحظات: أخفِ الأزرار والقوائم من PDF بـ @media print { .no-print { display: none } }. يعرض PDF المنزَّل "تم تنزيل <name> · فتح" كأي تنزيل. fromHtml يشغّل سكربتات HTML (فتظهر المخططات المرسومة بالسكربت) لكن لا وصول له إلى ميزات التطبيق الأصلية. الصفحات الأطول من ورقة واحدة تُقسَّم كما يفعل Chrome؛ استخدم break-before: page للتحكم في مكان القسمة.
pdfFromPage الجسر (bridge)#
window.WebToApk.pdfFromPage(optionsJson: String, callbackId: String)
يحفظ الصفحة كـ PDF دون نافذة طباعة، استخدم `AppMint.pdf.fromPage(options)`. [optionsJson] هو `{fileName, pageSize, landscape, margins, save}`؛ ويُحَل [callbackId].
مثال
موثَّق مع AppMint.pdf - والمثال هناك يعرض هذا أيضًا.
ينشئ PDF حقيقيًا (نص قابل للتحديد ورسومات متجهية) دون نافذة طباعة: fromPage يحفظ الصفحة كما هي على الشاشة، مرتّبة بحسب CSS الخاص بـ @media print؛ وfromHtml يعرض HTML تمرّره في صفحة غير مرئية على عنوان التطبيق نفسه، فتُحمَّل الصور وأوراق الأنماط والخطوط النسبية كما في صفحتك، وينتظر الخطوط وكل الصور، ثم يحفظه. أما window.print() فما زال يفتح نافذة الطباعة المعتادة.
يُرجع: Promise بـ {ok: true, fileName, pages, bytes, saved, uri?, base64?} أو {ok: false, code, message}، حيث code هو busy (PDF واحد في كل مرة) أو bad-options أو failed أو too-large (base64 فوق 25 MB) أو permission-denied (رُفض التخزين على Android 7-9). يتطلب: لا شيء، فكل إنشاء يملكه. الحفظ في التنزيلات لا يحتاج إذنًا على Android 10+.
الخيارات: fileName (تُضاف ".pdf"؛ الافتراضي: عنوان الصفحة)، pageSize 'A4' (افتراضي) | 'Letter' | 'Legal' | 'A3' | 'A5'، landscape (true/false)، margins بالمليمتر (رقم واحد، أو {top, right, bottom, left}؛ وإن تُرك فقاعدة @page الخاصة بك)، save 'downloads' (افتراضي) | 'share' | 'base64'.
احفظ الصفحة الحالية في التنزيلات:
async function saveInvoice() {
if (!(window.AppMint && AppMint.pdf)) { window.print(); return; } // in a browser
var r = await AppMint.pdf.fromPage({ fileName: 'invoice-1042', pageSize: 'A4', margins: 12 });
if (r.ok) console.log('Saved ' + r.fileName + ' (' + r.pages + ' pages)');
else alert('Could not make the PDF: ' + r.message);
}إيصال مبني من HTML، مباشرة إلى ورقة المشاركة (تُحمَّل الصور والخطوط قبل إنشاء PDF):
async function shareReceipt(order) {
var html = '<style>body{font-family:sans-serif} td{padding:4px 8px}</style>' +
'<img src="img/logo.png" width="120"><h1>Receipt #' + order.id + '</h1><table>' +
order.items.map(function (i) { return '<tr><td>' + i.name + '</td><td>' + i.price + '</td></tr>'; }).join('') +
'</table><p><b>Total ' + order.total + '</b></p>';
var r = await AppMint.pdf.fromHtml(html, { fileName: 'receipt-' + order.id, pageSize: 'Letter', save: 'share' });
if (!r.ok) console.warn(r.code, r.message);
}استرجع البايتات لترفعها بنفسك:
async function uploadReport() {
var r = await AppMint.pdf.fromPage({ landscape: true, margins: { top: 10, right: 8, bottom: 10, left: 8 }, save: 'base64' });
if (!r.ok) return;
var bin = atob(r.base64), buf = new Uint8Array(bin.length);
for (var i = 0; i < bin.length; i++) buf[i] = bin.charCodeAt(i);
await fetch('/api/reports', { method: 'POST', headers: { 'Content-Type': 'application/pdf' }, body: buf });
}الاستدعاءات الخام تأخذ الخيارات كنص JSON ومعرّف استدعاء؛ استخدم الأداة المساعدة أعلاه بدلًا منها:
if (window.WebToApk && typeof window.WebToApk.pdfFromPage === 'function') {
// AppMint.pdf.fromPage wraps: WebToApk.pdfFromPage(JSON.stringify(options), callbackId)
// and AppMint.pdf.fromHtml wraps: WebToApk.pdfFromHtml(html, JSON.stringify(options), callbackId)
AppMint.pdf.fromPage({ save: 'downloads' }).then(function (r) { console.log(r); });
}ملاحظات: أخفِ الأزرار والقوائم من PDF بـ @media print { .no-print { display: none } }. يعرض PDF المنزَّل "تم تنزيل <name> · فتح" كأي تنزيل. fromHtml يشغّل سكربتات HTML (فتظهر المخططات المرسومة بالسكربت) لكن لا وصول له إلى ميزات التطبيق الأصلية. الصفحات الأطول من ورقة واحدة تُقسَّم كما يفعل Chrome؛ استخدم break-before: page للتحكم في مكان القسمة.
print الجسر (bridge)#
window.WebToApk.print()
يسلّم الصفحة كما هي الآن إلى مربع الطباعة في Android، الذي يمكنه الطباعة على الورق أو حفظ PDF. لا شيء لضبطه، فـ WebView يعرض المستند.
موصوف ضمن مجموعته، الطباعة، وليس على حدة.
مثال
يفتح شاشة الطباعة في Android للصفحة كما تبدو الآن: اطبع على الورق أو "احفظ كـ PDF". الصفحات تستخدم عادةً window.print() القياسي، الذي يوجّهه الغلاف إلى هنا.
يعيد: لا شيء. يتطلب: لا شيء.
الواجهة القياسية أولًا:
document.getElementById('print-btn').onclick = function () {
window.print(); // in the app: the Android print screen
};الاستدعاء الخام يؤدي الغرض نفسه:
if (window.WebToApk && typeof window.WebToApk.print === 'function') {
window.WebToApk.print();
}اطبع فاتورة واحدة من قائمة بوسمها لورقة أنماط الطباعة (اترك الوسم، فشاشة الطباعة ترتب الصفحة بعد عودة print()):
// CSS: @media print { .invoice:not(.print-me), nav, button { display: none !important; } }
function printInvoice(id) {
document.querySelectorAll('.invoice.print-me').forEach(function (el) {
el.classList.remove('print-me');
});
document.getElementById('invoice-' + id).classList.add('print-me');
if (window.WebToApk && typeof window.WebToApk.print === 'function') {
window.WebToApk.print();
} else {
window.print(); // a normal browser
}
}ملاحظات: يطبع WebView كاملًا، أي الصفحة الرئيسية. أما print() الخاص بـ iframe من النطاق نفسه فيطبع ذلك الإطار فقط (راجع window.print). استخدم ورقة أنماط @media print لإخفاء الأزرار والقوائم. تُسمّى المهمة "<App name> Document". تُسجَّل الأخطاء فقط.
readClipboard الجسر (bridge)#
window.WebToApk.readClipboard(): String
استخدم غلاف الوعد: const r = await AppMint.requestReview(); // {result, openedStore} const r = await AppMint.requestReview({ openStore: true }); // صفحة المتجر إن لم تظهر الورقة r.result: 'shown' | 'not_from_play' | 'quota' | 'error'. راجع RatePrompt.
موصوفة في مجموعتها، ورقة التقييم داخل التطبيق من Google Play، لا بمفردها.
مثال
يقرأ النص الموجود الآن في حافظة الهاتف. الصفحات تستخدم عادةً navigator.clipboard.readText() القياسي، الذي يوجّهه الغلاف إلى هنا.
يُرجع: النص، أو "" عندما تكون الحافظة فارغة أو لا يمكن قراءتها (بشكل متزامن). يتطلب: لا شيء.
الواجهة القياسية أولًا، مثلًا زر "لصق الرمز":
document.getElementById('paste-btn').onclick = async function () {
try {
var text = await navigator.clipboard.readText();
if (text) document.getElementById('code').value = text.trim();
else showMessage('The clipboard is empty');
} catch (e) {
showMessage('Could not read the clipboard');
}
};الاستدعاء الخام:
if (window.WebToApk && typeof window.WebToApk.readClipboard === 'function') {
var text = window.WebToApk.readClipboard();
if (text) document.getElementById('code').value = text;
}زر "لصق الرابط" يأخذ أول عنوان ويب من أي شيء نُسخ:
document.getElementById('paste-link').onclick = function () {
if (!(window.WebToApk && typeof window.WebToApk.readClipboard === 'function')) return;
var text = window.WebToApk.readClipboard();
var m = /https?:\/\/\S+/.exec(text);
if (m) document.getElementById('link').value = m[0];
else showMessage('There is no link on the clipboard');
};ملاحظات: صفحات تطبيقك فقط يمكنها قراءتها: الموقع الخارجي المفتوح داخل التطبيق يحصل على "". لا يسمح Android للتطبيق بقراءة الحافظة إلا وهو ظاهر على الشاشة، ويعرض Android 12+ إشعار "تم اللصق من الحافظة"، فاقرأها عند نقرة من المستخدم وليس عند تحميل الصفحة.