@myop/sdk 0.3.32 → 0.3.33
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/bundled-declarations.d.ts +135 -48
- package/dist/cjs/_IframeSDK.c7a53057.min.js +1 -0
- package/dist/cjs/{_IframeSDK.8ce25264.js → _IframeSDK.e5b2bc49.js} +201 -28
- package/dist/cjs/_IframeSDK.e5b2bc49.js.map +7 -0
- package/dist/cjs/_MyopHelpers.95610381.js.map +2 -2
- package/dist/cjs/{_MyopHelpers.172384f4.min.js → _MyopHelpers.ca1b3a3c.min.js} +1 -1
- package/dist/cjs/_WebComponentSDK.3a72ed95.min.js +1 -0
- package/dist/cjs/{_WebComponentSDK.1aa213d9.js → _WebComponentSDK.a7e660ab.js} +201 -28
- package/dist/cjs/_WebComponentSDK.a7e660ab.js.map +7 -0
- package/dist/cjs/_hostSDK.0529d5ed.min.js +1 -0
- package/dist/cjs/{_hostSDK.c7ca0fae.js → _hostSDK.1905850e.js} +201 -28
- package/dist/cjs/_hostSDK.1905850e.js.map +7 -0
- package/dist/cjs/myop_sdk.js +11 -11
- package/dist/cjs/myop_sdk.js.map +1 -1
- package/dist/cjs/myop_sdk.min.js +1 -1
- package/dist/cjs-bundled/myop_sdk.bundled.js +203 -29
- package/dist/cjs-bundled/myop_sdk.bundled.js.map +3 -3
- package/dist/cjs-bundled/myop_sdk.bundled.min.js +1 -1
- package/dist/module/Iframe/index.js +259 -29
- package/dist/module/Iframe/index.js.map +2 -2
- package/dist/module/SDK.js +260 -29
- package/dist/module/SDK.js.map +3 -3
- package/dist/module/common/index.d.ts +26 -0
- package/dist/module/common/index.js +1 -1
- package/dist/module/common/index.js.map +2 -2
- package/dist/module/embeddedSDK.js +1 -1
- package/dist/module/helpers/index.js +1 -1
- package/dist/module/helpers/index.js.map +2 -2
- package/dist/module/host/components/myopExtractedWebComponent.d.ts +1 -0
- package/dist/module/host/components/myopIframeComponent.d.ts +17 -0
- package/dist/module/host/embeddedSDK.js +1 -1
- package/dist/module/host/hostSDK.d.ts +15 -0
- package/dist/module/host/index.d.ts +1 -1
- package/dist/module/host/index.js +259 -29
- package/dist/module/host/index.js.map +2 -2
- package/dist/module/host/loaders/HTMLComponentLoader.d.ts +29 -1
- package/dist/module/webcomponent/index.js +259 -29
- package/dist/module/webcomponent/index.js.map +2 -2
- package/package.json +1 -1
- package/dist/cjs/_IframeSDK.07df88d3.min.js +0 -1
- package/dist/cjs/_IframeSDK.8ce25264.js.map +0 -7
- package/dist/cjs/_WebComponentSDK.1aa213d9.js.map +0 -7
- package/dist/cjs/_WebComponentSDK.92468fac.min.js +0 -1
- package/dist/cjs/_hostSDK.c7ca0fae.js.map +0 -7
- package/dist/cjs/_hostSDK.dc198afa.min.js +0 -1
|
@@ -1166,6 +1166,19 @@ var MyopExtractedWebComponent = class extends BaseMyopComponent {
|
|
|
1166
1166
|
__publicField(this, "ctaCleanup");
|
|
1167
1167
|
__publicField(this, "_ctaHandler");
|
|
1168
1168
|
__publicField(this, "_ctaQueue", []);
|
|
1169
|
+
// A single 'myop-cta' listener, attached at construction so CTAs a component
|
|
1170
|
+
// dispatches during its first initWithData() render — before the host attaches
|
|
1171
|
+
// a handler — are buffered (and flushed on setCtaHandler), matching the iframe
|
|
1172
|
+
// path's pre-handler CTA queue.
|
|
1173
|
+
__publicField(this, "_ctaListener", (e) => {
|
|
1174
|
+
const detail = e.detail;
|
|
1175
|
+
if (!(detail == null ? void 0 : detail.action)) return;
|
|
1176
|
+
if (this._ctaHandler && !this.markedForDisposed) {
|
|
1177
|
+
this._ctaHandler(detail.action, detail.payload);
|
|
1178
|
+
} else if (!this._ctaHandler) {
|
|
1179
|
+
this._ctaQueue.push({ action: detail.action, payload: detail.payload });
|
|
1180
|
+
}
|
|
1181
|
+
});
|
|
1169
1182
|
__publicField(this, "cleanupInspect", () => {
|
|
1170
1183
|
});
|
|
1171
1184
|
/**
|
|
@@ -1186,6 +1199,8 @@ var MyopExtractedWebComponent = class extends BaseMyopComponent {
|
|
|
1186
1199
|
(_a = this.customElement.parentNode) == null ? void 0 : _a.removeChild(this.customElement);
|
|
1187
1200
|
});
|
|
1188
1201
|
this.element = customElement;
|
|
1202
|
+
this.customElement.addEventListener("myop-cta", this._ctaListener);
|
|
1203
|
+
this.ctaCleanup = () => this.customElement.removeEventListener("myop-cta", this._ctaListener);
|
|
1189
1204
|
this.setInitiated();
|
|
1190
1205
|
}
|
|
1191
1206
|
inspect() {
|
|
@@ -1230,9 +1245,6 @@ var MyopExtractedWebComponent = class extends BaseMyopComponent {
|
|
|
1230
1245
|
* Called via props.myop_cta_handler = handler
|
|
1231
1246
|
*/
|
|
1232
1247
|
setCtaHandler(handler) {
|
|
1233
|
-
if (this.ctaCleanup) {
|
|
1234
|
-
this.ctaCleanup();
|
|
1235
|
-
}
|
|
1236
1248
|
this._ctaHandler = handler;
|
|
1237
1249
|
if (this._ctaQueue.length > 0) {
|
|
1238
1250
|
const queue = [...this._ctaQueue];
|
|
@@ -1243,24 +1255,6 @@ var MyopExtractedWebComponent = class extends BaseMyopComponent {
|
|
|
1243
1255
|
}
|
|
1244
1256
|
});
|
|
1245
1257
|
}
|
|
1246
|
-
const listener = (e) => {
|
|
1247
|
-
var _a;
|
|
1248
|
-
const customEvent = e;
|
|
1249
|
-
if ((_a = customEvent.detail) == null ? void 0 : _a.action) {
|
|
1250
|
-
if (this._ctaHandler && !this.markedForDisposed) {
|
|
1251
|
-
this._ctaHandler(customEvent.detail.action, customEvent.detail.payload);
|
|
1252
|
-
} else if (!this._ctaHandler) {
|
|
1253
|
-
this._ctaQueue.push({
|
|
1254
|
-
action: customEvent.detail.action,
|
|
1255
|
-
payload: customEvent.detail.payload
|
|
1256
|
-
});
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
};
|
|
1260
|
-
this.customElement.addEventListener("myop-cta", listener);
|
|
1261
|
-
this.ctaCleanup = () => {
|
|
1262
|
-
this.customElement.removeEventListener("myop-cta", listener);
|
|
1263
|
-
};
|
|
1264
1258
|
}
|
|
1265
1259
|
};
|
|
1266
1260
|
|
|
@@ -1329,6 +1323,17 @@ var connectProps = (component, propsConfig, selectedSkin) => {
|
|
|
1329
1323
|
}
|
|
1330
1324
|
return void 0;
|
|
1331
1325
|
}
|
|
1326
|
+
if (component instanceof MyopIframeComponent && component.isolated) {
|
|
1327
|
+
const typedPropBehavior = propConfig.behavior;
|
|
1328
|
+
const propName = typedPropBehavior.remap || prop;
|
|
1329
|
+
if (propName === "myop_init_interface") {
|
|
1330
|
+
return (data) => {
|
|
1331
|
+
if (data === void 0) return component.getData();
|
|
1332
|
+
component.initWithData(data);
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
return void 0;
|
|
1336
|
+
}
|
|
1332
1337
|
if (selectedSkin.loader.type === SkinLoaders.HTMLLoader) {
|
|
1333
1338
|
const typedLoader = selectedSkin.loader;
|
|
1334
1339
|
if (typedLoader.shadowRootMode === ShadowRootModeType.localFrame) {
|
|
@@ -1375,6 +1380,18 @@ var connectProps = (component, propsConfig, selectedSkin) => {
|
|
|
1375
1380
|
return true;
|
|
1376
1381
|
}
|
|
1377
1382
|
}
|
|
1383
|
+
if (component instanceof MyopIframeComponent && component.isolated) {
|
|
1384
|
+
const typedPropBehavior = propConfig.behavior;
|
|
1385
|
+
const propName = typedPropBehavior.remap || prop;
|
|
1386
|
+
if (propName === "myop_cta_handler") {
|
|
1387
|
+
component.setCtaHandler(value);
|
|
1388
|
+
return true;
|
|
1389
|
+
}
|
|
1390
|
+
if (propName === "myop_init_interface") {
|
|
1391
|
+
component.initWithData(value);
|
|
1392
|
+
return true;
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1378
1395
|
if (selectedSkin.loader.type === SkinLoaders.HTMLLoader) {
|
|
1379
1396
|
const typedLoader = selectedSkin.loader;
|
|
1380
1397
|
if (typedLoader.shadowRootMode === ShadowRootModeType.localFrame) {
|
|
@@ -1580,6 +1597,7 @@ var connectRefs = async (component, componentConfig, components, withoutRefCompo
|
|
|
1580
1597
|
|
|
1581
1598
|
// src/host/components/myopIframeComponent.ts
|
|
1582
1599
|
var MyopIframeComponent = class extends BaseMyopComponent {
|
|
1600
|
+
// last reported size (for the enable race)
|
|
1583
1601
|
constructor(componentConfig, skin, container, IframeElement, options) {
|
|
1584
1602
|
super(componentConfig, container, options);
|
|
1585
1603
|
this.componentConfig = componentConfig;
|
|
@@ -1588,6 +1606,17 @@ var MyopIframeComponent = class extends BaseMyopComponent {
|
|
|
1588
1606
|
__publicField(this, "_autoSizeCleanup");
|
|
1589
1607
|
__publicField(this, "_autoSizeOptions");
|
|
1590
1608
|
__publicField(this, "_autoSizeUpdate");
|
|
1609
|
+
// ── Isolation (sandboxed cross-origin frame) — postMessage bridge, host side ──
|
|
1610
|
+
__publicField(this, "isolated", false);
|
|
1611
|
+
__publicField(this, "_lastData");
|
|
1612
|
+
// cached last-sent data (sync getData)
|
|
1613
|
+
__publicField(this, "_ctaHandler");
|
|
1614
|
+
__publicField(this, "_ctaQueue", []);
|
|
1615
|
+
__publicField(this, "_isoMsgHandler");
|
|
1616
|
+
__publicField(this, "_isoSizeOpts");
|
|
1617
|
+
__publicField(this, "_isoAutoSize", false);
|
|
1618
|
+
// bridge sizing only when auto-size is on
|
|
1619
|
+
__publicField(this, "_isoLastSize");
|
|
1591
1620
|
__publicField(this, "sizeMeta");
|
|
1592
1621
|
__publicField(this, "cleanupInspect");
|
|
1593
1622
|
__publicField(this, "setHeightBasedOnDocumentElement", () => {
|
|
@@ -1627,6 +1656,15 @@ var MyopIframeComponent = class extends BaseMyopComponent {
|
|
|
1627
1656
|
*/
|
|
1628
1657
|
__publicField(this, "observeAutoSize", (options) => {
|
|
1629
1658
|
this._autoSizeOptions = options;
|
|
1659
|
+
if (this.isolated) {
|
|
1660
|
+
this._isoSizeOpts = options;
|
|
1661
|
+
this._isoAutoSize = true;
|
|
1662
|
+
if (this._isoLastSize) this._applyIsoSize(this._isoLastSize.height, this._isoLastSize.width);
|
|
1663
|
+
return () => {
|
|
1664
|
+
this._isoAutoSize = false;
|
|
1665
|
+
this._isoSizeOpts = void 0;
|
|
1666
|
+
};
|
|
1667
|
+
}
|
|
1630
1668
|
if (this._autoSizeCleanup && this._autoSizeUpdate) {
|
|
1631
1669
|
this._autoSizeUpdate();
|
|
1632
1670
|
return this._autoSizeCleanup;
|
|
@@ -1829,12 +1867,73 @@ var MyopIframeComponent = class extends BaseMyopComponent {
|
|
|
1829
1867
|
this._autoSizeCleanup();
|
|
1830
1868
|
this._autoSizeCleanup = void 0;
|
|
1831
1869
|
}
|
|
1870
|
+
if (this._isoMsgHandler) {
|
|
1871
|
+
window.removeEventListener("message", this._isoMsgHandler);
|
|
1872
|
+
this._isoMsgHandler = void 0;
|
|
1873
|
+
}
|
|
1832
1874
|
if (this.cleanupInspect)
|
|
1833
1875
|
this.cleanupInspect();
|
|
1834
1876
|
super.dispose();
|
|
1835
1877
|
this.IframeElement.parentNode.removeChild(this.IframeElement);
|
|
1836
1878
|
});
|
|
1837
1879
|
this.element = this.IframeElement;
|
|
1880
|
+
this._lastData = options == null ? void 0 : options.data;
|
|
1881
|
+
}
|
|
1882
|
+
// ── Isolation bridge (host side) ─────────────────────────────────────────
|
|
1883
|
+
/** Attach the host-side postMessage listener for a sandboxed frame. */
|
|
1884
|
+
enableIsolation() {
|
|
1885
|
+
this.isolated = true;
|
|
1886
|
+
this.setInitiated();
|
|
1887
|
+
this._isoMsgHandler = (e) => {
|
|
1888
|
+
if (e.source !== this.IframeElement.contentWindow) return;
|
|
1889
|
+
const d = e.data;
|
|
1890
|
+
if (!d || d.__myop !== true) return;
|
|
1891
|
+
if (d.type === "myop:cta") {
|
|
1892
|
+
if (this._ctaHandler && !this.markedForDisposed) this._ctaHandler(d.action, d.payload);
|
|
1893
|
+
else if (!this._ctaHandler) this._ctaQueue.push({ action: d.action, payload: d.payload });
|
|
1894
|
+
} else if (d.type === "myop:size") {
|
|
1895
|
+
this._applyIsoSize(d.height, d.width);
|
|
1896
|
+
}
|
|
1897
|
+
};
|
|
1898
|
+
window.addEventListener("message", this._isoMsgHandler);
|
|
1899
|
+
}
|
|
1900
|
+
/** Data-in — unified with the extracted-WC API. Posts init over the bridge. */
|
|
1901
|
+
initWithData(data) {
|
|
1902
|
+
var _a, _b;
|
|
1903
|
+
this._lastData = data;
|
|
1904
|
+
(_b = (_a = this.IframeElement) == null ? void 0 : _a.contentWindow) == null ? void 0 : _b.postMessage({ __myop: true, type: "myop:init", data }, "*");
|
|
1905
|
+
}
|
|
1906
|
+
/** Data-in getter — returns the last data the host sent (cached, synchronous). */
|
|
1907
|
+
getData() {
|
|
1908
|
+
return this._lastData;
|
|
1909
|
+
}
|
|
1910
|
+
/** Data-out — unified with the extracted-WC API. Flushes CTAs queued pre-handler. */
|
|
1911
|
+
setCtaHandler(handler) {
|
|
1912
|
+
this._ctaHandler = handler;
|
|
1913
|
+
if (this._ctaQueue.length > 0) {
|
|
1914
|
+
const queue = [...this._ctaQueue];
|
|
1915
|
+
this._ctaQueue = [];
|
|
1916
|
+
queue.forEach((item) => {
|
|
1917
|
+
if (!this.markedForDisposed) handler(item.action, item.payload);
|
|
1918
|
+
});
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
_applyIsoSize(height, width) {
|
|
1922
|
+
var _a;
|
|
1923
|
+
if (!height || Number.isNaN(height)) return;
|
|
1924
|
+
this._isoLastSize = { height, width };
|
|
1925
|
+
if (!this._isoAutoSize) return;
|
|
1926
|
+
const opts = this._isoSizeOpts;
|
|
1927
|
+
const toNum = (v) => v === void 0 ? void 0 : typeof v === "number" ? v : isNaN(parseFloat(v)) ? void 0 : parseFloat(v);
|
|
1928
|
+
const min = toNum(opts == null ? void 0 : opts.minHeight), max = toNum(opts == null ? void 0 : opts.maxHeight);
|
|
1929
|
+
let h = height;
|
|
1930
|
+
if (min !== void 0 && h < min) h = min;
|
|
1931
|
+
if (max !== void 0 && h > max) h = max;
|
|
1932
|
+
this.IframeElement.style.position = "relative";
|
|
1933
|
+
this.IframeElement.style.inset = "auto";
|
|
1934
|
+
this.IframeElement.style.height = h + "px";
|
|
1935
|
+
this.IframeElement.style.width = "100%";
|
|
1936
|
+
(_a = opts == null ? void 0 : opts.onSizeChange) == null ? void 0 : _a.call(opts, { width: width != null ? width : this.IframeElement.clientWidth, height: h, autoSizingWidth: false, autoSizingHeight: true });
|
|
1838
1937
|
}
|
|
1839
1938
|
inspect() {
|
|
1840
1939
|
if (this.cleanupInspect) {
|
|
@@ -2043,7 +2142,7 @@ var WebcomponentLoader = class extends BaseMyopLoader {
|
|
|
2043
2142
|
};
|
|
2044
2143
|
|
|
2045
2144
|
// version:myop-sdk-version
|
|
2046
|
-
var myop_sdk_version_default = "0.3.
|
|
2145
|
+
var myop_sdk_version_default = "0.3.33";
|
|
2047
2146
|
|
|
2048
2147
|
// src/webcomponent/messageHandlers/BaseWebComponentMessageHandler.ts
|
|
2049
2148
|
var BaseWebComponentMessageHandler = class extends BaseContextMessageHandler {
|
|
@@ -2414,7 +2513,15 @@ var HTMLComponentLoader = class extends BaseMyopLoader {
|
|
|
2414
2513
|
__publicField(this, "type", SkinLoaders.HTMLLoader);
|
|
2415
2514
|
__publicField(this, "load", async (componentDefinition, skin, container, options) => {
|
|
2416
2515
|
const loaderConfig = skin.loader;
|
|
2417
|
-
|
|
2516
|
+
const isWC = this.isMyopWebComponent(loaderConfig.HTML);
|
|
2517
|
+
const { mode, isolate } = await this.resolveRenderMode(componentDefinition, skin, loaderConfig, isWC, options);
|
|
2518
|
+
if (mode === false) {
|
|
2519
|
+
throw new Error('[Myop] Rendering blocked by render policy for component "'.concat(componentDefinition.id, '"'));
|
|
2520
|
+
}
|
|
2521
|
+
if (isWC) {
|
|
2522
|
+
if (mode !== "webComponent") {
|
|
2523
|
+
throw new Error('[Myop] Web-component rendering denied by render policy for component "'.concat(componentDefinition.id, '"'));
|
|
2524
|
+
}
|
|
2418
2525
|
return this.loadExtractedWebComponent(componentDefinition, skin, container, loaderConfig.HTML, options);
|
|
2419
2526
|
}
|
|
2420
2527
|
let domId = "myop-comp-".concat(uuidv4());
|
|
@@ -2424,12 +2531,28 @@ var HTMLComponentLoader = class extends BaseMyopLoader {
|
|
|
2424
2531
|
const domId2 = "myop-comp-".concat(uniqId);
|
|
2425
2532
|
let IframeElement = document.createElement("iframe");
|
|
2426
2533
|
IframeElement.id = domId2;
|
|
2534
|
+
if (isolate) {
|
|
2535
|
+
IframeElement.setAttribute("sandbox", "allow-scripts allow-forms allow-popups");
|
|
2536
|
+
}
|
|
2427
2537
|
IframeElement.style.cssText = "\n display: block;\n padding: 0;\n margin: 0;\n position: absolute;\n inset: 0;\n overflow: hidden;\n border: none;\n opacity: ".concat((options == null ? void 0 : options.hidden) ? "0" : "1", ";\n width: 100%;\n height: 100%;\n pointer-events: ").concat((options == null ? void 0 : options.hidden) ? "none" : "all", ";\n ");
|
|
2428
2538
|
if (!container.querySelector('[id^="myop-comp-"]'))
|
|
2429
2539
|
container.innerHTML = "";
|
|
2430
2540
|
IframeElement = this.appendChild(container, IframeElement, options);
|
|
2431
|
-
const
|
|
2432
|
-
doc
|
|
2541
|
+
const __srcParts = [];
|
|
2542
|
+
const doc = isolate ? {
|
|
2543
|
+
open() {
|
|
2544
|
+
},
|
|
2545
|
+
writeln(s) {
|
|
2546
|
+
__srcParts.push(s);
|
|
2547
|
+
},
|
|
2548
|
+
close() {
|
|
2549
|
+
IframeElement.srcdoc = __srcParts.join("\n");
|
|
2550
|
+
}
|
|
2551
|
+
} : (() => {
|
|
2552
|
+
const d = IframeElement.contentDocument || IframeElement.contentWindow.document;
|
|
2553
|
+
d.open();
|
|
2554
|
+
return d;
|
|
2555
|
+
})();
|
|
2433
2556
|
let parsedSizeMeta = null;
|
|
2434
2557
|
{
|
|
2435
2558
|
const _preParser = new DOMParser();
|
|
@@ -2469,22 +2592,29 @@ var HTMLComponentLoader = class extends BaseMyopLoader {
|
|
|
2469
2592
|
const _doc = parser.parseFromString(HTML2Render, "text/html");
|
|
2470
2593
|
const styleTag = _doc.createElement("style");
|
|
2471
2594
|
styleTag.setAttribute("data-myop-injected", "true");
|
|
2472
|
-
styleTag.textContent = options.injectCss;
|
|
2595
|
+
styleTag.textContent = options.injectCss.replace(/<\s*\/\s*style/gi, "<\\/style");
|
|
2473
2596
|
(_doc.head || _doc.documentElement).appendChild(styleTag);
|
|
2474
2597
|
HTML2Render = "<!DOCTYPE html>" + _doc.documentElement.outerHTML;
|
|
2475
2598
|
}
|
|
2476
2599
|
doc.writeln(HTML2Render);
|
|
2477
2600
|
const sdkScript = HAS_EMBEDDED_SDK ? "<script>".concat(EMBEDDED_SDK_CONTENT, "<\/script>") : '<script src="'.concat(window.myop.__ROOT_SDK_PUBLIC_URL__, '"><\/script>');
|
|
2478
2601
|
const initScript = HAS_EMBEDDED_SDK ? "<script>\n const __myop_init = async () => {\n const iframeModule = await MyopSDK.getIframeModule();\n const IframeSDK = iframeModule.IframeSDK;\n const sdk = new IframeSDK();\n sdk.init();\n }\n __myop_init().then();\n <\/script>" : "<script>\n window.__federation__.__public_path__ = window.__federation__.__public_path__;\n const __myop_init = async () => {\n const {IframeSDK} = (await window.myop.rootSDK.getIframeModule());\n const sdk = new IframeSDK();\n sdk.init();\n }\n __myop_init().then();\n <\/script>";
|
|
2479
|
-
|
|
2480
|
-
|
|
2602
|
+
if (!isolate) {
|
|
2603
|
+
doc.writeln("".concat(sdkScript).concat(initScript));
|
|
2604
|
+
}
|
|
2605
|
+
if (!isolate && (options == null ? void 0 : options.data) !== void 0) {
|
|
2481
2606
|
const ctaQueueScript = "<script>\n window.__myop_cta_queue = [];\n window.myop_cta_handler = function(action, payload) {\n window.__myop_cta_queue.push({action: action, payload: payload});\n };\n <\/script>";
|
|
2482
2607
|
const escapedData = JSON.stringify(options.data).replace(/<\/script/gi, "\\u003c/script");
|
|
2483
2608
|
const dataScript = '<script id="__myop_init_data_script">\n (function() {\n var data = '.concat(escapedData, ";\n var scriptEl = document.getElementById('__myop_init_data_script');\n\n var callInitInterface = function(fn) {\n var startTime = performance.now();\n // Mark as pre-injected data call for extension tracking\n window.__myop_init_preinjected = true;\n try {\n fn(data);\n } finally {\n window.__myop_init_preinjected = false;\n }\n var duration = performance.now() - startTime;\n\n // Notify extension via postMessage (init* = pre-injected)\n try {\n window.parent.postMessage({\n type: 'MYOP_PREINJECTED_INIT',\n payload: {\n data: data,\n duration: duration,\n timestamp: Date.now()\n }\n }, '*');\n } catch (e) {}\n\n // Cleanup: remove script tag and stored data\n if (scriptEl && scriptEl.parentNode) {\n scriptEl.parentNode.removeChild(scriptEl);\n }\n delete window.__myop_init_data;\n };\n\n if (typeof window.myop_init_interface === 'function') {\n // Function already exists - call immediately\n callInitInterface(window.myop_init_interface);\n } else {\n // Function not yet defined - store data and watch for definition\n window.__myop_init_data = data;\n\n var _original;\n Object.defineProperty(window, 'myop_init_interface', {\n configurable: true,\n enumerable: true,\n set: function(fn) {\n _original = fn;\n if (window.__myop_init_data !== undefined) {\n var storedData = window.__myop_init_data;\n delete window.__myop_init_data;\n callInitInterface(fn);\n }\n },\n get: function() {\n return _original;\n }\n });\n }\n })();\n <\/script>");
|
|
2484
2609
|
doc.writeln(ctaQueueScript + dataScript);
|
|
2485
2610
|
}
|
|
2611
|
+
if (isolate) {
|
|
2612
|
+
const escapedData = (options == null ? void 0 : options.data) !== void 0 ? JSON.stringify(options.data).replace(/<\/script/gi, "\\u003c/script") : "undefined";
|
|
2613
|
+
doc.writeln(this.buildIsolationBridge(escapedData));
|
|
2614
|
+
}
|
|
2486
2615
|
doc.close();
|
|
2487
2616
|
const comp = new MyopIframeComponent(componentDefinition, skin, container, IframeElement, options);
|
|
2617
|
+
if (isolate) comp.enableIsolation();
|
|
2488
2618
|
comp.sizeMeta = parsedSizeMeta;
|
|
2489
2619
|
comp.initiated().then(() => {
|
|
2490
2620
|
if ((options == null ? void 0 : options.autoSize) === false) {
|
|
@@ -2539,6 +2669,42 @@ var HTMLComponentLoader = class extends BaseMyopLoader {
|
|
|
2539
2669
|
isMyopWebComponent(html) {
|
|
2540
2670
|
return html.trimStart().startsWith(MYOP_WEB_COMPONENT_MARKER);
|
|
2541
2671
|
}
|
|
2672
|
+
/**
|
|
2673
|
+
* Resolve how this component should render, applying the host render policy.
|
|
2674
|
+
* Precedence: options.renderPolicy (per-call) fully replaces the global
|
|
2675
|
+
* hostSDK.setRenderPolicy — so an app can restrict globally and allow specifics.
|
|
2676
|
+
* With no policy set, behavior is unchanged from before (marker ⇒ web component).
|
|
2677
|
+
*/
|
|
2678
|
+
async resolveRenderMode(componentDefinition, skin, loaderConfig, isWebComponent, options) {
|
|
2679
|
+
var _a, _b, _c, _d;
|
|
2680
|
+
const requestedMode = isWebComponent ? "webComponent" : loaderConfig.isolation || (options == null ? void 0 : options.isolation) ? "isolatedIframe" : "iframe";
|
|
2681
|
+
const policy = (_d = options == null ? void 0 : options.renderPolicy) != null ? _d : (_c = (_b = (_a = window == null ? void 0 : window.myop) == null ? void 0 : _a.hostSDK) == null ? void 0 : _b.getRenderPolicy) == null ? void 0 : _c.call(_b);
|
|
2682
|
+
const mode = policy ? await policy({ componentDefinition, skin, requestedMode, isWebComponent }) : requestedMode;
|
|
2683
|
+
return { mode, isolate: mode === "isolatedIframe" };
|
|
2684
|
+
}
|
|
2685
|
+
/**
|
|
2686
|
+
* The in-frame bridge for isolated components. Runs inside the sandboxed
|
|
2687
|
+
* (opaque-origin) iframe, translating the same author-facing contract to/from
|
|
2688
|
+
* postMessage since the host has no same-origin access:
|
|
2689
|
+
* • data-in : parent posts {type:'myop:init'} → calls window.myop_init_interface
|
|
2690
|
+
* (plus a baked initial value for the first render)
|
|
2691
|
+
* • data-out: window.myop_cta_handler → parent.postMessage({type:'myop:cta'})
|
|
2692
|
+
* • resize : ResizeObserver → parent.postMessage({type:'myop:size'})
|
|
2693
|
+
*
|
|
2694
|
+
* TODO(dev-extension): the isolated path deliberately skips the same-origin
|
|
2695
|
+
* dataScript, so it never posts the `MYOP_PREINJECTED_INIT` message the Myop dev
|
|
2696
|
+
* extension listens for to log the INITIAL render (`init*`). Later init updates and
|
|
2697
|
+
* all CTAs are still tracked (the extension wraps `comp.props`, which our isolated
|
|
2698
|
+
* connectProps branch routes through), so only the first-render payload is missing
|
|
2699
|
+
* from the extension's activity log for isolated components. Closing this would be a
|
|
2700
|
+
* ~1-line `parent.postMessage({type:'MYOP_PREINJECTED_INIT', payload:{data}})` inside
|
|
2701
|
+
* flushInitial() below — intentionally NOT done for now to avoid adding extension-only
|
|
2702
|
+
* traffic to the component runtime. Web components have the same initial-init gap
|
|
2703
|
+
* (initWithData is called on the element, not via comp.props) and it predates this.
|
|
2704
|
+
*/
|
|
2705
|
+
buildIsolationBridge(initialDataLiteral) {
|
|
2706
|
+
return "<script>\n (function () {\n var __initial = ".concat(initialDataLiteral, ";\n var __pending;\n // data-out (cta)\n window.myop_cta_handler = function (action, payload) {\n try { parent.postMessage({ __myop: true, type: 'myop:cta', action: action, payload: payload }, '*'); } catch (e) {}\n };\n function callInit(data) {\n if (typeof window.myop_init_interface === 'function') { window.myop_init_interface(data); return true; }\n return false;\n }\n // data-in (init updates)\n window.addEventListener('message', function (e) {\n var d = e.data;\n if (!d || d.__myop !== true) return;\n if (d.type === 'myop:init') { if (!callInit(d.data)) __pending = d.data; }\n });\n // first render: use a pending update if one arrived, else the baked initial data\n (function flushInitial() {\n var data = (__pending !== undefined) ? __pending : __initial;\n if (data === undefined) return;\n if (callInit(data)) { __pending = undefined; __initial = undefined; }\n else requestAnimationFrame(flushInitial);\n })();\n // resize (report content size)\n function contentHeight() {\n // Measure the BODY (content box). documentElement.scrollHeight includes\n // the iframe viewport \u2014 which we're driving \u2014 so it would report the\n // current frame height, not the content, and never shrink.\n var b = document.body;\n if (b) return Math.max(b.scrollHeight, b.offsetHeight);\n return document.documentElement.scrollHeight;\n }\n function postSize() {\n try {\n parent.postMessage({\n __myop: true, type: 'myop:size',\n height: contentHeight(),\n width: document.documentElement.scrollWidth\n }, '*');\n } catch (e) {}\n }\n // Observe the BODY (reflows with content) \u2014 not documentElement, whose box is\n // the iframe viewport and would feed back into a resize loop. A MutationObserver\n // catches content swaps (e.g. innerHTML re-render) that don't change body's box.\n if (window.ResizeObserver) {\n try { var __ro = new ResizeObserver(postSize); if (document.body) __ro.observe(document.body); } catch (e) {}\n }\n if (window.MutationObserver && document.body) {\n try { new MutationObserver(postSize).observe(document.body, { childList: true, subtree: true, attributes: true, characterData: true }); } catch (e) {}\n }\n window.addEventListener('load', postSize);\n postSize();\n })();\n <\/script>");
|
|
2707
|
+
}
|
|
2542
2708
|
/**
|
|
2543
2709
|
* Extract the web component script content from HTML
|
|
2544
2710
|
*/
|
|
@@ -2988,6 +3154,13 @@ var HostSDK = class {
|
|
|
2988
3154
|
__publicField(this, "components2init", []);
|
|
2989
3155
|
__publicField(this, "components", []);
|
|
2990
3156
|
__publicField(this, "componentsLoaders", []);
|
|
3157
|
+
// Global render policy (allow/deny/mode gate). A per-call options.renderPolicy
|
|
3158
|
+
// takes precedence over this — see HTMLComponentLoader.resolveRenderMode.
|
|
3159
|
+
__publicField(this, "_renderPolicy");
|
|
3160
|
+
__publicField(this, "setRenderPolicy", (policy) => {
|
|
3161
|
+
this._renderPolicy = policy;
|
|
3162
|
+
});
|
|
3163
|
+
__publicField(this, "getRenderPolicy", () => this._renderPolicy);
|
|
2991
3164
|
__publicField(this, "initiated", false);
|
|
2992
3165
|
__publicField(this, "version", myop_sdk_version_default);
|
|
2993
3166
|
__publicField(this, "type2InstanceCount", {});
|