Skip to content

Update splittext plan with CSS, a11y, SEO, BiDi, nesting, and line detection amendments#132

Merged
tombigel merged 19 commits intomasterfrom
tombigel/splittext-plan-revisions
Apr 28, 2026
Merged

Update splittext plan with CSS, a11y, SEO, BiDi, nesting, and line detection amendments#132
tombigel merged 19 commits intomasterfrom
tombigel/splittext-plan-revisions

Conversation

@tombigel
Copy link
Copy Markdown
Contributor

  • Add base CSS strategy (injectStyles, space handling, direction detection)
  • Simplify ARIA to container-level only
  • Add SEO strategy with preserveText visually-hidden duplicate
  • Add BiDi/shaping injection options (bidiResolver, shaper)
  • Add nested option (flatten/preserve/depth) for DOM structure control
  • Make line detection opt-in and note binary-search algorithm improvement
  • Add Safari whitespace normalization test results and Playwright test case

…tection amendments

- Add base CSS strategy (injectStyles, space handling, direction detection)
- Simplify ARIA to container-level only
- Add SEO strategy with preserveText visually-hidden duplicate
- Add BiDi/shaping injection options (bidiResolver, shaper)
- Add nested option (flatten/preserve/depth) for DOM structure control
- Make line detection opt-in and note binary-search algorithm improvement
- Add Safari whitespace normalization test results and Playwright test case

Co-authored-by: Cursor <[email protected]>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the SplitText package implementation plan to incorporate new strategies for base CSS injection, accessibility/SEO handling, BiDi/shaping extensibility, nested DOM handling, and opt-in line detection (including Safari/WebKit whitespace quirks and a Playwright test case).

Changes:

  • Makes line detection explicitly opt-in and documents a more efficient binary-search-based approach.
  • Adds plan-level API/options for CSS injection, preserveText for SEO/a11y, nested DOM handling, and BiDi/shaping injection points.
  • Expands testing/documentation sections (Safari whitespace normalization notes + Playwright test case, wrapper/CSS guidance).
Comments suppressed due to low confidence (1)

.cursor/plans/text_splitter_package_1eeee927.plan.md:850

  • SplitTextResult is typed as returning HTMLSpanElement[], but the implementation sketch (cache + getters + _performSplit) uses HTMLElement[]. This should be consistent (ideally HTMLSpanElement[] everywhere, since wrappers are spans), otherwise the public API typing and internals will diverge.
  private _cache: {
    chars?: HTMLElement[];
    words?: HTMLElement[];
    lines?: HTMLElement[];
    sentences?: HTMLElement[];
  } = {};

  constructor(element: HTMLElement, options?: SplitTextOptions) {
    this._element = element;
    this._originalHTML = element.innerHTML;

    // Eager split if type is provided; track whether 'lines' was requested (lines are opt-in and expensive)
    this._linesRequested = false;
    if (options?.type) {
      const types = Array.isArray(options.type) ? options.type : [options.type];
      this._linesRequested = types.includes('lines');
      for (const type of types) {
        this._performSplit(type);
      }
    }
  }

  // Lazy getter - split on first access, return cached thereafter
  get chars(): HTMLElement[] {
    if (!this._cache.chars) {
      this._cache.chars = this._performSplit('chars');
    }
    return this._cache.chars;
  }

  get words(): HTMLElement[] {
    if (!this._cache.words) {
      this._cache.words = this._performSplit('words');
    }
    return this._cache.words;
  }

  get lines(): HTMLElement[] {
    if (!this._linesRequested) return []; // or throw with message: "Lines not requested; pass type: 'lines' or type: [..., 'lines']"
    if (!this._cache.lines) {
      this._cache.lines = this._performSplit('lines');
    }
    return this._cache.lines;
  }

  get sentences(): HTMLElement[] {
    if (!this._cache.sentences) {
      this._cache.sentences = this._performSplit('sentences');
    }
    return this._cache.sentences;
  }

  private _performSplit(type: 'chars' | 'words' | 'lines' | 'sentences'): HTMLElement[] {
    // Actual splitting logic - creates wrapper elements in DOM
    // Returns array of created HTMLElements
  }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 20 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
tombigel and others added 2 commits February 24, 2026 11:39
…requirements

- Fix revert() prose, test locator, _handleResize options, remove splitBy/preserveWhitespace
- Add Intl.Segmenter browser requirement + polyfill note
- BiDi: external plugin API; remove shaper; shaped-languages note
- Line detection: binary search pseudocode, naive example, heightTracker fix
- Nested: clarify flatten deeper than N with example
- Minor: aria inner div, line detection string[] note, numbered lists, Prettier

Co-authored-by: Cursor <[email protected]>
@tombigel tombigel requested a review from ameerabuf February 27, 2026 18:28
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
- Remove lines opt-in special-casing; .lines is now lazy like all other getters
- Add display: contents to aria-hidden wrapper div to prevent layout breakage
- Remove redundant .split-space class (base CSS handles space preservation)
- Assert withoutNorm in Safari whitespace test
- Add Segmenter Polyfill API section with contract and compatible polyfills
- Trim repetitive integration examples and redundant code subsections
- Tag all code snippets with target file paths

Made-with: Cursor
@tombigel tombigel requested review from ameerabuf and ydaniv March 3, 2026 14:35
Copy link
Copy Markdown
Collaborator

@ydaniv ydaniv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed until Line Detection Algorithm

Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
…, fix gaps

- Remove untested binary search line detection; restore Ben Nadel's proven
  getClientRects() approach as primary algorithm
- Remove redundant cross-reference line, stale binary-search perf note
- Simplify Base CSS section (static predefined stylesheet, less prescriptive)
- Add .sr-only to base CSS required styles
- Fix broken markdown formatting on SplitTextResultImpl heading
- Remove orphaned masking todo (no plan section existed)
- Remove redundant range.selectNodeContents line in height-tracking code
- Fix markdown lint warnings (double blank lines)

Made-with: Cursor
@tombigel tombigel requested a review from ydaniv March 11, 2026 14:29
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md
…code, trim verbosity

- Remove injectStyles from per-split options; CSS now injected globally via adoptedStyleSheets
- Add partIndexing option with --char-index/--word-index/--line-index/--sentence-index CSS custom properties
- Restore original detectLines() function code (reverts compact description per reviewer request)
- Remove height-tracking alternative from line detection section
- Trim verbose Intl.Segmenter section and remove redundant code examples
- Restore lazy/eager integration examples that explain core API behavior
- Update doc references from data-index to CSS custom property indexing

Made-with: Cursor
@tombigel tombigel requested a review from ydaniv March 12, 2026 12:35
Copy link
Copy Markdown
Collaborator

@ydaniv ydaniv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tombigel did another round.
I think we're getting very close! Let's wrap this up.
Before we run "build" I think we I'll extract a spec doc that we can review and have that be our source-of-truth.

Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
Comment thread .cursor/plans/text_splitter_package_1eeee927.plan.md Outdated
@tombigel tombigel requested a review from ydaniv April 28, 2026 09:35
- **wrapperStyle (per-type)**: Verify different styles for chars vs words vs lines
- **wrapperAttrs**: Verify custom data attributes and other attributes applied
- **data-index attribute**: Verify each wrapper has correct index for animation sequencing
- **contentAttribute**: Verify char/word wrappers support `data-content` modes (`none`, `both`, `attribute-only`)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why verify "support"? This is for actual tests. Should probably test rendering.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@tombigel tombigel requested a review from ydaniv April 28, 2026 12:09
ydaniv
ydaniv previously approved these changes Apr 28, 2026
@tombigel tombigel requested a review from ydaniv April 28, 2026 12:51
@tombigel tombigel enabled auto-merge (squash) April 28, 2026 12:51
@tombigel tombigel merged commit e00d803 into master Apr 28, 2026
1 of 2 checks passed
@tombigel tombigel deleted the tombigel/splittext-plan-revisions branch April 28, 2026 13:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants