diff --git a/frontend/app/player/MessageDistributor/managers/DOM/DOMManager.ts b/frontend/app/player/MessageDistributor/managers/DOM/DOMManager.ts index 278e97ba4..924333eea 100644 --- a/frontend/app/player/MessageDistributor/managers/DOM/DOMManager.ts +++ b/frontend/app/player/MessageDistributor/managers/DOM/DOMManager.ts @@ -15,45 +15,45 @@ const IGNORED_ATTRS = [ "autocomplete", "name" ]; const ATTR_NAME_REGEXP = /([^\t\n\f \/>"'=]+)/; // regexp costs ~ export default class DOMManager extends ListWalker { - private isMobile: boolean; - private screen: StatedScreen; private vTexts: Map = new Map() // map vs object here? private vElements: Map = new Map() private vRoots: Map = new Map() private upperBodyId: number = -1; - private nodeScrollManagers: Array> = [] + private nodeScrollManagers: Map> = new Map() private stylesManager: StylesManager - constructor(screen: StatedScreen, isMobile: boolean, public readonly time: number) { - super(); - this.isMobile = isMobile; - this.screen = screen; - this.stylesManager = new StylesManager(screen); + constructor( + private readonly screen: StatedScreen, + private readonly isMobile: boolean, + public readonly time: number + ) { + super() + this.stylesManager = new StylesManager(screen) } append(m: Message): void { - switch (m.tp) { - case "set_node_scroll": - if (!this.nodeScrollManagers[ m.id ]) { - this.nodeScrollManagers[ m.id ] = new ListWalker(); + if (m.tp === "set_node_scroll") { + let scrollManager = this.nodeScrollManagers.get(m.id) + if (!scrollManager) { + scrollManager = new ListWalker() + this.nodeScrollManagers.set(m.id, scrollManager) } - this.nodeScrollManagers[ m.id ].append(m); - return; - default: - if (m.tp === "create_element_node") { - if(m.tag === "BODY" && this.upperBodyId === -1) { - this.upperBodyId = m.id - } - } else if (m.tp === "set_node_attribute" && - (IGNORED_ATTRS.includes(m.name) || !ATTR_NAME_REGEXP.test(m.name))) { - logger.log("Ignorring message: ", m) - return; // Ignoring - } - super.append(m); + scrollManager.append(m) + return } + if (m.tp === "create_element_node") { + if(m.tag === "BODY" && this.upperBodyId === -1) { + this.upperBodyId = m.id + } + } else if (m.tp === "set_node_attribute" && + (IGNORED_ATTRS.includes(m.name) || !ATTR_NAME_REGEXP.test(m.name))) { + logger.log("Ignorring message: ", m) + return; // Ignoring + } + super.append(m) } private removeBodyScroll(id: number, vn: VElement): void { @@ -160,9 +160,9 @@ export default class DOMManager extends ListWalker { if (!vn) { logger.error("Node not found", msg); return } if (name === "href" && vn.node.tagName === "LINK") { // @ts-ignore TODO: global ENV type // Hack for queries in rewrited urls (don't we do that in backend?) - if (value.startsWith(window.env.ASSETS_HOST || window.location.origin + '/assets')) { - value = value.replace("?", "%3F"); - } + // if (value.startsWith(window.env.ASSETS_HOST || window.location.origin + '/assets')) { + // value = value.replace("?", "%3F"); + // } this.stylesManager.setStyleHandlers(vn.node as HTMLLinkElement, value); } if (vn.node.namespaceURI === 'http://www.w3.org/2000/svg' && value.startsWith("url(")) { @@ -236,7 +236,7 @@ export default class DOMManager extends ListWalker { vn = this.vElements.get(msg.id) if (!vn) { logger.error("Node not found", msg); return } if (!(vn instanceof VStyleElement)) { - logger.warn("Non-style node in CSS rules message (or sheet is null)", msg, node.sheet); + logger.warn("Non-style node in CSS rules message (or sheet is null)", msg, vn); return } vn.onStyleSheet(sheet => { diff --git a/frontend/app/player/MessageDistributor/managers/DOM/StylesManager.ts b/frontend/app/player/MessageDistributor/managers/DOM/StylesManager.ts index 14a2ee8a4..c6b674c4e 100644 --- a/frontend/app/player/MessageDistributor/managers/DOM/StylesManager.ts +++ b/frontend/app/player/MessageDistributor/managers/DOM/StylesManager.ts @@ -41,20 +41,20 @@ export default class StylesManager extends ListWalker { setStyleHandlers(node: HTMLLinkElement, value: string): void { let timeoutId: ReturnType | undefined; - const promise = new Promise((resolve) => { - if (this.skipCSSLinks.includes(value)) resolve(null); + const promise = new Promise((resolve) => { + if (this.skipCSSLinks.includes(value)) resolve(); this.linkLoadingCount++; this.screen.setCSSLoading(true); const addSkipAndResolve = () => { this.skipCSSLinks.push(value); // watch out - resolve(null); + resolve() } timeoutId = setTimeout(addSkipAndResolve, 4000); node.onload = () => { const doc = this.screen.document; doc && rewriteNodeStyleSheet(doc, node); - resolve(null); + resolve(); } node.onerror = addSkipAndResolve; }).then(() => { diff --git a/frontend/app/player/MessageDistributor/managers/DOM/VirtualDOM.ts b/frontend/app/player/MessageDistributor/managers/DOM/VirtualDOM.ts index 3df1b5a3e..12009c21c 100644 --- a/frontend/app/player/MessageDistributor/managers/DOM/VirtualDOM.ts +++ b/frontend/app/player/MessageDistributor/managers/DOM/VirtualDOM.ts @@ -65,18 +65,18 @@ export class VFragment extends VParent { export class VElement extends VParent { parentNode: VParent | null = null - private newAttributes: Record = {} + private newAttributes: Map = new Map() //private props: Record constructor(public readonly node: Element) { super() } setAttribute(name: string, value: string) { - this.newAttributes[name] = value + this.newAttributes.set(name, value) } removeAttribute(name: string) { - this.newAttributes[name] = false + this.newAttributes.set(name, false) } applyChanges() { - Object.entries(this.newAttributes).forEach(([key, value]) => { + this.newAttributes.forEach((value, key) => { if (value === false) { this.node.removeAttribute(key) } else { @@ -87,7 +87,7 @@ export class VElement extends VParent { } } }) - this.newAttributes = {} + this.newAttributes.clear() super.applyChanges() } }