Skip to content

Commit

Permalink
Merge branch 'master' into addLockNotification-naturalcrit#3326
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Ambatte committed Jun 1, 2024
2 parents 632efe8 + a2f0546 commit 2424d34
Show file tree
Hide file tree
Showing 52 changed files with 1,548 additions and 603 deletions.
1 change: 0 additions & 1 deletion client/admin/brewCleanup/brewCleanup.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
require('./brewCleanup.less');
const React = require('react');
const createClass = require('create-react-class');
const cx = require('classnames');

const request = require('superagent');

Expand Down
1 change: 0 additions & 1 deletion client/admin/brewCompress/brewCompress.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
require('./brewCompress.less');
const React = require('react');
const createClass = require('create-react-class');
const cx = require('classnames');

const request = require('superagent');

Expand Down
1 change: 0 additions & 1 deletion client/components/combobox.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const cx = require('classnames');
require('./combobox.less');

const Combobox = createClass({
Expand Down
41 changes: 25 additions & 16 deletions client/homebrew/brewRenderer/brewRenderer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const RenderWarnings = require('homebrewery/renderWarnings/renderWarnings.jsx');
const NotificationPopup = require('./notificationPopup/notificationPopup.jsx');
const Frame = require('react-frame-component').default;
const dedent = require('dedent-tabs').default;
const { printCurrentBrew } = require('../../../shared/helpers.js');

const DOMPurify = require('dompurify');
const purifyConfig = { FORCE_BODY: true, SANITIZE_DOM: false };

const Themes = require('themes/themes.json');

Expand All @@ -33,8 +37,9 @@ const BrewPage = (props)=>{
index : 0,
...props
};
const cleanText = DOMPurify.sanitize(props.contents, purifyConfig);
return <div className={props.className} id={`p${props.index + 1}`} >
<div className='columnWrapper' dangerouslySetInnerHTML={{ __html: props.contents }} />
<div className='columnWrapper' dangerouslySetInnerHTML={{ __html: cleanText }} />
</div>;
};

Expand Down Expand Up @@ -102,13 +107,6 @@ const BrewRenderer = (props)=>{
return false;
};

const sanitizeScriptTags = (content)=>{
return content
?.replace(/<script/ig, '&lt;script')
.replace(/<\/script>/ig, '&lt;/script&gt;')
|| '';
};

const renderPageInfo = ()=>{
return <div className='pageInfo' ref={mainRef}>
<div>
Expand All @@ -128,19 +126,18 @@ const BrewRenderer = (props)=>{

const renderStyle = ()=>{
if(!props.style) return;
const cleanStyle = sanitizeScriptTags(props.style);
const cleanStyle = DOMPurify.sanitize(props.style, purifyConfig);
//return <div style={{ display: 'none' }} dangerouslySetInnerHTML={{ __html: `<style>@layer styleTab {\n${sanitizeScriptTags(props.style)}\n} </style>` }} />;
return <div style={{ display: 'none' }} dangerouslySetInnerHTML={{ __html: `<style> ${cleanStyle} </style>` }} />;
};

const renderPage = (pageText, index)=>{
let cleanPageText = sanitizeScriptTags(pageText);
if(props.renderer == 'legacy') {
const html = MarkdownLegacy.render(cleanPageText);
const html = MarkdownLegacy.render(pageText);
return <BrewPage className='page phb' index={index} key={index} contents={html} />;
} else {
cleanPageText += `\n\n&nbsp;\n\\column\n&nbsp;`; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear)
const html = Markdown.render(cleanPageText, index);
pageText += `\n\n&nbsp;\n\\column\n&nbsp;`; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear)
const html = Markdown.render(pageText, index);
return <BrewPage className='page' index={index} key={index} contents={html} />;
}
};
Expand All @@ -163,6 +160,16 @@ const BrewRenderer = (props)=>{
return renderedPages;
};

const handleControlKeys = (e)=>{
if(!(e.ctrlKey || e.metaKey)) return;
const P_KEY = 80;
if(e.keyCode == P_KEY && props.allowPrint) printCurrentBrew();
if(e.keyCode == P_KEY) {
e.stopPropagation();
e.preventDefault();
}
};

const frameDidMount = ()=>{ //This triggers when iFrame finishes internal "componentDidMount"
setTimeout(()=>{ //We still see a flicker where the style isn't applied yet, so wait 100ms before showing iFrame
updateSize();
Expand Down Expand Up @@ -204,18 +211,20 @@ const BrewRenderer = (props)=>{
>
<div className={'brewRenderer'}
onScroll={handleScroll}
onKeyDown={handleControlKeys}
tabIndex={-1}
style={{ height: state.height }}>

<ErrorBar errors={props.errors} />
<div className='popups'>
<RenderWarnings />
<NotificationPopup />
</div>
<link href={`/themes/${rendererPath}/Blank/style.css`} type="text/css" rel='stylesheet'/>
<link href={`/themes/${rendererPath}/Blank/style.css`} type='text/css' rel='stylesheet'/>
{baseThemePath &&
<link href={`/themes/${rendererPath}/${baseThemePath}/style.css`} type="text/css" rel='stylesheet'/>
<link href={`/themes/${rendererPath}/${baseThemePath}/style.css`} type='text/css' rel='stylesheet'/>
}
<link href={`/themes/${rendererPath}/${themePath}/style.css`} type="text/css" rel='stylesheet'/>
<link href={`/themes/${rendererPath}/${themePath}/style.css`} type='text/css' rel='stylesheet'/>

{/* Apply CSS from Style tab and render pages from Markdown tab */}
{state.isMounted
Expand Down
13 changes: 13 additions & 0 deletions client/homebrew/brewRenderer/brewRenderer.less
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,16 @@
color : white;
background-color : #333333;
}

@media print {
.brewRenderer {
height: 100%;
overflow-y: unset;
.pages {
margin: 0px;
&>.page {
box-shadow: unset;
}
}
}
}
1 change: 0 additions & 1 deletion client/homebrew/brewRenderer/errorBar/errorBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ require('./errorBar.less');
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const cx = require('classnames');

const ErrorBar = createClass({
displayName : 'ErrorBar',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ require('./notificationPopup.less');
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const cx = require('classnames'); //Unused variable

const DISMISS_KEY = 'dismiss_notification12-04-23';

Expand All @@ -26,8 +25,8 @@ const NotificationPopup = createClass({
<>
<li key='psa'>
<em>Don't store IMAGES in Google Drive</em><br />
Google Drive is not an image service, and will block images from being used
in brews if they get more views than expected. Google has confirmed they won't fix
Google Drive is not an image service, and will block images from being used
in brews if they get more views than expected. Google has confirmed they won't fix
this, so we recommend you look for another image hosting service such as imgur, ImgBB or Google Photos.
</li>

Expand Down
51 changes: 27 additions & 24 deletions client/homebrew/editor/editor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ const Editor = createClass({
};
},

editor : React.createRef(null),
codeEditor : React.createRef(null),

isText : function() {return this.state.view == 'text';},
isStyle : function() {return this.state.view == 'style';},
isMeta : function() {return this.state.view == 'meta';},
Expand Down Expand Up @@ -80,15 +83,15 @@ const Editor = createClass({
},

updateEditorSize : function() {
if(this.refs.codeEditor) {
let paneHeight = this.refs.main.parentNode.clientHeight;
if(this.codeEditor.current) {
let paneHeight = this.editor.current.parentNode.clientHeight;
paneHeight -= SNIPPETBAR_HEIGHT;
this.refs.codeEditor.codeMirror.setSize(null, paneHeight);
this.codeEditor.current.codeMirror.setSize(null, paneHeight);
}
},

handleInject : function(injectText){
this.refs.codeEditor?.injectText(injectText, false);
this.codeEditor.current?.injectText(injectText, false);
},

handleViewChange : function(newView){
Expand All @@ -99,7 +102,7 @@ const Editor = createClass({
},

getCurrentPage : function(){
const lines = this.props.brew.text.split('\n').slice(0, this.refs.codeEditor.getCursorPosition().line + 1);
const lines = this.props.brew.text.split('\n').slice(0, this.codeEditor.current.getCursorPosition().line + 1);
return _.reduce(lines, (r, line)=>{
if(
(this.props.renderer == 'legacy' && line.indexOf('\\page') !== -1)
Expand All @@ -111,9 +114,9 @@ const Editor = createClass({
},

highlightCustomMarkdown : function(){
if(!this.refs.codeEditor) return;
if(!this.codeEditor.current) return;
if(this.state.view === 'text') {
const codeMirror = this.refs.codeEditor.codeMirror;
const codeMirror = this.codeEditor.current.codeMirror;

codeMirror.operation(()=>{ // Batch CodeMirror styling
//reset custom text styles
Expand Down Expand Up @@ -302,23 +305,23 @@ const Editor = createClass({

targetLine = lineCount - 1; //Scroll to `\page`, which is one line back.

let currentY = this.refs.codeEditor.codeMirror.getScrollInfo().top;
let targetY = this.refs.codeEditor.codeMirror.heightAtLine(targetLine, 'local', true);
let currentY = this.codeEditor.current.codeMirror.getScrollInfo().top;
let targetY = this.codeEditor.current.codeMirror.heightAtLine(targetLine, 'local', true);

//Scroll 1/10 of the way every 10ms until 1px off.
const incrementalScroll = setInterval(()=>{
currentY += (targetY - currentY) / 10;
this.refs.codeEditor.codeMirror.scrollTo(null, currentY);
this.codeEditor.current.codeMirror.scrollTo(null, currentY);

// Update target: target height is not accurate until within +-10 lines of the visible window
if(Math.abs(targetY - currentY > 100))
targetY = this.refs.codeEditor.codeMirror.heightAtLine(targetLine, 'local', true);
targetY = this.codeEditor.current.codeMirror.heightAtLine(targetLine, 'local', true);

// End when close enough
if(Math.abs(targetY - currentY) < 1) {
this.refs.codeEditor.codeMirror.scrollTo(null, targetY); // Scroll any remaining difference
this.refs.codeEditor.setCursorPosition({ line: targetLine + 1, ch: 0 });
this.refs.codeEditor.codeMirror.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash');
this.codeEditor.current.codeMirror.scrollTo(null, targetY); // Scroll any remaining difference
this.codeEditor.current.setCursorPosition({ line: targetLine + 1, ch: 0 });
this.codeEditor.current.codeMirror.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash');
clearInterval(incrementalScroll);
}
}, 10);
Expand All @@ -328,7 +331,7 @@ const Editor = createClass({

//Called when there are changes to the editor's dimensions
update : function(){
this.refs.codeEditor?.updateSize();
this.codeEditor.current?.updateSize();
},

updateEditorTheme : function(newTheme){
Expand All @@ -347,7 +350,7 @@ const Editor = createClass({
if(this.isText()){
return <>
<CodeEditor key='codeEditor'
ref='codeEditor'
ref={this.codeEditor}
language='gfm'
view={this.state.view}
value={this.props.brew.text}
Expand All @@ -359,7 +362,7 @@ const Editor = createClass({
if(this.isStyle()){
return <>
<CodeEditor key='codeEditor'
ref='codeEditor'
ref={this.codeEditor}
language='css'
view={this.state.view}
value={this.props.brew.style ?? DEFAULT_STYLE_TEXT}
Expand All @@ -384,28 +387,28 @@ const Editor = createClass({
},

redo : function(){
return this.refs.codeEditor?.redo();
return this.codeEditor.current?.redo();
},

historySize : function(){
return this.refs.codeEditor?.historySize();
return this.codeEditor.current?.historySize();
},

undo : function(){
return this.refs.codeEditor?.undo();
return this.codeEditor.current?.undo();
},

foldCode : function(){
return this.refs.codeEditor?.foldAllCode();
return this.codeEditor.current?.foldAllCode();
},

unfoldCode : function(){
return this.refs.codeEditor?.unfoldAllCode();
return this.codeEditor.current?.unfoldAllCode();
},

render : function(){
return (
<div className='editor' ref='main'>
<div className='editor' ref={this.editor}>
<SnippetBar
brew={this.props.brew}
view={this.state.view}
Expand All @@ -421,7 +424,7 @@ const Editor = createClass({
historySize={this.historySize()}
currentEditorTheme={this.state.editorTheme}
updateEditorTheme={this.updateEditorTheme}
cursorPos={this.refs.codeEditor?.getCursorPosition() || {}} />
cursorPos={this.codeEditor.current?.getCursorPosition() || {}} />

{this.renderEditor()}
</div>
Expand Down
1 change: 0 additions & 1 deletion client/homebrew/editor/metadataEditor/metadataEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ require('./metadataEditor.less');
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const cx = require('classnames');
const request = require('../../utils/request-middleware.js');
const Nav = require('naturalcrit/nav/nav.jsx');
const Combobox = require('client/components/combobox.jsx');
Expand Down
4 changes: 2 additions & 2 deletions client/homebrew/editor/snippetbar/snippetbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const Snippetbar = createClass({
onClick={this.props.unfoldCode} >
<i className='fas fa-expand-alt' />
</div>
</>
</>;

}

Expand All @@ -181,7 +181,7 @@ const Snippetbar = createClass({
<i className='fas fa-palette' />
{this.state.themeSelector && this.renderThemeSelector()}
</div>

<div className='divider'></div>
<div className={cx('text', { selected: this.props.view === 'text' })}
onClick={()=>this.props.onViewChange('text')}>
Expand Down
20 changes: 3 additions & 17 deletions client/homebrew/homebrew.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const UserPage = require('./pages/userPage/userPage.jsx');
const SharePage = require('./pages/sharePage/sharePage.jsx');
const NewPage = require('./pages/newPage/newPage.jsx');
const ErrorPage = require('./pages/errorPage/errorPage.jsx');
const PrintPage = require('./pages/printPage/printPage.jsx');
const AccountPage = require('./pages/accountPage/accountPage.jsx');

const WithRoute = (props)=>{
Expand Down Expand Up @@ -72,31 +71,18 @@ const Homebrew = createClass({
<Route path='/new/:id' element={<WithRoute el={NewPage} brew={this.props.brew} />} />
<Route path='/new' element={<WithRoute el={NewPage}/>} />
<Route path='/user/:username' element={<WithRoute el={UserPage} brews={this.props.brews} />} />
<Route path='/print/:id' element={<WithRoute el={PrintPage} brew={this.props.brew} />} />
<Route path='/print' element={<WithRoute el={PrintPage} />} />
<Route path='/changelog' element={<WithRoute el={SharePage} brew={this.props.brew} />} />
<Route path='/faq' element={<WithRoute el={SharePage} brew={this.props.brew} />} />
<Route path='/account' element={<WithRoute el={AccountPage} brew={this.props.brew} accountDetails={this.props.brew.accountDetails} />} />
<Route path='/legacy' element={<WithRoute el={HomePage} brew={this.props.brew} />} />
<Route path='/error' element={<WithRoute el={ErrorPage} brew={this.props.brew} />} />
<Route path='/' element={<WithRoute el={HomePage} brew={this.props.brew} />} />
<Route path='/*' element={<WithRoute el={HomePage} brew={this.props.brew} />} />
<Route path='/' element={<WithRoute el={HomePage} brew={this.props.brew} />} />
<Route path='/*' element={<WithRoute el={HomePage} brew={this.props.brew} />} />
</Routes>
</div>
</Router>
);
}
});

module.exports = Homebrew;

//TODO: Nicer Error page instead of just "cant get that"
// '/share/:id' : (args)=>{
// if(!this.props.brew.shareId){
// return <ErrorPage errorId={args.id}/>;
// }
//
// return <SharePage
// id={args.id}
// brew={this.props.brew} />;
// },
module.exports = Homebrew;
Loading

0 comments on commit 2424d34

Please sign in to comment.