npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

text-range

v1.2.3

Published

[![publish](https://github.com/PinghuaZhuang/TextRange/actions/workflows/publish.yml/badge.svg)](https://github.com/PinghuaZhuang/TextRange/actions/workflows/publish.yml) [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/P

Downloads

20

Readme

TextRange

publish license Commit Verison

管理 Range 的工具. 支持导入/导出. 可用于页面批注.

安装

pnpm add text-range

Example

访问 Live Demo 或者克隆项目, 并执行:

pnpm install
pnpm dev

使用

// 用户选中文本后
// 未选中文本会抛出异常
new TextRange(/** options */);

interface TextRangeOptions {
  container?: Element;
  range?: Range;
  id?: string | number;
  /**
   * 是否裁剪开始和结束的文本节点
   * @default false
   */
  splitText?: boolean;
}

类型

interface RangeNodeData {
  path: Path;
  offset: number;
  text: string;
}

interface RangeData {
  id: string | number;
  text: string;
  start: RangeNodeData;
  end: RangeNodeData;
}

/**
 * 距离根元素的距离
 * @example body > div(0) + div(1) > span > text(0) + text(1)
 *  对于 text(1) 的path为 [1, 0, 1]
 *  [(body > div + div), (div(1) > span), (span > text(0) + text(1))]
 */
type Path = number[];

导出

const r = new TextRange();
const data: RangeData = r.data;

导入

TextRange.create(data as RangeData); // => TextRange

高亮选中文本

import TextRange from 'text-range';

document.addEventListener('mouseup', function (e) {
  if (getSelection().isCollapsed) return;
  const r = new TextRange();
  r.replace((textNode) => {
    const nrmark = document.createElement('nrmark');
    nrmark.appendChild(textNode);
    return nrmark;
  });
  getSelection().collapseToStart();
});
// css
nrmark {
  background-color: #ffeb3b;
}

属性

  • root: Element.

    • default: document.body
    • 计算路径的根元素, 不传默认为 body.
  • range: Range.

    • 不传默认取 getSelection().getRangeAt(0).
  • split: boolean;

    • default: false;
    • 首尾文本节点是否根据索引裁剪.
  • single: boolean;

    • range 首尾节点是否是同一个.
  • data: RangeData;

    • 记录 range 的数据.
  • isEmpty: boolean;

    • range 是否为空.

方法

  • rects: () => DOMRect[];

    • range.getClientRects() 所有元素的非空 DOMRect.
  • mergeRects: () => DOMRect[];

    • 合并 rects 使相邻的 rect 高度一致.
  • replace: (render: (textNode: Text) => Node | Element) => void;

    • 替换文本节点为新的节点.
    • 会执行 splitText 方法.
  • isPointInRange: (point: { x: number; y: number; }, expand?: number | [number, number]) => boolean;

    • 判断坐标是否在 Range 内.
    • expand: DOMRect 扩展区域. 默认值: 0.
  • isIntersecting: (threshold?: number) => boolean;

    • 判断 range 是否在可视区域内.
    • threshold: 目标元素与视窗重叠的阈值(0~1)
  • replaceNodes: (render: (textNodes: Text[]) => Node | Element | void) => void;

    • 如果是相邻的文本节点则合并到新节点中.
  • text: () => string;

    • range.toString().
  • textNodes: () => Text[];

    • 返回所有的非空文本节点.
  • trimTextNode: () => Text[];

    • 返回除掉首尾的所有非空文本节点.
  • rect: () => DOMRect;

    • Range.getBoundingClientRect().
  • splitText: () => void;

    • 根据 startOffset endOffset 裁剪掉首尾的文本节点.
  • export: () => RangeData;

    • 导出数据.
    • ⚠️ 裁剪文本节点(splitText)后, 导出的数据是没办法还原的.
  • update:() => void;

    • 更新 range.

静态方法

  • create: (config: RangeData, root?: Element) => TextRange;
    • 根据数据创建 TextRange.
  • createRange: (config: RangeData, root?: Element) => Range.
    • 根据数据创建 Range.
  • getPath: (textNode: Node, root: Element) => Path;
    • 生成节点的路径.
  • getNodeByPath(path: number[], root: Element) => void;
    • 根据路径, 获取对应的节点.