From c82b62f953aba3e9c2db6b02c42f5879345fc9c6 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 19 Jul 2024 16:03:44 -0500 Subject: [PATCH 01/14] Add Code folding on CSS style tab --- client/homebrew/editor/editor.jsx | 2 +- shared/naturalcrit/codeEditor/codeEditor.jsx | 9 ++++-- shared/naturalcrit/codeEditor/fold-css.js | 32 +++++++++++++++++++ .../{fold-code.js => fold-pages.js} | 0 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 shared/naturalcrit/codeEditor/fold-css.js rename shared/naturalcrit/codeEditor/{fold-code.js => fold-pages.js} (100%) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index efcc9c861..b28c5dcf3 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -367,7 +367,7 @@ const Editor = createClass({ view={this.state.view} value={this.props.brew.style ?? DEFAULT_STYLE_TEXT} onChange={this.props.onStyleChange} - enableFolding={false} + enableFolding={true} editorTheme={this.state.editorTheme} rerenderParent={this.rerenderParent} /> ; diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index e624694f1..a42484827 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -39,8 +39,10 @@ if(typeof window !== 'undefined'){ //Autocompletion require('codemirror/addon/hint/show-hint.js'); - const foldCode = require('./fold-code'); - foldCode.registerHomebreweryHelper(CodeMirror); + const foldPagesCode = require('./fold-pages'); + foldPagesCode.registerHomebreweryHelper(CodeMirror); + const foldCSSCode = require('./fold-css'); + foldCSSCode.registerHomebreweryHelper(CodeMirror); } const CodeEditor = createClass({ @@ -411,7 +413,7 @@ const CodeEditor = createClass({ foldOptions : function(cm){ return { scanUp : true, - rangeFinder : CodeMirror.fold.homebrewery, + rangeFinder : this.props.language === 'css' ? CodeMirror.fold.homebrewerycss : CodeMirror.fold.homebrewery, widget : (from, to)=>{ let text = ''; let currentLine = from.line; @@ -450,3 +452,4 @@ const CodeEditor = createClass({ }); module.exports = CodeEditor; + diff --git a/shared/naturalcrit/codeEditor/fold-css.js b/shared/naturalcrit/codeEditor/fold-css.js new file mode 100644 index 000000000..29501c4c6 --- /dev/null +++ b/shared/naturalcrit/codeEditor/fold-css.js @@ -0,0 +1,32 @@ +module.exports = { + registerHomebreweryHelper : function(CodeMirror) { + CodeMirror.registerHelper('fold', 'homebrewerycss', function(cm, start) { + const startMatcher = /\{[ \t]*$/; + const endMatcher = /\}[ \t]*$/; + const prevLine = cm.getLine(start.line); + + if((start.line === cm.firstLine()) && (!cm.getLine(start.line).match(startMatcher))) return null; + + if(start.line === cm.firstLine() || prevLine.match(startMatcher)) { + const lastLineNo = cm.lastLine(); + let end = start.line + 1; + let braceCount = 1; + + while (end < lastLineNo) { + const curLine = cm.getLine(end); + if(curLine.match(startMatcher)) braceCount++; + if(curLine.match(endMatcher)) braceCount--; + if(braceCount == 0) break; + ++end; + } + + return { + from : CodeMirror.Pos(start.line, 0), + to : CodeMirror.Pos(end, cm.getLine(end).length) + }; + } + + return null; + }); + } +}; diff --git a/shared/naturalcrit/codeEditor/fold-code.js b/shared/naturalcrit/codeEditor/fold-pages.js similarity index 100% rename from shared/naturalcrit/codeEditor/fold-code.js rename to shared/naturalcrit/codeEditor/fold-pages.js From 9a4cc5f63eb7e71074ed5692127ace4bfd795889 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Sat, 20 Jul 2024 14:57:09 +1200 Subject: [PATCH 02/14] Add @import folding --- shared/naturalcrit/codeEditor/fold-css.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/shared/naturalcrit/codeEditor/fold-css.js b/shared/naturalcrit/codeEditor/fold-css.js index 29501c4c6..ae43675b6 100644 --- a/shared/naturalcrit/codeEditor/fold-css.js +++ b/shared/naturalcrit/codeEditor/fold-css.js @@ -1,13 +1,14 @@ module.exports = { registerHomebreweryHelper : function(CodeMirror) { CodeMirror.registerHelper('fold', 'homebrewerycss', function(cm, start) { + + // BRACE FOLDING const startMatcher = /\{[ \t]*$/; const endMatcher = /\}[ \t]*$/; const prevLine = cm.getLine(start.line); - if((start.line === cm.firstLine()) && (!cm.getLine(start.line).match(startMatcher))) return null; - if(start.line === cm.firstLine() || prevLine.match(startMatcher)) { + if(prevLine.match(startMatcher)) { const lastLineNo = cm.lastLine(); let end = start.line + 1; let braceCount = 1; @@ -26,6 +27,17 @@ module.exports = { }; } + // IMPORT FOLDING + + const importMatcher = /^@import.*?[;]/; + + if(prevLine.match(importMatcher)) { + return { + from : CodeMirror.Pos(start.line, 0), + to : CodeMirror.Pos(start.line, cm.getLine(start.line).length) + }; + } + return null; }); } From 2c4f3473e51155dd0833a55d711a3e129af3c0ec Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 20 Jul 2024 00:43:02 -0500 Subject: [PATCH 03/14] Trim the trailing { on a CSS fold. --- shared/naturalcrit/codeEditor/codeEditor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index a42484827..c683c3f2e 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -433,7 +433,7 @@ const CodeEditor = createClass({ } text = foldPreviewText || `Lines ${from.line+1}-${to.line+1}`; - text = text.trim(); + text = text.trim().replace('{', '').trim(); if(text.length > maxLength) text = `${text.substr(0, maxLength)}...`; From 6693fb1c13b88e3ad2aed6de476d704177c04e08 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 20 Jul 2024 21:40:22 -0500 Subject: [PATCH 04/14] reduce redundant trim()s --- shared/naturalcrit/codeEditor/codeEditor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index c683c3f2e..af9c5c733 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -433,7 +433,7 @@ const CodeEditor = createClass({ } text = foldPreviewText || `Lines ${from.line+1}-${to.line+1}`; - text = text.trim().replace('{', '').trim(); + text = text.replace('{', '').trim(); if(text.length > maxLength) text = `${text.substr(0, maxLength)}...`; From fde797c044bc0809ae57bfd904d31750d99a2683 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sat, 20 Jul 2024 21:51:03 -0500 Subject: [PATCH 05/14] Rename prevLine to activeLine for better reading clarity. --- shared/naturalcrit/codeEditor/fold-css.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shared/naturalcrit/codeEditor/fold-css.js b/shared/naturalcrit/codeEditor/fold-css.js index ae43675b6..b7a2a6da1 100644 --- a/shared/naturalcrit/codeEditor/fold-css.js +++ b/shared/naturalcrit/codeEditor/fold-css.js @@ -5,10 +5,10 @@ module.exports = { // BRACE FOLDING const startMatcher = /\{[ \t]*$/; const endMatcher = /\}[ \t]*$/; - const prevLine = cm.getLine(start.line); + const activeLine = cm.getLine(start.line); - if(prevLine.match(startMatcher)) { + if(activeLine.match(startMatcher)) { const lastLineNo = cm.lastLine(); let end = start.line + 1; let braceCount = 1; @@ -31,7 +31,7 @@ module.exports = { const importMatcher = /^@import.*?[;]/; - if(prevLine.match(importMatcher)) { + if(activeLine.match(importMatcher)) { return { from : CodeMirror.Pos(start.line, 0), to : CodeMirror.Pos(start.line, cm.getLine(start.line).length) From 2fc7aa454f95dc953c384fdebc4c4a2f90db6005 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 21 Jul 2024 12:40:49 -0500 Subject: [PATCH 06/14] Add data: URL folding for CSS. Regex might need tweaking to catch all cases, but it catches the basics. --- shared/naturalcrit/codeEditor/codeEditor.jsx | 10 +++++++++- shared/naturalcrit/codeEditor/fold-css.js | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index af9c5c733..cc74a6f0a 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -433,9 +433,17 @@ const CodeEditor = createClass({ } text = foldPreviewText || `Lines ${from.line+1}-${to.line+1}`; + text = text.replace('{', '').trim(); + + // Extra data url chomping + console.log(text); + text = text.indexOf('data:') > -1 ? `${text.slice(0, text.indexOf('data:') + 5)} ...` : text; + console.log(text); + if(text.length > maxLength) - text = `${text.substr(0, maxLength)}...`; + text = `${text.slice(0, maxLength)}...`; + return `\u21A4 ${text} \u21A6`; } diff --git a/shared/naturalcrit/codeEditor/fold-css.js b/shared/naturalcrit/codeEditor/fold-css.js index b7a2a6da1..f21eaef45 100644 --- a/shared/naturalcrit/codeEditor/fold-css.js +++ b/shared/naturalcrit/codeEditor/fold-css.js @@ -38,6 +38,18 @@ module.exports = { }; } + // data-url folding FOR CSS. + + const dataURLMatcher = /url\(.*?data\:.*\)/; + + if(activeLine.match(dataURLMatcher)) { + return { + from : CodeMirror.Pos(start.line, 0), + to : CodeMirror.Pos(start.line, cm.getLine(start.line).length) + }; + } + + return null; }); } From 2af2ad629d4f15aa53389cc2c12ce39f604f1df7 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Sun, 21 Jul 2024 12:58:21 -0500 Subject: [PATCH 07/14] Try to account for situations where the URL folding is past the max length for the truncation so the user can see why this is a fold. Remove missed debug messages. --- shared/naturalcrit/codeEditor/codeEditor.jsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index cc74a6f0a..a96feb723 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -437,9 +437,13 @@ const CodeEditor = createClass({ text = text.replace('{', '').trim(); // Extra data url chomping - console.log(text); - text = text.indexOf('data:') > -1 ? `${text.slice(0, text.indexOf('data:') + 5)} ...` : text; - console.log(text); + // Try to make it pretty... + const startOfData = text.indexOf('data:'); + if(startOfData) { + text = (startOfData > maxLength) ? + `${text.slice(0, text.indexOf(':') + 1)} ... ${text.slice(startOfData, startOfData + 5)} ...` : + `${text.slice(0, text.indexOf('data:') + 5)} ...`; + } if(text.length > maxLength) text = `${text.slice(0, maxLength)}...`; From c926f0de7960d22aea4a4ee9d64724eac3c09809 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 2 Aug 2024 15:10:39 -0500 Subject: [PATCH 08/14] Resolve import matching suggestion. --- shared/naturalcrit/codeEditor/fold-css.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/naturalcrit/codeEditor/fold-css.js b/shared/naturalcrit/codeEditor/fold-css.js index f21eaef45..a384d2fc2 100644 --- a/shared/naturalcrit/codeEditor/fold-css.js +++ b/shared/naturalcrit/codeEditor/fold-css.js @@ -29,7 +29,7 @@ module.exports = { // IMPORT FOLDING - const importMatcher = /^@import.*?[;]/; + const importMatcher = /^@import.*?;/; if(activeLine.match(importMatcher)) { return { From ad1e8d50d75e3cdef443de9e3a1efbec334f1366 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 2 Aug 2024 15:24:14 -0500 Subject: [PATCH 09/14] Correct truncation when looking for data: in css folding --- shared/naturalcrit/codeEditor/codeEditor.jsx | 2 +- shared/naturalcrit/codeEditor/fold-css.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index a96feb723..9080379a1 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -438,7 +438,7 @@ const CodeEditor = createClass({ // Extra data url chomping // Try to make it pretty... - const startOfData = text.indexOf('data:'); + const startOfData = text.indexOf('data:') > 0 ? text.indexOf('data:') : false; if(startOfData) { text = (startOfData > maxLength) ? `${text.slice(0, text.indexOf(':') + 1)} ... ${text.slice(startOfData, startOfData + 5)} ...` : diff --git a/shared/naturalcrit/codeEditor/fold-css.js b/shared/naturalcrit/codeEditor/fold-css.js index a384d2fc2..f21eaef45 100644 --- a/shared/naturalcrit/codeEditor/fold-css.js +++ b/shared/naturalcrit/codeEditor/fold-css.js @@ -29,7 +29,7 @@ module.exports = { // IMPORT FOLDING - const importMatcher = /^@import.*?;/; + const importMatcher = /^@import.*?[;]/; if(activeLine.match(importMatcher)) { return { From 05d4d5b1ff39d8de3a65255e1f19c3029f07acf8 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 2 Aug 2024 15:25:10 -0500 Subject: [PATCH 10/14] Revert "Correct truncation when looking for data: in css folding" This reverts commit ad1e8d50d75e3cdef443de9e3a1efbec334f1366. --- shared/naturalcrit/codeEditor/codeEditor.jsx | 2 +- shared/naturalcrit/codeEditor/fold-css.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index 9080379a1..a96feb723 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -438,7 +438,7 @@ const CodeEditor = createClass({ // Extra data url chomping // Try to make it pretty... - const startOfData = text.indexOf('data:') > 0 ? text.indexOf('data:') : false; + const startOfData = text.indexOf('data:'); if(startOfData) { text = (startOfData > maxLength) ? `${text.slice(0, text.indexOf(':') + 1)} ... ${text.slice(startOfData, startOfData + 5)} ...` : diff --git a/shared/naturalcrit/codeEditor/fold-css.js b/shared/naturalcrit/codeEditor/fold-css.js index f21eaef45..a384d2fc2 100644 --- a/shared/naturalcrit/codeEditor/fold-css.js +++ b/shared/naturalcrit/codeEditor/fold-css.js @@ -29,7 +29,7 @@ module.exports = { // IMPORT FOLDING - const importMatcher = /^@import.*?[;]/; + const importMatcher = /^@import.*?;/; if(activeLine.match(importMatcher)) { return { From 423a4a521acf666d8b32ff8b8e779c68807df954 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Fri, 2 Aug 2024 15:25:41 -0500 Subject: [PATCH 11/14] Correct truncation when looking for data: in css folding --- shared/naturalcrit/codeEditor/codeEditor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index a96feb723..9080379a1 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -438,7 +438,7 @@ const CodeEditor = createClass({ // Extra data url chomping // Try to make it pretty... - const startOfData = text.indexOf('data:'); + const startOfData = text.indexOf('data:') > 0 ? text.indexOf('data:') : false; if(startOfData) { text = (startOfData > maxLength) ? `${text.slice(0, text.indexOf(':') + 1)} ... ${text.slice(startOfData, startOfData + 5)} ...` : From 3b61cd355feed53af9edb21d0165fab38b7a46ac Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 8 Aug 2024 17:43:57 -0400 Subject: [PATCH 12/14] Fix edge case where string was emitting `data:` twice. Also, a case where the input is right around 50 chars. It can be truncated twice, leading to a long `.....` --- shared/naturalcrit/codeEditor/codeEditor.jsx | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index 9080379a1..bc6b2b8dd 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -417,7 +417,7 @@ const CodeEditor = createClass({ widget : (from, to)=>{ let text = ''; let currentLine = from.line; - const maxLength = 50; + let maxLength = 50; let foldPreviewText = ''; while (currentLine <= to.line && text.length <= maxLength) { @@ -432,23 +432,16 @@ const CodeEditor = createClass({ } } text = foldPreviewText || `Lines ${from.line+1}-${to.line+1}`; - - text = text.replace('{', '').trim(); - // Extra data url chomping - // Try to make it pretty... - const startOfData = text.indexOf('data:') > 0 ? text.indexOf('data:') : false; - if(startOfData) { - text = (startOfData > maxLength) ? - `${text.slice(0, text.indexOf(':') + 1)} ... ${text.slice(startOfData, startOfData + 5)} ...` : - `${text.slice(0, text.indexOf('data:') + 5)} ...`; - } + // Truncate data URLs + const startOfData = text.indexOf('data:'); + if(startOfData > 0) + maxLength = Math.min(startOfData + 5, maxLength); if(text.length > maxLength) text = `${text.slice(0, maxLength)}...`; - return `\u21A4 ${text} \u21A6`; } }; From 643af98ca38d938f7f97e15d64091bb8ddf9c751 Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 8 Aug 2024 17:44:16 -0400 Subject: [PATCH 13/14] Add comment --- shared/naturalcrit/codeEditor/codeEditor.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/naturalcrit/codeEditor/codeEditor.jsx b/shared/naturalcrit/codeEditor/codeEditor.jsx index bc6b2b8dd..3186e39f1 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.jsx +++ b/shared/naturalcrit/codeEditor/codeEditor.jsx @@ -434,7 +434,7 @@ const CodeEditor = createClass({ text = foldPreviewText || `Lines ${from.line+1}-${to.line+1}`; text = text.replace('{', '').trim(); - // Truncate data URLs + // Truncate data URLs at `data:` const startOfData = text.indexOf('data:'); if(startOfData > 0) maxLength = Math.min(startOfData + 5, maxLength); From 31352e417fb686277d309167c7c2663be841caed Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Thu, 8 Aug 2024 17:48:32 -0400 Subject: [PATCH 14/14] Simplify folding logic --- shared/naturalcrit/codeEditor/fold-css.js | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/shared/naturalcrit/codeEditor/fold-css.js b/shared/naturalcrit/codeEditor/fold-css.js index a384d2fc2..338cab176 100644 --- a/shared/naturalcrit/codeEditor/fold-css.js +++ b/shared/naturalcrit/codeEditor/fold-css.js @@ -27,29 +27,17 @@ module.exports = { }; } - // IMPORT FOLDING + // @import and data-url folding + const importMatcher = /^@import.*?;/; + const dataURLMatcher = /url\(.*?data\:.*\)/; - const importMatcher = /^@import.*?;/; - - if(activeLine.match(importMatcher)) { + if(activeLine.match(importMatcher) || activeLine.match(dataURLMatcher)) { return { from : CodeMirror.Pos(start.line, 0), - to : CodeMirror.Pos(start.line, cm.getLine(start.line).length) + to : CodeMirror.Pos(start.line, activeLine.length) }; } - // data-url folding FOR CSS. - - const dataURLMatcher = /url\(.*?data\:.*\)/; - - if(activeLine.match(dataURLMatcher)) { - return { - from : CodeMirror.Pos(start.line, 0), - to : CodeMirror.Pos(start.line, cm.getLine(start.line).length) - }; - } - - return null; }); }