From 470f762a14771774da0f7fa56fbc8c070ca12d84 Mon Sep 17 00:00:00 2001 From: Raunak Raj <71929976+bajrangCoder@users.noreply.github.com> Date: Sun, 5 Jul 2026 10:36:29 +0530 Subject: [PATCH 1/2] fix(editor): prevent styling loss flash on custom page tabs when splitting/closing panes - Implement DOM reconciliation in renderPaneLayout to keep pane element detachment to a minimum. - Use adoptedStyleSheets inside Shadow DOM for type: "page" files to synchronously apply and retain main.css styles, avoiding FOUC when re-parenting. --- src/lib/editorFile.js | 34 +++++++++++++++++++++++++++++++++- src/lib/editorManager.js | 31 +++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/lib/editorFile.js b/src/lib/editorFile.js index 1c98fea5e..d92b9544c 100644 --- a/src/lib/editorFile.js +++ b/src/lib/editorFile.js @@ -29,6 +29,33 @@ import run from "./run"; import saveFile from "./saveFile"; import appSettings from "./settings"; +let mainCSSStyleSheet = null; + +function getMainCSSStyleSheet() { + if (mainCSSStyleSheet) return mainCSSStyleSheet; + if ( + typeof CSSStyleSheet === "undefined" || + !CSSStyleSheet.prototype.replaceSync + ) { + return null; + } + for (const sheet of document.styleSheets) { + if (sheet.href && sheet.href.endsWith("main.css")) { + try { + const cssText = Array.from(sheet.cssRules) + .map((rule) => rule.cssText) + .join("\n"); + mainCSSStyleSheet = new CSSStyleSheet(); + mainCSSStyleSheet.replaceSync(cssText); + return mainCSSStyleSheet; + } catch (e) { + console.warn("Failed to create CSSStyleSheet from main.css rules", e); + } + } + } + return null; +} + function syncQuickToolsVisibility(file) { const { $toggler } = quickTools; const hideForFile = !!file?.hideQuickTools; @@ -530,7 +557,12 @@ export default class EditorFile { shadow = container.attachShadow({ mode: "open" }); // Add base styles to shadow DOM first - shadow.appendChild(); + const sharedSheet = getMainCSSStyleSheet(); + if (sharedSheet) { + shadow.adoptedStyleSheets = [sharedSheet]; + } else { + shadow.appendChild(); + } // Handle custom stylesheets if provided if (options.stylesheets) { diff --git a/src/lib/editorManager.js b/src/lib/editorManager.js index 53384932a..3a12f6184 100644 --- a/src/lib/editorManager.js +++ b/src/lib/editorManager.js @@ -408,13 +408,36 @@ async function EditorManager($header, $body) { if (!node || node.type !== "split") return; node.element.dataset.direction = node.direction; - cleanupPaneSplitHandles(node.element); - node.element.replaceChildren(); + + const targetElements = []; node.children.forEach((child, index) => { if (index > 0) { - node.element.append(createPaneSplitHandle(node, index)); + targetElements.push(createPaneSplitHandle(node, index)); + } + targetElements.push(child.element); + }); + + cleanupPaneSplitHandles(node.element); + + const currentChildren = Array.from(node.element.children); + const targetSet = new Set(targetElements); + + currentChildren.forEach((childEl) => { + if (!targetSet.has(childEl)) { + childEl.remove(); } - node.element.append(child.element); + }); + + let currentEl = node.element.firstElementChild; + for (const targetEl of targetElements) { + if (currentEl === targetEl) { + currentEl = currentEl.nextElementSibling; + } else { + node.element.insertBefore(targetEl, currentEl); + } + } + + node.children.forEach((child) => { renderPaneLayout(child); }); } From efdae01ddf7dfffbd3dc1bd9b250987478bce16c Mon Sep 17 00:00:00 2001 From: Raunak Raj <71929976+bajrangCoder@users.noreply.github.com> Date: Sun, 5 Jul 2026 10:50:34 +0530 Subject: [PATCH 2/2] fix issue --- src/lib/editorFile.js | 52 ++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/src/lib/editorFile.js b/src/lib/editorFile.js index d92b9544c..c59127d03 100644 --- a/src/lib/editorFile.js +++ b/src/lib/editorFile.js @@ -33,24 +33,9 @@ let mainCSSStyleSheet = null; function getMainCSSStyleSheet() { if (mainCSSStyleSheet) return mainCSSStyleSheet; - if ( - typeof CSSStyleSheet === "undefined" || - !CSSStyleSheet.prototype.replaceSync - ) { - return null; - } for (const sheet of document.styleSheets) { if (sheet.href && sheet.href.endsWith("main.css")) { - try { - const cssText = Array.from(sheet.cssRules) - .map((rule) => rule.cssText) - .join("\n"); - mainCSSStyleSheet = new CSSStyleSheet(); - mainCSSStyleSheet.replaceSync(cssText); - return mainCSSStyleSheet; - } catch (e) { - console.warn("Failed to create CSSStyleSheet from main.css rules", e); - } + return sheet; } } return null; @@ -558,9 +543,40 @@ export default class EditorFile { // Add base styles to shadow DOM first const sharedSheet = getMainCSSStyleSheet(); + let adopted = false; if (sharedSheet) { - shadow.adoptedStyleSheets = [sharedSheet]; - } else { + try { + shadow.adoptedStyleSheets = [sharedSheet]; + adopted = true; + } catch (e) { + console.warn( + "Failed to adopt document stylesheet, attempting constructed fallback", + e, + ); + if ( + typeof CSSStyleSheet !== "undefined" && + CSSStyleSheet.prototype.replaceSync + ) { + try { + const cssText = Array.from(sharedSheet.cssRules) + .map((rule) => rule.cssText) + .join("\n"); + const constructedSheet = new CSSStyleSheet(); + constructedSheet.replaceSync(cssText); + shadow.adoptedStyleSheets = [constructedSheet]; + adopted = true; + mainCSSStyleSheet = constructedSheet; + } catch (innerError) { + console.warn( + "Failed constructed stylesheet fallback", + innerError, + ); + } + } + } + } + + if (!adopted) { shadow.appendChild(); }