From 7b23e96a616199b60d3c287a3dcd4602a266861c Mon Sep 17 00:00:00 2001 From: garrettmills Date: Sat, 2 Jan 2021 21:55:58 -0600 Subject: [PATCH] update wysiwyg to start positioning remote carets more accurately --- .../components/wysiwyg/wysiwyg.component.scss | 3 +- .../components/wysiwyg/wysiwyg.component.ts | 29 ++++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/app/components/wysiwyg/wysiwyg.component.scss b/src/app/components/wysiwyg/wysiwyg.component.scss index 1403d3d..0ba9242 100644 --- a/src/app/components/wysiwyg/wysiwyg.component.scss +++ b/src/app/components/wysiwyg/wysiwyg.component.scss @@ -64,7 +64,8 @@ .remote-cursor { min-height: 20px; width: 3px; - position: absolute; + //position: absolute; + position: fixed; } } diff --git a/src/app/components/wysiwyg/wysiwyg.component.ts b/src/app/components/wysiwyg/wysiwyg.component.ts index f51cf8a..4118577 100644 --- a/src/app/components/wysiwyg/wysiwyg.component.ts +++ b/src/app/components/wysiwyg/wysiwyg.component.ts @@ -117,7 +117,7 @@ export class WysiwygComponent implements OnInit { } const parts = path.split('.') - .map(x => x.split('#')) + .map(x => x.split('@')) .map(([tagName, idxString]) => [tagName, Number(idxString)]); let currentElem = this.editable.nativeElement; @@ -127,7 +127,7 @@ export class WysiwygComponent implements OnInit { } const [tagName, idx] = part; - const children = [...currentElem.getElementsByTagName(tagName)]; + const children = [...(tagName === '#text' ? currentElem.childNodes : currentElem.getElementsByTagName(tagName))]; currentElem = children[idx]; } @@ -139,9 +139,11 @@ export class WysiwygComponent implements OnInit { throw new Error('Cannot get path to element unless editable.'); } + debug('getPathToElement', elem); + const maxNest = 5000; let currentNest = 0; - const parents = []; + const parents = [elem]; let currentParent = elem; do { @@ -159,7 +161,9 @@ export class WysiwygComponent implements OnInit { return parents.reverse() .slice(1) .map((element, idx) => { - const siblings = element.parentElement.getElementsByTagName(element.tagName); + const siblings = element.tagName ? element.parentElement.getElementsByTagName(element.tagName) + : element.parentElement.childNodes; + let siblingIdx = -1; [...siblings].some((sibling, potentialIdx) => { if ( sibling === element ) { @@ -168,7 +172,7 @@ export class WysiwygComponent implements OnInit { } }); - return `${element.tagName}#${siblingIdx}`; + return `${element.tagName || '#text'}@${siblingIdx}`; }) .join('.'); } @@ -176,8 +180,19 @@ export class WysiwygComponent implements OnInit { processSelections() { for ( const sel of this.privEditingUserSelections ) { sel.element = this.getElementFromPath(sel.path); - sel.top = sel.element.offsetTop; - sel.left = sel.element.offsetLeft; + if ( sel.element ) { + sel.top = sel.element.offsetTop; + sel.left = sel.element.offsetLeft; + + const range = document.createRange(); + range.setStart(sel.element, sel.offset); + range.setEnd(sel.element, sel.offset); + + const rect = range.getClientRects()[0]; + sel.top = rect.top; + sel.left = rect.left; + } + console.log({sel, editable: this.editable}); } }