FIX Multiple redraw calls on navigation

This commit is contained in:
Hamish Friedlander 2013-08-12 14:18:18 +12:00
parent 3510b60ab8
commit c59305d6d4
2 changed files with 77 additions and 66 deletions

View File

@ -30,7 +30,7 @@
WidthCollapsed: null,
onmatch: function() {
onadd: function() {
if(!this.find('.cms-panel-content').length) throw new Exception('Content panel for ".cms-panel" not found');
// Create default controls unless they already exist.
@ -62,9 +62,6 @@
this._super();
},
onunmatch: function() {
this._super();
},
/**
* @param {Boolean} TRUE to expand, FALSE to collapse.
* @param {Boolean} TRUE means that events won't be fired, which is useful for the component initialization phase.
@ -89,7 +86,7 @@
// Save collapsed state in cookie
if($.cookie && this.attr('id')) $.cookie('cms-panel-collapsed-' + this.attr('id'), !bool, {path: '/', expires: 31});
// TODO Fix redraw order (inner to outer), and re-enable silent flag
// to avoid multiple expensive redraws on a single load.
// if(!silent) {

View File

@ -104,8 +104,7 @@ jQuery.noConflict();
statusMessage(decodeURIComponent(msg), msgType);
}
});
/**
* Main LeftAndMain interface with some control panel and an edit form.
*
@ -190,13 +189,22 @@ jQuery.noConflict();
},
/**
* Change the options of the threeColumnCompressor layout, and trigger layouting. You can provide any or
* all options. The remaining options will not be changed.
* Change the options of the threeColumnCompressor layout, and trigger layouting if needed.
* You can provide any or all options. The remaining options will not be changed.
*/
updateLayoutOptions: function(newSpec) {
var spec = this.getLayoutOptions();
$.extend(spec, newSpec);
this.redraw();
var dirty = false;
for (var k in newSpec) {
if (spec[k] !== newSpec[k]) {
spec[k] = newSpec[k];
dirty = true;
}
}
if (dirty) this.redraw();
},
/**
@ -206,7 +214,6 @@ jQuery.noConflict();
this.updateLayoutOptions({
mode: 'split'
});
this.redraw();
},
/**
@ -216,7 +223,6 @@ jQuery.noConflict();
this.updateLayoutOptions({
mode: 'content'
});
this.redraw();
},
/**
@ -226,10 +232,13 @@ jQuery.noConflict();
this.updateLayoutOptions({
mode: 'preview'
});
this.redraw();
},
RedrawSuppression: false,
redraw: function() {
if (this.getRedrawSuppression()) return;
if(window.debug) console.log('redraw', this.attr('class'), this.get(0));
// Reset the algorithm.
@ -247,9 +256,9 @@ jQuery.noConflict();
this.layout();
// 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-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();
},
@ -503,62 +512,67 @@ jQuery.noConflict();
newFragments[guessFragment] = $data;
}
// Replace each fragment individually
$.each(newFragments, function(newFragment, html) {
var contentEl = $('[data-pjax-fragment]').filter(function() {
return $.inArray(newFragment, $(this).data('pjaxFragment').split(' ')) != -1;
}), newContentEl = $(html);
this.setRedrawSuppression(true);
try {
// Replace each fragment individually
$.each(newFragments, function(newFragment, html) {
var contentEl = $('[data-pjax-fragment]').filter(function() {
return $.inArray(newFragment, $(this).data('pjaxFragment').split(' ')) != -1;
}), newContentEl = $(html);
// Add to result collection
if(newContentEls) newContentEls.add(newContentEl);
else newContentEls = newContentEl;
// Update panels
if(newContentEl.find('.cms-container').length) {
throw 'Content loaded via ajax is not allowed to contain tags matching the ".cms-container" selector to avoid infinite loops';
}
// Set loading state and store element state
var origStyle = contentEl.attr('style');
var origParent = contentEl.parent();
var origParentLayoutApplied = (typeof origParent.data('jlayout')!=='undefined');
var layoutClasses = ['east', 'west', 'center', 'north', 'south', 'column-hidden'];
var elemClasses = contentEl.attr('class');
var origLayoutClasses = [];
if(elemClasses) {
origLayoutClasses = $.grep(
elemClasses.split(' '),
function(val) { return ($.inArray(val, layoutClasses) >= 0);}
);
}
newContentEl
.removeClass(layoutClasses.join(' '))
.addClass(origLayoutClasses.join(' '));
if(origStyle) newContentEl.attr('style', origStyle);
// Add to result collection
if(newContentEls) newContentEls.add(newContentEl);
else newContentEls = newContentEl;
// Allow injection of inline styles, as they're not allowed in the document body.
// Not handling this through jQuery.ondemand to avoid parsing the DOM twice.
var styles = newContentEl.find('style').detach();
if(styles.length) $(document).find('head').append(styles);
// Update panels
if(newContentEl.find('.cms-container').length) {
throw 'Content loaded via ajax is not allowed to contain tags matching the ".cms-container" selector to avoid infinite loops';
}
// Replace panel completely (we need to override the "layout" attribute, so can't replace the child instead)
contentEl.replaceWith(newContentEl);
// Set loading state and store element state
var origStyle = contentEl.attr('style');
var origParent = contentEl.parent();
var origParentLayoutApplied = (typeof origParent.data('jlayout')!=='undefined');
var layoutClasses = ['east', 'west', 'center', 'north', 'south', 'column-hidden'];
var elemClasses = contentEl.attr('class');
var origLayoutClasses = [];
if(elemClasses) {
origLayoutClasses = $.grep(
elemClasses.split(' '),
function(val) { return ($.inArray(val, layoutClasses) >= 0);}
);
}
// Force jlayout to rebuild internal hierarchy to point to the new elements.
// This is only necessary for elements that are at least 3 levels deep. 2nd level elements will
// be taken care of when we lay out the top level element (.cms-container).
if (!origParent.is('.cms-container') && origParentLayoutApplied) {
origParent.layout();
}
});
newContentEl
.removeClass(layoutClasses.join(' '))
.addClass(origLayoutClasses.join(' '));
if(origStyle) newContentEl.attr('style', origStyle);
// Re-init tabs (in case the form tag itself is a tabset)
var newForm = newContentEls.filter('form');
if(newForm.hasClass('cms-tabset')) newForm.removeClass('cms-tabset').addClass('cms-tabset');
// Allow injection of inline styles, as they're not allowed in the document body.
// Not handling this through jQuery.ondemand to avoid parsing the DOM twice.
var styles = newContentEl.find('style').detach();
if(styles.length) $(document).find('head').append(styles);
// Replace panel completely (we need to override the "layout" attribute, so can't replace the child instead)
contentEl.replaceWith(newContentEl);
// Force jlayout to rebuild internal hierarchy to point to the new elements.
// This is only necessary for elements that are at least 3 levels deep. 2nd level elements will
// be taken care of when we lay out the top level element (.cms-container).
if (!origParent.is('.cms-container') && origParentLayoutApplied) {
origParent.layout();
}
});
// Re-init tabs (in case the form tag itself is a tabset)
var newForm = newContentEls.filter('form');
if(newForm.hasClass('cms-tabset')) newForm.removeClass('cms-tabset').addClass('cms-tabset');
}
finally {
this.setRedrawSuppression(false);
}
this.redraw();
this.restoreTabState((state && typeof state.data.tabState !== 'undefined') ? state.data.tabState : null);
return newContentEls;