@metapages/metapage 1.10.7 → 1.10.8

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.
@@ -0,0 +1,17 @@
1
+ import { Disposer } from "./core.js";
2
+ import { Metapage } from "./Metapage.js";
3
+ import { MetaframeInputMap } from "./v0_4/index.js";
4
+ export interface MetaframeRendererResult {
5
+ setInputs: (inputs: MetaframeInputMap) => void;
6
+ setOutputs: (outputs: MetaframeInputMap) => void;
7
+ dispose: Disposer;
8
+ metapage: Metapage;
9
+ }
10
+ export declare function renderMetaframe(props: {
11
+ url: string;
12
+ onOutputs?: (outputs: MetaframeInputMap) => void;
13
+ onUrlChange?: (url: string) => void;
14
+ rootDiv: HTMLElement;
15
+ debug?: boolean;
16
+ }): Promise<MetaframeRendererResult>;
17
+ //# sourceMappingURL=metaframeRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metaframeRenderer.d.ts","sourceRoot":"","sources":["../../src/metapage/metaframeRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAKpD,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC/C,UAAU,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,OAAO,EAAE,QAAQ,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAQD,wBAAsB,eAAe,CAAC,KAAK,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAsHnC"}
@@ -1 +1 @@
1
- {"version":3,"file":"metapageRenderer.d.ts","sourceRoot":"","sources":["../../src/metapage/metapageRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGtD,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACpD,UAAU,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACtD,OAAO,EAAE,QAAQ,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAGD,UAAU,UAAU;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAGD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAKvD;AAuED,eAAO,MAAM,wBAAwB,eACvB,kBAAkB;wBAEV,UAAU,EAAE;wBACZ,IAAI,MAAM,CAAC;yBACV,IAAI,MAAM,CAAC;4BACR,MAAM;CA8E/B,CAAC;AAMF,wBAAsB,cAAc,CAAC,KAAK,EAAE;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACtD,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA2OlC;AAED,eAAO,MAAM,iBAAiB,eAChB,kBAAkB,eACjB,WAAW,KACvB,OA8CF,CAAC"}
1
+ {"version":3,"file":"metapageRenderer.d.ts","sourceRoot":"","sources":["../../src/metapage/metapageRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGtD,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACpD,UAAU,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACtD,OAAO,EAAE,QAAQ,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAGD,UAAU,UAAU;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAGD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAKvD;AAuED,eAAO,MAAM,wBAAwB,eACvB,kBAAkB;wBAEV,UAAU,EAAE;wBACZ,IAAI,MAAM,CAAC;yBACV,IAAI,MAAM,CAAC;4BACR,MAAM;CA8E/B,CAAC;AAMF,wBAAsB,cAAc,CAAC,KAAK,EAAE;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACtD,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAuPlC;AAED,eAAO,MAAM,iBAAiB,eAChB,kBAAkB,eACjB,WAAW,KACvB,OA8CF,CAAC"}
@@ -0,0 +1 @@
1
+ /* Optional styles for metapage rendering */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@metapages/metapage",
3
3
  "public": true,
4
- "version": "1.10.7",
4
+ "version": "1.10.8",
5
5
  "description": "Connect web pages together",
6
6
  "repository": "https://github.com/metapages/metapage",
7
7
  "homepage": "https://metapage.io/",
@@ -15,7 +15,8 @@
15
15
  "types": "./dist/index.d.ts",
16
16
  "import": "./dist/index.js",
17
17
  "default": "./dist/index.js"
18
- }
18
+ },
19
+ "./metapage.css": "./dist/metapage.css"
19
20
  },
20
21
  "files": [
21
22
  "dist",
@@ -23,8 +24,8 @@
23
24
  ],
24
25
  "source": "src/index.ts",
25
26
  "dependencies": {
26
- "@metapages/hash-query": "^0.9.12",
27
27
  "@metapages/dataref": "^2.0.1",
28
+ "@metapages/hash-query": "^0.9.12",
28
29
  "base64-arraybuffer": "^1.0.2",
29
30
  "compare-versions": "^6.1.1",
30
31
  "eventemitter3": "^4.0.0",
@@ -40,7 +41,7 @@
40
41
  "@rollup/plugin-typescript": "^11.1.5",
41
42
  "@types/object-hash": "^2.2.1",
42
43
  "@vitest/browser": "^3.2.4",
43
- "playwright": "^1.54.2",
44
+ "playwright": "^1.59.1",
44
45
  "rollup": "^2.79.2",
45
46
  "rollup-plugin-typescript-paths": "^1.4.0",
46
47
  "tslib": "^2.6.2",
package/src/index.ts CHANGED
@@ -18,3 +18,4 @@ export * from "./metapage/versions";
18
18
  export * from "./metapage/version-detection";
19
19
  export * from "./metapage/util";
20
20
  export * from "./metapage/metapageRenderer";
21
+ export * from "./metapage/metaframeRenderer";
@@ -0,0 +1,147 @@
1
+ import { Disposer } from "./core.js";
2
+ import { MetapageEventDefinitionUpdate, MetapageEvents } from "./events.js";
3
+ import { Metapage } from "./Metapage.js";
4
+ import { pageLoaded } from "./MetapageTools.js";
5
+ import { MetaframeInputMap } from "./v0_4/index.js";
6
+ import { MetapageDefinition } from "./v2/metapage.js";
7
+
8
+ const METAFRAME_ID = "mf";
9
+
10
+ export interface MetaframeRendererResult {
11
+ setInputs: (inputs: MetaframeInputMap) => void;
12
+ setOutputs: (outputs: MetaframeInputMap) => void;
13
+ dispose: Disposer;
14
+ metapage: Metapage;
15
+ }
16
+
17
+ /**
18
+ * Renders a single metaframe URL as a full-size iframe.
19
+ * Creates a minimal metapage definition wrapping the URL,
20
+ * then renders the iframe at 100% width/height with no
21
+ * borders, labels, or grid layout.
22
+ */
23
+ export async function renderMetaframe(props: {
24
+ url: string;
25
+ onOutputs?: (outputs: MetaframeInputMap) => void;
26
+ onUrlChange?: (url: string) => void;
27
+ rootDiv: HTMLElement;
28
+ debug?: boolean;
29
+ }): Promise<MetaframeRendererResult> {
30
+ const { url, onOutputs, onUrlChange, rootDiv, debug = false } = props;
31
+
32
+ if (!url) {
33
+ throw new Error("url must be provided");
34
+ }
35
+
36
+ // Build a minimal metapage definition with a single metaframe
37
+ const definition: MetapageDefinition = {
38
+ version: "0.4",
39
+ metaframes: {
40
+ [METAFRAME_ID]: { url },
41
+ },
42
+ meta: {
43
+ layouts: {
44
+ "react-grid-layout": {
45
+ docs: "https://www.npmjs.com/package/react-grid-layout",
46
+ props: {
47
+ cols: 1,
48
+ margin: [0, 0],
49
+ rowHeight: 100,
50
+ containerPadding: [0, 0],
51
+ },
52
+ layout: [{ i: METAFRAME_ID, x: 0, y: 0, w: 1, h: 1 }],
53
+ },
54
+ },
55
+ },
56
+ };
57
+
58
+ await pageLoaded();
59
+
60
+ const metapage = new Metapage();
61
+ metapage.debug = debug;
62
+
63
+ try {
64
+ await metapage.setDefinition(JSON.parse(JSON.stringify(definition)));
65
+ } catch (err) {
66
+ metapage.dispose();
67
+ throw new Error(`Failed to set metapage definition: ${err}`);
68
+ }
69
+
70
+ const disposers: Disposer[] = [];
71
+
72
+ if (onOutputs) {
73
+ disposers.push(
74
+ metapage.addListenerReturnDisposer(MetapageEvents.Outputs, (outputs) => {
75
+ onOutputs(outputs[METAFRAME_ID] || {});
76
+ }),
77
+ );
78
+ }
79
+
80
+ if (onUrlChange) {
81
+ let lastUrl = url;
82
+ disposers.push(
83
+ metapage.addListenerReturnDisposer(
84
+ MetapageEvents.DefinitionUpdate,
85
+ (event: MetapageEventDefinitionUpdate) => {
86
+ const newUrl = event.definition?.metaframes?.[METAFRAME_ID]?.url;
87
+ if (newUrl && newUrl !== lastUrl) {
88
+ lastUrl = newUrl;
89
+ onUrlChange(newUrl);
90
+ }
91
+ },
92
+ ),
93
+ );
94
+ }
95
+
96
+ // Get the single metaframe's iframe
97
+ const metaframe = metapage.getMetaframes()[METAFRAME_ID];
98
+ if (!metaframe) {
99
+ metapage.dispose();
100
+ throw new Error("Failed to create metaframe");
101
+ }
102
+
103
+ const iframe = await metaframe.iframe;
104
+
105
+ // Container fills the rootDiv completely
106
+ const container = document.createElement("div");
107
+ container.style.width = "100%";
108
+ container.style.height = "100%";
109
+ container.style.margin = "0";
110
+ container.style.padding = "0";
111
+ container.style.overflow = "hidden";
112
+ container.style.position = "relative";
113
+
114
+ // Iframe fills the container
115
+ iframe.style.position = "absolute";
116
+ iframe.style.top = "0";
117
+ iframe.style.left = "0";
118
+ iframe.style.width = "100%";
119
+ iframe.style.height = "100%";
120
+ iframe.style.border = "none";
121
+ iframe.style.margin = "0";
122
+ iframe.style.padding = "0";
123
+
124
+ container.appendChild(iframe);
125
+ rootDiv.appendChild(container);
126
+
127
+ return {
128
+ metapage,
129
+ setInputs: (inputs: MetaframeInputMap) => {
130
+ if (!metapage.isDisposed()) {
131
+ metapage.setInputs({ [METAFRAME_ID]: inputs });
132
+ }
133
+ },
134
+ setOutputs: (outputs: MetaframeInputMap) => {
135
+ if (!metapage.isDisposed()) {
136
+ metapage.setOutputs({ [METAFRAME_ID]: outputs });
137
+ }
138
+ },
139
+ dispose: () => {
140
+ disposers.forEach((disposer) => disposer());
141
+ metapage.dispose();
142
+ if (container.parentNode) {
143
+ container.parentNode.removeChild(container);
144
+ }
145
+ },
146
+ };
147
+ }
@@ -342,18 +342,30 @@ export async function renderMetapage(props: {
342
342
  const itemStyle: Record<string, string | number> = {
343
343
  gridColumn: `${layoutItem.x + 1} / span ${layoutItem.w}`,
344
344
  gridRow: `${layoutItem.y + 1} / span ${layoutItem.h}`,
345
- overflow: "hidden",
345
+ position: "relative",
346
+ overflowY: "hidden",
346
347
  width: "100%",
347
- height: "100%", // Use full height of grid cell
348
+ height: "100%",
348
349
  border: options.hideFrameBorders ? "none" : "1px solid #e0e0e0",
349
- position: "relative" as const,
350
- alignSelf: "stretch", // Stretch to fill the grid cell height
351
- justifySelf: "stretch", // Stretch to fill the grid cell width
350
+ alignSelf: "stretch",
351
+ justifySelf: "stretch",
352
352
  };
353
353
 
354
354
  // Create wrapper div for proper grid positioning
355
355
  const wrapper = document.createElement("div");
356
+ wrapper.classList.add("metaframe-container");
356
357
  Object.assign(wrapper.style, itemStyle);
358
+
359
+ // Absolutely position iframe within its relative container
360
+ iframe.classList.add("metaframe");
361
+ iframe.style.position = "absolute";
362
+ iframe.style.top = "0";
363
+ iframe.style.left = "0";
364
+ iframe.style.width = "100%";
365
+ iframe.style.height = "100%";
366
+ iframe.style.border = "0";
367
+ iframe.style.overflow = "hidden";
368
+
357
369
  wrapper.appendChild(iframe);
358
370
 
359
371
  gridContainer.appendChild(wrapper);
@@ -0,0 +1 @@
1
+ /* Optional styles for metapage rendering */