From 565ccb399ab80e10820a4c3322b32af8bd8ee7f8 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Tue, 4 Feb 2025 20:29:12 -0800 Subject: [PATCH] Remove editor, use welshman editor again --- package-lock.json | 174 +++-------- package.json | 2 +- src/app/editor/MentionNodeView.ts | 12 +- src/app/editor/index.ts | 4 +- src/lib/editor/extensions/BreakOrSubmit.ts | 31 -- src/lib/editor/extensions/CodeInline.ts | 75 ----- src/lib/editor/extensions/Welshman.ts | 227 -------------- src/lib/editor/extensions/WordCount.ts | 19 -- src/lib/editor/extensions/index.ts | 4 - src/lib/editor/index.css | 105 ------- src/lib/editor/index.ts | 5 - src/lib/editor/nodeviews/Bolt11NodeView.ts | 18 -- src/lib/editor/nodeviews/EventNodeView.ts | 19 -- src/lib/editor/nodeviews/MediaNodeView.ts | 32 -- src/lib/editor/nodeviews/MentionNodeView.ts | 18 -- src/lib/editor/nodeviews/index.ts | 4 - src/lib/editor/plugins/TippySuggestion.ts | 310 -------------------- src/lib/editor/plugins/index.ts | 1 - 18 files changed, 44 insertions(+), 1016 deletions(-) delete mode 100644 src/lib/editor/extensions/BreakOrSubmit.ts delete mode 100644 src/lib/editor/extensions/CodeInline.ts delete mode 100644 src/lib/editor/extensions/Welshman.ts delete mode 100644 src/lib/editor/extensions/WordCount.ts delete mode 100644 src/lib/editor/extensions/index.ts delete mode 100644 src/lib/editor/index.css delete mode 100644 src/lib/editor/index.ts delete mode 100644 src/lib/editor/nodeviews/Bolt11NodeView.ts delete mode 100644 src/lib/editor/nodeviews/EventNodeView.ts delete mode 100644 src/lib/editor/nodeviews/MediaNodeView.ts delete mode 100644 src/lib/editor/nodeviews/MentionNodeView.ts delete mode 100644 src/lib/editor/nodeviews/index.ts delete mode 100644 src/lib/editor/plugins/TippySuggestion.ts delete mode 100644 src/lib/editor/plugins/index.ts diff --git a/package-lock.json b/package-lock.json index 6e459688..a9806d11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "@welshman/app": "~0.0.41", "@welshman/content": "~0.0.16", "@welshman/dvm": "~0.0.14", - "@welshman/editor": "~0.0.10", + "@welshman/editor": "~0.0.11-pre.4", "@welshman/feeds": "~0.0.30", "@welshman/lib": "~0.0.38", "@welshman/net": "~0.0.46", @@ -3103,7 +3103,6 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -3124,8 +3123,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.3.1", @@ -3924,7 +3922,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.11.5.tgz", "integrity": "sha512-jb0KTdUJaJY53JaN7ooY3XAxHQNoMYti/H6ANo707PsLXVeEqJ9o8+eBup1JU5CuwzrgnDc2dECt2WIGX9f8Jw==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3933,30 +3930,11 @@ "@tiptap/pm": "^2.7.0" } }, - "node_modules/@tiptap/extension-bubble-menu": { - "version": "2.11.5", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.11.5.tgz", - "integrity": "sha512-rx+rMd7EEdht5EHLWldpkzJ56SWYA9799b33ustePqhXd6linnokJCzBqY13AfZ9+xp3RsR6C0ZHI9GGea0tIA==", - "license": "MIT", - "peer": true, - "dependencies": { - "tippy.js": "^6.3.7" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/pm": "^2.7.0" - } - }, "node_modules/@tiptap/extension-code": { "version": "2.11.5", "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.11.5.tgz", "integrity": "sha512-xOvHevNIQIcCCVn9tpvXa1wBp0wHN/2umbAZGTVzS+AQtM7BTo0tz8IyzwxkcZJaImONcUVYLOLzt2AgW1LltA==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3970,7 +3948,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.11.5.tgz", "integrity": "sha512-ksxMMvqLDlC+ftcQLynqZMdlJT1iHYZorXsXw/n+wuRd7YElkRkd6YWUX/Pq/njFY6lDjKiqFLEXBJB8nrzzBA==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3985,7 +3962,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.11.5.tgz", "integrity": "sha512-7I4BRTpIux2a0O2qS3BDmyZ5LGp3pszKbix32CmeVh7lN9dV7W5reDqtJJ9FCZEEF+pZ6e1/DQA362dflwZw2g==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -3999,25 +3975,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.11.5.tgz", "integrity": "sha512-uIN7L3FU0904ec7FFFbndO7RQE/yiON4VzAMhNn587LFMyWO8US139HXIL4O8dpZeYwYL3d1FnDTflZl6CwLlg==", "license": "MIT", - "peer": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/pm": "^2.7.0" - } - }, - "node_modules/@tiptap/extension-floating-menu": { - "version": "2.11.5", - "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.11.5.tgz", - "integrity": "sha512-HsMI0hV5Lwzm530Z5tBeyNCBNG38eJ3qjfdV2OHlfSf3+KOEfn6a5AUdoNaZO02LF79/8+7BaYU2drafag9cxQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "tippy.js": "^6.3.7" - }, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -4032,7 +3989,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.11.5.tgz", "integrity": "sha512-kcWa+Xq9cb6lBdiICvLReuDtz/rLjFKHWpW3jTTF3FiP3wx4H8Rs6bzVtty7uOVTfwupxZRiKICAMEU6iT0xrQ==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -4047,7 +4003,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.11.5.tgz", "integrity": "sha512-q9doeN+Yg9F5QNTG8pZGYfNye3tmntOwch683v0CCVCI4ldKaLZ0jG3NbBTq+mosHYdgOH2rNbIORlRRsQ+iYQ==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -4061,7 +4016,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.11.5.tgz", "integrity": "sha512-b+wOS33Dz1azw6F1i9LFTEIJ/gUui0Jwz5ZvmVDpL2ZHBhq1Ui0/spTT+tuZOXq7Y/uCbKL8Liu4WoedIvhboQ==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -4108,7 +4062,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.11.5.tgz", "integrity": "sha512-YFBWeg7xu/sBnsDIF/+nh9Arf7R0h07VZMd0id5Ydd2Qe3c1uIZwXxeINVtH0SZozuPIQFAT8ICe9M0RxmE+TA==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -4122,7 +4075,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.11.5.tgz", "integrity": "sha512-Pr+0Ju/l2ZvXMd9VQxtaoSZbs0BBp1jbBDqwms88ctpyvQFRfLSfSkqudQcSHyw2ROOz2E31p/7I7fpI8Y0CLA==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -4137,7 +4089,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.11.5.tgz", "integrity": "sha512-Gq1WwyhFpCbEDrLPIHt5A8aLSlf8bfz4jm417c8F/JyU0J5dtYdmx0RAxjnLw1i7ZHE7LRyqqAoS0sl7JHDNSQ==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -4151,7 +4102,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.11.5.tgz", "integrity": "sha512-z9JFtqc5ZOsdQLd9vRnXfTCQ8v5ADAfRt9Nm7SqP6FUHII8E1hs38ACzf5xursmth/VonJYb5+73Pqxk1hGIPw==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-changeset": "^2.2.1", "prosemirror-collab": "^1.3.1", @@ -4182,7 +4132,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/suggestion/-/suggestion-2.11.5.tgz", "integrity": "sha512-uafwGgB5YuKX/xLRjnt2H5eA21I8HcNXpdbH4Du2gg3KM71RpUbkyjaV7KEMA/5qwCEo+sddlpuErj4wBycZ5Q==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -4422,15 +4371,13 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/markdown-it": { "version": "14.1.2", "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "license": "MIT", - "peer": true, "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" @@ -4440,8 +4387,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/minimist": { "version": "1.2.5", @@ -4847,29 +4793,29 @@ } }, "node_modules/@welshman/editor": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/@welshman/editor/-/editor-0.0.10.tgz", - "integrity": "sha512-685+KUYrGHzSgz2V6hRRltyp3LMhdHKvYBqkc9DyDNZoz3qqn4pUsOF+SMGSBnisiXBEZrKj2d52Jv46FT81iQ==", - "peerDependencies": { - "@tiptap/core": "^2.9.1", - "@tiptap/extension-code": "^2.9.1", - "@tiptap/extension-code-block": "^2.9.1", - "@tiptap/extension-document": "^2.9.1", - "@tiptap/extension-dropcursor": "^2.9.1", - "@tiptap/extension-gapcursor": "^2.9.1", - "@tiptap/extension-hard-break": "^2.9.1", - "@tiptap/extension-history": "^2.9.1", - "@tiptap/extension-paragraph": "^2.9.1", - "@tiptap/extension-placeholder": "^2.9.1", - "@tiptap/extension-text": "^2.9.1", - "@tiptap/pm": "^2.9.1", - "@tiptap/suggestion": "^2.9.1", - "@welshman/lib": "~0.0.36", - "@welshman/util": "~0.0.53", - "nostr-editor": "^0.0.4-pre.7", - "nostr-tools": "^2.8.1", - "svelte": "^4.0.0", - "svelte-tiptap": "^1.0.0" + "version": "0.0.11-pre.4", + "resolved": "https://registry.npmjs.org/@welshman/editor/-/editor-0.0.11-pre.4.tgz", + "integrity": "sha512-V2DETqs0OgBHAwvtj3bEXiKXXhtSwEKviSSH0j7I1v4abnoWAa7OyNPoQYeuJ9g3fC7CgvoFCcBTbNaeNcKtLw==", + "license": "MIT", + "dependencies": { + "@tiptap/core": "^2.11.5", + "@tiptap/extension-code": "^2.11.5", + "@tiptap/extension-code-block": "^2.11.5", + "@tiptap/extension-document": "^2.11.5", + "@tiptap/extension-dropcursor": "^2.11.5", + "@tiptap/extension-gapcursor": "^2.11.5", + "@tiptap/extension-hard-break": "^2.11.5", + "@tiptap/extension-history": "^2.11.5", + "@tiptap/extension-paragraph": "^2.11.5", + "@tiptap/extension-placeholder": "^2.11.5", + "@tiptap/extension-text": "^2.11.5", + "@tiptap/pm": "^2.11.5", + "@tiptap/suggestion": "^2.11.5", + "@welshman/lib": "^0.0.39", + "@welshman/util": "^0.0.60", + "nostr-editor": "^0.0.4-pre.12", + "nostr-tools": "^2.10.4", + "tippy.js": "^6.3.7" } }, "node_modules/@welshman/feeds": { @@ -6284,8 +6230,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.6", @@ -9402,7 +9347,6 @@ "resolved": "https://registry.npmjs.org/light-bolt11-decoder/-/light-bolt11-decoder-3.2.0.tgz", "integrity": "sha512-3QEofgiBOP4Ehs9BI+RkZdXZNtSys0nsJ6fyGeSiAGCBsMwHGUDS/JQlY/sTnWs91A2Nh0S9XXfA8Sy9g6QpuQ==", "license": "MIT", - "peer": true, "dependencies": { "@scure/base": "1.1.1" } @@ -9417,8 +9361,7 @@ "url": "https://paulmillr.com/funding/" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/lilconfig": { "version": "2.1.0", @@ -9442,7 +9385,6 @@ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "license": "MIT", - "peer": true, "dependencies": { "uc.micro": "^2.0.0" } @@ -9583,7 +9525,6 @@ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -9608,7 +9549,6 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "license": "BSD-2-Clause", - "peer": true, "engines": { "node": ">=0.12" }, @@ -9636,8 +9576,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/meow": { "version": "8.1.2", @@ -10217,7 +10156,6 @@ "resolved": "https://registry.npmjs.org/nostr-editor/-/nostr-editor-0.0.4-pre.12.tgz", "integrity": "sha512-vztmbEKxt2jnO1JEoprwVf3s4TN4D3B0fcsrhckOITR1KaDX88QhIG+qTee92xp+n96vYj4GQt0W06rSv3NXHA==", "license": "MIT", - "peer": true, "dependencies": { "light-bolt11-decoder": "^3.1.1" }, @@ -10449,8 +10387,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/own-keys": { "version": "1.0.1", @@ -11164,7 +11101,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz", "integrity": "sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-transform": "^1.0.0" } @@ -11174,7 +11110,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-state": "^1.0.0" } @@ -11184,7 +11119,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.6.2.tgz", "integrity": "sha512-0nDHH++qcf/BuPLYvmqZTUUsPJUCPBUXt0J1ErTcDIS369CTp773itzLGIgIXG4LJXOlwYCr44+Mh4ii6MP1QA==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -11196,7 +11130,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz", "integrity": "sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.1.0", @@ -11208,7 +11141,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz", "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-keymap": "^1.0.0", "prosemirror-model": "^1.0.0", @@ -11221,7 +11153,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz", "integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-state": "^1.2.2", "prosemirror-transform": "^1.0.0", @@ -11234,7 +11165,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz", "integrity": "sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.0.0" @@ -11245,7 +11175,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz", "integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-state": "^1.0.0", "w3c-keyname": "^2.2.0" @@ -11256,7 +11185,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.1.tgz", "integrity": "sha512-Sl+oMfMtAjWtlcZoj/5L/Q39MpEnVZ840Xo330WJWUvgyhNmLBLN7MsHn07s53nG/KImevWHSE6fEj4q/GihHw==", "license": "MIT", - "peer": true, "dependencies": { "@types/markdown-it": "^14.0.0", "markdown-it": "^14.0.0", @@ -11268,7 +11196,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz", "integrity": "sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==", "license": "MIT", - "peer": true, "dependencies": { "crelt": "^1.0.0", "prosemirror-commands": "^1.0.0", @@ -11281,7 +11208,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.24.1.tgz", "integrity": "sha512-YM053N+vTThzlWJ/AtPtF1j0ebO36nvbmDy4U7qA2XQB8JVaQp1FmB9Jhrps8s+z+uxhhVTny4m20ptUvhk0Mg==", "license": "MIT", - "peer": true, "dependencies": { "orderedmap": "^2.0.0" } @@ -11291,7 +11217,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.3.tgz", "integrity": "sha512-h+H0OQwZVqMon1PNn0AG9cTfx513zgIG2DY00eJ00Yvgb3UD+GQ/VlWW5rcaxacpCGT1Yx8nuhwXk4+QbXUfJA==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.19.0" } @@ -11301,7 +11226,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.0.tgz", "integrity": "sha512-gg1tAfH1sqpECdhIHOA/aLg2VH3ROKBWQ4m8Qp9mBKrOxQRW61zc+gMCI8nh22gnBzd1t2u1/NPLmO3nAa3ssg==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -11313,7 +11237,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-transform": "^1.0.0", @@ -11325,7 +11248,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.6.3.tgz", "integrity": "sha512-8B0X6PjAkXaHKntKndetNquxLIhWDDTybON1N4flKMY9Bq8/rm5k2ddW6X6LvFpqJBQeiKRp4yG3FqI/zOyQuA==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-keymap": "^1.2.2", "prosemirror-model": "^1.24.1", @@ -11339,7 +11261,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", "license": "MIT", - "peer": true, "dependencies": { "@remirror/core-constants": "3.0.0", "escape-string-regexp": "^4.0.0" @@ -11355,7 +11276,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.2.tgz", "integrity": "sha512-2iUq0wv2iRoJO/zj5mv8uDUriOHWzXRnOTVgCzSXnktS/2iQRa3UUQwVlkBlYZFtygw6Nh1+X4mGqoYBINn5KQ==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.21.0" } @@ -11365,7 +11285,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.37.2.tgz", "integrity": "sha512-ApcyrfV/cRcaL65on7TQcfWElwLyOgIjnIynfAuV+fIdlpbSvSWRwfuPaH7T5mo4AbO/FID29qOtjiDIKGWyog==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", @@ -11403,7 +11322,6 @@ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -12349,8 +12267,7 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/run-parallel": { "version": "1.2.0", @@ -13437,26 +13354,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/svelte-tiptap": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/svelte-tiptap/-/svelte-tiptap-1.1.3.tgz", - "integrity": "sha512-Wx4d57SLC5bgx8/hOmdt28CflW17DbiqQWgv4pUUT1Z3o5u9lInNsY8OMQWx24EYPEUyzJsjxj2OejSEoKafcg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "peer": true, - "peerDependencies": { - "@tiptap/core": "^2.0.3", - "@tiptap/extension-bubble-menu": "^2.0.3", - "@tiptap/extension-floating-menu": "^2.0.3", - "@tiptap/pm": "^2.0.3", - "svelte": "^4.0.1" - } - }, "node_modules/svgo": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", @@ -13937,7 +13834,6 @@ "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", "license": "MIT", - "peer": true, "dependencies": { "@popperjs/core": "^2.9.0" } @@ -14294,8 +14190,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/uglify-js": { "version": "3.19.3", @@ -14646,8 +14541,7 @@ "version": "2.2.8", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/webidl-conversions": { "version": "3.0.1", diff --git a/package.json b/package.json index a171e059..2105a726 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@welshman/app": "~0.0.41", "@welshman/content": "~0.0.16", "@welshman/dvm": "~0.0.14", - "@welshman/editor": "~0.0.10", + "@welshman/editor": "~0.0.11-pre.4", "@welshman/feeds": "~0.0.30", "@welshman/lib": "~0.0.38", "@welshman/net": "~0.0.46", diff --git a/src/app/editor/MentionNodeView.ts b/src/app/editor/MentionNodeView.ts index 24411fe5..a4a10bc5 100644 --- a/src/app/editor/MentionNodeView.ts +++ b/src/app/editor/MentionNodeView.ts @@ -1,14 +1,14 @@ -import type {NodeViewProps} from '@tiptap/core' +import type {NodeViewProps} from "@tiptap/core" import {deriveProfileDisplay} from "@welshman/app" export const MentionNodeView = ({node}: NodeViewProps) => { - const dom = document.createElement('span') + const dom = document.createElement("span") const display = deriveProfileDisplay(node.attrs.pubkey) - dom.classList.add('tiptap-object') + dom.classList.add("tiptap-object") const unsubDisplay = display.subscribe($display => { - dom.textContent = '@' + $display + dom.textContent = "@" + $display }) return { @@ -17,10 +17,10 @@ export const MentionNodeView = ({node}: NodeViewProps) => { unsubDisplay() }, selectNode() { - dom.classList.add('tiptap-active') + dom.classList.add("tiptap-active") }, deselectNode() { - dom.classList.remove('tiptap-active') + dom.classList.remove("tiptap-active") }, } } diff --git a/src/app/editor/index.ts b/src/app/editor/index.ts index 3fb35c36..1cb5f313 100644 --- a/src/app/editor/index.ts +++ b/src/app/editor/index.ts @@ -1,3 +1,5 @@ +import "@welshman/editor/index.css" + import {mount} from "svelte" import type {Writable} from "svelte/store" import {get} from "svelte/store" @@ -5,7 +7,7 @@ import {Editor} from "@tiptap/core" import {ctx} from "@welshman/lib" import type {StampedEvent} from "@welshman/util" import {signer, profileSearch} from "@welshman/app" -import {MentionSuggestion, WelshmanExtension} from "@lib/editor" +import {MentionSuggestion, WelshmanExtension} from "@welshman/editor" import {getSetting, userSettingValues} from "@app/state" import {MentionNodeView} from "./MentionNodeView" import ProfileSuggestion from "./ProfileSuggestion.svelte" diff --git a/src/lib/editor/extensions/BreakOrSubmit.ts b/src/lib/editor/extensions/BreakOrSubmit.ts deleted file mode 100644 index 775eca31..00000000 --- a/src/lib/editor/extensions/BreakOrSubmit.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {HardBreak, type HardBreakOptions} from "@tiptap/extension-hard-break" - -export interface BreakOrSubmitOptions extends HardBreakOptions { - /** Handler for when enter is pressed. */ - submit: () => void - - /** Whether to call `submit` on unmodified Enter */ - aggressive?: boolean -} - -export const BreakOrSubmit = HardBreak.extend({ - addKeyboardShortcuts() { - return { - "Shift-Enter": () => this.editor.commands.setHardBreak(), - "Mod-Enter": () => { - this.options.submit() - - return true - }, - Enter: () => { - if (this.options.aggressive) { - this.options.submit() - - return true - } - - return false - }, - } - }, -}) diff --git a/src/lib/editor/extensions/CodeInline.ts b/src/lib/editor/extensions/CodeInline.ts deleted file mode 100644 index c26061de..00000000 --- a/src/lib/editor/extensions/CodeInline.ts +++ /dev/null @@ -1,75 +0,0 @@ -import {InputRule, mergeAttributes, Node, PasteRule} from "@tiptap/core" -import type {CodeOptions} from "@tiptap/extension-code" - -const inputRegex = /(?:^|\s)(`(?!\s+`)((?:[^`]+))`(?!\s+`))$/ - -const pasteRegex = /(?:^|\s)(`(?!\s+`)((?:[^`]+))`(?!\s+`))/g - -export type CodeInlineOptions = object - -export const CodeInline = Node.create({ - name: "codeInline", - content: "text*", - marks: "", - group: "inline", - inline: true, - code: true, - defining: true, - addOptions() { - return { - HTMLAttributes: {}, - } - }, - parseHTML() { - return [{tag: "code"}] - }, - renderHTML({HTMLAttributes}) { - return ["code", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0] - }, - addKeyboardShortcuts() { - return { - // remove code block when at start of document or code block is empty - Backspace: () => { - const {empty, $anchor, $from} = this.editor.state.selection - - const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2 - - if (!empty || $anchor.parent.type.name !== this.name) { - return false - } - - if (isAtEnd) { - const {tr} = this.editor.state - tr.delete($from.start(), $from.end() + 1) - this.editor.view.dispatch(tr) - } - - return false - }, - } - }, - addInputRules() { - return [ - new InputRule({ - find: inputRegex, - handler: ({state, range, match}) => { - const textNode = state.schema.text(match[2]) - const codeNode = this.type.create(null, textNode) - state.tr.replaceWith(range.from, range.to, codeNode).insertText(" ") - }, - }), - ] - }, - addPasteRules() { - return [ - new PasteRule({ - find: pasteRegex, - handler: ({state, range, match}) => { - const textNode = state.schema.text(match[2]) - const codeNode = this.type.create(null, textNode) - state.tr.replaceWith(range.from, range.to, codeNode).insertText(" ") - }, - }), - ] - }, -}) diff --git a/src/lib/editor/extensions/Welshman.ts b/src/lib/editor/extensions/Welshman.ts deleted file mode 100644 index 5233b6b9..00000000 --- a/src/lib/editor/extensions/Welshman.ts +++ /dev/null @@ -1,227 +0,0 @@ -import type {StampedEvent, SignedEvent} from "@welshman/util" -import {deepMergeLeft} from "@welshman/lib" -import type {Extensions, AnyExtension} from "@tiptap/core" -import {CodeBlock} from "@tiptap/extension-code-block" -import type {CodeBlockOptions} from "@tiptap/extension-code-block" -import {Document} from "@tiptap/extension-document" -import {Dropcursor} from "@tiptap/extension-dropcursor" -import type {DropcursorOptions} from "@tiptap/extension-dropcursor" -import {Gapcursor} from "@tiptap/extension-gapcursor" -import {History} from "@tiptap/extension-history" -import type {HistoryOptions} from "@tiptap/extension-history" -import {Paragraph} from "@tiptap/extension-paragraph" -import type {ParagraphOptions} from "@tiptap/extension-paragraph" -import {Text} from "@tiptap/extension-text" -import {Placeholder} from "@tiptap/extension-placeholder" -import type {PlaceholderOptions} from "@tiptap/extension-placeholder" -import type { - NostrOptions, - FileUploadOptions, - ImageOptions, - LinkOptions, - NSecRejectOptions, -} from "nostr-editor" -import { - NostrExtension, - Bolt11Extension, - FileUploadExtension, - ImageExtension, - LinkExtension, - NAddrExtension, - NEventExtension, - NProfileExtension, - TagExtension, - VideoExtension, - NSecRejectExtension, -} from "nostr-editor" -import {WordCount} from "./WordCount.js" -import {CodeInline, type CodeInlineOptions} from "./CodeInline.js" -import {BreakOrSubmit, type BreakOrSubmitOptions} from "./BreakOrSubmit.js" -import {MentionNodeView, Bolt11NodeView, MediaNodeView, EventNodeView} from "../nodeviews/index.js" - -export type ChildExtensionOptions = - | false - | { - extend?: Partial - config?: Partial - } - -export type EmptyOptions = object - -export type WelshmanExtensionOptions = { - bolt11?: false - breakOrSubmit?: ChildExtensionOptions - codeInline?: ChildExtensionOptions - codeBlock?: ChildExtensionOptions - document?: false - dropcursor?: ChildExtensionOptions - fileUpload?: ChildExtensionOptions - gapcursor?: false - history?: ChildExtensionOptions - image?: ChildExtensionOptions - link?: ChildExtensionOptions - naddr?: ChildExtensionOptions - nevent?: ChildExtensionOptions - nprofile?: ChildExtensionOptions - nsecReject?: ChildExtensionOptions - paragraph?: ChildExtensionOptions - placeholder?: ChildExtensionOptions - tag?: false - text?: false - video?: false - wordCount?: false -} - -export interface WelshmanOptions extends NostrOptions { - submit?: () => void - sign?: (event: StampedEvent) => Promise - defaultUploadUrl?: string - defaultUploadType?: "nip96" | "blossom" - extensions?: WelshmanExtensionOptions -} - -export const WelshmanExtension = NostrExtension.extend({ - // Return an empty object or else options can't be passed - addOptions() { - return {} - }, - - addExtensions() { - const { - sign, - submit, - defaultUploadUrl = "https://nostr.build", - defaultUploadType = "nip96", - } = this.options - - if (!sign) throw new Error("sign is a required argument to WelshmanExtension") - if (!submit) throw new Error("submit is a required argument to WelshmanExtension") - - const extensionOptions = deepMergeLeft(this.options.extensions || {}, { - codeInline: { - extend: { - renderText: (props: any) => "`" + props.node.textContent + "`", - }, - }, - codeBlock: { - extend: { - renderText: (props: any) => "```" + props.node.textContent + "```", - }, - }, - bolt11: { - config: { - inline: true, - group: "inline", - }, - extend: { - addNodeView: () => Bolt11NodeView, - }, - }, - image: { - config: { - inline: true, - group: "inline", - defaultUploadUrl, - defaultUploadType, - }, - extend: { - addNodeView: () => MediaNodeView, - }, - }, - video: { - config: { - inline: true, - group: "inline", - defaultUploadUrl, - defaultUploadType, - }, - extend: { - addNodeView: () => MediaNodeView, - }, - }, - nevent: { - config: { - inline: true, - group: "inline", - }, - extend: { - addNodeView: () => EventNodeView, - }, - }, - naddr: { - config: { - inline: true, - group: "inline", - }, - extend: { - addNodeView: () => EventNodeView, - }, - }, - nprofile: { - extend: { - addNodeView: () => MentionNodeView, - }, - }, - breakOrSubmit: { - config: { - submit, - }, - }, - fileUpload: { - config: { - sign, - immediateUpload: true, - allowedMimeTypes: [ - "image/jpeg", - "image/png", - "image/gif", - "image/webp", - "video/mp4", - "video/mpeg", - "video/webm", - ], - }, - }, - }) as WelshmanExtensionOptions - - const extensions: Extensions = [] - - const addExtension = (extension: AnyExtension, options?: ChildExtensionOptions | false) => { - if (options === false) return - - if (options?.extend) { - extension = extension.extend(options.extend) - } - - if (options?.config) { - extension = extension.configure(options.config) - } - - extensions.push(extension) - } - - addExtension(Document, extensionOptions.document) - addExtension(Text, extensionOptions.text) - addExtension(Paragraph, extensionOptions.paragraph) - addExtension(History, extensionOptions.history) - addExtension(CodeBlock, extensionOptions.codeBlock) - addExtension(CodeInline, extensionOptions.codeInline) - addExtension(Dropcursor, extensionOptions.dropcursor) - addExtension(FileUploadExtension, extensionOptions.fileUpload) - addExtension(Gapcursor, extensionOptions.gapcursor) - addExtension(BreakOrSubmit, extensionOptions.breakOrSubmit) - addExtension(ImageExtension, extensionOptions.image) - addExtension(LinkExtension, extensionOptions.link) - addExtension(NAddrExtension, extensionOptions.naddr) - addExtension(NEventExtension, extensionOptions.nevent) - addExtension(NProfileExtension, extensionOptions.nprofile) - addExtension(NSecRejectExtension, extensionOptions.nsecReject) - addExtension(Placeholder, extensionOptions.placeholder) - addExtension(TagExtension, extensionOptions.tag) - addExtension(VideoExtension, extensionOptions.video) - addExtension(Bolt11Extension, extensionOptions.bolt11) - addExtension(WordCount, extensionOptions.wordCount) - - return extensions - }, -}) diff --git a/src/lib/editor/extensions/WordCount.ts b/src/lib/editor/extensions/WordCount.ts deleted file mode 100644 index 333d3d4b..00000000 --- a/src/lib/editor/extensions/WordCount.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {Extension} from "@tiptap/core" - -export const WordCount = Extension.create({ - name: "wordCount", - - addStorage() { - return { - words: 0, - chars: 0, - } - }, - - onUpdate() { - const text = this.editor.state.doc.textContent - - this.storage.words = text.split(/\s+/).filter(word => word.length > 0).length - this.storage.chars = text.length - }, -}) diff --git a/src/lib/editor/extensions/index.ts b/src/lib/editor/extensions/index.ts deleted file mode 100644 index b532d025..00000000 --- a/src/lib/editor/extensions/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./BreakOrSubmit.js" -export * from "./CodeInline.js" -export * from "./Welshman.js" -export * from "./WordCount.js" diff --git a/src/lib/editor/index.css b/src/lib/editor/index.css deleted file mode 100644 index b9af8204..00000000 --- a/src/lib/editor/index.css +++ /dev/null @@ -1,105 +0,0 @@ -:root { - --tiptap-object-bg: #eee; - --tiptap-object-fg: #111; - --tiptap-active-bg: #ddd; - --tiptap-active-fg: #111; -} - -.tiptap { - outline: none; - min-height: 0; - height: 100%; -} - -.tiptap p.is-editor-empty:first-child::before { - color: #adb5bd; - content: attr(data-placeholder); - float: left; - height: 0; - pointer-events: none; -} - -.tiptap pre code { - display: block; - max-width: 100%; - overflow: auto; - padding: 0.25rem; - background-color: var(--tiptap-object-bg); - color: var(--tiptap-object-fg); -} - -.tiptap .tiptap-object, -.tiptap p code, -.tiptap [tag] { - max-width: 100%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - border-radius: 3px; - padding: 0 0.25rem; - background-color: var(--tiptap-object-bg); - color: var(--tiptap-object-fg); -} - -.tiptap .tiptap-active { - background-color: var(--tiptap-active-bg); - color: var(--tiptap-active-fg); -} - -.tiptap .tiptap-uploading { - animation: tiptapFileUpload 1.5s infinite; -} - -.tiptap-suggestions { - margin-top: 0.5rem; - max-height: 350px; -} - -.tiptap-suggestions__content { - border-radius: 3px; - box-shadow: 0px 5px 8px 0px rgba(0, 0, 0, 0.2); - overflow-y: auto; - overflow-x: hidden; -} - -.tiptap-suggestions__create, -.tiptap-suggestions__item { - white-space: nowrap; - display: block; - width: 100%; - min-width: 0px; - cursor: pointer; - overflow-x: hidden; - text-overflow: ellipsis; - padding: 0.5rem 1rem; - text-align: left; - transition-duration: 100ms; - transition-property: color, background-color; - background-color: var(--tiptap-object-bg); - color: var(--tiptap-object-fg); -} - -.tiptap-suggestions__selected, -.tiptap-suggestions__create:hover, -.tiptap-suggestions__item:hover { - background-color: var(--tiptap-active-bg); - color: var(--tiptap-active-fg); -} - -.tiptap-suggestions__empty { - display: flex; - gap: 0.5rem; - padding: 0.5rem 1rem; -} - -@keyframes tiptapFileUpload { - 0% { - opacity: 0.2; - } - 50% { - opacity: 1; - } - 100% { - opacity: 0.2; - } -} diff --git a/src/lib/editor/index.ts b/src/lib/editor/index.ts deleted file mode 100644 index 682f45dc..00000000 --- a/src/lib/editor/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import "./index.css" - -export * from "./nodeviews/index.js" -export * from "./extensions/index.js" -export * from "./plugins/index.js" diff --git a/src/lib/editor/nodeviews/Bolt11NodeView.ts b/src/lib/editor/nodeviews/Bolt11NodeView.ts deleted file mode 100644 index 285fca9d..00000000 --- a/src/lib/editor/nodeviews/Bolt11NodeView.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type {NodeViewProps} from '@tiptap/core' - -export const Bolt11NodeView = ({node}: NodeViewProps) => { - const dom = document.createElement('span') - - dom.classList.add('tiptap-object') - dom.innerText = `${node.attrs.lnbc.slice(0, 16)}...` - - return { - dom, - selectNode() { - dom.classList.add('tiptap-active') - }, - deselectNode() { - dom.classList.remove('tiptap-active') - }, - } -} diff --git a/src/lib/editor/nodeviews/EventNodeView.ts b/src/lib/editor/nodeviews/EventNodeView.ts deleted file mode 100644 index 4e789ed1..00000000 --- a/src/lib/editor/nodeviews/EventNodeView.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type {NodeViewProps} from '@tiptap/core' -import {fromNostrURI} from "@welshman/util" - -export const EventNodeView = ({node}: NodeViewProps) => { - const dom = document.createElement('span') - - dom.classList.add('tiptap-object') - dom.innerText = `${fromNostrURI(node.attrs.bech32).slice(0, 16)}...` - - return { - dom, - selectNode() { - dom.classList.add('tiptap-active') - }, - deselectNode() { - dom.classList.remove('tiptap-active') - }, - } -} diff --git a/src/lib/editor/nodeviews/MediaNodeView.ts b/src/lib/editor/nodeviews/MediaNodeView.ts deleted file mode 100644 index 6e90f2b7..00000000 --- a/src/lib/editor/nodeviews/MediaNodeView.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type {Node, NodeViewProps} from '@tiptap/core' -import {fromNostrURI} from "@welshman/util" - -export const MediaNodeView = ({node}: NodeViewProps) => { - const dom = document.createElement('span') - - const syncUploading = (node: NodeViewProps['node']) => { - if (node.attrs.uploading) { - dom.classList.add('tiptap-uploading') - } else { - dom.classList.remove('tiptap-uploading') - } - } - - dom.classList.add('tiptap-object') - dom.innerText = node.attrs.file?.name || node.attrs.src - - syncUploading(node) - - return { - dom, - update(node: NodeViewProps['node']) { - syncUploading(node) - }, - selectNode() { - dom.classList.add('tiptap-active') - }, - deselectNode() { - dom.classList.remove('tiptap-active') - }, - } -} diff --git a/src/lib/editor/nodeviews/MentionNodeView.ts b/src/lib/editor/nodeviews/MentionNodeView.ts deleted file mode 100644 index cb93e271..00000000 --- a/src/lib/editor/nodeviews/MentionNodeView.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type {NodeViewProps} from '@tiptap/core' - -export const MentionNodeView = ({node}: NodeViewProps) => { - const dom = document.createElement('span') - - dom.classList.add('tiptap-object') - dom.textContent = `@${node.attrs.bech32.slice(0, 16)}...` - - return { - dom, - selectNode() { - dom.classList.add('tiptap-active') - }, - deselectNode() { - dom.classList.remove('tiptap-active') - }, - } -} diff --git a/src/lib/editor/nodeviews/index.ts b/src/lib/editor/nodeviews/index.ts deleted file mode 100644 index 0d241821..00000000 --- a/src/lib/editor/nodeviews/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './MentionNodeView.js' -export * from './Bolt11NodeView.js' -export * from './EventNodeView.js' -export * from './MediaNodeView.js' diff --git a/src/lib/editor/plugins/TippySuggestion.ts b/src/lib/editor/plugins/TippySuggestion.ts deleted file mode 100644 index 67fd2c29..00000000 --- a/src/lib/editor/plugins/TippySuggestion.ts +++ /dev/null @@ -1,310 +0,0 @@ -import type {Instance} from "tippy.js" -import tippy from "tippy.js" -import {nprofileEncode} from "nostr-tools/nip19" -import type {Editor} from "@tiptap/core" -import {makeNProfileAttrs} from "nostr-editor" -import {PluginKey} from "@tiptap/pm/state" -import Suggestion from "@tiptap/suggestion" -import {throttle, enumerate, clamp} from "@welshman/lib" - -export type CreateSuggestion = (item: string) => HTMLElement - -export const defaultCreateSuggestion = (item: string) => { - const span = document.createElement("span") - - span.textContent = item - - return span -} - -export type SuggestionsWrapperProps = { - term: string - allowCreate: boolean - select: (value: string) => void - search: (term: string) => string[] - createSuggestion: CreateSuggestion -} - -export interface ISuggestionsWrapperConstructor { - new (target: HTMLElement, props: SuggestionsWrapperProps): ISuggestionsWrapper -} - -export interface ISuggestionsWrapper { - setProps: (props: SuggestionsWrapperProps) => void - onKeyDown: (event: Event) => boolean - destroy: () => void -} - -function createSuggestionsWrapper( - ctor: ISuggestionsWrapperConstructor, - target: HTMLElement, - props: SuggestionsWrapperProps, -): ISuggestionsWrapper { - return new ctor(target, props) -} - -export class DefaultSuggestionsWrapper implements ISuggestionsWrapper { - index = 0 - items: string[] = [] - target: HTMLElement - content: HTMLElement - props: SuggestionsWrapperProps - - constructor(target: HTMLElement, props: SuggestionsWrapperProps) { - this.target = target - this.props = props - this.content = document.createElement("div") - this.content.classList.add("tiptap-suggestions__content") - - target.appendChild(this.content) - target.classList.add("tiptap-suggestions") - - this.search() - this.render() - } - - search = throttle(300, () => { - const {term, search} = this.props - - this.items = search(term).slice(0, 5) - }) - - render() { - const {index} = this - const {select, term, allowCreate, createSuggestion} = this.props - - this.content.innerHTML = "" - - if (term && allowCreate && this.items.includes(term)) { - const button = document.createElement("button") - - button.classList.add("tiptap-suggestions__create") - - button.addEventListener("mousedown", (event: Event) => { - event.preventDefault() - event.stopPropagation() - }) - - button.addEventListener("click", (event: Event) => { - event.preventDefault() - event.stopPropagation() - select(term) - }) - - this.content.appendChild(button) - } - - for (const [i, item] of enumerate(this.items)) { - const button = document.createElement("button") - - button.classList.add("tiptap-suggestions__item") - - if (i === index) { - button.classList.add("tiptap-suggestions__selected") - } - - button.addEventListener("mousedown", (event: Event) => { - event.preventDefault() - event.stopPropagation() - }) - - button.addEventListener("click", (event: Event) => { - event.preventDefault() - event.stopPropagation() - select(item) - }) - - button.appendChild(createSuggestion(item)) - - this.content.appendChild(button) - } - } - - setIndex(index: number) { - this.index = clamp([0, this.items.length - 1], index) - this.render() - } - - setProps(props: SuggestionsWrapperProps) { - this.props = props - this.search() - this.render() - } - - onKeyDown(event: any) { - const {index, items} = this - const {term, select, allowCreate} = this.props - - if (["Enter", "Tab"].includes(event.code)) { - const value = items[index] - - if (value) { - select(value) - - return true - } else if (term && allowCreate) { - select(term) - - return true - } - } - - if (event.code === "Space" && term && allowCreate) { - select(term) - - return true - } - - if (event.code === "ArrowUp") { - this.setIndex(index - 1) - - return true - } - - if (event.code === "ArrowDown") { - this.setIndex(index + 1) - - return true - } - - return false - } - - destroy() { - this.target.remove() - } -} - -export type TippySuggestionOptions = { - char: string - name: string - editor: Editor - search: (term: string) => string[] - select: (value: string, props: any) => void - allowCreate?: boolean - createSuggestion?: CreateSuggestion - suggestionsWrapper?: ISuggestionsWrapperConstructor -} - -export const TippySuggestion = ({ - char, - name, - editor, - search, - select, - allowCreate = false, - createSuggestion = defaultCreateSuggestion, - suggestionsWrapper = DefaultSuggestionsWrapper, -}: TippySuggestionOptions) => - Suggestion({ - char, - editor, - pluginKey: new PluginKey(`suggest-${name}`), - command: ({editor, range, props}) => { - // increase range.to by one when the next node is of type "text" - // and starts with a space character - const nodeAfter = editor.view.state.selection.$to.nodeAfter - const overrideSpace = nodeAfter?.text?.startsWith(" ") - - if (overrideSpace) { - range.to += 1 - } - - editor - .chain() - .focus() - .insertContentAt(range, [ - {type: name, attrs: props}, - {type: "text", text: " "}, - ]) - .run() - - window.getSelection()?.collapseToEnd() - }, - allow: ({state, range}) => { - const $from = state.doc.resolve(range.from) - const type = state.schema.nodes[name] - - return !!$from.parent.type.contentMatch.matchType(type) - }, - render: () => { - let popover: Instance[] - let wrapper: ISuggestionsWrapper - - const mapProps = (props: any) => ({ - term: props.query, - search, - allowCreate, - createSuggestion, - select: (value: string) => select(value, props), - }) - - return { - onStart: props => { - const target = document.createElement("div") - - // @ts-ignore - popover = tippy("body", { - getReferenceClientRect: props.clientRect as any, - appendTo: document.querySelector("dialog[open]") || document.body, - content: target, - showOnCreate: true, - interactive: true, - trigger: "manual", - placement: "bottom-start", - }) - - if (!props.query) popover[0].hide() - - wrapper = createSuggestionsWrapper(suggestionsWrapper, target, mapProps(props)) - }, - onUpdate: props => { - if (props.query) { - popover[0].show() - } else { - popover[0].hide() - } - - wrapper.setProps(mapProps(props)) - - if (props.clientRect) { - popover[0].setProps({ - getReferenceClientRect: props.clientRect as any, - }) - } - }, - onKeyDown: props => { - if (props.event.key === "Escape") { - popover[0].hide() - - return true - } - - return Boolean(wrapper.onKeyDown(props.event)) - }, - onExit: () => { - popover[0].destroy() - wrapper.destroy() - }, - } - }, - }) - -export type MentionSuggestionOptions = Partial & { - editor: Editor - search: (term: string) => string[] - getRelays: (pubkey: string) => string[] -} - -export const MentionSuggestion = (options: MentionSuggestionOptions) => - TippySuggestion({ - char: "@", - name: "nprofile", - select: (pubkey: string, props: any) => { - const relays = options.getRelays(pubkey) - const bech32 = nprofileEncode({pubkey, relays}) - - return props.command(makeNProfileAttrs(bech32, {})) - }, - ...options, - }) diff --git a/src/lib/editor/plugins/index.ts b/src/lib/editor/plugins/index.ts deleted file mode 100644 index 6b8cb0a5..00000000 --- a/src/lib/editor/plugins/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./TippySuggestion.js"