From 5c2acf3183a3f4ac7369303df2ca775e1d229e81 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Sat, 14 Sep 2024 18:52:13 -0400 Subject: [PATCH] Let Editor pass changes up and inherit values down --- client/homebrew/editor/editor.jsx | 58 ++++++++++---------- shared/naturalcrit/codeEditor/codeEditor.jsx | 19 ++++--- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 24e975ebc..0bc64e500 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -36,9 +36,16 @@ const Editor = createClass({ onStyleChange : ()=>{}, onMetaChange : ()=>{}, reportError : ()=>{}, + + onCursorPageChange : ()=>{}, + onViewPageChange : ()=>{}, editorTheme : 'default', - renderer : 'legacy' + renderer : 'legacy', + + currentEditorCursorPageNum : 0, + currentEditorViewPageNum : 0, + currentBrewRendererPageNum : 0, }; }, getInitialState : function() { @@ -62,6 +69,9 @@ 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)); + const editorTheme = window.localStorage.getItem(EDITOR_THEME_KEY); if(editorTheme) { this.setState({ @@ -96,7 +106,6 @@ const Editor = createClass({ } }, - updateEditorSize : function() { if(this.codeEditor.current) { let paneHeight = this.editor.current.parentNode.clientHeight; @@ -105,6 +114,20 @@ 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); + 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); + this.props.onViewPageChange(currentPage); + }, + handleInject : function(injectText){ this.codeEditor.current?.injectText(injectText, false); }, @@ -119,18 +142,6 @@ const Editor = createClass({ }); //TODO: not sure if updateeditorsize needed }, - getCurrentPage : function(){ - 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) - || - (this.props.renderer == 'V3' && line.match(/^\\page$/)) - ) r++; - return r; - }, 1); - }, - highlightCustomMarkdown : function(){ if(!this.codeEditor.current) return; if(this.state.view === 'text') { @@ -291,9 +302,9 @@ const Editor = createClass({ } }, - brewJump : function(targetPage=this.getCurrentPage()){ + brewJump : function(targetPage=this.props.currentEditorCursorPageNum){ if(!window) return; - // console.log(`Scroll to: p${targetPage}`); + // Get current brewRenderer scroll position and calculate target position const brewRenderer = window.frames['BrewRenderer'].contentDocument.getElementsByClassName('brewRenderer')[0]; const currentPos = brewRenderer.scrollTop; const targetPos = window.frames['BrewRenderer'].contentDocument.getElementById(`p${targetPage}`).getBoundingClientRect().top; @@ -321,19 +332,8 @@ const Editor = createClass({ if(targetLine == null) { targetLine = 0; - const pageCollection = window.frames['BrewRenderer'].contentDocument.getElementsByClassName('page'); - const brewRendererHeight = window.frames['BrewRenderer'].contentDocument.getElementsByClassName('brewRenderer').item(0).getBoundingClientRect().height; - - let currentPage = 1; - for (const page of pageCollection) { - if(page.getBoundingClientRect().bottom > (brewRendererHeight / 2)) { - currentPage = parseInt(page.id.slice(1)) || 1; - break; - } - } - const textSplit = this.props.renderer == 'V3' ? /^\\page$/gm : /\\page/; - const textString = this.props.brew.text.split(textSplit).slice(0, currentPage-1).join(textSplit); + const textString = this.props.brew.text.split(textSplit).slice(0, this.props.currentBrewRendererPageNum-1).join(textSplit); const textPosition = textString.length; const lineCount = textString.match('\n') ? textString.slice(0, textPosition).split('\n').length : 0; @@ -389,6 +389,8 @@ const Editor = createClass({ view={this.state.view} value={this.props.brew.text} onChange={this.props.onTextChange} + onCursorActivity={this.props.onCursorActivity} + onScroll={this.props.onPageChange} editorTheme={this.state.editorTheme} rerenderParent={this.rerenderParent} /> ; diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index 3186e39f1..3e93cd176 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -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(); }, @@ -397,6 +397,11 @@ const CodeEditor = createClass({ getCursorPosition : function(){ return this.codeMirror.getCursor(); }, + getTopVisibleLine : function(){ + const rect = this.codeMirror.getWrapperElement().getBoundingClientRect(); + const topVisibleLine = this.codeMirror.lineAtHeight(rect.top, "window"); + return topVisibleLine; + }, updateSize : function(){ this.codeMirror.refresh(); },