From 73c68fd11c7517e465bf5bcf690ee24f190bb6f9 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 27 Nov 2024 21:35:29 -0600 Subject: [PATCH 01/56] Functional first pass. Needs: - [ ] opinions on UI placement - [ ] opinions on best choice for displaying a write-in based User Brew ( flip to writin box? Add to drop-down list? ) --- .../editor/metadataEditor/metadataEditor.jsx | 35 ++++++++++++++++--- server/homebrew.api.js | 4 +-- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index bfc3b8b61..0405b942b 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -47,7 +47,8 @@ const MetadataEditor = createClass({ getInitialState : function(){ return { - showThumbnail : true + showThumbnail : true, + showThemeWritein : false }; }, @@ -57,6 +58,12 @@ const MetadataEditor = createClass({ }); }, + toggleThemeWritein : function(){ + this.setState({ + showThemeWritein : !this.state.showThemeWritein + }); + }, + renderThumbnail : function(){ if(!this.state.showThumbnail) return; return ; @@ -115,6 +122,12 @@ const MetadataEditor = createClass({ this.props.onChange(this.props.metadata, 'theme'); }, + handleThemeWritein : function(e) { + this.props.metadata.renderer = 'V3'; + this.props.metadata.theme = e.target.value; + this.props.onChange(this.props.metadata, 'theme'); + }, + handleLanguage : function(languageCode){ this.props.metadata.lang = languageCode; this.props.onChange(this.props.metadata); @@ -213,6 +226,7 @@ const MetadataEditor = createClass({ }); }; + const currentRenderer = this.props.metadata.renderer; const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] ?? { name: `!!! THEME MISSING !!! ID=${this.props.metadata.theme}` }; @@ -234,10 +248,23 @@ const MetadataEditor = createClass({ return
- {dropdown} + {!this.state.showThemeWritein?dropdown:''} + + {this.renderThemeWritein()}
; }, + renderThemeWritein : function(){ + if(!this.state.showThemeWritein) return; + return this.handleThemeWritein(e)} />; + }, + renderLanguageDropdown : function(){ const langCodes = ['en', 'de', 'de-ch', 'fr', 'ja', 'es', 'it', 'sv', 'ru', 'zh-Hans', 'zh-Hant']; const listLanguages = ()=>{ @@ -345,7 +372,7 @@ const MetadataEditor = createClass({ placeholder='add tag' unique={true} values={this.props.metadata.tags} onChange={(e)=>this.handleFieldChange('tags', e)} - /> + />
@@ -370,7 +397,7 @@ const MetadataEditor = createClass({ values={this.props.metadata.invitedAuthors} notes={['Invited author usernames are case sensitive.', 'After adding an invited author, send them the edit link. There, they can choose to accept or decline the invitation.']} onChange={(e)=>this.handleFieldChange('invitedAuthors', e)} - /> + />

Privacy

diff --git a/server/homebrew.api.js b/server/homebrew.api.js index b8d4024ad..f997de1c4 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -1,6 +1,6 @@ /* eslint-disable max-lines */ import _ from 'lodash'; -import {model as HomebrewModel} from './homebrew.model.js'; +import { model as HomebrewModel } from './homebrew.model.js'; import express from 'express'; import zlib from 'zlib'; import GoogleActions from './googleActions.js'; @@ -302,7 +302,7 @@ const api = { splitTextStyleAndMetadata(currentTheme); // If there is anything in the snippets or style members, append them to the appropriate array - if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); + // if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); if(currentTheme?.style) completeStyles.push(`/* From Brew: ${req.protocol}://${req.get('host')}/share/${req.params.id} */\n\n${currentTheme.style}`); req.params.id = currentTheme.theme; From 7c357a2aa130a072cad58779c377d0888e61992c Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 29 Dec 2024 23:23:48 -0600 Subject: [PATCH 02/56] Attempt to save state but seems to break brew. --- .../editor/metadataEditor/metadataEditor.jsx | 13 ++++++++++--- .../editor/metadataEditor/metadataEditor.less | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 0405b942b..0bd91ae35 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -40,6 +40,7 @@ const MetadataEditor = createClass({ theme : '5ePHB', lang : 'en' }, + onChange : ()=>{}, reportError : ()=>{} }; @@ -47,8 +48,10 @@ const MetadataEditor = createClass({ getInitialState : function(){ return { - showThumbnail : true, - showThemeWritein : false + showThumbnail : true, + showThemeWritein : false, + lastThemePulldown : '', + lastThemeWriteIn : '' }; }, @@ -60,8 +63,12 @@ const MetadataEditor = createClass({ toggleThemeWritein : function(){ this.setState({ - showThemeWritein : !this.state.showThemeWritein + showThemeWritein : !this.state.showThemeWritein, + // lastThemePulldown : !this.state.showThemeWritein ? this.props.metadata.theme : this.state.lastThemePulldown, + // lastThemeWriteIn : !this.state.showThemeWritein ? this.state.lastThemePulldown : this.props.metadata.theme }); + // if(this.state.showThemeWritein) this.props.metadata.theme = this.state.lastThemeWriteIn; + // else this.props.metadata.theme = this.state.lastThemePulldown; }, renderThumbnail : function(){ diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index 2cff01cfe..13397c89f 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -71,7 +71,7 @@ border : 1px solid gray; &:focus { outline : 1px solid #444444; } } - &.thumbnail { + &.thumbnail, &.themes{ height : 1.4em; label { line-height : 2.0em; } .value { From fe2d02a24c570c829eca48a7481cf7f99e245cbf Mon Sep 17 00:00:00 2001 From: David Bolack Date: Mon, 30 Dec 2024 12:28:47 -0600 Subject: [PATCH 03/56] Work in progress. Still issues with saving the state of the theme pulldowns and collecting the written in theme. --- .../editor/metadataEditor/metadataEditor.jsx | 27 +++++++++++++------ .../editor/metadataEditor/metadataEditor.less | 11 ++++++++ client/homebrew/pages/editPage/editPage.jsx | 5 ++-- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 0bd91ae35..08b9c7165 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -62,13 +62,17 @@ const MetadataEditor = createClass({ }, toggleThemeWritein : function(){ + console.log('toggleThemeWritein'); this.setState({ showThemeWritein : !this.state.showThemeWritein, - // lastThemePulldown : !this.state.showThemeWritein ? this.props.metadata.theme : this.state.lastThemePulldown, - // lastThemeWriteIn : !this.state.showThemeWritein ? this.state.lastThemePulldown : this.props.metadata.theme + lastThemePulldown : this.state.showThemeWritein ? this.props.metadata.theme : this.state.lastThemePulldown, + lastThemeWriteIn : this.state.showThemeWritein ? this.state.lastThemePulldown : this.props.metadata.theme }); - // if(this.state.showThemeWritein) this.props.metadata.theme = this.state.lastThemeWriteIn; - // else this.props.metadata.theme = this.state.lastThemePulldown; + console.log(this.state); + console.log(this.props.metadata); + if(!this.state.showThemeWritein) this.props.metadata.theme = this.state.lastThemeWriteIn; + else this.props.metadata.theme = this.state.lastThemePulldown; + this.props.onChange(this.props.metadata, 'theme'); }, renderThumbnail : function(){ @@ -130,9 +134,13 @@ const MetadataEditor = createClass({ }, handleThemeWritein : function(e) { + console.log('Enter!'); this.props.metadata.renderer = 'V3'; this.props.metadata.theme = e.target.value; + console.log(e.target.value); + this.props.onChange(this.props.metadata, 'renderer'); this.props.onChange(this.props.metadata, 'theme'); + console.log(this.props.metadata); }, handleLanguage : function(languageCode){ @@ -214,6 +222,7 @@ const MetadataEditor = createClass({ if(!global.enable_themes) return; const mergedThemes = _.merge(Themes, this.props.userThemes); + console.log(mergedThemes); const listThemes = (renderer)=>{ return _.map(_.values(mergedThemes[renderer]), (theme)=>{ @@ -230,11 +239,11 @@ const MetadataEditor = createClass({
; - }); + }).filter(Boolean); }; - const currentRenderer = this.props.metadata.renderer; + console.log(this.props.metadata.theme); const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] ?? { name: `!!! THEME MISSING !!! ID=${this.props.metadata.theme}` }; let dropdown; @@ -250,13 +259,14 @@ const MetadataEditor = createClass({
{currentTheme.author ?? _.upperFirst(currentRenderer)} : {currentTheme.name}
{listThemes(currentRenderer)} + {console.log(listThemes(currentRenderer))} ; } return
{!this.state.showThemeWritein?dropdown:''} - {this.renderThemeWritein()} @@ -268,7 +278,8 @@ const MetadataEditor = createClass({ return this.handleThemeWritein(e)} />; }, diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index 13397c89f..9f13fbc49 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -88,6 +88,17 @@ } } + &.themes{ + .value { + overflow : visible; + text-overflow : auto; + } + button { + padding-left: 5px; + padding-right: 5px; + } + } + &.description { flex : 1; textarea.value { diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index cf2b559c3..585d5205d 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -151,9 +151,10 @@ const EditPage = createClass({ }, handleMetaChange : function(metadata, field=undefined){ - if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed + if(field == 'theme' || field == 'renderer') {// Fetch theme bundle only if theme or renderer was changed + console.log(metadata); fetchThemeBundle(this, metadata.renderer, metadata.theme); - + } this.setState((prevState)=>({ brew : { ...prevState.brew, From b9f7e820c7d9f4320386941c54e8b3de1ebc384a Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 7 Jan 2025 20:36:38 -0600 Subject: [PATCH 04/56] Functionally? working. --- .../editor/metadataEditor/metadataEditor.jsx | 40 +++++++++---------- client/homebrew/pages/editPage/editPage.jsx | 1 - 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 08b9c7165..6d8755aba 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -16,6 +16,8 @@ const SYSTEMS = ['5e', '4e', '3.5e', 'Pathfinder']; const homebreweryThumbnail = require('../../thumbnail.png'); +let mergedThemes; + const callIfExists = (val, fn, ...args)=>{ if(val[fn]) { val[fn](...args); @@ -47,11 +49,12 @@ const MetadataEditor = createClass({ }, getInitialState : function(){ + mergedThemes = _.merge(Themes, this.props.userThemes); return { showThumbnail : true, - showThemeWritein : false, - lastThemePulldown : '', - lastThemeWriteIn : '' + showThemeWritein : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? false : true, + lastThemePulldown : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] : '', + lastThemeWriteIn : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? '' : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] }; }, @@ -62,17 +65,12 @@ const MetadataEditor = createClass({ }, toggleThemeWritein : function(){ - console.log('toggleThemeWritein'); - this.setState({ - showThemeWritein : !this.state.showThemeWritein, - lastThemePulldown : this.state.showThemeWritein ? this.props.metadata.theme : this.state.lastThemePulldown, - lastThemeWriteIn : this.state.showThemeWritein ? this.state.lastThemePulldown : this.props.metadata.theme - }); - console.log(this.state); - console.log(this.props.metadata); if(!this.state.showThemeWritein) this.props.metadata.theme = this.state.lastThemeWriteIn; else this.props.metadata.theme = this.state.lastThemePulldown; this.props.onChange(this.props.metadata, 'theme'); + this.setState({ + showThemeWritein : !this.state.showThemeWritein + }); }, renderThumbnail : function(){ @@ -130,17 +128,22 @@ const MetadataEditor = createClass({ handleTheme : function(theme){ this.props.metadata.renderer = theme.renderer; this.props.metadata.theme = theme.path; + this.setState({ + lastThemePulldown : theme.path + }); + this.props.onChange(this.props.metadata, 'theme'); }, handleThemeWritein : function(e) { - console.log('Enter!'); this.props.metadata.renderer = 'V3'; this.props.metadata.theme = e.target.value; - console.log(e.target.value); + this.setState({ + lastThemeWriteIn : e.target.value + }); + this.props.onChange(this.props.metadata, 'renderer'); this.props.onChange(this.props.metadata, 'theme'); - console.log(this.props.metadata); }, handleLanguage : function(languageCode){ @@ -221,9 +224,6 @@ const MetadataEditor = createClass({ renderThemeDropdown : function(){ if(!global.enable_themes) return; - const mergedThemes = _.merge(Themes, this.props.userThemes); - console.log(mergedThemes); - const listThemes = (renderer)=>{ return _.map(_.values(mergedThemes[renderer]), (theme)=>{ if(theme.path == this.props.metadata.shareId) return; @@ -243,9 +243,8 @@ const MetadataEditor = createClass({ }; const currentRenderer = this.props.metadata.renderer; - console.log(this.props.metadata.theme); const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] - ?? { name: `!!! THEME MISSING !!! ID=${this.props.metadata.theme}` }; + ?? { name: `!!! Manually selected theme !!! ID=${this.props.metadata.theme}` }; let dropdown; if(currentRenderer == 'legacy') { @@ -259,7 +258,6 @@ const MetadataEditor = createClass({
{currentTheme.author ?? _.upperFirst(currentRenderer)} : {currentTheme.name}
{listThemes(currentRenderer)} - {console.log(listThemes(currentRenderer))} ; } @@ -279,7 +277,7 @@ const MetadataEditor = createClass({ default='' placeholder='Enter share id' className='value' - defaultValue={this.state.lastThemeWriteIn} + defaultValue={this.state.lastThemeWriteIn || this.props.metadata.theme} onChange={(e)=>this.handleThemeWritein(e)} />; }, diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 585d5205d..ef6da5099 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -152,7 +152,6 @@ const EditPage = createClass({ handleMetaChange : function(metadata, field=undefined){ if(field == 'theme' || field == 'renderer') {// Fetch theme bundle only if theme or renderer was changed - console.log(metadata); fetchThemeBundle(this, metadata.renderer, metadata.theme); } this.setState((prevState)=>({ From 74122d90579812916b526626144f85ff9f7debba Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 7 Jan 2025 22:11:01 -0600 Subject: [PATCH 05/56] Display name of write in theme next to write-in Clear user's active ThemeBundle when an incomplete/broken/invalid writein. Needs theming help. --- client/homebrew/editor/editor.jsx | 1 + .../editor/metadataEditor/metadataEditor.jsx | 13 ++++++++----- .../editor/metadataEditor/metadataEditor.less | 4 ++++ client/homebrew/pages/editPage/editPage.jsx | 1 + server/homebrew.api.js | 6 +++++- shared/helpers.js | 15 +++++++++++++-- 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index bba5f3ad9..3e37aba57 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -454,6 +454,7 @@ const Editor = createClass({ rerenderParent={this.rerenderParent} /> diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 6d8755aba..694444bc9 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -53,8 +53,8 @@ const MetadataEditor = createClass({ return { showThumbnail : true, showThemeWritein : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? false : true, - lastThemePulldown : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] : '', - lastThemeWriteIn : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? '' : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] + lastThemePulldown : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? mergedThemes[this.props.metadata.renderer][this.props.metadata.theme].path : '', + lastThemeWriteIn : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? '' : this.props.metadata.theme }; }, @@ -244,7 +244,7 @@ const MetadataEditor = createClass({ const currentRenderer = this.props.metadata.renderer; const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] - ?? { name: `!!! Manually selected theme !!! ID=${this.props.metadata.theme}` }; + ?? { name: `${this.props.themeBundle?.path || ''}`, author: '!!!' }; let dropdown; if(currentRenderer == 'legacy') { @@ -273,12 +273,15 @@ const MetadataEditor = createClass({ renderThemeWritein : function(){ if(!this.state.showThemeWritein) return; - return + this.handleThemeWritein(e)} />; + onChange={(e)=>this.handleThemeWritein(e)} /> + {`${this.state.lastThemeWriteIn ? this.props.themeBundle?.path || '' : ''}`} +
; }, renderLanguageDropdown : function(){ diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index 9f13fbc49..d06e420ae 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -1,5 +1,9 @@ @import 'naturalcrit/styles/colors.less'; +.userThemeName { + padding-left: 10px; + padding-right: 10px; +} .metadataEditor { position : absolute; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index ef6da5099..7c7044832 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -443,6 +443,7 @@ const EditPage = createClass({ reportError={this.errorReported} renderer={this.state.brew.renderer} userThemes={this.props.userThemes} + themeBundle={this.state.themeBundle} snippetBundle={this.state.themeBundle.snippets} updateBrew={this.updateBrew} onCursorPageChange={this.handleEditorCursorPageChange} diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 8f0d143fa..8b4175491 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -279,6 +279,7 @@ const api = { let currentTheme; const completeStyles = []; const completeSnippets = []; + let themePath = ''; while (req.params.id) { //=== User Themes ===// @@ -292,6 +293,7 @@ const api = { currentTheme = req.brew; splitTextStyleAndMetadata(currentTheme); + if(themePath === '') themePath = currentTheme.title; // If there is anything in the snippets or style members, append them to the appropriate array // if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); @@ -301,6 +303,7 @@ const api = { req.params.renderer = currentTheme.renderer; } else { //=== Static Themes ===// + if(themePath === '') themePath = req.params.id; const localSnippets = `${req.params.renderer}_${req.params.id}`; // Just log the name for loading on client const localStyle = `@import url(\"/themes/${req.params.renderer}/${req.params.id}/style.css\");`; completeSnippets.push(localSnippets); @@ -313,7 +316,8 @@ const api = { const returnObj = { // Reverse the order of the arrays so they are listed oldest parent to youngest child. styles : completeStyles.reverse(), - snippets : completeSnippets.reverse() + snippets : completeSnippets.reverse(), + path : themePath }; res.setHeader('Content-Type', 'application/json'); diff --git a/shared/helpers.js b/shared/helpers.js index b2190cdcd..3aff9538a 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -44,8 +44,13 @@ const fetchThemeBundle = async (obj, renderer, theme)=>{ .catch((err)=>{ obj.setState({ error: err }); }); - if(!res) return; - + if(!res) { + obj.setState((prevState)=>({ + ...prevState, + themeBundle : {} + })); + return; + } const themeBundle = res.body; themeBundle.joinedStyles = themeBundle.styles.map((style)=>``).join('\n\n'); obj.setState((prevState)=>({ @@ -54,8 +59,14 @@ const fetchThemeBundle = async (obj, renderer, theme)=>{ })); }; +const fetchBrewAsThemeJSON = async (renderer, theme)=>{ + if(!renderer || !theme) return; + +} + export { splitTextStyleAndMetadata, printCurrentBrew, fetchThemeBundle, + fetchBrewAsThemeJSON }; From 94a431eec8ffeed1340615d15e56a5136529040f Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 7 Jan 2025 22:28:12 -0600 Subject: [PATCH 06/56] Update tests. --- server/homebrew.api.spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index 8270b1568..d6433bced 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -587,6 +587,7 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ + path : 'User Theme A', styles : ['/* From Brew: https://localhost/share/userThemeAID */\n\nUser Theme A Style'], snippets : [] }); @@ -607,6 +608,7 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ + path : 'User Theme A', styles : [ '/* From Brew: https://localhost/share/userThemeCID */\n\nUser Theme C Style', '/* From Brew: https://localhost/share/userThemeBID */\n\nUser Theme B Style', @@ -623,6 +625,7 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ + path : '5ePHB', styles : [ `/* From Theme Blank */\n\n@import url("/themes/V3/Blank/style.css");`, `/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");` @@ -649,6 +652,7 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ + path : 'User Theme A', styles : [ `/* From Theme Blank */\n\n@import url("/themes/V3/Blank/style.css");`, `/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");`, From 6eb938bb373b2d15428f9c3425c0ce8bdcddd8ce Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 8 Jan 2025 09:25:16 -0600 Subject: [PATCH 07/56] Change theme button toggle to be a bit more obvious. --- client/homebrew/editor/metadataEditor/metadataEditor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 694444bc9..0fd17db3e 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -265,7 +265,7 @@ const MetadataEditor = createClass({ {!this.state.showThemeWritein?dropdown:''} {this.renderThemeWritein()} ; From 2d47cd2a767f7e2f258bd057efc09ad4a58eb3e6 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 8 Jan 2025 09:28:37 -0600 Subject: [PATCH 08/56] Formatting cleanup --- .../editor/metadataEditor/metadataEditor.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 0fd17db3e..92e737764 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -265,7 +265,7 @@ const MetadataEditor = createClass({ {!this.state.showThemeWritein?dropdown:''} {this.renderThemeWritein()} ; @@ -275,11 +275,11 @@ const MetadataEditor = createClass({ if(!this.state.showThemeWritein) return; return
this.handleThemeWritein(e)} /> + default='' + placeholder='Enter share id' + className='value' + defaultValue={this.state.lastThemeWriteIn || this.props.metadata.theme} + onChange={(e)=>this.handleThemeWritein(e)} /> {`${this.state.lastThemeWriteIn ? this.props.themeBundle?.path || '' : ''}`}
; }, From f6c95fb8b773ebeff021bd7a581e352e7ea5bddd Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Tue, 14 Jan 2025 08:25:46 +1300 Subject: [PATCH 09/56] Extend header nav to exclude frontCover pages --- .../brewRenderer/headerNav/headerNav.jsx | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/client/homebrew/brewRenderer/headerNav/headerNav.jsx b/client/homebrew/brewRenderer/headerNav/headerNav.jsx index 68963129f..8278e2bd9 100644 --- a/client/homebrew/brewRenderer/headerNav/headerNav.jsx +++ b/client/homebrew/brewRenderer/headerNav/headerNav.jsx @@ -11,11 +11,18 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ const renderHeaderLinks = ()=>{ if(!pagesRef.current) return; + const excludedPages = { + '.frontCover' : 'Cover Page', + '.toc' : 'Contents' + }; + + const excluded = Object.keys(excludedPages).join(','); + const selector = [ - '.pages > .page', // All page elements, which by definition have IDs - '.page:not(:has(.toc)) > [id]', // All direct children of non-ToC .page with an ID (Legacy) - '.page:not(:has(.toc)) > .columnWrapper > [id]', // All direct children of non-ToC .page > .columnWrapper with an ID (V3) - '.page:not(:has(.toc)) h2', // All non-ToC H2 titles, like Monster frame titles + '.pages > .page', // All page elements, which by definition have IDs + `.page:not(:has(${excluded})) > [id]`, // All direct children of non-excluded .pages with an ID (Legacy) + `.page:not(:has(${excluded})) > .columnWrapper > [id]`, // All direct children of non-excluded .page > .columnWrapper with an ID (V3) + `.page:not(:has(${excluded})) h2`, // All non-excluded H2 titles, like Monster frame titles ]; const elements = pagesRef.current.querySelectorAll(selector.join(',')); if(!elements) return; @@ -32,9 +39,13 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ elements.forEach((el)=>{ if(el.className.match(/\bpage\b/)) { let text = `Page ${el.id.slice(1)}`; // The ID of a page *should* always be equal to `p` followed by the page number - if(el.querySelector('.toc')){ // If the page contains a table of contents, add "- Contents" to the display text - text += ' - Contents'; - }; + Object.keys(excludedPages).every((pageType)=>{ + if(el.querySelector(pageType)){ // If the page contains a table of contents, add "- Contents" to the display text + text += ` - ${excludedPages[pageType]}`; + return false; + }; + return true; + }); navList.push({ depth : 0, // Pages are always at the least indented level text : text, From a04df0fdfc5fc2ca9a10a086e9d07fae4c15f230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Sat, 1 Feb 2025 19:27:55 +0100 Subject: [PATCH 10/56] small adjustements --- themes/V3/5ePHB/style.less | 3 --- 1 file changed, 3 deletions(-) diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index ba975e58a..4f3e1d7a4 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -622,7 +622,6 @@ left : 0; filter : drop-shadow(0 0 0.075cm black); img { - width : 100%; height : 2cm; } } @@ -667,7 +666,6 @@ left : 0; height : 2cm; img { - width : 100%; height : 2cm; } } @@ -685,7 +683,6 @@ position : absolute; inset : 0; z-index : -1; - width : 11cm; background-image : @backCover; background-repeat : no-repeat; background-size : contain; From 8eef810f3f8f2dae658a8053435f84fff1eeb4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Losada=20Hern=C3=A1ndez?= Date: Sat, 1 Feb 2025 20:30:54 +0100 Subject: [PATCH 11/56] backcover logo width --- themes/V3/5ePHB/style.less | 1 - 1 file changed, 1 deletion(-) diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index 4f3e1d7a4..6b8126eb6 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -734,7 +734,6 @@ img { position : relative; z-index : 0; - width : 100%; height : 1.5cm; } p { From 659510e364c68ea5a3e1199a3f74498c61119376 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Sun, 9 Feb 2025 12:07:09 -0500 Subject: [PATCH 12/56] Remove unused function --- shared/helpers.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/shared/helpers.js b/shared/helpers.js index 3aff9538a..c31516ac9 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -59,14 +59,8 @@ const fetchThemeBundle = async (obj, renderer, theme)=>{ })); }; -const fetchBrewAsThemeJSON = async (renderer, theme)=>{ - if(!renderer || !theme) return; - -} - export { splitTextStyleAndMetadata, printCurrentBrew, fetchThemeBundle, - fetchBrewAsThemeJSON }; From cfbf4021dccb57df02cbd64db116a5a0ab54f651 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Sun, 9 Feb 2025 12:23:42 -0500 Subject: [PATCH 13/56] Remove unneeded filter --- client/homebrew/editor/metadataEditor/metadataEditor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 92e737764..8b7c31e53 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -239,7 +239,7 @@ const MetadataEditor = createClass({ ; - }).filter(Boolean); + }); }; const currentRenderer = this.props.metadata.renderer; From 11396389abf8c29d4d6aea2dbebe3547ddc34b36 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Mon, 10 Feb 2025 20:47:17 -0600 Subject: [PATCH 14/56] Move Superscript/Subscript functions into their own module --- package-lock.json | 10 ++++++++++ package.json | 1 + shared/naturalcrit/markdown.js | 33 +++------------------------------ 3 files changed, 14 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 649c6597c..165f4d343 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "marked-extended-tables": "^1.1.0", "marked-gfm-heading-id": "^4.0.1", "marked-smartypants-lite": "^1.0.3", + "marked-subsuper-text": "^1.0.1", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", "mongoose": "^8.9.6", @@ -9837,6 +9838,15 @@ "marked": ">=4 <16" } }, + "node_modules/marked-subsuper-text": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/marked-subsuper-text/-/marked-subsuper-text-1.0.1.tgz", + "integrity": "sha512-VxKzXdijXd/smeoBcKBJstzxCuTddSvDpsIs1EPhEXCHYfk1MenDxqPXzRrC5kksZe47eptUzg+Bd6EK9HmMbw==", + "license": "MIT", + "peerDependencies": { + "marked": ">=3 <16" + } + }, "node_modules/markedLegacy": { "name": "marked", "version": "0.3.19", diff --git a/package.json b/package.json index 2bf3a0a93..0e2ca72c1 100644 --- a/package.json +++ b/package.json @@ -114,6 +114,7 @@ "marked-extended-tables": "^1.1.0", "marked-gfm-heading-id": "^4.0.1", "marked-smartypants-lite": "^1.0.3", + "marked-subsuper-text": "^1.0.1", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", "mongoose": "^8.9.6", diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 99766b536..181cc55bd 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -7,6 +7,7 @@ import MarkedExtendedTables from 'marked-extended-tables'; import { markedSmartypantsLite as MarkedSmartypantsLite } from 'marked-smartypants-lite'; import { gfmHeadingId as MarkedGFMHeadingId, resetHeadings as MarkedGFMResetHeadingIDs } from 'marked-gfm-heading-id'; import { markedEmoji as MarkedEmojis } from 'marked-emoji'; +import MarkedSubSuperText from 'marked-subsuper-text'; //Icon fonts included so they can appear in emoji autosuggest dropdown import diceFont from '../../themes/fonts/iconFonts/diceFont.js'; @@ -333,35 +334,6 @@ const mustacheInjectBlock = { } }; -const superSubScripts = { - name : 'superSubScript', - level : 'inline', - start(src) { return src.match(/\^/m)?.index; }, // Hint to Marked.js to stop and check for a match - tokenizer(src, tokens) { - const superRegex = /^\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^/m; - const subRegex = /^\^\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^\^/m; - let isSuper = false; - let match = subRegex.exec(src); - if(!match){ - match = superRegex.exec(src); - if(match) - isSuper = true; - } - if(match?.length) { - return { - type : 'superSubScript', // Should match "name" above - raw : match[0], // Text to consume from the source - tag : isSuper ? 'sup' : 'sub', - tokens : this.lexer.inlineTokens(match[1]) - }; - } - }, - renderer(token) { - return `<${token.tag}>${this.parser.parseInline(token.tokens)}`; - } -}; - - const justifiedParagraphClasses = []; justifiedParagraphClasses[2] = 'Left'; justifiedParagraphClasses[4] = 'Right'; @@ -796,8 +768,9 @@ const tableTerminators = [ Marked.use(MarkedVariables()); Marked.use({ extensions : [justifiedParagraphs, definitionListsMultiLine, definitionListsSingleLine, forcedParagraphBreaks, - nonbreakingSpaces, superSubScripts, mustacheSpans, mustacheDivs, mustacheInjectInline] }); + nonbreakingSpaces, mustacheSpans, mustacheDivs, mustacheInjectInline] }); Marked.use(mustacheInjectBlock); +Marked.use(MarkedSubSuperText()); Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false }); Marked.use(MarkedExtendedTables(tableTerminators), MarkedGFMHeadingId({ globalSlugs: true }), MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions)); From c080e5b1915eea919c2f683aa4445a759b381ff4 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 10 Feb 2025 22:20:12 -0500 Subject: [PATCH 15/56] Add author to snippetBundle --- server/homebrew.api.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 8b4175491..17e9ae7fe 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -279,7 +279,8 @@ const api = { let currentTheme; const completeStyles = []; const completeSnippets = []; - let themePath = ''; + let themeName; + let themeAuthor; while (req.params.id) { //=== User Themes ===// @@ -293,17 +294,18 @@ const api = { currentTheme = req.brew; splitTextStyleAndMetadata(currentTheme); - if(themePath === '') themePath = currentTheme.title; + themeName ??= currentTheme.title; + themeAuthor ??= currentTheme.authors?.[0]; // If there is anything in the snippets or style members, append them to the appropriate array - // if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); + if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets)); if(currentTheme?.style) completeStyles.push(`/* From Brew: ${req.protocol}://${req.get('host')}/share/${req.params.id} */\n\n${currentTheme.style}`); req.params.id = currentTheme.theme; req.params.renderer = currentTheme.renderer; } else { //=== Static Themes ===// - if(themePath === '') themePath = req.params.id; + themeName ??= req.params.id; const localSnippets = `${req.params.renderer}_${req.params.id}`; // Just log the name for loading on client const localStyle = `@import url(\"/themes/${req.params.renderer}/${req.params.id}/style.css\");`; completeSnippets.push(localSnippets); @@ -317,7 +319,8 @@ const api = { // Reverse the order of the arrays so they are listed oldest parent to youngest child. styles : completeStyles.reverse(), snippets : completeSnippets.reverse(), - path : themePath + name : themeName, + author : themeAuthor }; res.setHeader('Content-Type', 'application/json'); From 1aed7539110badb8c7b3429f4dd30db113238905 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 10 Feb 2025 22:20:54 -0500 Subject: [PATCH 16/56] Use ComboBox component for Theme Selector --- .../editor/metadataEditor/metadataEditor.jsx | 86 +++++------ .../editor/metadataEditor/metadataEditor.less | 136 ++++++++---------- 2 files changed, 94 insertions(+), 128 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 199d2c4b7..141e1ab92 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -49,12 +49,8 @@ const MetadataEditor = createClass({ }, getInitialState : function(){ - mergedThemes = _.merge(Themes, this.props.userThemes); return { - showThumbnail : true, - showThemeWritein : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? false : true, - lastThemePulldown : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? mergedThemes[this.props.metadata.renderer][this.props.metadata.theme].path : '', - lastThemeWriteIn : mergedThemes[this.props.metadata.renderer][this.props.metadata.theme] ? '' : this.props.metadata.theme + showThumbnail : true }; }, @@ -64,15 +60,6 @@ const MetadataEditor = createClass({ }); }, - toggleThemeWritein : function(){ - if(!this.state.showThemeWritein) this.props.metadata.theme = this.state.lastThemeWriteIn; - else this.props.metadata.theme = this.state.lastThemePulldown; - this.props.onChange(this.props.metadata, 'theme'); - this.setState({ - showThemeWritein : !this.state.showThemeWritein - }); - }, - renderThumbnail : function(){ if(!this.state.showThumbnail) return; return ; @@ -128,21 +115,15 @@ const MetadataEditor = createClass({ handleTheme : function(theme){ this.props.metadata.renderer = theme.renderer; this.props.metadata.theme = theme.path; - this.setState({ - lastThemePulldown : theme.path - }); this.props.onChange(this.props.metadata, 'theme'); }, handleThemeWritein : function(e) { - this.props.metadata.renderer = 'V3'; this.props.metadata.theme = e.target.value; - this.setState({ - lastThemeWriteIn : e.target.value - }); - this.props.onChange(this.props.metadata, 'renderer'); + + this.props.onChange(this.props.metadata, 'theme'); }, @@ -224,12 +205,14 @@ const MetadataEditor = createClass({ renderThemeDropdown : function(){ if(!global.enable_themes) return; + const mergedThemes = _.merge(Themes, this.props.userThemes); + const listThemes = (renderer)=>{ return _.map(_.values(mergedThemes[renderer]), (theme)=>{ if(theme.path == this.props.metadata.shareId) return; const preview = theme.thumbnail || `/themes/${theme.renderer}/${theme.path}/dropdownPreview.png`; const texture = theme.thumbnail || `/themes/${theme.renderer}/${theme.path}/dropdownTexture.png`; - return
this.handleTheme(theme)} title={''}> + return
{theme.author ?? renderer} : {theme.name}
@@ -242,45 +225,45 @@ const MetadataEditor = createClass({ }); }; + console.log(this.props.themeBundle); + const currentRenderer = this.props.metadata.renderer; const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] - ?? { name: `${this.props.themeBundle?.path || ''}`, author: '!!!' }; + ?? { name: `${this.props.themeBundle?.name || ''}`, author: `${this.props.themeBundle?.author || ''}` }; let dropdown; if(currentRenderer == 'legacy') { dropdown = - -
{`Themes are not supported in the Legacy Renderer`}
-
; +
+
Themes are not supported in the Legacy Renderer
+
; } else { dropdown = - -
{currentTheme.author ?? _.upperFirst(currentRenderer)} : {currentTheme.name}
- - {listThemes(currentRenderer)} -
; +
+ this.handleTheme(value)} + onEntry={(e)=>{ + e.target.setCustomValidity(''); //Clear the validation popup while typing + //debouncedHandleFieldChange('theme', e); + this.handleThemeWritein(e); + }} + options={listThemes(currentRenderer)} + autoSuggest={{ + suggestMethod : 'includes', + clearAutoSuggestOnClick : true, + filterOn : ['value', 'title'] + }} + /> + Select from the list below (built-in themes and brews you have tagged "meta:theme"), or paste in the Share URL or Share ID of any brew. +
; } return
- {!this.state.showThemeWritein?dropdown:''} - - {this.renderThemeWritein()} -
; - }, - - renderThemeWritein : function(){ - if(!this.state.showThemeWritein) return; - return
- this.handleThemeWritein(e)} /> - {`${this.state.lastThemeWriteIn ? this.props.themeBundle?.path || '' : ''}`} + {dropdown}
; }, @@ -317,8 +300,7 @@ const MetadataEditor = createClass({ clearAutoSuggestOnClick : true, filterOn : ['value', 'detail', 'title'] }} - > - + /> Sets the HTML Lang property for your brew. May affect hyphenation or spellcheck.
diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index d06e420ae..d76220e48 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -171,89 +171,73 @@ } .themes.field { - .navDropdownContainer { + & .dropdown-container { position : relative; z-index : 100; background-color : white; - &.disabled { - font-style : italic; - color : dimgray; - background-color : darkgray; - } - & > div:first-child { - padding : 3px 3px; - background-color : inherit; - border : 1px solid gray; - i { float : right; } - &:hover { - color : white; - background-color : @blue; + } + & .dropdown-options { + overflow-y : visible; + } + .disabled { + font-style : italic; + color : dimgray; + background-color : darkgray; + } + .item { + position : relative; + padding : 3px 3px; + overflow : visible; + background-color : white; + border-top : 1px solid rgb(118, 118, 118); + .preview { + position : absolute; + top : 0; + right : 0; + z-index : 1; + display : flex; + flex-direction : column; + width : 200px; + overflow : hidden; + color : black; + background : #CCCCCC; + border-radius : 5px; + box-shadow : 0 0 5px black; + opacity : 0; + transition : opacity 250ms ease; + h6 { + padding-block : 0.5em; + padding-inline : 1em; + font-weight : 900; + border-bottom : 2px solid hsl(0,0%,40%); } } - .navDropdown .item > p { - width : 45%; - height : 1.1em; - overflow : hidden; - text-overflow : ellipsis; - white-space : nowrap; - } - .navDropdown { - position : absolute; - width : 100%; - box-shadow : 0px 5px 10px rgba(0, 0, 0, 0.3); - .item { - position : relative; - padding : 3px 3px; - overflow : visible; - background-color : white; - border-top : 1px solid rgb(118, 118, 118); - .preview { - position : absolute; - top : 0; - right : 0; - z-index : 1; - display : flex; - flex-direction : column; - width : 200px; - overflow : hidden; - color : black; - background : #CCCCCC; - border-radius : 5px; - box-shadow : 0 0 5px black; - opacity : 0; - transition : opacity 250ms ease; - h6 { - padding-block : 0.5em; - padding-inline : 1em; - font-weight : 900; - border-bottom : 2px solid hsl(0,0%,40%); - } - } - &:hover { - color : white; - background-color : @blue; - } - &:hover > .preview { opacity : 1; } - .texture-container { - position : absolute; - top : 0; - left : 0; - width : 100%; - height : 100%; - min-height : 100%; - overflow : hidden; - > img { - position : absolute; - top : 0px; - right : 0; - width : 50%; - min-height : 100%; - -webkit-mask-image : linear-gradient(90deg, transparent, black 20%); - mask-image : linear-gradient(90deg, transparent, black 20%); - } - } + + .texture-container { + position : absolute; + top : 0; + left : 0; + width : 100%; + height : 100%; + min-height : 100%; + overflow : hidden; + > img { + position : absolute; + top : 0; + right : 0; + width : 50%; + min-height : 100%; + -webkit-mask-image : linear-gradient(90deg, transparent, black 20%); + mask-image : linear-gradient(90deg, transparent, black 20%); } } + + &:hover { + color : white; + background-color : @blue; + filter : unset; + } + &:hover > .preview { opacity : 1; } } } From 85ea91fed8283bee6089f0caf29db2d805b102f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Feb 2025 03:21:18 +0000 Subject: [PATCH 17/56] Bump globals from 15.14.0 to 15.15.0 Bumps [globals](https://github.com/sindresorhus/globals) from 15.14.0 to 15.15.0. - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](https://github.com/sindresorhus/globals/compare/v15.14.0...v15.15.0) --- updated-dependencies: - dependency-name: globals dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 9 +++++---- package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index add91f28e..ea722068b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,7 +58,7 @@ "eslint": "^9.20.1", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", - "globals": "^15.14.0", + "globals": "^15.15.0", "jest": "^29.7.0", "jest-expect-message": "^1.1.3", "jsdom-global": "^3.0.2", @@ -6813,10 +6813,11 @@ } }, "node_modules/globals": { - "version": "15.14.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", - "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, diff --git a/package.json b/package.json index a853391d8..7f9105f04 100644 --- a/package.json +++ b/package.json @@ -133,7 +133,7 @@ "eslint": "^9.20.1", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", - "globals": "^15.14.0", + "globals": "^15.15.0", "jest": "^29.7.0", "jest-expect-message": "^1.1.3", "jsdom-global": "^3.0.2", From f326d1123247831eff13ade79b04afeb31f81886 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 00:05:30 -0500 Subject: [PATCH 18/56] Added input validation (allows Share ID or Share URL) --- .../editor/metadataEditor/metadataEditor.jsx | 13 ++++++------- .../homebrew/editor/metadataEditor/validations.js | 13 +++++++++++++ client/homebrew/pages/editPage/editPage.jsx | 4 ++-- server/app.js | 1 + 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 141e1ab92..0656b08e7 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -77,6 +77,7 @@ const MetadataEditor = createClass({ ...this.props.metadata, [name] : e.target.value }); + return true; } else { // if validation issues, display built-in browser error popup with each error. const errMessage = validationErr.map((err)=>{ @@ -85,6 +86,7 @@ const MetadataEditor = createClass({ callIfExists(e.target, 'setCustomValidity', errMessage); callIfExists(e.target, 'reportValidity'); + return false; } }, @@ -120,9 +122,8 @@ const MetadataEditor = createClass({ }, handleThemeWritein : function(e) { - this.props.metadata.theme = e.target.value; - - + const shareId = e.target.value.split('/').pop(); //Extract just the ID if a URL was pasted in + this.props.metadata.theme = shareId; this.props.onChange(this.props.metadata, 'theme'); }, @@ -225,8 +226,6 @@ const MetadataEditor = createClass({ }); }; - console.log(this.props.themeBundle); - const currentRenderer = this.props.metadata.renderer; const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] ?? { name: `${this.props.themeBundle?.name || ''}`, author: `${this.props.themeBundle?.author || ''}` }; @@ -247,8 +246,8 @@ const MetadataEditor = createClass({ onSelect={(value)=>this.handleTheme(value)} onEntry={(e)=>{ e.target.setCustomValidity(''); //Clear the validation popup while typing - //debouncedHandleFieldChange('theme', e); - this.handleThemeWritein(e); + if(this.handleFieldChange('theme', e)) + this.handleThemeWritein(e); }} options={listThemes(currentRenderer)} autoSuggest={{ diff --git a/client/homebrew/editor/metadataEditor/validations.js b/client/homebrew/editor/metadataEditor/validations.js index 32c8131f6..b475783a4 100644 --- a/client/homebrew/editor/metadataEditor/validations.js +++ b/client/homebrew/editor/metadataEditor/validations.js @@ -27,6 +27,19 @@ module.exports = { (value)=>{ return new RegExp(/^([a-zA-Z]{2,3})(-[a-zA-Z]{4})?(-(?:[0-9]{3}|[a-zA-Z]{2}))?$/).test(value) === false && (value.length > 0) ? 'Invalid language code.' : null; } + ], + theme: [ + (value) => { + const URL = global.config.baseUrl.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); //Escape any regex characters + const shareIDPattern = '[a-zA-Z0-9-_]{12}'; + const shareURLRegex = new RegExp(`^${URL}\\/share\\/${shareIDPattern}$`); + const shareIDRegex = new RegExp(`^${shareIDPattern}$`); + if (value?.length === 0) return null; + if (shareURLRegex.test(value)) return null; + if (shareIDRegex.test(value)) return null; + + return 'Must be a valid Share URL or a 12-character ID.'; + } ] }; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index c784edc8e..bee813f46 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -379,7 +379,7 @@ const EditPage = createClass({ const title = `${this.props.brew.title} ${systems}`; const text = `Hey guys! I've been working on this homebrew. I'd love your feedback. Check it out. -**[Homebrewery Link](${global.config.publicUrl}/share/${shareLink})**`; +**[Homebrewery Link](${global.config.baseUrl}/share/${shareLink})**`; return `https://www.reddit.com/r/UnearthedArcana/submit?title=${encodeURIComponent(title.toWellFormed())}&text=${encodeURIComponent(text)}`; }, @@ -410,7 +410,7 @@ const EditPage = createClass({ view - {navigator.clipboard.writeText(`${global.config.publicUrl}/share/${shareLink}`);}}> + {navigator.clipboard.writeText(`${global.config.baseUrl}/share/${shareLink}`);}}> copy url diff --git a/server/app.js b/server/app.js index 4dec6b4c4..76caf6fed 100644 --- a/server/app.js +++ b/server/app.js @@ -552,6 +552,7 @@ const renderPage = async (req, res)=>{ const configuration = { local : isLocalEnvironment, publicUrl : config.get('publicUrl') ?? '', + baseUrl : `${req.protocol}://${req.get('host')}`, environment : nodeEnv, deployment : config.get('heroku_app_name') ?? '' }; From af729de09681e4fa7579a66626e1ba383b6afd76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Feb 2025 05:13:33 +0000 Subject: [PATCH 19/56] Bump elliptic from 6.6.0 to 6.6.1 Bumps [elliptic](https://github.com/indutny/elliptic) from 6.6.0 to 6.6.1. - [Commits](https://github.com/indutny/elliptic/compare/v6.6.0...v6.6.1) --- updated-dependencies: - dependency-name: elliptic dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ea722068b..8afd699c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5397,9 +5397,10 @@ "license": "ISC" }, "node_modules/elliptic": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.0.tgz", - "integrity": "sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "license": "MIT", "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", From 0bd5ac42b600fccdae7c7c3ee4d65eaca67f0330 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 00:40:59 -0500 Subject: [PATCH 20/56] Remove too-small height for themes + thumbnail --- client/homebrew/editor/metadataEditor/metadataEditor.less | 1 - 1 file changed, 1 deletion(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index d76220e48..1f6e228f8 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -76,7 +76,6 @@ &:focus { outline : 1px solid #444444; } } &.thumbnail, &.themes{ - height : 1.4em; label { line-height : 2.0em; } .value { overflow : hidden; From 45e98debbd61bd0ddbe278ec6edc96430c42629a Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 00:43:14 -0500 Subject: [PATCH 21/56] Remove z-index for metadata editor to not cover nav bar (errors/dropdowns/etc) The other editor panels don't have a z-index. For some reason the metadata editor does, and it covers items from the navbar --- client/homebrew/editor/metadataEditor/metadataEditor.less | 1 - 1 file changed, 1 deletion(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index 1f6e228f8..c5658a796 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -7,7 +7,6 @@ .metadataEditor { position : absolute; - z-index : 5; box-sizing : border-box; width : 100%; height : calc(100vh - 54px); // 54px is the height of the navbar + snippet bar. probably a better way to dynamic get this. From e584eec8c225e9689266185e34400ff0fd6d6ff1 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 14:51:45 -0500 Subject: [PATCH 22/56] When clicked, combobox textbox clears --- client/components/combobox.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/components/combobox.jsx b/client/components/combobox.jsx index 56633bbdd..3f1134bd6 100644 --- a/client/components/combobox.jsx +++ b/client/components/combobox.jsx @@ -45,6 +45,7 @@ const Combobox = createClass({ }, handleDropdown : function(show){ this.setState({ + value : show ? '' : this.props.default, showDropdown : show, inputFocused : this.props.autoSuggest.clearAutoSuggestOnClick ? show : false }); From df563b929429182f1436e9b89a2cd54334f4009e Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 14:53:02 -0500 Subject: [PATCH 23/56] Change combobox default text --- .../homebrew/editor/metadataEditor/metadataEditor.jsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 0656b08e7..d45f75932 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -16,8 +16,6 @@ const SYSTEMS = ['5e', '4e', '3.5e', 'Pathfinder']; const homebreweryThumbnail = require('../../thumbnail.png'); -let mergedThemes; - const callIfExists = (val, fn, ...args)=>{ if(val[fn]) { val[fn](...args); @@ -223,12 +221,11 @@ const MetadataEditor = createClass({
; - }); + }).filter(Boolean); }; const currentRenderer = this.props.metadata.renderer; - const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme] - ?? { name: `${this.props.themeBundle?.name || ''}`, author: `${this.props.themeBundle?.author || ''}` }; + const currentThemeDisplay = this.props.themeBundle?.name ? `${this.props.themeBundle.author ?? currentRenderer} : ${this.props.themeBundle.name}` : 'No Theme Selected'; let dropdown; if(currentRenderer == 'legacy') { @@ -241,8 +238,8 @@ const MetadataEditor = createClass({
this.handleTheme(value)} onEntry={(e)=>{ e.target.setCustomValidity(''); //Clear the validation popup while typing From bf297939dccf2efb5b0d14a6664d6e32b98fe58e Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 15:01:35 -0500 Subject: [PATCH 24/56] Debounce validation popup --- client/components/combobox.jsx | 2 +- .../editor/metadataEditor/metadataEditor.jsx | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/client/components/combobox.jsx b/client/components/combobox.jsx index 3f1134bd6..ae9f1d7f8 100644 --- a/client/components/combobox.jsx +++ b/client/components/combobox.jsx @@ -79,7 +79,7 @@ const Combobox = createClass({ if(!e.target.checkValidity()){ this.setState({ value : this.props.default - }, ()=>this.props.onEntry(e)); + }); } }} /> diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index d45f75932..2a65d9384 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -68,6 +68,11 @@ const MetadataEditor = createClass({ const inputRules = validations[name] ?? []; const validationErr = inputRules.map((rule)=>rule(e.target.value)).filter(Boolean); + const debouncedReportValidity = _.debounce((target, errMessage) => { + callIfExists(target, 'setCustomValidity', errMessage); + callIfExists(target, 'reportValidity'); + }, 300); // 300ms debounce delay, adjust as needed + // if no validation rules, save to props if(validationErr.length === 0){ callIfExists(e.target, 'setCustomValidity', ''); @@ -82,8 +87,8 @@ const MetadataEditor = createClass({ return `- ${err}`; }).join('\n'); - callIfExists(e.target, 'setCustomValidity', errMessage); - callIfExists(e.target, 'reportValidity'); + + debouncedReportValidity(e.target, errMessage); return false; } }, @@ -276,8 +281,6 @@ const MetadataEditor = createClass({ }); }; - const debouncedHandleFieldChange = _.debounce(this.handleFieldChange, 500); - return
@@ -288,7 +291,7 @@ const MetadataEditor = createClass({ onSelect={(value)=>this.handleLanguage(value)} onEntry={(e)=>{ e.target.setCustomValidity(''); //Clear the validation popup while typing - debouncedHandleFieldChange('lang', e); + this.handleFieldChange('lang', e); }} options={listLanguages()} autoSuggest={{ From d8d672fada688aa616997288b38027b39acfa0b5 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 15:51:06 -0500 Subject: [PATCH 25/56] Error message if chosen theme does not have "meta:theme" tag. --- client/homebrew/navbar/error-navitem.jsx | 13 +++++++++++++ .../homebrew/pages/errorPage/errors/errorIndex.js | 8 ++++++++ server/homebrew.api.js | 2 ++ 3 files changed, 23 insertions(+) diff --git a/client/homebrew/navbar/error-navitem.jsx b/client/homebrew/navbar/error-navitem.jsx index f6788e6d5..3de26ca56 100644 --- a/client/homebrew/navbar/error-navitem.jsx +++ b/client/homebrew/navbar/error-navitem.jsx @@ -116,6 +116,19 @@ const ErrorNavItem = createClass({ ; } + if(HBErrorCode === '10') { + return + Oops! +
+ Looks like the brew you have selected + as a theme is not tagged for use as a + theme. Verify that + brew + {response.body.brewId} has the meta:theme tag! +
+
; + } + return Oops!
diff --git a/client/homebrew/pages/errorPage/errors/errorIndex.js b/client/homebrew/pages/errorPage/errors/errorIndex.js index 2c7be5d4b..c2c49f958 100644 --- a/client/homebrew/pages/errorPage/errors/errorIndex.js +++ b/client/homebrew/pages/errorPage/errors/errorIndex.js @@ -167,6 +167,14 @@ const errorIndex = (props)=>{ **Requested access:** ${props.brew.accessType} **Brew ID:** ${props.brew.brewId}`, + + // Theme Not Valid + '10' : dedent` + ## The selected theme is not tagged as a theme. + + The brew selected as a theme exists, but has not been marked for use as a theme with the \`theme:meta\` tag. + + If the selected brew is your document, you may designate it as a theme by adding the \`theme:meta\` tag.`, //account page when account is not defined '50' : dedent` diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 17e9ae7fe..7c5460803 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -294,6 +294,8 @@ const api = { currentTheme = req.brew; splitTextStyleAndMetadata(currentTheme); + if(!currentTheme.tags.some(tag => tag === "meta:theme" || tag === "meta:Theme")) + throw { brewId: req.params.id, name: 'Invalid Theme Selected', message: 'Selected theme does not have the meta:theme tag', HBErrorCode: '10' }; themeName ??= currentTheme.title; themeAuthor ??= currentTheme.authors?.[0]; From 50bda9455f4e7a2dc9defcfa18322575c511302a Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 15:51:22 -0500 Subject: [PATCH 26/56] Immediately clear errors if a theme successfully loads --- shared/helpers.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shared/helpers.js b/shared/helpers.js index c31516ac9..2ad9218fa 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -55,7 +55,8 @@ const fetchThemeBundle = async (obj, renderer, theme)=>{ themeBundle.joinedStyles = themeBundle.styles.map((style)=>``).join('\n\n'); obj.setState((prevState)=>({ ...prevState, - themeBundle : themeBundle + themeBundle : themeBundle, + error : null })); }; From 94f478477d01ce586106f1ee3adae8eefab0636e Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 16:20:50 -0500 Subject: [PATCH 27/56] Add test for missing meta:theme tag --- server/homebrew.api.js | 2 +- server/homebrew.api.spec.js | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 7c5460803..7bd88cbdb 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -295,7 +295,7 @@ const api = { currentTheme = req.brew; splitTextStyleAndMetadata(currentTheme); if(!currentTheme.tags.some(tag => tag === "meta:theme" || tag === "meta:Theme")) - throw { brewId: req.params.id, name: 'Invalid Theme Selected', message: 'Selected theme does not have the meta:theme tag', HBErrorCode: '10' }; + throw { brewId: req.params.id, name: 'Invalid Theme Selected', message: 'Selected theme does not have the meta:theme tag', status: 422, HBErrorCode: '10' }; themeName ??= currentTheme.title; themeAuthor ??= currentTheme.authors?.[0]; diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index d6433bced..cfa7d13cc 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -690,6 +690,27 @@ brew`); name : 'ThemeLoad Error', status : 404 }); }); + + it('should fail for a User Theme not tagged with meta:theme', async ()=>{ + const brews = { + userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: null, shareId: 'userThemeAID', style: 'User Theme A Style' } + }; + + const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); + model.get = jest.fn((getParams)=>toBrewPromise(brews[getParams.shareId])); + const req = { params: { renderer: 'V3', id: 'userThemeAID' }, get: ()=>{ return 'localhost'; }, protocol: 'https' }; + + let err; + await api.getThemeBundle(req, res) + .catch((e)=>err = e); + + expect(err).toEqual({ + HBErrorCode : '10', + brewId : 'userThemeAID', + message : 'Selected theme does not have the meta:theme tag', + name : 'Invalid Theme Selected', + status : 422 }); + }); }); describe('deleteBrew', ()=>{ From ed30a1cd7d9a484fa0f5f7002e5a439a1fc5bee7 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 16:20:59 -0500 Subject: [PATCH 28/56] Update other tests to pass --- server/homebrew.api.spec.js | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index cfa7d13cc..1c42cb4be 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -576,7 +576,7 @@ brew`); describe('Theme bundle', ()=>{ it('should return Theme Bundle for a User Theme', async ()=>{ const brews = { - userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: null, shareId: 'userThemeAID', style: 'User Theme A Style' } + userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: null, shareId: 'userThemeAID', style: 'User Theme A Style', tags: ['meta:theme'], authors: ['authorName'] } }; const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); @@ -587,7 +587,8 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ - path : 'User Theme A', + name : 'User Theme A', + author : 'authorName', styles : ['/* From Brew: https://localhost/share/userThemeAID */\n\nUser Theme A Style'], snippets : [] }); @@ -595,9 +596,9 @@ brew`); it('should return Theme Bundle for nested User Themes', async ()=>{ const brews = { - userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: 'userThemeBID', shareId: 'userThemeAID', style: 'User Theme A Style' }, - userThemeBID : { title: 'User Theme B', renderer: 'V3', theme: 'userThemeCID', shareId: 'userThemeBID', style: 'User Theme B Style' }, - userThemeCID : { title: 'User Theme C', renderer: 'V3', theme: null, shareId: 'userThemeCID', style: 'User Theme C Style' } + userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: 'userThemeBID', shareId: 'userThemeAID', style: 'User Theme A Style', tags: ['meta:theme'], authors: ['authorName'] }, + userThemeBID : { title: 'User Theme B', renderer: 'V3', theme: 'userThemeCID', shareId: 'userThemeBID', style: 'User Theme B Style', tags: ['meta:theme'], authors: ['authorName'] }, + userThemeCID : { title: 'User Theme C', renderer: 'V3', theme: null, shareId: 'userThemeCID', style: 'User Theme C Style', tags: ['meta:theme'], authors: ['authorName'] } }; const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); @@ -608,7 +609,8 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ - path : 'User Theme A', + name : 'User Theme A', + author : 'authorName', styles : [ '/* From Brew: https://localhost/share/userThemeCID */\n\nUser Theme C Style', '/* From Brew: https://localhost/share/userThemeBID */\n\nUser Theme B Style', @@ -625,7 +627,8 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ - path : '5ePHB', + name : '5ePHB', + author : undefined, styles : [ `/* From Theme Blank */\n\n@import url("/themes/V3/Blank/style.css");`, `/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");` @@ -639,9 +642,9 @@ brew`); it('should return Theme Bundle for nested User and Static Themes together', async ()=>{ const brews = { - userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: 'userThemeBID', shareId: 'userThemeAID', style: 'User Theme A Style' }, - userThemeBID : { title: 'User Theme B', renderer: 'V3', theme: 'userThemeCID', shareId: 'userThemeBID', style: 'User Theme B Style' }, - userThemeCID : { title: 'User Theme C', renderer: 'V3', theme: '5eDMG', shareId: 'userThemeCID', style: 'User Theme C Style' } + userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: 'userThemeBID', shareId: 'userThemeAID', style: 'User Theme A Style', tags: ['meta:theme'], authors: ['authorName'] }, + userThemeBID : { title: 'User Theme B', renderer: 'V3', theme: 'userThemeCID', shareId: 'userThemeBID', style: 'User Theme B Style', tags: ['meta:theme'], authors: ['authorName'] }, + userThemeCID : { title: 'User Theme C', renderer: 'V3', theme: '5eDMG', shareId: 'userThemeCID', style: 'User Theme C Style', tags: ['meta:theme'], authors: ['authorName'] } }; const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); @@ -652,7 +655,8 @@ brew`); expect(res.status).toHaveBeenCalledWith(200); expect(res.send).toHaveBeenCalledWith({ - path : 'User Theme A', + name : 'User Theme A', + author : 'authorName', styles : [ `/* From Theme Blank */\n\n@import url("/themes/V3/Blank/style.css");`, `/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");`, @@ -669,9 +673,9 @@ brew`); }); }); - it('should fail for an invalid Theme in the chain', async()=>{ + it('should fail for a missing Theme in the chain', async()=>{ const brews = { - userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: 'missingTheme', shareId: 'userThemeAID', style: 'User Theme A Style' }, + userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: 'missingTheme', shareId: 'userThemeAID', style: 'User Theme A Style', tags: ['meta:theme'], authors: ['authorName'] }, }; const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); From 42accdb54fbc167d12278d0ca94a32438076073b Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 17:54:37 -0500 Subject: [PATCH 29/56] linting --- client/homebrew/pages/editPage/editPage.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index bee813f46..4db6d6e23 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -151,9 +151,9 @@ const EditPage = createClass({ }, handleMetaChange : function(metadata, field=undefined){ - if(field == 'theme' || field == 'renderer') {// Fetch theme bundle only if theme or renderer was changed + if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed fetchThemeBundle(this, metadata.renderer, metadata.theme); - } + this.setState((prevState)=>({ brew : { ...prevState.brew, From 854a2ab35eb873cf93e2f7b5d9ba6dd26f8265a5 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 13 Feb 2025 17:56:39 -0500 Subject: [PATCH 30/56] Fix /new --- client/homebrew/pages/newPage/newPage.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index ee2c67d5f..1d5887b8a 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -233,6 +233,7 @@ const NewPage = createClass({ onMetaChange={this.handleMetaChange} renderer={this.state.brew.renderer} userThemes={this.props.userThemes} + themeBundle={this.state.themeBundle} snippetBundle={this.state.themeBundle.snippets} onCursorPageChange={this.handleEditorCursorPageChange} onViewPageChange={this.handleEditorViewPageChange} From 34a0b4eb054ab91c94ae95568dffaef7c7c754c5 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 15 Feb 2025 00:12:20 +1300 Subject: [PATCH 31/56] Base savedBrew on current brew state, apply only updated properties from API call --- client/homebrew/pages/editPage/editPage.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index ffb6a6b40..bef4ec1b0 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -247,7 +247,13 @@ const EditPage = createClass({ }); if(!res) return; - this.savedBrew = res.body; + this.savedBrew = { + ...this.state.brew, + googleId : res.body.googleId ? res.body.googleId : null, + editId : res.body.editId, + shareId : res.body.shareId, + version : res.body.version + }; history.replaceState(null, null, `/edit/${this.savedBrew.editId}`); this.setState((prevState)=>({ From 2cb8b5d014a3951ab09f9d733a25366a436a6ccf Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 15 Feb 2025 00:12:55 +1300 Subject: [PATCH 32/56] Set brew state to exactly match savedBrew --- client/homebrew/pages/editPage/editPage.jsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index bef4ec1b0..6750023dd 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -256,13 +256,8 @@ const EditPage = createClass({ }; history.replaceState(null, null, `/edit/${this.savedBrew.editId}`); - this.setState((prevState)=>({ - brew : { ...prevState.brew, - googleId : this.savedBrew.googleId ? this.savedBrew.googleId : null, - editId : this.savedBrew.editId, - shareId : this.savedBrew.shareId, - version : this.savedBrew.version - }, + this.setState(()=>({ + brew : this.savedBrew, isPending : false, isSaving : false, unsavedTime : new Date() From 1af66cf571fce7ccc7ff7a5c09a172bd54fb0d33 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 15 Feb 2025 00:13:23 +1300 Subject: [PATCH 33/56] Add default case for SAVE button text --- client/homebrew/pages/editPage/editPage.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 6750023dd..9b08327b1 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -337,6 +337,7 @@ const EditPage = createClass({ if(!this.state.isPending && !this.state.isSaving){ return saved.; } + return no changes.; }, handleAutoSave : function(){ From d6d445dad54c25130450bbe9a5f514fa65795785 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 03:58:22 +0000 Subject: [PATCH 34/56] Bump @babel/plugin-transform-runtime from 7.26.8 to 7.26.9 Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.26.8 to 7.26.9. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.26.9/packages/babel-plugin-transform-runtime) --- updated-dependencies: - dependency-name: "@babel/plugin-transform-runtime" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8afd699c1..cc1e3b939 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "license": "MIT", "dependencies": { "@babel/core": "^7.26.8", - "@babel/plugin-transform-runtime": "^7.26.8", + "@babel/plugin-transform-runtime": "^7.26.9", "@babel/preset-env": "^7.26.8", "@babel/preset-react": "^7.26.3", "@googleapis/drive": "^8.14.0", @@ -1406,9 +1406,9 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.8.tgz", - "integrity": "sha512-H0jlQxFMI0Q8SyGPsj9pO3ygVQRxPkIGytsL3m1Zqca8KrCPpMlvh+e2dxknqdfS8LFwBw+PpiYPD9qy/FPQpA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.9.tgz", + "integrity": "sha512-Jf+8y9wXQbbxvVYTM8gO5oEF2POdNji0NMltEkG7FtmzD9PVz7/lxpqSdTvwsjTMU5HIHuDVNf2SOxLkWi+wPQ==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", diff --git a/package.json b/package.json index 7f9105f04..3ad0049f7 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ }, "dependencies": { "@babel/core": "^7.26.8", - "@babel/plugin-transform-runtime": "^7.26.8", + "@babel/plugin-transform-runtime": "^7.26.9", "@babel/preset-env": "^7.26.8", "@babel/preset-react": "^7.26.3", "@googleapis/drive": "^8.14.0", From f5aa37bd5e3ee0905cc6c6ed8f19d8598f22ac51 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 17 Feb 2025 15:08:47 -0500 Subject: [PATCH 35/56] Change Marked extension to emit
instead of
--- shared/naturalcrit/markdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 99766b536..61ba0669b 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -415,7 +415,7 @@ const forcedParagraphBreaks = { } }, renderer(token) { - return `
`.repeat(token.length).concat('\n'); + return `
`.repeat(token.length).concat('\n'); } }; From 01d93b98d57f1cbf4b973c3c5bb0f858d337ae9e Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 17 Feb 2025 15:09:04 -0500 Subject: [PATCH 36/56] Remove LESS styling for .blank --- .../notificationPopup/notificationPopup.less | 5 ----- client/homebrew/pages/basePages/uiPage/uiPage.less | 5 ----- themes/V3/5ePHB/style.less | 2 +- themes/V3/Blank/style.less | 11 ----------- 4 files changed, 1 insertion(+), 22 deletions(-) diff --git a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less index be642f0fe..6180decc6 100644 --- a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less +++ b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less @@ -85,9 +85,4 @@ display : inline-block; width : 100%; } - .blank { - height : 1em; - margin-top : 0; - & + * { margin-top : 0; } - } } \ No newline at end of file diff --git a/client/homebrew/pages/basePages/uiPage/uiPage.less b/client/homebrew/pages/basePages/uiPage/uiPage.less index 913c74a2e..49cb8311d 100644 --- a/client/homebrew/pages/basePages/uiPage/uiPage.less +++ b/client/homebrew/pages/basePages/uiPage/uiPage.less @@ -59,11 +59,6 @@ padding-left : 1.25em; list-style : square; } - .blank { - height : 1em; - margin-top : 0; - & + * { margin-top : 0; } - } } } } \ No newline at end of file diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index ba975e58a..7cdb01a54 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -679,6 +679,7 @@ padding : 2.25cm 1.3cm 2cm 1.3cm; color : #FFFFFF; columns : 1; + line-height : 1.4em; &::after { display : none; } .columnWrapper { width : 7.6cm; } .backCover { @@ -690,7 +691,6 @@ background-repeat : no-repeat; background-size : contain; } - .blank { height : 1.4em; } h1 { margin-bottom : 0.3cm; font-family : 'NodestoCapsCondensed'; diff --git a/themes/V3/Blank/style.less b/themes/V3/Blank/style.less index 65eeee683..1a22db6a7 100644 --- a/themes/V3/Blank/style.less +++ b/themes/V3/Blank/style.less @@ -427,17 +427,6 @@ body { counter-reset : page-numbers 0; } } } -//***************************** -// * BLANK LINE -// *****************************/ -.page { - .blank { - height : 1em; - margin-top : 0; - & + * { margin-top : 0; } - } -} - //***************************** // * WIDE // *****************************/ From fc065d250bfcf707db9b57028adb97e4a7d3ba95 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Mon, 17 Feb 2025 16:27:22 -0500 Subject: [PATCH 37/56] Fix `useSansSerif()` case (monster stat blocks, descriptiven note, etc.) Removed line-height value that affects only
height. Doesn't impact anywhere else because they all have their own explicit line-heights already. --- themes/V3/5ePHB/style.less | 1 - 1 file changed, 1 deletion(-) diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less index 7cdb01a54..33ba33ff6 100644 --- a/themes/V3/5ePHB/style.less +++ b/themes/V3/5ePHB/style.less @@ -17,7 +17,6 @@ .useSansSerif() { font-family : 'ScalySansRemake'; font-size : 0.318cm; - line-height : 1.2em; p,dl,ul,ol { line-height : 1.2em; } ul, ol { padding-left : 1em; } em { font-style : italic; } From 68f66b2bacd4cc3ed6aff14f7700a0c051d3e26e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 21:47:15 +0000 Subject: [PATCH 38/56] Bump @babel/core from 7.26.8 to 7.26.9 Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.26.8 to 7.26.9. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.26.9/packages/babel-core) --- updated-dependencies: - dependency-name: "@babel/core" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 85 ++++++++++++++++++++++------------------------- package.json | 2 +- 2 files changed, 40 insertions(+), 47 deletions(-) diff --git a/package-lock.json b/package-lock.json index cc1e3b939..7a0126f52 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.26.8", + "@babel/core": "^7.26.9", "@babel/plugin-transform-runtime": "^7.26.9", "@babel/preset-env": "^7.26.8", "@babel/preset-react": "^7.26.3", @@ -110,22 +110,21 @@ } }, "node_modules/@babel/core": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.8.tgz", - "integrity": "sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", + "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.8", + "@babel/generator": "^7.26.9", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.7", - "@babel/parser": "^7.26.8", - "@babel/template": "^7.26.8", - "@babel/traverse": "^7.26.8", - "@babel/types": "^7.26.8", - "@types/gensync": "^1.0.0", + "@babel/helpers": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.9", + "@babel/types": "^7.26.9", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -141,13 +140,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz", - "integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", + "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.8", - "@babel/types": "^7.26.8", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -377,25 +376,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz", - "integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", + "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", "license": "MIT", "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.7" + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz", - "integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", + "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", "license": "MIT", "dependencies": { - "@babel/types": "^7.26.8" + "@babel/types": "^7.26.9" }, "bin": { "parser": "bin/babel-parser.js" @@ -1699,30 +1698,30 @@ } }, "node_modules/@babel/template": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz", - "integrity": "sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.26.8", - "@babel/types": "^7.26.8" + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz", - "integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", + "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.8", - "@babel/parser": "^7.26.8", - "@babel/template": "^7.26.8", - "@babel/types": "^7.26.8", + "@babel/generator": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1740,9 +1739,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz", - "integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", + "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -2871,12 +2870,6 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, - "node_modules/@types/gensync": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.4.tgz", - "integrity": "sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==", - "license": "MIT" - }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", diff --git a/package.json b/package.json index 3ad0049f7..28720691f 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ ] }, "dependencies": { - "@babel/core": "^7.26.8", + "@babel/core": "^7.26.9", "@babel/plugin-transform-runtime": "^7.26.9", "@babel/preset-env": "^7.26.8", "@babel/preset-react": "^7.26.3", From c15e7b2da3f73076c91c4f763b5d95f38eb37258 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 21:53:00 +0000 Subject: [PATCH 39/56] Bump nanoid from 5.0.9 to 5.1.0 Bumps [nanoid](https://github.com/ai/nanoid) from 5.0.9 to 5.1.0. - [Release notes](https://github.com/ai/nanoid/releases) - [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md) - [Commits](https://github.com/ai/nanoid/compare/5.0.9...5.1.0) --- updated-dependencies: - dependency-name: nanoid dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7a0126f52..15d68c60a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", "mongoose": "^8.10.0", - "nanoid": "5.0.9", + "nanoid": "5.1.0", "nconf": "^0.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -10388,9 +10388,9 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/nanoid": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz", - "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.0.tgz", + "integrity": "sha512-zDAl/llz8Ue/EblwSYwdxGBYfj46IM1dhjVi8dyp9LQffoIGxJEAHj2oeZ4uNcgycSRcQ83CnfcZqEJzVDLcDw==", "funding": [ { "type": "github", diff --git a/package.json b/package.json index 28720691f..e71bc32e3 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,7 @@ "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", "mongoose": "^8.10.0", - "nanoid": "5.0.9", + "nanoid": "5.1.0", "nconf": "^0.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", From a11b67f13987083efe8df30229319c9620609fb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 22:02:38 +0000 Subject: [PATCH 40/56] Bump mongoose from 8.10.0 to 8.10.1 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.10.0 to 8.10.1. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.10.0...8.10.1) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 15d68c60a..c3d5c639a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "marked-smartypants-lite": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.10.0", + "mongoose": "^8.10.1", "nanoid": "5.1.0", "nconf": "^0.12.1", "react": "^18.3.1", @@ -10233,9 +10233,9 @@ } }, "node_modules/mongoose": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.10.0.tgz", - "integrity": "sha512-nLhk3Qrv6q/HpD2k1O7kbBqsq+/kmKpdv5KJ+LLhQlII3e1p/SSLoLP6jMuSiU6+iLK7zFw4T1niAk3mA3QVug==", + "version": "8.10.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.10.1.tgz", + "integrity": "sha512-5beTeBZnJNndRXU9rxPol0JmTWZMAtgkPbooROkGilswvrZALDERY4cJrGZmgGwDS9dl0mxiB7si+Mv9Yms2fg==", "license": "MIT", "dependencies": { "bson": "^6.10.1", diff --git a/package.json b/package.json index e71bc32e3..45f867d13 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "marked-smartypants-lite": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.10.0", + "mongoose": "^8.10.1", "nanoid": "5.1.0", "nconf": "^0.12.1", "react": "^18.3.1", From 0564fb82f6a7078e39895efb88489bbd4e79a9b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 02:06:21 +0000 Subject: [PATCH 41/56] Bump @babel/preset-env from 7.26.8 to 7.26.9 Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.26.8 to 7.26.9. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.26.9/packages/babel-preset-env) --- updated-dependencies: - dependency-name: "@babel/preset-env" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 19 ++++++++++--------- package.json | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index c3d5c639a..f80818987 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "dependencies": { "@babel/core": "^7.26.9", "@babel/plugin-transform-runtime": "^7.26.9", - "@babel/preset-env": "^7.26.8", + "@babel/preset-env": "^7.26.9", "@babel/preset-react": "^7.26.3", "@googleapis/drive": "^8.14.0", "body-parser": "^1.20.2", @@ -973,11 +973,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", - "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.26.9.tgz", + "integrity": "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { @@ -1557,9 +1558,9 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.8.tgz", - "integrity": "sha512-um7Sy+2THd697S4zJEfv/U5MHGJzkN2xhtsR3T/SWRbVSic62nbISh51VVfU9JiO/L/Z97QczHTaFVkOU8IzNg==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz", + "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.26.8", @@ -1591,7 +1592,7 @@ "@babel/plugin-transform-dynamic-import": "^7.25.9", "@babel/plugin-transform-exponentiation-operator": "^7.26.3", "@babel/plugin-transform-export-namespace-from": "^7.25.9", - "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.26.9", "@babel/plugin-transform-function-name": "^7.25.9", "@babel/plugin-transform-json-strings": "^7.25.9", "@babel/plugin-transform-literals": "^7.25.9", diff --git a/package.json b/package.json index 45f867d13..b9451f23b 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "dependencies": { "@babel/core": "^7.26.9", "@babel/plugin-transform-runtime": "^7.26.9", - "@babel/preset-env": "^7.26.8", + "@babel/preset-env": "^7.26.9", "@babel/preset-react": "^7.26.3", "@googleapis/drive": "^8.14.0", "body-parser": "^1.20.2", From 9f5a29099c4fd206f1e28d31dcab6891a84a0599 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 19 Feb 2025 13:24:07 +1300 Subject: [PATCH 42/56] Address requested changes --- .../brewRenderer/headerNav/headerNav.jsx | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/client/homebrew/brewRenderer/headerNav/headerNav.jsx b/client/homebrew/brewRenderer/headerNav/headerNav.jsx index 8278e2bd9..d5332f011 100644 --- a/client/homebrew/brewRenderer/headerNav/headerNav.jsx +++ b/client/homebrew/brewRenderer/headerNav/headerNav.jsx @@ -11,18 +11,31 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ const renderHeaderLinks = ()=>{ if(!pagesRef.current) return; - const excludedPages = { - '.frontCover' : 'Cover Page', - '.toc' : 'Contents' + // Top Level Pages + // Pages that contain an element with a specified class will NOT have its content scanned for navigation headers + // e.g. cover pages, table of content pages + // Instead, a label will be added to the navigation at the page level + // --- + // The property name is class that will be used for detecting the page is a top level page + // The property value is a function that returns the text to be used + + const topLevelPages = { + '.frontCover' : (text)=>{ return text ? `Cover: ${text}` : 'Cover Page'; }, + '.insideCover' : (text)=>{ return text ? `Interior: ${text}` : 'Interior Cover Page'; }, + '.partCover' : (text)=>{ return text ? `Section: ${text}` : 'Section Cover Page'; }, + '.backCover' : (text)=>{ return text ? `Back: ${text}` : 'Rear Cover Page'; }, + '.toc' : ()=>{ return 'Table of Contents'; }, }; - const excluded = Object.keys(excludedPages).join(','); + const getTextContent = (el, pageType)=>{ return el.querySelector(pageType).textContent; }; + + const topLevelPageSelector = Object.keys(topLevelPages).join(','); const selector = [ - '.pages > .page', // All page elements, which by definition have IDs - `.page:not(:has(${excluded})) > [id]`, // All direct children of non-excluded .pages with an ID (Legacy) - `.page:not(:has(${excluded})) > .columnWrapper > [id]`, // All direct children of non-excluded .page > .columnWrapper with an ID (V3) - `.page:not(:has(${excluded})) h2`, // All non-excluded H2 titles, like Monster frame titles + '.pages > .page', // All page elements, which by definition have IDs + `.page:not(:has(${topLevelPageSelector})) > [id]`, // All direct children of non-excluded .pages with an ID (Legacy) + `.page:not(:has(${topLevelPageSelector})) > .columnWrapper > [id]`, // All direct children of non-excluded .page > .columnWrapper with an ID (V3) + `.page:not(:has(${topLevelPageSelector})) h2`, // All non-excluded H2 titles, like Monster frame titles ]; const elements = pagesRef.current.querySelectorAll(selector.join(',')); if(!elements) return; @@ -39,9 +52,9 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ elements.forEach((el)=>{ if(el.className.match(/\bpage\b/)) { let text = `Page ${el.id.slice(1)}`; // The ID of a page *should* always be equal to `p` followed by the page number - Object.keys(excludedPages).every((pageType)=>{ - if(el.querySelector(pageType)){ // If the page contains a table of contents, add "- Contents" to the display text - text += ` - ${excludedPages[pageType]}`; + Object.keys(topLevelPages).every((pageType)=>{ + if(el.querySelector(pageType)){ // If a Top Level Page, add the text result to the navigation text + text += ` - ${topLevelPages[pageType](getTextContent(el, pageType))}`; return false; }; return true; From 87d76ea8f67318dcb9dfe92e968dbe1c689a7325 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 19 Feb 2025 13:46:35 +1300 Subject: [PATCH 43/56] Change topLevelPages functions for cover pages --- client/homebrew/brewRenderer/headerNav/headerNav.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/homebrew/brewRenderer/headerNav/headerNav.jsx b/client/homebrew/brewRenderer/headerNav/headerNav.jsx index d5332f011..895b59589 100644 --- a/client/homebrew/brewRenderer/headerNav/headerNav.jsx +++ b/client/homebrew/brewRenderer/headerNav/headerNav.jsx @@ -20,10 +20,10 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ // The property value is a function that returns the text to be used const topLevelPages = { - '.frontCover' : (text)=>{ return text ? `Cover: ${text}` : 'Cover Page'; }, - '.insideCover' : (text)=>{ return text ? `Interior: ${text}` : 'Interior Cover Page'; }, - '.partCover' : (text)=>{ return text ? `Section: ${text}` : 'Section Cover Page'; }, - '.backCover' : (text)=>{ return text ? `Back: ${text}` : 'Rear Cover Page'; }, + '.frontCover' : (el, pageType)=>{ const text = getTextContent(el, pageType); return text ? `Cover: ${text}` : 'Cover Page'; }, + '.insideCover' : (el, pageType)=>{ const text = getTextContent(el, pageType); return text ? `Interior: ${text}` : 'Interior Cover Page'; }, + '.partCover' : (el, pageType)=>{ const text = getTextContent(el, pageType); return text ? `Section: ${text}` : 'Section Cover Page'; }, + '.backCover' : (el, pageType)=>{ const text = getTextContent(el, pageType); return text ? `Back: ${text}` : 'Rear Cover Page'; }, '.toc' : ()=>{ return 'Table of Contents'; }, }; @@ -54,7 +54,7 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ let text = `Page ${el.id.slice(1)}`; // The ID of a page *should* always be equal to `p` followed by the page number Object.keys(topLevelPages).every((pageType)=>{ if(el.querySelector(pageType)){ // If a Top Level Page, add the text result to the navigation text - text += ` - ${topLevelPages[pageType](getTextContent(el, pageType))}`; + text += ` - ${topLevelPages[pageType](el, pageType)}`; return false; }; return true; From ca0f18acd6878a11efad23190b6a49fd66ae7063 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 19 Feb 2025 15:22:08 +1300 Subject: [PATCH 44/56] Update getTextContent function to getHeaderContent --- client/homebrew/brewRenderer/headerNav/headerNav.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/homebrew/brewRenderer/headerNav/headerNav.jsx b/client/homebrew/brewRenderer/headerNav/headerNav.jsx index 895b59589..3d2902da9 100644 --- a/client/homebrew/brewRenderer/headerNav/headerNav.jsx +++ b/client/homebrew/brewRenderer/headerNav/headerNav.jsx @@ -20,14 +20,14 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ // The property value is a function that returns the text to be used const topLevelPages = { - '.frontCover' : (el, pageType)=>{ const text = getTextContent(el, pageType); return text ? `Cover: ${text}` : 'Cover Page'; }, - '.insideCover' : (el, pageType)=>{ const text = getTextContent(el, pageType); return text ? `Interior: ${text}` : 'Interior Cover Page'; }, - '.partCover' : (el, pageType)=>{ const text = getTextContent(el, pageType); return text ? `Section: ${text}` : 'Section Cover Page'; }, - '.backCover' : (el, pageType)=>{ const text = getTextContent(el, pageType); return text ? `Back: ${text}` : 'Rear Cover Page'; }, + '.frontCover' : (el, pageType)=>{ const text = getHeaderContent(el); return text ? `Cover: ${text}` : 'Cover Page'; }, + '.insideCover' : (el, pageType)=>{ const text = getHeaderContent(el); return text ? `Interior: ${text}` : 'Interior Cover Page'; }, + '.partCover' : (el, pageType)=>{ const text = getHeaderContent(el); return text ? `Section: ${text}` : 'Section Cover Page'; }, + '.backCover' : (el, pageType)=>{ const text = getHeaderContent(el); return text ? `Back: ${text}` : 'Rear Cover Page'; }, '.toc' : ()=>{ return 'Table of Contents'; }, }; - const getTextContent = (el, pageType)=>{ return el.querySelector(pageType).textContent; }; + const getHeaderContent = (el)=>{ return el.querySelector('h1')?.textContent; }; const topLevelPageSelector = Object.keys(topLevelPages).join(','); From f421ce1d93e1c3fcb048735ffefa1a5ae3dfcb4c Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 19 Feb 2025 16:10:27 +1300 Subject: [PATCH 45/56] Fix missing depth styling --- client/homebrew/brewRenderer/headerNav/headerNav.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/homebrew/brewRenderer/headerNav/headerNav.less b/client/homebrew/brewRenderer/headerNav/headerNav.less index 8b35041d9..a5769ef99 100644 --- a/client/homebrew/brewRenderer/headerNav/headerNav.less +++ b/client/homebrew/brewRenderer/headerNav/headerNav.less @@ -35,11 +35,11 @@ font-weight: 900; } - @depths: 1,2,3,4,5,6,7; + @depths: 0,1,2,3,4,5,6,7; each(@depths, { &.depth-@{value} { - padding-left: ((@value - 1) * 0.5em); + padding-left: ((@value) * 0.5em); } }); } From 58a22750c554bfafc2163f85f953079077cbc514 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 19 Feb 2025 11:38:38 -0600 Subject: [PATCH 46/56] Update package-lock --- package-lock.json | 147 ++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 76 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5b6e5844b..1020abc8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,9 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.26.8", - "@babel/plugin-transform-runtime": "^7.26.8", - "@babel/preset-env": "^7.26.8", + "@babel/core": "^7.26.9", + "@babel/plugin-transform-runtime": "^7.26.9", + "@babel/preset-env": "^7.26.9", "@babel/preset-react": "^7.26.3", "@googleapis/drive": "^8.14.0", "body-parser": "^1.20.2", @@ -39,11 +39,11 @@ "marked-extended-tables": "^1.1.0", "marked-gfm-heading-id": "^4.0.1", "marked-smartypants-lite": "^1.0.3", - "marked-subsuper-text": "^1.0.1", + "marked-subsuper-text": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.10.0", - "nanoid": "5.0.9", + "mongoose": "^8.10.1", + "nanoid": "5.1.0", "nconf": "^0.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -56,10 +56,10 @@ "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.2", "babel-plugin-transform-import-meta": "^2.3.2", - "eslint": "^9.20.0", + "eslint": "^9.20.1", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", - "globals": "^15.14.0", + "globals": "^15.15.0", "jest": "^29.7.0", "jest-expect-message": "^1.1.3", "jsdom-global": "^3.0.2", @@ -111,22 +111,21 @@ } }, "node_modules/@babel/core": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.8.tgz", - "integrity": "sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", + "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.8", + "@babel/generator": "^7.26.9", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.7", - "@babel/parser": "^7.26.8", - "@babel/template": "^7.26.8", - "@babel/traverse": "^7.26.8", - "@babel/types": "^7.26.8", - "@types/gensync": "^1.0.0", + "@babel/helpers": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.9", + "@babel/types": "^7.26.9", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -142,13 +141,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz", - "integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", + "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.8", - "@babel/types": "^7.26.8", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -378,25 +377,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz", - "integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", + "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", "license": "MIT", "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.7" + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz", - "integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", + "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", "license": "MIT", "dependencies": { - "@babel/types": "^7.26.8" + "@babel/types": "^7.26.9" }, "bin": { "parser": "bin/babel-parser.js" @@ -975,11 +974,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", - "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.26.9.tgz", + "integrity": "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { @@ -1407,9 +1407,9 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.8.tgz", - "integrity": "sha512-H0jlQxFMI0Q8SyGPsj9pO3ygVQRxPkIGytsL3m1Zqca8KrCPpMlvh+e2dxknqdfS8LFwBw+PpiYPD9qy/FPQpA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.9.tgz", + "integrity": "sha512-Jf+8y9wXQbbxvVYTM8gO5oEF2POdNji0NMltEkG7FtmzD9PVz7/lxpqSdTvwsjTMU5HIHuDVNf2SOxLkWi+wPQ==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", @@ -1559,9 +1559,9 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.8.tgz", - "integrity": "sha512-um7Sy+2THd697S4zJEfv/U5MHGJzkN2xhtsR3T/SWRbVSic62nbISh51VVfU9JiO/L/Z97QczHTaFVkOU8IzNg==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz", + "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.26.8", @@ -1593,7 +1593,7 @@ "@babel/plugin-transform-dynamic-import": "^7.25.9", "@babel/plugin-transform-exponentiation-operator": "^7.26.3", "@babel/plugin-transform-export-namespace-from": "^7.25.9", - "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.26.9", "@babel/plugin-transform-function-name": "^7.25.9", "@babel/plugin-transform-json-strings": "^7.25.9", "@babel/plugin-transform-literals": "^7.25.9", @@ -1700,30 +1700,30 @@ } }, "node_modules/@babel/template": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz", - "integrity": "sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.26.8", - "@babel/types": "^7.26.8" + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz", - "integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", + "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.8", - "@babel/parser": "^7.26.8", - "@babel/template": "^7.26.8", - "@babel/types": "^7.26.8", + "@babel/generator": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1741,9 +1741,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz", - "integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", + "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -2872,12 +2872,6 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, - "node_modules/@types/gensync": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.4.tgz", - "integrity": "sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==", - "license": "MIT" - }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -6814,10 +6808,11 @@ } }, "node_modules/globals": { - "version": "15.14.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", - "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -9885,9 +9880,9 @@ } }, "node_modules/marked-subsuper-text": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/marked-subsuper-text/-/marked-subsuper-text-1.0.1.tgz", - "integrity": "sha512-VxKzXdijXd/smeoBcKBJstzxCuTddSvDpsIs1EPhEXCHYfk1MenDxqPXzRrC5kksZe47eptUzg+Bd6EK9HmMbw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/marked-subsuper-text/-/marked-subsuper-text-1.0.3.tgz", + "integrity": "sha512-v5hVVJo6L7HQtplIT8OYNbRWMCGupXYuZ7U9qTsC4yLDtfw24oM5xmWVYfzqzX6hD7KneMfDssMPt6U7fslbxQ==", "license": "MIT", "peerDependencies": { "marked": ">=3 <16" @@ -10248,9 +10243,9 @@ } }, "node_modules/mongoose": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.10.0.tgz", - "integrity": "sha512-nLhk3Qrv6q/HpD2k1O7kbBqsq+/kmKpdv5KJ+LLhQlII3e1p/SSLoLP6jMuSiU6+iLK7zFw4T1niAk3mA3QVug==", + "version": "8.10.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.10.1.tgz", + "integrity": "sha512-5beTeBZnJNndRXU9rxPol0JmTWZMAtgkPbooROkGilswvrZALDERY4cJrGZmgGwDS9dl0mxiB7si+Mv9Yms2fg==", "license": "MIT", "dependencies": { "bson": "^6.10.1", @@ -10403,9 +10398,9 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/nanoid": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz", - "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.0.tgz", + "integrity": "sha512-zDAl/llz8Ue/EblwSYwdxGBYfj46IM1dhjVi8dyp9LQffoIGxJEAHj2oeZ4uNcgycSRcQ83CnfcZqEJzVDLcDw==", "funding": [ { "type": "github", From b36376f9e824693c87bfab83408786c31bb7adec Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Wed, 19 Feb 2025 13:44:28 -0500 Subject: [PATCH 47/56] Linting --- .../brewRenderer/headerNav/headerNav.jsx | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/client/homebrew/brewRenderer/headerNav/headerNav.jsx b/client/homebrew/brewRenderer/headerNav/headerNav.jsx index 3d2902da9..e1ef56fb2 100644 --- a/client/homebrew/brewRenderer/headerNav/headerNav.jsx +++ b/client/homebrew/brewRenderer/headerNav/headerNav.jsx @@ -3,7 +3,6 @@ require('./headerNav.less'); import * as React from 'react'; import * as _ from 'lodash'; - const MAX_TEXT_LENGTH = 40; const HeaderNav = React.forwardRef(({}, pagesRef)=>{ @@ -32,10 +31,10 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ const topLevelPageSelector = Object.keys(topLevelPages).join(','); const selector = [ - '.pages > .page', // All page elements, which by definition have IDs - `.page:not(:has(${topLevelPageSelector})) > [id]`, // All direct children of non-excluded .pages with an ID (Legacy) - `.page:not(:has(${topLevelPageSelector})) > .columnWrapper > [id]`, // All direct children of non-excluded .page > .columnWrapper with an ID (V3) - `.page:not(:has(${topLevelPageSelector})) h2`, // All non-excluded H2 titles, like Monster frame titles + '.pages > .page', // All page elements, which by definition have IDs + `.page:not(:has(${topLevelPageSelector})) > [id]`, // All direct children of non-excluded .pages with an ID (Legacy) + `.page:not(:has(${topLevelPageSelector})) > .columnWrapper > [id]`, // All direct children of non-excluded .page > .columnWrapper with an ID (V3) + `.page:not(:has(${topLevelPageSelector})) h2`, // All non-excluded H2 titles, like Monster frame titles ]; const elements = pagesRef.current.querySelectorAll(selector.join(',')); if(!elements) return; @@ -43,17 +42,17 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ // navList is a list of objects which have the following structure: // { - // depth : how deeply indented the item should be - // text : the text to display in the nav link - // link : the hyperlink to navigate to when clicked - // className : [optional] the class to apply to the nav link for styling + // depth : how deeply indented the item should be + // text : the text to display in the nav link + // link : the hyperlink to navigate to when clicked + // className : [optional] the class to apply to the nav link for styling // } elements.forEach((el)=>{ if(el.className.match(/\bpage\b/)) { - let text = `Page ${el.id.slice(1)}`; // The ID of a page *should* always be equal to `p` followed by the page number + let text = `Page ${el.id.slice(1)}`; // The ID of a page *should* always be equal to `p` followed by the page number Object.keys(topLevelPages).every((pageType)=>{ - if(el.querySelector(pageType)){ // If a Top Level Page, add the text result to the navigation text + if(el.querySelector(pageType)){ // If a Top Level Page, add the text result to the navigation text text += ` - ${topLevelPages[pageType](el, pageType)}`; return false; }; @@ -67,17 +66,17 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ }); return; } - if(el.localName.match(/^h[1-6]/)){ // Header elements H1 through H6 + if(el.localName.match(/^h[1-6]/)){ // Header elements H1 through H6 navList.push({ - depth : el.localName[1], // Depth is set by the header level - text : el.textContent, // Use `textContent` because `innerText` is affected by rendering, e.g. 'content-visibility: auto' + depth : el.localName[1], // Depth is set by the header level + text : el.textContent, // Use `textContent` because `innerText` is affected by rendering, e.g. 'content-visibility: auto' link : el.id }); return; } navList.push({ - depth : 7, // All unmatched elements with IDs are set to the maximum depth (7) - text : el.textContent, // Use `textContent` because `innerText` is affected by rendering, e.g. 'content-visibility: auto' + depth : 7, // All unmatched elements with IDs are set to the maximum depth (7) + text : el.textContent, // Use `textContent` because `innerText` is affected by rendering, e.g. 'content-visibility: auto' link : el.id }); }); From 917b6b314568f95f857c8c25c58d253ce7cfd91b Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Wed, 19 Feb 2025 15:52:52 -0500 Subject: [PATCH 48/56] Shrinking down some logic --- .../brewRenderer/headerNav/headerNav.jsx | 60 +++++++------------ 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/client/homebrew/brewRenderer/headerNav/headerNav.jsx b/client/homebrew/brewRenderer/headerNav/headerNav.jsx index e1ef56fb2..cfc10bbd6 100644 --- a/client/homebrew/brewRenderer/headerNav/headerNav.jsx +++ b/client/homebrew/brewRenderer/headerNav/headerNav.jsx @@ -11,9 +11,8 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ if(!pagesRef.current) return; // Top Level Pages - // Pages that contain an element with a specified class will NOT have its content scanned for navigation headers - // e.g. cover pages, table of content pages - // Instead, a label will be added to the navigation at the page level + // Pages that contain an element with a specified class (e.g. cover pages, table of contents) + // will NOT have its content scanned for navigation headers, instead displaying a custom label // --- // The property name is class that will be used for detecting the page is a top level page // The property value is a function that returns the text to be used @@ -26,7 +25,7 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ '.toc' : ()=>{ return 'Table of Contents'; }, }; - const getHeaderContent = (el)=>{ return el.querySelector('h1')?.textContent; }; + const getHeaderContent = el => el.querySelector('h1')?.textContent; const topLevelPageSelector = Object.keys(topLevelPages).join(','); @@ -49,42 +48,30 @@ const HeaderNav = React.forwardRef(({}, pagesRef)=>{ // } elements.forEach((el)=>{ - if(el.className.match(/\bpage\b/)) { - let text = `Page ${el.id.slice(1)}`; // The ID of a page *should* always be equal to `p` followed by the page number - Object.keys(topLevelPages).every((pageType)=>{ - if(el.querySelector(pageType)){ // If a Top Level Page, add the text result to the navigation text - text += ` - ${topLevelPages[pageType](el, pageType)}`; - return false; - }; - return true; - }); - navList.push({ - depth : 0, // Pages are always at the least indented level - text : text, - link : el.id, - className : 'pageLink' - }); - return; - } - if(el.localName.match(/^h[1-6]/)){ // Header elements H1 through H6 - navList.push({ - depth : el.localName[1], // Depth is set by the header level - text : el.textContent, // Use `textContent` because `innerText` is affected by rendering, e.g. 'content-visibility: auto' - link : el.id - }); - return; - } - navList.push({ + const navEntry = { // Default structure of a navList entry depth : 7, // All unmatched elements with IDs are set to the maximum depth (7) text : el.textContent, // Use `textContent` because `innerText` is affected by rendering, e.g. 'content-visibility: auto' link : el.id - }); - }); - - return _.map(navList, (navItem, index)=>{ - return ; + } + if(el.classList.contains('page')) { + let text = `Page ${el.id.slice(1)}`; // Get the page # by trimming off the 'p' from the ID + const pageType = Object.keys(topLevelPages).find(pageType => el.querySelector(pageType)); + if (pageType) + text += ` - ${topLevelPages[pageType](el, pageType)}` // If a Top Level Page, add extra label + + navEntry.depth = 0; // Pages are always at the least indented level + navEntry.text = text; + navEntry.className = 'pageLink'; + } + else if(el.localName.match(/^h[1-6]/)){ // Header elements H1 through H6 + navEntry.depth = el.localName[1]; // Depth is set by the header level + } + navList.push(navEntry); }); + return _.map(navList, (navItem, index)=> + + ); }; return ; -} -); +}); const HeaderNavItem = ({ link, text, depth, className })=>{ From 578a8d7eba74b93aa8775dc60d072b105cf915f8 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Wed, 19 Feb 2025 16:00:37 -0500 Subject: [PATCH 49/56] Add `\n` after each `
` --- shared/naturalcrit/markdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 61ba0669b..3b9f0e9f0 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -415,7 +415,7 @@ const forcedParagraphBreaks = { } }, renderer(token) { - return `
`.repeat(token.length).concat('\n'); + return `
\n`.repeat(token.length); } }; From 0ba943ceb08b8c396ce673621bb7d6f1914d76a1 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Wed, 19 Feb 2025 16:15:31 -0500 Subject: [PATCH 50/56] Update Test Cases --- tests/markdown/definition-lists.test.js | 4 ++-- tests/markdown/hard-breaks.test.js | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/markdown/definition-lists.test.js b/tests/markdown/definition-lists.test.js index 039754ca1..4c754db48 100644 --- a/tests/markdown/definition-lists.test.js +++ b/tests/markdown/definition-lists.test.js @@ -92,12 +92,12 @@ describe('Multiline Definition Lists', ()=>{ test('Multiline Definition Term must have at least one non-empty Definition', function() { const source = 'Term 1\n::'; const rendered = Markdown.render(source).trim(); - expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Term 1

\n
`); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Term 1

\n
\n
`); }); test('Multiline Definition List must have at least one non-newline character after ::', function() { const source = 'Term 1\n::\nDefinition 1\n\n'; const rendered = Markdown.render(source).trim(); - expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Term 1

\n
\n

Definition 1

`); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Term 1

\n
\n
\n

Definition 1

`); }); }); diff --git a/tests/markdown/hard-breaks.test.js b/tests/markdown/hard-breaks.test.js index 8af102716..fe646eac9 100644 --- a/tests/markdown/hard-breaks.test.js +++ b/tests/markdown/hard-breaks.test.js @@ -6,37 +6,37 @@ describe('Hard Breaks', ()=>{ test('Single Break', function() { const source = ':\n\n'; const rendered = Markdown.render(source).trim(); - expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`); }); test('Double Break', function() { const source = '::\n\n'; const rendered = Markdown.render(source).trim(); - expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
`); }); test('Triple Break', function() { const source = ':::\n\n'; const rendered = Markdown.render(source).trim(); - expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
\n
`); }); test('Many Break', function() { const source = '::::::::::\n\n'; const rendered = Markdown.render(source).trim(); - expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
\n
\n
\n
\n
\n
\n
\n
\n
`); }); test('Multiple sets of Breaks', function() { const source = ':::\n:::\n:::'; const rendered = Markdown.render(source).trim(); - expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
\n
`); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n
\n
\n
\n
\n
\n
\n
\n
`); }); test('Break directly between two paragraphs', function() { const source = 'Line 1\n::\nLine 2'; const rendered = Markdown.render(source).trim(); - expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Line 1

\n
\n

Line 2

`); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Line 1

\n
\n
\n

Line 2

`); }); test('Ignored inside a code block', function() { From 56d18555180d9da4322110f043ef4cf61f0df2e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 03:59:59 +0000 Subject: [PATCH 51/56] Bump react-router from 7.1.5 to 7.2.0 Bumps [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router) from 7.1.5 to 7.2.0. - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router@7.2.0/packages/react-router) --- updated-dependencies: - dependency-name: react-router dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1020abc8e..d17771395 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-frame-component": "^4.1.3", - "react-router": "^7.1.5", + "react-router": "^7.2.0", "sanitize-filename": "1.6.3", "superagent": "^10.1.1", "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" @@ -11671,9 +11671,9 @@ "license": "MIT" }, "node_modules/react-router": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.5.tgz", - "integrity": "sha512-8BUF+hZEU4/z/JD201yK6S+UYhsf58bzYIDq2NS1iGpwxSXDu7F+DeGSkIXMFBuHZB21FSiCzEcUb18cQNdRkA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.2.0.tgz", + "integrity": "sha512-fXyqzPgCPZbqhrk7k3hPcCpYIlQ2ugIXDboHUzhJISFVy2DEPsmHgN588MyGmkIOv3jDgNfUE3kJi83L28s/LQ==", "license": "MIT", "dependencies": { "@types/cookie": "^0.6.0", diff --git a/package.json b/package.json index 3f125ed89..ac27c793a 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-frame-component": "^4.1.3", - "react-router": "^7.1.5", + "react-router": "^7.2.0", "sanitize-filename": "1.6.3", "superagent": "^10.1.1", "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" From b7e422ac067cb207c33225bd08903b1140b558bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 03:57:12 +0000 Subject: [PATCH 52/56] Bump nanoid from 5.1.0 to 5.1.2 Bumps [nanoid](https://github.com/ai/nanoid) from 5.1.0 to 5.1.2. - [Release notes](https://github.com/ai/nanoid/releases) - [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md) - [Commits](https://github.com/ai/nanoid/compare/5.1.0...5.1.2) --- updated-dependencies: - dependency-name: nanoid dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index d17771395..c185a2bc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", "mongoose": "^8.10.1", - "nanoid": "5.1.0", + "nanoid": "5.1.2", "nconf": "^0.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -10398,9 +10398,9 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/nanoid": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.0.tgz", - "integrity": "sha512-zDAl/llz8Ue/EblwSYwdxGBYfj46IM1dhjVi8dyp9LQffoIGxJEAHj2oeZ4uNcgycSRcQ83CnfcZqEJzVDLcDw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.2.tgz", + "integrity": "sha512-b+CiXQCNMUGe0Ri64S9SXFcP9hogjAJ2Rd6GdVxhPLRm7mhGaM7VgOvCAJ1ZshfHbqVDI3uqTI5C8/GaKuLI7g==", "funding": [ { "type": "github", diff --git a/package.json b/package.json index ac27c793a..369646876 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,7 @@ "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", "mongoose": "^8.10.1", - "nanoid": "5.1.0", + "nanoid": "5.1.2", "nconf": "^0.12.1", "react": "^18.3.1", "react-dom": "^18.3.1", From cfb9e1afa2132fec03d33583ea588477fb11bff4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 18:34:06 +0000 Subject: [PATCH 53/56] Bump eslint from 9.20.1 to 9.21.0 Bumps [eslint](https://github.com/eslint/eslint) from 9.20.1 to 9.21.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.20.1...v9.21.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 98 ++++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 51 insertions(+), 49 deletions(-) diff --git a/package-lock.json b/package-lock.json index c185a2bc9..8aa4a5df7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,7 +56,7 @@ "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.2", "babel-plugin-transform-import-meta": "^2.3.2", - "eslint": "^9.20.1", + "eslint": "^9.21.0", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", "globals": "^15.15.0", @@ -1863,12 +1863,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.0.tgz", - "integrity": "sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.4", + "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -1877,10 +1878,11 @@ } }, "node_modules/@eslint/core": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", - "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" }, @@ -1889,10 +1891,11 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", - "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -1916,6 +1919,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -1924,9 +1928,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.20.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz", - "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==", + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz", + "integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==", "dev": true, "license": "MIT", "engines": { @@ -1934,21 +1938,23 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", - "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.10.0", + "@eslint/core": "^0.12.0", "levn": "^0.4.1" }, "engines": { @@ -2016,10 +2022,11 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", - "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18.18" }, @@ -2913,7 +2920,8 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "22.1.0", @@ -3129,6 +3137,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3141,6 +3150,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -3194,6 +3204,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5660,22 +5671,22 @@ "license": "MIT" }, "node_modules/eslint": { - "version": "9.20.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.1.tgz", - "integrity": "sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==", + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.21.0.tgz", + "integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.11.0", - "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.20.0", - "@eslint/plugin-kit": "^0.2.5", + "@eslint/config-array": "^0.19.2", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.21.0", + "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.1", + "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -5836,19 +5847,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/core": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", - "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5919,6 +5917,7 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", @@ -5936,6 +5935,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -9421,7 +9421,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify": { "version": "0.0.1", @@ -14140,6 +14141,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } diff --git a/package.json b/package.json index 369646876..4fb5f8b5a 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.2", "babel-plugin-transform-import-meta": "^2.3.2", - "eslint": "^9.20.1", + "eslint": "^9.21.0", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", "globals": "^15.15.0", From fee88d1d470f7c55475faa47430491460db5d235 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 18:39:19 +0000 Subject: [PATCH 54/56] Bump globals from 15.15.0 to 16.0.0 Bumps [globals](https://github.com/sindresorhus/globals) from 15.15.0 to 16.0.0. - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](https://github.com/sindresorhus/globals/compare/v15.15.0...v16.0.0) --- updated-dependencies: - dependency-name: globals dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8aa4a5df7..ee7bd3c1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,7 +59,7 @@ "eslint": "^9.21.0", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", - "globals": "^15.15.0", + "globals": "^16.0.0", "jest": "^29.7.0", "jest-expect-message": "^1.1.3", "jsdom-global": "^3.0.2", @@ -6808,9 +6808,9 @@ } }, "node_modules/globals": { - "version": "15.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", - "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz", + "integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 4fb5f8b5a..70f096677 100644 --- a/package.json +++ b/package.json @@ -133,7 +133,7 @@ "eslint": "^9.21.0", "eslint-plugin-jest": "^28.11.0", "eslint-plugin-react": "^7.37.4", - "globals": "^15.15.0", + "globals": "^16.0.0", "jest": "^29.7.0", "jest-expect-message": "^1.1.3", "jsdom-global": "^3.0.2", From 9b0da36365d8a6d9b2f3d967a0a6cce00f7b8cec Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Tue, 25 Feb 2025 19:56:23 +1300 Subject: [PATCH 55/56] Rework isPending & hasChanges --- client/homebrew/pages/editPage/editPage.jsx | 42 +++++++++++++-------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 9b08327b1..40c74f9a8 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -102,6 +102,14 @@ const EditPage = createClass({ window.onbeforeunload = function(){}; document.removeEventListener('keydown', this.handleControlKeys); }, + componentDidUpdate : function(){ + const hasChange = this.hasChanges(); + if(this.state.isPending != hasChange){ + this.setState({ + isPending : hasChange + }); + } + }, handleControlKeys : function(e){ if(!(e.ctrlKey || e.metaKey)) return; @@ -138,15 +146,13 @@ const EditPage = createClass({ this.setState((prevState)=>({ brew : { ...prevState.brew, text: text }, - isPending : true, htmlErrors : htmlErrors, }), ()=>{if(this.state.autoSave) this.trySave();}); }, handleStyleChange : function(style){ this.setState((prevState)=>({ - brew : { ...prevState.brew, style: style }, - isPending : true + brew : { ...prevState.brew, style: style } }), ()=>{if(this.state.autoSave) this.trySave();}); }, @@ -158,8 +164,7 @@ const EditPage = createClass({ brew : { ...prevState.brew, ...metadata - }, - isPending : true, + } }), ()=>{if(this.state.autoSave) this.trySave();}); }, @@ -312,7 +317,14 @@ const EditPage = createClass({ }, renderSaveButton : function(){ - if(this.state.autoSaveWarning && this.hasChanges()){ + + // #1 - Currently saving, show SAVING + if(this.state.isSaving){ + return saving...; + } + + // #2 - Unsaved changes exist, autosave is OFF and warning timer has expired, show AUTOSAVE WARNING + if(this.state.isPending && this.state.autoSaveWarning){ this.setAutosaveWarning(); const elapsedTime = Math.round((new Date() - this.state.unsavedTime) / 1000 / 60); const text = elapsedTime == 0 ? 'Autosave is OFF.' : `Autosave is OFF, and you haven't saved for ${elapsedTime} minutes.`; @@ -325,19 +337,17 @@ const EditPage = createClass({ ; } - if(this.state.isSaving){ - return saving...; + // #3 - Unsaved changes exist, click to save, show SAVE NOW + // Use trySave(true) instead of save() to use debounced save function + if(this.state.isPending){ + return this.trySave(true)} color='blue' icon='fas fa-save'>Save Now; } - if(this.state.isPending && this.hasChanges()){ - return Save Now; - } - if(!this.state.isPending && !this.state.isSaving && this.state.autoSave){ + // #4 - No unsaved changes, autosave is ON, show AUTO-SAVED + if(this.state.autoSave){ return auto-saved.; } - if(!this.state.isPending && !this.state.isSaving){ - return saved.; - } - return no changes.; + // DEFAULT - No unsaved changes, show SAVED + return saved.; }, handleAutoSave : function(){ From e9d1209ce8c6656c0faa1c864001ee7fdebf3cf8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 03:33:15 +0000 Subject: [PATCH 56/56] Bump mongoose from 8.10.1 to 8.10.2 Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.10.1 to 8.10.2. - [Release notes](https://github.com/Automattic/mongoose/releases) - [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md) - [Commits](https://github.com/Automattic/mongoose/compare/8.10.1...8.10.2) --- updated-dependencies: - dependency-name: mongoose dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index ee7bd3c1e..063f1b0fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "marked-subsuper-text": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.10.1", + "mongoose": "^8.10.2", "nanoid": "5.1.2", "nconf": "^0.12.1", "react": "^18.3.1", @@ -10244,9 +10244,9 @@ } }, "node_modules/mongoose": { - "version": "8.10.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.10.1.tgz", - "integrity": "sha512-5beTeBZnJNndRXU9rxPol0JmTWZMAtgkPbooROkGilswvrZALDERY4cJrGZmgGwDS9dl0mxiB7si+Mv9Yms2fg==", + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.10.2.tgz", + "integrity": "sha512-DvqfK1s/JLwP39ogXULC8ygNDdmDber5ZbxZzELYtkzl9VGJ3K5T2MCLdpTs9I9J6DnkDyIHJwt7IOyMxh/Adw==", "license": "MIT", "dependencies": { "bson": "^6.10.1", diff --git a/package.json b/package.json index 70f096677..bbd99bac5 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "marked-subsuper-text": "^1.0.3", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^8.10.1", + "mongoose": "^8.10.2", "nanoid": "5.1.2", "nconf": "^0.12.1", "react": "^18.3.1",