diff --git a/apps/web/package-lock.json b/apps/web/package-lock.json index 37e7980c0..852ed1feb 100644 --- a/apps/web/package-lock.json +++ b/apps/web/package-lock.json @@ -296,7 +296,6 @@ "prism-themes": "^1.9.0", "prosemirror-codemark": "^0.4.1", "prosemirror-commands": "^1.3.1", - "prosemirror-utils": "github:atlassian/prosemirror-utils", "prosemirror-view": "1.29.0", "re-resizable": "^6.9.9", "react-colorful": "^5.5.1", diff --git a/packages/editor/package-lock.json b/packages/editor/package-lock.json index e725a0946..ab87034a1 100644 --- a/packages/editor/package-lock.json +++ b/packages/editor/package-lock.json @@ -41,7 +41,6 @@ "prism-themes": "^1.9.0", "prosemirror-codemark": "^0.4.1", "prosemirror-commands": "^1.3.1", - "prosemirror-utils": "github:atlassian/prosemirror-utils", "prosemirror-view": "1.29.0", "re-resizable": "^6.9.9", "react-colorful": "^5.5.1", @@ -2237,15 +2236,6 @@ "prosemirror-model": "^1.0.0" } }, - "node_modules/prosemirror-utils": { - "version": "1.0.0-0", - "resolved": "git+ssh://git@github.com/atlassian/prosemirror-utils.git#1b97ff08f1bbaea781f205744588a3dfd228b0d1", - "license": "Apache-2.0", - "peerDependencies": { - "prosemirror-model": "^1.0.0", - "prosemirror-state": "^1.0.1" - } - }, "node_modules/prosemirror-view": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.29.0.tgz", @@ -4454,10 +4444,6 @@ "prosemirror-model": "^1.0.0" } }, - "prosemirror-utils": { - "version": "git+ssh://git@github.com/atlassian/prosemirror-utils.git#1b97ff08f1bbaea781f205744588a3dfd228b0d1", - "from": "prosemirror-utils@github:atlassian/prosemirror-utils" - }, "prosemirror-view": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.29.0.tgz", diff --git a/packages/editor/package.json b/packages/editor/package.json index 1f2e53e3d..341ddd801 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -3,10 +3,6 @@ "version": "1.3.1", "main": "dist/index.js", "license": "GPL-3.0-or-later", - "repository": { - "type": "git", - "url": "git://github.com/streetwriters/notesnook-editor.git" - }, "dependencies": { "@_ueberdosis/prosemirror-tables": "^1.1.3", "@emotion/react": "^11.10.0", @@ -41,7 +37,6 @@ "prism-themes": "^1.9.0", "prosemirror-codemark": "^0.4.1", "prosemirror-commands": "^1.3.1", - "prosemirror-utils": "github:atlassian/prosemirror-utils", "prosemirror-view": "1.29.0", "re-resizable": "^6.9.9", "react-colorful": "^5.5.1", @@ -86,5 +81,10 @@ "publishConfig": { "registry": "https://npm.pkg.github.com", "access": "restricted" + }, + "repository": { + "type": "git", + "url": "git://github.com/streetwriters/notesnook.git", + "directory": "packages/editor" } } diff --git a/packages/editor/src/extensions/key-map/key-map.ts b/packages/editor/src/extensions/key-map/key-map.ts index 73762b581..72dfd9411 100644 --- a/packages/editor/src/extensions/key-map/key-map.ts +++ b/packages/editor/src/extensions/key-map/key-map.ts @@ -19,7 +19,7 @@ along with this program. If not, see . import { Extension } from "@tiptap/core"; import { isInTable } from "@_ueberdosis/prosemirror-tables"; -import { isListActive } from "../../toolbar/utils/prosemirror"; +import { isListActive } from "../../utils/prosemirror"; export const KeyMap = Extension.create({ name: "key-map", diff --git a/packages/editor/src/extensions/list-item/commands.ts b/packages/editor/src/extensions/list-item/commands.ts index 87b8ba690..67896f088 100644 --- a/packages/editor/src/extensions/list-item/commands.ts +++ b/packages/editor/src/extensions/list-item/commands.ts @@ -19,7 +19,6 @@ along with this program. If not, see . import { EditorState } from "prosemirror-state"; import { NodeType } from "prosemirror-model"; -import { findParentNodeOfType, hasParentNodeOfType } from "prosemirror-utils"; import { Editor } from "@tiptap/core"; // WORKAROUND: if we're at the start of a list item, we need to either diff --git a/packages/editor/src/extensions/outline-list-item/outline-list-item.ts b/packages/editor/src/extensions/outline-list-item/outline-list-item.ts index 46451ebfb..0f03cd48a 100644 --- a/packages/editor/src/extensions/outline-list-item/outline-list-item.ts +++ b/packages/editor/src/extensions/outline-list-item/outline-list-item.ts @@ -19,7 +19,7 @@ along with this program. If not, see . import { Node, mergeAttributes, findChildren, Editor } from "@tiptap/core"; import { NodeType } from "prosemirror-model"; -import { findParentNodeOfTypeClosestToPos } from "prosemirror-utils"; +import { findParentNodeOfTypeClosestToPos } from "../../utils/prosemirror"; import { onArrowUpPressed, onBackspacePressed } from "../list-item/commands"; import { OutlineList } from "../outline-list/outline-list"; import { createNodeView } from "../react"; diff --git a/packages/editor/src/extensions/table/component.tsx b/packages/editor/src/extensions/table/component.tsx index 48459b0e7..ac63b155e 100644 --- a/packages/editor/src/extensions/table/component.tsx +++ b/packages/editor/src/extensions/table/component.tsx @@ -35,7 +35,7 @@ import { } from "../../toolbar/tools/table"; import { getToolDefinition } from "../../toolbar/tool-definitions"; import { getPosition } from "../../utils/position"; -import { findSelectedDOMNode } from "../../toolbar/utils/prosemirror"; +import { findSelectedDOMNode } from "../../utils/prosemirror"; import { DesktopOnly } from "../../components/responsive"; export function TableComponent(props: SelectionBasedReactNodeViewProps) { diff --git a/packages/editor/src/extensions/task-list/component.tsx b/packages/editor/src/extensions/task-list/component.tsx index 2acd95c74..4fc721c07 100644 --- a/packages/editor/src/extensions/task-list/component.tsx +++ b/packages/editor/src/extensions/task-list/component.tsx @@ -21,10 +21,9 @@ import { Box, Flex, Input, Text } from "@theme-ui/components"; import { findChildren, getNodeType } from "@tiptap/core"; import TaskItem from "@tiptap/extension-task-item"; import { Node } from "prosemirror-model"; -import { findParentNodeOfTypeClosestToPos } from "prosemirror-utils"; import { useCallback, useEffect, useMemo, useState } from "react"; import { ToolButton } from "../../toolbar/components/tool-button"; -import { useIsMobile } from "../../toolbar/stores/toolbar-store"; +import { findParentNodeOfTypeClosestToPos } from "../../utils/prosemirror"; import { ReactNodeViewProps } from "../react"; import { TaskItemNode } from "../task-item"; import { TaskListAttributes } from "./task-list"; @@ -32,7 +31,7 @@ import { TaskListAttributes } from "./task-list"; export function TaskListComponent( props: ReactNodeViewProps ) { - const isMobile = useIsMobile(); + // const isMobile = useIsMobile(); const { editor, getPos, node, updateAttributes, forwardRef } = props; const taskItemType = getNodeType(TaskItemNode.name, editor.schema); const { title } = node.attrs; diff --git a/packages/editor/src/extensions/task-list/task-list.ts b/packages/editor/src/extensions/task-list/task-list.ts index 59cad1060..7271b69a2 100644 --- a/packages/editor/src/extensions/task-list/task-list.ts +++ b/packages/editor/src/extensions/task-list/task-list.ts @@ -24,7 +24,7 @@ import { TaskListComponent } from "./component"; import { Plugin, PluginKey, NodeSelection } from "prosemirror-state"; import TaskItem from "@tiptap/extension-task-item"; import { dropPoint } from "prosemirror-transform"; -import { findChildrenByType } from "prosemirror-utils"; +import { findChildrenByType } from "../../utils/prosemirror"; export type TaskListAttributes = { title: string; diff --git a/packages/editor/src/toolbar/components/toolbar-group.tsx b/packages/editor/src/toolbar/components/toolbar-group.tsx index 705543dc1..0b156ed52 100644 --- a/packages/editor/src/toolbar/components/toolbar-group.tsx +++ b/packages/editor/src/toolbar/components/toolbar-group.tsx @@ -23,7 +23,7 @@ import { Flex, FlexProps } from "@theme-ui/components"; import { Editor } from "../../types"; import { MoreTools } from "./more-tools"; import { getToolDefinition } from "../tool-definitions"; -import { NodeWithOffset } from "../utils/prosemirror"; +import { NodeWithOffset } from "../../utils/prosemirror"; export type ToolbarGroupProps = FlexProps & { tools: ToolbarGroupDefinition; diff --git a/packages/editor/src/toolbar/floating-menus/hover-popup/index.tsx b/packages/editor/src/toolbar/floating-menus/hover-popup/index.tsx index b29ef9d6e..92a486df7 100644 --- a/packages/editor/src/toolbar/floating-menus/hover-popup/index.tsx +++ b/packages/editor/src/toolbar/floating-menus/hover-popup/index.tsx @@ -20,7 +20,7 @@ along with this program. If not, see . import { useEffect, useRef } from "react"; import { showPopup } from "../../../components/popup-presenter"; import { Editor } from "../../../types"; -import { NodeWithOffset } from "../../utils/prosemirror"; +import { NodeWithOffset } from "../../../utils/prosemirror"; import { FloatingMenuProps } from "../types"; import { LinkHoverPopupHandler } from "./link"; diff --git a/packages/editor/src/toolbar/tools/attachment.tsx b/packages/editor/src/toolbar/tools/attachment.tsx index a480645d7..89d0d17ec 100644 --- a/packages/editor/src/toolbar/tools/attachment.tsx +++ b/packages/editor/src/toolbar/tools/attachment.tsx @@ -21,7 +21,7 @@ import { ToolProps } from "../types"; import { ToolButton } from "../components/tool-button"; import { MoreTools } from "../components/more-tools"; import { useToolbarLocation } from "../stores/toolbar-store"; -import { findSelectedNode } from "../utils/prosemirror"; +import { findSelectedNode } from "../../utils/prosemirror"; import { Attachment } from "../../extensions/attachment"; export function AttachmentSettings(props: ToolProps) { diff --git a/packages/editor/src/toolbar/tools/embed.tsx b/packages/editor/src/toolbar/tools/embed.tsx index 162f9c3b3..ea1ab2e54 100644 --- a/packages/editor/src/toolbar/tools/embed.tsx +++ b/packages/editor/src/toolbar/tools/embed.tsx @@ -23,7 +23,7 @@ import { useMemo, useRef, useState } from "react"; import { ResponsivePresenter } from "../../components/responsive"; import { MoreTools } from "../components/more-tools"; import { useToolbarLocation } from "../stores/toolbar-store"; -import { findSelectedNode } from "../utils/prosemirror"; +import { findSelectedNode } from "../../utils/prosemirror"; import { Embed } from "../../extensions/embed"; import { EmbedPopup } from "../popups/embed-popup"; diff --git a/packages/editor/src/toolbar/tools/image.tsx b/packages/editor/src/toolbar/tools/image.tsx index 0c95dff83..c5582bc51 100644 --- a/packages/editor/src/toolbar/tools/image.tsx +++ b/packages/editor/src/toolbar/tools/image.tsx @@ -28,7 +28,7 @@ import { ImageAlignmentOptions, ImageSizeOptions } from "../../extensions/image"; -import { findSelectedNode } from "../utils/prosemirror"; +import { findSelectedNode } from "../../utils/prosemirror"; export function ImageSettings(props: ToolProps) { const { editor } = props; diff --git a/packages/editor/src/toolbar/tools/link.tsx b/packages/editor/src/toolbar/tools/link.tsx index 816a43ee6..25dac30d6 100644 --- a/packages/editor/src/toolbar/tools/link.tsx +++ b/packages/editor/src/toolbar/tools/link.tsx @@ -25,7 +25,7 @@ import { LinkPopup } from "../popups/link-popup"; import { useIsMobile, useToolbarLocation } from "../stores/toolbar-store"; import { MoreTools } from "../components/more-tools"; import { useRefValue } from "../../hooks/use-ref-value"; -import { findMark, selectionToOffset } from "../utils/prosemirror"; +import { findMark, selectionToOffset } from "../../utils/prosemirror"; import { TextSelection } from "prosemirror-state"; import { Flex, Link } from "@theme-ui/components"; import { ImageNode } from "../../extensions/image"; diff --git a/packages/editor/src/toolbar/tools/lists.tsx b/packages/editor/src/toolbar/tools/lists.tsx index c1a75f9a6..9ea8c56db 100644 --- a/packages/editor/src/toolbar/tools/lists.tsx +++ b/packages/editor/src/toolbar/tools/lists.tsx @@ -27,7 +27,7 @@ import { getToolbarElement } from "../utils/dom"; import { PopupWrapper } from "../../components/popup-presenter"; import React from "react"; import { ToolButton } from "../components/tool-button"; -import { findListItemType, isListActive } from "../utils/prosemirror"; +import { findListItemType, isListActive } from "../../utils/prosemirror"; type ListSubType = { items: string[]; diff --git a/packages/editor/src/toolbar/tools/web-clip.tsx b/packages/editor/src/toolbar/tools/web-clip.tsx index 4ed315b2c..f065b0ed0 100644 --- a/packages/editor/src/toolbar/tools/web-clip.tsx +++ b/packages/editor/src/toolbar/tools/web-clip.tsx @@ -21,7 +21,7 @@ import { ToolProps } from "../types"; import { ToolButton } from "../components/tool-button"; import { MoreTools } from "../components/more-tools"; import { useToolbarLocation } from "../stores/toolbar-store"; -import { findSelectedNode, selectionToOffset } from "../utils/prosemirror"; +import { findSelectedNode, selectionToOffset } from "../../utils/prosemirror"; export function WebClipSettings(props: ToolProps) { const { editor } = props; diff --git a/packages/editor/src/toolbar/types.ts b/packages/editor/src/toolbar/types.ts index f1cc528c2..fec60f5df 100644 --- a/packages/editor/src/toolbar/types.ts +++ b/packages/editor/src/toolbar/types.ts @@ -20,7 +20,7 @@ along with this program. If not, see . import { Editor } from "../types"; import { IconNames } from "./icons"; import { ToolId } from "./tools"; -import { NodeWithOffset } from "./utils/prosemirror"; +import { NodeWithOffset } from "../utils/prosemirror"; export type ToolButtonVariant = "small" | "normal"; export type ToolProps = ToolDefinition & { diff --git a/packages/editor/src/toolbar/utils/prosemirror.ts b/packages/editor/src/utils/prosemirror.ts similarity index 59% rename from packages/editor/src/toolbar/utils/prosemirror.ts rename to packages/editor/src/utils/prosemirror.ts index cd37f9cd3..e803edbc7 100644 --- a/packages/editor/src/toolbar/utils/prosemirror.ts +++ b/packages/editor/src/utils/prosemirror.ts @@ -17,9 +17,20 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -import { Editor, findParentNode } from "@tiptap/core"; -import { Node as ProsemirrorNode, Mark } from "prosemirror-model"; -import { EditorState } from "prosemirror-state"; +import { + Editor, + findParentNode, + NodeWithPos, + Predicate, + findParentNodeClosestToPos +} from "@tiptap/core"; +import { + Node as ProsemirrorNode, + Mark, + NodeType, + ResolvedPos +} from "prosemirror-model"; +import { EditorState, Selection } from "prosemirror-state"; export type NodeWithOffset = { node?: ProsemirrorNode; @@ -102,3 +113,71 @@ export function isListActive(editor: Editor): boolean { return isTaskList || isOutlineList || isList; } + +export const findChildren = ( + node: ProsemirrorNode, + predicate: Predicate, + descend: boolean +) => { + if (!node) { + throw new Error('Invalid "node" parameter'); + } else if (!predicate) { + throw new Error('Invalid "predicate" parameter'); + } + return walkNode(node, descend).filter((child) => predicate(child.node)); +}; + +export function findChildrenByType( + node: ProsemirrorNode, + nodeType: NodeType, + descend = true +): NodeWithPos[] { + return findChildren(node, (child) => child.type === nodeType, descend); +} + +export const findParentNodeOfTypeClosestToPos = ( + $pos: ResolvedPos, + nodeType: NodeType +) => { + return findParentNodeClosestToPos($pos, (node) => + equalNodeType(nodeType, node) + ); +}; + +export function hasParentNode(predicate: Predicate) { + return function (selection: Selection) { + return !!findParentNode(predicate)(selection); + }; +} + +export function hasParentNodeOfType(nodeType: NodeType | NodeType[]) { + return hasParentNode((node) => equalNodeType(nodeType, node)); +} + +export function findParentNodeOfType(nodeType: NodeType | NodeType[]) { + return findParentNode((node) => equalNodeType(nodeType, node)); +} + +const walkNode = (node: ProsemirrorNode, descend = true) => { + if (!node) { + throw new Error('Invalid "node" parameter'); + } + const result: NodeWithPos[] = []; + node.descendants((child, pos) => { + result.push({ node: child, pos }); + if (!descend) { + return false; + } + }); + return result; +}; + +const equalNodeType = ( + nodeType: NodeType | NodeType[], + node: ProsemirrorNode +) => { + return ( + (Array.isArray(nodeType) && nodeType.indexOf(node.type) > -1) || + node.type === nodeType + ); +};