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();
}