From 45f7080afd1744624d34efb78e9d925ad52a0bec Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Sun, 21 Jul 2024 16:25:24 -0400 Subject: [PATCH] Move `loadAllBrewStylesAndSnippets` to the parent page component Themes contain both CSS and Snippets. The brewRenderer only cares about the CSS, but other components need the Snippets. Better to have the parent "editPage", etc. load the theme bundles and pass them down to each child that needs it, rather than trying to pass from the child up. This also fixes the `metadataEditor.jsx` not being able to change themes live; A new theme bundle is now loaded when a new theme is selected, instead of only the first time the BrewRenderer mounts. Also renamed to "fetchThemeBundle" --- client/homebrew/brewRenderer/brewRenderer.jsx | 16 ++----------- .../editor/metadataEditor/metadataEditor.jsx | 2 +- client/homebrew/pages/editPage/editPage.jsx | 24 ++++++++++++++++--- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index baea64d3d..c01182d7b 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -61,6 +61,7 @@ const BrewRenderer = (props)=>{ lang : '', errors : [], currentEditorPage : 0, + themeBundle : {}, ...props }; @@ -69,7 +70,6 @@ const BrewRenderer = (props)=>{ height : PAGE_HEIGHT, isMounted : false, visibility : 'hidden', - themeBundle : {} }); const mainRef = useRef(null); @@ -131,7 +131,7 @@ const BrewRenderer = (props)=>{ const renderStyle = ()=>{ const cleanStyle = props.style; //DOMPurify.sanitize(props.style, purifyConfig); - return
${cleanStyle} ` }} />; + return
${cleanStyle} ` }} />; }; const renderPage = (pageText, index)=>{ @@ -173,19 +173,7 @@ const BrewRenderer = (props)=>{ } }; - // Loads the theme bundle and parses it out. Called when the iFrame is first mounted, and when a new theme is selected - const loadAllBrewStylesAndSnippets = ()=>{ - fetch(`${window.location.protocol}//${window.location.host}/theme/${props.renderer}/${props.theme}`).then((response)=>response.json()).then((themeBundle)=>{ - themeBundle.joinedStyles = themeBundle.styles.map(style => ``).join('\n\n'); //DOMPurify.sanitize(joinedStyles, purifyConfig); - setState((prevState)=>({ - ...prevState, - themeBundle : themeBundle - })); - }); - }; - const frameDidMount = ()=>{ //This triggers when iFrame finishes internal "componentDidMount" - loadAllBrewStylesAndSnippets(); // Load the brew's inherited and local styles. setTimeout(()=>{ //We still see a flicker where the style isn't applied yet, so wait 100ms before showing iFrame updateSize(); window.addEventListener('resize', updateSize); diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 5d6972e49..2ccf5c440 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -111,7 +111,7 @@ const MetadataEditor = createClass({ handleTheme : function(theme){ this.props.metadata.renderer = theme.renderer; this.props.metadata.theme = theme.path; - this.props.onChange(this.props.metadata); + this.props.onChange(this.props.metadata, "theme"); }, handleLanguage : function(languageCode){ diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index a67129ca3..1c6fe1620 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -55,7 +55,8 @@ const EditPage = createClass({ autoSaveWarning : false, unsavedTime : new Date(), currentEditorPage : 0, - displayLockMessage : this.props.brew.lock || false + displayLockMessage : this.props.brew.lock || false, + themeBundle : {} }; }, @@ -87,6 +88,8 @@ const EditPage = createClass({ htmlErrors : Markdown.validate(prevState.brew.text) })); + this.fetchThemeBundle(this.props.brew.renderer, this.props.brew.theme); + document.addEventListener('keydown', this.handleControlKeys); }, componentWillUnmount : function() { @@ -130,7 +133,10 @@ const EditPage = createClass({ }), ()=>{if(this.state.autoSave) this.trySave();}); }, - handleMetaChange : function(metadata){ + handleMetaChange : function(metadata, field=undefined){ + if(field == "theme") // Fetch theme bundle only if theme was changed + this.fetchThemeBundle(metadata.renderer, metadata.theme); + this.setState((prevState)=>({ brew : { ...prevState.brew, @@ -138,13 +144,24 @@ const EditPage = createClass({ }, isPending : true, }), ()=>{if(this.state.autoSave) this.trySave();}); - }, hasChanges : function(){ return !_.isEqual(this.state.brew, this.savedBrew); }, + // Loads the theme bundle and parses it out. Called when the iFrame is first mounted, and when a new theme is selected + fetchThemeBundle : function(renderer, theme) { + fetch(`${window.location.protocol}//${window.location.host}/theme/${renderer}/${theme}`).then((response)=>response.json()).then((themeBundle)=>{ + themeBundle.joinedStyles = themeBundle.styles.map(style => ``).join('\n\n'); //DOMPurify.sanitize(joinedStyles, purifyConfig); + this.setState((prevState)=>({ // MOVE TO MOUNT STEP OF SHARE / NEW / EDIT + ...prevState, + themeBundle : themeBundle + })); + }); + + }, + trySave : function(immediate=false){ if(!this.debounceSave) this.debounceSave = _.debounce(this.save, SAVE_TIMEOUT); if(this.hasChanges()){ @@ -413,6 +430,7 @@ const EditPage = createClass({ style={this.state.brew.style} renderer={this.state.brew.renderer} theme={this.state.brew.theme} + themeBundle={this.state.themeBundle} errors={this.state.htmlErrors} lang={this.state.brew.lang} userThemes={this.props.userThemes}