ساخت APK رایگان

API پل جاوااسکریپت

اشتراک‌گذاری، کلیپ‌بورد و چاپ

برگه‌ی اشتراک‌گذاری اندروید، کلیپ‌بورد سیستم، متنی که اپلیکیشن دیگری به اپلیکیشن شما به اشتراک گذاشته و پنجره‌ی چاپ.

AppMint.pdf کمک‌کننده#

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 بیش از ۲۵ مگابایت) یا permission-denied (ذخیره‌سازی در اندروید ۷ تا ۹ رد شد) است. نیازمند: هیچ چیز - هر ساختی آن را دارد. ذخیره در Downloads در اندروید ۱۰ به بالا به مجوز نیاز ندارد.

گزینه‌ها: 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 و یک شناسه‌ی فراخوانی می‌گیرند؛ به‌جایش از کمکی بالا استفاده کنید:

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); });
}

نکته‌ها: دکمه‌ها و منوها را با @media print { .no-print { display: none } } از PDF پنهان کنید. یک PDF دانلودشده مثل هر دانلود دیگری «دانلود شد <name> · باز کردن» را نشان می‌دهد. 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() → Promise‌ها، مطابق استاندارد. نیازمند: هیچ چیز. در آغاز سند نصب می‌شود، پس بررسی‌ای که هنگام تجزیه‌ی صفحه‌ی شما انجام شود هم آن را می‌بیند.

کپی:

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');
  }
};

کپی یک تصویر (مثلاً یک QR code که روی canvas کشیده شده) با 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 و یک تصویر (تا ۱۶ مگابایت؛ در یک مورد، تصویر بر متن مقدم است) پشتیبانی می‌کند. read() با [item] و متن، HTML یا تصویر کلیپ‌بورد حل می‌شود ([] وقتی خالی است). فقط صفحه‌های خود اپلیکیشن می‌توانند آن را بخوانند: وب‌سایت خارجی باز شده داخل اپلیکیشن رد می‌شود (NotAllowedError). آن را با ضربه‌ی کاربر بخوانید - اندروید ۱۲ به بالا اعلان «از کلیپ‌بورد چسبانده شد» را نشان می‌دهد. در مرورگر همین کد با قواعد مجوز خود مرورگر کار می‌کند.

navigator.share استاندارد وب#

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

نمونه

Web Share API استاندارد که برای کار داخل اپلیکیشن آماده شده: متن و پیوند برگه‌ی اشتراک‌گذاری اندروید را باز می‌کنند و 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)، پس فایل‌ها را در حد چند مگابایت نگه دارید. اگر برگه‌ی اشتراک‌گذاری باز نشود، فایل‌ها به‌جایش به‌صورت دانلود ذخیره می‌شوند و promise همچنان حل می‌شود. canShare برای هر اشتراک متنی true برمی‌گرداند. اپلیکیشن‌های ساخته‌شده با هوش مصنوعی می‌توانند از share از @/lib/appmintNative.

window.print استاندارد وب#

window.print()

نمونه

فراخوانی استاندارد چاپ که برای کار داخل اپلیکیشن آماده شده: صفحه‌ی چاپ اندروید را باز می‌کند که کاربر در آن روی کاغذ چاپ می‌کند یا 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 { '&': '&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() را فراخوانی می‌کند، یا صفحه‌ای در iframe که window.print() خودش را فراخوانی می‌کند - سند همان 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');
  }
};

نکته‌ها: اندروید ۱۲ به بالا هنگام خواندن کلیپ‌بورد توسط یک اپلیکیشن، پیام «از کلیپ‌بورد شما چسبانده شد» را نشان می‌دهد.

__clipboardWrite پل#

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]). صفحه‌ها از 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 code، کپی کنید تا بتوان آن را در گفتگو چسباند:

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 اپلیکیشن به‌صورت content URI کپی می‌شود، پس در WhatsApp، Gmail یا Keep قابل چسباندن است.

__printHtml پل#

window.WebToApk.__printHtml(html: String, baseUrl: String, title: String)

[html] را - سند سریال‌شده‌ی یک iframe هم‌مبدأ که توسط shim مربوط به `window.print()` ([PrintShim]) فرستاده شده - از طریق یک WebView خارج از صفحه در [baseUrl] چاپ می‌کند، چون آداپتور چاپ WebView اصلی فقط می‌تواند کل صفحه را چاپ کند. [title] نام کار چاپ است (وقتی خالی باشد "<App name> Document").

نمونه

انتقال داخلی پشت چاپ یک iframe: iframe.contentWindow.print() (و window.print() خودِ صفحه‌ی iframe) سند آن iframe را به اینجا می‌فرستد و اپلیکیشن آن را از طریق صفحه‌ی چاپ اندروید چاپ می‌کند. صفحه‌ها از فراخوانی‌های استاندارد استفاده می‌کنند؛ هرگز مستقیم این را صدا نزنید.

مقدار بازگشتی: هیچ. نیازها: هیچ.

الگوی رسیدی که این کار را ممکن می‌کند - یک 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 را درست پیش از گرفتن عکس لحظه‌ای با beforeprint روی پنجره‌ی iframe تنظیم کنید:

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، نشانی‌ای که پیوندهای نسبی آن نسبت به آن حل می‌شوند (نشانی خود صفحه برای iframe از نوع about:blank) و نام کار چاپ (<title> مربوط به iframe، وگرنه عنوان صفحه). عکس لحظه‌ای هنگام فراخوانی print() گرفته می‌شود - اسکریپت‌های داخل آن دوباره اجرا نمی‌شوند - و beforeprint / afterprint روی پنجره‌ی iframe در اطراف آن فعال می‌شوند. iframe غیرهم‌مبدأ را نمی‌توان از صفحه چاپ کرد.

clearSharedText پل#

window.WebToApk.clearSharedText()

اشتراک نگه‌داشته‌شده را پس از مصرف توسط صفحه پاک می‌کند.

نمونه

متن یا پیوندی را که به اپلیکیشن به اشتراک گذاشته شده بود، پس از اینکه صفحه‌ی شما از آن استفاده کرد فراموش می‌کند.

بازگشتی: هیچ. نیازمند: هیچ چیز (خود اشتراک‌گذاری به دریافت اشتراک از اپلیکیشن‌های دیگر با علامت‌دار بودن متن و پیوند نیاز دارد).

اشتراک نگه‌داشته‌شده را بخوانید، استفاده کنید، سپس پاکش کنید تا بعد از بارگذاری مجدد دوباره پردازش نشود:

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 }); // اگر برگه‌ای نیست، صفحه‌ی فروشگاه 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');
}

یک دکمه‌ی «کپی» روی هر بلوک کد، با استفاده از پاسخ همزمان برای به‌روزرسانی برچسب:

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). اندروید ۱۳ به بالا پیش‌نمایش کوچک «کپی شد» خودش را نشان می‌دهد، پس شاید به پیام خودتان آنجا نیازی نباشد.

getSharedText پل#

window.WebToApk.getSharedText(): String

متن یا پیوندی که اپلیکیشن دیگری به این اپلیکیشن به اشتراک گذاشته («اشتراک به <app>» - ویدیوی YouTube که از اپلیکیشن YouTube به اشتراک گذاشته شود به‌صورت پیوندش می‌رسد) به‌صورت JSON `{text, subject, url, receivedAt}` یا "" وقتی چیزی به اشتراک گذاشته نشده. تا خوانده شدن نگه داشته می‌شود، پس اپلیکیشنی که بعد از اشتراک بالا می‌آید هم آن را می‌بیند؛ اشتراکی که هنگام اجرای اپلیکیشن برسد `appmint:shared` را هم فعال می‌کند. عکس یا ویدیویی که با توضیح به اشتراک گذاشته شود فایل را از طریق AppMint.getOpenedFile() و توضیح را اینجا تحویل می‌دهد. نیازمند گزینه‌ی «دریافت اشتراک از اپلیکیشن‌های دیگر» در ساخت با علامت‌دار بودن «متن و پیوند» است که ورودی برگه‌ی اشتراک‌گذاری را ثبت می‌کند.

نمونه

متن یا پیوندی که اپلیکیشن دیگری به اپلیکیشن شما به اشتراک گذاشته («اشتراک ← اپلیکیشن شما») به‌صورت یک رشته‌ی JSON، یا "" وقتی چیزی به اشتراک گذاشته نشده.

بازگشتی: یک رشته‌ی JSON به شکل {text, subject, url, receivedAt} یا "" (همزمان). url اولین پیوند http(s):// است که در text پیدا شده (یا "")؛ receivedAt یک زمان به میلی‌ثانیه است. نیازمند: روشن بودن دریافت اشتراک از اپلیکیشن‌های دیگر هنگام ساخت، با علامت‌دار بودن متن و پیوند - این کار اپلیکیشن شما را در منوی اشتراک‌گذاری اپلیکیشن‌های دیگر قرار می‌دهد.

اشتراک تا زمانی که پاکش نکنید نگه داشته می‌شود، پس آن را در شروع بخوانید و به اشتراک‌هایی که هنگام اجرای اپلیکیشن می‌رسند گوش دهید:

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() و توضیح را اینجا تحویل می‌دهد. پس از استفاده اشتراک را پاک کنید، وگرنه در شروع بعدی دوباره آن را می‌بینید. اپلیکیشن‌های ساخته‌شده با هوش مصنوعی می‌توانند از 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 صفحه را همان‌طور که روی صفحه‌نمایش است و با 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 بیش از ۲۵ مگابایت) یا permission-denied (ذخیره‌سازی در اندروید ۷ تا ۹ رد شد) است. نیازمند: هیچ چیز - هر ساختی آن را دارد. ذخیره در Downloads در اندروید ۱۰ به بالا به مجوز نیاز ندارد.

گزینه‌ها: 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 و یک شناسه‌ی فراخوانی می‌گیرند؛ به‌جایش از کمکی بالا استفاده کنید:

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); });
}

نکته‌ها: دکمه‌ها و منوها را با @media print { .no-print { display: none } } از PDF پنهان کنید. یک PDF دانلودشده مثل هر دانلود دیگری «دانلود شد <name> · باز کردن» را نشان می‌دهد. 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 صفحه را همان‌طور که روی صفحه‌نمایش است و با 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 بیش از ۲۵ مگابایت) یا permission-denied (ذخیره‌سازی در اندروید ۷ تا ۹ رد شد) است. نیازمند: هیچ چیز - هر ساختی آن را دارد. ذخیره در Downloads در اندروید ۱۰ به بالا به مجوز نیاز ندارد.

گزینه‌ها: 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 و یک شناسه‌ی فراخوانی می‌گیرند؛ به‌جایش از کمکی بالا استفاده کنید:

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); });
}

نکته‌ها: دکمه‌ها و منوها را با @media print { .no-print { display: none } } از PDF پنهان کنید. یک PDF دانلودشده مثل هر دانلود دیگری «دانلود شد <name> · باز کردن» را نشان می‌دهد. fromHtml اسکریپت‌های HTML را اجرا می‌کند (نمودارهایی که با اسکریپت رسم می‌شوند ظاهر می‌شوند) اما به قابلیت‌های بومی اپلیکیشن دسترسی ندارد. صفحه‌های بلندتر از یک برگ همان‌طور که Chrome تقسیم می‌کند تقسیم می‌شوند؛ برای کنترل محل تقسیم از break-before: page استفاده کنید.

print پل#

window.WebToApk.print()

صفحه را همان‌طور که اکنون هست به پنجره‌ی چاپ اندروید می‌سپارد که می‌تواند روی کاغذ چاپ کند یا PDF ذخیره کند. چیزی برای پیکربندی نیست - WebView سند را رندر می‌کند.

به‌جای خودش، با گروهش چاپ توضیح داده می‌شود.

نمونه

صفحه‌ی چاپ اندروید را برای صفحه به شکل فعلی‌اش باز می‌کند - روی کاغذ چاپ کنید یا «ذخیره به‌صورت 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 را چاپ می‌کند - صفحه‌ی اصلی. print() خودِ یک iframe هم‌مبدأ فقط همان 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 }); // اگر برگه‌ای نیست، صفحه‌ی فروشگاه r.result: 'shown' | 'not_from_play' | 'quota' | 'error'. RatePrompt را ببینید.

با گروهش، برگه‌ی نظرسنجی درون‌برنامه‌ای Google Play، توضیح داده می‌شود، نه جداگانه.

نمونه

متنی را که اکنون روی کلیپ‌بورد گوشی است می‌خواند. صفحه‌ها معمولاً از navigator.clipboard.readText() استاندارد استفاده می‌کنند که پوسته آن را به اینجا هدایت می‌کند.

بازگشتی: متن، یا "" وقتی کلیپ‌بورد خالی است یا خوانده نمی‌شود (همزمان). نیازمند: هیچ چیز.

ابتدا API استاندارد - برای مثال یک دکمه‌ی «چسباندن کد»:

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');
};

نکته‌ها: فقط صفحه‌های خود اپلیکیشن شما می‌توانند آن را بخوانند: وب‌سایت خارجی که داخل اپلیکیشن باز شده "" می‌گیرد. اندروید فقط وقتی اجازه می‌دهد اپلیکیشن کلیپ‌بورد را بخواند که روی صفحه باشد و اندروید ۱۲ به بالا اعلان «از کلیپ‌بورد چسبانده شد» را نشان می‌دهد - آن را با ضربه‌ی کاربر بخوانید، نه هنگام بارگذاری صفحه.

shareFiles پل#

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

اشتراک‌گذاری فایل واقعاً بومی برای navigator.share({files:[...]}). WebView اندروید Web Share API ندارد و ACTION_SEND از نوع text/plain نمی‌تواند فایل حمل کند - پس پیش از این یک تصویر اشتراکی فقط ذخیره می‌شد، نه به اشتراک گذاشته. filesJson برابر [{name, mimeType, base64}, ...] است؛ هر کدام را در حافظه‌ی پنهان می‌نویسیم، از طریق FileProvider اپلیکیشن در دسترس می‌گذاریم و ACTION_SEND / ACTION_SEND_MULTIPLE را اجرا می‌کنیم تا برگه‌ی اشتراک‌گذاری واقعی اندروید (WhatsApp، Gmail و ...) باز شود. اگر برگه باز شد true برمی‌گرداند.

نمونه

یک یا چند فایل واقعی (تصویر، 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 */ }
}

فراخوانی خام یک رشته‌ی JSON از [{name, mimeType, base64}] (base64 بدون پیشوند data:) می‌گیرد، سپس 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 از پل عبور می‌کند، پس آن را در حد چند مگابایت نگه دارید. وقتی navigator.share({files}) نتواند برگه را باز کند، پوسته فایل‌ها را به‌صورت دانلود ذخیره می‌کند و promise همچنان حل می‌شود.

shareNative پل#

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

برگه‌ی اشتراک‌گذاری اندروید، کلیپ‌بورد سیستم و بستن پنجره‌ای که صفحه باز کرده. این‌ها معادل‌های وب ساده‌اند (navigator.share، navigator.clipboard، window.close) که به‌صورت بومی پاسخ داده می‌شوند تا داخل اپلیکیشن هم همان‌طور رفتار کنند.

به‌جای خودش، با گروهش اشتراک‌گذاری، کلیپ‌بورد و پنجره توضیح داده می‌شود.

نمونه

برگه‌ی اشتراک‌گذاری اندروید را با یک عنوان، متن و پیوند باز می‌کند. صفحه‌ها معمولاً از 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> است همین برگه‌ی اشتراک‌گذاری را با آن متن باز می‌کند، بدون هیچ کد صفحه. قالب دعوت از دوستان از 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');
});