@solid-primitives/selection
Advanced tools
+4
-7
@@ -1,7 +0,4 @@ | ||
| import { Accessor, Setter } from 'solid-js'; | ||
| type HTMLSelection = [node: HTMLElement | null, start: number, end: number]; | ||
| declare const getTextNodes: (startNode: Node) => Node[]; | ||
| declare const createSelection: () => [Accessor<HTMLSelection>, Setter<HTMLSelection>]; | ||
| export { HTMLSelection, createSelection, getTextNodes }; | ||
| import { Accessor, Setter } from "solid-js"; | ||
| export type HTMLSelection = [node: HTMLElement | null, start: number, end: number]; | ||
| export declare const getTextNodes: (startNode: Node) => Node[]; | ||
| export declare const createSelection: () => [Accessor<HTMLSelection>, Setter<HTMLSelection>]; |
+86
-83
@@ -1,88 +0,91 @@ | ||
| import { createSignal, createEffect, onCleanup } from 'solid-js'; | ||
| import { isServer } from 'solid-js/web'; | ||
| // src/index.ts | ||
| var getTextNodes = (startNode) => { | ||
| const textNodes = []; | ||
| const walkNodes = (node) => { | ||
| node instanceof Text && textNodes.push(node); | ||
| node.firstChild && walkNodes(node.firstChild); | ||
| node.nextSibling && walkNodes(node.nextSibling); | ||
| }; | ||
| walkNodes(startNode); | ||
| return textNodes; | ||
| import { createEffect, createSignal, onCleanup } from "solid-js"; | ||
| import { isServer } from "solid-js/web"; | ||
| export const getTextNodes = (startNode) => { | ||
| const textNodes = []; | ||
| const walkNodes = (node) => { | ||
| node instanceof Text && textNodes.push(node); | ||
| node.firstChild && walkNodes(node.firstChild); | ||
| node.nextSibling && walkNodes(node.nextSibling); | ||
| }; | ||
| walkNodes(startNode); | ||
| return textNodes; | ||
| }; | ||
| var addNodeLength = (length, node) => length + node.data.length; | ||
| var getRangePos = (container, offset, texts) => { | ||
| const index = texts.indexOf(container); | ||
| return index === -1 ? NaN : texts.slice(0, index).reduce(addNodeLength, 0) + offset; | ||
| const addNodeLength = (length, node) => length + node.data.length; | ||
| const getRangePos = (container, offset, texts) => { | ||
| const index = texts.indexOf(container); | ||
| return index === -1 ? NaN : texts.slice(0, index).reduce(addNodeLength, 0) + offset; | ||
| }; | ||
| var getParent = (node) => node === null || node.contentEditable === "true" ? node : getParent(node.parentNode || null); | ||
| var getRangeArgs = (offset, texts) => texts.reduce( | ||
| ([node, pos], text) => node ? [node, pos] : pos <= text.data.length ? [text, pos] : [null, pos - text.data.length], | ||
| [null, offset] | ||
| ); | ||
| var createSelection = () => { | ||
| if (isServer) { | ||
| return [ | ||
| () => [null, NaN, NaN], | ||
| (sel) => typeof sel === "function" ? sel([null, NaN, NaN]) : sel | ||
| ]; | ||
| } | ||
| const [getSelection, setSelection] = createSignal([null, NaN, NaN]); | ||
| const [selected, setSelected] = createSignal([null, NaN, NaN]); | ||
| const selectionHandler = () => { | ||
| const active = document.activeElement; | ||
| if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement) { | ||
| return setSelection([active, active.selectionStart ?? NaN, active.selectionEnd ?? NaN]); | ||
| const getParent = (node) => node === null || node.contentEditable === "true" | ||
| ? node | ||
| : getParent(node.parentNode || null); | ||
| const getRangeArgs = (offset, texts) => texts.reduce(([node, pos], text) => node | ||
| ? [node, pos] | ||
| : pos <= text.data.length | ||
| ? [text, pos] | ||
| : [null, pos - text.data.length], [null, offset]); | ||
| export const createSelection = () => { | ||
| if (isServer) { | ||
| return [ | ||
| () => [null, NaN, NaN], | ||
| sel => (typeof sel === "function" ? sel([null, NaN, NaN]) : sel), | ||
| ]; | ||
| } | ||
| const selection = window.getSelection(); | ||
| if (!selection?.rangeCount) { | ||
| return setSelection([null, NaN, NaN]); | ||
| } | ||
| const range = selection.getRangeAt(0); | ||
| const parent = getParent(range.commonAncestorContainer); | ||
| if (!parent) { | ||
| return setSelection([null, NaN, NaN]); | ||
| } | ||
| const texts = getTextNodes(parent); | ||
| const startPosition = getRangePos(range.startContainer, range.startOffset, texts); | ||
| const endPosition = range.collapsed ? startPosition : getRangePos(range.endContainer, range.endOffset, texts); | ||
| setSelection([parent, startPosition, endPosition]); | ||
| }; | ||
| selectionHandler(); | ||
| createEffect(() => { | ||
| document.addEventListener("selectionchange", selectionHandler); | ||
| document.addEventListener("click", selectionHandler); | ||
| document.addEventListener("keyup", selectionHandler); | ||
| onCleanup(() => { | ||
| document.removeEventListener("selectionchange", selectionHandler); | ||
| document.removeEventListener("click", selectionHandler); | ||
| document.removeEventListener("keyup", selectionHandler); | ||
| const [getSelection, setSelection] = createSignal([null, NaN, NaN]); | ||
| const [selected, setSelected] = createSignal([null, NaN, NaN]); | ||
| const selectionHandler = () => { | ||
| const active = document.activeElement; | ||
| if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement) { | ||
| return setSelection([active, active.selectionStart ?? NaN, active.selectionEnd ?? NaN]); | ||
| } | ||
| const selection = window.getSelection(); | ||
| if (!selection?.rangeCount) { | ||
| return setSelection([null, NaN, NaN]); | ||
| } | ||
| const range = selection.getRangeAt(0); | ||
| const parent = getParent(range.commonAncestorContainer); | ||
| if (!parent) { | ||
| return setSelection([null, NaN, NaN]); | ||
| } | ||
| const texts = getTextNodes(parent); | ||
| const startPosition = getRangePos(range.startContainer, range.startOffset, texts); | ||
| const endPosition = range.collapsed | ||
| ? startPosition | ||
| : getRangePos(range.endContainer, range.endOffset, texts); | ||
| setSelection([parent, startPosition, endPosition]); | ||
| }; | ||
| selectionHandler(); | ||
| createEffect(() => { | ||
| document.addEventListener("selectionchange", selectionHandler); | ||
| document.addEventListener("click", selectionHandler); | ||
| document.addEventListener("keyup", selectionHandler); | ||
| onCleanup(() => { | ||
| document.removeEventListener("selectionchange", selectionHandler); | ||
| document.removeEventListener("click", selectionHandler); | ||
| document.removeEventListener("keyup", selectionHandler); | ||
| }); | ||
| }); | ||
| }); | ||
| createEffect(() => { | ||
| const [node, start, end] = selected(); | ||
| const selection = window.getSelection(); | ||
| if (node === null) { | ||
| selection?.rangeCount && selection.removeAllRanges(); | ||
| } else if (node instanceof HTMLInputElement || node instanceof HTMLTextAreaElement) { | ||
| document.activeElement !== node && node.focus(); | ||
| node.setSelectionRange(start, end); | ||
| } else { | ||
| selection?.removeAllRanges(); | ||
| const range = document.createRange(); | ||
| const texts = getTextNodes(node); | ||
| const [startNode, startPos] = getRangeArgs(start, texts); | ||
| const [endNode, endPos] = start === end ? [startNode, startPos] : getRangeArgs(end, texts); | ||
| if (startNode && endNode && startPos !== -1 && endPos !== -1) { | ||
| range.setStart(startNode, startPos); | ||
| range.setEnd(endNode, endPos); | ||
| selection?.addRange(range); | ||
| } | ||
| } | ||
| }); | ||
| return [getSelection, setSelected]; | ||
| createEffect(() => { | ||
| const [node, start, end] = selected(); | ||
| const selection = window.getSelection(); | ||
| if (node === null) { | ||
| selection?.rangeCount && selection.removeAllRanges(); | ||
| } | ||
| else if (node instanceof HTMLInputElement || node instanceof HTMLTextAreaElement) { | ||
| document.activeElement !== node && node.focus(); | ||
| node.setSelectionRange(start, end); | ||
| } | ||
| else { | ||
| selection?.removeAllRanges(); | ||
| const range = document.createRange(); | ||
| const texts = getTextNodes(node); | ||
| const [startNode, startPos] = getRangeArgs(start, texts); | ||
| const [endNode, endPos] = start === end ? [startNode, startPos] : getRangeArgs(end, texts); | ||
| if (startNode && endNode && startPos !== -1 && endPos !== -1) { | ||
| range.setStart(startNode, startPos); | ||
| range.setEnd(endNode, endPos); | ||
| selection?.addRange(range); | ||
| } | ||
| } | ||
| }); | ||
| return [getSelection, setSelected]; | ||
| }; | ||
| export { createSelection, getTextNodes }; |
+2
-6
| { | ||
| "name": "@solid-primitives/selection", | ||
| "version": "0.0.8", | ||
| "version": "0.1.0", | ||
| "description": "selection primitive.", | ||
@@ -26,3 +26,2 @@ "author": "Alex Lohr <alex.lohr@logmein.com>", | ||
| "type": "module", | ||
| "main": "./dist/index.cjs", | ||
| "module": "./dist/index.js", | ||
@@ -32,9 +31,6 @@ "browser": {}, | ||
| "exports": { | ||
| "@solid-primitives/source": "./src/index.ts", | ||
| "import": { | ||
| "types": "./dist/index.d.ts", | ||
| "default": "./dist/index.js" | ||
| }, | ||
| "require": { | ||
| "types": "./dist/index.d.cts", | ||
| "default": "./dist/index.cjs" | ||
| } | ||
@@ -41,0 +37,0 @@ }, |
+0
-1
@@ -7,3 +7,2 @@ <p> | ||
| [](https://turborepo.org/) | ||
| [](https://bundlephobia.com/package/@solid-primitives/selection) | ||
@@ -10,0 +9,0 @@ [](https://www.npmjs.com/package/@solid-primitives/selection) |
| 'use strict'; | ||
| var solidJs = require('solid-js'); | ||
| var web = require('solid-js/web'); | ||
| // src/index.ts | ||
| exports.getTextNodes = (startNode) => { | ||
| const textNodes = []; | ||
| const walkNodes = (node) => { | ||
| node instanceof Text && textNodes.push(node); | ||
| node.firstChild && walkNodes(node.firstChild); | ||
| node.nextSibling && walkNodes(node.nextSibling); | ||
| }; | ||
| walkNodes(startNode); | ||
| return textNodes; | ||
| }; | ||
| var addNodeLength = (length, node) => length + node.data.length; | ||
| var getRangePos = (container, offset, texts) => { | ||
| const index = texts.indexOf(container); | ||
| return index === -1 ? NaN : texts.slice(0, index).reduce(addNodeLength, 0) + offset; | ||
| }; | ||
| var getParent = (node) => node === null || node.contentEditable === "true" ? node : getParent(node.parentNode || null); | ||
| var getRangeArgs = (offset, texts) => texts.reduce( | ||
| ([node, pos], text) => node ? [node, pos] : pos <= text.data.length ? [text, pos] : [null, pos - text.data.length], | ||
| [null, offset] | ||
| ); | ||
| exports.createSelection = () => { | ||
| if (web.isServer) { | ||
| return [ | ||
| () => [null, NaN, NaN], | ||
| (sel) => typeof sel === "function" ? sel([null, NaN, NaN]) : sel | ||
| ]; | ||
| } | ||
| const [getSelection, setSelection] = solidJs.createSignal([null, NaN, NaN]); | ||
| const [selected, setSelected] = solidJs.createSignal([null, NaN, NaN]); | ||
| const selectionHandler = () => { | ||
| const active = document.activeElement; | ||
| if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement) { | ||
| return setSelection([active, active.selectionStart ?? NaN, active.selectionEnd ?? NaN]); | ||
| } | ||
| const selection = window.getSelection(); | ||
| if (!selection?.rangeCount) { | ||
| return setSelection([null, NaN, NaN]); | ||
| } | ||
| const range = selection.getRangeAt(0); | ||
| const parent = getParent(range.commonAncestorContainer); | ||
| if (!parent) { | ||
| return setSelection([null, NaN, NaN]); | ||
| } | ||
| const texts = exports.getTextNodes(parent); | ||
| const startPosition = getRangePos(range.startContainer, range.startOffset, texts); | ||
| const endPosition = range.collapsed ? startPosition : getRangePos(range.endContainer, range.endOffset, texts); | ||
| setSelection([parent, startPosition, endPosition]); | ||
| }; | ||
| selectionHandler(); | ||
| solidJs.createEffect(() => { | ||
| document.addEventListener("selectionchange", selectionHandler); | ||
| document.addEventListener("click", selectionHandler); | ||
| document.addEventListener("keyup", selectionHandler); | ||
| solidJs.onCleanup(() => { | ||
| document.removeEventListener("selectionchange", selectionHandler); | ||
| document.removeEventListener("click", selectionHandler); | ||
| document.removeEventListener("keyup", selectionHandler); | ||
| }); | ||
| }); | ||
| solidJs.createEffect(() => { | ||
| const [node, start, end] = selected(); | ||
| const selection = window.getSelection(); | ||
| if (node === null) { | ||
| selection?.rangeCount && selection.removeAllRanges(); | ||
| } else if (node instanceof HTMLInputElement || node instanceof HTMLTextAreaElement) { | ||
| document.activeElement !== node && node.focus(); | ||
| node.setSelectionRange(start, end); | ||
| } else { | ||
| selection?.removeAllRanges(); | ||
| const range = document.createRange(); | ||
| const texts = exports.getTextNodes(node); | ||
| const [startNode, startPos] = getRangeArgs(start, texts); | ||
| const [endNode, endPos] = start === end ? [startNode, startPos] : getRangeArgs(end, texts); | ||
| if (startNode && endNode && startPos !== -1 && endPos !== -1) { | ||
| range.setStart(startNode, startPos); | ||
| range.setEnd(endNode, endPos); | ||
| selection?.addRange(range); | ||
| } | ||
| } | ||
| }); | ||
| return [getSelection, setSelected]; | ||
| }; |
| 'use strict'; | ||
| var solidJs = require('solid-js'); | ||
| var web = require('solid-js/web'); | ||
| // src/index.ts | ||
| exports.getTextNodes = (startNode) => { | ||
| const textNodes = []; | ||
| const walkNodes = (node) => { | ||
| node instanceof Text && textNodes.push(node); | ||
| node.firstChild && walkNodes(node.firstChild); | ||
| node.nextSibling && walkNodes(node.nextSibling); | ||
| }; | ||
| walkNodes(startNode); | ||
| return textNodes; | ||
| }; | ||
| var addNodeLength = (length, node) => length + node.data.length; | ||
| var getRangePos = (container, offset, texts) => { | ||
| const index = texts.indexOf(container); | ||
| return index === -1 ? NaN : texts.slice(0, index).reduce(addNodeLength, 0) + offset; | ||
| }; | ||
| var getParent = (node) => node === null || node.contentEditable === "true" ? node : getParent(node.parentNode || null); | ||
| var getRangeArgs = (offset, texts) => texts.reduce( | ||
| ([node, pos], text) => node ? [node, pos] : pos <= text.data.length ? [text, pos] : [null, pos - text.data.length], | ||
| [null, offset] | ||
| ); | ||
| exports.createSelection = () => { | ||
| if (web.isServer) { | ||
| return [ | ||
| () => [null, NaN, NaN], | ||
| (sel) => typeof sel === "function" ? sel([null, NaN, NaN]) : sel | ||
| ]; | ||
| } | ||
| const [getSelection, setSelection] = solidJs.createSignal([null, NaN, NaN]); | ||
| const [selected, setSelected] = solidJs.createSignal([null, NaN, NaN]); | ||
| const selectionHandler = () => { | ||
| const active = document.activeElement; | ||
| if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement) { | ||
| return setSelection([active, active.selectionStart ?? NaN, active.selectionEnd ?? NaN]); | ||
| } | ||
| const selection = window.getSelection(); | ||
| if (!selection?.rangeCount) { | ||
| return setSelection([null, NaN, NaN]); | ||
| } | ||
| const range = selection.getRangeAt(0); | ||
| const parent = getParent(range.commonAncestorContainer); | ||
| if (!parent) { | ||
| return setSelection([null, NaN, NaN]); | ||
| } | ||
| const texts = exports.getTextNodes(parent); | ||
| const startPosition = getRangePos(range.startContainer, range.startOffset, texts); | ||
| const endPosition = range.collapsed ? startPosition : getRangePos(range.endContainer, range.endOffset, texts); | ||
| setSelection([parent, startPosition, endPosition]); | ||
| }; | ||
| selectionHandler(); | ||
| solidJs.createEffect(() => { | ||
| document.addEventListener("selectionchange", selectionHandler); | ||
| document.addEventListener("click", selectionHandler); | ||
| document.addEventListener("keyup", selectionHandler); | ||
| solidJs.onCleanup(() => { | ||
| document.removeEventListener("selectionchange", selectionHandler); | ||
| document.removeEventListener("click", selectionHandler); | ||
| document.removeEventListener("keyup", selectionHandler); | ||
| }); | ||
| }); | ||
| solidJs.createEffect(() => { | ||
| const [node, start, end] = selected(); | ||
| const selection = window.getSelection(); | ||
| if (node === null) { | ||
| selection?.rangeCount && selection.removeAllRanges(); | ||
| } else if (node instanceof HTMLInputElement || node instanceof HTMLTextAreaElement) { | ||
| document.activeElement !== node && node.focus(); | ||
| node.setSelectionRange(start, end); | ||
| } else { | ||
| selection?.removeAllRanges(); | ||
| const range = document.createRange(); | ||
| const texts = exports.getTextNodes(node); | ||
| const [startNode, startPos] = getRangeArgs(start, texts); | ||
| const [endNode, endPos] = start === end ? [startNode, startPos] : getRangeArgs(end, texts); | ||
| if (startNode && endNode && startPos !== -1 && endPos !== -1) { | ||
| range.setStart(startNode, startPos); | ||
| range.setEnd(endNode, endPos); | ||
| selection?.addRange(range); | ||
| } | ||
| } | ||
| }); | ||
| return [getSelection, setSelected]; | ||
| }; |
| import { Accessor, Setter } from 'solid-js'; | ||
| type HTMLSelection = [node: HTMLElement | null, start: number, end: number]; | ||
| declare const getTextNodes: (startNode: Node) => Node[]; | ||
| declare const createSelection: () => [Accessor<HTMLSelection>, Setter<HTMLSelection>]; | ||
| export { HTMLSelection, createSelection, getTextNodes }; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
10140
-42.38%5
-37.5%95
-63.88%88
-1.12%1
Infinity%