0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-06-24 13:18:39 +00:00

Merge branch 'master' into V4_Persistant_Templates

Change enable_v4 to enableV4 to shut up linter.
This commit is contained in:
David Bolack
2026-05-29 21:06:55 -05:00
133 changed files with 9228 additions and 10052 deletions
+25 -11
View File
@@ -1,10 +1,12 @@
/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/
import brewRendererStylesUrl from './brewRenderer.less?url';
import headerNavStylesUrl from './headerNav/headerNav.less?url';
import './brewRenderer.less';
import React, { useState, useRef, useMemo, useEffect } from 'react';
import _ from 'lodash';
import MarkdownLegacy from '../../../shared/markdownLegacy.js';
import Markdown from '../../../shared/markdown.js';
import MarkdownLegacy from '@shared/markdownLegacy.js';
import Markdown from '@shared/markdown.js';
import ErrorBar from './errorBar/errorBar.jsx';
import ToolBar from './toolBar/toolBar.jsx';
@@ -13,10 +15,10 @@ import RenderWarnings from '../../components/renderWarnings/renderWarnings.jsx';
import NotificationPopup from './notificationPopup/notificationPopup.jsx';
import Frame from 'react-frame-component';
import dedent from 'dedent';
import { printCurrentBrew } from '../../../shared/helpers.js';
import { printCurrentBrew } from '@shared/helpers.js';
import HeaderNav from './headerNav/headerNav.jsx';
import { safeHTML } from './safeHTML.js';
import safeHTML from './safeHTML.js';
const PAGEBREAK_REGEX_V3 = /^(?=\\page(?:break)?(?: *{[^\n{}]*})?$)/m;
const PAGEBREAK_REGEX_LEGACY = /\\page(?:break)?/m;
@@ -27,9 +29,10 @@ const TOOLBAR_STATE_KEY = 'HB_renderer_toolbarState';
const INITIAL_CONTENT = dedent`
<!DOCTYPE html><html><head>
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600,700" rel="stylesheet" type="text/css" />
<link href='/homebrew/bundle.css' type="text/css" rel='stylesheet' />
<base target=_blank>
<link href="${brewRendererStylesUrl}" rel="stylesheet" />
<link href="${headerNavStylesUrl}" rel="stylesheet" />
<base target="_top">
</head><body style='overflow: hidden'><div></div></body></html>`;
@@ -38,6 +41,7 @@ const BrewPage = (props)=>{
props = {
contents : '',
index : 0,
hoisted : false,
...props
};
const pageRef = useRef(null);
@@ -132,6 +136,7 @@ const BrewRenderer = (props)=>{
const mainRef = useRef(null);
const pagesRef = useRef(null);
const urlRef = useRef('');
if(props.renderer == 'legacy') {
rawPages = props.text.split(PAGEBREAK_REGEX_LEGACY);
@@ -204,13 +209,13 @@ const BrewRenderer = (props)=>{
styles = _.mapKeys(styles, (v, k)=>k.startsWith('--') ? k : _.camelCase(k)); // Convert CSS to camelCase for React
classes = [classes, injectedTags.classes].join(' ').trim();
attributes = injectedTags.attributes;
if(global.enable_v4) {
if(global.enablev4) {
if (attributes && Object.hasOwn(attributes, 'hbtemplate')) {
pageTemplates[index] = attributes['hbtemplate'];
}
}
}
if(global.enable_v4) {
if(global.enablev4) {
// If we don't have a template for this page, look backwards until one is found or the first page.
if(!pageTemplates[index]) {
for (let i=index;i>=0; i--) {
@@ -231,7 +236,8 @@ const BrewRenderer = (props)=>{
}
};
const renderPages = ()=>{
const renderPages = (checkHoists = false)=>{
if(props.errors && props.errors.length)
return renderedPages;
@@ -245,10 +251,16 @@ const BrewRenderer = (props)=>{
renderedPages[props.currentEditorCursorPageNum - 1] = renderPage(rawPages[props.currentEditorCursorPageNum - 1], props.currentEditorCursorPageNum - 1);
_.forEach(rawPages, (page, index)=>{
if((isInView(index) || !renderedPages[index]) && typeof window !== 'undefined'){
const varsOnPageRegex = /([!$]?)\[((?!\s*\])(?:\\.|[^\[\]\\])+)\]/g; // Find out if there are any vars on the page.
const forceRender = checkHoists &&
!props.hoisted &&
(page.match(varsOnPageRegex)); // forceRender forces pages outside of the PPR range to render if true.
// This is necessary on the first load to fully populate the variable table.
if((isInView(index) || !renderedPages[index] || forceRender) && typeof window !== 'undefined'){
renderedPages[index] = renderPage(page, index); // Render any page not yet rendered, but only re-render those in PPR range
}
});
if(!props.hoisted) { props.hoisted = true; } // Only fully hoist once.
return renderedPages;
};
@@ -285,8 +297,10 @@ const BrewRenderer = (props)=>{
const frameDidMount = ()=>{ //This triggers when iFrame finishes internal "componentDidMount"
scrollToHash(window.location.hash);
window.addEventListener('hashchange', ()=>scrollToHash(window.location.hash));
setTimeout(()=>{ //We still see a flicker where the style isn't applied yet, so wait 100ms before showing iFrame
renderPages(); //Make sure page is renderable before showing
renderPages(true); //Make sure page is renderable before showing
setState((prevState)=>({
...prevState,
isMounted : true,
@@ -1,4 +1,4 @@
@import (multiple, less) 'shared/naturalcrit/styles/reset.less';
@import '@sharedStyles/core.less';
.brewRenderer {
height : 100vh;
@@ -1,3 +1,4 @@
@import '@sharedStyles/colors.less';
.errorBar {
position : absolute;
@@ -104,7 +104,7 @@ const HeaderNavItem = ({ link, text, depth, className })=>{
if(!link || !text) return;
return <li>
<a href={`#${link}`} target='_self' className={`depth-${depth} ${className ?? ''}`}>
<a href={`#${link}`} className={`depth-${depth} ${className ?? ''}`}>
{trimString(text, depth)}
</a>
</li>;
@@ -1,7 +1,7 @@
import './notificationPopup.less';
import React, { useEffect, useState } from 'react';
import request from '../../utils/request-middleware.js';
import Markdown from 'markdown.js';
import Markdown from '@shared/markdown.js';
import Dialog from '../../../components/dialog.jsx';
@@ -1,3 +1,5 @@
@import './client/homebrew/navbar/navbar.less';
.popups {
position : fixed;
top : calc(@navbarHeight + @viewerToolsHeight);
+1 -1
View File
@@ -43,4 +43,4 @@ function safeHTML(htmlString) {
return div.innerHTML;
};
module.exports.safeHTML = safeHTML;
export default safeHTML;