diff --git a/embeds/codepen.ts b/embeds/codepen.ts index 52290d0..be81b06 100644 --- a/embeds/codepen.ts +++ b/embeds/codepen.ts @@ -1,25 +1,23 @@ import { PluginSettings } from "main"; import { EmbedBase } from "./embedBase"; -export class CodepenEmbed implements EmbedBase { +export class CodepenEmbed extends EmbedBase { name = "CodePen"; - regex = new RegExp(/https:\/\/codepen\.io\/(\w+)\/(?:pen)\/(\w+)/); + regex = new RegExp(/https:\/\/codepen\.io\/(\w+)\/pen\/(\w+)(\?.*)?/); - createEmbed(link: string, container: HTMLElement, settings: Readonly): HTMLElement { - const iframe = createEl("iframe", {parent: container}); + createEmbed(url: string, settings: Readonly): HTMLElement { + const regexMatch = url.match(this.regex); + // Shouldn't happen since got test before. But in case + if (regexMatch === null) + return this.onErrorCreatingEmbed(); - let url = link; - if (link.contains("?")) - url = link.substring(0, link.indexOf("?")); - if (link.contains("/pen/")) - url = url.replace("/pen/", "/embed/"); + // Creating the iframe + const iframe = createEl("iframe"); - iframe.src = url + "?default-tab=result&editable=true"; - // iframe.href = url + "?default-tab=result&editable=true"; - iframe.textContent = "Codepen"; - container.appendChild(iframe); - container.classList.add("codepen"); + iframe.src = `https://codepen.io/${regexMatch[1]}/embed/${regexMatch[2]}?default-tab=result&editable=true`; + + iframe.classList.add("auto-embed", "codepen-embed"); return iframe; } -} \ No newline at end of file +} \ No newline at end of file diff --git a/embeds/embedBase.ts b/embeds/embedBase.ts index 4a92c2c..36dcf7a 100644 --- a/embeds/embedBase.ts +++ b/embeds/embedBase.ts @@ -1,13 +1,25 @@ import { PluginSettings } from "main"; -export interface EmbedBase { +export abstract class EmbedBase { readonly name: string; // To identify if the anchor link matches the embed type readonly regex: RegExp; - createEmbed( - link: string, - container: HTMLElement, - settings: Readonly, - ): HTMLElement; + abstract createEmbed( + link: string, + settings: Readonly, + ): HTMLElement; + + onload?(): void; + + onunload?(): void; + + onErrorCreatingEmbed(): HTMLElement { + const errorMsg = "Error with codepen url"; + const error = createEl("p"); + error.setText(errorMsg); + + console.log(errorMsg); + return error; + } } \ No newline at end of file diff --git a/embeds/twitter.ts b/embeds/twitter.ts new file mode 100644 index 0000000..a2f4b61 --- /dev/null +++ b/embeds/twitter.ts @@ -0,0 +1,79 @@ +import { PluginSettings } from "main"; +import { EmbedBase } from "./embedBase"; + +export class TwitterEmbed extends EmbedBase { + name = "Twitter"; + regex = new RegExp(/https:\/\/(?:x|twitter)\.com\/\w+\/status\/(\w+)/); + + onload(): void { + window.addEventListener("message", this.listenForTwitterResize); + } + + createEmbed(url: string, settings: Readonly): HTMLElement { + const regexMatch = url.match(this.regex); + // Shouldn't happen since got test before. But in case + if (regexMatch === null) + return this.onErrorCreatingEmbed(); + + // Creating the iframe + const iframe = createEl("iframe"); + const postId = regexMatch[1]; + + url = "https://platform.twitter.com/embed/Tweet.html?dnt=true&theme=dark&id=" + postId; + iframe.src = url; + + iframe.id += "twitter-" + postId; + iframe.classList.add("auto-embed", "twitter-embed"); + + iframe.sandbox.add("allow-forms", "allow-presentation", "allow-same-origin", "allow-scripts", "allow-modals", "allow-popups"); + iframe.setAttribute("scrolling", "no"); + iframe.setAttribute("allowfullscreen", ""); + + return iframe; + } + + onunload() : void { + window.removeEventListener("message", this.listenForTwitterResize); + } + + listenForTwitterResize(e: MessageEvent) { + console.log("Origin: " + e.origin); + console.log("Data: " + e.data); + if (e.origin !== "https://platform.twitter.com") + return; + + // Twitter Params format: + /* + twttr.embed { + id: string, + jsonrpc: "2.0", + method: string, + params[]: + { + width: number; + height: number; + data: { + tweet_id: string; + }; + } + } + + */ + // To visualise the data: + // console.log(e.data); + + // Only continue if the method is for resizing + if (e.data["twttr.embed"]["method"] !== "twttr.private.resize") + return; + + const params = e.data["twttr.embed"]["params"][0]; + + const iframe = document.getElementById("twitter-" + params["data"]["tweet_id"]) as HTMLIFrameElement; + console.log("Tweet-id: " + params["data"]["tweet_id"]); + if (iframe === null) + return; + + iframe.style.height = params["height"] + "px"; + iframe.style.width = params["width"] + "px"; + } +} \ No newline at end of file diff --git a/main.ts b/main.ts index 95ea74f..30c12dd 100644 --- a/main.ts +++ b/main.ts @@ -1,6 +1,8 @@ import { CodepenEmbed } from 'embeds/codepen'; +import { TwitterEmbed } from 'embeds/twitter'; import { EmbedBase } from 'embeds/embedBase'; import { Plugin } from 'obsidian'; +import { YouTubeEmbed } from 'embeds/youtube'; // Remember to rename these classes and interfaces! @@ -16,24 +18,33 @@ export default class MyPlugin extends Plugin { settings: PluginSettings; embedSources: EmbedBase[] = [ new CodepenEmbed(), + new TwitterEmbed(), + new YouTubeEmbed(), ] async onload() { - console.log('loading plugin!!') + console.log('loading plugin'); await this.loadSettings(); + + this.embedSources.forEach(source => { + source.onload?.(); + }); this.registerMarkdownPostProcessor((el, ctx) => { console.log("Registering markdown") const anchors = el.querySelectorAll('a.external-link') as NodeListOf; anchors.forEach((anchor) => { - console.log("Testing: " + anchor.text); this.handleAnchor(anchor); }) }) } onunload() { - console.log('unloading plugin') + console.log('unloading plugin'); + + this.embedSources.forEach(source => { + source.onunload?.(); + }); } async loadSettings() { @@ -69,10 +80,8 @@ export default class MyPlugin extends Plugin { } private createEmbed(embedSource: EmbedBase, link: string) { - const container = createDiv({cls: "embed-container"}); - const embed = embedSource.createEmbed(link, container, this.settings); + const embed = embedSource.createEmbed(link, this.settings); return embed; - return container; } private insertEmbed(a: HTMLAnchorElement, container: HTMLElement) { diff --git a/styles.css b/styles.css index 527dabc..977e0d8 100644 --- a/styles.css +++ b/styles.css @@ -6,19 +6,33 @@ available in the app when your plugin is enabled. If your plugin does not need CSS, delete this file. */ -iframe { - width: 100%; - min-height: 500px; +iframe.auto-embed { + max-width: 100%; + /* min-height: 500px; */ } -iframe.small { +iframe.small.auto-embed { min-height: 300px; } -iframe.large { +iframe.large.auto-embed { min-height: 1000px; } -iframe.largest { +iframe.largest.auto-embed { min-height: calc(100vh - 100px); +} + +.auto-embed.twitter-embed { + width: 600px; + height: 350px; + min-height: unset; +} + +.auto-embed.youtube-embed { + /* width: 560px; + height: 315px; */ + + width: 100%; + aspect-ratio: 1.7777; } \ No newline at end of file