Timothy Jaeryang Baek 2 veckor sedan
förälder
incheckning
a89ffccd7e
3 ändrade filer med 69 tillägg och 2 borttagningar
  1. 25 0
      package-lock.json
  2. 1 0
      package.json
  3. 43 2
      src/lib/components/common/FullHeightIframe.svelte

+ 25 - 0
package-lock.json

@@ -39,6 +39,7 @@
 				"@tiptap/starter-kit": "^3.0.7",
 				"@tiptap/suggestion": "^3.4.2",
 				"@xyflow/svelte": "^0.1.19",
+				"alpinejs": "^3.15.0",
 				"async": "^3.2.5",
 				"bits-ui": "^0.21.15",
 				"chart.js": "^4.5.0",
@@ -4569,6 +4570,21 @@
 				"@types/estree": "^1.0.0"
 			}
 		},
+		"node_modules/@vue/reactivity": {
+			"version": "3.1.5",
+			"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz",
+			"integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==",
+			"license": "MIT",
+			"dependencies": {
+				"@vue/shared": "3.1.5"
+			}
+		},
+		"node_modules/@vue/shared": {
+			"version": "3.1.5",
+			"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz",
+			"integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==",
+			"license": "MIT"
+		},
 		"node_modules/@webreflection/fetch": {
 			"version": "0.1.5",
 			"resolved": "https://registry.npmjs.org/@webreflection/fetch/-/fetch-0.1.5.tgz",
@@ -4672,6 +4688,15 @@
 				"url": "https://github.com/sponsors/epoberezkin"
 			}
 		},
+		"node_modules/alpinejs": {
+			"version": "3.15.0",
+			"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.15.0.tgz",
+			"integrity": "sha512-lpokA5okCF1BKh10LG8YjqhfpxyHBk4gE7boIgVHltJzYoM7O9nK3M7VlntLEJGsVmu7U/RzUWajmHREGT38Eg==",
+			"license": "MIT",
+			"dependencies": {
+				"@vue/reactivity": "~3.1.1"
+			}
+		},
 		"node_modules/amator": {
 			"version": "1.1.0",
 			"resolved": "https://registry.npmjs.org/amator/-/amator-1.1.0.tgz",

+ 1 - 0
package.json

@@ -83,6 +83,7 @@
 		"@tiptap/starter-kit": "^3.0.7",
 		"@tiptap/suggestion": "^3.4.2",
 		"@xyflow/svelte": "^0.1.19",
+		"alpinejs": "^3.15.0",
 		"async": "^3.2.5",
 		"bits-ui": "^0.21.15",
 		"chart.js": "^4.5.0",

+ 43 - 2
src/lib/components/common/FullHeightIframe.svelte

@@ -60,9 +60,50 @@
 	}
 
 	// When the iframe loads, try same-origin resize (cross-origin will noop)
-	function onLoad() {
+	const onLoad = async () => {
 		requestAnimationFrame(resizeSameOrigin);
-	}
+
+		// If we're injecting Alpine into srcdoc iframe and sameOrigin allowed
+		if (iframeDoc && allowSameOrigin && iframe?.contentWindow) {
+			const alpineDirectives = [
+				'x-data',
+				'x-init',
+				'x-show',
+				'x-bind',
+				'x-on',
+				'x-text',
+				'x-html',
+				'x-model',
+				'x-modelable',
+				'x-ref',
+				'x-for',
+				'x-if',
+				'x-effect',
+				'x-transition',
+				'x-cloak',
+				'x-ignore',
+				'x-teleport',
+				'x-id'
+			];
+
+			const isAlpine = alpineDirectives.some((dir) => iframeDoc?.includes(dir));
+
+			if (isAlpine) {
+				const { default: Alpine } = await import('alpinejs');
+				const win = iframe.contentWindow as Window & { Alpine?: typeof Alpine };
+
+				// Assign Alpine
+				win.Alpine = Alpine;
+
+				// Initialize inside iframe DOM
+				try {
+					Alpine.start();
+				} catch (e) {
+					console.error('Error starting Alpine inside iframe:', e);
+				}
+			}
+		}
+	};
 
 	// Ensure event listener bound only while component lives
 	onMount(() => {