235 lines
8.9 KiB
JavaScript
235 lines
8.9 KiB
JavaScript
/* global FusionPageBuilderViewManager, fusionAllElements, FusionEvents, FusionApp */
|
|
var FusionPageBuilder = FusionPageBuilder || {};
|
|
|
|
( function() {
|
|
|
|
FusionPageBuilder.Navigator = Backbone.Model.extend( {
|
|
|
|
defaults: {
|
|
// see _getNavItemObject() function for this object format.
|
|
navigatorItems: null,
|
|
// An object with the views that are collapsed.
|
|
collapsedItems: {},
|
|
// If is either a page/column/element... etc. library navigator. This will not display some buttons.
|
|
navigatorType: ''
|
|
},
|
|
|
|
verifiedNestedRowsForCollapse: {},
|
|
|
|
initialize: function() {
|
|
this.update = _.debounce( this.update.bind( this ), 20 );
|
|
|
|
// Used for nested columns added.
|
|
this.listenTo( FusionEvents, 'fusion-columns-added', this.update );
|
|
this.listenTo( FusionEvents, 'fusion-content-changed', this.update );
|
|
this.listenTo( FusionEvents, 'fusion-element-removed', this.update );
|
|
this.listenTo( FusionEvents, 'fusion-column-resized', this.update );
|
|
|
|
this.listenTo( FusionEvents, 'fusion-cancel-nested-row-changes', this.restoreNestedRowCollapsible );
|
|
},
|
|
|
|
/**
|
|
* Update all the attributes. This will also trigger render if necessary.
|
|
*/
|
|
update: function() {
|
|
var navigatorItems = this.getNavigatorItems();
|
|
this.setNavigatorType();
|
|
this.setNewNestedRowsToCollapsible( navigatorItems );
|
|
|
|
// this will render if it's changed.
|
|
this.set( 'navigatorItems', navigatorItems );
|
|
},
|
|
|
|
getNavigatorItems: function() {
|
|
var elementViews = FusionPageBuilderViewManager.getViews(),
|
|
index,
|
|
navItems = [],
|
|
elType,
|
|
isContainerView,
|
|
isCheckoutForm,
|
|
isNextPageView,
|
|
isFormStep;
|
|
|
|
this._updateModelsToViewsMap( elementViews );
|
|
|
|
for ( index in elementViews ) {
|
|
if ( 'object' !== typeof elementViews[ index ] ) {
|
|
continue; // eslint-disable-line no-continue
|
|
}
|
|
|
|
elType = elementViews[ index ].model.get( 'element_type' );
|
|
isContainerView = ( 'fusion_builder_container' === elType );
|
|
isNextPageView = ( 'fusion_builder_next_page' === elType );
|
|
isCheckoutForm = ( 'fusion_woo_checkout_form' === elType );
|
|
isFormStep = ( 'fusion_builder_form_step' === elType );
|
|
|
|
|
|
// Construct all the containers, with their children in order.
|
|
// Only the children are in order, and not the containers themselves.
|
|
if ( isContainerView || ( isNextPageView && ! elementViews[ index ].$el.hasClass( 'fusion-builder-next-page-last' ) ) || isCheckoutForm || isFormStep ) {
|
|
navItems.push( this._getNavItemObject( elementViews[ index ] ) );
|
|
}
|
|
}
|
|
|
|
navItems = this._orderByDisplayedContainers( navItems );
|
|
|
|
return navItems;
|
|
},
|
|
|
|
setNavigatorType: function() {
|
|
this.set( 'navigatorType', FusionApp.data.fusion_element_type );
|
|
},
|
|
|
|
setNewNestedRowsToCollapsible( navigatorItems ) {
|
|
var i, j, k, l,
|
|
item,
|
|
collapsedItems = this.get( 'collapsedItems' );
|
|
|
|
if ( ! Array.isArray( navigatorItems ) ) {
|
|
return;
|
|
}
|
|
|
|
for ( i = 0; i < navigatorItems.length; i++ ) { // containers
|
|
for ( j = 0; j < navigatorItems[ i ].children.length; j++ ) { // rows
|
|
for ( k = 0; k < navigatorItems[ i ].children[ j ].children.length; k++ ) { // columns
|
|
for ( l = 0; l < navigatorItems[ i ].children[ j ].children[ k ].children.length; l++ ) { // elements or nested rows.
|
|
item = navigatorItems[ i ].children[ j ].children[ k ].children[ l ];
|
|
|
|
// eslint-disable-next-line max-depth
|
|
if (
|
|
'fusion_builder_row_inner' === item.type &&
|
|
'undefined' === typeof this.verifiedNestedRowsForCollapse[ item.view.cid ]
|
|
) {
|
|
this.verifiedNestedRowsForCollapse[ item.view.cid ] = true;
|
|
collapsedItems[ item.view.cid ] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.set( 'collapsedItems', collapsedItems );
|
|
},
|
|
|
|
|
|
/**
|
|
* When a nested row is canceled from editing, the view cid changes,
|
|
* so that the collapsible refreshes to default state of collapsed.
|
|
* */
|
|
restoreNestedRowCollapsible( data ) {
|
|
var oldStatus,
|
|
collapsedItems = this.get( 'collapsedItems' );
|
|
|
|
if ( 'object' !== typeof data.oldView || ! data.oldView.cid || 'object' !== typeof data.newView || ! data.newView.cid ) {
|
|
return;
|
|
}
|
|
|
|
oldStatus = collapsedItems[ data.oldView.cid ] ? collapsedItems[ data.oldView.cid ] : false;
|
|
|
|
if ( ! oldStatus ) {
|
|
this.verifiedNestedRowsForCollapse[ data.newView.cid ] = true;
|
|
} else {
|
|
this.verifiedNestedRowsForCollapse[ data.newView.cid ] = true;
|
|
collapsedItems[ data.newView.cid ] = true;
|
|
}
|
|
|
|
this.set( 'collapsedItems', collapsedItems );
|
|
},
|
|
|
|
_updateModelsToViewsMap: function( elementViews ) {
|
|
var index;
|
|
|
|
this.modelsToViewsMap = [];
|
|
this.viewsCidToViewsMap = [];
|
|
|
|
for ( index in elementViews ) {
|
|
if ( 'object' !== typeof elementViews[ index ] ) {
|
|
continue; // eslint-disable-line no-continue
|
|
}
|
|
|
|
this.modelsToViewsMap[ elementViews[ index ].model.cid ] = elementViews[ index ];
|
|
this.viewsCidToViewsMap[ elementViews[ index ].cid ] = elementViews[ index ];
|
|
}
|
|
},
|
|
|
|
_getNavItemObject: function( view ) {
|
|
return {
|
|
view: view,
|
|
model: view.model,
|
|
name: this._getElementDisplayName( view ),
|
|
type: view.model.get( 'element_type' ),
|
|
|
|
// An array with items of the same type as this.
|
|
children: this._getNavigationChildrenItems( view )
|
|
};
|
|
},
|
|
|
|
_getNavigationChildrenItems: function( view ) {
|
|
var model,
|
|
children = [],
|
|
childView,
|
|
i;
|
|
|
|
if ( ! view.model || ! view.model.children || ! view.model.children.length ) {
|
|
return children;
|
|
}
|
|
|
|
for ( i = 0; i < view.model.children.length; i++ ) {
|
|
model = view.model.children.models[ i ];
|
|
|
|
if ( 'object' === typeof this.modelsToViewsMap[ model.cid ] && 'multi_element_child' !== model.get( 'multi' ) ) {
|
|
childView = this.modelsToViewsMap[ model.cid ];
|
|
children.push( this._getNavItemObject( childView ) );
|
|
}
|
|
}
|
|
|
|
return children;
|
|
},
|
|
|
|
_orderByDisplayedContainers: function( navItems ) {
|
|
var previewIframe = jQuery( '#fb-preview' ),
|
|
containers,
|
|
orderedItems = [],
|
|
j,
|
|
index;
|
|
|
|
if ( ! previewIframe.length ) {
|
|
return navItems;
|
|
}
|
|
|
|
containers = previewIframe[ 0 ].contentWindow.jQuery( '#fusion_builder_container > .fusion-builder-container, #fusion_builder_container > .fusion-builder-next-page, #fusion_builder_container > .fusion-checkout-form, #fusion_builder_container > .fusion-builder-form-step' );
|
|
|
|
for ( index = 0; index < containers.length; index++ ) {
|
|
for ( j = 0; j < navItems.length; j++ ) {
|
|
if ( navItems[ j ].view.$el.is( containers.eq( index ) ) ) {
|
|
orderedItems.push( navItems[ j ] );
|
|
}
|
|
}
|
|
}
|
|
|
|
return orderedItems;
|
|
},
|
|
|
|
_getElementDisplayName: function( view ) {
|
|
var elType = view.model.get( 'element_type' ),
|
|
params;
|
|
|
|
// If element is container, the use the admin label.
|
|
if ( 'fusion_builder_container' === elType ) {
|
|
params = view.model.get( 'params' );
|
|
if ( params.admin_label ) {
|
|
return params.admin_label;
|
|
}
|
|
}
|
|
|
|
// Return the element name.
|
|
if ( fusionAllElements[ elType ] && fusionAllElements[ elType ].name ) {
|
|
return fusionAllElements[ elType ].name;
|
|
}
|
|
|
|
return elType;
|
|
}
|
|
|
|
} );
|
|
}( jQuery ) );
|