@open-wxa/wxa-runner-core 0.11.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +8 -3
- package/dist/index.d.ts +8 -3
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/runtime/host.js +231 -25
- package/dist/runtime/host.js.map +1 -1
- package/dist/{setup-DhDDVlit.d.mts → setup-D0ubZt2C.d.mts} +2 -0
- package/dist/{setup-DhDDVlit.d.ts → setup-D0ubZt2C.d.ts} +2 -0
- package/dist/setup.d.mts +1 -1
- package/dist/setup.d.ts +1 -1
- package/dist/test-api.d.mts +12 -2
- package/dist/test-api.d.ts +12 -2
- package/dist/{testApi-BbK_1vhj.d.mts → testApi-Df0ltBI6.d.ts} +29 -2
- package/dist/{testApi-DbTnccYV.d.ts → testApi-x2Yph6M2.d.mts} +29 -2
- package/dist/web.d.mts +2 -0
- package/dist/web.d.ts +2 -0
- package/package.json +3 -3
package/dist/runtime/host.js
CHANGED
|
@@ -1697,16 +1697,11 @@ ${frames}` : "");
|
|
|
1697
1697
|
}
|
|
1698
1698
|
|
|
1699
1699
|
// src/runtime/host/api/webView.ts
|
|
1700
|
-
function createWebViewApis({ documentOf, emitToWebview }) {
|
|
1700
|
+
function createWebViewApis({ documentOf, emitToWebview, windows }) {
|
|
1701
|
+
if (windows) return createWindowApis(documentOf, windows);
|
|
1701
1702
|
const find = (webviewId, htmlId) => documentOf(webviewId)?.querySelector(`iframe[data-wxa-html-id="${Number(htmlId)}"]`) ?? null;
|
|
1702
1703
|
const reportStart = (webviewId, htmlId, src) => emitToWebview(webviewId, "onWebviewStartLoad", { htmlId, src, isMainFrame: true });
|
|
1703
1704
|
const reportFinish = (webviewId, htmlId, src) => emitToWebview(webviewId, "onWebviewFinishLoad", { htmlId, src });
|
|
1704
|
-
const place = (frame, position) => {
|
|
1705
|
-
if (!position) return;
|
|
1706
|
-
for (const side of ["left", "top", "width", "height"]) {
|
|
1707
|
-
if (typeof position[side] === "number") frame.style[side] = `${position[side]}px`;
|
|
1708
|
-
}
|
|
1709
|
-
};
|
|
1710
1705
|
return {
|
|
1711
1706
|
insertHTMLWebView: (args, { api, webviewId }) => {
|
|
1712
1707
|
const doc = documentOf(webviewId);
|
|
@@ -1737,7 +1732,9 @@ ${frames}` : "");
|
|
|
1737
1732
|
place(frame, args.position);
|
|
1738
1733
|
if (args.src) {
|
|
1739
1734
|
const src = String(args.src);
|
|
1735
|
+
warnCrossSite(src);
|
|
1740
1736
|
frame.dataset.wxaLoading = src;
|
|
1737
|
+
frame.dataset.wxaSrc = src;
|
|
1741
1738
|
reportStart(webviewId, Number(args.htmlId), src);
|
|
1742
1739
|
frame.src = src;
|
|
1743
1740
|
}
|
|
@@ -1749,6 +1746,194 @@ ${frames}` : "");
|
|
|
1749
1746
|
}
|
|
1750
1747
|
};
|
|
1751
1748
|
}
|
|
1749
|
+
function createWindowApis(documentOf, windows) {
|
|
1750
|
+
return {
|
|
1751
|
+
insertHTMLWebView: (args, { api, webviewId }) => {
|
|
1752
|
+
const doc = documentOf(webviewId);
|
|
1753
|
+
if (!doc) return fail(api, "page not found");
|
|
1754
|
+
windows.insert(webviewId, Number(args.htmlId), doc, args.position);
|
|
1755
|
+
return ok(api);
|
|
1756
|
+
},
|
|
1757
|
+
updateHTMLWebView: (args, { api, webviewId }) => {
|
|
1758
|
+
if (!windows.update(webviewId, Number(args.htmlId), args.position, args.src ? String(args.src) : void 0)) {
|
|
1759
|
+
return fail(api, "web-view not found");
|
|
1760
|
+
}
|
|
1761
|
+
return ok(api);
|
|
1762
|
+
},
|
|
1763
|
+
removeHTMLWebView: (args, { api, webviewId }) => {
|
|
1764
|
+
windows.remove(webviewId, Number(args.htmlId));
|
|
1765
|
+
return ok(api);
|
|
1766
|
+
}
|
|
1767
|
+
};
|
|
1768
|
+
}
|
|
1769
|
+
function iframeWebViews(doc) {
|
|
1770
|
+
return Array.from(doc?.querySelectorAll("iframe[data-wxa-src]") ?? []).map((frame) => ({ src: frame.dataset.wxaSrc, windowName: null }));
|
|
1771
|
+
}
|
|
1772
|
+
var COMMIT_WAIT_MS = 5e3;
|
|
1773
|
+
var WebViewWindows = class {
|
|
1774
|
+
/** @param isShown 页面当前是否显示:隐藏的页面先记下地址,显示时再打开窗口 */
|
|
1775
|
+
constructor(device, isShown) {
|
|
1776
|
+
this.device = device;
|
|
1777
|
+
this.isShown = isShown;
|
|
1778
|
+
this.records = /* @__PURE__ */ new Map();
|
|
1779
|
+
}
|
|
1780
|
+
insert(webviewId, htmlId, doc, position) {
|
|
1781
|
+
const previous = this.records.get(windowName(webviewId, htmlId));
|
|
1782
|
+
previous?.placeholder.remove();
|
|
1783
|
+
const placeholder = doc.createElement("div");
|
|
1784
|
+
placeholder.dataset.wxaHtmlId = String(htmlId);
|
|
1785
|
+
placeholder.style.cssText = "position:fixed;z-index:2147483647;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:24px;background:#f7f7f7;color:#666;font:14px/1.6 sans-serif;text-align:center;word-break:break-all";
|
|
1786
|
+
const status = doc.createElement("div");
|
|
1787
|
+
const button = doc.createElement("button");
|
|
1788
|
+
button.textContent = "\u5728\u65B0\u7A97\u53E3\u6253\u5F00 H5";
|
|
1789
|
+
button.style.cssText = "padding:8px 16px;border:0;border-radius:4px;background:#07c160;color:#fff;font-size:14px";
|
|
1790
|
+
placeholder.append(status, button);
|
|
1791
|
+
place(placeholder, position);
|
|
1792
|
+
doc.body.appendChild(placeholder);
|
|
1793
|
+
const record = { webviewId, name: windowName(webviewId, htmlId), placeholder, status, src: previous?.src, win: previous?.win ?? null };
|
|
1794
|
+
this.records.set(record.name, record);
|
|
1795
|
+
button.addEventListener("click", () => {
|
|
1796
|
+
if (record.win && !record.win.closed) record.win.focus();
|
|
1797
|
+
else this.open(record);
|
|
1798
|
+
});
|
|
1799
|
+
this.render(record);
|
|
1800
|
+
}
|
|
1801
|
+
/** @returns 找不到这个 web-view 时为 false */
|
|
1802
|
+
update(webviewId, htmlId, position, src) {
|
|
1803
|
+
const record = this.records.get(windowName(webviewId, htmlId));
|
|
1804
|
+
if (!record) return false;
|
|
1805
|
+
place(record.placeholder, position);
|
|
1806
|
+
if (src && src !== record.src) {
|
|
1807
|
+
record.src = src;
|
|
1808
|
+
if (this.isShown(webviewId)) this.open(record);
|
|
1809
|
+
else this.render(record);
|
|
1810
|
+
}
|
|
1811
|
+
return true;
|
|
1812
|
+
}
|
|
1813
|
+
remove(webviewId, htmlId) {
|
|
1814
|
+
const record = this.records.get(windowName(webviewId, htmlId));
|
|
1815
|
+
if (!record) return;
|
|
1816
|
+
this.records.delete(record.name);
|
|
1817
|
+
close(record);
|
|
1818
|
+
record.placeholder.remove();
|
|
1819
|
+
}
|
|
1820
|
+
pageShown(webviewId) {
|
|
1821
|
+
for (const record of this.recordsOf(webviewId)) {
|
|
1822
|
+
if (record.src && !(record.win && !record.win.closed)) this.open(record);
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
pageHidden(webviewId) {
|
|
1826
|
+
for (const record of this.recordsOf(webviewId)) {
|
|
1827
|
+
close(record);
|
|
1828
|
+
this.render(record);
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
/** 页面关闭:渲染层已经或即将被删除,不必再动占位 */
|
|
1832
|
+
pageDestroyed(webviewId) {
|
|
1833
|
+
for (const record of this.recordsOf(webviewId)) {
|
|
1834
|
+
this.records.delete(record.name);
|
|
1835
|
+
close(record);
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
closeAll() {
|
|
1839
|
+
for (const record of this.records.values()) close(record);
|
|
1840
|
+
}
|
|
1841
|
+
/** 页面里的 web-view,按创建顺序;还没设置 src 的不算 */
|
|
1842
|
+
list(webviewId) {
|
|
1843
|
+
return this.recordsOf(webviewId).flatMap((record) => record.src ? [{ src: record.src, windowName: record.name }] : []);
|
|
1844
|
+
}
|
|
1845
|
+
recordsOf(webviewId) {
|
|
1846
|
+
return [...this.records.values()].filter((record) => record.webviewId === webviewId);
|
|
1847
|
+
}
|
|
1848
|
+
open(record) {
|
|
1849
|
+
if (!record.src) return;
|
|
1850
|
+
if (record.win && !record.win.closed) {
|
|
1851
|
+
this.navigate(record);
|
|
1852
|
+
} else {
|
|
1853
|
+
const features = `popup,width=${this.device.screenWidth},height=${this.device.screenHeight}`;
|
|
1854
|
+
record.win = window.open(record.src, record.name, features);
|
|
1855
|
+
if (record.win) {
|
|
1856
|
+
record.opening = { src: record.src, at: Date.now() };
|
|
1857
|
+
notify("open", record.name, record.src);
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
this.render(record);
|
|
1861
|
+
}
|
|
1862
|
+
/**
|
|
1863
|
+
* 已打开的窗口跳到最新的 src。用已有的引用跳转,不靠窗口名:网页可能改了自己的 window.name,按名字找不到时会多开一个窗口。
|
|
1864
|
+
*
|
|
1865
|
+
* Chrome 里新窗口的初始页面还没提交时改它的地址,这次跳转偶尔会被丢掉,窗口停在原来的网页上(不经过 CDP 也一样)。
|
|
1866
|
+
* 窗口刚打开就改 src 会碰上,所以等初始页面提交后再跳
|
|
1867
|
+
*/
|
|
1868
|
+
navigate(record) {
|
|
1869
|
+
const win = record.win;
|
|
1870
|
+
if (!win || win.closed || !record.src || record.retry !== void 0) return;
|
|
1871
|
+
if (record.opening && !committed(win, record.opening.src) && Date.now() - record.opening.at < COMMIT_WAIT_MS) {
|
|
1872
|
+
record.retry = window.setTimeout(() => {
|
|
1873
|
+
record.retry = void 0;
|
|
1874
|
+
this.navigate(record);
|
|
1875
|
+
}, 20);
|
|
1876
|
+
return;
|
|
1877
|
+
}
|
|
1878
|
+
record.opening = void 0;
|
|
1879
|
+
win.location.href = record.src;
|
|
1880
|
+
}
|
|
1881
|
+
render(record) {
|
|
1882
|
+
const opened = record.win && !record.win.closed;
|
|
1883
|
+
const [title, detail] = !record.src ? ["web-view \u8FD8\u6CA1\u6709\u8BBE\u7F6E src", ""] : opened ? ["H5 \u5DF2\u5728\u65B0\u7A97\u53E3\u6253\u5F00", record.src] : record.win === null && this.isShown(record.webviewId) ? ["\u6D4F\u89C8\u5668\u62E6\u622A\u4E86\u5F39\u51FA\u7A97\u53E3\uFF0C\u70B9\u4E0B\u9762\u7684\u6309\u94AE\u6253\u5F00 H5", record.src] : ["H5 \u5728\u65B0\u7A97\u53E3\u6253\u5F00", record.src];
|
|
1884
|
+
record.status.textContent = "";
|
|
1885
|
+
const heading = record.status.ownerDocument.createElement("div");
|
|
1886
|
+
heading.textContent = title;
|
|
1887
|
+
heading.style.cssText = "color:#333;font-size:16px";
|
|
1888
|
+
record.status.append(heading);
|
|
1889
|
+
if (detail) record.status.append(detail);
|
|
1890
|
+
}
|
|
1891
|
+
};
|
|
1892
|
+
function windowName(webviewId, htmlId) {
|
|
1893
|
+
return `wxa-h5-${webviewId}-${htmlId}`;
|
|
1894
|
+
}
|
|
1895
|
+
function committed(win, src) {
|
|
1896
|
+
try {
|
|
1897
|
+
return win.location.href !== "about:blank" || src === "about:blank";
|
|
1898
|
+
} catch {
|
|
1899
|
+
return true;
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
function close(record) {
|
|
1903
|
+
clearTimeout(record.retry);
|
|
1904
|
+
record.retry = void 0;
|
|
1905
|
+
record.opening = void 0;
|
|
1906
|
+
if (!record.win) return;
|
|
1907
|
+
record.win.close();
|
|
1908
|
+
record.win = null;
|
|
1909
|
+
notify("close", record.name);
|
|
1910
|
+
}
|
|
1911
|
+
function notify(type, name, src) {
|
|
1912
|
+
const listener = window.__wxa_webview_window_event__;
|
|
1913
|
+
listener?.(type, name, src)?.catch(() => void 0);
|
|
1914
|
+
}
|
|
1915
|
+
function place(element2, position) {
|
|
1916
|
+
if (!position) return;
|
|
1917
|
+
for (const side of ["left", "top", "width", "height"]) {
|
|
1918
|
+
if (typeof position[side] === "number") element2.style[side] = `${position[side]}px`;
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
var warnedOrigins = /* @__PURE__ */ new Set();
|
|
1922
|
+
function warnCrossSite(src) {
|
|
1923
|
+
let url;
|
|
1924
|
+
try {
|
|
1925
|
+
url = new URL(src, location.href);
|
|
1926
|
+
} catch {
|
|
1927
|
+
return;
|
|
1928
|
+
}
|
|
1929
|
+
if (!["http:", "https:"].includes(url.protocol)) return;
|
|
1930
|
+
if (url.hostname === location.hostname && url.protocol === location.protocol) return;
|
|
1931
|
+
if (warnedOrigins.has(url.origin)) return;
|
|
1932
|
+
warnedOrigins.add(url.origin);
|
|
1933
|
+
console.warn(
|
|
1934
|
+
`[wxa-runner] web-view \u52A0\u8F7D\u7684 ${url.origin} \u4E0E\u6A21\u62DF\u5668\uFF08${location.origin}\uFF09\u4E0D\u662F\u540C\u4E00\u4E2A\u7AD9\u70B9\uFF0C\u6D4F\u89C8\u5668\u6309\u8DE8\u7AD9\u5D4C\u5165\u5904\u7406\uFF0C\u7F51\u9875\u7684 Cookie \u53EF\u80FD\u4E0D\u751F\u6548\uFF08\u5FAE\u4FE1\u91CC\u7684\u5C0F\u7A0B\u5E8F\u6CA1\u6709\u8FD9\u4E2A\u95EE\u9898\uFF09\u3002\u9700\u8981 Cookie \u65F6\u8BA9\u7F51\u9875\u5728\u65B0\u7A97\u53E3\u6253\u5F00\uFF1A\u547D\u4EE4\u884C\u52A0 --webview-window\uFF0CPlaywright \u7528 test.use({ wxaWebView: 'window' })`
|
|
1935
|
+
);
|
|
1936
|
+
}
|
|
1752
1937
|
function readableUrl(frame) {
|
|
1753
1938
|
try {
|
|
1754
1939
|
return frame.contentWindow?.location.href ?? null;
|
|
@@ -2089,15 +2274,15 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2089
2274
|
layer.append(mask, sheet);
|
|
2090
2275
|
container.appendChild(layer);
|
|
2091
2276
|
columns.forEach((column, index) => column.setItems(options.columns[index], options.current[index] ?? 0));
|
|
2092
|
-
const
|
|
2277
|
+
const close2 = (value) => {
|
|
2093
2278
|
layer.remove();
|
|
2094
2279
|
resolve(value);
|
|
2095
2280
|
};
|
|
2096
|
-
cancel.addEventListener("click", () =>
|
|
2097
|
-
mask.addEventListener("click", () =>
|
|
2281
|
+
cancel.addEventListener("click", () => close2(null));
|
|
2282
|
+
mask.addEventListener("click", () => close2(null));
|
|
2098
2283
|
confirm.addEventListener("click", () => {
|
|
2099
2284
|
columns.forEach((column) => column.settle());
|
|
2100
|
-
|
|
2285
|
+
close2(columns.map((column) => column.index));
|
|
2101
2286
|
});
|
|
2102
2287
|
return {
|
|
2103
2288
|
result,
|
|
@@ -2435,19 +2620,19 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2435
2620
|
modal.appendChild(input);
|
|
2436
2621
|
}
|
|
2437
2622
|
const actions = element("div", "wxa-modal-actions");
|
|
2438
|
-
const
|
|
2623
|
+
const close2 = (confirm2) => {
|
|
2439
2624
|
wrapper.remove();
|
|
2440
2625
|
resolve({ confirm: confirm2, cancel: !confirm2, ...options.editable ? { content: input.value } : {} });
|
|
2441
2626
|
};
|
|
2442
2627
|
if (options.showCancel !== false) {
|
|
2443
2628
|
const cancel = element("button", "wxa-modal-cancel", options.cancelText || "\u53D6\u6D88");
|
|
2444
2629
|
cancel.style.color = options.cancelColor || "#000";
|
|
2445
|
-
cancel.addEventListener("click", () =>
|
|
2630
|
+
cancel.addEventListener("click", () => close2(false));
|
|
2446
2631
|
actions.appendChild(cancel);
|
|
2447
2632
|
}
|
|
2448
2633
|
const confirm = element("button", "wxa-modal-confirm", options.confirmText || "\u786E\u5B9A");
|
|
2449
2634
|
confirm.style.color = options.confirmColor || "#576b95";
|
|
2450
|
-
confirm.addEventListener("click", () =>
|
|
2635
|
+
confirm.addEventListener("click", () => close2(true));
|
|
2451
2636
|
actions.appendChild(confirm);
|
|
2452
2637
|
modal.appendChild(actions);
|
|
2453
2638
|
wrapper.appendChild(modal);
|
|
@@ -2459,7 +2644,7 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2459
2644
|
const wrapper = document.createElement("div");
|
|
2460
2645
|
const mask = maskElement(true);
|
|
2461
2646
|
const sheet = element("div", "wxa-actionsheet");
|
|
2462
|
-
const
|
|
2647
|
+
const close2 = (index) => {
|
|
2463
2648
|
wrapper.remove();
|
|
2464
2649
|
resolve(index);
|
|
2465
2650
|
};
|
|
@@ -2467,13 +2652,13 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2467
2652
|
options.itemList.forEach((text, index) => {
|
|
2468
2653
|
const button = element("button", "wxa-actionsheet-item", text);
|
|
2469
2654
|
button.style.color = options.itemColor || "#000";
|
|
2470
|
-
button.addEventListener("click", () =>
|
|
2655
|
+
button.addEventListener("click", () => close2(index));
|
|
2471
2656
|
sheet.appendChild(button);
|
|
2472
2657
|
});
|
|
2473
2658
|
const cancel = element("button", "wxa-actionsheet-cancel", "\u53D6\u6D88");
|
|
2474
|
-
cancel.addEventListener("click", () =>
|
|
2659
|
+
cancel.addEventListener("click", () => close2(null));
|
|
2475
2660
|
sheet.appendChild(cancel);
|
|
2476
|
-
mask.addEventListener("click", () =>
|
|
2661
|
+
mask.addEventListener("click", () => close2(null));
|
|
2477
2662
|
wrapper.append(mask, sheet);
|
|
2478
2663
|
this.overlay.appendChild(wrapper);
|
|
2479
2664
|
});
|
|
@@ -2494,10 +2679,10 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2494
2679
|
notice.setAttribute("role", "alert");
|
|
2495
2680
|
const text = element("div", "wxa-notice-text");
|
|
2496
2681
|
text.append(element("div", "wxa-notice-title", title), element("div", "wxa-notice-message", message));
|
|
2497
|
-
const
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
notice.append(element("span", "wxa-notice-icon", "!"), text,
|
|
2682
|
+
const close2 = element("button", "wxa-notice-close", "\xD7");
|
|
2683
|
+
close2.setAttribute("aria-label", "\u5173\u95ED");
|
|
2684
|
+
close2.addEventListener("click", () => this.hideNotice());
|
|
2685
|
+
notice.append(element("span", "wxa-notice-icon", "!"), text, close2);
|
|
2501
2686
|
this.stage.appendChild(notice);
|
|
2502
2687
|
this.noticeEl = notice;
|
|
2503
2688
|
this.noticeTimer = setTimeout(() => this.hideNotice(), NOTICE_DURATION);
|
|
@@ -2579,6 +2764,11 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2579
2764
|
this.shell = new PhoneShell(root, info.device);
|
|
2580
2765
|
this.tabPaths = new Set((info.wxConfig.tabBar?.list || []).map((item) => stripHtml(item.pagePath)));
|
|
2581
2766
|
this.storage = new MiniProgramStorage(window.localStorage, info.appid);
|
|
2767
|
+
this.webViewWindows = info.webViewWindow ? new WebViewWindows(info.device, (webviewId) => this.currentPage()?.id === webviewId) : null;
|
|
2768
|
+
if (this.webViewWindows) {
|
|
2769
|
+
const windows = this.webViewWindows;
|
|
2770
|
+
window.addEventListener("pagehide", () => windows.closeAll());
|
|
2771
|
+
}
|
|
2582
2772
|
const tabBar = info.wxConfig.tabBar ? { ...info.wxConfig.tabBar, list: info.wxConfig.tabBar.list.map((item) => ({ ...item, pagePath: stripHtml(item.pagePath) })) } : void 0;
|
|
2583
2773
|
this.shell.setTabBar(tabBar, (pagePath) => this.enqueueRoute(() => this.switchTab(pagePath)));
|
|
2584
2774
|
this.shell.onBack(() => this.enqueueRoute(() => this.navigateBack(1)));
|
|
@@ -2848,11 +3038,12 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2848
3038
|
}
|
|
2849
3039
|
closePage(page, options = { keepTab: true }) {
|
|
2850
3040
|
if (options.keepTab && this.tabPaths.has(page.path) && this.tabPages.get(page.path) === page) {
|
|
2851
|
-
|
|
3041
|
+
this.hidePage(page);
|
|
2852
3042
|
return;
|
|
2853
3043
|
}
|
|
2854
3044
|
if (this.tabPages.get(page.path) === page) this.tabPages.delete(page.path);
|
|
2855
3045
|
this.pages.delete(page.id);
|
|
3046
|
+
this.webViewWindows?.pageDestroyed(page.id);
|
|
2856
3047
|
page.destroy();
|
|
2857
3048
|
for (const [canvasNumber, record] of this.canvases) {
|
|
2858
3049
|
if (record.webviewId === page.id) this.canvases.delete(canvasNumber);
|
|
@@ -2860,9 +3051,10 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2860
3051
|
}
|
|
2861
3052
|
activate(page, openType) {
|
|
2862
3053
|
for (const other of this.pages.values()) {
|
|
2863
|
-
if (other !== page)
|
|
3054
|
+
if (other !== page) this.hidePage(other);
|
|
2864
3055
|
}
|
|
2865
3056
|
page.show();
|
|
3057
|
+
this.webViewWindows?.pageShown(page.id);
|
|
2866
3058
|
page.navigation = { ...page.navigation, showBack: this.stack.size > 1 };
|
|
2867
3059
|
this.shell.setNavigation(page.navigation);
|
|
2868
3060
|
this.shell.renderTabBar(this.tabPaths.has(page.path) ? page.path : null);
|
|
@@ -2875,6 +3067,14 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2875
3067
|
}, ROUTE_DONE_DELAY);
|
|
2876
3068
|
this.routeListeners.forEach((listener) => listener(page, openType));
|
|
2877
3069
|
}
|
|
3070
|
+
hidePage(page) {
|
|
3071
|
+
page.hide();
|
|
3072
|
+
this.webViewWindows?.pageHidden(page.id);
|
|
3073
|
+
}
|
|
3074
|
+
/** 页面里设置过 src 的 web-view,按创建顺序 */
|
|
3075
|
+
webViewsOf(page) {
|
|
3076
|
+
return this.webViewWindows ? this.webViewWindows.list(page.id) : iframeWebViews(page.win?.document);
|
|
3077
|
+
}
|
|
2878
3078
|
/** 宿主地址栏同步为当前页面,刷新后可回到同一页面 */
|
|
2879
3079
|
updateLocation(page) {
|
|
2880
3080
|
const params = new URLSearchParams(location.search);
|
|
@@ -2995,7 +3195,8 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2995
3195
|
}),
|
|
2996
3196
|
...createWebViewApis({
|
|
2997
3197
|
documentOf: (webviewId) => this.pages.get(webviewId)?.win?.document,
|
|
2998
|
-
emitToWebview: (webviewId, event, data) => this.emitToWebview(webviewId, event, data)
|
|
3198
|
+
emitToWebview: (webviewId, event, data) => this.emitToWebview(webviewId, event, data),
|
|
3199
|
+
windows: this.webViewWindows
|
|
2999
3200
|
}),
|
|
3000
3201
|
...createMiscApis(this.info.appid, {
|
|
3001
3202
|
devtoolsLogin: this.info.devtoolsLogin,
|
|
@@ -3354,6 +3555,10 @@ ${script}
|
|
|
3354
3555
|
ready,
|
|
3355
3556
|
currentPage: () => snapshot(host.currentPage()),
|
|
3356
3557
|
pageStack: () => host.pageStack().map((page) => snapshot(page)),
|
|
3558
|
+
webViews: () => {
|
|
3559
|
+
const page = host.currentPage();
|
|
3560
|
+
return page ? host.webViewsOf(page) : [];
|
|
3561
|
+
},
|
|
3357
3562
|
waitForPage(path, timeout = 1e4) {
|
|
3358
3563
|
const target = path.replace(/^\//, "");
|
|
3359
3564
|
return new Promise((resolve, reject) => {
|
|
@@ -3424,6 +3629,7 @@ ${script}
|
|
|
3424
3629
|
${info.buildError}`);
|
|
3425
3630
|
return;
|
|
3426
3631
|
}
|
|
3632
|
+
if (window.__wxa_webview_window__ === true) info.webViewWindow = true;
|
|
3427
3633
|
const host = new Host(info, root, sendReport);
|
|
3428
3634
|
window.__wxaHost = host;
|
|
3429
3635
|
let markReady;
|