From abbec5bde1647d79a576674d2b73f69b832753e7 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 15 Mar 2021 13:53:08 -0700 Subject: [PATCH 01/16] bugfix: move sidebyside accessor outside of options check --- src/js/easymde.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index 44427f8..d4fb686 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -332,9 +332,10 @@ function toggleFullScreen(editor) { document.body.style.overflow = saved_overflow; } + var sidebyside = cm.getWrapperElement().nextSibling; + // Hide side by side if needed, retain current state if sideBySideFullscreen is disabled if (editor.options.sideBySideFullscreen !== false) { - var sidebyside = cm.getWrapperElement().nextSibling; if (/editor-preview-active-side/.test(sidebyside.className)) toggleSideBySide(editor); } From 61e93a3d5389066f037d2f8ccbd7981ab11ac2c2 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 15 Mar 2021 19:30:56 -0700 Subject: [PATCH 02/16] handle fullscreen toggle consistently by adusting toggleSideBySide --- example/index_sideBySideFullscreenFalse.html | 20 +++ src/js/easymde.js | 122 ++++++++++++------- 2 files changed, 96 insertions(+), 46 deletions(-) create mode 100644 example/index_sideBySideFullscreenFalse.html diff --git a/example/index_sideBySideFullscreenFalse.html b/example/index_sideBySideFullscreenFalse.html new file mode 100644 index 0000000..29e3a64 --- /dev/null +++ b/example/index_sideBySideFullscreenFalse.html @@ -0,0 +1,20 @@ + + + + + + + + Example / Preview / sideBySideFullscreen : true + + + + + + + + + + diff --git a/src/js/easymde.js b/src/js/easymde.js index d4fb686..67ea60d 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -323,7 +323,6 @@ function toggleFullScreen(editor) { var cm = editor.codemirror; cm.setOption('fullScreen', !cm.getOption('fullScreen')); - // Prevent scrolling on body during fullscreen active if (cm.getOption('fullScreen')) { saved_overflow = document.body.style.overflow; @@ -334,11 +333,9 @@ function toggleFullScreen(editor) { var sidebyside = cm.getWrapperElement().nextSibling; - // Hide side by side if needed, retain current state if sideBySideFullscreen is disabled - if (editor.options.sideBySideFullscreen !== false) { - if (/editor-preview-active-side/.test(sidebyside.className)) - toggleSideBySide(editor); - } + // if (/editor-preview-active-side/.test(sidebyside.className)) { + toggleSideBySide(editor, true); + // } if (editor.options.onToggleFullScreen) { editor.options.onToggleFullScreen(cm.getOption('fullScreen') || false); @@ -873,15 +870,22 @@ function redo(editor) { /** - * Toggle side by side preview + * Toggle side by side preview. + * Note: If triggered by fullscreen toggle and sideBySideFullscreen === false, + * `sideBySide` is not actually toggled, but classes are reapplied as needed. + * @param {EasyMDE} editor - The EasyMDE object + * @param {boolean} triggeredByFullscreenToggle If triggered by fullscreen toggle. */ -function toggleSideBySide(editor) { +function toggleSideBySide(editor, triggeredByFullscreenToggle) { var cm = editor.codemirror; var wrapper = cm.getWrapperElement(); var preview = wrapper.nextSibling; var toolbarButton = editor.toolbarElements && editor.toolbarElements['side-by-side']; var useSideBySideListener = false; + // if triggered by fullscreen toggle and sideBySideFullscreen === false, don't toggle + var dontToggle = editor.options.sideBySideFullscreen === false && triggeredByFullscreenToggle; + var noFullscreenItems = [ wrapper.parentNode, // easyMDEContainer editor.gui.toolbar, @@ -891,56 +895,81 @@ function toggleSideBySide(editor) { ]; function addNoFullscreenClass(el) { - el.className += ' sided--no-fullscreen'; + if (el != null) { + el.className += ' sided--no-fullscreen'; + } } function removeNoFullscreenClass(el) { if (el != null) { el.className = el.className.replace( - /\s*sided--no-fullscreen\s*/g, '' + // retain spaces after the class + // in case there are subsequent classes + /\s*sided--no-fullscreen(\s*)/g, '$1' ); } } - if (/editor-preview-active-side/.test(preview.className)) { - if (cm.getOption('sideBySideNoFullscreen')) { - cm.setOption('sideBySideNoFullscreen', false); - noFullscreenItems.forEach(function (el) { - removeNoFullscreenClass(el); - }); - } - preview.className = preview.className.replace( - /\s*editor-preview-active-side\s*/g, '' - ); - if (toolbarButton) toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, ''); - wrapper.className = wrapper.className.replace(/\s*CodeMirror-sided\s*/g, ' '); - } else { - // When the preview button is clicked for the first time, - // give some time for the transition from editor.css to fire and the view to slide from right to left, - // instead of just appearing. - setTimeout(function () { - if (!cm.getOption('fullScreen')) { - if (editor.options.sideBySideFullscreen === false) { - cm.setOption('sideBySideNoFullscreen', true); - noFullscreenItems.forEach(function(el) { - if (el != null) { - addNoFullscreenClass(el); - } - }); - } else { - toggleFullScreen(editor); - } + // helper method to add/remove no-fullscreen classes as appropriate + function setupNoFullscreenClasses(previewActive) { + if (editor.options.sideBySideFullscreen === false) { + if (!cm.getOption('fullScreen') && previewActive) { + noFullscreenItems.forEach(function(el) { + addNoFullscreenClass(el); + }); + } else { + noFullscreenItems.forEach(function (el) { + removeNoFullscreenClass(el); + }); } - preview.className += ' editor-preview-active-side'; - }, 1); - if (toolbarButton) toolbarButton.className += ' active'; - wrapper.className += ' CodeMirror-sided'; - useSideBySideListener = true; + } } - // Hide normal preview if active + if (/editor-preview-active-side/.test(preview.className)) { + // If side-by-side active... + if (dontToggle) { + // if not toggling, cleanup noFullscreen classes as needed + setupNoFullscreenClasses(true); + } else { + // otherwise close side-by-side, and cleanup noFullscreen classes as needed + setupNoFullscreenClasses(false); + preview.className = preview.className.replace( + /\s*editor-preview-active-side\s*/g, '' + ); + if (toolbarButton) toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, ''); + wrapper.className = wrapper.className.replace(/\s*CodeMirror-sided\s*/g, ' '); + } + } else { + // If side-by-side not active... + if (dontToggle) { + // if not toggling, cleanup noFullscreen classes as needed + setupNoFullscreenClasses(false); + } else { + // otherwise open side-by-side, and setup noFullscreen classes as needed + setTimeout(function () { + // When the preview button is clicked for the first time, + // give some time for the transition from editor.css to + // fire and the view to slide from right to left, + // instead of just appearing. + if (!cm.getOption('fullScreen')) { + if (editor.options.sideBySideFullscreen === false) { + setupNoFullscreenClasses(true); + } else { + toggleFullScreen(editor); + } + } + preview.className += ' editor-preview-active-side'; + }, 1); + if (toolbarButton) toolbarButton.className += ' active'; + wrapper.className += ' CodeMirror-sided'; + useSideBySideListener = true; + } + } + + + // Hide normal (full-pane) preview if active var previewNormal = wrapper.lastChild; - if (/editor-preview-active/.test(previewNormal.className)) { + if (!dontToggle && /editor-preview-active/.test(previewNormal.className)) { previewNormal.className = previewNormal.className.replace( /\s*editor-preview-active\s*/g, '' ); @@ -991,8 +1020,8 @@ function togglePreview(editor) { if (/editor-preview-active-side/.test(sidebyside.className)) toggleSideBySide(editor); + // Construct preview element if it doesn't exist if (!preview || !/editor-preview-full/.test(preview.className)) { - preview = document.createElement('div'); preview.className = 'editor-preview-full'; @@ -1011,6 +1040,7 @@ function togglePreview(editor) { wrapper.appendChild(preview); } + // Toggle display of preview depending on current state if (/editor-preview-active/.test(preview.className)) { preview.className = preview.className.replace( /\s*editor-preview-active\s*/g, '' From fa8855e3bee23949616e7686e68c87c56f80b53f Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 15 Mar 2021 19:40:57 -0700 Subject: [PATCH 03/16] code refactoring to improve readability --- src/js/easymde.js | 80 +++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index 67ea60d..3559906 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -911,59 +911,49 @@ function toggleSideBySide(editor, triggeredByFullscreenToggle) { } // helper method to add/remove no-fullscreen classes as appropriate - function setupNoFullscreenClasses(previewActive) { + function setupNoFullscreenClasses(sidePreviewActive) { if (editor.options.sideBySideFullscreen === false) { - if (!cm.getOption('fullScreen') && previewActive) { - noFullscreenItems.forEach(function(el) { - addNoFullscreenClass(el); - }); + if (!cm.getOption('fullScreen') && sidePreviewActive) { + // only apply classes if !fullScreen and side preview is (or will be) active + noFullscreenItems.forEach(addNoFullscreenClass); } else { - noFullscreenItems.forEach(function (el) { - removeNoFullscreenClass(el); - }); + noFullscreenItems.forEach(removeNoFullscreenClass); } } } - if (/editor-preview-active-side/.test(preview.className)) { - // If side-by-side active... - if (dontToggle) { - // if not toggling, cleanup noFullscreen classes as needed - setupNoFullscreenClasses(true); - } else { - // otherwise close side-by-side, and cleanup noFullscreen classes as needed - setupNoFullscreenClasses(false); - preview.className = preview.className.replace( - /\s*editor-preview-active-side\s*/g, '' - ); - if (toolbarButton) toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, ''); - wrapper.className = wrapper.className.replace(/\s*CodeMirror-sided\s*/g, ' '); - } + var sidePreviewActive = /editor-preview-active-side/.test(preview.className); + + if (dontToggle) { + // if not toggling, handle noFullscreen classes as needed + setupNoFullscreenClasses(sidePreviewActive); + } else if (sidePreviewActive) { + // close side-by-side, and cleanup noFullscreen classes as needed + setupNoFullscreenClasses(false); + preview.className = preview.className.replace( + /\s*editor-preview-active-side\s*/g, '' + ); + if (toolbarButton) toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, ''); + wrapper.className = wrapper.className.replace(/\s*CodeMirror-sided\s*/g, ' '); } else { - // If side-by-side not active... - if (dontToggle) { - // if not toggling, cleanup noFullscreen classes as needed - setupNoFullscreenClasses(false); - } else { - // otherwise open side-by-side, and setup noFullscreen classes as needed - setTimeout(function () { - // When the preview button is clicked for the first time, - // give some time for the transition from editor.css to - // fire and the view to slide from right to left, - // instead of just appearing. - if (!cm.getOption('fullScreen')) { - if (editor.options.sideBySideFullscreen === false) { - setupNoFullscreenClasses(true); - } else { - toggleFullScreen(editor); - } + // open side-by-side, and setup noFullscreen classes as needed + setTimeout(function () { + // When the preview button is clicked for the first time, + // give some time for the transition from editor.css to + // fire and the view to slide from right to left, + // instead of just appearing. + if (!cm.getOption('fullScreen')) { + if (editor.options.sideBySideFullscreen === false) { + setupNoFullscreenClasses(true); + } else { + toggleFullScreen(editor); } - preview.className += ' editor-preview-active-side'; - }, 1); - if (toolbarButton) toolbarButton.className += ' active'; - wrapper.className += ' CodeMirror-sided'; - useSideBySideListener = true; - } + } + preview.className += ' editor-preview-active-side'; + }, 1); + if (toolbarButton) toolbarButton.className += ' active'; + wrapper.className += ' CodeMirror-sided'; + useSideBySideListener = true; } From 8702dd22d043ecdc2b61f66d7f4a09fb6505531e Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 15 Mar 2021 19:57:47 -0700 Subject: [PATCH 04/16] correct test page title --- example/index_sideBySideFullscreenFalse.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/index_sideBySideFullscreenFalse.html b/example/index_sideBySideFullscreenFalse.html index 29e3a64..8fe15db 100644 --- a/example/index_sideBySideFullscreenFalse.html +++ b/example/index_sideBySideFullscreenFalse.html @@ -5,7 +5,7 @@ - Example / Preview / sideBySideFullscreen : true + Example / Preview / sideBySideFullscreen : false From 25db654cf08c10854766a4ed709904ab87791a77 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 15 Mar 2021 20:08:38 -0700 Subject: [PATCH 05/16] more code cleanup for readibilty --- src/js/easymde.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index 3559906..8b6c51f 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -333,9 +333,12 @@ function toggleFullScreen(editor) { var sidebyside = cm.getWrapperElement().nextSibling; - // if (/editor-preview-active-side/.test(sidebyside.className)) { - toggleSideBySide(editor, true); - // } + // if non-fullscreen side-by-side is allowed, then pass along "dontToggle" flag + var dontToggleSideBySide = editor.options.sideBySideFullscreen === false; + + if (/editor-preview-active-side/.test(sidebyside.className) || dontToggleSideBySide) { + toggleSideBySide(editor, dontToggleSideBySide); + } if (editor.options.onToggleFullScreen) { editor.options.onToggleFullScreen(cm.getOption('fullScreen') || false); @@ -871,21 +874,16 @@ function redo(editor) { /** * Toggle side by side preview. - * Note: If triggered by fullscreen toggle and sideBySideFullscreen === false, - * `sideBySide` is not actually toggled, but classes are reapplied as needed. * @param {EasyMDE} editor - The EasyMDE object - * @param {boolean} triggeredByFullscreenToggle If triggered by fullscreen toggle. + * @param {boolean} dontToggle Flag for cleaning up side effects of fullScreen toggle. */ -function toggleSideBySide(editor, triggeredByFullscreenToggle) { +function toggleSideBySide(editor, dontToggle) { var cm = editor.codemirror; var wrapper = cm.getWrapperElement(); var preview = wrapper.nextSibling; var toolbarButton = editor.toolbarElements && editor.toolbarElements['side-by-side']; var useSideBySideListener = false; - // if triggered by fullscreen toggle and sideBySideFullscreen === false, don't toggle - var dontToggle = editor.options.sideBySideFullscreen === false && triggeredByFullscreenToggle; - var noFullscreenItems = [ wrapper.parentNode, // easyMDEContainer editor.gui.toolbar, From 8ed6cd699e876a2c5904940d59e393502cd4ebb2 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 15 Mar 2021 20:13:26 -0700 Subject: [PATCH 06/16] make toggle cleanup flag clearer --- src/js/easymde.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index 8b6c51f..3172faa 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -333,11 +333,11 @@ function toggleFullScreen(editor) { var sidebyside = cm.getWrapperElement().nextSibling; - // if non-fullscreen side-by-side is allowed, then pass along "dontToggle" flag - var dontToggleSideBySide = editor.options.sideBySideFullscreen === false; + // if non-fullscreen side-by-side is allowed, then pass along "onlyCleanup" flag + var onlyCleanup = editor.options.sideBySideFullscreen === false; - if (/editor-preview-active-side/.test(sidebyside.className) || dontToggleSideBySide) { - toggleSideBySide(editor, dontToggleSideBySide); + if (/editor-preview-active-side/.test(sidebyside.className) || onlyCleanup) { + toggleSideBySide(editor, onlyCleanup); } if (editor.options.onToggleFullScreen) { @@ -875,9 +875,9 @@ function redo(editor) { /** * Toggle side by side preview. * @param {EasyMDE} editor - The EasyMDE object - * @param {boolean} dontToggle Flag for cleaning up side effects of fullScreen toggle. + * @param {boolean} onlyCleanup Flag for only cleaning up side effects of fullScreen toggle. */ -function toggleSideBySide(editor, dontToggle) { +function toggleSideBySide(editor, onlyCleanup) { var cm = editor.codemirror; var wrapper = cm.getWrapperElement(); var preview = wrapper.nextSibling; @@ -922,7 +922,7 @@ function toggleSideBySide(editor, dontToggle) { var sidePreviewActive = /editor-preview-active-side/.test(preview.className); - if (dontToggle) { + if (onlyCleanup) { // if not toggling, handle noFullscreen classes as needed setupNoFullscreenClasses(sidePreviewActive); } else if (sidePreviewActive) { From d76872f4ffc6ba38ce1707a941d7bec74e6af6c7 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 15 Mar 2021 20:15:39 -0700 Subject: [PATCH 07/16] undo some comment changes to make diff cleaner --- src/js/easymde.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index 3172faa..b85c203 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -935,11 +935,10 @@ function toggleSideBySide(editor, onlyCleanup) { wrapper.className = wrapper.className.replace(/\s*CodeMirror-sided\s*/g, ' '); } else { // open side-by-side, and setup noFullscreen classes as needed + // When the preview button is clicked for the first time, + // give some time for the transition from editor.css to fire and the view to slide from right to left, + // instead of just appearing. setTimeout(function () { - // When the preview button is clicked for the first time, - // give some time for the transition from editor.css to - // fire and the view to slide from right to left, - // instead of just appearing. if (!cm.getOption('fullScreen')) { if (editor.options.sideBySideFullscreen === false) { setupNoFullscreenClasses(true); From 7069fd10318f54f318d2fbe107451f6beed9c43a Mon Sep 17 00:00:00 2001 From: Steve Date: Tue, 16 Mar 2021 09:08:54 -0700 Subject: [PATCH 08/16] Move from multiple "no-fullscreen" classes to one using inheritance --- src/css/easymde.css | 8 ++++---- src/js/easymde.js | 40 ++++++++++------------------------------ 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/src/css/easymde.css b/src/css/easymde.css index c59ee3f..4240cf3 100644 --- a/src/css/easymde.css +++ b/src/css/easymde.css @@ -41,7 +41,7 @@ width: 50% !important; } -.EasyMDEContainer .CodeMirror-sided.sided--no-fullscreen { +.EasyMDEContainer.sided--no-fullscreen .CodeMirror-sided { border-right: none!important; border-bottom-right-radius: 0px; position: relative; @@ -118,7 +118,7 @@ padding: 0; } -.editor-toolbar.sided--no-fullscreen { +.EasyMDEContainer.sided--no-fullscreen .editor-toolbar { width: 100%; } @@ -201,7 +201,7 @@ text-align: right; } -.editor-statusbar.sided--no-fullscreen { +.EasyMDEContainer.sided--no-fullscreen .editor-statusbar { width: 100%; } @@ -253,7 +253,7 @@ display: block } -.editor-preview-active-side.sided--no-fullscreen { +.EasyMDEContainer.sided--no-fullscreen .editor-preview-active-side { flex: 1 1 auto; height: auto; position: static; diff --git a/src/js/easymde.js b/src/js/easymde.js index b85c203..1a420a1 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -884,38 +884,18 @@ function toggleSideBySide(editor, onlyCleanup) { var toolbarButton = editor.toolbarElements && editor.toolbarElements['side-by-side']; var useSideBySideListener = false; - var noFullscreenItems = [ - wrapper.parentNode, // easyMDEContainer - editor.gui.toolbar, - wrapper, - preview, - editor.gui.statusbar, - ]; - - function addNoFullscreenClass(el) { - if (el != null) { - el.className += ' sided--no-fullscreen'; - } - } - - function removeNoFullscreenClass(el) { - if (el != null) { - el.className = el.className.replace( - // retain spaces after the class - // in case there are subsequent classes - /\s*sided--no-fullscreen(\s*)/g, '$1' - ); - } - } + var easyMDEContainer = wrapper.parentNode; // helper method to add/remove no-fullscreen classes as appropriate - function setupNoFullscreenClasses(sidePreviewActive) { + function setNoFullscreenClass (sidePreviewActive) { if (editor.options.sideBySideFullscreen === false) { if (!cm.getOption('fullScreen') && sidePreviewActive) { + easyMDEContainer.className += ' sided--no-fullscreen'; // only apply classes if !fullScreen and side preview is (or will be) active - noFullscreenItems.forEach(addNoFullscreenClass); } else { - noFullscreenItems.forEach(removeNoFullscreenClass); + // retain spaces after the class + // in case there are subsequent classes + easyMDEContainer.className = easyMDEContainer.className.replace(/\s*sided--no-fullscreen(\s*)/g, '$1'); } } } @@ -924,10 +904,10 @@ function toggleSideBySide(editor, onlyCleanup) { if (onlyCleanup) { // if not toggling, handle noFullscreen classes as needed - setupNoFullscreenClasses(sidePreviewActive); + setNoFullscreenClass(sidePreviewActive); } else if (sidePreviewActive) { // close side-by-side, and cleanup noFullscreen classes as needed - setupNoFullscreenClasses(false); + setNoFullscreenClass(false); preview.className = preview.className.replace( /\s*editor-preview-active-side\s*/g, '' ); @@ -941,7 +921,7 @@ function toggleSideBySide(editor, onlyCleanup) { setTimeout(function () { if (!cm.getOption('fullScreen')) { if (editor.options.sideBySideFullscreen === false) { - setupNoFullscreenClasses(true); + setNoFullscreenClass(true); } else { toggleFullScreen(editor); } @@ -956,7 +936,7 @@ function toggleSideBySide(editor, onlyCleanup) { // Hide normal (full-pane) preview if active var previewNormal = wrapper.lastChild; - if (!dontToggle && /editor-preview-active/.test(previewNormal.className)) { + if (/editor-preview-active/.test(previewNormal.className)) { previewNormal.className = previewNormal.className.replace( /\s*editor-preview-active\s*/g, '' ); From d636eb740732ff26e7f88d7f4df5bd7cf8a2b9df Mon Sep 17 00:00:00 2001 From: Steve Date: Tue, 16 Mar 2021 09:17:19 -0700 Subject: [PATCH 09/16] clean up diff --- src/js/easymde.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index 1a420a1..e7923ec 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -323,6 +323,7 @@ function toggleFullScreen(editor) { var cm = editor.codemirror; cm.setOption('fullScreen', !cm.getOption('fullScreen')); + // Prevent scrolling on body during fullscreen active if (cm.getOption('fullScreen')) { saved_overflow = document.body.style.overflow; @@ -873,7 +874,7 @@ function redo(editor) { /** - * Toggle side by side preview. + * Toggle side by side preview * @param {EasyMDE} editor - The EasyMDE object * @param {boolean} onlyCleanup Flag for only cleaning up side effects of fullScreen toggle. */ @@ -932,7 +933,6 @@ function toggleSideBySide(editor, onlyCleanup) { wrapper.className += ' CodeMirror-sided'; useSideBySideListener = true; } - // Hide normal (full-pane) preview if active var previewNormal = wrapper.lastChild; @@ -989,6 +989,7 @@ function togglePreview(editor) { // Construct preview element if it doesn't exist if (!preview || !/editor-preview-full/.test(preview.className)) { + preview = document.createElement('div'); preview.className = 'editor-preview-full'; From 4533dd47767aae638d26a8457d3c8ca47fca29d4 Mon Sep 17 00:00:00 2001 From: Steve Date: Tue, 16 Mar 2021 09:21:03 -0700 Subject: [PATCH 10/16] clarify comments in togglePreview --- src/js/easymde.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index e7923ec..76565bb 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -973,7 +973,8 @@ function toggleSideBySide(editor, onlyCleanup) { /** - * Preview action. + * Toggle display of normal (full-pane) preview. + * @param {EasyMDE} editor - The EasyMDE object */ function togglePreview(editor) { var cm = editor.codemirror; @@ -982,12 +983,12 @@ function togglePreview(editor) { var toolbar = editor.options.toolbar ? editor.toolbarElements.preview : false; var preview = wrapper.lastChild; - // Turn off side by side if needed + // Turn off side by side, if needed var sidebyside = cm.getWrapperElement().nextSibling; if (/editor-preview-active-side/.test(sidebyside.className)) toggleSideBySide(editor); - // Construct preview element if it doesn't exist + // Construct normal (full-pane) preview element if it doesn't exist if (!preview || !/editor-preview-full/.test(preview.className)) { preview = document.createElement('div'); @@ -1008,7 +1009,7 @@ function togglePreview(editor) { wrapper.appendChild(preview); } - // Toggle display of preview depending on current state + // Toggle display of normal (full-pane) preview depending on current state if (/editor-preview-active/.test(preview.className)) { preview.className = preview.className.replace( /\s*editor-preview-active\s*/g, '' From 1ee8519e50d07082d8860f616b890b5aab146105 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 17 Mar 2021 10:25:39 -0700 Subject: [PATCH 11/16] Unwind all the onlyCleanup stuff and set classes directly. --- src/js/easymde.js | 51 ++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index 76565bb..cb7dac6 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -332,13 +332,20 @@ function toggleFullScreen(editor) { document.body.style.overflow = saved_overflow; } - var sidebyside = cm.getWrapperElement().nextSibling; + var wrapper = cm.getWrapperElement(); + var sidebyside = wrapper.nextSibling; - // if non-fullscreen side-by-side is allowed, then pass along "onlyCleanup" flag - var onlyCleanup = editor.options.sideBySideFullscreen === false; - - if (/editor-preview-active-side/.test(sidebyside.className) || onlyCleanup) { - toggleSideBySide(editor, onlyCleanup); + if (/editor-preview-active-side/.test(sidebyside.className)) { + if(editor.options.sideBySideFullscreen === false) { + var easyMDEContainer = wrapper.parentNode; + if (cm.getOption('fullScreen')) { + easyMDEContainer.className = easyMDEContainer.className.replace(/\s*sided--no-fullscreen(\s*)/g, '$1'); + } else { + easyMDEContainer.className += ' sided--no-fullscreen'; + } + } else { + toggleSideBySide(editor); + } } if (editor.options.onToggleFullScreen) { @@ -872,13 +879,11 @@ function redo(editor) { cm.focus(); } - /** * Toggle side by side preview * @param {EasyMDE} editor - The EasyMDE object - * @param {boolean} onlyCleanup Flag for only cleaning up side effects of fullScreen toggle. */ -function toggleSideBySide(editor, onlyCleanup) { +function toggleSideBySide(editor) { var cm = editor.codemirror; var wrapper = cm.getWrapperElement(); var preview = wrapper.nextSibling; @@ -887,42 +892,24 @@ function toggleSideBySide(editor, onlyCleanup) { var easyMDEContainer = wrapper.parentNode; - // helper method to add/remove no-fullscreen classes as appropriate - function setNoFullscreenClass (sidePreviewActive) { - if (editor.options.sideBySideFullscreen === false) { - if (!cm.getOption('fullScreen') && sidePreviewActive) { - easyMDEContainer.className += ' sided--no-fullscreen'; - // only apply classes if !fullScreen and side preview is (or will be) active - } else { - // retain spaces after the class - // in case there are subsequent classes - easyMDEContainer.className = easyMDEContainer.className.replace(/\s*sided--no-fullscreen(\s*)/g, '$1'); - } - } - } - - var sidePreviewActive = /editor-preview-active-side/.test(preview.className); - - if (onlyCleanup) { - // if not toggling, handle noFullscreen classes as needed - setNoFullscreenClass(sidePreviewActive); - } else if (sidePreviewActive) { + if (/editor-preview-active-side/.test(preview.className)) { // close side-by-side, and cleanup noFullscreen classes as needed - setNoFullscreenClass(false); + if (editor.options.sideBySideFullscreen === false) { + easyMDEContainer.className = easyMDEContainer.className.replace(/\s*sided--no-fullscreen(\s*)/g, '$1'); + } preview.className = preview.className.replace( /\s*editor-preview-active-side\s*/g, '' ); if (toolbarButton) toolbarButton.className = toolbarButton.className.replace(/\s*active\s*/g, ''); wrapper.className = wrapper.className.replace(/\s*CodeMirror-sided\s*/g, ' '); } else { - // open side-by-side, and setup noFullscreen classes as needed // When the preview button is clicked for the first time, // give some time for the transition from editor.css to fire and the view to slide from right to left, // instead of just appearing. setTimeout(function () { if (!cm.getOption('fullScreen')) { if (editor.options.sideBySideFullscreen === false) { - setNoFullscreenClass(true); + easyMDEContainer.className += ' sided--no-fullscreen'; } else { toggleFullScreen(editor); } From d0f69390ced85d058f93931febe36c990340f8a2 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 17 Mar 2021 10:41:38 -0700 Subject: [PATCH 12/16] a little comment/cleanup --- src/js/easymde.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index cb7dac6..de2414f 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -336,7 +336,8 @@ function toggleFullScreen(editor) { var sidebyside = wrapper.nextSibling; if (/editor-preview-active-side/.test(sidebyside.className)) { - if(editor.options.sideBySideFullscreen === false) { + if (editor.options.sideBySideFullscreen === false) { + // if side-by-side not-fullscreen ok, apply classes as needed var easyMDEContainer = wrapper.parentNode; if (cm.getOption('fullScreen')) { easyMDEContainer.className = easyMDEContainer.className.replace(/\s*sided--no-fullscreen(\s*)/g, '$1'); @@ -893,8 +894,8 @@ function toggleSideBySide(editor) { var easyMDEContainer = wrapper.parentNode; if (/editor-preview-active-side/.test(preview.className)) { - // close side-by-side, and cleanup noFullscreen classes as needed if (editor.options.sideBySideFullscreen === false) { + // if side-by-side not-fullscreen ok, remove classes when hiding side easyMDEContainer.className = easyMDEContainer.className.replace(/\s*sided--no-fullscreen(\s*)/g, '$1'); } preview.className = preview.className.replace( @@ -909,6 +910,7 @@ function toggleSideBySide(editor) { setTimeout(function () { if (!cm.getOption('fullScreen')) { if (editor.options.sideBySideFullscreen === false) { + // if side-by-side not-fullscreen ok, add classes when not fullscreen and showing side easyMDEContainer.className += ' sided--no-fullscreen'; } else { toggleFullScreen(editor); From 40ddcea4e3c1d238c9e19effbea73a9daf882e35 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 17 Mar 2021 10:44:46 -0700 Subject: [PATCH 13/16] remove extra comment updates --- src/js/easymde.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index de2414f..19b93f2 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -880,9 +880,9 @@ function redo(editor) { cm.focus(); } + /** * Toggle side by side preview - * @param {EasyMDE} editor - The EasyMDE object */ function toggleSideBySide(editor) { var cm = editor.codemirror; @@ -962,8 +962,7 @@ function toggleSideBySide(editor) { /** - * Toggle display of normal (full-pane) preview. - * @param {EasyMDE} editor - The EasyMDE object + * Preview action. */ function togglePreview(editor) { var cm = editor.codemirror; @@ -972,12 +971,11 @@ function togglePreview(editor) { var toolbar = editor.options.toolbar ? editor.toolbarElements.preview : false; var preview = wrapper.lastChild; - // Turn off side by side, if needed + // Turn off side by side if needed var sidebyside = cm.getWrapperElement().nextSibling; if (/editor-preview-active-side/.test(sidebyside.className)) toggleSideBySide(editor); - // Construct normal (full-pane) preview element if it doesn't exist if (!preview || !/editor-preview-full/.test(preview.className)) { preview = document.createElement('div'); @@ -998,7 +996,6 @@ function togglePreview(editor) { wrapper.appendChild(preview); } - // Toggle display of normal (full-pane) preview depending on current state if (/editor-preview-active/.test(preview.className)) { preview.className = preview.className.replace( /\s*editor-preview-active\s*/g, '' From 548229dd1a3112314aec302fc130bcb80ee370a6 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 17 Mar 2021 10:45:45 -0700 Subject: [PATCH 14/16] remove added comment --- src/js/easymde.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index 19b93f2..4fdabea 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -923,7 +923,6 @@ function toggleSideBySide(editor) { useSideBySideListener = true; } - // Hide normal (full-pane) preview if active var previewNormal = wrapper.lastChild; if (/editor-preview-active/.test(previewNormal.className)) { previewNormal.className = previewNormal.className.replace( From 82a8e4a8ce1e7d2875be8a70728cdb4f54252b13 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 17 Mar 2021 10:46:18 -0700 Subject: [PATCH 15/16] restore removed comment --- src/js/easymde.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js/easymde.js b/src/js/easymde.js index 4fdabea..0d55ccd 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -923,6 +923,7 @@ function toggleSideBySide(editor) { useSideBySideListener = true; } + // Hide normal preview if active var previewNormal = wrapper.lastChild; if (/editor-preview-active/.test(previewNormal.className)) { previewNormal.className = previewNormal.className.replace( From b61fe7945a1df7ea8e0d46de9adf5604f7c39b3b Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 17 Mar 2021 11:17:14 -0700 Subject: [PATCH 16/16] Add simple class handling utiltity to DRY adding/removing class names. Note that this isn't necessary and can be rolled back, but could be used throughout the code to make class handling more clear and consistent. --- src/js/easymde.js | 52 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/js/easymde.js b/src/js/easymde.js index 0d55ccd..a9c56ab 100644 --- a/src/js/easymde.js +++ b/src/js/easymde.js @@ -138,6 +138,50 @@ function fixShortcut(name) { return name; } +/** + * Class handling utility methods. + */ +var CLASS_REGEX = {}; + +/** + * Convert a className string into a regex for matching (and cache). + * Note that the RegExp includes trailing spaces for replacement + * (to ensure that removing a class from the middle of the string will retain + * spacing between other classes.) + * @param {String} className Class name to convert to regex for matching. + * @returns {RegExp} Regular expression option that will match className. + */ +function getClassRegex (className) { + return CLASS_REGEX[className] || (CLASS_REGEX[className] = new RegExp('\\s*' + className + '(\\s*)', 'g')); +} + +/** + * Add a class string to an element. + * @param {Element} el DOM element on which to add className. + * @param {String} className Class string to apply + * @returns {void} + */ +function addClass (el, className) { + if (!el || !className) return; + var classRegex = getClassRegex(className); + if (el.className.match(classRegex)) return; // already applied + el.className += ' ' + className; +} + +/** + * Remove a class string from an element. + * @param {Element} el DOM element from which to remove className. + * @param {String} className Class string to remove + * @returns {void} + */ + function removeClass (el, className) { + if (!el || !className) return; + var classRegex = getClassRegex(className); + if (!el.className.match(classRegex)) return; // not available to remove + el.className = el.className.replace(classRegex, '$1'); +} + + /** * Create dropdown block */ @@ -340,9 +384,9 @@ function toggleFullScreen(editor) { // if side-by-side not-fullscreen ok, apply classes as needed var easyMDEContainer = wrapper.parentNode; if (cm.getOption('fullScreen')) { - easyMDEContainer.className = easyMDEContainer.className.replace(/\s*sided--no-fullscreen(\s*)/g, '$1'); + removeClass(easyMDEContainer, 'sided--no-fullscreen'); } else { - easyMDEContainer.className += ' sided--no-fullscreen'; + addClass(easyMDEContainer, 'sided--no-fullscreen'); } } else { toggleSideBySide(editor); @@ -896,7 +940,7 @@ function toggleSideBySide(editor) { if (/editor-preview-active-side/.test(preview.className)) { if (editor.options.sideBySideFullscreen === false) { // if side-by-side not-fullscreen ok, remove classes when hiding side - easyMDEContainer.className = easyMDEContainer.className.replace(/\s*sided--no-fullscreen(\s*)/g, '$1'); + removeClass(easyMDEContainer, 'sided--no-fullscreen'); } preview.className = preview.className.replace( /\s*editor-preview-active-side\s*/g, '' @@ -911,7 +955,7 @@ function toggleSideBySide(editor) { if (!cm.getOption('fullScreen')) { if (editor.options.sideBySideFullscreen === false) { // if side-by-side not-fullscreen ok, add classes when not fullscreen and showing side - easyMDEContainer.className += ' sided--no-fullscreen'; + addClass(easyMDEContainer, 'sided--no-fullscreen'); } else { toggleFullScreen(editor); }