From 24cbe068356b321f296616082b86e4a189aca8a6 Mon Sep 17 00:00:00 2001 From: nick-delirium Date: Fri, 10 Feb 2023 15:28:14 +0100 Subject: [PATCH] change(player): add focus event to player --- .../app/player/web/managers/DOM/DOMManager.ts | 32 ++++++++------- .../web/managers/DOM/SelectionManager.ts | 39 +++++++++++++++++++ tracker/tracker/src/main/modules/selection.ts | 2 +- 3 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 frontend/app/player/web/managers/DOM/SelectionManager.ts diff --git a/frontend/app/player/web/managers/DOM/DOMManager.ts b/frontend/app/player/web/managers/DOM/DOMManager.ts index 2bd7a6c0c..efdc29a8e 100644 --- a/frontend/app/player/web/managers/DOM/DOMManager.ts +++ b/frontend/app/player/web/managers/DOM/DOMManager.ts @@ -2,25 +2,24 @@ import logger from 'App/logger'; import type Screen from '../../Screen/Screen'; import type { Message, SetNodeScroll } from '../../messages'; - import { MType } from '../../messages'; import ListWalker from '../../../common/ListWalker'; import StylesManager, { rewriteNodeStyleSheet } from './StylesManager'; import FocusManager from './FocusManager'; -import { - VElement, - VText, - VShadowRoot, - VDocument, - VNode, - VStyleElement, - PostponedStyleSheet, -} from './VirtualDOM'; +import SelectionManager from './SelectionManager'; import type { StyleElement } from './VirtualDOM'; -import { insertRule, deleteRule } from './safeCSSRules'; +import { + PostponedStyleSheet, + VDocument, + VElement, + VNode, + VShadowRoot, + VStyleElement, + VText, +} from './VirtualDOM'; +import { deleteRule, insertRule } from './safeCSSRules'; - -type HTMLElementWithValue = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement +type HTMLElementWithValue = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement; const IGNORED_ATTRS = [ "autocomplete" ]; const ATTR_NAME_REGEXP = /([^\t\n\f \/>"'=]+)/; // regexp costs ~ @@ -50,7 +49,7 @@ export default class DOMManager extends ListWalker { private nodeScrollManagers: Map> = new Map() private stylesManager: StylesManager private focusManager: FocusManager = new FocusManager(this.vElements) - + private selectionManager: SelectionManager = new SelectionManager(this.vElements) constructor( private readonly screen: Screen, @@ -76,6 +75,10 @@ export default class DOMManager extends ListWalker { this.focusManager.append(m) return } + if (m.tp === MType.SelectionChange) { + this.selectionManager.append(m) + return + } if (m.tp === MType.CreateElementNode) { if(m.tag === "BODY" && this.upperBodyId === -1) { this.upperBodyId = m.id @@ -432,6 +435,7 @@ export default class DOMManager extends ListWalker { return this.stylesManager.moveReady(t).then(() => { // Apply focus this.focusManager.move(t) + this.selectionManager.move(t) // Apply all scrolls after the styles got applied this.nodeScrollManagers.forEach(manager => { const msg = manager.moveGetLast(t) diff --git a/frontend/app/player/web/managers/DOM/SelectionManager.ts b/frontend/app/player/web/managers/DOM/SelectionManager.ts new file mode 100644 index 000000000..f073b7567 --- /dev/null +++ b/frontend/app/player/web/managers/DOM/SelectionManager.ts @@ -0,0 +1,39 @@ +import type { SelectionChange } from '../../messages' +import type { VElement} from "./VirtualDOM"; +import ListWalker from '../../../common/ListWalker'; + +const SELECTION_CLASS = { start: "-openreplay-selection-start", end: "-openreplay-selection-end" } + + +export default class SelectionManager extends ListWalker { + constructor(private readonly vElements: Map) { + super(); + } + + private selected: [Element | null, Element | null] = [null, null] + + move(t: number) { + const msg = this.moveGetLast(t) + if (!msg) { return } + console.log(msg) + if (msg.selectionStart <= 0) { + this.selected[0]?.classList.remove(SELECTION_CLASS.start) + this.selected[0].style.border = 'unset' + this.selected[1]?.classList.remove(SELECTION_CLASS.end) + this.selected = [null, null] + return; + } + const startVNode = this.vElements.get(msg.selectionStart -1) + const endVNode = this.vElements.get(msg.selectionEnd -1) + + console.log(startVNode, endVNode, this.vElements) + + if (startVNode && endVNode) { + this.selected = [startVNode.node, endVNode.node] + + this.selected[0]?.classList.add(SELECTION_CLASS.start) + this.selected[0].style.border = '5px solid red' + this.selected[1]?.classList.add(SELECTION_CLASS.end) + } + } +} \ No newline at end of file diff --git a/tracker/tracker/src/main/modules/selection.ts b/tracker/tracker/src/main/modules/selection.ts index cd7004c44..8a422fedc 100644 --- a/tracker/tracker/src/main/modules/selection.ts +++ b/tracker/tracker/src/main/modules/selection.ts @@ -12,7 +12,7 @@ function selection(app: App) { app.send(SelectionChange(selectionStart, selectionEnd, selectedText)) } } else { - app.send(SelectionChange(0, 0, '')) + app.send(SelectionChange(-1, -1, '')) } }) }