]> BookStack Code Mirror - bookstack/commitdiff
Lexical: Range of bug fixes, Updated lexical version
authorDan Brown <redacted>
Sun, 8 Sep 2024 14:54:59 +0000 (15:54 +0100)
committerDan Brown <redacted>
Sun, 8 Sep 2024 14:54:59 +0000 (15:54 +0100)
- Updated selection change detection to be more accurate
- Added UI refresh for extra actions
- Fixed remove link deleting contents

package-lock.json
package.json
resources/js/wysiwyg/index.ts
resources/js/wysiwyg/nodes/image.ts
resources/js/wysiwyg/todo.md
resources/js/wysiwyg/ui/defaults/buttons/controls.ts
resources/js/wysiwyg/ui/defaults/buttons/objects.ts
resources/js/wysiwyg/ui/framework/manager.ts

index 3867a1d1fb016350e18e31c8570cc4e50944b6c1..1d252766152b45b7b8f3a238bf784b0149fe600e 100644 (file)
         "@codemirror/state": "^6.3.3",
         "@codemirror/theme-one-dark": "^6.1.2",
         "@codemirror/view": "^6.22.2",
-        "@lexical/history": "^0.16.0",
-        "@lexical/html": "^0.16.0",
-        "@lexical/link": "^0.16.0",
-        "@lexical/list": "^0.16.0",
-        "@lexical/rich-text": "^0.16.0",
-        "@lexical/selection": "^0.16.0",
-        "@lexical/table": "^0.16.0",
-        "@lexical/utils": "^0.16.0",
+        "@lexical/history": "^0.17.0",
+        "@lexical/html": "^0.17.0",
+        "@lexical/link": "^0.17.0",
+        "@lexical/list": "^0.17.0",
+        "@lexical/rich-text": "^0.17.0",
+        "@lexical/selection": "^0.17.0",
+        "@lexical/table": "^0.17.0",
+        "@lexical/utils": "^0.17.0",
         "@lezer/highlight": "^1.2.0",
         "@ssddanbrown/codemirror-lang-smarty": "^1.0.0",
         "@ssddanbrown/codemirror-lang-twig": "^1.0.0",
         "codemirror": "^6.0.1",
         "idb-keyval": "^6.2.1",
-        "lexical": "^0.16.0",
+        "lexical": "^0.17.0",
         "markdown-it": "^14.1.0",
         "markdown-it-task-lists": "^2.1.1",
         "snabbdom": "^3.5.1",
@@ -51,9 +51,9 @@
       }
     },
     "node_modules/@codemirror/autocomplete": {
-      "version": "6.16.3",
-      "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.16.3.tgz",
-      "integrity": "sha512-Vl/tIeRVVUCRDuOG48lttBasNQu8usGgXQawBXI7WJAiUDSFOfzflmEsZFZo48mAvAaa4FZ/4/yLLxFtdJaKYA==",
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.0.tgz",
+      "integrity": "sha512-5DbOvBbY4qW5l57cjDsmmpDh3/TeK1vXfTHa+BUMrRzdWdcxKZ4U4V7vQaTtOpApNU4kLS4FQ6cINtLg245LXA==",
       "dependencies": {
         "@codemirror/language": "^6.0.0",
         "@codemirror/state": "^6.0.0",
@@ -68,9 +68,9 @@
       }
     },
     "node_modules/@codemirror/commands": {
-      "version": "6.6.0",
-      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.0.tgz",
-      "integrity": "sha512-qnY+b7j1UNcTS31Eenuc/5YJB6gQOzkUoNmJQc0rznwqSRpeaWWpjkWy2C/MPTcePpsKJEM26hXrOXl1+nceXg==",
+      "version": "6.6.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.1.tgz",
+      "integrity": "sha512-iBfKbyIoXS1FGdsKcZmnrxmbc8VcbMrSgD7AVrsnX+WyAYjmUDWvE93dt5D874qS4CCVu4O1JpbagHdXbbLiOw==",
       "dependencies": {
         "@codemirror/language": "^6.0.0",
         "@codemirror/state": "^6.4.0",
       }
     },
     "node_modules/@codemirror/lang-css": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.2.1.tgz",
-      "integrity": "sha512-/UNWDNV5Viwi/1lpr/dIXJNWiwDxpw13I4pTUAsNxZdg6E0mI2kTQb0P2iHczg1Tu+H4EBgJR+hYhKiHKko7qg==",
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.0.tgz",
+      "integrity": "sha512-CyR4rUNG9OYcXDZwMPvJdtb6PHbBDKUc/6Na2BIwZ6dKab1JQqKa4di+RNRY9Myn7JB81vayKwJeQ7jEdmNVDA==",
       "dependencies": {
         "@codemirror/autocomplete": "^6.0.0",
         "@codemirror/language": "^6.0.0",
         "@codemirror/state": "^6.0.0",
         "@lezer/common": "^1.0.2",
-        "@lezer/css": "^1.0.0"
+        "@lezer/css": "^1.1.7"
       }
     },
     "node_modules/@codemirror/lang-html": {
       }
     },
     "node_modules/@codemirror/legacy-modes": {
-      "version": "6.4.0",
-      "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.4.0.tgz",
-      "integrity": "sha512-5m/K+1A6gYR0e+h/dEde7LoGimMjRtWXZFg4Lo70cc8HzjSdHe3fLwjWMR0VRl5KFT1SxalSap7uMgPKF28wBA==",
+      "version": "6.4.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.4.1.tgz",
+      "integrity": "sha512-vdg3XY7OAs5uLDx2Iw+cGfnwtd7kM+Et/eMsqAGTfT/JKiVBQZXosTzjEbWAi/FrY6DcQIz8mQjBozFHZEUWQA==",
       "dependencies": {
         "@codemirror/language": "^6.0.0"
       }
       }
     },
     "node_modules/@codemirror/view": {
-      "version": "6.28.2",
-      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.28.2.tgz",
-      "integrity": "sha512-A3DmyVfjgPsGIjiJqM/zvODUAPQdQl3ci0ghehYNnbt5x+o76xq+dL5+mMBuysDXnI3kapgOkoeJ0sbtL/3qPw==",
+      "version": "6.33.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.33.0.tgz",
+      "integrity": "sha512-AroaR3BvnjRW8fiZBalAaK+ZzB5usGgI014YKElYZvQdNH5ZIidHlO+cyf/2rWzyBFRkvG6VhiXeAEbC53P2YQ==",
       "dependencies": {
         "@codemirror/state": "^6.4.0",
         "style-mod": "^4.1.0",
       }
     },
     "node_modules/@eslint-community/regexpp": {
-      "version": "4.10.1",
-      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz",
-      "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==",
+      "version": "4.11.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
+      "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
       "dev": true,
       "engines": {
         "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
       "dev": true
     },
     "node_modules/@lexical/clipboard": {
-      "version": "0.16.0",
-      "resolved": "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.16.0.tgz",
-      "integrity": "sha512-eYMJ6jCXpWBVC05Mu9HLMysrBbfi++xFfsm+Yo7A6kYGrqYUhpXqjJkYnw1xdZYL3bV73Oe4ByVJuq42GU+Mqw==",
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.17.1.tgz",
+      "integrity": "sha512-OVqnEfWX8XN5xxuMPo6BfgGKHREbz++D5V5ISOiml0Z8fV/TQkdgwqbBJcUdJHGRHWSUwdK7CWGs/VALvVvZyw==",
       "dependencies": {
-        "@lexical/html": "0.16.0",
-        "@lexical/list": "0.16.0",
-        "@lexical/selection": "0.16.0",
-        "@lexical/utils": "0.16.0",
-        "lexical": "0.16.0"
+        "@lexical/html": "0.17.1",
+        "@lexical/list": "0.17.1",
+        "@lexical/selection": "0.17.1",
+        "@lexical/utils": "0.17.1",
+        "lexical": "0.17.1"
       }
     },
     "node_modules/@lexical/history": {
-      "version": "0.16.0",
-      "resolved": "https://registry.npmjs.org/@lexical/history/-/history-0.16.0.tgz",
-      "integrity": "sha512-xwFxgDZGviyGEqHmgt6A6gPhsyU/yzlKRk9TBUVByba3khuTknlJ1a80H5jb+OYcrpiElml7iVuGYt+oC7atCA==",
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/@lexical/history/-/history-0.17.1.tgz",
+      "integrity": "sha512-OU/ohajz4FXchUhghsWC7xeBPypFe50FCm5OePwo767G7P233IztgRKIng2pTT4zhCPW7S6Mfl53JoFHKehpWA==",
       "dependencies": {
-        "@lexical/utils": "0.16.0",
-        "lexical": "0.16.0"
+        "@lexical/utils": "0.17.1",
+        "lexical": "0.17.1"
       }
     },
     "node_modules/@lexical/html": {
-      "version": "0.16.0",
-      "resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.16.0.tgz",
-      "integrity": "sha512-okxn3q/1qkUpCZNEFRI39XeJj4YRjb6prm3WqZgP4d39DI1W24feeTZJjYRCW+dc3NInwFaolU3pNA2MGkjRtg==",
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.17.1.tgz",
+      "integrity": "sha512-yGG+K2DXl7Wn2DpNuZ0Y3uCHJgfHkJN3/MmnFb4jLnH1FoJJiuy7WJb/BRRh9H+6xBJ9v70iv+kttDJ0u1xp5w==",
       "dependencies": {
-        "@lexical/selection": "0.16.0",
-        "@lexical/utils": "0.16.0",
-        "lexical": "0.16.0"
+        "@lexical/selection": "0.17.1",
+        "@lexical/utils": "0.17.1",
+        "lexical": "0.17.1"
       }
     },
     "node_modules/@lexical/link": {
-      "version": "0.16.0",
-      "resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.16.0.tgz",
-      "integrity": "sha512-ppvJSh/XGqlzbeymOiwcXJcUcrqgQqTK2QXTBAZq7JThtb0WsJxYd2CSLSN+Ycu23prnwqOqILcU0+34+gAVFw==",
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.17.1.tgz",
+      "integrity": "sha512-qFJEKBesZAtR8kfJfIVXRFXVw6dwcpmGCW7duJbtBRjdLjralOxrlVKyFhW9PEXGhi4Mdq2Ux16YnnDncpORdQ==",
       "dependencies": {
-        "@lexical/utils": "0.16.0",
-        "lexical": "0.16.0"
+        "@lexical/utils": "0.17.1",
+        "lexical": "0.17.1"
       }
     },
     "node_modules/@lexical/list": {
-      "version": "0.16.0",
-      "resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.16.0.tgz",
-      "integrity": "sha512-nBx/DMM7nCgnOzo1JyNnVaIrk/Xi5wIPNi8jixrEV6w9Om2K6dHutn/79Xzp2dQlNGSLHEDjky6N2RyFgmXh0g==",
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.17.1.tgz",
+      "integrity": "sha512-k9ZnmQuBvW+xVUtWJZwoGtiVG2cy+hxzkLGU4jTq1sqxRIoSeGcjvhFAK8JSEj4i21SgkB1FmkWXoYK5kbwtRA==",
       "dependencies": {
-        "@lexical/utils": "0.16.0",
-        "lexical": "0.16.0"
+        "@lexical/utils": "0.17.1",
+        "lexical": "0.17.1"
       }
     },
     "node_modules/@lexical/rich-text": {
-      "version": "0.16.0",
-      "resolved": "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.16.0.tgz",
-      "integrity": "sha512-AGTD6yJZ+kj2TNah1r7/6vyufs6fZANeSvv9x5eG+WjV4uyUJYkd1qR8C5gFZHdkyr+bhAcsAXvS039VzAxRrQ==",
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.17.1.tgz",
+      "integrity": "sha512-T3kvj4P1OpedX9jvxN3WN8NP1Khol6mCW2ScFIRNRz2dsXgyN00thH1Q1J/uyu7aKyGS7rzcY0rb1Pz1qFufqQ==",
       "dependencies": {
-        "@lexical/clipboard": "0.16.0",
-        "@lexical/selection": "0.16.0",
-        "@lexical/utils": "0.16.0",
-        "lexical": "0.16.0"
+        "@lexical/clipboard": "0.17.1",
+        "@lexical/selection": "0.17.1",
+        "@lexical/utils": "0.17.1",
+        "lexical": "0.17.1"
       }
     },
     "node_modules/@lexical/selection": {
-      "version": "0.16.0",
-      "resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.16.0.tgz",
-      "integrity": "sha512-trT9gQVJ2j6AwAe7tHJ30SRuxCpV6yR9LFtggxphHsXSvJYnoHC0CXh1TF2jHl8Gd5OsdWseexGLBE4Y0V3gwQ==",
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.17.1.tgz",
+      "integrity": "sha512-qBKVn+lMV2YIoyRELNr1/QssXx/4c0id9NCB/BOuYlG8du5IjviVJquEF56NEv2t0GedDv4BpUwkhXT2QbNAxA==",
       "dependencies": {
-        "lexical": "0.16.0"
+        "lexical": "0.17.1"
       }
     },
     "node_modules/@lexical/table": {
-      "version": "0.16.0",
-      "resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.16.0.tgz",
-      "integrity": "sha512-A66K779kxdr0yH2RwT2itsMnkzyFLFNPXyiWGLobCH8ON4QPuBouZvjbRHBe8Pe64yJ0c1bRDxSbTqUi9Wt3Gg==",
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.17.1.tgz",
+      "integrity": "sha512-2fUYPmxhyuMQX3MRvSsNaxbgvwGNJpHaKx1Ldc+PT2MvDZ6ALZkfsxbi0do54Q3i7dOon8/avRp4TuVaCnqvoA==",
       "dependencies": {
-        "@lexical/utils": "0.16.0",
-        "lexical": "0.16.0"
+        "@lexical/utils": "0.17.1",
+        "lexical": "0.17.1"
       }
     },
     "node_modules/@lexical/utils": {
-      "version": "0.16.0",
-      "resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.16.0.tgz",
-      "integrity": "sha512-GWmFEmd7o3GHqJBaEwzuZQbfTNI3Gg8ReGuHMHABgrkhZ8j2NggoRBlxsQLG0f7BewfTMVwbye22yBPq78775w==",
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.17.1.tgz",
+      "integrity": "sha512-jCQER5EsvhLNxKH3qgcpdWj/necUb82Xjp8qWQ3c0tyL07hIRm2tDRA/s9mQmvcP855HEZSmGVmR5SKtkcEAVg==",
       "dependencies": {
-        "@lexical/list": "0.16.0",
-        "@lexical/selection": "0.16.0",
-        "@lexical/table": "0.16.0",
-        "lexical": "0.16.0"
+        "@lexical/list": "0.17.1",
+        "@lexical/selection": "0.17.1",
+        "@lexical/table": "0.17.1",
+        "lexical": "0.17.1"
       }
     },
     "node_modules/@lezer/common": {
       }
     },
     "node_modules/@lezer/highlight": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
-      "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz",
+      "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==",
       "dependencies": {
         "@lezer/common": "^1.0.0"
       }
       }
     },
     "node_modules/@lezer/lr": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.1.tgz",
-      "integrity": "sha512-CHsKq8DMKBf9b3yXPDIU4DbH+ZJd/sJdYOW2llbW/HudP5u0VS6Bfq1hLYfgU7uAYGFIyGGQIsSOXGPEErZiJw==",
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
+      "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
       "dependencies": {
         "@lezer/common": "^1.0.0"
       }
     },
     "node_modules/@lezer/markdown": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.3.0.tgz",
-      "integrity": "sha512-ErbEQ15eowmJUyT095e9NJc3BI9yZ894fjSDtHftD0InkfUBGgnKSU6dvan9jqsZuNHg2+ag/1oyDRxNsENupQ==",
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.3.1.tgz",
+      "integrity": "sha512-DGlzU/i8DC8k0uz1F+jeePrkATl0jWakauTzftMQOcbaMkHbNSRki/4E2tOzJWsVpoKYhe7iTJ03aepdwVUXUA==",
       "dependencies": {
         "@lezer/common": "^1.0.0",
         "@lezer/highlight": "^1.0.0"
         "node": ">= 8"
       }
     },
+    "node_modules/@rtsao/scc": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
+      "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+      "dev": true
+    },
     "node_modules/@ssddanbrown/codemirror-lang-smarty": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@ssddanbrown/codemirror-lang-smarty/-/codemirror-lang-smarty-1.0.0.tgz",
       "dev": true
     },
     "node_modules/acorn": {
-      "version": "8.12.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
-      "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
+      "version": "8.12.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+      "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
       "dev": true,
       "bin": {
         "acorn": "bin/acorn"
       }
     },
     "node_modules/debug": {
-      "version": "4.3.5",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
-      "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+      "version": "4.3.7",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+      "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
       "dev": true,
       "dependencies": {
-        "ms": "2.1.2"
+        "ms": "^2.1.3"
       },
       "engines": {
         "node": ">=6.0"
       }
     },
     "node_modules/eslint-module-utils": {
-      "version": "2.8.1",
-      "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz",
-      "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==",
+      "version": "2.11.0",
+      "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.0.tgz",
+      "integrity": "sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==",
       "dev": true,
       "dependencies": {
         "debug": "^3.2.7"
       }
     },
     "node_modules/eslint-plugin-import": {
-      "version": "2.29.1",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz",
-      "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==",
+      "version": "2.30.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz",
+      "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==",
       "dev": true,
       "dependencies": {
-        "array-includes": "^3.1.7",
-        "array.prototype.findlastindex": "^1.2.3",
+        "@rtsao/scc": "^1.1.0",
+        "array-includes": "^3.1.8",
+        "array.prototype.findlastindex": "^1.2.5",
         "array.prototype.flat": "^1.3.2",
         "array.prototype.flatmap": "^1.3.2",
         "debug": "^3.2.7",
         "doctrine": "^2.1.0",
         "eslint-import-resolver-node": "^0.3.9",
-        "eslint-module-utils": "^2.8.0",
-        "hasown": "^2.0.0",
-        "is-core-module": "^2.13.1",
+        "eslint-module-utils": "^2.9.0",
+        "hasown": "^2.0.2",
+        "is-core-module": "^2.15.1",
         "is-glob": "^4.0.3",
         "minimatch": "^3.1.2",
-        "object.fromentries": "^2.0.7",
-        "object.groupby": "^1.0.1",
-        "object.values": "^1.1.7",
+        "object.fromentries": "^2.0.8",
+        "object.groupby": "^1.0.3",
+        "object.values": "^1.2.0",
         "semver": "^6.3.1",
         "tsconfig-paths": "^3.15.0"
       },
       }
     },
     "node_modules/esquery": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
-      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+      "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
       "dev": true,
       "dependencies": {
         "estraverse": "^5.1.0"
       "integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg=="
     },
     "node_modules/ignore": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
-      "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
+      "version": "5.3.2",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
       "dev": true,
       "engines": {
         "node": ">= 4"
       }
     },
     "node_modules/immutable": {
-      "version": "4.3.6",
-      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz",
-      "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==",
+      "version": "4.3.7",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz",
+      "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==",
       "dev": true
     },
     "node_modules/import-fresh": {
       }
     },
     "node_modules/is-core-module": {
-      "version": "2.14.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz",
-      "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==",
+      "version": "2.15.1",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
+      "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
       "dev": true,
       "dependencies": {
         "hasown": "^2.0.2"
       }
     },
     "node_modules/lexical": {
-      "version": "0.16.0",
-      "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.16.0.tgz",
-      "integrity": "sha512-Skn45Qhriazq4fpAtwnAB11U//GKc4vjzx54xsV3TkDLDvWpbL4Z9TNRwRoN3g7w8AkWnqjeOSODKkrjgfRSrg=="
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.17.1.tgz",
+      "integrity": "sha512-72/MhR7jqmyqD10bmJw8gztlCm4KDDT+TPtU4elqXrEvHoO5XENi34YAEUD9gIkPfqSwyLa9mwAX1nKzIr5xEA=="
     },
     "node_modules/linkify-it": {
       "version": "5.0.0",
       }
     },
     "node_modules/ms": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
       "dev": true
     },
     "node_modules/natural-compare": {
       }
     },
     "node_modules/sass": {
-      "version": "1.77.6",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz",
-      "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==",
+      "version": "1.78.0",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.78.0.tgz",
+      "integrity": "sha512-AaIqGSrjo5lA2Yg7RvFZrlXDBCp3nV4XP73GrLGvdRWWwk+8H3l0SDvq/5bA4eF+0RFPLuWUk3E+P1U/YqnpsQ==",
       "dev": true,
       "dependencies": {
         "chokidar": ">=3.0.0 <4.0.0",
       }
     },
     "node_modules/sortablejs": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.2.tgz",
-      "integrity": "sha512-FJF5jgdfvoKn1MAKSdGs33bIqLi3LmsgVTliuX6iITj834F+JRQZN90Z93yql8h0K2t0RwDPBmxwlbZfDcxNZA=="
+      "version": "1.15.3",
+      "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.3.tgz",
+      "integrity": "sha512-zdK3/kwwAK1cJgy1rwl1YtNTbRmc8qW/+vgXf75A7NHag5of4pyI6uK86ktmQETyWRH7IGaE73uZOOBcGxgqZg=="
     },
     "node_modules/source-map-js": {
       "version": "1.2.0",
       }
     },
     "node_modules/spdx-license-ids": {
-      "version": "3.0.18",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz",
-      "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==",
+      "version": "3.0.20",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz",
+      "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==",
       "dev": true
     },
     "node_modules/string-width": {
       }
     },
     "node_modules/typescript": {
-      "version": "5.5.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
-      "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
+      "version": "5.5.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
+      "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
index 71debf2bd68b6700020925d96d12f7faaaa52cec..d39bf5a2cb2fd378dc2052011de0be74243cb1ca 100644 (file)
     "@codemirror/state": "^6.3.3",
     "@codemirror/theme-one-dark": "^6.1.2",
     "@codemirror/view": "^6.22.2",
-    "@lexical/history": "^0.16.0",
-    "@lexical/html": "^0.16.0",
-    "@lexical/link": "^0.16.0",
-    "@lexical/list": "^0.16.0",
-    "@lexical/rich-text": "^0.16.0",
-    "@lexical/selection": "^0.16.0",
-    "@lexical/table": "^0.16.0",
-    "@lexical/utils": "^0.16.0",
+    "@lexical/history": "^0.17.0",
+    "@lexical/html": "^0.17.0",
+    "@lexical/link": "^0.17.0",
+    "@lexical/list": "^0.17.0",
+    "@lexical/rich-text": "^0.17.0",
+    "@lexical/selection": "^0.17.0",
+    "@lexical/table": "^0.17.0",
+    "@lexical/utils": "^0.17.0",
     "@lezer/highlight": "^1.2.0",
     "@ssddanbrown/codemirror-lang-smarty": "^1.0.0",
     "@ssddanbrown/codemirror-lang-twig": "^1.0.0",
     "codemirror": "^6.0.1",
     "idb-keyval": "^6.2.1",
-    "lexical": "^0.16.0",
+    "lexical": "^0.17.0",
     "markdown-it": "^14.1.0",
     "markdown-it-task-lists": "^2.1.1",
     "snabbdom": "^3.5.1",
index 64b59492be1318b21fbe9916920c2af62831aa8a..1e5e4b3ce3e64f3315883bdffb0caee2bd3f0b06 100644 (file)
@@ -1,4 +1,4 @@
-import {createEditor, CreateEditorArgs, LexicalEditor} from 'lexical';
+import {$getSelection, createEditor, CreateEditorArgs, isCurrentlyReadOnlyMode, LexicalEditor} from 'lexical';
 import {createEmptyHistoryState, registerHistory} from '@lexical/history';
 import {registerRichText} from '@lexical/rich-text';
 import {mergeRegister} from '@lexical/utils';
@@ -69,7 +69,19 @@ export function createPageEditorInstance(container: HTMLElement, htmlContent: st
     }
 
     let changeFromLoading = true;
-    editor.registerUpdateListener(({editorState, dirtyElements, dirtyLeaves}) => {
+    editor.registerUpdateListener(({dirtyElements, dirtyLeaves, editorState, prevEditorState}) => {
+        // Watch for selection changes to update the UI on change
+        // Used to be done via SELECTION_CHANGE_COMMAND but this would not always emit
+        // for all selection changes, so this proved more reliable.
+        const selectionChange = !(prevEditorState._selection?.is(editorState._selection) || false);
+        if (selectionChange) {
+            editor.update(() => {
+                const selection = $getSelection();
+                context.manager.triggerStateUpdate({
+                    editor, selection,
+                });
+            });
+        }
 
         // Emit change event to component system (for draft detection) on actual user content change
         if (dirtyElements.size > 0 || dirtyLeaves.size > 0) {
index c9d11d871b3438d93e709b91cdf9e0c90f66619d..b6d362b62c91afe2ee79514c8af89b75ffd44030 100644 (file)
@@ -40,7 +40,7 @@ export class ImageNode extends ElementNode {
             alt: node.__alt,
             width: node.__width,
             height: node.__height,
-        });
+        }, node.__key);
         newNode.__alignment = node.__alignment;
         return newNode;
     }
index 92042295c909fa8f152dde62b0ee761087069909..15a59c7345f4e23221ad8baf317ffc1250932bdd 100644 (file)
@@ -16,6 +16,4 @@
 
 ## Bugs
 
-- Removing link around image via button deletes image, not just link 
-- `SELECTION_CHANGE_COMMAND` not fired when clicking out of a table cell. Prevents toolbar hiding on table unselect.
 - Template drag/drop not handled when outside core editor area (ignored in margin area).
\ No newline at end of file
index 2a2fecc40c41c216bfb68b65d5cc30c84844b453..8829d241f160c4d560c69f0aa4db8033d4d7bb6b 100644 (file)
@@ -19,6 +19,7 @@ export const undo: EditorButtonDefinition = {
     icon: undoIcon,
     action(context: EditorUiContext) {
         context.editor.dispatchCommand(UNDO_COMMAND, undefined);
+        context.manager.triggerFutureStateRefresh();
     },
     isActive(selection: BaseSelection|null): boolean {
         return false;
@@ -38,6 +39,7 @@ export const redo: EditorButtonDefinition = {
     icon: redoIcon,
     action(context: EditorUiContext) {
         context.editor.dispatchCommand(REDO_COMMAND, undefined);
+        context.manager.triggerFutureStateRefresh();
     },
     isActive(selection: BaseSelection|null): boolean {
         return false;
index 46556d3d1368ab8745d22080caa136ec735872cc..fd95f9f35d251dd5713d479575aed541e927b1e6 100644 (file)
@@ -6,7 +6,7 @@ import {
     $getRoot,
     $getSelection, $insertNodes,
     BaseSelection,
-    ElementNode
+    ElementNode, isCurrentlyReadOnlyMode
 } from "lexical";
 import {$isLinkNode, LinkNode} from "@lexical/link";
 import unlinkIcon from "@icons/editor/unlink.svg";
@@ -54,16 +54,17 @@ export const unlink: EditorButtonDefinition = {
         context.editor.update(() => {
             const selection = getLastSelection(context.editor);
             const selectedLink = $getNodeFromSelection(selection, $isLinkNode) as LinkNode | null;
-            const selectionPoints = selection?.getStartEndPoints();
 
             if (selectedLink) {
-                const newNode = $createTextNode(selectedLink.getTextContent());
-                selectedLink.replace(newNode);
-                if (selectionPoints?.length === 2) {
-                    newNode.select(selectionPoints[0].offset, selectionPoints[1].offset);
-                } else {
-                    newNode.select();
+                const contents = selectedLink.getChildren().reverse();
+                for (const child of contents) {
+                    selectedLink.insertAfter(child);
                 }
+                selectedLink.remove();
+
+                contents[contents.length - 1].selectStart();
+
+                context.manager.triggerFutureStateRefresh();
             }
         });
     },
index 8fda66cb25f8998b879f80d4c10e87c71c2223df..7325303758337871dbec98d60e252d558f9311ef 100644 (file)
@@ -108,7 +108,7 @@ export class EditorUIManager {
         this.contextToolbarDefinitionsByKey[key] = definition;
     }
 
-    protected triggerStateUpdate(update: EditorUiStateUpdate): void {
+    triggerStateUpdate(update: EditorUiStateUpdate): void {
         setLastSelection(update.editor, update.selection);
         this.toolbar?.updateState(update);
         this.updateContextToolbars(update);
@@ -120,9 +120,20 @@ export class EditorUIManager {
 
     triggerStateRefresh(): void {
         const editor = this.getContext().editor;
-        this.triggerStateUpdate({
+        const update = {
             editor,
             selection: getLastSelection(editor),
+        };
+
+        this.triggerStateUpdate(update);
+        this.updateContextToolbars(update);
+    }
+
+    triggerFutureStateRefresh(): void {
+        requestAnimationFrame(() => {
+            this.getContext().editor.getEditorState().read(() => {
+                this.triggerStateRefresh();
+            });
         });
     }
 
@@ -195,15 +206,6 @@ export class EditorUIManager {
     }
 
     protected setupEditor(editor: LexicalEditor) {
-        // Update button states on editor selection change
-        editor.registerCommand(SELECTION_CHANGE_COMMAND, () => {
-            this.triggerStateUpdate({
-                editor: editor,
-                selection: $getSelection(),
-            });
-            return false;
-        }, COMMAND_PRIORITY_LOW);
-
         // Register our DOM decorate listener with the editor
         const domDecorateListener: DecoratorListener<EditorDecoratorAdapter> = (decorators: Record<NodeKey, EditorDecoratorAdapter>) => {
             editor.getEditorState().read(() => {