diff --git a/jest.config.js b/jest.config.js index 5a8318a4..3db7b5d4 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,6 +2,6 @@ module.exports = { roots: ["/src"], testEnvironment: "jsdom", transform: { - "^.+\\.(ts|tsx)$": "ts-jest", + "^.+\\.(js|ts|tsx)$": "ts-jest", }, }; diff --git a/package-lock.json b/package-lock.json index f9aa11d6..cf315e16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,6 @@ "name": "rich-textarea", "version": "0.24.0", "license": "MIT", - "dependencies": { - "range-at-index": "^1.0.4" - }, "devDependencies": { "@babel/plugin-transform-react-pure-annotations": "7.22.5", "@playwright/test": "^1.36.1", @@ -11481,20 +11478,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/babel-runtime": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-4.7.4.tgz", - "integrity": "sha1-LkKp7CoYGXykb+Cvu3VR6R7x4PM=", - "dependencies": { - "core-js": "^0.6.1" - } - }, - "node_modules/babel-runtime/node_modules/core-js": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-0.6.1.tgz", - "integrity": "sha1-G0lwhz6BAb+MQ1rwlfqpAk9Lm1g=", - "deprecated": "core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js." - }, "node_modules/bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", @@ -24927,14 +24910,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/range-at-index": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/range-at-index/-/range-at-index-1.0.4.tgz", - "integrity": "sha1-2ZGay9EdYt5xqjjXFco9czNEYtE=", - "dependencies": { - "babel-runtime": "4.7.4" - } - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -36843,21 +36818,6 @@ "babel-preset-current-node-syntax": "^1.0.0" } }, - "babel-runtime": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-4.7.4.tgz", - "integrity": "sha1-LkKp7CoYGXykb+Cvu3VR6R7x4PM=", - "requires": { - "core-js": "^0.6.1" - }, - "dependencies": { - "core-js": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-0.6.1.tgz", - "integrity": "sha1-G0lwhz6BAb+MQ1rwlfqpAk9Lm1g=" - } - } - }, "bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", @@ -46850,14 +46810,6 @@ "safe-buffer": "^5.1.0" } }, - "range-at-index": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/range-at-index/-/range-at-index-1.0.4.tgz", - "integrity": "sha1-2ZGay9EdYt5xqjjXFco9czNEYtE=", - "requires": { - "babel-runtime": "4.7.4" - } - }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", diff --git a/package.json b/package.json index 29d1a352..fcb4a398 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,7 @@ "size": "size-limit", "prepublishOnly": "npm run typedoc && rimraf lib && npm run build" }, - "dependencies": { - "range-at-index": "^1.0.4" - }, + "dependencies": {}, "devDependencies": { "@babel/plugin-transform-react-pure-annotations": "7.22.5", "@playwright/test": "^1.36.1", diff --git a/src/input.tsx b/src/input.tsx index 586cb3e6..99b5a7d7 100644 --- a/src/input.tsx +++ b/src/input.tsx @@ -9,8 +9,7 @@ import { memo, RefObject, } from "react"; -// @ts-expect-error no type definition -import rangeAtIndex from "range-at-index"; +import rangeAtIndex from "./vendor/range-at-index"; import { hasPercentageUnit, isSafari, @@ -269,7 +268,7 @@ export const RichInput = forwardRef( }); } else { const range = rangeAtIndex( - backdropRef[refKey], + backdropRef[refKey]!, selectionStart, selectionStart + 1 ) as Range; diff --git a/src/textarea.tsx b/src/textarea.tsx index 14621c05..bb743cd3 100644 --- a/src/textarea.tsx +++ b/src/textarea.tsx @@ -9,8 +9,7 @@ import { memo, RefObject, } from "react"; -// @ts-expect-error no type definition -import rangeAtIndex from "range-at-index"; +import rangeAtIndex from "./vendor/range-at-index"; import { hasPercentageUnit, stopPropagation, syncBackdropStyle } from "./dom"; import { SelectionRange, initSelectionStore } from "./selection"; import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect"; @@ -247,7 +246,7 @@ export const RichTextarea = forwardRef( }); } else { const range = rangeAtIndex( - backdropRef[refKey], + backdropRef[refKey]!, selectionStart, selectionStart + 1 ) as Range; diff --git a/src/vendor/range-at-index.d.ts b/src/vendor/range-at-index.d.ts new file mode 100644 index 00000000..00e99c55 --- /dev/null +++ b/src/vendor/range-at-index.d.ts @@ -0,0 +1,8 @@ +declare function RangeAtIndex( + el: HTMLElement, + index: number, + offset: number, + range?: Range +): Range; + +export default RangeAtIndex; diff --git a/src/vendor/range-at-index.js b/src/vendor/range-at-index.js new file mode 100644 index 00000000..288b5192 --- /dev/null +++ b/src/vendor/range-at-index.js @@ -0,0 +1,53 @@ +/** + * range-at-index + * https://github.com/webmodules/range-at-index/ + * Nathan Rajlich + * + * Forked from version 1.0.4; includes the following modifications: + * 1) Change module.exports to export default. + **/ + +/** + * Returns a Range instance selecting text within HTML Element `el`, + * at the given `start` and `end` offsets. + * + * @param {HTMLElement} el - DOM element to select text within + * @public + */ + +function RangeAtIndex(el, index, offset, range) { + var doc = el.ownerDocument; + if (!range) range = doc.createRange(); + + let iterator = doc.createNodeIterator(el, NodeFilter.SHOW_TEXT, null, false); + + let start = {}; + let end = {}; + let node, val, len; + + while ((node = iterator.nextNode())) { + val = node.nodeValue; + len = val.length; + + if (!start.node && len > index) { + start.node = node; + start.offset = index; + } + + if (!end.node && len >= offset) { + end.node = node; + end.offset = offset; + } + + index -= len; + offset -= len; + } + + // update the range with the start and end offsets + if (start.node) range.setStart(start.node, start.offset); + if (end.node) range.setEnd(end.node, end.offset); + + return range; +} + +export default RangeAtIndex;