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
+ );
+};