Remove unused files and dependencies (#11850)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Tom Moor
2026-03-22 18:44:51 -04:00
committed by GitHub
parent eda59b1450
commit 0ba310e027
15 changed files with 0 additions and 987 deletions
-14
View File
@@ -1,14 +0,0 @@
export default function Arrow() {
return (
<svg
width="13"
height="30"
viewBox="0 0 13 30"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M7.40242 1.48635C8.23085 0.0650039 10.0656 -0.421985 11.5005 0.39863C12.9354 1.21924 13.427 3.03671 12.5986 4.45806L5.59858 16.4681C4.77015 17.8894 2.93538 18.3764 1.5005 17.5558C0.065623 16.7352 -0.426002 14.9177 0.402425 13.4964L7.40242 1.48635Z" />
<path d="M12.5986 25.5419C13.427 26.9633 12.9354 28.7808 11.5005 29.6014C10.0656 30.422 8.23087 29.935 7.40244 28.5136L0.402438 16.5036C-0.425989 15.0823 0.0656365 13.2648 1.50051 12.4442C2.93539 11.6236 4.77016 12.1106 5.59859 13.5319L12.5986 25.5419Z" />
</svg>
);
}
-11
View File
@@ -1,11 +0,0 @@
import styled from "styled-components";
import { s } from "@shared/styles";
const Divider = styled.hr`
border: 0;
border-bottom: 1px solid ${s("divider")};
margin: 0;
padding: 0;
`;
export default Divider;
-167
View File
@@ -1,167 +0,0 @@
import {
useFocusEffect,
useRovingTabIndex,
} from "@getoutline/react-roving-tabindex";
import { observer } from "mobx-react";
import * as React from "react";
import { Link } from "react-router-dom";
import styled, { css } from "styled-components";
import breakpoint from "styled-components-breakpoint";
import { s, hover, ellipsis } from "@shared/styles";
import type Document from "~/models/Document";
import Highlight, { Mark } from "~/components/Highlight";
import { sharedModelPath } from "~/utils/routeHelpers";
type Props = {
document: Document;
highlight: string;
context: string | undefined;
showParentDocuments?: boolean;
showCollection?: boolean;
showPublished?: boolean;
shareId?: string;
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
};
const SEARCH_RESULT_REGEX = /<b\b[^>]*>(.*?)<\/b>/gi;
function replaceResultMarks(tag: string) {
// don't use SEARCH_RESULT_REGEX here as it causes
// an infinite loop to trigger a regex inside it's own callback
return tag.replace(/<b\b[^>]*>(.*?)<\/b>/gi, "$1");
}
function DocumentListItem(
props: Props,
ref: React.RefObject<HTMLAnchorElement>
) {
const { document, highlight, context, shareId, ...rest } = props;
let itemRef: React.Ref<HTMLAnchorElement> =
React.useRef<HTMLAnchorElement>(null);
if (ref) {
itemRef = ref;
}
const { focused, ...rovingTabIndex } = useRovingTabIndex(itemRef, false);
useFocusEffect(focused, itemRef);
return (
<DocumentLink
ref={itemRef}
dir={document.dir}
to={{
pathname: shareId
? sharedModelPath(shareId, document.url)
: document.url,
search: highlight ? `?q=${encodeURIComponent(highlight)}` : undefined,
state: {
title: document.titleWithDefault,
},
}}
{...rest}
{...rovingTabIndex}
onClick={(ev) => {
if (rest.onClick) {
rest.onClick(ev);
}
rovingTabIndex.onClick(ev);
}}
>
<Content>
<Heading dir={document.dir}>
<Title
text={document.titleWithDefault}
highlight={highlight}
dir={document.dir}
/>
</Heading>
{
<ResultContext
text={context}
highlight={highlight ? SEARCH_RESULT_REGEX : undefined}
processResult={replaceResultMarks}
/>
}
</Content>
</DocumentLink>
);
}
const Content = styled.div`
flex-grow: 1;
flex-shrink: 1;
min-width: 0;
`;
const DocumentLink = styled(Link)<{
$isStarred?: boolean;
$menuOpen?: boolean;
}>`
display: flex;
align-items: center;
padding: 6px 12px;
max-height: 50vh;
cursor: var(--pointer);
&:not(:last-child) {
margin-bottom: 4px;
}
&:focus-visible {
outline: none;
}
${breakpoint("tablet")`
width: auto;
`};
&:${hover},
&:active,
&:focus,
&:focus-within {
background: ${s("listItemHoverBackground")};
}
${(props) =>
props.$menuOpen &&
css`
background: ${s("listItemHoverBackground")};
`}
`;
const Heading = styled.h4<{ rtl?: boolean }>`
display: flex;
justify-content: ${(props) => (props.rtl ? "flex-end" : "flex-start")};
align-items: center;
height: 22px;
margin-top: 0;
margin-bottom: 0.25em;
overflow: hidden;
white-space: nowrap;
color: ${s("text")};
`;
const Title = styled(Highlight)`
max-width: 90%;
${ellipsis()}
${Mark} {
padding: 0;
}
`;
const ResultContext = styled(Highlight)`
display: block;
color: ${s("textTertiary")};
font-size: 14px;
margin-top: -0.25em;
margin-bottom: 0;
${ellipsis()}
${Mark} {
padding: 0;
}
`;
export default observer(React.forwardRef(DocumentListItem));
-30
View File
@@ -1,30 +0,0 @@
import { observer } from "mobx-react";
import { useCallback } from "react";
import { toast } from "sonner";
import { TemplateForm } from "./TemplateForm";
import type Template from "~/models/Template";
type Props = {
template: Template;
onSubmit: () => void;
};
export const TemplateEdit = observer(function TemplateEdit_({
template,
onSubmit,
}: Props) {
const handleSubmit = useCallback(async () => {
try {
await template?.save();
onSubmit?.();
} catch (error) {
toast.error(error.message);
}
}, [template, onSubmit]);
if (!template) {
return null;
}
return <TemplateForm template={template} handleSubmit={handleSubmit} />;
});
-36
View File
@@ -1,36 +0,0 @@
import { observer } from "mobx-react";
import { useCallback, useState } from "react";
import { toast } from "sonner";
import Template from "~/models/Template";
import useStores from "~/hooks/useStores";
import { TemplateForm } from "./TemplateForm";
type Props = {
collectionId?: string | null;
onSubmit?: () => void;
};
export const TemplateNew = observer(function TemplateNew_({
collectionId,
onSubmit,
}: Props) {
const { templates } = useStores();
const [template] = useState(
new Template({ title: "", collectionId }, templates)
);
const handleSubmit = useCallback(async () => {
try {
await template.save();
onSubmit?.();
} catch (error) {
toast.error(error.message);
}
}, [template, onSubmit]);
if (!template) {
return null;
}
return <TemplateForm template={template} handleSubmit={handleSubmit} />;
});
-22
View File
@@ -1,22 +0,0 @@
import * as React from "react";
import styled from "styled-components";
import Flex from "~/components/Flex";
const Label = ({ icon, value }: { icon: React.ReactNode; value: string }) => (
<Flex align="center" gap={4}>
<IconWrapper>{icon}</IconWrapper>
{value}
</Flex>
);
const IconWrapper = styled.span`
display: flex;
justify-content: center;
align-items: center;
height: 24px;
width: 24px;
overflow: hidden;
flex-shrink: 0;
`;
export default Label;
-30
View File
@@ -1,30 +0,0 @@
import { useLayoutEffect, useState } from "react";
/**
* Hook to get the current viewport height, accounting for mobile virtual keyboards.
* Uses the VisualViewport API when available, falling back to window.innerHeight.
*
* @returns The current viewport height in pixels
*/
export default function useViewportHeight(): number | void {
// https://developer.mozilla.org/en-US/docs/Web/API/VisualViewport#browser_compatibility
// Note: No support in Firefox at time of writing, however this mainly exists
// for virtual keyboards on mobile devices, so that's okay.
const [height, setHeight] = useState<number>(
() => window.visualViewport?.height || window.innerHeight
);
useLayoutEffect(() => {
const handleResize = () => {
setHeight(() => window.visualViewport?.height || window.innerHeight);
};
window.visualViewport?.addEventListener("resize", handleResize);
return () => {
window.visualViewport?.removeEventListener("resize", handleResize);
};
}, []);
return height;
}
-7
View File
@@ -1,7 +0,0 @@
import type { MenuSeparator } from "~/types";
export default function separator(): MenuSeparator {
return {
type: "separator",
};
}
-1
View File
@@ -1 +0,0 @@
export const runAllPromises = () => new Promise<void>(setImmediate);
-4
View File
@@ -83,7 +83,6 @@
"@node-oauth/oauth2-server": "^5.2.0",
"@notionhq/client": "^2.3.0",
"@octokit/auth-app": "^6.1.4",
"@octokit/webhooks": "^13.9.1",
"@outlinewiki/koa-passport": "^4.2.1",
"@outlinewiki/passport-azure-ad-oauth2": "^0.1.0",
"@radix-ui/react-collapsible": "^1.1.12",
@@ -112,7 +111,6 @@
"addressparser": "^1.0.1",
"async-sema": "^3.1.1",
"autotrack": "^2.4.1",
"body-scroll-lock": "^4.0.0-beta.0",
"bull": "^4.16.5",
"class-validator": "^0.14.3",
"command-score": "^0.1.2",
@@ -287,7 +285,6 @@
"@faker-js/faker": "^8.4.1",
"@relative-ci/agent": "^4.3.1",
"@types/addressparser": "^1.0.3",
"@types/body-scroll-lock": "^3.1.2",
"@types/cookie": "0.6.0",
"@types/crypto-js": "^4.2.2",
"@types/diff": "^5.0.9",
@@ -382,7 +379,6 @@
"@hocuspocus/server": "1.1.2",
"fengari": "0.1.5",
"prosemirror-transform": "1.10.0",
"body-scroll-lock": "^4.0.0-beta.0",
"d3": "^7.0.0",
"debug": "4.3.4",
"node-fetch": "^2.7.0",
-112
View File
@@ -1,112 +0,0 @@
import { Trans } from "react-i18next";
export const Translations = () => (
<>
<Trans defaults={`New attribute`} />
<Trans defaults={`Paper size`} />
<Trans defaults={`Ask AI "{{question}}"`} />
<Trans defaults={`Are you sure you want to delete?`} />
<Trans
defaults={`Deleting this version of the document will permanently and irrevocably remove it from the history.`}
/>
<Trans defaults={`Format`} />
<Trans defaults={`Add option`} />
<Trans defaults={`Optional`} />
<Trans defaults={`Choose a size for your exported document`} />
<Trans defaults={`Revision renamed`} />
<Trans defaults={`Failed to save revision`} />
<Trans defaults={`Invite to document`} />
<Trans defaults={`Sorry, invalid embed link`} />
<Trans defaults={`Data Attributes`} />
<Trans defaults={`Edit attribute`} />
<Trans defaults={`Property`} />
<Trans defaults={`Yes`} />
<Trans defaults={`No`} />
<Trans defaults={`Search or ask a question`} />
<Trans
defaults={`Invited {{roleName}} will not receive access to any collections or documents unless explicitly shared.`}
/>
<Trans defaults={`Can view only what is explicitly shared`} />
<Trans
defaults={`SAML assertion was invalid or missing fields, please check your configuration`}
/>
<Trans
defaults={`AI generated answer based on related documents in your workspace`}
/>
<Trans defaults={`References`} />
<Trans
defaults={`Enable AI answers to get direct answers to searched questions.`}
/>
<Trans defaults={`Go to settings`} />
<Trans defaults={`Where do I find the file?`} />
<Trans
defaults={`In a Confluence space, navigate to <em>Space Settings -> Manage space -> Export space</em> and choose to export as HTML with the "Normal Export" option.`}
/>
<Trans
defaults={`Drag and drop the zip file from Confluence's HTML export option, or click to upload`}
/>
<Trans defaults={`Guests`} />
<Trans defaults={`New Attribute`} />
<Trans
defaults={`Attributes allow you to define data to be stored with your documents. They can be used to store custom properties, metadata, or any other structured information that is common across documents.`}
/>
<Trans defaults={`Custom domain`} />
<Trans defaults={`AI answers`} />
<Trans
defaults={`Use AI to directly answer searched questions using content in your workspace.`}
/>
<Trans defaults={`API access`} />
<Trans
defaults={`Allow members to create API keys for programmatic access`}
/>
<Trans defaults={`Public document embedding`} />
<Trans
defaults={`When enabled, publicly shared documents can be embedded in third-party websites`}
/>
<Trans defaults={`Include previews in emails`} />
<Trans
defaults={`When enabled, email notifications will include content previews`}
/>
<Trans defaults={`Boolean`} />
<Trans defaults={`Number`} />
<Trans defaults={`Text`} />
<Trans defaults={`List`} />
<Trans defaults={`Could not load events`} />
<Trans defaults={`Audit Log`} />
<Trans
defaults={`The audit log details the history of security related and other events across your knowledge base.`}
/>
<Trans defaults={`IP address`} />
<Trans defaults={`Actor`} />
<Trans defaults={`Event`} />
<Trans defaults={`Timestamp`} />
<Trans defaults={`IP`} />
<Trans defaults={`a group`} />
<Trans defaults={`All users`} />
<Trans defaults={`Private`} />
<Trans defaults={`View and edit`} />
<Trans defaults={`Sharing enabled`} />
<Trans defaults={`Date archived`} />
<Trans defaults={`Could not load collections`} />
<Trans
defaults={`Manage the permissions and settings of all collections in the knowledge base. As a workspace admin you can also administer private collections.`}
/>
<Trans
defaults={`Automatically index and search document content from {{appName}} inside <4>Glean</4> in realtime.`}
/>
<Trans defaults={`API Endpoint`} />
<Trans defaults={`API Secret`} />
<Trans defaults={`Datasource`} />
<Trans
defaults={`Details of the current {{appName}} license. To arrange contract renewal as expiry or seat limits approach or increase licensed seats please contact your account manager or email <4>priority@getoutline.com</4>.`}
/>
<Trans
defaults={`Sorry, an answer could not be found in the collection, try widening your search.`}
/>
<Trans
defaults={`Sorry, an answer could not be found in the workspace, try widening your search.`}
/>
<Trans defaults={`Looking for answers`} />
<Trans defaults={`Answer to "{{ query }}"`} />
</>
);
-1
View File
@@ -1 +0,0 @@
export { default } from "./comments";
@@ -1,390 +0,0 @@
import { Plugin, PluginKey, type EditorState } from "prosemirror-state";
import type { EditorView } from "prosemirror-view";
import { moveTableColumn, moveTableRow } from "prosemirror-tables";
import { EditorStyleHelper } from "../styles/EditorStyleHelper";
import { getCellsInRow, getRowsInTable } from "../queries/table";
interface DragState {
/** The type of drag operation. */
type: "row" | "column";
/** The index of the row/column being dragged. */
fromIndex: number;
/** The current target index for the drop. */
toIndex: number;
/** The grip element being dragged. */
gripElement: HTMLElement;
/** The table element containing the drag. */
tableElement: HTMLElement;
}
const pluginKey = new PluginKey<DragState | null>("table-drag-drop");
/**
* Creates a drop indicator element for visual feedback during drag operations.
*
* @returns the drop indicator element.
*/
function createDropIndicator(): HTMLElement {
const indicator = document.createElement("div");
indicator.className = EditorStyleHelper.tableDragDropIndicator;
return indicator;
}
/**
* Calculates the target index based on mouse position during drag.
*
* @param dragState Current drag state.
* @param mouseX Current mouse X position.
* @param mouseY Current mouse Y position.
* @param state Editor state.
* @returns The target index for the drop.
*/
function calculateTargetIndex(
dragState: DragState,
mouseX: number,
mouseY: number,
state: EditorState
): number {
if (dragState.type === "row") {
return calculateRowTargetIndex(dragState, mouseY, state);
} else {
return calculateColumnTargetIndex(dragState, mouseX, state);
}
}
/**
* Calculates the target row index based on mouse Y position.
*
* @param dragState Current drag state.
* @param mouseY Current mouse Y position.
* @param state Editor state.
* @returns The target row index.
*/
function calculateRowTargetIndex(
dragState: DragState,
mouseY: number,
state: EditorState
): number {
const rows = getRowsInTable(state);
if (rows.length === 0) {
return dragState.fromIndex;
}
const table = dragState.tableElement.querySelector("table");
if (!table) {
return dragState.fromIndex;
}
const tableRows = table.querySelectorAll("tr");
let targetIndex = dragState.fromIndex;
tableRows.forEach((row, index) => {
const rect = row.getBoundingClientRect();
const midpoint = rect.top + rect.height / 2;
if (mouseY < midpoint && index <= dragState.fromIndex) {
targetIndex = index;
} else if (mouseY >= midpoint && index >= dragState.fromIndex) {
targetIndex = index;
}
});
return Math.max(0, Math.min(targetIndex, rows.length - 1));
}
/**
* Calculates the target column index based on mouse X position.
*
* @param dragState Current drag state.
* @param mouseX Current mouse X position.
* @param state Editor state.
* @returns The target column index.
*/
function calculateColumnTargetIndex(
dragState: DragState,
mouseX: number,
state: EditorState
): number {
const cols = getCellsInRow(0)(state);
if (cols.length === 0) {
return dragState.fromIndex;
}
const table = dragState.tableElement.querySelector("table");
if (!table) {
return dragState.fromIndex;
}
const headerRow = table.querySelector("tr");
if (!headerRow) {
return dragState.fromIndex;
}
const cells = headerRow.querySelectorAll("th, td");
let targetIndex = dragState.fromIndex;
cells.forEach((cell, index) => {
const rect = cell.getBoundingClientRect();
const midpoint = rect.left + rect.width / 2;
if (mouseX < midpoint && index <= dragState.fromIndex) {
targetIndex = index;
} else if (mouseX >= midpoint && index >= dragState.fromIndex) {
targetIndex = index;
}
});
return Math.max(0, Math.min(targetIndex, cols.length - 1));
}
/**
* Positions the drop indicator based on the current drag state.
*
* @param indicator Drop indicator element.
* @param dragState Current drag state.
*/
function positionDropIndicator(
indicator: HTMLElement,
dragState: DragState
): void {
const table = dragState.tableElement.querySelector("table");
if (!table) {
return;
}
const tableRect = dragState.tableElement.getBoundingClientRect();
if (dragState.type === "row") {
const tableRows = table.querySelectorAll("tr");
const targetRow = tableRows[dragState.toIndex];
if (targetRow) {
const rowRect = targetRow.getBoundingClientRect();
const isMovingDown = dragState.toIndex > dragState.fromIndex;
indicator.style.left = `${rowRect.left - tableRect.left}px`;
indicator.style.width = `${rowRect.width}px`;
indicator.style.height = "2px";
indicator.style.top = isMovingDown
? `${rowRect.bottom - tableRect.top}px`
: `${rowRect.top - tableRect.top}px`;
}
} else {
const headerRow = table.querySelector("tr");
if (!headerRow) {
return;
}
const cells = headerRow.querySelectorAll("th, td");
const targetCell = cells[dragState.toIndex];
if (targetCell) {
const cellRect = targetCell.getBoundingClientRect();
const isMovingRight = dragState.toIndex > dragState.fromIndex;
indicator.style.top = `${table.getBoundingClientRect().top - tableRect.top}px`;
indicator.style.height = `${table.getBoundingClientRect().height}px`;
indicator.style.width = "2px";
indicator.style.left = isMovingRight
? `${cellRect.right - tableRect.left}px`
: `${cellRect.left - tableRect.left}px`;
}
}
}
/**
* A ProseMirror plugin that enables drag and drop for table rows and columns
* using the grip handles.
*/
export class TableDragDropPlugin extends Plugin<DragState | null> {
private dropIndicator: HTMLElement | null = null;
private dragState: DragState | null = null;
private view: EditorView | null = null;
constructor() {
super({
key: pluginKey,
view: (view: EditorView) => {
this.view = view;
return {
destroy: () => {
this.cleanup();
this.view = null;
},
};
},
props: {
handleDOMEvents: {
mousedown: (view: EditorView, event: MouseEvent) =>
this.handleMouseDown(view, event),
},
},
});
}
private handleMouseDown(view: EditorView, event: MouseEvent): boolean {
if (!(event.target instanceof HTMLElement)) {
return false;
}
// Check if we're clicking on a row grip
const rowGrip = event.target.closest(`.${EditorStyleHelper.tableGripRow}`);
if (rowGrip instanceof HTMLElement) {
return this.startDrag(view, event, rowGrip, "row");
}
// Check if we're clicking on a column grip
const colGrip = event.target.closest(
`.${EditorStyleHelper.tableGripColumn}`
);
if (colGrip instanceof HTMLElement) {
return this.startDrag(view, event, colGrip, "column");
}
return false;
}
private startDrag(
view: EditorView,
event: MouseEvent,
gripElement: HTMLElement,
type: "row" | "column"
): boolean {
const tableElement = gripElement.closest(`.${EditorStyleHelper.table}`);
if (!(tableElement instanceof HTMLElement)) {
return false;
}
const indexStr = gripElement.dataset.index;
if (indexStr === undefined) {
return false;
}
const fromIndex = parseInt(indexStr, 10);
if (isNaN(fromIndex)) {
return false;
}
// Initialize drag state
this.dragState = {
type,
fromIndex,
toIndex: fromIndex,
gripElement,
tableElement,
};
// Add dragging class
gripElement.classList.add(EditorStyleHelper.tableDragging);
document.body.style.cursor = "grabbing";
// Create and position drop indicator
this.dropIndicator = createDropIndicator();
this.dropIndicator.dataset.type = type;
tableElement.appendChild(this.dropIndicator);
positionDropIndicator(this.dropIndicator, this.dragState);
// Bind event listeners
const handleMouseMove = (e: MouseEvent) => {
this.handleMouseMove(view, e);
};
const handleMouseUp = (e: MouseEvent) => {
document.removeEventListener("mousemove", handleMouseMove);
document.removeEventListener("mouseup", handleMouseUp);
this.handleMouseUp(view, e);
};
document.addEventListener("mousemove", handleMouseMove);
document.addEventListener("mouseup", handleMouseUp);
// Prevent default to avoid text selection during drag
event.preventDefault();
return false;
}
private handleMouseMove(view: EditorView, event: MouseEvent): void {
if (!this.dragState || !this.dropIndicator) {
return;
}
const targetIndex = calculateTargetIndex(
this.dragState,
event.clientX,
event.clientY,
view.state
);
if (targetIndex !== this.dragState.toIndex) {
this.dragState.toIndex = targetIndex;
positionDropIndicator(this.dropIndicator, this.dragState);
}
// Show/hide indicator based on whether it's a valid drop target
if (targetIndex !== this.dragState.fromIndex) {
this.dropIndicator.classList.add("active");
} else {
this.dropIndicator.classList.remove("active");
}
}
private handleMouseUp(view: EditorView, _event: MouseEvent): void {
if (!this.dragState) {
this.cleanup();
return;
}
const { type, fromIndex, toIndex } = this.dragState;
// Only perform move if indices are different
if (fromIndex !== toIndex) {
// Execute the appropriate move command
if (type === "row") {
this.executeMoveRow(view, fromIndex, toIndex);
} else {
this.executeMoveColumn(view, fromIndex, toIndex);
}
}
this.cleanup();
}
private executeMoveRow(
view: EditorView,
fromIndex: number,
toIndex: number
): void {
// Use the moveTableRow command from prosemirror-tables
const { state, dispatch } = view;
moveTableRow({ from: fromIndex, to: toIndex })(state, dispatch);
}
private executeMoveColumn(
view: EditorView,
fromIndex: number,
toIndex: number
): void {
// Use the moveTableColumn command from prosemirror-tables
const { state, dispatch } = view;
moveTableColumn({ from: fromIndex, to: toIndex })(state, dispatch);
}
private cleanup(): void {
// Remove dragging class
if (this.dragState?.gripElement) {
this.dragState.gripElement.classList.remove("table-dragging");
}
// Remove drop indicator
if (this.dropIndicator) {
this.dropIndicator.remove();
this.dropIndicator = null;
}
// Reset cursor
document.body.style.cursor = "";
// Clear drag state
this.dragState = null;
}
}
-95
View File
@@ -1,95 +0,0 @@
import type { Token } from "markdown-it";
import type MarkdownIt from "markdown-it";
import type { EmbedDescriptor } from "../embeds";
function isParagraph(token: Token) {
return token?.type === "paragraph_open";
}
function isLinkOpen(token: Token) {
return token.type === "link_open";
}
function isLinkClose(token: Token) {
return token.type === "link_close";
}
export default function linksToEmbeds(embeds: EmbedDescriptor[]) {
function isEmbed(token: Token, link: Token) {
const href = link.attrs ? link.attrs[0][1] : "";
const simpleLink = href === token.content;
if (!simpleLink) {
return false;
}
if (!embeds) {
return false;
}
for (const embed of embeds) {
if (!embed.matchOnInput) {
continue;
}
const matches = embed.matcher(href);
if (matches) {
return {
...embed,
matches,
};
}
}
return false;
}
return function markdownEmbeds(md: MarkdownIt) {
md.core.ruler.after("inline", "embeds", (state) => {
const tokens = state.tokens;
let insideLink;
for (let i = 0; i < tokens.length - 1; i++) {
// once we find a paragraph, look through it's children for links
if (isParagraph(tokens[i - 1])) {
const tokenChildren = tokens[i].children || [];
for (let j = 0; j < tokenChildren.length - 1; j++) {
const current = tokenChildren[j];
if (!current) {
continue;
}
if (isLinkOpen(current)) {
insideLink = current;
continue;
}
if (isLinkClose(current)) {
insideLink = null;
continue;
}
// of hey, we found a link lets check to see if it should be
// converted to an embed
if (insideLink) {
const result = isEmbed(current, insideLink);
if (result) {
const { content } = current;
// convert to embed token
const token = new state.Token("embed", "iframe", 0);
token.attrSet("href", content);
// delete the inline link this makes the assumption that the
// embed is the only thing in the para.
tokens.splice(i - 1, 3, token);
break;
}
}
}
}
}
return false;
});
};
}
-67
View File
@@ -4842,20 +4842,6 @@ __metadata:
languageName: node
linkType: hard
"@octokit/openapi-types@npm:^25.1.0":
version: 25.1.0
resolution: "@octokit/openapi-types@npm:25.1.0"
checksum: 10c0/b5b1293b11c6ec7112c7a2713f8507c2696d5db8902ce893b594080ab0329f5a6fcda1b5ac6fe6eed9425e897f4d03326c1bdf5c337e35d324e7b925e52a2661
languageName: node
linkType: hard
"@octokit/openapi-webhooks-types@npm:11.0.0":
version: 11.0.0
resolution: "@octokit/openapi-webhooks-types@npm:11.0.0"
checksum: 10c0/cea59ba6b976a242fa4e6bedfab7e6fc3437381557d2c1876ca3aea5f6d4231559a378f9bc35e09593cb2d466afb4a2415be66b960f3e0a38b65b8b9f22ff90e
languageName: node
linkType: hard
"@octokit/plugin-paginate-graphql@npm:^4.0.0":
version: 4.0.1
resolution: "@octokit/plugin-paginate-graphql@npm:4.0.1"
@@ -4934,15 +4920,6 @@ __metadata:
languageName: node
linkType: hard
"@octokit/request-error@npm:^6.1.7":
version: 6.1.8
resolution: "@octokit/request-error@npm:6.1.8"
dependencies:
"@octokit/types": "npm:^14.0.0"
checksum: 10c0/02aa5bfebb5b1b9e152558b4a6f4f7dcb149b41538778ffe0fce3395fd0da5c0862311a78e94723435667581b2a58a7cefa458cf7aa19ae2948ae419276f7ee1
languageName: node
linkType: hard
"@octokit/request@npm:^8.3.1, @octokit/request@npm:^8.4.1":
version: 8.4.1
resolution: "@octokit/request@npm:8.4.1"
@@ -4973,15 +4950,6 @@ __metadata:
languageName: node
linkType: hard
"@octokit/types@npm:^14.0.0":
version: 14.1.0
resolution: "@octokit/types@npm:14.1.0"
dependencies:
"@octokit/openapi-types": "npm:^25.1.0"
checksum: 10c0/4640a6c0a95386be4d015b96c3a906756ea657f7df3c6e706d19fea6bf3ac44fd2991c8c817afe1e670ff9042b85b0e06f7fd373f6bbd47da64208701bb46d5b
languageName: node
linkType: hard
"@octokit/webhooks-methods@npm:^4.1.0":
version: 4.1.0
resolution: "@octokit/webhooks-methods@npm:4.1.0"
@@ -4989,13 +4957,6 @@ __metadata:
languageName: node
linkType: hard
"@octokit/webhooks-methods@npm:^5.1.1":
version: 5.1.1
resolution: "@octokit/webhooks-methods@npm:5.1.1"
checksum: 10c0/837aa49dbc7f8bc01448f4eaea32cfb0c1cbfa0b4ac570f7bcda385c71f43e4be05e91a3fb63708448410b27e246570fde42056b6b87d755154d84eff5a6500c
languageName: node
linkType: hard
"@octokit/webhooks-types@npm:7.6.1":
version: 7.6.1
resolution: "@octokit/webhooks-types@npm:7.6.1"
@@ -5015,17 +4976,6 @@ __metadata:
languageName: node
linkType: hard
"@octokit/webhooks@npm:^13.9.1":
version: 13.9.1
resolution: "@octokit/webhooks@npm:13.9.1"
dependencies:
"@octokit/openapi-webhooks-types": "npm:11.0.0"
"@octokit/request-error": "npm:^6.1.7"
"@octokit/webhooks-methods": "npm:^5.1.1"
checksum: 10c0/feb4a595d5f160908f97be9b68c9c579b5cdf7abc28407998e652759b15f9082b026caa6b41bd4f56132e3c99f0a9e5ebfe4319177818d14bd65ec49cd2b93f3
languageName: node
linkType: hard
"@one-ini/wasm@npm:0.1.1":
version: 0.1.1
resolution: "@one-ini/wasm@npm:0.1.1"
@@ -7641,13 +7591,6 @@ __metadata:
languageName: node
linkType: hard
"@types/body-scroll-lock@npm:^3.1.2":
version: 3.1.2
resolution: "@types/body-scroll-lock@npm:3.1.2"
checksum: 10c0/e766e44ef16e2b9a50488944eb8310247df7a8acfbbc4ed6d9f19ba83987404080aa02eae0256a57b5dd29bf5b9d39f6fa357abcabc3fbc47b8772dc681a1fac
languageName: node
linkType: hard
"@types/btoa-lite@npm:^1.0.0":
version: 1.0.2
resolution: "@types/btoa-lite@npm:1.0.2"
@@ -9952,13 +9895,6 @@ __metadata:
languageName: node
linkType: hard
"body-scroll-lock@npm:^4.0.0-beta.0":
version: 4.0.0-beta.0
resolution: "body-scroll-lock@npm:4.0.0-beta.0"
checksum: 10c0/32a9553b83424e69f3784d7bbcef2949c43159ea13b5084c96dc08b1e2585e4eeb1e915f14e37a4ac44110339dfa6fa2ddde4d3d812be88ecbea060aa724a791
languageName: node
linkType: hard
"boolbase@npm:^1.0.0":
version: 1.0.0
resolution: "boolbase@npm:1.0.0"
@@ -17633,7 +17569,6 @@ __metadata:
"@node-oauth/oauth2-server": "npm:^5.2.0"
"@notionhq/client": "npm:^2.3.0"
"@octokit/auth-app": "npm:^6.1.4"
"@octokit/webhooks": "npm:^13.9.1"
"@outlinewiki/koa-passport": "npm:^4.2.1"
"@outlinewiki/passport-azure-ad-oauth2": "npm:^0.1.0"
"@radix-ui/react-collapsible": "npm:^1.1.12"
@@ -17656,7 +17591,6 @@ __metadata:
"@tanstack/react-table": "npm:^8.21.3"
"@tanstack/react-virtual": "npm:^3.13.12"
"@types/addressparser": "npm:^1.0.3"
"@types/body-scroll-lock": "npm:^3.1.2"
"@types/cookie": "npm:0.6.0"
"@types/crypto-js": "npm:^4.2.2"
"@types/diff": "npm:^5.0.9"
@@ -17732,7 +17666,6 @@ __metadata:
babel-plugin-transform-inline-environment-variables: "npm:^0.4.4"
babel-plugin-transform-typescript-metadata: "npm:^0.4.0"
babel-plugin-tsconfig-paths-module-resolver: "npm:^1.0.4"
body-scroll-lock: "npm:^4.0.0-beta.0"
browserslist-to-esbuild: "npm:^1.2.0"
bull: "npm:^4.16.5"
class-validator: "npm:^0.14.3"