Permalink
Browse files

NEW Side by side editing functionality - first cut (os#7412)

Introduces a preview window that appears when the screen is wide enough,
removes old preview button, adds a draft-public switch, adds variety of
preview options which are not hooked up yet.

Goes along with cms commit fa3738a9f4c5181eabf18a77ca89792d31592250
  • Loading branch information...
1 parent fa84c2d commit f4b080ee06b677aa82ec0dbbe73e1503ec93005e @mateusz mateusz committed with chillu Nov 22, 2012
@@ -294,6 +294,7 @@ public function init() {
'leftandmain.js',
array_unique(array_merge(
array(
+ FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.Layout.js',
FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.js',
FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.Panel.js',
FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.Tree.js',
View

Large diffs are not rendered by default.

Oops, something went wrong.
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -93,7 +93,7 @@
if(window.debug) console.log('redraw', this.attr('class'), this.get(0));
// Fix dimensions to actual extents, in preparation for a relayout via jslayout.
- this.height('auto');
+ this.height('28px');
this.height(this.innerHeight()-this.css('padding-top')-this.css('padding-bottom'));
}
});
@@ -0,0 +1,96 @@
+/**
+ * File: LeftAndMain.Layout.js
+ */
+
+(function($) {
+
+ $.fn.layout.defaults.resize = false;
+
+ var minMenuWidth = 40;
+ var maxMenuWidth = 150;
+ var prefContentWidth = 820;
+ var prefPreviewWidth = 500;
+ var minPreviewWidth = 400;
+
+ jLayout = (typeof jLayout === 'undefined') ? {} : jLayout;
+
+ jLayout.threeColumnCompressor = function (spec) {
+ var obj = {}, menu = $.jLayoutWrap(spec.menu), content = $.jLayoutWrap(spec.content), preview = $.jLayoutWrap(spec.preview);
+
+ obj.layout = function (container) {
+ var contentHidden = (content.item.is('.is-collapsed'));
+
+ 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 = $('#cms-menu.cms-panel').hasClass('collapsed') ? minMenuWidth : maxMenuWidth;
+ var contentWidth = contentHidden ? 0 : prefContentWidth;
+ var previewWidth = right - left - (menuWidth + contentWidth);
+
+ if (!contentHidden) {
+ var previewWidth = right - left - (menuWidth + contentWidth);
+ var previewUnderlay = false;
+
+ // If preview width is less than the minimum size, take some off the menu
+ if (previewWidth < prefPreviewWidth) {
+ if (previewWidth < minPreviewWidth) {
+ contentWidth = right - left - menuWidth;
+ previewWidth = right - left - menuWidth;
+ previewUnderlay = true;
+
+ if (contentWidth < prefContentWidth) {
+ contentWidth = right - left - menuWidth;
+ previewWidth = right - left - menuWidth;
+ }
+ }
+ }
+
+ else if (previewWidth > 500) {
+ contentWidth = (right - left - menuWidth) / 2;
+ previewWidth = right - left - (menuWidth + contentWidth);
+ }
+ }
+
+ 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});
+ content.item.css({display: contentHidden ? 'none' : 'block'});
+ content.doLayout();
+ if (!previewUnderlay) left += contentWidth;
+
+ preview.bounds({'x': left, 'y': top, 'height': bottom - top, 'width': previewWidth});
+ preview.doLayout();
+
+
+ return container;
+ };
+
+ 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
+ };
+ };
+ }
+
+ obj.preferred = typeLayout('preferred');
+ obj.minimum = typeLayout('minimum');
+ obj.maximum = typeLayout('maximum');
+ return obj;
+ };
+
+}(jQuery));
@@ -79,8 +79,6 @@
var newWidth = bool ? this.getWidthExpanded() : this.getWidthCollapsed();
this.width(newWidth); // the content panel width always stays in "expanded state" to avoid floating elements
- this.find('.toggle-collapse')[bool ? 'show' : 'hide']();
- this.find('.toggle-expand')[bool ? 'hide' : 'show']();
// If an alternative collapsed view exists, toggle it as well
var collapsedContent = this.find('.cms-panel-content-collapsed');
@@ -10,7 +10,7 @@
* The admin UI itself is collapsible, leaving most screen space to this panel.
*
* Relies on the server responses to indicate if a preview URL is available for the
- * currently loaded admin interface. If no preview is available, the panel is "blocked"
+ * currently loaded admin interface. If no preview is available, the panel is "blocked"
* automatically.
*
* Internal links within the preview iframe trigger a refresh of the admin panel as well,
@@ -40,11 +40,9 @@
// Load edit view for new page, but only if the preview is activated at the moment.
// This avoids e.g. force-redirections of the edit view on RedirectorPage instances.
- if(!self.is('.is-collapsed')) self.loadCurrentPage();
+ self.loadCurrentPage();
});
- if(this.hasClass('is-expanded')) this.expand();
- else this.collapse();
this.data('cms-preview-initialized', true);
// Preview might not be available in all admin interfaces - block/disable when necessary
@@ -53,21 +51,18 @@
$('.cms-preview-toggle-link')[this.canPreview() ? 'show' : 'hide']();
self._fixIframeLinks();
-
+ this.updatePreview();
+
this._super();
},
+
loadUrl: function(url) {
this.find('iframe').attr('src', url);
},
- updateAfterXhr: function(){
- $('.cms-preview-toggle-link')[this.canPreview() ? 'show' : 'hide']();
-
- // Only load when panel is visible (see details in iframe load event handler).
- if(this.is('.is-collapsed')) return;
-
- // var url = ui.xmlhttp.getResponseHeader('x-frontend-url');
+ updatePreview: function() {
var url = $('.cms-edit-form').choosePreviewLink();
+
if(url) {
this.loadUrl(url);
this.unblock();
@@ -77,6 +72,11 @@
}
},
+ updateAfterXhr: function(){
+ $('.cms-preview-toggle-link')[this.canPreview() ? 'show' : 'hide']();
+ this.updatePreview();
+ },
+
'from .cms-container': {
onaftersubmitform: function(){
this.updateAfterXhr();
@@ -86,15 +86,6 @@
}
},
- // Toggle preview when new menu entry is selected.
- // Only do this when preview is actually shown,
- // to avoid auto-expanding the menu in normal CMS mode
- 'from .cms-menu-list li': {
- onselect: function(){
- if(!this.hasClass('is-collapsed')) this.collapse();
- }
- },
-
/**
* Loads the matching edit form for a page viewed in the preview iframe,
* based on metadata sent along with this document.
@@ -130,7 +121,13 @@
},
_fixIframeLinks: function() {
- var doc = this.find('iframe')[0].contentDocument;
+ var iframe = this.find('iframe')[0];
+ if(iframe){
+ var doc = iframe.contentDocument;
+ }else{
+ return;
+ }
+
if(!doc) return;
// Block outside links from going anywhere
@@ -151,40 +148,7 @@
var naviMsg = doc.getElementById('SilverStripeNavigatorMessage');
if(naviMsg) naviMsg.style.display = 'none';
},
-
- expand: function(inclMenu) {
- var self = this, containerEl = this.getLayoutContainer(), contentEl = containerEl.find('.cms-content');
- this.show();
- this.removeClass('east').addClass('center').removeClass('is-collapsed');
- // this.css('overflow', 'auto');
- contentEl.removeClass('center').hide();
- this.find('iframe').show();
- this.find('.cms-preview-toggle a').html('&raquo;');
- this.find('.cms-preview-controls').show();
-
- if(this.data('cms-preview-initialized')) {
- containerEl.find('.cms-menu').collapsePanel();
- }
-
- containerEl.redraw();
- },
-
- collapse: function() {
- var self = this, containerEl = this.getLayoutContainer(), contentEl = containerEl.find('.cms-content');
- this.addClass('east').removeClass('center').addClass('is-collapsed').width(10);
- // this.css('overflow', 'hidden');
- contentEl.addClass('center').show().css('visibility', 'visible');
- this.find('iframe').hide();
- this.find('.cms-preview-toggle a').html('&laquo;');
- this.find('.cms-preview-controls').hide();
- if(this.data('cms-preview-initialized')) {
- containerEl.find('.cms-menu').expandPanel();
- }
-
- containerEl.redraw();
- },
-
block: function() {
this.addClass('blocked');
},
@@ -197,13 +161,8 @@
return this.parents('.cms-container');
},
- toggle: function(bool) {
- this[this.hasClass('is-collapsed') ? 'expand' : 'collapse']();
- },
redraw: function() {
if(window.debug) console.log('redraw', this.attr('class'), this.get(0));
-
- this.layout({resize: false});
}
});
@@ -238,73 +197,56 @@
}
});
- $('.cms-preview .cms-preview-toggle').entwine({
- onclick: function(e) {
- e.preventDefault();
- this.parents('.cms-preview').toggle();
- }
- });
-
- $('.cms-switch-view a').entwine({
- onclick: function(e) {
- e.preventDefault();
+ $('.switch-options a').entwine({
+ onclick: function(e) {
var preview = $('.cms-preview');
- preview.toggle(true);
- preview.loadUrl($(e.target).attr('href'));
+ var loadSibling = $(this).siblings('a');
+ var checkbox = $(this).closest('.cms-preview-states').find('input');
+ if(checkbox.attr('checked') !== undefined){
+ checkbox.attr('checked', false);
+ }else{
+ checkbox.attr('checked', true);
+ }
+ preview.loadUrl($(loadSibling).attr('href'));
+ return false;
}
- });
+ });
- $('.cms-menu li').entwine({
- onclick: function(e) {
- // Prevent reloading of interface when opening the edit panel
- if(this.hasClass('Menu-CMSMain')) {
- var preview = $('.cms-preview');
- preview.toggle(true);
- e.preventDefault();
+
+ $('#cms-preview-mode-dropdown').entwine({
+ onchange: function(e) {
+ e.preventDefault();
+
+ var content = $('.cms-content');
+ var state = $(this).val();
+ if (state == 'split') {
+ content.removeClass('is-collapsed');
+ } else {
+ content.addClass('is-collapsed');
}
+ content.parent().redraw();
}
});
- $('.cms-preview .cms-preview-states').entwine({
- onmatch: function() {
- this.find('a').addClass('disabled');
- this.find('.active a').removeClass('disabled');
- this.find('.cms-preview-watermark').show();
- this.find('.active .cms-preview-watermark').hide();
- this._super();
- },
- onunmatch: function() {
- this._super();
- }
- });
- $('.cms-preview .cms-preview-states a').entwine({
+ // Preview selectors (screen size, screen mode)
+ $('.preview-selector .preview-selected').entwine({
onclick: function(e) {
e.preventDefault();
- this.parents('.cms-preview').loadUrl(this.attr('href'));
- this.addClass('disabled');
- this.parents('.cms-preview-states').find('a').not(this).removeClass('disabled');
- //This hides all watermarks
- this.parents('.cms-preview-states').find('.cms-preview-watermark').hide();
- //Show the watermark for the current state
- this.siblings('.cms-preview-watermark').show();
+ this.parents('.preview-selector').toggleClass('active');
}
});
-
- $('.cms-preview-toggle-link').entwine({
+ $(".preview-selector .preview-size-menu li").entwine({
onclick: function(e) {
- e.preventDefault();
-
- var preview = $('.cms-preview'),
- url = $('.cms-edit-form').choosePreviewLink();
-
- if(url) {
- preview.loadUrl(url);
- preview.unblock();
- preview.toggle();
- }
+ var text = $(this).html();
+ this.parents('.preview-selector').removeClass('active').find('.preview-selected').html(text);
+ this.siblings().removeClass('active');
+ this.addClass('active');
}
- });
+ });
+
+
+
$('.cms-edit-form').entwine({
/**
Oops, something went wrong.

0 comments on commit f4b080e

Please sign in to comment.