• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

keplergl / kepler.gl / 25830234009

13 May 2026 10:31PM UTC coverage: 57.668% (-1.0%) from 58.644%
25830234009

Pull #3434

github

web-flow
Merge b10a56eba into b4790f0f5
Pull Request #3434: feat: basic annotations

7143 of 14848 branches covered (48.11%)

Branch coverage included in aggregate %.

216 of 732 new or added lines in 25 files covered. (29.51%)

74 existing lines in 3 files now uncovered.

14551 of 22771 relevant lines covered (63.9%)

77.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/components/src/annotations/lexical-editor/lexical-utils.ts
1
// SPDX-License-Identifier: MIT
2
// Copyright contributors to the kepler.gl project
3

4
import {$isAtNodeEnd} from '@lexical/selection';
5
import {ElementNode, LexicalEditor, RangeSelection, SerializedEditorState, TextNode} from 'lexical';
6

7
export function getSelectedNode(selection: RangeSelection): TextNode | ElementNode {
NEW
8
  const anchor = selection.anchor;
×
NEW
9
  const focus = selection.focus;
×
NEW
10
  const anchorNode = selection.anchor.getNode();
×
NEW
11
  const focusNode = selection.focus.getNode();
×
NEW
12
  if (anchorNode === focusNode) {
×
NEW
13
    return anchorNode;
×
14
  }
NEW
15
  const isBackward = selection.isBackward();
×
NEW
16
  if (isBackward) {
×
NEW
17
    return $isAtNodeEnd(focus) ? anchorNode : focusNode;
×
18
  } else {
NEW
19
    return $isAtNodeEnd(anchor) ? focusNode : anchorNode;
×
20
  }
21
}
22

23
export function updateEditorState(
24
  editor: LexicalEditor,
25
  editorState: SerializedEditorState | undefined
26
): void {
NEW
27
  try {
×
NEW
28
    if (editorState) {
×
NEW
29
      editor.setEditorState(editor.parseEditorState(editorState));
×
30
    }
31
  } catch (e) {
32
    // eslint-disable-next-line no-console
NEW
33
    console.error(e);
×
34
  }
35
}
36

37
export function sanitizeUrl(url: string): string {
NEW
38
  const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^&:/?#]*(?:[/?#]|$))/gi;
×
39
  const DATA_URL_PATTERN =
NEW
40
    /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;
×
41

NEW
42
  url = String(url).trim();
×
NEW
43
  if (url.match(SAFE_URL_PATTERN) || url.match(DATA_URL_PATTERN)) return url;
×
NEW
44
  return 'https://';
×
45
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc