Compare commits
4 Commits
master
...
ryan-di/mo
Author | SHA1 | Date | |
---|---|---|---|
|
0ef2611633 | ||
|
46c12a9f8c | ||
|
20dae101e9 | ||
|
022c407e24 |
@ -44,6 +44,8 @@ const RE_TWITTER_EMBED =
|
|||||||
const RE_VALTOWN =
|
const RE_VALTOWN =
|
||||||
/^https:\/\/(?:www\.)?val\.town\/(v|embed)\/[a-zA-Z_$][0-9a-zA-Z_$]+\.[a-zA-Z_$][0-9a-zA-Z_$]+/;
|
/^https:\/\/(?:www\.)?val\.town\/(v|embed)\/[a-zA-Z_$][0-9a-zA-Z_$]+\.[a-zA-Z_$][0-9a-zA-Z_$]+/;
|
||||||
|
|
||||||
|
const RE_SLIDO = /^https:\/\/app\.sli\.do\/event\/([a-zA-Z0-9]+)/;
|
||||||
|
|
||||||
const RE_GENERIC_EMBED =
|
const RE_GENERIC_EMBED =
|
||||||
/^<(?:iframe|blockquote)[\s\S]*?\s(?:src|href)=["']([^"']*)["'][\s\S]*?>$/i;
|
/^<(?:iframe|blockquote)[\s\S]*?\s(?:src|href)=["']([^"']*)["'][\s\S]*?>$/i;
|
||||||
|
|
||||||
@ -56,7 +58,7 @@ const RE_REDDIT =
|
|||||||
const RE_REDDIT_EMBED =
|
const RE_REDDIT_EMBED =
|
||||||
/^<blockquote[\s\S]*?\shref=["'](https?:\/\/(?:www\.)?reddit\.com\/[^"']*)/i;
|
/^<blockquote[\s\S]*?\shref=["'](https?:\/\/(?:www\.)?reddit\.com\/[^"']*)/i;
|
||||||
|
|
||||||
const ALLOWED_DOMAINS = new Set([
|
const ALLOWED_EMBED_HOSTS = new Set([
|
||||||
"youtube.com",
|
"youtube.com",
|
||||||
"youtu.be",
|
"youtu.be",
|
||||||
"vimeo.com",
|
"vimeo.com",
|
||||||
@ -72,6 +74,9 @@ const ALLOWED_DOMAINS = new Set([
|
|||||||
"giphy.com",
|
"giphy.com",
|
||||||
"reddit.com",
|
"reddit.com",
|
||||||
"forms.microsoft.com",
|
"forms.microsoft.com",
|
||||||
|
"forms.gle",
|
||||||
|
"docs.google.com/forms",
|
||||||
|
"app.sli.do",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const ALLOW_SAME_ORIGIN = new Set([
|
const ALLOW_SAME_ORIGIN = new Set([
|
||||||
@ -86,6 +91,9 @@ const ALLOW_SAME_ORIGIN = new Set([
|
|||||||
"stackblitz.com",
|
"stackblitz.com",
|
||||||
"reddit.com",
|
"reddit.com",
|
||||||
"forms.microsoft.com",
|
"forms.microsoft.com",
|
||||||
|
"forms.gle",
|
||||||
|
"docs.google.com",
|
||||||
|
"app.sli.do",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const createSrcDoc = (body: string) => {
|
export const createSrcDoc = (body: string) => {
|
||||||
@ -278,6 +286,23 @@ export const getEmbedLink = (
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (RE_SLIDO.test(link)) {
|
||||||
|
const [, eventId] = link.match(RE_SLIDO)!;
|
||||||
|
link = `https://app.sli.do/event/${eventId}`;
|
||||||
|
embeddedLinkCache.set(originalLink, {
|
||||||
|
link,
|
||||||
|
intrinsicSize: aspectRatio,
|
||||||
|
type,
|
||||||
|
sandbox: { allowSameOrigin },
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
link,
|
||||||
|
intrinsicSize: aspectRatio,
|
||||||
|
type,
|
||||||
|
sandbox: { allowSameOrigin },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
embeddedLinkCache.set(link, {
|
embeddedLinkCache.set(link, {
|
||||||
link,
|
link,
|
||||||
intrinsicSize: aspectRatio,
|
intrinsicSize: aspectRatio,
|
||||||
@ -335,20 +360,29 @@ const matchHostname = (
|
|||||||
allowedHostnames: Set<string> | string,
|
allowedHostnames: Set<string> | string,
|
||||||
): string | null => {
|
): string | null => {
|
||||||
try {
|
try {
|
||||||
const { hostname } = new URL(url);
|
const { hostname, pathname } = new URL(url);
|
||||||
|
|
||||||
const bareDomain = hostname.replace(/^www\./, "");
|
const bareDomain = hostname.replace(/^www\./, "");
|
||||||
|
|
||||||
if (allowedHostnames instanceof Set) {
|
if (allowedHostnames instanceof Set) {
|
||||||
if (ALLOWED_DOMAINS.has(bareDomain)) {
|
// Check for exact domain match
|
||||||
|
if (ALLOWED_EMBED_HOSTS.has(bareDomain)) {
|
||||||
return bareDomain;
|
return bareDomain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for path-based match (e.g., docs.google.com/forms)
|
||||||
|
const domainWithPath = `${bareDomain}${
|
||||||
|
pathname.split("/")[1] ? `/${pathname.split("/")[1]}` : ""
|
||||||
|
}`;
|
||||||
|
if (ALLOWED_EMBED_HOSTS.has(domainWithPath)) {
|
||||||
|
return domainWithPath;
|
||||||
|
}
|
||||||
|
|
||||||
const bareDomainWithFirstSubdomainWildcarded = bareDomain.replace(
|
const bareDomainWithFirstSubdomainWildcarded = bareDomain.replace(
|
||||||
/^([^.]+)/,
|
/^([^.]+)/,
|
||||||
"*",
|
"*",
|
||||||
);
|
);
|
||||||
if (ALLOWED_DOMAINS.has(bareDomainWithFirstSubdomainWildcarded)) {
|
if (ALLOWED_EMBED_HOSTS.has(bareDomainWithFirstSubdomainWildcarded)) {
|
||||||
return bareDomainWithFirstSubdomainWildcarded;
|
return bareDomainWithFirstSubdomainWildcarded;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -399,6 +433,7 @@ export const embeddableURLValidator = (
|
|||||||
if (!url) {
|
if (!url) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validateEmbeddable != null) {
|
if (validateEmbeddable != null) {
|
||||||
if (typeof validateEmbeddable === "function") {
|
if (typeof validateEmbeddable === "function") {
|
||||||
const ret = validateEmbeddable(url);
|
const ret = validateEmbeddable(url);
|
||||||
@ -424,5 +459,5 @@ export const embeddableURLValidator = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!matchHostname(url, ALLOWED_DOMAINS);
|
return !!matchHostname(url, ALLOWED_EMBED_HOSTS);
|
||||||
};
|
};
|
||||||
|
@ -11,6 +11,7 @@ export const actionSetEmbeddableAsActiveTool = register({
|
|||||||
trackEvent: { category: "toolbar" },
|
trackEvent: { category: "toolbar" },
|
||||||
target: "Tool",
|
target: "Tool",
|
||||||
label: "toolBar.embeddable",
|
label: "toolBar.embeddable",
|
||||||
|
keywords: ["embeddable", "embed", "iframe"],
|
||||||
perform: (elements, appState, _, app) => {
|
perform: (elements, appState, _, app) => {
|
||||||
const nextActiveTool = updateActiveTool(appState, {
|
const nextActiveTool = updateActiveTool(appState, {
|
||||||
type: "embeddable",
|
type: "embeddable",
|
||||||
|
@ -319,6 +319,7 @@ function CommandPaletteInner({
|
|||||||
actionManager.actions.toggleHandTool,
|
actionManager.actions.toggleHandTool,
|
||||||
actionManager.actions.setFrameAsActiveTool,
|
actionManager.actions.setFrameAsActiveTool,
|
||||||
actionManager.actions.toggleLassoTool,
|
actionManager.actions.toggleLassoTool,
|
||||||
|
actionManager.actions.setEmbeddableAsActiveTool,
|
||||||
].map((action) => actionToCommand(action, DEFAULT_CATEGORIES.tools));
|
].map((action) => actionToCommand(action, DEFAULT_CATEGORIES.tools));
|
||||||
|
|
||||||
const editorCommands: CommandPaletteItem[] = [
|
const editorCommands: CommandPaletteItem[] = [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user