aboutsummaryrefslogtreecommitdiffstats
path: root/packages/excalidraw/element/elementLink.ts
blob: 991f9caec77aa4e01ab1af97a218dca2abf77ed2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/**
 * Create and link between shapes.
 */

import { ELEMENT_LINK_KEY } from "../constants";
import { normalizeLink } from "../data/url";
import { elementsAreInSameGroup } from "../groups";
import type { AppProps, AppState } from "../types";
import type { ExcalidrawElement } from "./types";

export const defaultGetElementLinkFromSelection: Exclude<
  AppProps["generateLinkForSelection"],
  undefined
> = (id, type) => {
  const url = window.location.href;

  try {
    const link = new URL(url);
    link.searchParams.set(ELEMENT_LINK_KEY, id);

    return normalizeLink(link.toString());
  } catch (error) {
    console.error(error);
  }

  return normalizeLink(url);
};

export const getLinkIdAndTypeFromSelection = (
  selectedElements: ExcalidrawElement[],
  appState: AppState,
): {
  id: string;
  type: "element" | "group";
} | null => {
  if (
    selectedElements.length > 0 &&
    canCreateLinkFromElements(selectedElements)
  ) {
    if (selectedElements.length === 1) {
      return {
        id: selectedElements[0].id,
        type: "element",
      };
    }

    if (selectedElements.length > 1) {
      const selectedGroupId = Object.keys(appState.selectedGroupIds)[0];

      if (selectedGroupId) {
        return {
          id: selectedGroupId,
          type: "group",
        };
      }
      return {
        id: selectedElements[0].groupIds[0],
        type: "group",
      };
    }
  }

  return null;
};

export const canCreateLinkFromElements = (
  selectedElements: ExcalidrawElement[],
) => {
  if (selectedElements.length === 1) {
    return true;
  }

  if (selectedElements.length > 1 && elementsAreInSameGroup(selectedElements)) {
    return true;
  }

  return false;
};

export const isElementLink = (url: string) => {
  try {
    const _url = new URL(url);
    return (
      _url.searchParams.has(ELEMENT_LINK_KEY) &&
      _url.host === window.location.host
    );
  } catch (error) {
    return false;
  }
};

export const parseElementLinkFromURL = (url: string) => {
  try {
    const { searchParams } = new URL(url);
    if (searchParams.has(ELEMENT_LINK_KEY)) {
      const id = searchParams.get(ELEMENT_LINK_KEY);
      return id;
    }
  } catch {}

  return null;
};