JavaScript ब्रिज API
शेयर, क्लिपबोर्ड और प्रिंट
Android शेयर शीट, सिस्टम क्लिपबोर्ड, किसी दूसरे ऐप से आपके ऐप में शेयर किया गया टेक्स्ट, और प्रिंट डायलॉग।
AppMint.pdf हेल्पर#
AppMint.pdf.fromPage(options) / fromHtml(html, options)
उदाहरण
असली PDF बनाता है (चुनने लायक टेक्स्ट, वेक्टर ग्राफ़िक्स) बिना प्रिंट डायलॉग के: fromPage पेज को वैसे ही सेव करता है जैसा स्क्रीन पर है, आपके @media print CSS के हिसाब से; fromHtml आपके दिए HTML को ऐप के अपने पते पर एक अदृश्य पेज में रेंडर करता है - इसलिए रिलेटिव इमेज, स्टाइलशीट और फ़ॉन्ट वैसे ही लोड होते हैं जैसे आपके पेज में - फ़ॉन्ट और हर इमेज का इंतज़ार करता है, फिर सेव करता है। window.print() अब भी सामान्य प्रिंट डायलॉग खोलता है।
लौटाता है: {ok: true, fileName, pages, bytes, saved, uri?, base64?} या {ok: false, code, message} का Promise - code है busy (एक बार में एक PDF), bad-options, failed, too-large (25 MB से ज़्यादा base64) या permission-denied (Android 7-9 पर स्टोरेज मना कर दिया गया)। ज़रूरी: कुछ नहीं - हर बिल्ड में है। Downloads में सेव करने के लिए Android 10+ पर किसी अनुमति की ज़रूरत नहीं।
विकल्प: fileName (".pdf" जुड़ जाता है; डिफ़ॉल्ट: पेज का टाइटल), pageSize 'A4' (डिफ़ॉल्ट) | 'Letter' | 'Legal' | 'A3' | 'A5', landscape (true/false), margins मिलीमीटर में (एक संख्या, या {top, right, bottom, left}; छोड़ने पर आपका अपना @page नियम), save 'downloads' (डिफ़ॉल्ट) | 'share' | 'base64'.
मौजूदा पेज को Downloads में सेव करें:
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 टेक्स्ट के रूप में और एक कॉलबैक id लेती हैं; इसके बजाय ऊपर का हेल्पर इस्तेमाल करें:
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 किसी भी डाउनलोड की तरह “Downloaded <name> · Open” दिखाती है। 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>शिपिंग लेबल को आसपास के पेज के बिना प्रिंट करें - उसी ऑरिजिन का srcdoc iframe सिर्फ़ अपना डॉक्यूमेंट प्रिंट करता है:
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() कॉल करती है, या अपना window.print() कॉल करता iframe पेज - उसी iframe का डॉक्यूमेंट प्रिंट करता है (देखें __printHtml)। दूसरे ऑरिजिन का iframe पेज से प्रिंट नहीं हो सकता। यह बदलाव पेज की पहली स्क्रिप्ट से पहले मौजूद होता है। beforeprint को (किसी भी ब्राउज़र में) रद्द नहीं किया जा सकता।
__clipboardRead ब्रिज#
window.WebToApk.__clipboardRead(): String
navigator.clipboard.read(): `{parts:[{type, text|base64}]}`। इस शेल में readClipboard() जितनी ही पहुँच (जिसमें ऑरिजिन गेट नहीं है)।
उदाहरण
navigator.clipboard.read() के पीछे का आंतरिक ट्रांसपोर्ट। पेज स्टैंडर्ड API इस्तेमाल करते हैं; इसे कभी सीधे कॉल न करें - __ मेथड बिना सूचना के बदल सकते हैं।
लौटाता है: {parts:[{type, text|base64}]} - इस ऐप में readClipboard() जितनी ही पहुँच। ज़रूरी: चालू करने के लिए कुछ नहीं।
पब्लिक API इस्तेमाल करें:
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+ अपना “pasted from your clipboard” संदेश दिखाता है।
__clipboardWrite ब्रिज#
window.WebToApk.__clipboardWrite(partsJson: String): Boolean
navigator.clipboard.write(): [partsJson] एक ClipboardItem के लिए `[{type, text}|{type, base64}]` है - text/plain, text/html, या ऐसी इमेज जो कंटेंट URI के रूप में कॉपी होती है।
उदाहरण
navigator.clipboard.write([ClipboardItem]) के पीछे का आंतरिक ट्रांसपोर्ट। पेज स्टैंडर्ड API इस्तेमाल करते हैं; इसे कभी सीधे कॉल न करें - __ मेथड बिना सूचना के बदल सकते हैं।
लौटाता है: क्लिप रखे जाने पर true। ज़रूरी: चालू करने के लिए कुछ नहीं।
पब्लिक API इस्तेमाल करें:
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 और एक इमेज। इमेज ऐप के FileProvider से कंटेंट URI के रूप में कॉपी होती है, इसलिए वह WhatsApp, Gmail या Keep में पेस्ट हो जाती है।
__printHtml ब्रिज#
window.WebToApk.__printHtml(html: String, baseUrl: String, title: String)
[html] - उसी ऑरिजिन के iframe का क्रमबद्ध डॉक्यूमेंट, जिसे `window.print()` शिम ([PrintShim]) भेजता है - को [baseUrl] पर एक ऑफ़स्क्रीन WebView से प्रिंट करता है, क्योंकि मुख्य WebView का प्रिंट अडैप्टर सिर्फ़ पूरा पेज प्रिंट कर सकता है। [title] प्रिंट जॉब का नाम तय करता है (खाली होने पर “<App name> Document”)।
उदाहरण
iframe प्रिंट करने के पीछे का अंदरूनी ट्रांसपोर्ट: iframe.contentWindow.print() (और iframe पेज का अपना 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 में लोड किया गया - उसका CSS और इमेज लोड होती हैं, और उसका <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 का डॉक्यूमेंट 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 iframe के लिए पेज का अपना पता), और प्रिंट जॉब का नाम (iframe का <title>, वरना पेज का)। स्नैपशॉट तब लिया जाता है जब print() कॉल होता है - उसके अंदर की स्क्रिप्ट दोबारा नहीं चलतीं - और beforeprint / afterprint उसके आसपास iframe की विंडो पर चलते हैं। दूसरे ऑरिजिन का iframe पेज से प्रिंट नहीं हो सकता।
copyToClipboard ब्रिज#
window.WebToApk.copyToClipboard(text: String): Boolean
promise रैपर इस्तेमाल करें: const r = await AppMint.requestReview(); // {result, openedStore} const r = await AppMint.requestReview({ openStore: true }); // listing if no sheet r.result: 'shown' | 'not_from_play' | 'quota' | 'error'। RatePrompt देखें।
इसे अलग से नहीं, बल्कि इसके समूह Google Play की इन-ऐप रिव्यू शीट में समझाया गया है।
उदाहरण
सादा टेक्स्ट फ़ोन के क्लिपबोर्ड पर कॉपी करता है। पेज आम तौर पर मानक navigator.clipboard.writeText(text) इस्तेमाल करते हैं, जिसे शेल यहाँ भेज देता है।
लौटाता है: सफल होने पर true, फ़ेल होने पर false (तुरंत)। ज़रूरी: कुछ नहीं।
पहले मानक API:
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');
}हर कोड ब्लॉक पर एक “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+ अपना छोटा “Copied” प्रीव्यू दिखाता है, इसलिए वहाँ आपको अपना संदेश शायद न चाहिए।
pdfFromHtml ब्रिज#
window.WebToApk.pdfFromHtml(html: String, optionsJson: String, callbackId: String)
[html] को ऐप के ऑरिजिन पर ऑफ़स्क्रीन रेंडर करके PDF के रूप में सेव करता है - `AppMint.pdf.fromHtml(html, options)` इस्तेमाल करें।
उदाहरण
AppMint.pdf के साथ दस्तावेज़ित - वहाँ का उदाहरण इसे भी दिखाता है।
असली PDF बनाता है (चुनने लायक टेक्स्ट, वेक्टर ग्राफ़िक्स) बिना प्रिंट डायलॉग के: fromPage पेज को वैसे ही सेव करता है जैसा स्क्रीन पर है, आपके @media print CSS के हिसाब से; fromHtml आपके दिए HTML को ऐप के अपने पते पर एक अदृश्य पेज में रेंडर करता है - इसलिए रिलेटिव इमेज, स्टाइलशीट और फ़ॉन्ट वैसे ही लोड होते हैं जैसे आपके पेज में - फ़ॉन्ट और हर इमेज का इंतज़ार करता है, फिर सेव करता है। window.print() अब भी सामान्य प्रिंट डायलॉग खोलता है।
लौटाता है: {ok: true, fileName, pages, bytes, saved, uri?, base64?} या {ok: false, code, message} का Promise - code है busy (एक बार में एक PDF), bad-options, failed, too-large (25 MB से ज़्यादा base64) या permission-denied (Android 7-9 पर स्टोरेज मना कर दिया गया)। ज़रूरी: कुछ नहीं - हर बिल्ड में है। Downloads में सेव करने के लिए Android 10+ पर किसी अनुमति की ज़रूरत नहीं।
विकल्प: fileName (".pdf" जुड़ जाता है; डिफ़ॉल्ट: पेज का टाइटल), pageSize 'A4' (डिफ़ॉल्ट) | 'Letter' | 'Legal' | 'A3' | 'A5', landscape (true/false), margins मिलीमीटर में (एक संख्या, या {top, right, bottom, left}; छोड़ने पर आपका अपना @page नियम), save 'downloads' (डिफ़ॉल्ट) | 'share' | 'base64'.
मौजूदा पेज को Downloads में सेव करें:
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 टेक्स्ट के रूप में और एक कॉलबैक id लेती हैं; इसके बजाय ऊपर का हेल्पर इस्तेमाल करें:
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 किसी भी डाउनलोड की तरह “Downloaded <name> · Open” दिखाती है। fromHtml HTML की स्क्रिप्ट चलाता है (स्क्रिप्ट से बने चार्ट दिखते हैं) लेकिन उसे ऐप के नेटिव फ़ीचर नहीं मिलते। एक शीट से लंबे पेज वैसे ही बँटते हैं जैसे Chrome बाँटता; कहाँ बँटे यह तय करने के लिए break-before: page इस्तेमाल करें।
pdfFromPage ब्रिज#
window.WebToApk.pdfFromPage(optionsJson: String, callbackId: String)
पेज को बिना प्रिंट डायलॉग के PDF के रूप में सेव करता है - `AppMint.pdf.fromPage(options)` इस्तेमाल करें। [optionsJson] `{fileName, pageSize, landscape, margins, save}`; [callbackId] को हल करता है।
उदाहरण
AppMint.pdf के साथ दस्तावेज़ित - वहाँ का उदाहरण इसे भी दिखाता है।
असली PDF बनाता है (चुनने लायक टेक्स्ट, वेक्टर ग्राफ़िक्स) बिना प्रिंट डायलॉग के: fromPage पेज को वैसे ही सेव करता है जैसा स्क्रीन पर है, आपके @media print CSS के हिसाब से; fromHtml आपके दिए HTML को ऐप के अपने पते पर एक अदृश्य पेज में रेंडर करता है - इसलिए रिलेटिव इमेज, स्टाइलशीट और फ़ॉन्ट वैसे ही लोड होते हैं जैसे आपके पेज में - फ़ॉन्ट और हर इमेज का इंतज़ार करता है, फिर सेव करता है। window.print() अब भी सामान्य प्रिंट डायलॉग खोलता है।
लौटाता है: {ok: true, fileName, pages, bytes, saved, uri?, base64?} या {ok: false, code, message} का Promise - code है busy (एक बार में एक PDF), bad-options, failed, too-large (25 MB से ज़्यादा base64) या permission-denied (Android 7-9 पर स्टोरेज मना कर दिया गया)। ज़रूरी: कुछ नहीं - हर बिल्ड में है। Downloads में सेव करने के लिए Android 10+ पर किसी अनुमति की ज़रूरत नहीं।
विकल्प: fileName (".pdf" जुड़ जाता है; डिफ़ॉल्ट: पेज का टाइटल), pageSize 'A4' (डिफ़ॉल्ट) | 'Letter' | 'Legal' | 'A3' | 'A5', landscape (true/false), margins मिलीमीटर में (एक संख्या, या {top, right, bottom, left}; छोड़ने पर आपका अपना @page नियम), save 'downloads' (डिफ़ॉल्ट) | 'share' | 'base64'.
मौजूदा पेज को Downloads में सेव करें:
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 टेक्स्ट के रूप में और एक कॉलबैक id लेती हैं; इसके बजाय ऊपर का हेल्पर इस्तेमाल करें:
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 किसी भी डाउनलोड की तरह “Downloaded <name> · Open” दिखाती है। fromHtml HTML की स्क्रिप्ट चलाता है (स्क्रिप्ट से बने चार्ट दिखते हैं) लेकिन उसे ऐप के नेटिव फ़ीचर नहीं मिलते। एक शीट से लंबे पेज वैसे ही बँटते हैं जैसे Chrome बाँटता; कहाँ बँटे यह तय करने के लिए break-before: page इस्तेमाल करें।
print ब्रिज#
window.WebToApk.print()
पेज को जैसा वह अभी है, Android के प्रिंट डायलॉग को सौंपता है, जो कागज़ पर प्रिंट कर सकता है या PDF सेव कर सकता है। कुछ सेट करने की ज़रूरत नहीं - WebView डॉक्यूमेंट रेंडर करता है।
इसका वर्णन अलग से नहीं, बल्कि इसके समूह प्रिंटिंग में है।
उदाहरण
पेज जैसा अभी दिखता है उसके लिए Android की प्रिंट स्क्रीन खोलता है - कागज़ पर प्रिंट करें या “Save as PDF”। पेज आम तौर पर मानक window.print() इस्तेमाल करते हैं, जिसे शेल यहाँ भेज देता है।
लौटाता है: कुछ नहीं। ज़रूरत: कुछ नहीं।
पहले मानक API:
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 - मुख्य पेज - प्रिंट करता है। उसी ऑरिजिन के iframe का अपना print() सिर्फ़ वही iframe प्रिंट करता है (देखें window.print)। बटन और मेन्यू छिपाने के लिए @media print स्टाइलशीट इस्तेमाल करें। जॉब का नाम “<App name> Document” होता है। त्रुटियाँ सिर्फ़ लॉग होती हैं।
readClipboard ब्रिज#
window.WebToApk.readClipboard(): String
promise रैपर इस्तेमाल करें: const r = await AppMint.requestReview(); // {result, openedStore} const r = await AppMint.requestReview({ openStore: true }); // listing if no sheet r.result: 'shown' | 'not_from_play' | 'quota' | 'error'। RatePrompt देखें।
इसे अलग से नहीं, बल्कि इसके समूह Google Play की इन-ऐप रिव्यू शीट में समझाया गया है।
उदाहरण
फ़ोन के क्लिपबोर्ड पर अभी मौजूद टेक्स्ट पढ़ता है। पेज आम तौर पर मानक navigator.clipboard.readText() इस्तेमाल करते हैं, जिसे शेल यहाँ भेज देता है।
लौटाता है: टेक्स्ट, या क्लिपबोर्ड खाली होने या न पढ़े जा सकने पर "" (तुरंत)। ज़रूरी: कुछ नहीं।
पहले मानक API - जैसे “Paste code” बटन:
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;
}एक “Paste link” बटन जो कॉपी की गई किसी भी चीज़ में से पहला वेब पता निकाल लेता है:
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+ “pasted from clipboard” सूचना दिखाता है - इसे यूज़र के टैप पर पढ़ें, पेज लोड पर नहीं।