diff --git a/client/images/down-arrow-white.svg b/client/images/down-arrow-white.svg new file mode 100644 index 00000000..34efd84b --- /dev/null +++ b/client/images/down-arrow-white.svg @@ -0,0 +1,18 @@ + + + + arrow-shape-copy-2 + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/images/right-arrow-white.svg b/client/images/right-arrow-white.svg new file mode 100644 index 00000000..b789f93d --- /dev/null +++ b/client/images/right-arrow-white.svg @@ -0,0 +1,16 @@ + + + + arrow-shape-copy + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/client/modules/IDE/components/Editor.jsx b/client/modules/IDE/components/Editor.jsx index 2bef97c7..00344e98 100644 --- a/client/modules/IDE/components/Editor.jsx +++ b/client/modules/IDE/components/Editor.jsx @@ -7,6 +7,11 @@ import 'codemirror/addon/lint/lint'; import 'codemirror/addon/lint/javascript-lint'; import 'codemirror/addon/lint/css-lint'; import 'codemirror/addon/lint/html-lint'; +import 'codemirror/addon/fold/brace-fold'; +import 'codemirror/addon/fold/comment-fold'; +import 'codemirror/addon/fold/foldcode'; +import 'codemirror/addon/fold/foldgutter'; +import 'codemirror/addon/fold/indent-fold'; import 'codemirror/addon/comment/comment'; import 'codemirror/keymap/sublime'; import 'codemirror/addon/search/searchcursor'; @@ -62,7 +67,9 @@ class Editor extends React.Component { inputStyle: 'contenteditable', lineWrapping: false, fixedGutter: false, - gutters: ['CodeMirror-lint-markers'], + foldGutter: true, + foldOptions: { widget: '\u2026' }, + gutters: ['CodeMirror-foldgutter'], keyMap: 'sublime', highlightSelectionMatches: true, // highlight current search match lint: { @@ -86,6 +93,7 @@ class Editor extends React.Component { } }); + this._cm.setOption('extraKeys', { [`${metaKey}-Enter`]: () => null, [`Shift-${metaKey}-Enter`]: () => null, diff --git a/client/styles/abstracts/_variables.scss b/client/styles/abstracts/_variables.scss index 69736822..d3a62a22 100644 --- a/client/styles/abstracts/_variables.scss +++ b/client/styles/abstracts/_variables.scss @@ -49,6 +49,8 @@ $themes: ( dropdown-color: #414141, keyboard-shortcut-color: #757575, nav-hover-color: $p5js-pink, + codefold-icon-open: url(../images/down-arrow.svg), + codefold-icon-closed: url(../images/right-arrow.svg) ), dark: ( logo-color: $p5js-pink, @@ -88,6 +90,8 @@ $themes: ( dropdown-color: #dadada, keyboard-shortcut-color: #B5B5B5, nav-hover-color: $p5js-pink, + codefold-icon-open: url(../images/down-arrow-white.svg), + codefold-icon-closed: url(../images/right-arrow-white.svg) ), contrast: ( logo-color: $yellow, @@ -125,7 +129,9 @@ $themes: ( search-background-color: $white, dropdown-color: #e1e1e1, keyboard-shortcut-color: #e1e1e1, - nav-hover-color: $yellow + nav-hover-color: $yellow, + codefold-icon-open: url(../images/down-arrow-white.svg), + codefold-icon-closed: url(../images/right-arrow-white.svg) ) ); diff --git a/client/styles/components/_editor.scss b/client/styles/components/_editor.scss index 194264d0..bf317fb0 100644 --- a/client/styles/components/_editor.scss +++ b/client/styles/components/_editor.scss @@ -13,17 +13,17 @@ .CodeMirror-linenumber { width: #{32 / $base-font-size}rem; - left: 0 !important; + left: #{-3 / $base-font-size}rem !important; @include themify() { color: getThemifyVariable('inactive-text-color'); } } .CodeMirror-lines { - padding-top: #{25 / $base-font-size}rem; + padding-top: #{25 / $base-font-size}rem; } -.CodeMirror-line { +pre.CodeMirror-line { padding-left: #{5 / $base-font-size}rem; } @@ -243,6 +243,40 @@ background: transparent url(../images/exit.svg) no-repeat; } +.CodeMirror-foldgutter-open:after { + @include themify() { + background-image: getThemifyVariable('codefold-icon-open'); + } +} + +.CodeMirror-foldgutter-folded:after { + @include themify() { + background-image: getThemifyVariable('codefold-icon-closed'); + } +} + +.CodeMirror-foldgutter-folded:after, +.CodeMirror-foldgutter-open:after { + background-size: 10px 10px; + content: ""; + padding-left: 15px; + background-repeat: no-repeat; + background-position: center center; +} + +.CodeMirror-foldmarker { + text-shadow: none; + border-radius: 5px; + opacity: 1; + font-weight: normal; + display: inline-block; + vertical-align: middle; + height: 0.85em; + line-height: 0.7; + padding: 0 #{5 / $base-font-size}rem; + font-family: serif; +} + .editor-holder { height: calc(100% - #{29 / $base-font-size}rem); width: 100%; diff --git a/client/styles/components/_p5-contrast-codemirror-theme.scss b/client/styles/components/_p5-contrast-codemirror-theme.scss index d5a2a997..6ddef26a 100644 --- a/client/styles/components/_p5-contrast-codemirror-theme.scss +++ b/client/styles/components/_p5-contrast-codemirror-theme.scss @@ -125,3 +125,8 @@ $p5-contrast-activeline: #999999; color: $p5-contrast-pink; font-weight: bold; } + +.cm-s-p5-contrast .CodeMirror-foldmarker { + background-color: white; + color: #333; +} diff --git a/client/styles/components/_p5-dark-codemirror-theme.scss b/client/styles/components/_p5-dark-codemirror-theme.scss index e727b03f..275d57ff 100644 --- a/client/styles/components/_p5-dark-codemirror-theme.scss +++ b/client/styles/components/_p5-dark-codemirror-theme.scss @@ -128,3 +128,8 @@ $p5-dark-activeline: rgb(207, 207, 207); color: $p5-dark-pink; font-weight: bold; } + +.cm-s-p5-dark .CodeMirror-foldmarker { + background-color: white; + color: #333; +} diff --git a/client/styles/components/_p5-light-codemirror-theme.scss b/client/styles/components/_p5-light-codemirror-theme.scss index 0a5fcd78..dbb72dbd 100644 --- a/client/styles/components/_p5-light-codemirror-theme.scss +++ b/client/styles/components/_p5-light-codemirror-theme.scss @@ -126,3 +126,8 @@ $p5-light-activeline: rgb(207, 207, 207); .cm-s-p5-light .cm-p5-variable { color: $p5-light-pink; } + +.cm-s-p5-light .CodeMirror-foldmarker { + background-color: #333; + color: white; +} diff --git a/client/styles/vendors/_codemirror.scss b/client/styles/vendors/_codemirror.scss index 1cf66a9f..8938568c 100644 --- a/client/styles/vendors/_codemirror.scss +++ b/client/styles/vendors/_codemirror.scss @@ -336,3 +336,33 @@ div.CodeMirror-dragcursors { /* Help users use markselection to safely style text background */ span.CodeMirror-selectedtext { background: none; } + +/* CODE FOLDING (FOLDGUTTER.JS) */ + +.CodeMirror-foldmarker { + text-shadow: -1px 0 #ed225d, 0 1px #ed225d, 1px 0 #ed225d, 0 -1px #ed225d; + color: #FFF; + /* background-color: rgba(237, 34, 93, 0.42); */ + /* border-radius: 3px; */ + font-weight: bold; + font-family: arial; + line-height: .3; + cursor: pointer; + opacity: 0.75; +} +.CodeMirror-foldgutter { + width: 2.7em; +} +.CodeMirror-foldgutter-open, +.CodeMirror-foldgutter-folded { + cursor: pointer; + padding-bottom: 0.4em; + text-align: right; + line-height: 1.0; +} +.CodeMirror-foldgutter-open:after { + content: "\25BE"; +} +.CodeMirror-foldgutter-folded:after { + content: "\25B8"; +}