मुफ़्त APK बनाएँ

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 इस्तेमाल करें।

navigator.clipboard वेब स्टैंडर्ड#

navigator.clipboard.writeText / readText (and write / read)

उदाहरण

मानक Clipboard API, जिसका जवाब ऐप के अंदर फ़ोन का असली क्लिपबोर्ड देता है।

लौटाता है: writeText(text) → एक Promise जो कॉपी होने पर पूरा होता है और वरना NotAllowedError के साथ रिजेक्ट होता है। readText() → क्लिपबोर्ड टेक्स्ट वाला Promise (खाली होने पर "")। write([item]) / read() → मानक की तरह Promises। ज़रूरी: कुछ नहीं। डॉक्यूमेंट शुरू होते ही इंस्टॉल हो जाता है, इसलिए आपके पेज के पार्स होते समय की गई जाँच उसे पहले से देख लेती है।

कॉपी:

async function copyLink(link) {
  if (!(navigator.clipboard && navigator.clipboard.writeText)) { alert('Copy is not available'); return; }
  try {
    await navigator.clipboard.writeText(link);
    showMessage('Link copied');
  } catch (e) {
    showMessage('Could not copy');
  }
}

पेस्ट - टैप से:

document.getElementById('paste').onclick = async function () {
  try {
    var text = await navigator.clipboard.readText();
    document.getElementById('input').value = text;
  } catch (e) {
    showMessage('Could not read the clipboard');
  }
};

इमेज कॉपी करें (जैसे canvas पर बना QR कोड) ClipboardItem:

async function copyCanvas(canvas) {
  if (!(navigator.clipboard && navigator.clipboard.write && window.ClipboardItem)) {
    alert('Copying images is not available here');
    return;
  }
  var blob = await new Promise(function (r) { canvas.toBlob(r, 'image/png'); });
  try {
    await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]);
    showMessage('Image copied');
  } catch (e) {
    showMessage('Could not copy the image');
  }
}

ध्यान दें: ऐप में writeText/readText WebToApk.copyToClipboard और WebToApk.readClipboard को कॉल करते हैं। write() सिर्फ़ पहला ClipboardItem लेता है और text/plain, text/html और एक इमेज (16 MB तक; एक ही आइटम में इमेज टेक्स्ट पर भारी पड़ती है) सपोर्ट करता है। read() क्लिपबोर्ड के टेक्स्ट, HTML या इमेज के साथ [item] पर पूरा होता है (खाली होने पर [])। इसे सिर्फ़ ऐप के अपने पेज पढ़ सकते हैं: ऐप के अंदर खुली कोई बाहरी वेबसाइट रोक दी जाती है (NotAllowedError)। इसे यूज़र के टैप पर पढ़ें - Android 12+ “pasted from clipboard” सूचना दिखाता है। ब्राउज़र में वही कोड ब्राउज़र के अपने अनुमति नियमों के साथ चलता है।

navigator.share वेब स्टैंडर्ड#

navigator.share(data) / navigator.canShare(data)

उदाहरण

मानक Web Share API, जिसे ऐप के अंदर काम करने लायक बनाया गया है: टेक्स्ट और लिंक Android शेयर शीट खोलते हैं, और files असली फ़ाइलों के रूप में शेयर होती हैं (WhatsApp, Gmail, Drive…)।

लौटाता है: navigator.share → एक Promise जो शीट खुलने पर पूरा होता है (यह नहीं बताता कि कौन-सा ऐप चुना गया)। navigator.canShare → true/false। ज़रूरी: कुछ नहीं। डॉक्यूमेंट शुरू होते ही इंस्टॉल हो जाता है, इसलिए आपके पेज के पार्स होते समय की गई जाँच उसे पहले से देख लेती है।

टेक्स्ट और लिंक:

async function shareItem(item) {
  if (!navigator.share) { alert('Sharing is not available here'); return; }
  try {
    await navigator.share({ title: item.name, text: 'Look at this', url: item.link });
  } catch (e) { /* in a browser: AbortError when the user closes the sheet */ }
}

फ़ाइलें - पहले canShare से जाँचें:

async function sharePdf(blob) {
  var file = new File([blob], 'invoice.pdf', { type: 'application/pdf' });
  var data = { files: [file], title: 'Invoice', text: 'Invoice for March' };
  if (!(navigator.canShare && navigator.canShare(data))) {
    alert('File sharing is not available here');
    return;
  }
  try {
    await navigator.share(data);
  } catch (e) { console.log('Share failed', e); }
}

कई फ़ाइलें जो यूज़र ने चुनीं - एक ही प्रकार की फ़ोटो उसी प्रकार के साथ शेयर होती हैं:

document.getElementById('photos').onchange = async function (e) {
  var files = Array.from(e.target.files);
  if (!files.length) return;
  var data = { files: files, title: 'Trip photos' };
  if (!(navigator.canShare && navigator.canShare(data))) {
    alert('File sharing is not available here');
    return;
  }
  try {
    await navigator.share(data);
  } catch (err) { console.log('Share failed', err); }
};

ध्यान दें: ऐप में title विषय बन जाता है, और text + url एक टेक्स्ट के रूप में भेजे जाते हैं। files के साथ हर फ़ाइल पेज में पढ़ी जाती है और base64 (WebToApk.shareFiles) के रूप में भेजी जाती है, इसलिए फ़ाइलें कुछ MB तक रखें। अगर शेयर शीट न खुल सके, तो फ़ाइलें डाउनलोड के रूप में सेव हो जाती हैं और promise फिर भी पूरा होता है। किसी भी टेक्स्ट शेयर के लिए canShare true लौटाता है। AI से बने ऐप share इस्तेमाल कर सकते हैं, @/lib/appmintNative.

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 { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[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 पेज से प्रिंट नहीं हो सकता।

clearSharedText ब्रिज#

window.WebToApk.clearSharedText()

रखा हुआ शेयर साफ़ करता है, जब पेज उसे इस्तेमाल कर चुका हो।

उदाहरण

ऐप में शेयर किया गया टेक्स्ट या लिंक भुला देता है, जब आपका पेज उसे इस्तेमाल कर चुका हो।

लौटाता है: कुछ नहीं। ज़रूरी: कुछ नहीं (शेयर के लिए खुद Receive Shares From Other Apps चाहिए, जिसमें Text and links पर टिक हो)।

रखा हुआ शेयर पढ़ें, इस्तेमाल करें, फिर उसे साफ़ करें ताकि रीलोड के बाद उसे दोबारा न संभाला जाए:

if (window.WebToApk && typeof window.WebToApk.getSharedText === 'function') {
  var raw = window.WebToApk.getSharedText();
  if (raw) {
    var shared = JSON.parse(raw);          // { text, subject, url, receivedAt }
    saveNote(shared.subject, shared.text);
    window.WebToApk.clearSharedText();     // getSharedText() now returns ""
  }
}

window.addEventListener('appmint:shared', function (e) {
  saveNote(e.detail.subject, e.detail.text);
  if (window.WebToApk && window.WebToApk.clearSharedText) window.WebToApk.clearSharedText();
});

पहले पूछें, और यूज़र जो भी बटन दबाए, शेयर साफ़ कर दें:

function askAboutShare(s) {
  var dialog = document.getElementById('share-dialog');
  document.getElementById('share-preview').textContent = s.text;
  dialog.hidden = false;
  function done() {
    dialog.hidden = true;
    if (window.WebToApk && typeof window.WebToApk.clearSharedText === 'function') {
      window.WebToApk.clearSharedText();
    }
  }
  document.getElementById('share-save').onclick = function () { saveNote(s.subject, s.text); done(); };
  document.getElementById('share-discard').onclick = done;
}

इसे तभी साफ़ करें जब वह सुरक्षित सेव हो जाए, ताकि फ़ेल हुए अपलोड को फिर आज़माया जा सके:

async function importShare() {
  if (!(window.WebToApk && typeof window.WebToApk.getSharedText === 'function')) return;
  var raw = window.WebToApk.getSharedText();
  if (!raw) return;
  var s = JSON.parse(raw);
  try {
    var res = await fetch('/api/bookmarks', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ url: s.url || s.text, title: s.subject })
    });
    if (!res.ok) throw new Error('HTTP ' + res.status);
    window.WebToApk.clearSharedText();
  } catch (e) {
    showMessage('Could not save the link — tap Retry');   // Retry calls importShare() again
  }
}

ध्यान दें: साफ़ करने का असर सिर्फ़ getSharedText() पर होता है। नया शेयर रखे हुए शेयर को बदल देता है और appmint:shared फिर चलाता है। ऐप में शेयर की गई फ़ाइलें अलग से छोड़ी जाती हैं AppMint.releaseOpenedFile().

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” प्रीव्यू दिखाता है, इसलिए वहाँ आपको अपना संदेश शायद न चाहिए।

getSharedText ब्रिज#

window.WebToApk.getSharedText(): String

वह टेक्स्ट या लिंक जो किसी दूसरे ऐप ने इसमें शेयर किया (“Share to <app>” - YouTube ऐप से शेयर किया YouTube वीडियो उसके लिंक के रूप में आता है), JSON `{text, subject, url, receivedAt}` के रूप में या कुछ शेयर न होने पर ""। पढ़े जाने तक रखा रहता है, इसलिए शेयर के बाद माउंट होने वाला ऐप भी उसे देख लेता है; ऐप चलते समय आने वाला शेयर `appmint:shared` भी चलाता है। कैप्शन के साथ शेयर की गई फ़ोटो या वीडियो की फ़ाइल AppMint.getOpenedFile() से और कैप्शन यहाँ मिलता है। इसके लिए बिल्ड का “Receive shares from other apps” विकल्प चाहिए, जिसमें “Text and links” पर टिक हो; वही शेयर-शीट एंट्री रजिस्टर करता है।

उदाहरण

वह टेक्स्ट या लिंक जो किसी दूसरे ऐप ने आपके ऐप में शेयर किया (“Share → your app”), JSON स्ट्रिंग के रूप में, या कुछ शेयर न होने पर ""।

लौटाता है: JSON स्ट्रिंग {text, subject, url, receivedAt} या "" (तुरंत)। url वह पहला http(s):// लिंक है जो text (या "") में मिला; receivedAt मिलीसेकंड में समय है। ज़रूरी: बिल्ड करते समय Receive Shares From Other Apps चालू, जिसमें Text and links पर टिक हो - इससे आपका ऐप दूसरे ऐप के Share मेन्यू में आ जाता है।

शेयर आपके साफ़ करने तक रखा रहता है, इसलिए शुरुआत में उसे पढ़ें, और ऐप चलते समय आने वाले शेयर सुनें:

function handleShare(s) {
  addBookmark(s.url || s.text, s.subject);
  if (window.WebToApk && window.WebToApk.clearSharedText) window.WebToApk.clearSharedText();
}

// 1. On start (the app may have been opened by the share).
if (window.WebToApk && typeof window.WebToApk.getSharedText === 'function') {
  var raw = window.WebToApk.getSharedText();
  if (raw) handleShare(JSON.parse(raw));
}

// 2. While running: detail has the same keys { text, subject, url, receivedAt }.
window.addEventListener('appmint:shared', function (e) {
  handleShare(e.detail);
});

अगर आप एक ही चाहें, तो एक ग्लोबल हुक वही ऑब्जेक्ट पाता है:

window.onAppMintShared = function (s) { handleShare(s); };

ऐप में शेयर किया गया YouTube वीडियो url फ़ील्ड से खोलें:

function openSharedVideo() {
  if (!(window.WebToApk && typeof window.WebToApk.getSharedText === 'function')) return;
  var raw = window.WebToApk.getSharedText();
  if (!raw) return;
  var s = JSON.parse(raw);
  var m = /(?:youtu\.be\/|[?&]v=)([\w-]{11})/.exec(s.url || s.text);
  if (m) {
    showVideo(m[1]);
    window.WebToApk.clearSharedText();
  } else {
    showMessage('That share is not a video link');
  }
}

ध्यान दें: YouTube ऐप से शेयर किया गया YouTube वीडियो उसके लिंक के रूप में आता है। कैप्शन के साथ शेयर की गई फ़ोटो या वीडियो की फ़ाइल AppMint.getOpenedFile() से और कैप्शन यहाँ मिलता है। इस्तेमाल के बाद शेयर साफ़ करें, वरना अगली शुरुआत पर वह फिर दिखेगा। AI से बने ऐप sharedText() / onShared() इस्तेमाल कर सकते हैं, @/lib/appmintNative.

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” सूचना दिखाता है - इसे यूज़र के टैप पर पढ़ें, पेज लोड पर नहीं।

shareFiles ब्रिज#

window.WebToApk.shareFiles(filesJson: String, title: String, text: String): Boolean

navigator.share({files:[...]}) के लिए असली नेटिव फ़ाइल शेयर। Android WebView में Web Share API नहीं है, और text/plain ACTION_SEND फ़ाइल नहीं ले जा सकता - इसलिए पहले शेयर की गई इमेज बस सेव हो जाती थी, शेयर नहीं होती थी। filesJson है [{name, mimeType, base64}, ...]; हम हर फ़ाइल कैश में लिखते हैं, उसे ऐप के FileProvider से उपलब्ध कराते हैं, और ACTION_SEND / ACTION_SEND_MULTIPLE चलाते हैं ताकि असली Android शेयर शीट (WhatsApp, Gmail, …) खुले। शीट खुलने पर true लौटाता है।

उदाहरण

Android शेयर शीट से एक या ज़्यादा असली फ़ाइलें (इमेज, PDF…) शेयर करता है। पेज आम तौर पर मानक navigator.share({ files: [...] }) इस्तेमाल करते हैं, जिसे शेल यहाँ भेज देता है।

लौटाता है: शेयर शीट खुली तो true, वरना false (तुरंत)। ज़रूरी: कुछ नहीं।

पहले मानक API:

async function shareCanvas(canvas) {
  var blob = await new Promise(function (r) { canvas.toBlob(r, 'image/png'); });
  var file = new File([blob], 'drawing.png', { type: 'image/png' });
  if (!(navigator.canShare && navigator.canShare({ files: [file] }))) {
    alert('File sharing is not available here');
    return;
  }
  try {
    await navigator.share({ files: [file], title: 'My drawing', text: 'Made in my app' });
  } catch (e) { /* in a browser: the user closed the sheet */ }
}

रॉ कॉल [{name, mimeType, base64}] (data: प्रीफ़िक्स के बिना base64) की JSON स्ट्रिंग लेती है, फिर title और text:

function shareBase64Png(base64) {
  if (!(window.WebToApk && typeof window.WebToApk.shareFiles === 'function')) return false;
  var files = [{ name: 'receipt.png', mimeType: 'image/png', base64: base64 }];
  return window.WebToApk.shareFiles(JSON.stringify(files), 'Receipt', 'Your receipt');
}

टेबल को CSV फ़ाइल के रूप में एक्सपोर्ट करें (base64 से पहले टेक्स्ट UTF-8 में एन्कोड होता है):

function shareCsv(rows) {
  if (!(window.WebToApk && typeof window.WebToApk.shareFiles === 'function')) return;
  var csv = rows.map(function (r) {
    return r.map(function (c) { return '"' + String(c).replace(/"/g, '""') + '"'; }).join(',');
  }).join('\n');
  var base64 = btoa(unescape(encodeURIComponent(csv)));
  var files = [{ name: 'expenses.csv', mimeType: 'text/csv', base64: base64 }];
  if (!window.WebToApk.shareFiles(JSON.stringify(files), 'Expenses', '')) {
    showMessage('Could not open the share sheet');
  }
}

ध्यान दें: फ़ाइलें ऐप के कैश में लिखी जाती हैं और उसके FileProvider से शेयर होती हैं। name के असुरक्षित वर्ण _ बन जाते हैं। एक प्रकार की कई फ़ाइलें उसी प्रकार के साथ शेयर होती हैं; मिले-जुले प्रकार */* के रूप में शेयर होते हैं। पूरी फ़ाइल ब्रिज पर base64 के रूप में जाती है, इसलिए उसे कुछ MB तक रखें। जब navigator.share({files}) शीट न खोल सके, तो शेल फ़ाइलें डाउनलोड के रूप में सेव कर देता है और promise फिर भी पूरा होता है।

shareNative ब्रिज#

window.WebToApk.shareNative(title: String, text: String, url: String)

Android शेयर शीट, सिस्टम क्लिपबोर्ड, और पेज की खोली हुई विंडो बंद करना। ये सादे वेब के बराबर कॉल हैं (navigator.share, navigator.clipboard, window.close) जिनका जवाब नेटिव तरीके से दिया जाता है ताकि वे ऐप के अंदर भी वैसे ही चलें।

इसका वर्णन अलग से नहीं, बल्कि इसके समूह शेयर, क्लिपबोर्ड और विंडो में है।

उदाहरण

टाइटल, टेक्स्ट और लिंक के साथ Android शेयर शीट खोलता है। पेज आम तौर पर मानक navigator.share({title, text, url}) इस्तेमाल करते हैं, जिसे शेल यहाँ भेज देता है।

लौटाता है: कुछ नहीं (यह नहीं बता सकता कि यूज़र ने कौन-सा ऐप चुना)। ज़रूरी: कुछ नहीं।

पहले मानक API - यह मोबाइल ब्राउज़र में भी चलता है:

document.getElementById('share-btn').onclick = async function () {
  if (!navigator.share) { alert('Sharing is not available here'); return; }
  try {
    await navigator.share({ title: 'My app', text: 'Look at this', url: 'https://mysite.com/item/42' });
  } catch (e) {
    // in a browser: AbortError when the user closes the sheet
  }
};

रॉ कॉल, तीनों आर्गुमेंट स्ट्रिंग हैं (किसी को छोड़ने के लिए '' इस्तेमाल करें):

if (window.WebToApk && typeof window.WebToApk.shareNative === 'function') {
  window.WebToApk.shareNative('My app', 'Look at this', 'https://mysite.com/item/42');
}

सिर्फ़ टेक्स्ट, लिंक नहीं - जैसे गेम का स्कोर:

function shareScore(score) {
  if (!(window.WebToApk && typeof window.WebToApk.shareNative === 'function')) return;
  window.WebToApk.shareNative('My score', 'I scored ' + score + ' points. Can you beat it?', '');
}

ध्यान दें: शेयर किया गया टेक्स्ट text + नई लाइन + url होता है (या उनमें से बस एक)। title ईमेल का विषय और शेयर शीट का हेडिंग बनता है। सिर्फ़ टेक्स्ट और लिंक - फ़ाइल शेयर करने के लिए navigator.share({files}) इस्तेमाल करें (देखें shareFiles).

इन-ऐप संदेशों में share: बटन लिंक। जिस बटन का लिंक share:<text> हो, वह बिना किसी पेज कोड के उसी टेक्स्ट के साथ यही शेयर शीट खोलता है। Invite friends टेम्पलेट share:Try {app}: {store} इस्तेमाल करता है; ऐप अपना नाम और Play पता खुद भर देता है। आपका पेज जान सकता है कि ऐसा हुआ:

window.addEventListener('appmint:inapp', function (e) {
  var d = e.detail;
  if (d.type === 'clicked' && d.link && d.link.indexOf('share:') === 0) analytics('invite_shared', d.name);
});

अगर आप इन-ऐप संदेश खुद बनाते हैं (setInAppPresentation('none')), तो share: बटन को भी इसी तरह चलाएँ:

function runInAppButton(link) {
  if (link.indexOf('share:') === 0 && window.WebToApk && WebToApk.shareNative) {
    WebToApk.shareNative('', link.slice(6), '');   // text only
  }
}

copy:<text> लिंक शेयर करने के बजाय कॉपी करता है, जैसे प्रोमो संदेश से कूपन कोड:

window.addEventListener('appmint:inapp', function (e) {
  var d = e.detail;
  if (d.type === 'clicked' && d.link === 'copy:SAVE20') showToast('Code SAVE20 copied');
});

हर डॉक्स बिल्ड पर ऐप रनटाइम और उसकी उदाहरण फ़ाइलों से बनाया जाता है। Markdown में पढ़ें · सभी फ़ैमिली.

2026-10-03 को शिप किए गए ब्रिज से मिलाकर जाँचा गया।