ui: use slot name as target
This commit is contained in:
parent
9f4852bd38
commit
8b568ee027
2 changed files with 18 additions and 121 deletions
|
|
@ -9,7 +9,6 @@ import FocusManager from './FocusManager';
|
|||
import SelectionManager from './SelectionManager';
|
||||
import {
|
||||
StyleElement,
|
||||
VSpriteMap,
|
||||
OnloadStyleSheet,
|
||||
VDocument,
|
||||
VElement,
|
||||
|
|
@ -55,14 +54,12 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
*/
|
||||
private olStyleSheets: Map<number, OnloadStyleSheet> = new Map();
|
||||
/** @depreacted since tracker 4.0.2 Mapping by nodeID */
|
||||
private olStyleSheetsDeprecated: Map<number, OnloadStyleSheet> = new Map();
|
||||
private upperBodyId: number = -1;
|
||||
private nodeScrollManagers: Map<number, ListWalker<SetNodeScroll>> =
|
||||
new Map();
|
||||
private stylesManager: StylesManager;
|
||||
private focusManager: FocusManager = new FocusManager(this.vElements);
|
||||
private selectionManager: SelectionManager;
|
||||
private nodeSlots: Map<number, { slotID: number; host: any }> = new Map();
|
||||
private readonly screen: Screen;
|
||||
private readonly isMobile: boolean;
|
||||
private readonly stringDict: Record<number, string>;
|
||||
|
|
@ -72,7 +69,7 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
};
|
||||
public readonly time: number;
|
||||
private virtualMode = false;
|
||||
private hasSlots = false
|
||||
private hasSlots = false;
|
||||
private showVModeBadge?: () => void;
|
||||
|
||||
constructor(params: {
|
||||
|
|
@ -286,42 +283,26 @@ export default class DOMManager extends ListWalker<Message> {
|
|||
logger.error('SetNodeSlot: Node not found', msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.slotID > 0) {
|
||||
const slotElem = this.vElements.get(msg.slotID);
|
||||
if (!(slotElem instanceof VSlot)) {
|
||||
logger.error('SetNodeSlot: Slot not found', msg);
|
||||
return;
|
||||
}
|
||||
const host = vChild.parentNode;
|
||||
if (host && (vChild as any).assignedSlot !== slotElem) {
|
||||
if (vChild.node.parentNode === (host as any).node) {
|
||||
host.node.removeChild(vChild.node);
|
||||
|
||||
if (vChild instanceof VElement) {
|
||||
const slotName = (slotElem.node as HTMLSlotElement).name;
|
||||
if (slotName && slotName !== 'default') {
|
||||
vChild.setAttribute('slot', slotName);
|
||||
} else {
|
||||
// if el goes to default slot, we don't need attr
|
||||
vChild.removeAttribute('slot');
|
||||
}
|
||||
(host as any).notMontedChildren?.delete(vChild);
|
||||
slotElem.addAssigned(vChild);
|
||||
(vChild as any).assignedSlot = slotElem;
|
||||
this.nodeSlots.set(msg.id, { slotID: msg.slotID, host });
|
||||
}
|
||||
} else {
|
||||
if (vChild.assignedSlot) {
|
||||
const slotElem = vChild.assignedSlot as VSlot;
|
||||
slotElem.removeAssigned(vChild);
|
||||
if (vChild.parentNode) {
|
||||
const host = vChild.parentNode;
|
||||
const siblings = host['children'] as any[];
|
||||
const index = siblings.indexOf(vChild);
|
||||
let next: Node | null = null;
|
||||
for (let i = index + 1; i < siblings.length; i++) {
|
||||
const sib = siblings[i];
|
||||
if (!sib.assignedSlot) {
|
||||
next = sib.node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
host.node.insertBefore(vChild.node, next);
|
||||
}
|
||||
vChild.assignedSlot = null;
|
||||
this.nodeSlots.delete(msg.id);
|
||||
if (vChild instanceof VElement) {
|
||||
vChild.removeAttribute('slot');
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export abstract class VNode<T extends Node = Node> {
|
|||
public abstract applyChanges(): void;
|
||||
}
|
||||
|
||||
type VChild = VElement | VText | VSpriteMap;
|
||||
type VChild = VElement | VText;
|
||||
abstract class VParent<T extends Node = Node> extends VNode<T> {
|
||||
/**
|
||||
*/
|
||||
|
|
@ -163,46 +163,6 @@ export class VShadowRoot extends VParent<ShadowRoot> {
|
|||
|
||||
export type VRoot = VDocument | VShadowRoot;
|
||||
|
||||
export class VSpriteMap extends VParent<Element> {
|
||||
parentNode: VParent | null =
|
||||
null; /** Should be modified only by he parent itself */
|
||||
|
||||
private newAttributes: Map<string, string | false> = new Map();
|
||||
|
||||
constructor(
|
||||
readonly tagName: string,
|
||||
readonly isSVG = true,
|
||||
public readonly index: number,
|
||||
private readonly nodeId: number,
|
||||
) {
|
||||
super();
|
||||
this.createNode();
|
||||
}
|
||||
|
||||
protected createNode() {
|
||||
try {
|
||||
const element = document.createElementNS(
|
||||
'http://www.w3.org/2000/svg',
|
||||
this.tagName,
|
||||
);
|
||||
element.dataset.openreplayId = this.nodeId.toString();
|
||||
return element;
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'Openreplay: Player received invalid html tag',
|
||||
this.tagName,
|
||||
e,
|
||||
);
|
||||
return document.createElement(this.tagName.replace(/[^a-z]/gi, ''));
|
||||
}
|
||||
}
|
||||
|
||||
applyChanges() {
|
||||
// this is a hack to prevent the sprite map from being removed from the DOM
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export class VElement extends VParent<Element> {
|
||||
parentNode: VParent | null =
|
||||
null; /** Should be modified only by he parent itself */
|
||||
|
|
@ -298,58 +258,14 @@ export class VElement extends VParent<Element> {
|
|||
}
|
||||
|
||||
export class VSlot extends VElement {
|
||||
assignedNodes: VChild[] = [];
|
||||
|
||||
addAssigned(child: VChild) {
|
||||
if (this.assignedNodes.indexOf(child) === -1) {
|
||||
this.assignedNodes.push(child);
|
||||
this.notMontedChildren.add(child);
|
||||
}
|
||||
}
|
||||
|
||||
removeAssigned(child: VChild) {
|
||||
this.assignedNodes = this.assignedNodes.filter((c) => c !== child);
|
||||
this.notMontedChildren.delete(child);
|
||||
}
|
||||
|
||||
private mountAssigned() {
|
||||
let nextMounted: VChild | null = null;
|
||||
for (let i = this.assignedNodes.length - 1; i >= 0; i--) {
|
||||
const child = this.assignedNodes[i];
|
||||
if (this.notMontedChildren.has(child)) {
|
||||
this.node.insertBefore(
|
||||
child.node,
|
||||
nextMounted ? nextMounted.node : null,
|
||||
);
|
||||
this.notMontedChildren.delete(child);
|
||||
}
|
||||
if (!this.notMontedChildren.has(child)) {
|
||||
nextMounted = child;
|
||||
}
|
||||
}
|
||||
protected createNode() {
|
||||
const element = super.createNode() as HTMLSlotElement;
|
||||
return element;
|
||||
}
|
||||
|
||||
applyChanges() {
|
||||
if (this.assignedNodes.length > 0) {
|
||||
this.assignedNodes.forEach((c) => c.applyChanges());
|
||||
this.mountAssigned();
|
||||
const { node } = this;
|
||||
const realChildren = node.childNodes;
|
||||
if (realChildren.length > 0) {
|
||||
for (let j = 0; j < this.assignedNodes.length; j++) {
|
||||
while (realChildren[j] !== this.assignedNodes[j].node) {
|
||||
if (isNode(realChildren[j])) {
|
||||
node.removeChild(realChildren[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (realChildren.length > this.assignedNodes.length) {
|
||||
node.removeChild(node.lastChild as Node);
|
||||
}
|
||||
} else {
|
||||
super.applyChanges();
|
||||
}
|
||||
super.applyChanges();
|
||||
// todo safety checks here ?
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue