diff --git a/example/index_sideBySideFullscreenFalse.html b/example/index_sideBySideFullscreenFalse.html new file mode 100644 index 0000000..8fe15db --- /dev/null +++ b/example/index_sideBySideFullscreenFalse.html @@ -0,0 +1,20 @@ + + + + + + + + Example / Preview / sideBySideFullscreen : false + + + + + + + + + + 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 44427f8..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 */ @@ -332,11 +376,21 @@ function toggleFullScreen(editor) { document.body.style.overflow = saved_overflow; } - // 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)) + var wrapper = cm.getWrapperElement(); + var sidebyside = wrapper.nextSibling; + + if (/editor-preview-active-side/.test(sidebyside.className)) { + if (editor.options.sideBySideFullscreen === false) { + // if side-by-side not-fullscreen ok, apply classes as needed + var easyMDEContainer = wrapper.parentNode; + if (cm.getOption('fullScreen')) { + removeClass(easyMDEContainer, 'sided--no-fullscreen'); + } else { + addClass(easyMDEContainer, 'sided--no-fullscreen'); + } + } else { toggleSideBySide(editor); + } } if (editor.options.onToggleFullScreen) { @@ -881,32 +935,12 @@ function toggleSideBySide(editor) { 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) { - el.className += ' sided--no-fullscreen'; - } - - function removeNoFullscreenClass(el) { - if (el != null) { - el.className = el.className.replace( - /\s*sided--no-fullscreen\s*/g, '' - ); - } - } + var easyMDEContainer = wrapper.parentNode; if (/editor-preview-active-side/.test(preview.className)) { - if (cm.getOption('sideBySideNoFullscreen')) { - cm.setOption('sideBySideNoFullscreen', false); - noFullscreenItems.forEach(function (el) { - removeNoFullscreenClass(el); - }); + if (editor.options.sideBySideFullscreen === false) { + // if side-by-side not-fullscreen ok, remove classes when hiding side + removeClass(easyMDEContainer, 'sided--no-fullscreen'); } preview.className = preview.className.replace( /\s*editor-preview-active-side\s*/g, '' @@ -920,12 +954,8 @@ function toggleSideBySide(editor) { setTimeout(function () { if (!cm.getOption('fullScreen')) { if (editor.options.sideBySideFullscreen === false) { - cm.setOption('sideBySideNoFullscreen', true); - noFullscreenItems.forEach(function(el) { - if (el != null) { - addNoFullscreenClass(el); - } - }); + // if side-by-side not-fullscreen ok, add classes when not fullscreen and showing side + addClass(easyMDEContainer, 'sided--no-fullscreen'); } else { toggleFullScreen(editor); }