mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
feat: use hostname from embed settings in matcher
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import { find } from "lodash";
|
||||
import * as React from "react";
|
||||
import Frame from "../components/Frame";
|
||||
import Image from "../components/Image";
|
||||
@@ -11,16 +10,6 @@ function Diagrams(props: Props) {
|
||||
? `Diagrams.net (${params.get("title")})`
|
||||
: "Diagrams.net";
|
||||
|
||||
const integration = find(
|
||||
props.embedIntegrations,
|
||||
(i) => i.service === "diagrams"
|
||||
);
|
||||
|
||||
// TODO: This is just for initial debugging
|
||||
// to ensure proper data flow. It'll be removed
|
||||
// once further work is done.
|
||||
console.log(integration);
|
||||
|
||||
return (
|
||||
<Frame
|
||||
{...props}
|
||||
|
||||
@@ -53,13 +53,31 @@ export type EmbedProps = {
|
||||
href: string;
|
||||
matches: RegExpMatchArray;
|
||||
};
|
||||
embedIntegrations?: any;
|
||||
embedIntegrations?: any[];
|
||||
};
|
||||
|
||||
function matcher(Component: React.ComponentType<EmbedProps>) {
|
||||
return (url: string): boolean | [] | RegExpMatchArray => {
|
||||
return (url: string, embedConfig?: any): boolean | [] | RegExpMatchArray => {
|
||||
// @ts-expect-error not aware of static
|
||||
const regexes = Component.ENABLED;
|
||||
let regexes = Component.ENABLED;
|
||||
|
||||
if (embedConfig) {
|
||||
const hostname = embedConfig?.settings.hostname;
|
||||
|
||||
try {
|
||||
const url = new URL(hostname);
|
||||
regexes = [
|
||||
new RegExp(
|
||||
`^${url.protocol}//${url.host.replace(
|
||||
/\./g,
|
||||
"\\."
|
||||
)}/(?!proxy).*(title=\\\\w+)?`
|
||||
),
|
||||
];
|
||||
} catch (err) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
for (const regex of regexes) {
|
||||
const result = url.match(regex);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { find } from "lodash";
|
||||
import Token from "markdown-it/lib/token";
|
||||
import { NodeSpec, NodeType, Node as ProsemirrorNode } from "prosemirror-model";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
@@ -28,12 +29,16 @@ export default class Embed extends Node {
|
||||
{
|
||||
tag: "iframe.embed",
|
||||
getAttrs: (dom: HTMLIFrameElement) => {
|
||||
const { embeds } = this.editor.props;
|
||||
const { embeds, embedIntegrations } = this.editor.props;
|
||||
const href = dom.getAttribute("src") || "";
|
||||
|
||||
if (embeds) {
|
||||
for (const embed of embeds) {
|
||||
const matches = embed.matcher(href);
|
||||
const embedConf = find(
|
||||
embedIntegrations,
|
||||
(i) => i.service === embed.component.name.toLowerCase()
|
||||
);
|
||||
const matches = embed.matcher(href, embedConf);
|
||||
if (matches) {
|
||||
return {
|
||||
href,
|
||||
@@ -60,7 +65,9 @@ export default class Embed extends Node {
|
||||
}
|
||||
|
||||
get rulePlugins() {
|
||||
return [embedsRule(this.options.embeds)];
|
||||
const { embeds } = this.options;
|
||||
const { embedIntegrations } = this.editor.props;
|
||||
return [embedsRule(embeds, embedIntegrations as any[])];
|
||||
}
|
||||
|
||||
component({ isEditable, isSelected, theme, node }: ComponentProps) {
|
||||
@@ -76,7 +83,11 @@ export default class Embed extends Node {
|
||||
|
||||
if (!Component) {
|
||||
for (const e of embeds) {
|
||||
const m = e.matcher(node.attrs.href);
|
||||
const embedConf = find(
|
||||
embedIntegrations,
|
||||
(i) => i.service === e.component.name.toLowerCase()
|
||||
);
|
||||
const m = e.matcher(node.attrs.href, embedConf);
|
||||
if (m) {
|
||||
Component = e.component;
|
||||
matches = m;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { find } from "lodash";
|
||||
import { toggleMark } from "prosemirror-commands";
|
||||
import { Plugin } from "prosemirror-state";
|
||||
import { isInTable } from "prosemirror-tables";
|
||||
@@ -96,11 +97,15 @@ export default class PasteHandler extends Extension {
|
||||
}
|
||||
|
||||
// Is this link embeddable? Create an embed!
|
||||
const { embeds } = this.editor.props;
|
||||
const { embeds, embedIntegrations } = this.editor.props;
|
||||
|
||||
if (embeds && !isInTable(state)) {
|
||||
for (const embed of embeds) {
|
||||
const matches = embed.matcher(text);
|
||||
const embedConf = find(
|
||||
embedIntegrations,
|
||||
(i) => i.service === embed.component.name.toLowerCase()
|
||||
);
|
||||
const matches = embed.matcher(text, embedConf);
|
||||
if (matches) {
|
||||
this.editor.commands.embed({
|
||||
href: text,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { find } from "lodash";
|
||||
import MarkdownIt from "markdown-it";
|
||||
import Token from "markdown-it/lib/token";
|
||||
import { EmbedDescriptor } from "../types";
|
||||
@@ -18,7 +19,10 @@ function isLinkClose(token: Token) {
|
||||
return token.type === "link_close";
|
||||
}
|
||||
|
||||
export default function linksToEmbeds(embeds: EmbedDescriptor[]) {
|
||||
export default function linksToEmbeds(
|
||||
embeds: EmbedDescriptor[],
|
||||
embedIntegrations: any[]
|
||||
) {
|
||||
function isEmbed(token: Token, link: Token) {
|
||||
const href = link.attrs ? link.attrs[0][1] : "";
|
||||
const simpleLink = href === token.content;
|
||||
@@ -31,7 +35,13 @@ export default function linksToEmbeds(embeds: EmbedDescriptor[]) {
|
||||
}
|
||||
|
||||
for (const embed of embeds) {
|
||||
const matches = embed.matcher(href);
|
||||
const matches = embed.matcher(
|
||||
href,
|
||||
find(
|
||||
embedIntegrations,
|
||||
(i) => i.service === embed.component.name.toLowerCase()
|
||||
)
|
||||
);
|
||||
if (matches) {
|
||||
return {
|
||||
...embed,
|
||||
|
||||
@@ -29,7 +29,7 @@ export type MenuItem = {
|
||||
|
||||
export type EmbedDescriptor = MenuItem & {
|
||||
icon: React.FC<any>;
|
||||
matcher: (url: string) => boolean | [] | RegExpMatchArray;
|
||||
matcher: (url: string, embedConfig?: any) => boolean | [] | RegExpMatchArray;
|
||||
component: typeof React.Component | React.FC<any>;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user