From badaba8373d01576d47c9e1dc19bad644bdb2bd9 Mon Sep 17 00:00:00 2001
From: SupunKavinda
Date: Wed, 23 Oct 2024 17:40:42 +0530
Subject: [PATCH] wip
---
.temp/iframe-inner.html | 22 +++++++
src/Embed/Embed.php | 9 ++-
src/Embed/Iframe/PrivacyIframe.php | 21 +++++++
src/UnfoldConfig.php | 25 --------
website/src/routes/[[slug]]/Iframe.svelte | 57 +++++++++++++++++++
.../src/routes/[[slug]]/Introduction.svelte | 2 +-
website/src/routes/[[slug]]/docs.ts | 14 +++--
website/src/routes/iframe-test/+page.svelte | 8 +++
.../src/routes/iframe-test/inner/+page.svelte | 25 ++++++++
website/static/child.js | 42 ++++++++++++++
website/static/parent.js | 15 +++++
11 files changed, 207 insertions(+), 33 deletions(-)
create mode 100644 .temp/iframe-inner.html
create mode 100644 website/src/routes/[[slug]]/Iframe.svelte
create mode 100644 website/src/routes/iframe-test/+page.svelte
create mode 100644 website/src/routes/iframe-test/inner/+page.svelte
create mode 100644 website/static/child.js
create mode 100644 website/static/parent.js
diff --git a/.temp/iframe-inner.html b/.temp/iframe-inner.html
new file mode 100644
index 0000000..02494c7
--- /dev/null
+++ b/.temp/iframe-inner.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Embed/Embed.php b/src/Embed/Embed.php
index 80ab284..c8e6023 100644
--- a/src/Embed/Embed.php
+++ b/src/Embed/Embed.php
@@ -2,6 +2,7 @@
namespace Hyvor\Unfold\Embed;
+use Hyvor\Unfold\Embed\Iframe\PrivacyIframe;
use Hyvor\Unfold\Exception\EmbedUnableToResolveException;
use Hyvor\Unfold\Exception\EmbedParserException;
use Hyvor\Unfold\Exception\UnfoldException;
@@ -19,11 +20,11 @@ public static function getParsers(): array
$namespace = __NAMESPACE__ . '\\Platforms\\';
$parsers = array_map(
- fn ($file) => $namespace . pathinfo((string)$file, PATHINFO_FILENAME),
+ fn($file) => $namespace . pathinfo((string)$file, PATHINFO_FILENAME),
(array)glob(__DIR__ . '/Platforms/*.php')
);
- usort($parsers, fn ($a, $b) => $b::PRIORITY <=> $a::PRIORITY);
+ usort($parsers, fn($a, $b) => $b::PRIORITY <=> $a::PRIORITY);
return $parsers;
}
@@ -73,6 +74,10 @@ public static function getUnfoldedObject(
): Unfolded {
$oembed = self::parse($url, $context->config);
+ if ($context->config->embedIframeEndpoint && $oembed->html) {
+ $oembed->html = PrivacyIframe::wrap($oembed->html);
+ }
+
return Unfolded::fromEmbed(
$oembed,
$url,
diff --git a/src/Embed/Iframe/PrivacyIframe.php b/src/Embed/Iframe/PrivacyIframe.php
index 907c834..b5876c2 100644
--- a/src/Embed/Iframe/PrivacyIframe.php
+++ b/src/Embed/Iframe/PrivacyIframe.php
@@ -5,4 +5,25 @@
class PrivacyIframe
{
+ public static function wrap(string $html): string
+ {
+ $encoded = base64_encode($html);
+
+ return <<
+
+
+HTML;
+ }
+
+}
+
+class EmbedController
+{
+ public function handle()
+ {
+ $url = $_GET['url'];
+ $embed = Unfold::unfold($url, EMBED);
+ echo $embed;
+ }
}
\ No newline at end of file
diff --git a/src/UnfoldConfig.php b/src/UnfoldConfig.php
index 3c4cc42..586c561 100644
--- a/src/UnfoldConfig.php
+++ b/src/UnfoldConfig.php
@@ -33,26 +33,6 @@ public function __construct(
*/
public UnfoldMethod $method = UnfoldMethod::LINK,
- /**
- * Adding embed codes directly to the page can be a privacy concern since
- * it gives third-party platforms full access to the page via Javascript.
- * The best solution is to wrap the embed code in an iframe.
- *
- * We tried using iframe `srcdoc` directly, but it resulted in many inconsistencies and issues
- * with different platforms (ex: Reddit does not support about: scheme in srcdoc).
- *
- * So, the best solution is to use an iframe endpoint that wraps the embed code.
- * This requires you to add an endpoint to your app to serve the iframe.
- * Then, set that endpoint's absolute URL in this config.
- * See https://unfold.hyvor.com/iframe for more details.
- *
- * Ex: 'https://yourapp.com/unfold-iframe'
- *
- * If this option is set to a string, the embed code will be wrapped in an iframe.
- * It also comes with JS code to handle iframe resizing.
- */
- public ?string $embedIframeEndpoint = null,
-
/**
* If the $method is UnfoldMethod::EMBED or UnfoldMethod::EMBED_LINK,
* and if we cannot find a way to embed the URL using our default parsers,
@@ -80,11 +60,6 @@ public function __construct(
*/
public string $httpUserAgent = 'Hyvor Unfold PHP Client',
- /**
- * TODO: Implement this
- */
- public ?string $iframeEndpoint = null,
-
/**
* Meta requires an access_token to access the OEmbed Read Graph API
* This is required for both FacebookPost & Instagram
diff --git a/website/src/routes/[[slug]]/Iframe.svelte b/website/src/routes/[[slug]]/Iframe.svelte
new file mode 100644
index 0000000..2f403cb
--- /dev/null
+++ b/website/src/routes/[[slug]]/Iframe.svelte
@@ -0,0 +1,57 @@
+
+
+
Privacy Iframe
+
+
+ Adding embed codes directly to your website is a privacy concern since most of
+ the time they include Javascript libraries that can access your page and user's data. Using an
+ iframe to wrap the embed code is the best way to prevent this.
+
+
+Docker Image
+
+
+ If you are using the Docker image, the iframe endpoint is already included.
+ On your website, use iframes with `src` set to /iframe?url=my-url
to embed content.
+
+
+
+`}
+/>
+
+PHP Library
+
+
+ If you are using the PHP Library, you have to set up an endpoint for the
+ iframe. Here is an example with Laravel:
+
+
+input('url');
+
+ try {
+ $data = Unfold::unfold($url);
+ return PrivacyIframe::inner($data);
+ } catch (UnfoldException) {
+ // handle the exception
+ }
+ }
+
+}
+`}
+ language="js"
+/>
diff --git a/website/src/routes/[[slug]]/Introduction.svelte b/website/src/routes/[[slug]]/Introduction.svelte
index e6d4666..498c4a9 100644
--- a/website/src/routes/[[slug]]/Introduction.svelte
+++ b/website/src/routes/[[slug]]/Introduction.svelte
@@ -2,7 +2,7 @@
import { CodeBlock } from '@hyvor/design/components';
-Introduction
+Hyvor Unfold
Hyvor Unfold is an open-source API that can fetch metadata from URLs for acc.concat(category.pages), [] as Page[]);
diff --git a/website/src/routes/iframe-test/+page.svelte b/website/src/routes/iframe-test/+page.svelte
new file mode 100644
index 0000000..5ecafff
--- /dev/null
+++ b/website/src/routes/iframe-test/+page.svelte
@@ -0,0 +1,8 @@
+This is an iframe that changes its height every time you click on it.
+
+
+
+
+
+
diff --git a/website/src/routes/iframe-test/inner/+page.svelte b/website/src/routes/iframe-test/inner/+page.svelte
new file mode 100644
index 0000000..47fc03e
--- /dev/null
+++ b/website/src/routes/iframe-test/inner/+page.svelte
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ {#each Array(items) as _, i}
+
+ {/each}
+
+
+
diff --git a/website/static/child.js b/website/static/child.js
new file mode 100644
index 0000000..2b6bce6
--- /dev/null
+++ b/website/static/child.js
@@ -0,0 +1,42 @@
+(function () {
+ function sendHeight() {
+ const height = document.documentElement.scrollHeight;
+
+ try {
+ const iframe = window.frameElement;
+ if (iframe) {
+ iframe.style.height = `${height}px`;
+ } else {
+ throw new Error('iframe not found');
+ }
+ } catch (e) {
+ window.parent.postMessage(
+ {
+ type: 'unfold-iframe-resize',
+ height
+ },
+ '*'
+ );
+ }
+ }
+
+ let mutationCallTimeout = null;
+
+ function processMutations() {
+ if (mutationCallTimeout) {
+ clearTimeout(mutationCallTimeout);
+ }
+ mutationCallTimeout = setTimeout(sendHeight, 100);
+ }
+
+ function init() {
+ const mutation = new window.MutationObserver(processMutations);
+ mutation.observe(document.body, {
+ childList: true,
+ subtree: true
+ });
+ sendHeight();
+ }
+
+ document.addEventListener('DOMContentLoaded', init);
+})();
diff --git a/website/static/parent.js b/website/static/parent.js
new file mode 100644
index 0000000..b061fb9
--- /dev/null
+++ b/website/static/parent.js
@@ -0,0 +1,15 @@
+(function () {
+ window.addEventListener('message', function (event) {
+ const source = event.source;
+ const iframes = document.querySelectorAll('iframe');
+
+ for (let iframe in iframes) {
+ if (iframes[iframe].contentWindow === source) {
+ console.log('found the source', event.data);
+ if (event.data.type === 'unfold-iframe-resize') {
+ iframes[iframe].style.height = `${event.data.height}px`;
+ }
+ }
+ }
+ });
+})();