diff --git a/src/vs/base/browser/domStylesheets.ts b/src/vs/base/browser/domStylesheets.ts index 76a71c5402dd0..feb3aeba8d7cd 100644 --- a/src/vs/base/browser/domStylesheets.ts +++ b/src/vs/base/browser/domStylesheets.ts @@ -5,6 +5,7 @@ import { DisposableStore, toDisposable, IDisposable } from '../common/lifecycle.js'; import { autorun, IObservable } from '../common/observable.js'; +import { isFirefox } from './browser.js'; import { getWindows, sharedMutationObserver } from './dom.js'; import { mainWindow } from './window.js'; @@ -97,7 +98,15 @@ function cloneGlobalStyleSheet(globalStylesheet: HTMLStyleElement, globalStylesh clone.sheet?.insertRule(rule.cssText, clone.sheet?.cssRules.length); } - disposables.add(sharedMutationObserver.observe(globalStylesheet, disposables, { childList: true })(() => { + let observeInit: MutationObserverInit = { childList: true }; + if (isFirefox) { + // Firefox doesn't support observing style tag contents + // As a workaround, also observe the data-version attribute + // that is updated when the content is updated + observeInit = { ...observeInit, attributes: true, attributeFilter: ['data-version'] }; + } + + disposables.add(sharedMutationObserver.observe(globalStylesheet, disposables, observeInit)(() => { clone.textContent = globalStylesheet.textContent; })); diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index d85b23015f45c..972e265195504 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -33,7 +33,7 @@ import { updateColorThemeConfigurationSchemas, updateFileIconThemeConfigurationS import { ProductIconThemeData, DEFAULT_PRODUCT_ICON_THEME_ID } from './productIconThemeData.js'; import { registerProductIconThemeSchemas } from '../common/productIconThemeSchema.js'; import { ILogService } from '../../../../platform/log/common/log.js'; -import { isWeb } from '../../../../base/common/platform.js'; +import { isFirefox, isWeb } from '../../../../base/common/platform.js'; import { ColorScheme, ThemeTypeSelector } from '../../../../platform/theme/common/theme.js'; import { IHostColorSchemeService } from '../common/hostColorSchemeService.js'; import { RunOnceScheduler, Sequencer } from '../../../../base/common/async.js'; @@ -42,6 +42,7 @@ import { getIconsStyleSheet } from '../../../../platform/theme/browser/iconsStyl import { asCssVariableName, getColorRegistry } from '../../../../platform/theme/common/colorRegistry.js'; import { ILanguageService } from '../../../../editor/common/languages/language.js'; import { mainWindow } from '../../../../base/browser/window.js'; +import { generateUuid } from '../../../../base/common/uuid.js'; // implementation @@ -793,13 +794,21 @@ class ThemeFileWatcher { } function _applyRules(styleSheetContent: string, rulesClassName: string) { - const themeStyles = mainWindow.document.head.getElementsByClassName(rulesClassName); - if (themeStyles.length === 0) { - const elStyle = createStyleSheet(); - elStyle.className = rulesClassName; - elStyle.textContent = styleSheetContent; - } else { - (themeStyles[0]).textContent = styleSheetContent; + let themeStyle = mainWindow.document.head.getElementsByClassName(rulesClassName).item(0); + if (!themeStyle) { + themeStyle = createStyleSheet(); + themeStyle.className = rulesClassName; + } + + if (themeStyle.textContent !== styleSheetContent) { + themeStyle.textContent = styleSheetContent; + + if (isFirefox) { + // Firefox doesn't support observing style tag contents + // As a workaround, also update the data-version attribute + // when it changes so it can be observed + themeStyle.setAttribute('data-version', generateUuid()); + } } }