Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: usage of root node for getting window or shadow root #1064

Merged
merged 9 commits into from
Jul 4, 2022
51 changes: 33 additions & 18 deletions packages/shared/src/lib/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,43 @@ type Row = number;
export type CaretOffset = [number, number];
export type CaretPosition = [Column, Row];

interface ShadowCompanion extends ShadowRoot {
getSelection: typeof window.getSelection;
}

const isFirefox = process.env.TARGET_BROWSER === 'firefox';
const isExtension = !!process.env.TARGET_BROWSER;

const getShadowDom = (ownerDocument = false): Document => {
if (!isExtension) {
return null;
const getRoot = (node: Node) => {
const root = node.getRootNode();

if (root instanceof ShadowRoot) {
return isFirefox ? root.ownerDocument : (root as ShadowCompanion);
}

const companion = document.querySelector('daily-companion-app');
if (root instanceof Window) {
return isFirefox ? window.document : window;
}

return root as Document;
};

const getRootDom = (node: Node): Document => {
const root = getRoot(node);

if (!companion) {
return null;
if (root instanceof Document) {
return root;
}

if (!isFirefox && !ownerDocument) {
return companion.shadowRoot as unknown as Document;
if (root instanceof Window) {
return root.document;
}

return companion.shadowRoot.ownerDocument;
return root.ownerDocument;
};

export function getCaretPostition(el: Element): CaretPosition {
const dom = getShadowDom() || window;
const sel = dom.getSelection();
const root = getRoot(el);
const sel = root.getSelection();
let row = 0;
for (; row < el.childNodes.length; row += 1) {
const child = el.childNodes[row];
Expand Down Expand Up @@ -101,11 +114,13 @@ const getNodeText = (node: Node) => {
return string.replaceAll('\xa0', ' ');
};

export function setCaretPosition(el: Node, col: number): void {
const range = (getShadowDom(true) || document).createRange();
const sel = (getShadowDom() || window).getSelection();
export function setCaretPosition(node: Node, col: number): void {
const root = getRoot(node);
const dom = getRootDom(node);
const range = dom.createRange();
const sel = root.getSelection();

range.setStart(el, col);
range.setStart(node, col);
range.collapse(true);

sel.removeAllRanges();
Expand All @@ -130,8 +145,8 @@ export const getSplittedText = (
[col, row]: CaretPosition,
query: string,
): [Node, string, string] => {
const companion = getShadowDom();
const offset = companion && isFirefox ? 0 : 1;
const isCompanion = getRoot(textarea) instanceof ShadowRoot;
const offset = isCompanion && isFirefox ? 0 : 1;
const node = Array.from(textarea.childNodes).find((_, i) => i === row);
const text = getNodeText(node);
const left = text?.substring(0, col - 1) || '';
Expand Down