From d195967b1b1d7d0fcee36a673a9055931f8ea12e Mon Sep 17 00:00:00 2001 From: telamonian Date: Thu, 22 Aug 2019 17:50:01 -0400 Subject: [PATCH] fixed `isToggled` param of 'apputils:theme-scrollbars' command `apputils-extension/src/index.ts` was getting crowded, so I also split out the theme plugins into their own source file --- packages/apputils-extension/src/index.ts | 242 +---------------- .../apputils-extension/src/themeplugins.ts | 252 ++++++++++++++++++ packages/apputils/src/thememanager.ts | 7 + 3 files changed, 264 insertions(+), 237 deletions(-) create mode 100644 packages/apputils-extension/src/themeplugins.ts diff --git a/packages/apputils-extension/src/index.ts b/packages/apputils-extension/src/index.ts index b897017d69a0..15c3115bb14c 100644 --- a/packages/apputils-extension/src/index.ts +++ b/packages/apputils-extension/src/index.ts @@ -14,9 +14,7 @@ import { Dialog, ICommandPalette, ISplashScreen, - IThemeManager, IWindowResolver, - ThemeManager, WindowResolver, Printing } from '@jupyterlab/apputils'; @@ -32,16 +30,14 @@ import { URLExt } from '@jupyterlab/coreutils'; -import { IMainMenu } from '@jupyterlab/mainmenu'; - import { PromiseDelegate } from '@phosphor/coreutils'; import { DisposableDelegate } from '@phosphor/disposable'; -import { Menu } from '@phosphor/widgets'; - import { Palette } from './palette'; +import { themesPlugin, themesPaletteMenuPlugin } from './themeplugins'; + /** * The interval in milliseconds before recover options appear during splash. */ @@ -51,14 +47,6 @@ const SPLASH_RECOVER_TIMEOUT = 12000; * The command IDs used by the apputils plugin. */ namespace CommandIDs { - export const changeTheme = 'apputils:change-theme'; - - export const themeScrollbars = 'apputils:theme-scrollbars'; - - export const incrFontSize = 'apputils:incr-font-size'; - - export const decrFontSize = 'apputils:decr-font-size'; - export const loadState = 'apputils:load-statedb'; export const print = 'apputils:print'; @@ -109,230 +97,10 @@ const settings: JupyterFrontEndPlugin = { provides: ISettingRegistry }; -/** - * The default theme manager provider. - */ -const themes: JupyterFrontEndPlugin = { - id: '@jupyterlab/apputils-extension:themes', - requires: [ISettingRegistry, JupyterFrontEnd.IPaths], - optional: [ISplashScreen], - activate: ( - app: JupyterFrontEnd, - settings: ISettingRegistry, - paths: JupyterFrontEnd.IPaths, - splash: ISplashScreen | null - ): IThemeManager => { - const host = app.shell; - const commands = app.commands; - const url = URLExt.join(paths.urls.base, paths.urls.themes); - const key = themes.id; - const manager = new ThemeManager({ key, host, settings, splash, url }); - - // Keep a synchronously set reference to the current theme, - // since the asynchronous setting of the theme in `changeTheme` - // can lead to an incorrect toggle on the currently used theme. - let currentTheme: string; - - manager.themeChanged.connect((sender, args) => { - // Set data attributes on the application shell for the current theme. - currentTheme = args.newValue; - document.body.dataset.jpThemeLight = String( - manager.isLight(currentTheme) - ); - document.body.dataset.jpThemeName = currentTheme; - if ( - document.body.dataset.jpThemeScrollbars !== - String(manager.themeScrollbars(currentTheme)) - ) { - document.body.dataset.jpThemeScrollbars = String( - manager.themeScrollbars(currentTheme) - ); - } - - // Set any CSS overrides - manager.loadCSSOverrides(); - - commands.notifyCommandChanged(CommandIDs.changeTheme); - }); - - commands.addCommand(CommandIDs.changeTheme, { - label: args => { - const theme = args['theme'] as string; - return args['isPalette'] ? `Use ${theme} Theme` : theme; - }, - isToggled: args => args['theme'] === currentTheme, - execute: args => { - const theme = args['theme'] as string; - if (theme === manager.theme) { - return; - } - return manager.setTheme(theme); - } - }); - - commands.addCommand(CommandIDs.themeScrollbars, { - label: 'Theme Scrollbars', - isToggled: () => manager.themeScrollbars(currentTheme), - execute: () => manager.toggleThemeScrollbars() - }); - - commands.addCommand(CommandIDs.incrFontSize, { - label: args => `Increase ${args['label']} Font Size`, - execute: args => manager.incrFontSize(args['key'] as string) - }); - - commands.addCommand(CommandIDs.decrFontSize, { - label: args => `Decrease ${args['label']} Font Size`, - execute: args => manager.decrFontSize(args['key'] as string) - }); - - return manager; - }, - autoStart: true, - provides: IThemeManager -}; - -/** - * The default theme manager's UI command palette and main menu functionality. - * - * #### Notes - * This plugin loads separately from the theme manager plugin in order to - * prevent blocking of the theme manager while it waits for the command palette - * and main menu to become available. - */ -const themesPaletteMenu: JupyterFrontEndPlugin = { - id: '@jupyterlab/apputils-extension:themes-palette-menu', - requires: [IThemeManager], - optional: [ICommandPalette, IMainMenu], - activate: ( - app: JupyterFrontEnd, - manager: IThemeManager, - palette: ICommandPalette | null, - mainMenu: IMainMenu | null - ): void => { - const commands = app.commands; - - // If we have a main menu, add the theme manager to the settings menu. - if (mainMenu) { - const themeMenu = new Menu({ commands }); - themeMenu.title.label = 'JupyterLab Theme'; - void app.restored.then(() => { - const isPalette = false; - - // choose a theme - manager.themes.forEach(theme => { - themeMenu.addItem({ - command: CommandIDs.changeTheme, - args: { isPalette, theme } - }); - }); - themeMenu.addItem({ type: 'separator' }); - - // toggle scrollbar theming - themeMenu.addItem({ command: CommandIDs.themeScrollbars }); - themeMenu.addItem({ type: 'separator' }); - - // increase/decrease code font size - themeMenu.addItem({ - command: CommandIDs.incrFontSize, - args: { label: 'Code', key: 'code-font-size' } - }); - themeMenu.addItem({ - command: CommandIDs.decrFontSize, - args: { label: 'Code', key: 'code-font-size' } - }); - themeMenu.addItem({ type: 'separator' }); - - // increase/decrease content font size - themeMenu.addItem({ - command: CommandIDs.incrFontSize, - args: { label: 'Content', key: 'content-font-size1' } - }); - themeMenu.addItem({ - command: CommandIDs.decrFontSize, - args: { label: 'Content', key: 'content-font-size1' } - }); - themeMenu.addItem({ type: 'separator' }); - - // increase/decrease ui font size - themeMenu.addItem({ - command: CommandIDs.incrFontSize, - args: { label: 'UI', key: 'ui-font-size1' } - }); - themeMenu.addItem({ - command: CommandIDs.decrFontSize, - args: { label: 'UI', key: 'ui-font-size1' } - }); - }); - mainMenu.settingsMenu.addGroup( - [ - { - type: 'submenu' as Menu.ItemType, - submenu: themeMenu - } - ], - 0 - ); - } - - // If we have a command palette, add theme switching options to it. - if (palette) { - void app.restored.then(() => { - const category = 'Theme'; - const command = CommandIDs.changeTheme; - const isPalette = true; - - // choose a theme - manager.themes.forEach(theme => { - palette.addItem({ command, args: { isPalette, theme }, category }); - }); - - // toggle scrollbar theming - palette.addItem({ command: CommandIDs.themeScrollbars, category }); - - // increase/decrease code font size - palette.addItem({ - command: CommandIDs.incrFontSize, - args: { label: 'Code', key: 'code-font-size' }, - category - }); - palette.addItem({ - command: CommandIDs.decrFontSize, - args: { label: 'Code', key: 'code-font-size' }, - category - }); - // increase/decrease content font size - palette.addItem({ - command: CommandIDs.incrFontSize, - args: { label: 'Content', key: 'content-font-size1' }, - category - }); - palette.addItem({ - command: CommandIDs.decrFontSize, - args: { label: 'Content', key: 'content-font-size1' }, - category - }); - // increase/decrease ui font size - palette.addItem({ - command: CommandIDs.incrFontSize, - args: { label: 'UI', key: 'ui-font-size1' }, - category - }); - palette.addItem({ - command: CommandIDs.decrFontSize, - args: { label: 'UI', key: 'ui-font-size1' }, - category - }); - }); - } - }, - autoStart: true -}; - /** * The default window name resolver provider. */ -const resolver: JupyterFrontEndPlugin = { +export const resolver: JupyterFrontEndPlugin = { id: '@jupyterlab/apputils-extension:resolver', autoStart: true, provides: IWindowResolver, @@ -689,8 +457,8 @@ const plugins: JupyterFrontEndPlugin[] = [ settings, state, splash, - themes, - themesPaletteMenu, + themesPlugin, + themesPaletteMenuPlugin, print ]; export default plugins; diff --git a/packages/apputils-extension/src/themeplugins.ts b/packages/apputils-extension/src/themeplugins.ts new file mode 100644 index 000000000000..6ee4d3458aec --- /dev/null +++ b/packages/apputils-extension/src/themeplugins.ts @@ -0,0 +1,252 @@ +/*----------------------------------------------------------------------------- +| Copyright (c) Jupyter Development Team. +| Distributed under the terms of the Modified BSD License. +|----------------------------------------------------------------------------*/ + +import { + JupyterFrontEnd, + JupyterFrontEndPlugin +} from '@jupyterlab/application'; + +import { + ICommandPalette, + ISplashScreen, + IThemeManager, + ThemeManager +} from '@jupyterlab/apputils'; + +import { ISettingRegistry, URLExt } from '@jupyterlab/coreutils'; + +import { IMainMenu } from '@jupyterlab/mainmenu'; + +import { Menu } from '@phosphor/widgets'; + +namespace CommandIDs { + export const changeTheme = 'apputils:change-theme'; + + export const themeScrollbars = 'apputils:theme-scrollbars'; + + export const incrFontSize = 'apputils:incr-font-size'; + + export const decrFontSize = 'apputils:decr-font-size'; +} + +/** + * The default theme manager provider. + */ +export const themesPlugin: JupyterFrontEndPlugin = { + id: '@jupyterlab/apputils-extension:themes', + requires: [ISettingRegistry, JupyterFrontEnd.IPaths], + optional: [ISplashScreen], + activate: ( + app: JupyterFrontEnd, + settings: ISettingRegistry, + paths: JupyterFrontEnd.IPaths, + splash: ISplashScreen | null + ): IThemeManager => { + const host = app.shell; + const commands = app.commands; + const url = URLExt.join(paths.urls.base, paths.urls.themes); + const key = themesPlugin.id; + const manager = new ThemeManager({ key, host, settings, splash, url }); + + // Keep a synchronously set reference to the current theme, + // since the asynchronous setting of the theme in `changeTheme` + // can lead to an incorrect toggle on the currently used theme. + let currentTheme: string; + + manager.themeChanged.connect((sender, args) => { + // Set data attributes on the application shell for the current theme. + currentTheme = args.newValue; + document.body.dataset.jpThemeLight = String( + manager.isLight(currentTheme) + ); + document.body.dataset.jpThemeName = currentTheme; + if ( + document.body.dataset.jpThemeScrollbars !== + String(manager.themeScrollbars(currentTheme)) + ) { + document.body.dataset.jpThemeScrollbars = String( + manager.themeScrollbars(currentTheme) + ); + } + + // Set any CSS overrides + manager.loadCSSOverrides(); + + commands.notifyCommandChanged(CommandIDs.changeTheme); + }); + + commands.addCommand(CommandIDs.changeTheme, { + label: args => { + const theme = args['theme'] as string; + return args['isPalette'] ? `Use ${theme} Theme` : theme; + }, + isToggled: args => args['theme'] === currentTheme, + execute: args => { + const theme = args['theme'] as string; + if (theme === manager.theme) { + return; + } + return manager.setTheme(theme); + } + }); + + commands.addCommand(CommandIDs.themeScrollbars, { + label: 'Theme Scrollbars', + isToggled: () => manager.isToggledThemeScrollbars(), + execute: () => manager.toggleThemeScrollbars() + }); + + commands.addCommand(CommandIDs.incrFontSize, { + label: args => `Increase ${args['label']} Font Size`, + execute: args => manager.incrFontSize(args['key'] as string) + }); + + commands.addCommand(CommandIDs.decrFontSize, { + label: args => `Decrease ${args['label']} Font Size`, + execute: args => manager.decrFontSize(args['key'] as string) + }); + + return manager; + }, + autoStart: true, + provides: IThemeManager +}; + +/** + * The default theme manager's UI command palette and main menu functionality. + * + * #### Notes + * This plugin loads separately from the theme manager plugin in order to + * prevent blocking of the theme manager while it waits for the command palette + * and main menu to become available. + */ +export const themesPaletteMenuPlugin: JupyterFrontEndPlugin = { + id: '@jupyterlab/apputils-extension:themes-palette-menu', + requires: [IThemeManager], + optional: [ICommandPalette, IMainMenu], + activate: ( + app: JupyterFrontEnd, + manager: IThemeManager, + palette: ICommandPalette | null, + mainMenu: IMainMenu | null + ): void => { + const commands = app.commands; + + // If we have a main menu, add the theme manager to the settings menu. + if (mainMenu) { + const themeMenu = new Menu({ commands }); + themeMenu.title.label = 'JupyterLab Theme'; + void app.restored.then(() => { + const isPalette = false; + + // choose a theme + manager.themes.forEach(theme => { + themeMenu.addItem({ + command: CommandIDs.changeTheme, + args: { isPalette, theme } + }); + }); + themeMenu.addItem({ type: 'separator' }); + + // toggle scrollbar theming + themeMenu.addItem({ command: CommandIDs.themeScrollbars }); + themeMenu.addItem({ type: 'separator' }); + + // increase/decrease code font size + themeMenu.addItem({ + command: CommandIDs.incrFontSize, + args: { label: 'Code', key: 'code-font-size' } + }); + themeMenu.addItem({ + command: CommandIDs.decrFontSize, + args: { label: 'Code', key: 'code-font-size' } + }); + themeMenu.addItem({ type: 'separator' }); + + // increase/decrease content font size + themeMenu.addItem({ + command: CommandIDs.incrFontSize, + args: { label: 'Content', key: 'content-font-size1' } + }); + themeMenu.addItem({ + command: CommandIDs.decrFontSize, + args: { label: 'Content', key: 'content-font-size1' } + }); + themeMenu.addItem({ type: 'separator' }); + + // increase/decrease ui font size + themeMenu.addItem({ + command: CommandIDs.incrFontSize, + args: { label: 'UI', key: 'ui-font-size1' } + }); + themeMenu.addItem({ + command: CommandIDs.decrFontSize, + args: { label: 'UI', key: 'ui-font-size1' } + }); + }); + mainMenu.settingsMenu.addGroup( + [ + { + type: 'submenu' as Menu.ItemType, + submenu: themeMenu + } + ], + 0 + ); + } + + // If we have a command palette, add theme switching options to it. + if (palette) { + void app.restored.then(() => { + const category = 'Theme'; + const command = CommandIDs.changeTheme; + const isPalette = true; + + // choose a theme + manager.themes.forEach(theme => { + palette.addItem({ command, args: { isPalette, theme }, category }); + }); + + // toggle scrollbar theming + palette.addItem({ command: CommandIDs.themeScrollbars, category }); + + // increase/decrease code font size + palette.addItem({ + command: CommandIDs.incrFontSize, + args: { label: 'Code', key: 'code-font-size' }, + category + }); + palette.addItem({ + command: CommandIDs.decrFontSize, + args: { label: 'Code', key: 'code-font-size' }, + category + }); + // increase/decrease content font size + palette.addItem({ + command: CommandIDs.incrFontSize, + args: { label: 'Content', key: 'content-font-size1' }, + category + }); + palette.addItem({ + command: CommandIDs.decrFontSize, + args: { label: 'Content', key: 'content-font-size1' }, + category + }); + // increase/decrease ui font size + palette.addItem({ + command: CommandIDs.incrFontSize, + args: { label: 'UI', key: 'ui-font-size1' }, + category + }); + palette.addItem({ + command: CommandIDs.decrFontSize, + args: { label: 'UI', key: 'ui-font-size1' }, + category + }); + }); + } + }, + autoStart: true +}; diff --git a/packages/apputils/src/thememanager.ts b/packages/apputils/src/thememanager.ts index b2cf9dd02856..97a41fa7682b 100644 --- a/packages/apputils/src/thememanager.ts +++ b/packages/apputils/src/thememanager.ts @@ -245,6 +245,13 @@ export class ThemeManager implements IThemeManager { ); } + /** + * Test if the user has scrollbar styling enabled. + */ + isToggledThemeScrollbars(): boolean { + return !!this._settings.composite['theme-scrollbars']; + } + /** * Toggle the `theme-scrollbbars` setting. */