diff --git a/admin/client/dist/styles/bundle.css b/admin/client/dist/styles/bundle.css index 136f1e617..9ac0da5f2 100644 --- a/admin/client/dist/styles/bundle.css +++ b/admin/client/dist/styles/bundle.css @@ -9353,6 +9353,10 @@ body.cms{ background:#f6f7f8; } +.cms-container--content-mode .cms-preview,.cms-container--preview-mode .cms-content,.cms-container--split-mode .cms-content .preview-mode-selector{ + display:none; +} + .cms-content-header{ padding-left:1.5385rem; padding-right:1.5385rem; @@ -12536,6 +12540,7 @@ li.class-ErrorPage>a .jstree-pageicon{ .cms-preview{ background-color:#f6f7f8; border-left:1px solid #ced3d9; + position:relative; } .cms-preview .cms-preview-overlay{ diff --git a/admin/client/src/bundles/bundle.js b/admin/client/src/bundles/bundle.js index b87e2664d..f5074a8e3 100644 --- a/admin/client/src/bundles/bundle.js +++ b/admin/client/src/bundles/bundle.js @@ -27,7 +27,6 @@ require('expose?Router!lib/Router'); require('i18n.js'); require('../legacy/sspath.js'); require('../legacy/ssui.core.js'); -// require('../legacy/LeftAndMain.Layout.js'); require('../legacy/LeftAndMain.js'); require('../legacy/LeftAndMain.ActionTabSet.js'); require('../legacy/LeftAndMain.Panel.js'); diff --git a/admin/client/src/legacy/LeftAndMain.Layout.js b/admin/client/src/legacy/LeftAndMain.Layout.js deleted file mode 100644 index 487e2050e..000000000 --- a/admin/client/src/legacy/LeftAndMain.Layout.js +++ /dev/null @@ -1,178 +0,0 @@ -/** - * File: LeftAndMain.Layout.js - */ - -import $ from 'jQuery'; - -$.fn.layout.defaults.resize = false; - -/** - * Acccess the global variable in the same way the plugin does it. - */ -jLayout = (typeof jLayout === 'undefined') ? {} : jLayout; - -/** - * Factory function for generating new type of algorithm for our CMS. - * - * Spec requires a definition of three column elements: - * - `menu` on the left - * - `content` area in the middle (includes the EditForm, side tool panel, actions, breadcrumbs and tabs) - * - `preview` on the right (will be shown if there is enough space) - * - * Required options: - * - `minContentWidth`: minimum size for the content display as long as the preview is visible - * - `minPreviewWidth`: preview will not be displayed below this size - * - `mode`: one of "split", "content" or "preview" - * - * The algorithm first checks which columns are to be visible and which hidden. - * - * In the case where both preview and content should be shown it first tries to assign half of non-menu space to - * preview and the other half to content. Then if there is not enough space for either content or preview, it tries - * to allocate the minimum acceptable space to that column, and the rest to the other one. If the minimum - * requirements are still not met, it falls back to showing content only. - * - * @param spec A structure defining columns and parameters as per above. - */ -jLayout.threeColumnCompressor = function (spec, options) { - // Spec sanity checks. - if (typeof spec.menu==='undefined' || - typeof spec.content==='undefined' || - typeof spec.preview==='undefined') { - throw 'Spec is invalid. Please provide "menu", "content" and "preview" elements.'; - } - if (typeof options.minContentWidth==='undefined' || - typeof options.minPreviewWidth==='undefined' || - typeof options.mode==='undefined') { - throw 'Spec is invalid. Please provide "minContentWidth", "minPreviewWidth", "mode"'; - } - if (options.mode!=='split' && options.mode!=='content' && options.mode!=='preview') { - throw 'Spec is invalid. "mode" should be either "split", "content" or "preview"'; - } - - // Instance of the algorithm being produced. - var obj = { - options: options - }; - - // Internal column handles, also implementing layout. - var menu = $.jLayoutWrap(spec.menu), - content = $.jLayoutWrap(spec.content), - preview = $.jLayoutWrap(spec.preview); - - /** - * Required interface implementations follow. - * Refer to https://github.com/bramstein/jlayout#layout-algorithms for the interface spec. - */ - obj.layout = function (container) { - var size = container.bounds(), - insets = container.insets(), - top = insets.top, - bottom = size.height - insets.bottom, - left = insets.left, - right = size.width - insets.right; - - var menuWidth = spec.menu.width(), - contentWidth = 0, - previewWidth = 0; - - if (this.options.mode==='preview') { - // All non-menu space allocated to preview. - contentWidth = 0; - previewWidth = right - left - menuWidth; - } else if (this.options.mode==='content') { - // All non-menu space allocated to content. - contentWidth = right - left - menuWidth; - previewWidth = 0; - } else { // ==='split' - // Split view - first try 50-50 distribution. - contentWidth = (right - left - menuWidth) / 2; - previewWidth = right - left - (menuWidth + contentWidth); - - // If violating one of the minima, try to readjust towards satisfying it. - if (contentWidth < this.options.minContentWidth) { - contentWidth = this.options.minContentWidth; - previewWidth = right - left - (menuWidth + contentWidth); - } else if (previewWidth < this.options.minPreviewWidth) { - previewWidth = this.options.minPreviewWidth; - contentWidth = right - left - (menuWidth + previewWidth); - } - - // If still violating one of the (other) minima, remove the preview and allocate everything to content. - if (contentWidth < this.options.minContentWidth || previewWidth < this.options.minPreviewWidth) { - contentWidth = right - left - menuWidth; - previewWidth = 0; - } - } - - // Calculate what columns are already hidden pre-layout - var prehidden = { - content: spec.content.hasClass('column-hidden'), - preview: spec.preview.hasClass('column-hidden') - }; - - // Calculate what columns will be hidden (zero width) post-layout - var posthidden = { - content: contentWidth === 0, - preview: previewWidth === 0 - }; - - // Apply classes for elements that might not be visible at all. - spec.content.toggleClass('column-hidden', posthidden.content); - spec.preview.toggleClass('column-hidden', posthidden.preview); - - // Apply the widths to columns, and call subordinate layouts to arrange the children. - menu.bounds({'x': left, 'y': top, 'height': bottom - top, 'width': menuWidth}); - menu.doLayout(); - - left += menuWidth; - - content.bounds({'x': left, 'y': top, 'height': bottom - top, 'width': contentWidth}); - if (!posthidden.content) content.doLayout(); - - left += contentWidth; - - preview.bounds({'x': left, 'y': top, 'height': bottom - top, 'width': previewWidth}); - if (!posthidden.preview) preview.doLayout(); - - if (posthidden.content !== prehidden.content) spec.content.trigger('columnvisibilitychanged'); - if (posthidden.preview !== prehidden.preview) spec.preview.trigger('columnvisibilitychanged'); - - // Calculate whether preview is possible in split mode - if (contentWidth + previewWidth < options.minContentWidth + options.minPreviewWidth) { - spec.preview.trigger('disable'); - } else { - spec.preview.trigger('enable'); - } - - return container; - }; - - /** - * Helper to generate the required `preferred`, `minimum` and `maximum` interface functions. - */ - function typeLayout(type) { - var func = type + 'Size'; - - return function (container) { - var menuSize = menu[func](), - contentSize = content[func](), - previewSize = preview[func](), - insets = container.insets(); - - width = menuSize.width + contentSize.width + previewSize.width; - height = Math.max(menuSize.height, contentSize.height, previewSize.height); - - return { - 'width': insets.left + insets.right + width, - 'height': insets.top + insets.bottom + height - }; - }; - } - - // Generate interface functions. - obj.preferred = typeLayout('preferred'); - obj.minimum = typeLayout('minimum'); - obj.maximum = typeLayout('maximum'); - - return obj; -}; diff --git a/admin/client/src/legacy/LeftAndMain.Preview.js b/admin/client/src/legacy/LeftAndMain.Preview.js index c0bb892b6..278feda96 100644 --- a/admin/client/src/legacy/LeftAndMain.Preview.js +++ b/admin/client/src/legacy/LeftAndMain.Preview.js @@ -99,18 +99,18 @@ $.entwine('ss.preview', function($){ * modeName can be: split, content, preview. */ changeMode: function(modeName, save) { - var container = $('.cms-container'); + var container = $('.cms-container').entwine('.ss'); if (modeName == 'split') { - container.entwine('.ss').splitViewMode(); + container.splitViewMode(); this.setIsPreviewEnabled(true); this._loadCurrentState(); } else if (modeName == 'content') { - container.entwine('.ss').contentViewMode(); + container.contentViewMode(); this.setIsPreviewEnabled(false); // Do not load content as the preview is not visible. } else if (modeName == 'preview') { - container.entwine('.ss').previewMode(); + container.previewMode(); this.setIsPreviewEnabled(true); this._loadCurrentState(); } else { @@ -119,8 +119,6 @@ $.entwine('ss.preview', function($){ if(save !== false) this.saveState('mode', modeName); - this.redraw(); - return this; }, @@ -242,7 +240,7 @@ $.entwine('ss.preview', function($){ * Initialise the preview element. */ onadd: function() { - var self = this, layoutContainer = this.parent(), iframe = this.find('iframe'); + var self = this, iframe = this.find('iframe'); // Create layout and controls iframe.addClass('center'); @@ -267,8 +265,7 @@ $.entwine('ss.preview', function($){ } // Preview might not be available in all admin interfaces - block/disable when necessary - this.append('
'); - this.find('.cms-preview-overlay').hide(); + this._unblock(); this.disablePreview(); @@ -310,7 +307,7 @@ $.entwine('ss.preview', function($){ * Set the preview to unavailable - could be still visible. This is purely visual. */ _block: function() { - this.addClass('blocked'); + this.find('.preview-note').show(); this.find('.cms-preview-overlay').show(); return this; }, @@ -319,7 +316,7 @@ $.entwine('ss.preview', function($){ * Set the preview to available (remove the overlay); */ _unblock: function() { - this.removeClass('blocked'); + this.find('.preview-note').hide(); this.find('.cms-preview-overlay').hide(); return this; }, @@ -640,9 +637,8 @@ $.entwine('ss.preview', function($){ /** * Adjust the visibility of the preview-mode selector in the CMS part (hidden if preview is visible). */ - $('.cms-preview.column-hidden').entwine({ + $('.cms-container--content-mode').entwine({ onmatch: function() { - $('#preview-mode-dropdown-in-content').show(); // Alert the user as to why the preview is hidden if ($('.cms-preview .result-selected').hasClass('font-icon-columns')) { statusMessage(i18n._t( @@ -651,29 +647,6 @@ $.entwine('ss.preview', function($){ "error"); } this._super(); - }, - - onunmatch: function() { - $('#preview-mode-dropdown-in-content').hide(); - this._super(); - } - }); - - /** - * Initialise the preview-mode selector in the CMS part (could be hidden if preview is visible). - */ - $('#preview-mode-dropdown-in-content').entwine({ - onmatch: function() { - if ($('.cms-preview').is('.column-hidden')) { - this.show(); - } - else { - this.hide(); - } - this._super(); - }, - onunmatch: function() { - this._super(); } }); @@ -751,7 +724,7 @@ $.entwine('ss.preview', function($){ } }); - + /** * Rotate preview to landscape diff --git a/admin/client/src/legacy/LeftAndMain.js b/admin/client/src/legacy/LeftAndMain.js index d16670225..b63e97113 100644 --- a/admin/client/src/legacy/LeftAndMain.js +++ b/admin/client/src/legacy/LeftAndMain.js @@ -260,6 +260,12 @@ $.entwine('ss', function($) { if (dirty) this.redraw(); }, + clearViewMode: function () { + this.removeClass('cms-container--split-mode'); + this.removeClass('cms-container--preview-mode'); + this.removeClass('cms-container--content-mode'); + }, + /** * Enable the split view - with content on the left and preview on the right. */ @@ -294,12 +300,53 @@ $.entwine('ss', function($) { if(window.debug) console.log('redraw', this.attr('class'), this.get(0)); - // Redraw on all the children that need it - this.find('.cms-panel-layout').redraw(); - this.find('.cms-content-fields[data-layout-type]').redraw(); - this.find('.cms-edit-form[data-layout-type]').redraw(); - this.find('.cms-preview').redraw(); - this.find('.cms-content').redraw(); + // disable split mode if screen is too small + var changed = this.setProperMode(); + + // if changed, then the changing would trigger a redraw, so we don't want to redraw twice + if (!changed) { + // Redraw on all the children that need it + this.find('.cms-panel-layout').redraw(); + this.find('.cms-content-fields[data-layout-type]').redraw(); + this.find('.cms-edit-form[data-layout-type]').redraw(); + this.find('.cms-preview').redraw(); + this.find('.cms-content').redraw(); + } + }, + + /** + * Changes the viewing mode if the screen is too small, disables split mode. + * + * @returns {boolean} changedMode - so redraw is not called twice + */ + setProperMode: function () { + var options = this.getLayoutOptions(); + var mode = options.mode; + this.clearViewMode(); + + var content = this.find('.cms-content'); + var preview = this.find('.cms-preview'); + + content.css('min-width', ''); + preview.css('min-width', ''); + + if (content.width() + preview.width() >= options.minContentWidth + options.minPreviewWidth) { + if (content.width() < options.minContentWidth) { + content.css('min-width', options.minContentWidth); + } else { + preview.css('min-width', options.minPreviewWidth); + } + $('.cms-preview').trigger('enable'); + } else { + $('.cms-preview').trigger('disable'); + if (mode == 'split') { + // force change mode and leave it redraw after + this.contentViewMode(); + return true; + } + } + this.addClass('cms-container--' + mode + '-mode'); + return false; }, /** diff --git a/admin/client/src/styles/legacy/_preview.scss b/admin/client/src/styles/legacy/_preview.scss index 61340506c..c52d98109 100644 --- a/admin/client/src/styles/legacy/_preview.scss +++ b/admin/client/src/styles/legacy/_preview.scss @@ -233,6 +233,7 @@ .cms-preview { background-color: $tab-panel-texture-color; border-left: 1px solid $border-color-dark; + position: relative; .cms-preview-overlay { width: 100%; diff --git a/admin/client/src/styles/legacy/_style.scss b/admin/client/src/styles/legacy/_style.scss index 7f21b5ed7..79f782925 100644 --- a/admin/client/src/styles/legacy/_style.scss +++ b/admin/client/src/styles/legacy/_style.scss @@ -49,6 +49,24 @@ body.cms { background: $tab-panel-texture-color; } +.cms-container--content-mode { + .cms-preview { + display: none; + } +} + +.cms-container--split-mode { + .cms-content .preview-mode-selector { + display: none; + } +} + +.cms-container--preview-mode { + .cms-content { + display: none; + } +} + // .cms-preview, // .cms-menu, // .cms-content,