@@ -2,13 +2,32 @@ import * as Vue from "vue"; // eslint-disable-line import/no-extraneous-dependen
22import { VueView , createViewContext , vueRender } from "jupyter-vue" ;
33import "vuetify/styles" ;
44import colors from "vuetify/lib/util/colors.mjs" ;
5- import { createVuetify , useTheme } from "vuetify" ;
5+ import { createVuetify } from "vuetify" ;
66import * as components from "vuetify/components" ;
77import * as directives from "vuetify/directives" ;
88import { VDataTable } from "vuetify/labs/VDataTable" ;
99import { ThemeColorsModel , ThemeModel } from "./Themes" ;
1010
11- const observer = new MutationObserver ( ( mutationList , observer ) => {
11+ // Every widget view gets its own Vue app, but all views for one widget manager
12+ // should share a single Vuetify plugin and theme state.
13+ const managerStateByWidgetManager = new WeakMap ( ) ;
14+
15+ function getManagerState ( widgetManager ) {
16+ let managerState = managerStateByWidgetManager . get ( widgetManager ) ;
17+ if ( ! managerState ) {
18+ managerState = {
19+ themeInitialized : false ,
20+ vuetify : createVuetify ( {
21+ components : { ...components , VDataTable } ,
22+ directives,
23+ } ) ,
24+ } ;
25+ managerStateByWidgetManager . set ( widgetManager , managerState ) ;
26+ }
27+ return managerState ;
28+ }
29+
30+ const observer = new MutationObserver ( ( mutationList ) => {
1231 for ( const mutation of mutationList ) {
1332 if ( mutation . type === "childList" ) {
1433 const overlay = document . querySelector ( ".v-overlay-container" ) ;
@@ -26,10 +45,7 @@ observer.observe(document.body, { childList: true });
2645export class VuetifyView extends VueView {
2746 addPlugins ( vueApp ) {
2847 super . addPlugins ( vueApp ) ;
29- const vuetify = createVuetify ( {
30- components : { ...components , VDataTable } ,
31- directives,
32- } ) ;
48+ const { vuetify } = getManagerState ( this . model . widget_manager ) ;
3349 this . el . classList . add ( "vuetify-styles" ) ;
3450 document . querySelector ( "html" ) . style . fontSize = "16px" ;
3551 vueApp . use ( vuetify ) ;
@@ -73,67 +89,75 @@ export class VuetifyView extends VueView {
7389 if ( ! this . themeModel ) {
7490 return ;
7591 }
76- this . theme = useTheme ( ) ;
77-
78- if ( ThemeModel . themeManager ) {
79- const setAutoTheme = ( ) => {
80- if ( this . themeModel . get ( "dark" ) === null ) {
81- const isDark = document . body . dataset . jpThemeLight === "false" ;
82- this . theme . global . name . value = isDark ? "dark" : "light" ;
83- this . themeModel . set ( "dark_jlab" , isDark ) ;
84- this . themeModel . save_changes ( ) ;
85- }
86- } ;
87- ThemeModel . themeManager . themeChanged . connect ( ( ) => {
88- setAutoTheme ( ) ;
89- } , this ) ;
90- setAutoTheme ( ) ;
92+ const managerState = getManagerState ( this . model . widget_manager ) ;
93+ if ( ! managerState . themeInitialized ) {
94+ initializeTheme (
95+ managerState ,
96+ this . themeModel ,
97+ this . themeLightModel ,
98+ this . themeDarkModel
99+ ) ;
91100 }
101+ }
102+ }
92103
93- const onDark = ( ) => {
94- this . theme . global . name . value = this . themeModel . get ( "dark" )
95- ? "dark"
96- : "light" ;
97- } ;
98-
99- const onColorsLight = ( ) => {
100- this . theme . themes . value . light . colors = getColors ( this . themeLightModel ) ;
101- } ;
102- onColorsLight ( ) ;
103-
104- const onColorsDark = ( ) => {
105- this . theme . themes . value . dark . colors = getColors ( this . themeDarkModel ) ;
104+ function initializeTheme (
105+ managerState ,
106+ themeModel ,
107+ themeLightModel ,
108+ themeDarkModel
109+ ) {
110+ const theme = managerState . vuetify . theme ;
111+
112+ if ( ThemeModel . themeManager ) {
113+ const setAutoTheme = ( ) => {
114+ if ( themeModel . get ( "dark" ) === null ) {
115+ const isDark = document . body . dataset . jpThemeLight === "false" ;
116+ theme . global . name . value = isDark ? "dark" : "light" ;
117+ themeModel . set ( "dark_jlab" , isDark ) ;
118+ themeModel . save_changes ( ) ;
119+ }
106120 } ;
107- onColorsDark ( ) ;
108-
109- if ( this . themeModel . get ( "dark" ) !== null ) {
110- onDark ( ) ;
111- } else if ( document . body . dataset . jpThemeLight ) {
112- const isDark = document . body . dataset . jpThemeLight === "false" ;
113- this . theme . global . name . value = isDark ? "dark" : "light" ;
114- this . themeModel . set ( "dark_jlab" , isDark ) ;
115- this . themeModel . save_changes ( ) ;
116- } else if ( document . body . classList . contains ( "theme-dark" ) ) {
117- this . theme . global . name . value = "dark" ;
118- this . themeModel . set ( "dark" , true ) ;
119- this . themeModel . save_changes ( ) ;
120- } else if ( document . body . classList . contains ( "theme-light" ) ) {
121- this . themeModel . set ( "dark" , false ) ;
122- this . themeModel . save_changes ( ) ;
123- }
124-
125- Vue . onMounted ( ( ) => {
126- this . themeModel . on ( "change:dark" , onDark ) ;
127- this . themeLightModel . on ( "change" , onColorsLight ) ;
128- this . themeDarkModel . on ( "change" , onColorsDark ) ;
121+ ThemeModel . themeManager . themeChanged . connect ( ( ) => {
122+ setAutoTheme ( ) ;
129123 } ) ;
124+ setAutoTheme ( ) ;
125+ }
130126
131- Vue . onUnmounted ( ( ) => {
132- this . themeModel . off ( "change:dark" , onDark ) ;
133- this . themeLightModel . off ( "change" , onColorsLight ) ;
134- this . themeDarkModel . off ( "change" , onColorsDark ) ;
135- } ) ;
127+ const onDark = ( ) => {
128+ theme . global . name . value = themeModel . get ( "dark" ) ? "dark" : "light" ;
129+ } ;
130+
131+ const onColorsLight = ( ) => {
132+ theme . themes . value . light . colors = getColors ( themeLightModel ) ;
133+ } ;
134+ onColorsLight ( ) ;
135+
136+ const onColorsDark = ( ) => {
137+ theme . themes . value . dark . colors = getColors ( themeDarkModel ) ;
138+ } ;
139+ onColorsDark ( ) ;
140+
141+ if ( themeModel . get ( "dark" ) !== null ) {
142+ onDark ( ) ;
143+ } else if ( document . body . dataset . jpThemeLight ) {
144+ const isDark = document . body . dataset . jpThemeLight === "false" ;
145+ theme . global . name . value = isDark ? "dark" : "light" ;
146+ themeModel . set ( "dark_jlab" , isDark ) ;
147+ themeModel . save_changes ( ) ;
148+ } else if ( document . body . classList . contains ( "theme-dark" ) ) {
149+ theme . global . name . value = "dark" ;
150+ themeModel . set ( "dark" , true ) ;
151+ themeModel . save_changes ( ) ;
152+ } else if ( document . body . classList . contains ( "theme-light" ) ) {
153+ themeModel . set ( "dark" , false ) ;
154+ themeModel . save_changes ( ) ;
136155 }
156+
157+ themeModel . on ( "change:dark" , onDark ) ;
158+ themeLightModel . on ( "change" , onColorsLight ) ;
159+ themeDarkModel . on ( "change" , onColorsDark ) ;
160+ managerState . themeInitialized = true ;
137161}
138162
139163function parseColor ( colorStr ) {
0 commit comments