0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2025-12-24 18:32:41 +00:00

Merge branch 'master' into experimentalLocalStorageHistory

This commit is contained in:
Trevor Buckner
2024-09-16 01:50:54 -04:00
committed by GitHub
12 changed files with 64 additions and 65 deletions

View File

@@ -17,7 +17,7 @@ const NotificationPopup = ()=>{
<ul>
<li key='Vault'>
<em>Search brews with our new page!</em><br />
We have been working very hard in making this possible, now you can share your work and look at it in the new <a href="/vault">Vault</a> page!
We have been working very hard in making this possible, now you can share your work and look at it in the new <a href='/vault'>Vault</a> page!
All PUBLISHED brews will be available to anyone searching there, by title or author, and filtering by renderer.
More features will be coming.

View File

@@ -56,7 +56,7 @@ const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{
} else if(mode == 'fit'){
// find the page with the largest single dim (height or width) so that zoom can be adapted to fit it.
const minDimRatio = [...pages].reduce((minRatio, page) => Math.min(minRatio, iframeWidth / page.offsetWidth, iframeHeight / page.offsetHeight), Infinity);
const minDimRatio = [...pages].reduce((minRatio, page)=>Math.min(minRatio, iframeWidth / page.offsetWidth, iframeHeight / page.offsetHeight), Infinity);
desiredZoom = minDimRatio * 100;
}
@@ -67,9 +67,9 @@ const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{
return deltaZoom;
};
return (
return (
<div className={`toolBar ${toolsVisible ? 'visible' : 'hidden'}`}>
<button className='toggleButton' title={`${toolsVisible ? 'Hide' : 'Show'} Preview Toolbar`} onClick={()=>{setToolsVisible(!toolsVisible)}}><i className='fas fa-glasses' /></button>
<button className='toggleButton' title={`${toolsVisible ? 'Hide' : 'Show'} Preview Toolbar`} onClick={()=>{setToolsVisible(!toolsVisible);}}><i className='fas fa-glasses' /></button>
{/*v=====----------------------< Zoom Controls >---------------------=====v*/}
<div className='group'>
<button

View File

@@ -36,7 +36,7 @@ const Editor = createClass({
onStyleChange : ()=>{},
onMetaChange : ()=>{},
reportError : ()=>{},
onCursorPageChange : ()=>{},
onViewPageChange : ()=>{},
@@ -45,7 +45,7 @@ const Editor = createClass({
currentEditorCursorPageNum : 1,
currentEditorViewPageNum : 1,
currentBrewRendererPageNum : 1,
currentBrewRendererPageNum : 1,
};
},
getInitialState : function() {
@@ -70,8 +70,8 @@ const Editor = createClass({
document.getElementById('BrewRenderer').addEventListener('keydown', this.handleControlKeys);
document.addEventListener('keydown', this.handleControlKeys);
this.codeEditor.current.codeMirror.on('cursorActivity', (cm)=>{this.updateCurrentCursorPage(cm.getCursor())});
this.codeEditor.current.codeMirror.on('scroll', _.throttle(()=>{this.updateCurrentViewPage(this.codeEditor.current.getTopVisibleLine())}, 200));
this.codeEditor.current.codeMirror.on('cursorActivity', (cm)=>{this.updateCurrentCursorPage(cm.getCursor());});
this.codeEditor.current.codeMirror.on('scroll', _.throttle(()=>{this.updateCurrentViewPage(this.codeEditor.current.getTopVisibleLine());}, 200));
const editorTheme = window.localStorage.getItem(EDITOR_THEME_KEY);
if(editorTheme) {
@@ -109,9 +109,9 @@ const Editor = createClass({
if(!(e.ctrlKey && e.metaKey && e.shiftKey)) return;
const LEFTARROW_KEY = 37;
const RIGHTARROW_KEY = 39;
if (e.keyCode == RIGHTARROW_KEY) this.brewJump();
if (e.keyCode == LEFTARROW_KEY) this.sourceJump();
if (e.keyCode == LEFTARROW_KEY || e.keyCode == RIGHTARROW_KEY) {
if(e.keyCode == RIGHTARROW_KEY) this.brewJump();
if(e.keyCode == LEFTARROW_KEY) this.sourceJump();
if(e.keyCode == LEFTARROW_KEY || e.keyCode == RIGHTARROW_KEY) {
e.stopPropagation();
e.preventDefault();
}
@@ -128,14 +128,14 @@ const Editor = createClass({
updateCurrentCursorPage : function(cursor) {
const lines = this.props.brew.text.split('\n').slice(0, cursor.line + 1);
const pageRegex = this.props.brew.renderer == 'V3' ? /^\\page$/ : /\\page/;
const currentPage = lines.reduce((count, line) => count + (pageRegex.test(line) ? 1 : 0), 1);
const currentPage = lines.reduce((count, line)=>count + (pageRegex.test(line) ? 1 : 0), 1);
this.props.onCursorPageChange(currentPage);
},
updateCurrentViewPage : function(topScrollLine) {
const lines = this.props.brew.text.split('\n').slice(0, topScrollLine + 1);
const pageRegex = this.props.brew.renderer == 'V3' ? /^\\page$/ : /\\page/;
const currentPage = lines.reduce((count, line) => count + (pageRegex.test(line) ? 1 : 0), 1);
const currentPage = lines.reduce((count, line)=>count + (pageRegex.test(line) ? 1 : 0), 1);
this.props.onViewPageChange(currentPage);
},
@@ -322,10 +322,10 @@ const Editor = createClass({
const currentPos = brewRenderer.scrollTop;
const targetPos = window.frames['BrewRenderer'].contentDocument.getElementById(`p${targetPage}`).getBoundingClientRect().top;
const checkIfScrollComplete = () => {
const checkIfScrollComplete = ()=>{
let scrollingTimeout;
clearTimeout(scrollingTimeout); // Reset the timer every time a scroll event occurs
scrollingTimeout = setTimeout(() => {
scrollingTimeout = setTimeout(()=>{
isJumping = false;
brewRenderer.removeEventListener('scroll', checkIfScrollComplete);
}, 150); // If 150 ms pass without a brewRenderer scroll event, assume scrolling is done
@@ -364,16 +364,16 @@ const Editor = createClass({
let currentY = this.codeEditor.current.codeMirror.getScrollInfo().top;
let targetY = this.codeEditor.current.codeMirror.heightAtLine(targetLine, 'local', true);
const checkIfScrollComplete = () => {
const checkIfScrollComplete = ()=>{
let scrollingTimeout;
clearTimeout(scrollingTimeout); // Reset the timer every time a scroll event occurs
scrollingTimeout = setTimeout(() => {
scrollingTimeout = setTimeout(()=>{
isJumping = false;
this.codeEditor.current.codeMirror.off('scroll', checkIfScrollComplete);
}, 150); // If 150 ms pass without a scroll event, assume scrolling is done
};
isJumping = true;
checkIfScrollComplete();
this.codeEditor.current.codeMirror.on('scroll', checkIfScrollComplete);

View File

@@ -111,7 +111,7 @@ const ErrorNavItem = createClass({
Looks like there was a problem retreiving
the theme, or a theme that it inherits,
for this brew. Verify that brew <a className='lowercase' target='_blank' rel='noopener noreferrer' href={`/share/${response.body.brewId}`}>
{response.body.brewId}</a> still exists!
{response.body.brewId}</a> still exists!
</div>
</Nav.item>;
}

View File

@@ -330,7 +330,7 @@ const VaultPage = (props)=>{
if(error) {
const errorText = ErrorIndex()[error.HBErrorCode.toString()] || '';
return (
<div className='foundBrews noBrews'>
<h3>Error: {errorText}</h3>

11
package-lock.json generated
View File

@@ -25,7 +25,7 @@
"expr-eval": "^2.0.2",
"express": "^4.21.0",
"express-async-handler": "^1.2.0",
"express-static-gzip": "2.1.7",
"express-static-gzip": "2.1.8",
"fs-extra": "11.2.0",
"js-yaml": "^4.1.0",
"jwt-simple": "^0.5.6",
@@ -6362,12 +6362,11 @@
"license": "MIT"
},
"node_modules/express-static-gzip": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.7.tgz",
"integrity": "sha512-QOCZUC+lhPPCjIJKpQGu1Oa61Axg9Mq09Qvit8Of7kzpMuwDeMSqjjQteQS3OVw/GkENBoSBheuQDWPlngImvw==",
"license": "MIT",
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/express-static-gzip/-/express-static-gzip-2.1.8.tgz",
"integrity": "sha512-g8tiJuI9Y9Ffy59ehVXvqb0hhP83JwZiLxzanobPaMbkB5qBWA8nuVgd+rcd5qzH3GkgogTALlc0BaADYwnMbQ==",
"dependencies": {
"serve-static": "^1.14.1"
"serve-static": "^1.16.2"
}
},
"node_modules/express/node_modules/cookie": {

View File

@@ -100,7 +100,7 @@
"expr-eval": "^2.0.2",
"express": "^4.21.0",
"express-async-handler": "^1.2.0",
"express-static-gzip": "2.1.7",
"express-static-gzip": "2.1.8",
"fs-extra": "11.2.0",
"js-yaml": "^4.1.0",
"jwt-simple": "^0.5.6",

View File

@@ -934,7 +934,7 @@ brew`);
expect(req.brew).toEqual(testBrew);
expect(req.brew).toHaveProperty('style', '\nI Have a style!\n');
expect(res.status).toHaveBeenCalledWith(200);
expect(res.send).toHaveBeenCalledWith("\nI Have a style!\n");
expect(res.send).toHaveBeenCalledWith('\nI Have a style!\n');
expect(res.set).toHaveBeenCalledWith({
'Cache-Control' : 'no-cache',
'Content-Type' : 'text/css'

View File

@@ -49,12 +49,12 @@ const CodeEditor = createClass({
displayName : 'CodeEditor',
getDefaultProps : function() {
return {
language : '',
value : '',
wrap : true,
onChange : ()=>{},
enableFolding : true,
editorTheme : 'default'
language : '',
value : '',
wrap : true,
onChange : ()=>{},
enableFolding : true,
editorTheme : 'default'
};
},
@@ -189,7 +189,7 @@ const CodeEditor = createClass({
autoCompleteEmoji.showAutocompleteEmoji(CodeMirror, this.codeMirror);
// Note: codeMirror passes a copy of itself in this callback. cm === this.codeMirror. Either one works.
this.codeMirror.on('change', (cm)=>{this.props.onChange(cm.getValue())});
this.codeMirror.on('change', (cm)=>{this.props.onChange(cm.getValue());});
this.updateSize();
},
@@ -399,7 +399,7 @@ const CodeEditor = createClass({
},
getTopVisibleLine : function(){
const rect = this.codeMirror.getWrapperElement().getBoundingClientRect();
const topVisibleLine = this.codeMirror.lineAtHeight(rect.top, "window");
const topVisibleLine = this.codeMirror.lineAtHeight(rect.top, 'window');
return topVisibleLine;
},
updateSize : function(){

View File

@@ -105,16 +105,16 @@ renderer.link = function (href, title, text) {
// Expose `src` attribute as `--HB_src` to make the URL accessible via CSS
renderer.image = function (href, title, text) {
href = cleanUrl(href);
if (href === null)
if(href === null)
return text;
let out = `<img src="${href}" alt="${text}" style="--HB_src:url(${href});"`;
if (title)
if(title)
out += ` title="${title}"`;
out += '>';
return out;
}
};
// Disable default reflink behavior, as it steps on our variables extension
tokenizer.def = function () {
@@ -745,7 +745,7 @@ const tableTerminators = [
`:+\\n`, // hardBreak
` *{[^\n]+}`, // blockInjector
` *{{[^{\n]*\n.*?\n}}` // mustacheDiv
]
];
Marked.use(MarkedVariables());
Marked.use({ extensions : [definitionListsMultiLine, definitionListsSingleLine, forcedParagraphBreaks, superSubScripts,
@@ -755,12 +755,12 @@ Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false });
Marked.use(MarkedExtendedTables(tableTerminators), MarkedGFMHeadingId({ globalSlugs: true }), MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions));
function cleanUrl(href) {
try {
href = encodeURI(href).replace(/%25/g, '%');
} catch {
return null;
}
return href;
try {
href = encodeURI(href).replace(/%25/g, '%');
} catch {
return null;
}
return href;
}
const escapeTest = /[&<>"']/;

View File

@@ -15,12 +15,12 @@ const SplitPane = createClass({
getInitialState : function() {
return {
currentDividerPos : null,
windowWidth : 0,
isDragging : false,
moveSource : false,
moveBrew : false,
showMoveArrows : true
currentDividerPos : null,
windowWidth : 0,
isDragging : false,
moveSource : false,
moveBrew : false,
showMoveArrows : true
};
},
@@ -45,7 +45,7 @@ const SplitPane = createClass({
// This lives here instead of in the initial render because you cannot touch localStorage until the componant mounts.
const loadLiveScroll = window.localStorage.getItem('liveScroll') === 'true';
this.setState({ liveScroll : loadLiveScroll });
this.setState({ liveScroll: loadLiveScroll });
},
componentWillUnmount : function() {
@@ -130,7 +130,7 @@ const SplitPane = createClass({
<i className='fas fa-arrow-right' />
</div>
<div id='scrollToggleDiv' className={this.state.liveScroll ? 'arrow lock' : 'arrow unlock'}
style={{ left: this.state.currentDividerPos-4 }}
style={{ left: this.state.currentDividerPos-4 }}
onClick={this.liveScrollToggle} >
<i id='scrollToggle' className={this.state.liveScroll ? 'fas fa-lock' : 'fas fa-unlock'} />
</div>
@@ -160,7 +160,7 @@ const SplitPane = createClass({
...(this.props.showDividerButtons && {
moveBrew : this.state.moveBrew,
moveSource : this.state.moveSource,
liveScroll : this.state.liveScroll,
liveScroll : this.state.liveScroll,
setMoveArrows : this.setMoveArrows,
}),
})}

View File

@@ -4,9 +4,9 @@ const dedent = require('dedent-tabs').default;
const mapPages = (pages)=>{
let actualPage = 0;
let mappedPage = 0; // Number displayed in footer
let pageMap = [];
const pageMap = [];
pages.forEach(page => {
pages.forEach((page)=>{
actualPage++;
const doSkip = page.querySelector('.skipCounting');
const doReset = page.querySelector('.resetCounting');
@@ -24,13 +24,13 @@ const mapPages = (pages)=>{
return pageMap;
};
const getMarkdown = (headings, pageMap) => {
const getMarkdown = (headings, pageMap)=>{
const levelPad = ['- ###', ' - ####', ' -', ' -', ' -', ' -'];
let allMarkdown = [];
let depthChain = [0];
headings.forEach(heading => {
const allMarkdown = [];
const depthChain = [0];
headings.forEach((heading)=>{
const page = parseInt(heading.closest('.page').id?.replace(/^p/, ''));
const mappedPage = pageMap[page].mappedPage;
const showPage = pageMap[page].showPage;
@@ -42,14 +42,14 @@ const getMarkdown = (headings, pageMap) => {
return;
//If different header depth than last, remove indents until nearest higher-level header, then indent once
if (depth !== depthChain[depthChain.length -1]) {
if(depth !== depthChain[depthChain.length -1]) {
while (depth <= depthChain[depthChain.length - 1]) {
depthChain.pop();
}
depthChain.push(depth);
}
let markdown = `${levelPad[depthChain.length - 2]} [{{ ${title}}}{{ ${mappedPage}}}](#p${page})`;
const markdown = `${levelPad[depthChain.length - 2]} [{{ ${title}}}{{ ${mappedPage}}}](#p${page})`;
allMarkdown.push(markdown);
});
return allMarkdown.join('\n');