/* global FusionPageBuilderApp, FusionPageBuilder, FusionPageBuilderElements */ /* eslint no-unused-vars: 0 */ ( function() { // Insert shortcode into post editor window.fusionBuilderInsertIntoEditor = function( shortcode, editorID ) { // jshint ignore:line var editorArea, editor; if ( 'tinymce' === window.SCmoduleContentEditorMode && ( '' === editorID || 'undefined' === typeof editorID ) ) { if ( 'undefined' !== typeof window.tinyMCE ) { // Set active editor editor = FusionPageBuilderApp.shortcodeGeneratorActiveEditor; editor.focus(); if ( 'excerpt' === editor.id ) { FusionPageBuilderApp.fromExcerpt = true; } // Insert shortcode window.tinyMCE.activeEditor.execCommand( 'mceInsertContent', false, shortcode ); window.tinyMCE.activeEditor.execCommand( 'mceCleanup', false ); } } else { if ( null === editorID || '' === editorID || 'undefined' === typeof editorID ) { editorArea = jQuery( window.editorArea ); } else { editorArea = jQuery( '#' + editorID ); } if ( 'excerpt' === editorArea.attr( 'id' ) ) { FusionPageBuilderApp.fromExcerpt = true; } if ( 'undefined' === typeof window.cursorPosition ) { if ( 0 === editorArea.getCursorPosition() ) { editorArea.val( shortcode + editorArea.val() ); } else if ( editorArea.val().length === editorArea.getCursorPosition() ) { editorArea.val( editorArea.val() + shortcode ); } else { editorArea.val( editorArea.val().slice( 0, editorArea.getCursorPosition() ) + shortcode + editorArea.val().slice( editorArea.getCursorPosition() ) ); } } else { editorArea.val( [ editorArea.val().slice( 0, window.cursorPosition ), shortcode, editorArea.val().slice( window.cursorPosition ) ].join( '' ) ); } editorArea.trigger( 'change' ); } if ( false === FusionPageBuilderApp.manuallyAdded ) { FusionPageBuilderApp.shortcodeGeneratorActiveEditor = ''; } }; }( jQuery ) ); function openShortcodeGenerator( trigger ) { // jshint ignore:line // Get editor id from event.trigger. parent.parent var view, viewSettings, editorArea, editorCid; if ( 'object' === typeof trigger && 'undefined' !== typeof trigger[ 0 ].$el ) { trigger = trigger[ 0 ].$el; } editorArea = '#' + trigger.parent().parent().find( '.wp-editor-area' ).attr( 'id' ); editorCid = trigger.closest( '.fusion-builder-module-settings' ).attr( 'data-element-cid' ); window.cursorPosition = 0; window.editorArea = editorArea; // Set shortcode generator flag FusionPageBuilderApp.shortcodeGenerator = true; // Get active editor mode if ( FusionPageBuilderApp.isTinyMceActive() ) { window.SCmoduleContentEditorMode = 'tinymce'; } else { window.SCmoduleContentEditorMode = 'html'; } // Get current cursor position ( for html editor ) if ( 'tinymce' !== window.SCmoduleContentEditorMode ) { window.cursorPosition = jQuery( editorArea ).getCursorPosition(); } viewSettings = { collection: FusionPageBuilderElements, view: this, targetCid: editorCid }, view = new FusionPageBuilder.GeneratorElementsView( viewSettings ); jQuery( view.render().el ).dialog( { title: 'Select Element', draggable: false, modal: true, resizable: false, dialogClass: 'fusion-builder-dialog fusion-builder-large-library-dialog fusion-builder-element-library-dialog', open: function( event, ui ) { // jshint ignore: line window.FusionApp.dialog.resizeDialog(); }, close: function( event, ui ) { // jshint ignore: line view.removeView(); } } ); } // Helper function to check the cursor position of text editor content field before the shortcode generator is opened ( function() { jQuery.fn.getCursorPosition = function() { var el = jQuery( this ).get( 0 ), pos = 0, Sel, SelLength; if ( 'selectionStart' in el ) { pos = el.selectionStart; } else if ( 'selection' in document ) { el.focus(); Sel = document.selection.createRange(); SelLength = document.selection.createRange().text.length; Sel.moveStart( 'character', -el.value.length ); pos = Sel.text.length - SelLength; } return pos; }; }( jQuery ) ); ;/* global FusionPageBuilderApp, FusionApp, fusionBuilderText, FusionEvents */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { // Builder Builder History FusionPageBuilder.BuilderHistory = window.wp.Backbone.View.extend( { template: FusionPageBuilder.template( jQuery( '#fusion-builder-front-end-history' ).html() ), className: 'fusion-builder-history-list submenu-trigger-target', tagName: 'ul', /** * Init. * * @since 2.0.0 * @param {Object} data - The data. * @return {void} */ initialize: function() { var data = FusionApp.data; this.fusionCommands = new Array( '[]' ); this.fusionCommandsStates = new Array( '[]' ); // History states this.maxSteps = 25; // Maximum steps allowed/saved this.currStep = 1; // Current Index of step this.allElements = data.postDetails.post_content; this.fusionHistoryState = ''; this.tracking = 'on'; this.trackingPaused = 'off'; this.unsavedStep = 1; // Unsaved steps. // Set initial history step this.fusionCommands[ this.currStep ] = { allElements: data.postDetails.post_content }; this.fusionCommandsStates[ this.currStep ] = fusionBuilderText.empty; this.listenTo( FusionEvents, 'fusion-history-pause-tracking', this.pauseTracking ); this.listenTo( FusionEvents, 'fusion-history-resume-tracking', this.resumeTracking ); this.listenTo( FusionEvents, 'fusion-history-save-step', this.saveHistoryStep ); this.listenTo( FusionEvents, 'fusion-history-turn-on-tracking', this.turnOnTracking ); this.listenTo( FusionEvents, 'fusion-history-turn-off-tracking', this.turnOffTracking ); this.listenTo( FusionEvents, 'fusion-history-go-to-step', this.historyStep ); this.listenTo( FusionEvents, 'fusion-history-clear', this.clearEditor ); this.listenTo( FusionEvents, 'fusion-history-capture-editor', this.captureEditor ); this.listenTo( FusionEvents, 'fusion-history-undo', this.doUndo ); this.listenTo( FusionEvents, 'fusion-history-redo', this.doRedo ); this.listenTo( FusionEvents, 'fusion-builder-reset', this.resetStates ); this.listenTo( FusionEvents, 'fusion-element-removed', this.resetStates ); }, resetStates: function( cid ) { var self = this; if ( 'object' === typeof this.fusionCommands ) { _.each( this.fusionCommands, function( state, index ) { if ( 'undefined' === typeof cid || ! cid || ( 'param' === state.type && 'undefined' !== typeof state.cid && cid === state.cid ) ) { self.fusionCommands[ index ] = { allElements: state.allElements }; } } ); } }, /** * Renders the view. * * @since 2.0.0 * @return {Object} this */ render: function() { var self = this; this.$el.html( this.template( { steps: this.fusionCommandsStates, currentStep: this.currStep } ) ); this.$el.attr( 'aria-expanded', false ); this.$el.find( 'li' ).on( 'click', function( event ) { if ( event ) { event.preventDefault(); } self.historyStep( event ); } ); this.updateUI(); return this; }, /** * Saves a step in the history. * * @since 2.0.0 * @param {string} text - The text to be displayed in the history log. * @return {void} */ saveHistoryStep: function( text, state ) { this.fusionHistoryState = text; this.turnOnTracking(); this.captureEditor( state ); this.turnOffTracking(); }, /** * Captures the editor (used in front-end.js) * * @since 2.0.0 * @return {void} */ captureEditor: function( state ) { if ( 'object' !== typeof state ) { state = {}; } if ( 'undefined' === typeof FusionPageBuilderApp ) { return; } FusionPageBuilderApp.builderToShortcodes(); if ( this.isTrackingOn() && ! this.isTrackingPaused() ) { // If reached limit if ( this.currStep == this.maxSteps ) { // Remove first index this.fusionCommands.shift(); this.fusionCommandsStates.shift(); } else { // Else increment index this.currStep += 1; this.unsavedStep += 1; } // If we are not at the end of the states, we need to wipe those ahead. if ( this.currStep !== this.fusionCommands.length ) { this.fusionCommandsStates.length = this.currStep; this.fusionCommands.length = this.currStep; } // Get content this.allElements = FusionApp.data.postDetails.post_content; // Add all elements as fallback method. state.allElements = this.allElements; // Add editor data to Array this.fusionCommands[ this.currStep ] = state; // Add history state this.fusionCommandsStates[ this.currStep ] = this.fusionHistoryState; FusionApp.contentChange( 'page', 'builder-content' ); // Update buttons this.fusionHistoryState = ''; this.render(); } }, /** * Turn history tracking ON. * * @since 2.0.0 * @return {void} */ turnOnTracking: function() { this.tracking = 'on'; }, /** * Turn history tracking OFF. * * @since 2.0.0 * @return {void} */ turnOffTracking: function() { this.tracking = 'off'; }, /** * Turn history tracking ON. * * @since 2.0.0 * @return {void} */ pauseTracking: function() { this.trackingPaused = 'on'; }, /** * Turn history tracking OFF. * * @since 2.0.0 * @return {void} */ resumeTracking: function() { this.trackingPaused = 'off'; }, canApplyStep: function( historyStep ) { if ( 'object' !== typeof historyStep || 'undefined' === typeof historyStep.type ) { return false; } if ( 'param' === historyStep.type || 'price-param' === historyStep.type || 'pricefooter-param' === historyStep.type || 'pricefeatures-param' === historyStep.type ) { return true; } return false; }, canApplySteps: function( stepIndex ) { var self = this, redo = stepIndex < this.currStep ? false : true, steps = [], canApply = true; if ( ! redo ) { steps = this.fusionCommands.slice( stepIndex + 1, this.currStep + 1 ); } else { steps = this.fusionCommands.slice( this.currStep + 1, stepIndex + 1 ); } _.each( steps, function( step ) { if ( ! self.canApplyStep( step ) ) { canApply = false; } } ); return canApply; }, applySteps: function( stepIndex ) { var self = this, redo = stepIndex < this.currStep ? false : true, steps = []; if ( ! redo ) { steps = this.fusionCommands.slice( stepIndex + 1, this.currStep + 1 ).reverse(); } else { steps = this.fusionCommands.slice( this.currStep + 1, stepIndex + 1 ); } _.each( steps, function( step ) { self.applyStep( step, redo ); } ); }, applyStep: function( historyStep, redo ) { var elementView, params, // eslint-disable-line no-unused-vars columnView; redo = 'undefined' === typeof redo ? false : redo; switch ( historyStep.type ) { case 'param': elementView = window.FusionPageBuilderViewManager.getView( historyStep.cid ); if ( elementView ) { params = elementView.model.get( 'params' ); // eslint-disable-line no-unused-vars // If undo, set new value to step so redo can use it. if ( ! redo ) { elementView.historyUpdateParam( historyStep.param, historyStep.oldValue ); FusionEvents.trigger( 'fusion-param-changed', historyStep.param, historyStep.oldValue ); FusionEvents.trigger( 'fusion-param-changed-' + historyStep.cid, historyStep.param, historyStep.oldValue ); } else { elementView.historyUpdateParam( historyStep.param, historyStep.newValue ); FusionEvents.trigger( 'fusion-param-changed', historyStep.param, historyStep.newValue ); FusionEvents.trigger( 'fusion-param-changed-' + historyStep.cid, historyStep.param, historyStep.newValue ); } } break; case 'price-param': elementView = window.FusionPageBuilderViewManager.getView( historyStep.cid ); if ( elementView ) { // If undo, set new value to step so redo can use it. if ( ! redo ) { elementView.updatePricingTablePrice( historyStep.param, historyStep.oldValue ); FusionEvents.trigger( 'fusion-param-changed', historyStep.param, historyStep.oldValue ); FusionEvents.trigger( 'fusion-param-changed-' + historyStep.cid, historyStep.param, historyStep.oldValue ); } else { elementView.updatePricingTablePrice( historyStep.param, historyStep.newValue ); FusionEvents.trigger( 'fusion-param-changed', historyStep.param, historyStep.newValue ); FusionEvents.trigger( 'fusion-param-changed-' + historyStep.cid, historyStep.param, historyStep.newValue ); } } break; case 'pricefooter-param': elementView = window.FusionPageBuilderViewManager.getView( historyStep.cid ); if ( elementView ) { // If undo, set new value to step so redo can use it. if ( ! redo ) { elementView.updatePricingTableFooter( historyStep.oldValue ); FusionEvents.trigger( 'fusion-param-changed', 'footer_content', historyStep.oldValue ); FusionEvents.trigger( 'fusion-param-changed-' + historyStep.cid, 'footer_content', historyStep.oldValue ); } else { elementView.updatePricingTableFooter( historyStep.newValue ); FusionEvents.trigger( 'fusion-param-changed', 'footer_content', historyStep.newValue ); FusionEvents.trigger( 'fusion-param-changed-' + historyStep.cid, 'footer_content', historyStep.newValue ); } } break; case 'pricefeatures-param': elementView = window.FusionPageBuilderViewManager.getView( historyStep.cid ); if ( elementView ) { // If undo, set new value to step so redo can use it. if ( ! redo ) { elementView.updatePricingTableFeatures( historyStep.oldValue ); FusionEvents.trigger( 'fusion-param-changed', 'footer_content', historyStep.oldValue ); FusionEvents.trigger( 'fusion-param-changed-' + historyStep.cid, 'feature_rows', historyStep.oldValue ); } else { elementView.updatePricingTableFeatures( historyStep.newValue ); FusionEvents.trigger( 'fusion-param-changed', 'footer_content', historyStep.newValue ); FusionEvents.trigger( 'fusion-param-changed-' + historyStep.cid, 'feature_rows', historyStep.newValue ); } } break; case 'add-element': if ( redo ) { FusionPageBuilderApp.collection.add( historyStep.model ); } else { elementView = window.FusionPageBuilderViewManager.getView( historyStep.model.cid ); if ( elementView ) { elementView.removeElement(); } } break; case 'remove-element': if ( redo ) { elementView = window.FusionPageBuilderViewManager.getView( historyStep.model.cid ); if ( elementView ) { elementView.removeElement(); } } else { FusionPageBuilderApp.collection.add( historyStep.model ); } break; case 'move-element': elementView = window.FusionPageBuilderViewManager.getView( historyStep.cid ); // Need to ignore itself. elementView.$el.addClass( 'ignore-me' ); if ( redo ) { columnView = window.FusionPageBuilderViewManager.getView( historyStep.newParent ); if ( elementView && columnView ) { columnView.$el.find( '.fusion-builder-column-content' ).first().find( '> span, > div' ).not( '.ignore-me' ).eq( ( historyStep.newIndex - 1 ) ).after( elementView.$el ); FusionPageBuilderApp.onDropCollectionUpdate( elementView.model, historyStep.newIndex, historyStep.newParent ); } } else { columnView = window.FusionPageBuilderViewManager.getView( historyStep.oldParent ); if ( elementView && columnView ) { columnView.$el.find( '.fusion-builder-column-content' ).first().find( '> span, > div' ).not( '.ignore-me' ).eq( ( historyStep.oldIndex - 1 ) ).after( elementView.$el ); FusionPageBuilderApp.onDropCollectionUpdate( elementView.model, historyStep.oldIndex, historyStep.oldParent ); } } elementView.$el.removeClass( 'ignore-me' ); break; } }, updateActiveStyling: function() { FusionApp.builderToolbarView.$el.find( '.fusion-builder-history-list li' ).removeClass( 'fusion-history-active-state' ); FusionApp.builderToolbarView.$el.find( '.fusion-builder-history-list' ).find( '[data-state-id="' + this.currStep + '"]' ).addClass( 'fusion-history-active-state' ); }, fullContentReplace: function( data ) { this.resetStates(); FusionPageBuilderApp.clearBuilderLayout(); FusionPageBuilderApp.$el.find( '.fusion_builder_container' ).remove(); // Try to make the shortcode if the content does not contain them. if ( ! FusionApp.data.is_fusion_element || 'mega_menus' === FusionApp.data.fusion_element_type ) { data = FusionPageBuilderApp.validateContent( data ); } // Reset models with new elements FusionPageBuilderApp.createBuilderLayout( data ); }, /** * Undo last step in history. * Saves the undone step so that we may redo later if needed. * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ doUndo: function( event ) { var undoData, historyStep = {}; if ( event ) { event.preventDefault(); } // Turn off tracking first, so these actions are not captured if ( this.hasUndo() ) { // If no data or end of stack and nothing to undo // Close opened nested cols to make sure UI works after history change. this.closeNestedCols(); this.turnOffTracking(); // Data to undo historyStep = this.fusionCommands[ this.currStep ]; if ( this.canApplyStep( historyStep ) ) { this.applyStep( historyStep, false ); this.currStep -= 1; } else { this.currStep -= 1; historyStep = this.fusionCommands[ this.currStep ]; undoData = 'object' === typeof historyStep ? historyStep.allElements : false; if ( undoData && '[]' !== undoData ) { this.fullContentReplace( undoData ); } } this.updateActiveStyling(); } }, /** * Redo last step. * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ doRedo: function( event ) { var redoData; if ( event ) { event.preventDefault(); } if ( this.hasRedo() ) { // If not at end and nothing to redo // Close opened nested cols to make sure UI works after history change. this.closeNestedCols(); // Turn off tracking, so these actions are not tracked this.turnOffTracking(); // Move index this.currStep += 1; window.historyStep = this.fusionCommands[ this.currStep ]; redoData = 'object' === typeof window.historyStep ? window.historyStep.allElements : false; if ( this.canApplyStep( window.historyStep ) ) { this.applyStep( window.historyStep, true ); } else if ( redoData && '[]' !== redoData ) { this.fullContentReplace( redoData ); } this.updateActiveStyling(); } }, /** * Go to a step. * * @since 2.0.0 * @param {string|number} step - The step. * @param {Object} event - The event. * @return {void} */ historyStep: function( event ) { var step, stepData; if ( event ) { event.preventDefault(); } // Close opened nested cols to make sure UI works after history change. this.closeNestedCols(); step = jQuery( event.currentTarget ).data( 'state-id' ); // Turn off tracking, so these actions are not tracked this.turnOffTracking(); if ( this.canApplySteps( step ) ) { this.applySteps( step ); this.currStep = step; } else { this.currStep = step; stepData = 'object' === typeof this.fusionCommands[ this.currStep ] ? this.fusionCommands[ this.currStep ].allElements : false; if ( stepData && '[]' !== stepData ) { this.fullContentReplace( stepData ); } } this.updateActiveStyling(); }, /** * Are we currently tracking history? * * @since 2.0.0 * @return {boolean} */ isTrackingOn: function() { return 'on' === this.tracking; }, /** * Is tracking paused currently? * * @since 2.0.0 * @return {boolean} */ isTrackingPaused: function() { return 'on' === this.trackingPaused; }, /** * Log commands in the console as JSON. * * @since 2.0.0 * @return {void} */ logStacks: function() { console.log( JSON.parse( this.fusionCommands ) ); }, /** * Clear the editor. * * @since 2.0.0 * @return {void} */ clearEditor: function() { this.fusionCommands = new Array( '[]' ); this.fusionCommandsStates = new Array( '[]' ); this.currStep = 1; this.unsavedStep = 1; this.fusionHistoryState = ''; this.fusionCommands[ this.currStep ] = { allElements: FusionApp.data.postDetails.post_content }; this.fusionCommandsStates[ this.currStep ] = fusionBuilderText.empty; this.render(); }, /** * Do we have an undo? Checks if the current step is the 1st one. * * @since 2.0.0 * @return {boolean} */ hasUndo: function() { return 1 !== this.currStep; }, /** * Do we have a redo? Checks if a step greater than current one exists. * * @since 2.0.0 * @return {boolean} */ hasRedo: function() { return this.currStep < ( this.fusionCommands.length - 1 ); }, /** * Get the array of steps/fusionCommands. * * @since 2.0.0 * @return {Array} */ getCommands: function() { return this.fusionCommands; }, /** * Update the undo/redo/history buttons. * * @since 2.0.0 * @return {void} */ updateUI: function() { if ( 1 < this.unsavedStep ) { FusionApp.builderToolbarView.$el.find( '#fusion-builder-toolbar-history-menu' ).attr( 'data-has-unsaved', true ); } else { FusionApp.builderToolbarView.$el.find( '#fusion-builder-toolbar-history-menu' ).attr( 'data-has-unsaved', false ); } this.updateActiveStyling(); }, /** * Close nested cols. * * @since 2.2 * @return {void} */ closeNestedCols: function() { var activeNestedCols = FusionPageBuilderApp.$el.find( '.fusion-nested-columns.editing' ); if ( activeNestedCols.length ) { activeNestedCols.find( '.fusion-builder-cancel-row' ).trigger( 'click' ); } } } ); }( jQuery ) ); ;/* global FusionPageBuilderApp, fusionAppConfig, FusionApp, FusionEvents, fusionBuilderText */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { // Builder Toolbar FusionPageBuilder.BuilderToolbar = window.wp.Backbone.View.extend( { template: FusionPageBuilder.template( jQuery( '#fusion-builder-front-end-toolbar' ).html() ), className: 'fusion-toolbar-nav fb', tagName: 'ul', events: { 'click .fusion-builder-clear-layout': 'clearLayout', 'click .fusion-builder-open-library': 'openLibrary', 'click .fusion-builder-save-template': 'openLibrary', 'click #fusion-builder-toolbar-new-post .add-new': 'newPost', 'click .fusion-builder-preferences': 'openPreferences', 'click #fusion-builder-toolbar-history-menu': 'preventDefault', 'click .fusion-preview-only-link': 'generatePreview' }, initialize: function() { this.builderHistory = new FusionPageBuilder.BuilderHistory(); this.listenTo( FusionEvents, 'fusion-post_title-changed', this.updatePreviewTitle ); }, /** * Renders the view. * * @since 2.0.0 * @return {Object} this */ render: function() { this.$el.html( this.template() ); this.$el.find( '.fusion-builder-history-container' ).append( this.builderHistory.render().el ); this.delegateEvents(); return this; }, /** * Make sure all the unsaved content is set like on frame refresh, then open page. * * @since 2.0.0 * @param {Object} event - The JS event. * @return {Object} this */ generatePreview: function( event ) { var $element = jQuery( event.currentTarget ); if ( 'undefined' !== typeof event ) { event.preventDefault(); event.stopPropagation(); } if ( $element.attr( 'data-disabled' ) ) { return; } $element.attr( 'data-disabled', true ); // Avada Builder if ( 'undefined' !== typeof FusionPageBuilderApp ) { FusionPageBuilderApp.builderToShortcodes(); } // Fusion Panel if ( this.sidebarView ) { this.setGoogleFonts(); } FusionApp.formPost( FusionApp.getAjaxData( 'fusion_app_preview_only' ), false, '_blank' ); $element.removeAttr( 'data-disabled' ); }, /** * Opens the library. * Calls the LibraryView and then renders it. * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ openLibrary: function( event ) { var view, libraryModel = { target: jQuery( event.currentTarget ).data( 'target' ), focus: jQuery( event.currentTarget ).data( 'focus' ) }, viewSettings = { model: libraryModel }; if ( 'undefined' !== typeof event ) { event.preventDefault(); event.stopPropagation(); } if ( jQuery( '.fusion-builder-dialog' ).length && jQuery( '.fusion-builder-dialog' ).is( ':visible' ) ) { FusionApp.multipleDialogsNotice(); return; } view = new FusionPageBuilder.LibraryView( viewSettings ); view.render(); }, /** * Clears the layout. * Calls FusionPageBuilderApp.clearLayout * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ clearLayout: function( event ) { if ( event ) { event.preventDefault(); } FusionApp.confirmationPopup( { title: fusionBuilderText.are_you_sure, content: fusionBuilderText.are_you_sure_you_want_to_delete_this_layout, actions: [ { label: fusionBuilderText.cancel, classes: 'cancel', callback: function() { FusionApp.confirmationPopup( { action: 'hide' } ); } }, { label: fusionBuilderText.remove, classes: 'delete-layout', callback: function() { // Close dialogs. if ( jQuery( '.ui-dialog-content' ).length ) { jQuery( '.ui-dialog-content' ).dialog( 'close' ); } FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.layout_cleared ); FusionPageBuilderApp.clearLayout( event ); FusionApp.confirmationPopup( { action: 'hide' } ); } } ] } ); }, /** * Create a new draft of specific post type. * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ newPost: function( event ) { var postType = jQuery( event.currentTarget ).data( 'post-type' ); if ( event ) { event.preventDefault(); } jQuery.ajax( { type: 'POST', url: fusionAppConfig.ajaxurl, dataType: 'JSON', data: { action: 'fusion_create_post', fusion_load_nonce: fusionAppConfig.fusion_load_nonce, post_type: postType } } ) .done( function( response ) { FusionApp.checkLink( event, response.permalink ); } ); }, /** * Renders the FusionPageBuilder.PreferencesView view. * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ openPreferences: function( event ) { var view; if ( 'undefined' !== typeof event ) { event.preventDefault(); event.stopPropagation(); } if ( jQuery( '.fusion-builder-dialog' ).length && jQuery( '.fusion-builder-dialog' ).is( ':visible' ) ) { FusionApp.multipleDialogsNotice(); return; } view = new FusionPageBuilder.PreferencesView(); view.render(); }, /** * Prevents default action. * * @param {Object} event - The event. * @return {void} */ preventDefault: function( event ) { event.preventDefault(); }, /** * Updates the text for the title of the page. * * @return {void} */ updatePreviewTitle: function() { this.$el.find( '.fusion-preview-only-link strong' ).html( FusionApp.getPost( 'post_title' ) ); } } ); }( jQuery ) ); ;var FusionPageBuilder = FusionPageBuilder || {}; ( function() { // Builder element model FusionPageBuilder.Element = Backbone.Model.extend( { defaults: { type: 'element' } } ); }( jQuery ) ); ;var FusionPageBuilder = FusionPageBuilder || {}; ( function() { FusionPageBuilder.ExtraShortcodes = Backbone.Model.extend( { defaults: { elementCount: 0, shortcodes: {} }, addData: function( content ) { var self = this, shortcodes = self.get( 'shortcodes' ), elementCount = self.get( 'elementCount' ); _.each( content, function( shortcode ) { shortcode.id = elementCount; shortcode.matcher = self.convert( shortcode.shortcode ); shortcodes[ elementCount ] = shortcode; elementCount++; } ); this.set( { elementCount: elementCount } ); this.set( { shortcodes: shortcodes } ); }, addShortcode: function( shortcode, output, tag ) { var self = this, shortcodes = self.get( 'shortcodes' ), elementCount = self.get( 'elementCount' ), originalCount = self.get( 'elementCount' ); shortcodes[ elementCount ] = { shortcode: shortcode, output: output, matcher: self.convert( shortcode ), id: elementCount, tag: tag }; elementCount++; this.set( { elementCount: elementCount } ); this.set( { shortcodes: shortcodes } ); return originalCount; }, byId: function( id ) { var shortcodes = this.get( 'shortcodes' ); return shortcodes[ id ]; }, byShortcode: function( content ) { var shortcodes = this.get( 'shortcodes' ), $matches = _.findWhere( shortcodes, { shortcode: content } ); if ( 'undefined' === typeof $matches ) { content = this.convert( content ); $matches = _.findWhere( shortcodes, { matcher: content } ); } return $matches; }, byOutput: function( content ) { var shortcodes = this.get( 'shortcodes' ); return _.findWhere( shortcodes, { ouput: content } ); }, getAll: function() { return this.get( 'shortcodes' ); }, convert: function( content ) { // Clean up any parts which can be ignored for sake of matching. content = content.replace( / /g, '' ); content = content.replace( /\r?\n|\r/g, '' ); content = content.replace( /(]+?>|

|<\/p>)/g, '' ); content = content.replace( /(]+?>|
|<\/br>)/g, '' ); content = content.replace( /\[fusion_text\]\[\/fusion_text\]/g, '' ); return content.trim(); } } ); }( jQuery ) ); ;/* global FusionEvents, FusionApp, fusionBuilderText */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { FusionPageBuilder.DynamicValues = Backbone.Model.extend( { defaults: { values: {}, options: {}, orderedParams: false }, getOrderedParams: function() { var params = this.get( 'orderedParams' ), options = this.getOptions(); if ( ! params ) { params = {}; _.each( options, function( object, id ) { var group, groupText; if ( 'object' !== typeof object ) { return; } group = object.group; groupText = group; if ( 'string' !== typeof object.group ) { group = 'other'; groupText = fusionBuilderText.other; } group = group.replace( /\s+/g, '_' ).toLowerCase(); if ( 'object' !== typeof params[ group ] ) { params[ group ] = { label: '', params: {} }; } params[ group ].label = groupText; params[ group ].params[ id ] = object; } ); } return params; }, addData: function( data, options ) { this.set( 'values', data ); this.set( 'options', options ); }, getOptions: function() { var options = this.get( 'options' ); return jQuery.extend( true, {}, options ); }, getOption: function( param ) { var options = this.getOptions(); return 'undefined' !== typeof options[ param ] ? options[ param ] : false; }, getAll: function() { var values = this.get( 'values' ); return jQuery.extend( true, {}, values ); }, getValue: function( args ) { var values = this.getAll(), id = args.data, postId = FusionApp.getDynamicPost( 'post_id' ), idValues = false, match = false; if ( 'undefined' !== typeof values[ postId ] ) { idValues = 'object' === typeof values[ postId ][ id ] ? values[ postId ][ id ] : false; } // No initial match, fetch it. if ( ! idValues ) { return this.fetchValue( id, args ); } // Check each value object with same ID. match = this.findMatch( idValues, args ); // We found a matching object, then return its value. if ( match ) { return match.value; } // No match, fetch. return this.fetchValue( id, args ); }, findMatch: function( idValues, args, idWanted ) { var match = false; idWanted = 'undefined' === typeof idWanted ? false : idWanted; _.each( idValues, function( idValue, idCount ) { var argsMatch = true; // Already found a match, just return early. if ( match ) { return true; } // Value object has no args, then set match and return. if ( 'undefined' === typeof idValue.args ) { match = idWanted ? idCount : idValue; return true; } // We do have args, check that each value matches. if ( 'object' === typeof idValue.args ) { _.each( idValue.args, function( argValue, argId ) { if ( 'undefined' === typeof args[ argId ] || 'before' === argId || 'after' === argId || 'fallback' === argId ) { return true; } if ( args[ argId ] !== argValue ) { argsMatch = false; } } ); if ( argsMatch ) { match = idWanted ? idCount : idValue; } } } ); return match; }, fetchValue: function( id, args ) { var options = this.getOptions(), param = 'object' === typeof options && 'object' === typeof options[ id ] ? options[ id ] : false, callback = param && 'undefined' !== typeof param.callback ? param.callback : false, callbackFunction = callback && 'string' === typeof callback[ 'function' ] ? callback[ 'function' ] : false, callbackExists = callbackFunction && 'function' === typeof FusionApp.callback[ callbackFunction ] ? true : false, callbackAjax = callbackExists && 'undefined' !== typeof callback.ajax ? callback.ajax : false, dynamicPost, value; // If no callback found, use default ajax one. if ( ! callbackExists ) { callbackFunction = 'defaultDynamicCallback'; callbackAjax = true; } if ( ! param ) { this.setValue( args, false ); return false; } // Return default (dummy) value if template post is set as target post. dynamicPost = 'fusion_tb_section' === FusionApp.data.postDetails.post_type || 'post_cards' === FusionApp.data.template_category; if ( true === FusionApp.data.is_singular && dynamicPost && -99 === FusionApp.getDynamicPost( 'post_id' ) && 'undefined' !== typeof param[ 'default' ] ) { return param[ 'default' ]; } // If ajax callback should be run when template is edited. if ( true === FusionApp.data.is_singular && dynamicPost && 'undefined' !== typeof param.ajax_on_template && true === param.ajax_on_template ) { return FusionApp.callback.defaultDynamicCallback( args ); } if ( callbackAjax ) { return FusionApp.callback[ callbackFunction ]( args ); } value = FusionApp.callback[ callbackFunction ]( args ); this.setValue( args, value ); return value; }, setValue: function( args, value ) { var values = this.getAll(), id = args.data, postId = FusionApp.getDynamicPost( 'post_id' ), existing = {}, matchId = false, newData = { args: jQuery.extend( true, {}, args ), value: value }; if ( 'object' !== typeof values[ postId ] ) { values[ postId ] = []; } existing = jQuery.extend( true, {}, values[ postId ][ id ] ); if ( 'object' !== typeof values[ postId ][ id ] ) { values[ postId ][ id ] = []; } else if ( 'function' !== typeof values[ postId ][ id ].push ) { values[ postId ][ id ] = [ existing[ 0 ] ]; } matchId = this.findMatch( values[ postId ][ id ], args, true ); if ( ! matchId ) { values[ postId ][ id ].push( newData ); } else { values[ postId ][ id ][ matchId ] = newData; } this.set( 'values', values ); // ReRender the element. Perhaps via event using id. FusionEvents.trigger( 'fusion-dynamic-data-value', id ); }, removeValue: function( id ) { var values = this.getAll(), postId = FusionApp.getDynamicPost( 'post_id' ); if ( 'object' === typeof values[ postId ][ id ] ) { delete values[ postId ][ id ]; } this.set( 'values', values ); } } ); }( jQuery ) ); ;/* global FusionEvents, FusionPageBuilderApp, fusionAllElements, fusionBuilderText */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { FusionPageBuilder.DynamicParams = Backbone.Model.extend( { defaults: { params: {}, elementView: false, listeners: [] }, initialize: function() { this._historyPush = _.debounce( _.bind( this.historyPush, this ), 300 ); }, setData: function( data ) { if ( 'object' === typeof data ) { this.set( 'params', data ); this.setListeners(); } }, getAll: function() { var params = this.get( 'params' ); return jQuery.extend( true, {}, params ); }, setListeners: function() { var params = this.getAll(), self = this; _.each( params, function( param ) { var option = FusionPageBuilderApp.dynamicValues.getOption( param.data ); if ( option && 'object' === typeof option.listeners ) { _.each( option.listeners, function( listenerData, listenerId ) { self.setListener( listenerId, listenerData, param ); } ); } } ); }, setListener: function( id, data, args ) { var location = 'undefined' !== typeof data.location ? data.location : false, self = this, cid = this.cid, listeners = this.get( 'listeners' ); if ( ! location ) { return; } switch ( location ) { case 'postDetails': FusionEvents.on( 'fusion-' + id + '-changed', function() { FusionPageBuilderApp.dynamicValues.removeValue( args.data ); self.getValueAndUpdate( args ); }, cid ); listeners.push( 'fusion-' + id + '-changed' ); self.set( 'listeners', listeners ); break; case 'postMeta': FusionEvents.on( 'fusion-po-' + id + '-changed', function() { FusionPageBuilderApp.dynamicValues.removeValue( args.data ); self.getValueAndUpdate( args ); }, cid ); listeners.push( 'fusion-po-' + id + '-changed' ); self.set( 'listeners', listeners ); break; } }, hasDynamicParam: function( param ) { var params = this.getAll(); if ( 'undefined' !== typeof params[ param ] ) { return true; } return false; }, getParamValue: function( data ) { var value = FusionPageBuilderApp.dynamicValues.getValue( data ), beforeString = 'string' === typeof data.before ? data.before : '', afterString = 'string' === typeof data.after ? data.after : '', fallback = 'undefined' !== typeof data.fallback ? data.fallback : false, hasValue = 'undefined' !== typeof value && null !== value && false !== value && '' !== value, elementView = this.get( 'elementView' ); if ( ! hasValue && fallback ) { return fallback; } if ( ! hasValue ) { return undefined; } if ( 'object' === typeof value && 'function' === typeof value.then ) { value.then( function() { elementView.reRender(); } ); return false; } else if ( 'string' !== typeof value ) { return value; } return beforeString + value + afterString; }, addParam: function( param, data ) { var self = this, params = this.getAll(), options = FusionPageBuilderApp.dynamicValues.getOptions(), option = false; if ( 'object' !== typeof data ) { data = { data: data }; } // // Set default values. _.each( options[ data.data ].fields, function( field, key ) { if ( 'undefined' === typeof data[ key ] ) { if ( 'undefined' !== typeof field[ 'default' ] ) { data[ key ] = field[ 'default' ]; } else if ( 'undefined' !== typeof field.value ) { data[ key ] = field.value; } } } ); params[ param ] = data; option = FusionPageBuilderApp.dynamicValues.getOption( data.data ); if ( option && 'object' === typeof option.listeners ) { _.each( option.listeners, function( listenerData, listenerId ) { self.setListener( listenerId, listenerData, param ); } ); } this.set( 'params', params ); this.saveData(); FusionEvents.trigger( 'fusion-dynamic-data-added', param, this.cid ); this.getValueAndUpdate( params[ param ] ); }, updateParam: function( param, subParam, value ) { var params = this.getAll(); if ( 'object' === typeof params[ param ] ) { params[ param ][ subParam ] = value; this.set( 'params', params ); FusionEvents.trigger( 'fusion-dynamic-data-updated', param ); this.saveData(); this.getValueAndUpdate( params[ param ] ); } }, getValueAndUpdate: function( args ) { var elementView = this.get( 'elementView' ), valueReturn = FusionPageBuilderApp.dynamicValues.getValue( args, elementView ); if ( valueReturn && 'object' === typeof valueReturn && 'function' === typeof valueReturn.then ) { elementView.addLoadingOverlay(); valueReturn.then( function() { elementView.reRender(); }, function() { elementView.removeLoadingOverlay(); } ); } else { elementView.reRender(); } }, updateListeners: function() { var cid = this.cid; _.each( this.get( 'listeners' ), function( listener ) { FusionEvents.off( listener, null, cid ); } ); this.setListeners(); }, removeParam: function( param ) { var params = this.getAll(), elementView = this.get( 'elementView' ); delete params[ param ]; this.set( 'params', params ); this.updateListeners(); this.saveData(); elementView.reRender(); FusionEvents.trigger( 'fusion-dynamic-data-removed', param ); }, historyPush: function() { var elementView = this.get( 'elementView' ), elementMap = fusionAllElements[ elementView.model.get( 'element_type' ) ]; // TODO: refactor history. FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.edited + ' ' + elementMap.name + ' - ' + fusionBuilderText.dynamic_data ); }, saveData: function() { var elementView = this.get( 'elementView' ), elementParams = elementView.model.get( 'params' ), originalValue = elementParams.dynamic_params; elementParams.dynamic_params = FusionPageBuilderApp.base64Encode( JSON.stringify( this.getAll() ) ); elementView.model.set( 'params', elementParams ); // Make sure that parent is updated, usually done in base view changeParam. if ( 'function' === typeof elementView.forceUpdateParent ) { elementView.forceUpdateParent(); } if ( originalValue !== elementParams.dynamic_params ) { this._historyPush(); } } } ); }( jQuery ) ); ;/* global FusionApp, FusionEvents */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { FusionPageBuilder.FormStyles = Backbone.Model.extend( { initialize: function() { this.baseSelector = '.fusion-form.fusion-form-form-wrapper'; this.dynamic_css = {}; this.formData = FusionApp.data.postMeta._fusion; this.addStyleVariables(); this.listenTo( FusionEvents, 'fusion-form-styles', this.addStyleVariables ); this.listenTo( FusionEvents, 'fusion-builder-loaded', this.addStyleVariables ); this.listenTo( FusionEvents, 'fusion-preview-refreshed', this.updateFormData ); }, updateFormData: function() { this.formData = FusionApp.data.postMeta._fusion; }, isDefault: function( param, subset ) { if ( 'string' === typeof subset ) { return 'undefined' === typeof this.formData[ param ] || 'undefined' === typeof this.formData[ param ][ subset ] || '' === this.formData[ param ][ subset ]; } return 'undefined' === typeof this.formData[ param ] || '' === this.formData[ param ]; }, /** * Adds style variables. * * @since 3.9 * @return {String} */ addStyleVariables: function() { var customVars = [], cssVarsOptions = [], styles; if ( 'undefined' !== typeof this.formData.tooltip_text_color && '' !== this.formData.tooltip_text_color ) { customVars.tooltip_text_color = this.formData.tooltip_text_color; } if ( 'undefined' !== typeof this.formData.tooltip_background_color && '' !== this.formData.tooltip_background_color ) { customVars.tooltip_background_color = this.formData.tooltip_background_color; } if ( ! this.isDefault( 'field_margin', 'top' ) ) { customVars.field_margin_top = _.fusionGetValueWithUnit( this.formData.field_margin.top ); } if ( ! this.isDefault( 'field_margin', 'bottom' ) ) { customVars.field_margin_bottom = _.fusionGetValueWithUnit( this.formData.field_margin.bottom ); } if ( ! this.isDefault( 'form_input_height' ) ) { customVars.form_input_height = _.fusionGetValueWithUnit( this.formData.form_input_height ); } if ( ! this.isDefault( 'form_bg_color' ) ) { customVars.form_bg_color = this.formData.form_bg_color; } if ( ! this.isDefault( 'label_font_size' ) ) { customVars.label_font_size = _.fusionGetValueWithUnit( this.formData.label_font_size ); } if ( ! this.isDefault( 'form_font_size' ) ) { customVars.form_font_size = _.fusionGetValueWithUnit( this.formData.form_font_size ); } if ( 'undefined' !== typeof this.formData.form_placeholder_color && '' !== this.formData.form_placeholder_color ) { customVars.form_placeholder_color = this.formData.form_placeholder_color; } else if ( ! this.isDefault( 'form_text_color' ) ) { customVars.form_placeholder_color = jQuery.AWB_Color( this.formData.form_text_color ).alpha( 0.5 ).toRgbaString(); } if ( ! this.isDefault( 'form_text_color' ) ) { customVars.form_text_color = this.formData.form_text_color; } if ( ! this.isDefault( 'form_label_color' ) ) { customVars.form_label_color = this.formData.form_label_color; } if ( ! this.isDefault( 'form_border_width', 'top' ) ) { customVars.form_border_width_top = _.fusionGetValueWithUnit( this.formData.form_border_width.top, 'px' ); } if ( ! this.isDefault( 'form_border_width', 'bottom' ) ) { customVars.form_border_width_bottom = _.fusionGetValueWithUnit( this.formData.form_border_width.bottom, 'px' ); } if ( ! this.isDefault( 'form_border_width', 'right' ) ) { customVars.form_border_width_right = _.fusionGetValueWithUnit( this.formData.form_border_width.right, 'px' ); } if ( ! this.isDefault( 'form_border_width', 'left' ) ) { customVars.form_border_width_left = _.fusionGetValueWithUnit( this.formData.form_border_width.left, 'px' ); } if ( ! this.isDefault( 'form_border_color' ) ) { customVars.form_border_color = this.formData.form_border_color; } if ( ! this.isDefault( 'form_focus_border_color' ) ) { customVars.form_focus_border_color = this.formData.form_focus_border_color; customVars.form_focus_border_hover_color = jQuery.AWB_Color( this.formData.form_focus_border_color ).alpha( 0.5 ).toRgbaString(); } if ( ! this.isDefault( 'form_border_radius' ) ) { customVars.form_border_radius = _.fusionGetValueWithUnit( this.formData.form_border_radius, 'px' ); } if ( ! this.isDefault( 'form_border_width', 'bottom' ) || !this.isDefault( 'form_border_width', 'top' ) ) { customVars.icon_alignment_top = this.isDefault( 'form_border_width', 'top' ) ? 'var(--form_border_width-top)' : _.fusionGetValueWithUnit( this.formData.form_border_width.top, 'px' ); customVars.icon_alignment_bottom = this.isDefault( 'form_border_width', 'bottom' ) ? 'var(--form_border_width-bottom)' : _.fusionGetValueWithUnit( this.formData.form_border_width.bottom, 'px' ); customVars.icon_alignment_font_size = this.isDefault( 'form_font_size' ) ? '1em' : this.formData.form_font_size; jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).find( '.fusion-form-form-wrapper' ).addClass( 'has-icon-alignment' ); } else { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).find( '.fusion-form-form-wrapper' ).removeClass( 'has-icon-alignment' ); } if ( 'undefined' !== typeof this.formData.required_field_symbol_decoration && 'no' === this.formData.required_field_symbol_decoration ) { customVars.required_field_symbol_deco = 'none'; } cssVarsOptions.margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left = { 'callback': _.fusionGetValueWithUnit }; styles = this.getCssVarsForOptions( cssVarsOptions ) + this.getCustomCssVars( customVars ); jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).find( '.fusion-form-form-wrapper' ).attr( 'style', styles ); }, /** * Get a string with each of the option as a CSS variable, if the option is not default. * * @since 3.9 * @param {array} options The array with the options ids. * @return {string} */ getCssVarsForOptions( options ) { var css = '', varName, value, callback_args, key; for ( key in options ) { if ( ! options.hasOwnProperty( key ) || 'length' === key ) { continue; // eslint-disable-line no-continue } value = options[ key ]; if ( 'object' === typeof value ) { // If the value is an array, then the CSS var name is the key. if ( ! this.isDefault( key ) ) { varName = '--awb-' + key.replaceAll( '_', '-' ); callback_args = ( 'object' === typeof value.args ? value.args : [ this.values[ key ] ] ); css += varName + ':' + value.callback.apply( null, callback_args ) + ';'; } } else { if ( ! this.isDefault( value ) ) { // eslint-disable-line no-lonely-if varName = '--awb-' + value.replaceAll( '_', '-' ); css += varName + ':' + this.values[ value ] + ';'; } } } return css; }, /** * Get a string with custom CSS variables, created from array key => value pairs. * * @since 3.9 * @param {Object} $options The object with the custom css vars. The property * represents the option name, while the value represents the custom value. * @return {string} */ getCustomCssVars( options, prefix ) { var css = '', varName, property; if ( 'undefined' === typeof prefix ) { prefix = true; } for ( property in options ) { if ( ! options.hasOwnProperty( property ) ) { continue; // eslint-disable-line no-continue } if ( prefix ) { varName = '--awb-' + property.replaceAll( '_', '-' ); } else { varName = '--' + property; } css += varName + ':' + options[ property ] + ';'; } return css; } } ); }( jQuery ) ); ;/* global FusionApp, FusionPageBuilderApp, FusionEvents */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { FusionPageBuilder.offCanvasStyles = Backbone.Model.extend( { /** * Off Canvas Live editor preview initialization. * * @since 3.6 * @return {void} */ initialize: function() { const body = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ), ocID = body.find( '.awb-off-canvas-wrap' ).attr( 'data-id' ); // Make sure Off Canvas is 100% width in LE. body.find( '#main' ).addClass( 'width-100' ); this.baseSelector = '.awb-off-canvas-wrap[data-id="' + ocID + '"]'; this.dynamic_css = {}; this.options = this.filterOptions(); this.buildAttr(); // Remove saved styles. body.find( '#awb-off-canvas-style-block-' + ocID ).remove(); this.listenTo( FusionEvents, 'awb-off-canvas-styles', this.buildStyles ); this.listenTo( FusionEvents, 'awb-off-canvas-attr', this.buildAttr ); this.listenTo( FusionEvents, 'awb-off-canvas-custom-close-button', this.customCloseButton ); this.listenTo( FusionEvents, 'awb-off-canvas-enter-animation', this.enterAnimation ); this.listenTo( FusionEvents, 'awb-off-canvas-exit-animation', this.exitAnimation ); this.listenTo( FusionEvents, 'fusion-builder-loaded', this.buildStyles ); this.listenTo( FusionEvents, 'fusion-builder-loaded', this.buildAttr ); this.listenTo( FusionEvents, 'fusion-builder-loaded', this.customCloseButton ); }, /** * Array with animations without directions. * * @since 3.6 * @return {void} */ animationsWithoutDirection: [ 'flash', 'rubberBand', 'shake', 'flipinx', 'flipiny', 'lightspeedin', 'flipOutX', 'flipOutY', 'lightSpeedOut' ], /** * Modify options mostly for sliding bar type. * * @since 3.6 * @return {Object} Modified options object. */ filterOptions: function() { const options = FusionApp.data.postMeta._fusion; const filteredOptions = Object.assign( {}, options ); if ( 'undefined' !== typeof options && 'sliding-bar' === options.type ) { filteredOptions.type = 'sliding-bar'; filteredOptions.enter_animation = filteredOptions.sb_enter_animation; filteredOptions.enter_animation_speed = filteredOptions.sb_enter_animation_speed; filteredOptions.enter_animation_timing = filteredOptions.sb_enter_animation_timing; filteredOptions.exit_animation = filteredOptions.sb_exit_animation; filteredOptions.exit_animation_speed = filteredOptions.sb_exit_animation_speed; filteredOptions.exit_animation_timing = filteredOptions.sb_exit_animation_timing; if ( 'left' === filteredOptions.position || !filteredOptions.position ) { filteredOptions.height = 'full'; filteredOptions.width = options.width || 400; filteredOptions.enter_animation_direction = 'left'; filteredOptions.exit_animation_direction = 'left'; filteredOptions.vertical_position = 'flex-start'; if ( this.isRTL() ) { filteredOptions.horizontal_position = 'flex-end'; } else { filteredOptions.horizontal_position = 'flex-start'; } } if ( 'right' === filteredOptions.position ) { filteredOptions.height = 'full'; filteredOptions.width = options.width || 400; filteredOptions.enter_animation_direction = 'right'; filteredOptions.exit_animation_direction = 'right'; filteredOptions.vertical_position = 'flex-start'; if ( this.isRTL() ) { filteredOptions.horizontal_position = 'flex-start'; } else { filteredOptions.horizontal_position = 'flex-end'; } } if ( 'top' === filteredOptions.position ) { const height = filteredOptions.sb_height || 'auto'; filteredOptions.width = '100vw'; filteredOptions.height = 'custom'; filteredOptions.custom_height = height; filteredOptions.enter_animation_direction = 'down'; filteredOptions.exit_animation_direction = 'up'; filteredOptions.vertical_position = 'flex-start'; filteredOptions.horizontal_position = 'flex-start'; } if ( 'bottom' === filteredOptions.position ) { const height = filteredOptions.sb_height || 'auto'; filteredOptions.width = '100vw'; filteredOptions.height = 'custom'; filteredOptions.custom_height = height; filteredOptions.enter_animation_direction = 'up'; filteredOptions.exit_animation_direction = 'down'; filteredOptions.vertical_position = 'flex-end'; filteredOptions.horizontal_position = 'flex-start'; } return this.parseOptions( filteredOptions ); } return this.parseOptions( options ); }, /** * Merge default options with current options. * To ensure the preview works as same as the front-end. * @since 3.6 * @param {Object} options - The options object. * @return {Object} New options object with default values. */ parseOptions( options ) { const defaults = { // General. 'type': 'popup', 'width': '800', 'width_medium': '', 'width_small': '', 'height': 'fit', 'custom_height': '', 'custom_height_medium': '', 'custom_height_small': '', 'horizontal_position': 'center', 'horizontal_position_medium': '', 'horizontal_position_small': '', 'vertical_position': 'center', 'vertical_position_medium': '', 'vertical_position_small': '', 'content_layout': 'column', 'align_content': 'flex-start', 'valign_content': 'flex-start', 'content_wrap': 'wrap', 'enter_animation': '', 'enter_animation_direction': 'static', 'enter_animation_speed': 0.5, 'enter_animation_timing': 'ease', 'exit_animation': '', 'exit_animation_direction': 'static', 'exit_animation_speed': 0.5, 'exit_animation_timing': 'ease', 'off_canvas_state': 'closed', 'sb_height': '', 'position': 'left', 'transition': 'overlap', 'sb_enter_animation': 'slideShort', 'sb_enter_animation_speed': 0.5, 'sb_enter_animation_timing': 'ease', 'sb_exit_animation': 'slideShort', 'sb_exit_animation_speed': 0.5, 'sb_exit_animation_timing': 'ease', // Design. 'background_color': '#ffffff', 'background_image': '', 'background_position': 'left top', 'background_repeat': 'repeat', 'background_size': '', 'background_custom_size': '', 'background_blend_mode': 'none', 'oc_scrollbar': 'default', 'oc_scrollbar_background': '#f2f3f5', 'oc_scrollbar_handle_color': '#65bc7b', 'margin': '', 'padding': '', 'box_shadow': 'no', 'box_shadow_position': '', 'box_shadow_blur': '0', 'box_shadow_spread': '0', 'box_shadow_color': '', 'border_radius': '', 'border_width': '', 'border_color': '', // Overlay. 'overlay': 'yes', 'overlay_z_index': '', 'overlay_close_on_click': 'yes', 'overlay_page_scrollbar': 'yes', 'overlay_background_color': 'rgba(0,0,0,0.8)', 'overlay_background_image': '', 'overlay_background_position': 'left top', 'overlay_background_repeat': 'repeat', 'overlay_background_size': '', 'overlay_background_custom_size': '', 'overlay_background_blend_mode': 'none', // close button. 'close_button': 'yes', 'close_on_esc': 'yes', 'close_button_position': 'right', 'close_button_margin': {}, 'close_button_color': '', 'close_button_color_hover': '', 'close_icon_size': '16', 'close_button_custom_icon': '' }; return Object.assign( defaults, options ); }, /** * Adds CSS property to object. * * @since 3.2 * @param {String} selectors - The CSS selectors. * @param {String} property - The CSS property. * @param {String} value - The CSS property value. * @param {Bool} important - Should have important tag. * @return {void} */ addCssProperty: function ( selectors, property, value, important ) { if ( 'object' === typeof selectors ) { selectors = Object.values( selectors ); } if ( 'object' === typeof selectors ) { selectors = selectors.join( ',' ); } if ( 'object' !== typeof this.dynamic_css[ selectors ] ) { this.dynamic_css[ selectors ] = {}; } if ( 'undefined' !== typeof important && important ) { value += ' !important'; } if ( 'undefined' === typeof this.dynamic_css[ selectors ][ property ] || ( 'undefined' !== typeof important && important ) || ! this.dynamic_css[ selectors ][ property ].includes( 'important' ) ) { this.dynamic_css[ selectors ][ property ] = value; } }, /** * Parses CSS. * * @since 3.2 * @return {String} */ parseCSS: function () { var css = '.awb-off-canvas-wrap .awb-off-canvas .fusion-fullwidth{margin-right:0;margin-left:0;}'; if ( 'object' === typeof this.dynamic_css ) { _.each( this.dynamic_css, function ( properties, selector ) { if ( 'object' === typeof properties ) { css += selector + '{'; _.each( properties, function ( value, property ) { css += property + ':' + value + ';'; } ); css += '}'; } } ); } return css; }, /** * Checks if param has got default value or not. * * @since 3.2 * @param {String} param - The param. * @return {Bool} */ isDefault: function( param, subset ) { if ( 'string' === typeof subset ) { return 'undefined' === typeof this.options[ param ] || 'undefined' === typeof this.options[ param ][ subset ] || '' === this.options[ param ][ subset ]; } return 'undefined' === typeof this.options[ param ] || '' === this.options[ param ]; }, /** * Checks if website using RTL language. * * @since 3.6 * @return {Bool} */ isRTL: function () { return jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).hasClass( 'rtl' ); }, /** * Get CSS from spacing fields. * used for margin, padding, position, etc. * @since 3.6 * @param {Object} options - The options object. * @param {String} key - options key. * @param {String} prop - CSS property, if empty key will used instead. * @return {String} CSS code. */ getSpacing: function( options, key ) { if ( !options[ key ] && 'object' !== typeof options[ key ] ) { return []; } const vars = []; const keys = [ 'top', 'right', 'bottom', 'left' ]; keys.forEach( ( k ) => { const v = options[ key ][ k ] || ''; if ( '' !== v ) { vars[ key + '_' + k ] = _.fusionGetValueWithUnit( v ); } } ); return vars; }, /** * Get CSS code for box shadow. * * @since 3.6 * @param {Object} options - The options object. * @return {String} CSS code. */ getShadow( options ) { if ( 'yes' !== options.box_shadow ) { return ''; } let h = '0', v = '0'; const blur = options.box_shadow_blur || '0', spread = options.box_shadow_spread || '0', color = options.box_shadow_color || ''; if ( options.box_shadow_position && 'object' === typeof options.box_shadow_position ) { h = options.box_shadow_position.horizontal || h; v = options.box_shadow_position.vertical || v; } return `${_.fusionGetValueWithUnit( h )} ${_.fusionGetValueWithUnit( v )} ${_.fusionGetValueWithUnit( blur )} ${_.fusionGetValueWithUnit( spread )} ${color}`; }, /** * Get CSS code for borders including border radius. * * @since 3.6 * @param {Object} options - The options object. * @return {String} CSS code. */ getBorder( options ) { const vars = []; // Border radius. if ( options.border_radius && 'object' === typeof options.border_radius ) { const br = options.border_radius; // ensure preview works when delete value. if ( !br.top_left ) { br.top_left = ''; } if ( !br.top_right ) { br.top_right = ''; } if ( !br.bottom_right ) { br.bottom_right = ''; } if ( !br.bottom_left ) { br.bottom_left = ''; } // loop through border radius. Object.keys( br ).forEach( ( r ) => { const v = br[ r ] || 0; vars[ `border_${r}_radius` ] = _.fusionGetValueWithUnit( v ); } ); } // Border width. if ( options.border_width && 'object' === typeof options.border_width ) { const bw = options.border_width; // ensure preview works when delete value. if ( !bw.top ) { bw.top = ''; } if ( !bw.right ) { bw.right = ''; } if ( !bw.bottom ) { bw.bottom = ''; } if ( !bw.left ) { bw.left = ''; } Object.keys( bw ).forEach( ( b ) => { const v = bw[ b ] || 0; vars[ `border_${b}_width` ] = _.fusionGetValueWithUnit( v ); } ); } // Border color. if ( options.border_color ) { vars.border_color = options.border_color; } return vars; }, /** * Build CSS style block and add it to the head. * * @since 3.6 * @return {void} CSS code. */ buildStyles: function() { var selectors, css = ''; this.dynamic_css = {}; const options = this.filterOptions(); // Add style variables. const body = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ); body.find( this.baseSelector ).attr( 'style', this.getStylesVars() ); // Fix close button z-index in LE. selectors = [ this.baseSelector + ' .awb-off-canvas:hover .off-canvas-close' ]; this.addCssProperty( selectors, 'display', 'none' ); // Close button. selectors = [ this.baseSelector + ' .off-canvas-close' ]; if ( 'no' === options.close_button ) { this.addCssProperty( selectors, 'display', 'none' ); } // Add attribute to the option. const value = jQuery( '[data-option-id="content_layout"]' ).find( 'input#content_layout' ).val(); jQuery( '[data-option-id="content_layout"]' ).attr( 'data-direction', value ); // hidden scrollbar. if ( 'hidden' === options.oc_scrollbar ) { selectors = [ this.baseSelector + ' .off-canvas-content' ]; // Firefox. this.addCssProperty( selectors, 'scrollbar-width', 'none' ); // Chrome, Safari, Edge. this.addCssProperty( [ this.baseSelector + ' .off-canvas-content::-webkit-scrollbar' ], 'display', 'none' ); } css = this.parseCSS(); if ( jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'head' ).find( '#awb-off-canvas-style-block' ).length ) { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'head' ).find( '#awb-off-canvas-style-block' ).html( css ); return; } jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'head' ).prepend( '' ); }, /** * Build style variables. * * @since 3.9 * @return String CSS variables. */ getStylesVars: function() { const options = this.filterOptions(); let vars = {}; if ( options.horizontal_position ) { vars.horizontal_position = options.horizontal_position; } if ( options.horizontal_position_medium ) { vars.horizontal_position_medium = options.horizontal_position_medium; } if ( options.horizontal_position_small ) { vars.horizontal_position_small = options.horizontal_position_small; } if ( options.vertical_position ) { vars.vertical_position = options.vertical_position; } if ( options.vertical_position_medium ) { vars.vertical_position_medium = options.vertical_position_medium; } if ( options.vertical_position_small ) { vars.vertical_position_small = options.vertical_position_small; } if ( options.overlay_z_index ) { vars.overlay_z_index = options.overlay_z_index; } // Overlay Background. if ( 'yes' === options.overlay ) { if ( options.overlay_background_color ) { vars.overlay_background_color = options.overlay_background_color; } if ( options.overlay_background_image ) { let overlay_background_image = options.overlay_background_image; if ( _.isObject( overlay_background_image ) ) { overlay_background_image = overlay_background_image.url; } vars.overlay_background_image = `url(${overlay_background_image})`; if ( options.overlay_background_repeat ) { vars.overlay_background_repeat = options.overlay_background_repeat; } if ( options.overlay_background_position ) { vars.overlay_background_position = options.overlay_background_position; } if ( options.overlay_background_blend_mode ) { vars.overlay_background_blend_mode = options.overlay_background_blend_mode; } if ( '' !== options.overlay_background_size ) { if ( 'custom' === options.overlay_background_size ) { const width = options.overlay_background_custom_size.width ? _.fusionGetValueWithUnit( options.overlay_background_custom_size.width ) : ''; const height = options.overlay_background_custom_size.height ? _.fusionGetValueWithUnit( options.overlay_background_custom_size.height ) : ''; // eslint-disable-next-line max-depth if ( width ) { vars.overlay_background_size = width + ' ' + height; } } else { vars.overlay_background_size = options.overlay_background_size; } } } } if ( options.width ) { vars.width = _.fusionGetValueWithUnit( options.width ); } if ( options.width_medium ) { vars.width_medium = _.fusionGetValueWithUnit( options.width_medium ); } if ( options.width_small ) { vars.width_small = _.fusionGetValueWithUnit( options.width_small ); } if ( options.height ) { if ( 'full' === options.height ) { vars.height = '100vh'; } if ( 'custom' === options.height ) { if ( options.custom_height ) { vars.height = _.fusionGetValueWithUnit( options.custom_height ); } if ( options.custom_height_medium ) { vars.height_medium = _.fusionGetValueWithUnit( options.custom_height_medium ); } if ( options.custom_height_small ) { vars.height_small = _.fusionGetValueWithUnit( options.custom_height_small ); } } } // Margin. vars = { ...vars, ...this.getSpacing( options, 'margin' ) }; // Padding. vars = { ...vars, ...this.getSpacing( options, 'padding' ) }; vars.box_shadow = this.getShadow( options ); vars = { ...vars, ...this.getBorder( options ) }; if ( options.background_color ) { vars.background_color = options.background_color; } if ( options.background_image ) { let background_image = options.background_image; if ( _.isObject( background_image ) ) { background_image = background_image.url; } vars.background_image = `url(${background_image})`; if ( options.background_repeat ) { vars.background_repeat = options.background_repeat; } if ( options.background_position ) { vars.background_position = options.background_position; } if ( options.background_blend_mode ) { vars.background_blend_mode = options.background_blend_mode; } if ( '' !== options.background_size ) { if ( 'custom' === options.background_size ) { const width = options.background_custom_size.width ? _.fusionGetValueWithUnit( options.background_custom_size.width ) : ''; const height = options.background_custom_size.height ? _.fusionGetValueWithUnit( options.background_custom_size.height ) : ''; if ( width ) { vars.background_size = width + ' ' + height; } } else { vars.background_size = options.background_size; } } } // Custom Scrollbar. if ( 'custom' === options.oc_scrollbar ) { if ( options.oc_scrollbar_handle_color ) { vars.oc_scrollbar_handle_color = options.oc_scrollbar_handle_color; } if ( options.oc_scrollbar_background ) { vars.oc_scrollbar_background = options.oc_scrollbar_background; } } // Alignment. if ( options.content_layout ) { vars.content_layout = options.content_layout; } if ( options.align_content ) { vars.align_content = options.align_content; } if ( options.valign_content ) { vars.valign_content = options.valign_content; } if ( options.content_wrap ) { vars.content_wrap = options.content_wrap; } // Close button. vars = { ...vars, ...this.getSpacing( options, 'close_button_margin' ) }; if ( options.close_button_color ) { vars.close_button_color = options.close_button_color; } if ( options.close_icon_size ) { vars.close_icon_size = _.fusionGetValueWithUnit( options.close_icon_size ); } if ( options.close_button_color_hover ) { vars.close_button_color_hover = options.close_button_color_hover; } let style = ''; Object.keys( vars ).forEach( ( v ) => { const var_name = '--awb-' + v.replaceAll( '_', '-' ); style += var_name + ':' + vars[ v ] + ';'; } ); return style; }, /** * build attributes. * * @since 3.6 * @return {String} CSS code. */ buildAttr: function() { const body = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ); const options = this.filterOptions(); // Wrap Classes. let wrapClasses = 'awb-off-canvas-wrap awb-show'; if ( '' !== options.css_id ) { body.find( this.baseSelector ).attr( 'id', options.css_id ); } if ( '' !== options.css_class ) { wrapClasses += ' ' + options.css_class; } if ( '' !== options.type ) { wrapClasses += ' type-' + options.type; } if ( 'sliding-bar' === options.type ) { if ( !options.position ) { options.position = 'left'; } wrapClasses += ' position-' + options.position; } if ( 'no' === options.overlay ) { wrapClasses += ' overlay-disabled'; } if ( 'custom' === options.oc_scrollbar ) { wrapClasses += ' has-custom-scrollbar'; } if ( 'hidden' === options.oc_scrollbar ) { wrapClasses += ' hidden-scrollbar'; } body.find( this.baseSelector ).removeClass().addClass( wrapClasses ); body.find( this.baseSelector ).attr( 'style', this.getStylesVars() ); // remove is empty class. if ( 1 < FusionPageBuilderApp.collection.length ) { body.find( this.baseSelector + ' .awb-off-canvas-inner' ).removeClass( 'is-empty' ); } // close button attr. const closeButton = body.find( this.baseSelector ).find( '.off-canvas-close' ); closeButton.removeClass( function ( index, className ) { return ( className.match( /(^|\s)close-position-\S+/g ) || [] ).join( ' ' ); } ); closeButton.addClass( 'close-position-' + options.close_button_position ); }, /** * Custom close button. * * @since 3.6 * @return {void}. */ customCloseButton: function() { const options = this.filterOptions(); const body = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ); let closeButton = body.find( '.off-canvas-close' ); if ( ! closeButton.length ) { body.find( '.awb-off-canvas' ).prepend( '' ); closeButton = body.find( '.off-canvas-close' ); } let cls = 'off-canvas-close'; if ( options.close_button_custom_icon ) { cls += ' ' + _.fusionFontAwesome( options.close_button_custom_icon ); } else { cls += ' awb-icon-close'; } cls += ' close-position-' + options.close_button_position; closeButton.removeClass().addClass( cls ); }, /** * Capitalize string. * * @since 3.6 * @return {String} The capitalized string. */ capitalize: function ( string ) { return string.charAt( 0 ).toUpperCase() + string.slice( 1 ); }, /** * Enter animation preview. * * @since 3.6 * @param {String} string * @return {void} */ enterAnimation: function() { const body = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ), offCanvas = body.find( '.awb-off-canvas' ), options = this.filterOptions(); let animation = options.enter_animation; const animationDirection = options.enter_animation_direction && 'static' !== options.enter_animation_direction ? this.capitalize( options.enter_animation_direction ) : '', animationSpeed = options.enter_animation_speed || 1, animationTiming = options.enter_animation_timing || 'ease'; if ( animation ) { if ( ! this.animationsWithoutDirection.includes( animation ) ) { animation = animation + 'In' + animationDirection; } offCanvas.addClass( 'fusion-animated ' + animation ); offCanvas.attr( 'data-animation-type', animation ); offCanvas.css( { 'visibility': 'visible', 'animation-duration': animationSpeed + 's', 'animation-timing-function': animationTiming } ); } offCanvas.addClass( 'fusion-animated ' + animation ); offCanvas.on( 'animationend', function() { const el = jQuery( this ); if ( el.attr( 'data-animation-type' ) ) { el.removeClass( 'fusion-animated' ).removeClass( el.attr( 'data-animation-type' ) ).removeAttr( 'data-animation-type' ); } } ); }, /** * Exit animation preview. * * @since 3.6 * @return {void} */ exitAnimation: function() { const body = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ), offCanvas = body.find( '.awb-off-canvas' ), options = this.filterOptions(); let animation = options.exit_animation; const animationDirection = options.exit_animation_direction && 'static' !== options.exit_animation_direction ? this.capitalize( options.exit_animation_direction ) : '', animationSpeed = options.exit_animation_speed || 1, animationTiming = options.exit_animation_timing || 'ease'; if ( animation ) { if ( ! this.animationsWithoutDirection.includes( animation ) ) { animation = animation + 'Out' + animationDirection; } offCanvas.addClass( 'fusion-animated ' + animation ); offCanvas.attr( 'data-animation-type', animation ); offCanvas.css( { 'visibility': 'visible', 'animation-duration': animationSpeed + 's', 'animation-timing-function': animationTiming } ); } offCanvas.addClass( 'fusion-animated ' + animation ); offCanvas.on( 'animationend', function() { const el = jQuery( this ); setTimeout( () => { if ( el.attr( 'data-animation-type' ) ) { el.removeClass( 'fusion-animated' ).removeClass( el.attr( 'data-animation-type' ) ).removeAttr( 'data-animation-type' ); } }, 500 ); } ); } } ); }( jQuery ) ); ;var FusionPageBuilder = FusionPageBuilder || {}; ( function() { // Element collection FusionPageBuilder.Collection = Backbone.Collection.extend( { model: FusionPageBuilder.Element } ); window.FusionPageBuilderElements = new FusionPageBuilder.Collection(); // jshint ignore: line }( jQuery ) ); ;/* global fusionBuilderText, fusionGlobalManager, FusionApp, FusionPageBuilderViewManager, fusionAllElements, FusionPageBuilderApp, FusionEvents, fusionAppConfig */ /* eslint no-empty-function: 0 */ /* eslint no-shadow: 0 */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Builder Element View FusionPageBuilder.BaseView = window.wp.Backbone.View.extend( { modalDialogMoreView: null, events: { }, /** * Init. * * @since 2.0.0 * @return {void} */ initialize: function() { }, /** * Before initial render. * * @since 2.0.0 * @return {void} */ beforeRender: function() { }, /** * Filters render markup. * * @since 2.0.0 * @return null */ filterRender: function( $markup ) { return $markup; }, /** * Runs during render() call. * * @since 2.0.0 * @return null */ onRender: function() { }, /** * Runs during initialize() call. * * @since 2.0.0 * @return null */ onInit: function() { }, /** * Runs just before view is removed. * * @since 2.0.0 * @return null */ beforeRemove: function() { }, /** * Runs just after render on cancel. * * @since 2.0.0 * @return null */ onCancel: function() { }, /** * Runs just after render on cancel. * * @since 3.0.2 * @return null */ beforeGenerateShortcode: function() { var elementType = this.model.get( 'element_type' ), options = fusionAllElements[ elementType ].params, values = jQuery.extend( true, {}, fusionAllElements[ elementType ].defaults, _.fusionCleanParameters( this.model.get( 'params' ) ) ), self = this, iconWithoutFusionPrefix; if ( 'object' !== typeof options ) { return; } // If images needs replaced lets check element to see if we have media being used to add to object. if ( 'undefined' !== typeof FusionApp.data.replaceAssets && FusionApp.data.replaceAssets && ( 'undefined' !== typeof FusionApp.data.fusion_element_type || 'fusion_template' === FusionApp.getPost( 'post_type' ) ) ) { this.mapStudioImages( options, values ); if ( 'undefined' !== typeof this.model.get( 'multi' ) && 'multi_element_parent' === this.model.get( 'multi' ) ) { this.model.children.each( function( child ) { var elementType = child.attributes.element_type, childOptions = fusionAllElements[ elementType ].params, childValues = jQuery.extend( true, {}, fusionAllElements[ elementType ].defaults, _.fusionCleanParameters( child.attributes.params ) ); self.mapStudioImages( childOptions, childValues ); } ); } if ( 'fusion_form' === elementType && '' !== values.form_post_id ) { // If its not within object already, add it. if ( 'undefined' === typeof FusionPageBuilderApp.mediaMap.forms[ values.form_post_id ] ) { FusionPageBuilderApp.mediaMap.forms[ values.form_post_id ] = true; } } // Add custom icons that used in forms to media map. if ( this.isString( elementType ) && elementType.startsWith( 'fusion_form_' ) && this.isString( values.input_field_icon ) && 'fusion-prefix-' === values.input_field_icon.substr( 0, 14 ) ) { if ( 'undefined' !== typeof fusionAppConfig.customIcons ) { iconWithoutFusionPrefix = values.input_field_icon.substr( 14 ); // TODO: try to optimize this check. jQuery.each( fusionAppConfig.customIcons, function( iconPostName, iconSet ) { if ( 0 === iconWithoutFusionPrefix.indexOf( iconSet.css_prefix ) ) { FusionPageBuilderApp.mediaMap.icons[ iconSet.post_id ] = iconSet.css_prefix; return false; } } ); } } } }, /** * Add studio images to media map. * @param {Object} options * @param {Object} values * @returns void */ mapStudioImages: function( options, values ) { if ( 'object' !== typeof options ) { return; } // If images needs replaced lets check element to see if we have media being used to add to object. _.each( options, function( option ) { var value; if ( 'upload' === option.type && 'undefined' !== typeof values[ option.param_name ] && '' !== values[ option.param_name ] ) { value = values[ option.param_name ]; if ( 'undefined' === typeof value || 'undefined' === value ) { return; } // If its not within object already, add it. if ( 'undefined' === typeof FusionPageBuilderApp.mediaMap.images[ value ] ) { FusionPageBuilderApp.mediaMap.images[ value ] = true; } // Check if we have an image ID for this param. if ( 'undefined' !== typeof values[ option.param_name + '_id' ] && '' !== values[ option.param_name + '_id' ] ) { if ( 'object' !== typeof FusionPageBuilderApp.mediaMap.images[ value ] ) { FusionPageBuilderApp.mediaMap.images[ value ] = {}; } FusionPageBuilderApp.mediaMap.images[ value ][ option.param_name + '_id' ] = values[ option.param_name + '_id' ]; } } else if ( 'upload_images' === option.type && 'undefined' !== typeof values[ option.param_name ] && '' !== values[ option.param_name ] ) { if ( 'object' !== typeof FusionPageBuilderApp.mediaMap.multiple_images ) { FusionPageBuilderApp.mediaMap.multiple_images = {}; } const key = option.param_name + '-' + values[ option.param_name ]; if ( 'object' !== typeof FusionPageBuilderApp.mediaMap.multiple_images[ key ] ) { FusionPageBuilderApp.mediaMap.multiple_images[ key ] = {}; } // Add images URLs const images = values[ option.param_name ].split( ',' ); images.forEach( ( id ) => { const image = wp.media.attachment( id ); if ( _.isUndefined( image.get( 'url' ) ) ) { image.fetch().then( function() { FusionPageBuilderApp.mediaMap.multiple_images[ key ][ id ] = image.get( 'url' ); } ); } else { FusionPageBuilderApp.mediaMap.multiple_images[ key ][ id ] = image.get( 'url' ); } } ); } } ); }, /** * Triggers a refresh. * * @since 2.0.0 * @return void */ refreshJs: function() { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-element-render-' + this.model.attributes.element_type, this.model.attributes.cid ); }, /** * Triggers responsive typography to recalculate. * * @since 2.0.0 * @return void */ updateResponsiveTypography: function() { document.querySelector( '#fb-preview' ).contentWindow.document.body.dispatchEvent( new Event( 'fusion-force-typography-update', { 'bubbles': true, 'cancelable': true } ) ); }, /** * Re-Renders the view. * * @since 2.0.0 * @param {Object} event - The event triggering the rerender. * @return {void} */ reRender: function( event ) { if ( event && 'object' === typeof event ) { event.preventDefault(); } this.patchView( event ); if ( this.model.get( 'inline_editor' ) && ! this.activeInlineEditing ) { FusionPageBuilderApp.inlineEditorHelpers.liveEditorEvent( this ); this.activeInlineEditing = false; } }, patchView: function() { var self = this, $oldContent = '', $newContent = '', MultiGlobalArgs = {}, diff, heightBeforePatch; if ( 'generated_element' === this.model.get( 'type' ) || 'fusion_builder_form_step' === this.model.get( 'type' ) ) { return; } heightBeforePatch = this.$el.outerHeight(); this.beforePatch(); FusionPageBuilderApp.disableDocumentWrite(); $oldContent = this.getElementContent(); $newContent = $oldContent.clone(); $newContent.html( self.getTemplate() ); // Find the difference diff = FusionPageBuilderApp._diffdom.diff( $oldContent[ 0 ], $newContent[ 0 ] ); // Columns. Skip resizable patching. if ( 'function' === typeof this.patcherFilter ) { diff = this.patcherFilter( diff ); } // Apply the difference. FusionPageBuilderApp._diffdom.apply( $oldContent[ 0 ], diff ); if ( 'fusion_builder_column' !== this.model.get( 'element_type' ) ) { // Handle multiple global elements. MultiGlobalArgs = { currentModel: this.model, handleType: 'changeView', difference: diff }; fusionGlobalManager.handleMultiGlobal( MultiGlobalArgs ); } $oldContent.removeClass( 'fusion-loader' ); FusionPageBuilderApp.enableDocumentWrite(); this.afterPatch(); // So equalHeights columns are updated. if ( heightBeforePatch !== this.$el.outerHeight() && 'function' === typeof this._triggerColumn ) { this._triggerColumn(); } }, /** * Filter out DOM before patching. * * @since 2.0.0 * @return {void} */ patcherFilter: function( diffs ) { var filteredDiffs = [], ignoreList = [ 'aria-multiline', 'contenteditable', 'data-inline-fontsize', 'data-medium-editor-index', 'data-medium-editor-element', 'data-medium-focused', 'data-placeholder', 'medium-editor-index', 'role', 'spellcheck' ], skipReInit = false; if ( this.activeInlineEditing ) { _.each( diffs, function( diff ) { if ( 'removeAttribute' === diff.action && -1 !== jQuery.inArray( diff.name, ignoreList ) ) { skipReInit = true; return; } else if ( 'modifyAttribute' === diff.action && -1 !== diff.oldValue.indexOf( 'medium-editor-element' ) && -1 === diff.oldValue.indexOf( 'medium-editor-element' ) ) { diff.newValue = diff.newValue + ' medium-editor-element'; filteredDiffs.push( diff ); skipReInit = true; return; } filteredDiffs.push( diff ); } ); diffs = filteredDiffs; // If we are not just removing/modifying attributes then inline needs recreated. this.activeInlineEditing = skipReInit; this.autoSelectEditor = ! skipReInit; } return diffs; }, /** * Runs before view DOM is patched. * * @since 2.0.0 * @return null */ beforePatch: function() { }, /** * Runs after view DOM is patched. * * @since 2.0.0 * @return null */ afterPatch: function() { // This will trigger a JS event on the preview frame. this._refreshJs(); }, /** * Runs after render to open any newly added inline element settings. * * @since 2.0.0 * @return null */ renderInlineSettings: function() { var newlyAdded; if ( 'undefined' === typeof FusionPageBuilderApp.inlineEditors || ! FusionPageBuilderApp.inlineEditors.shortcodeAdded ) { return; } newlyAdded = this.model.inlineCollection.find( function( model ) { return 'true' == model.get( 'params' ).open_settings; // jshint ignore: line } ); if ( 'undefined' !== typeof newlyAdded ) { newlyAdded.parentView = this; newlyAdded.$target = this.$el.find( '.fusion-disable-editing[data-id="' + newlyAdded.get( 'cid' ) + '"]' ); delete newlyAdded.attributes.params.open_settings; if ( 'undefined' !== typeof FusionApp && 'off' !== FusionApp.preferencesData.open_settings ) { newlyAdded.set( 'added', true ); FusionPageBuilderApp.inlineEditorHelpers.getInlineElementSettings( newlyAdded ); } } }, /** * Get the template. * * @since 2.0.0 * @return {void} */ getTemplate: function() { var atts = this.getTemplateAtts(); if ( 'undefined' !== typeof this.elementTemplate ) { return this.elementTemplate( atts ); } }, /** * Modify template attributes. * * @since 2.0.0 * @return {Object} */ filterTemplateAtts: function( atts ) { return atts; }, /** * Get dynamic values. * * @since 2.0.0 * @return {Object} */ getDynamicAtts: function( atts ) { var self = this; if ( 'undefined' !== typeof this.dynamicParams && this.dynamicParams && ! _.isEmpty( this.dynamicParams.getAll() ) ) { _.each( this.dynamicParams.getAll(), function( data, id ) { var value = self.dynamicParams.getParamValue( data ); if ( 'undefined' !== typeof value && false !== value ) { atts.values[ id ] = value; } } ); } return atts; }, /** * Gets element DOM for patching. * * @since 2.1 * @return {Object} */ getValues: function() { var elementType = this.model.get( 'element_type' ), element = fusionAllElements[ elementType ]; return this.getDynamicAtts( jQuery.extend( true, {}, element.defaults, _.fusionCleanParameters( this.model.get( 'params' ) ) ) ); }, /** * Gets element DOM for patching. * * @since 2.0.0 * @return {Object} */ getElementContent: function() { var self = this; switch ( this.model.get( 'type' ) ) { case 'fusion_builder_column': case 'fusion_builder_container': case 'fusion_builder_column_inner': return self.$el; case 'element': if ( 'multi_element_child' !== self.model.get( 'multi' ) ) { return self.$el.find( '.fusion-builder-element-content' ); } return self.$el.find( '.fusion-builder-child-element-content' ); } }, /** * Settings handler. * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ settings: function( event ) { var self = this, viewSettings = { model: this.model, collection: this.collection }, customSettingsViewName, modalView, parentView, generated = 'generated_element' === this.model.get( 'type' ), childElementClass = '', dialogTitle = '', resizePopupClass = localStorage.getItem( 'resizePopupClass' ); if ( event ) { event.preventDefault(); } this.onSettingsOpen(); customSettingsViewName = fusionAllElements[ this.model.get( 'element_type' ) ].custom_settings_view_name; // Check for generated element child. if ( 'multi_element_child' === this.model.get( 'multi' ) ) { parentView = FusionPageBuilderViewManager.getView( this.model.get( 'parent' ) ); if ( parentView && 'generated_element' === parentView.model.get( 'type' ) ) { generated = true; viewSettings.model.set( 'type', 'generated_element' ); viewSettings.model.set( 'display', 'dialog' ); } } if ( 'undefined' !== typeof customSettingsViewName && '' !== customSettingsViewName ) { modalView = new FusionPageBuilder[ customSettingsViewName ]( viewSettings ); } else { modalView = new FusionPageBuilder.ElementSettingsView( viewSettings ); } // Activate column spacing. if ( 'fusion_builder_column' === this.model.get( 'element_type' ) || 'fusion_builder_column_inner' === this.model.get( 'element_type' ) ) { this.columnSpacing(); this.paddingDrag(); this.marginDrag(); // Hides column size popup. this.$el.removeClass( 'active' ); this.$el.closest( '.fusion-builder-container' ).removeClass( 'fusion-column-sizer-active' ); } // Activate resize handles. if ( 'fusion_builder_container' === this.model.get( 'element_type' ) ) { this.paddingDrag(); this.marginDrag(); } if ( 'fusion_builder_container' === this.model.get( 'element_type' ) || 'fusion_builder_column' === this.model.get( 'element_type' ) || 'fusion_builder_column_inner' === this.model.get( 'element_type' ) ) { this.$el.addClass( 'fusion-builder-element-edited' ); } childElementClass = 'undefined' !== this.model.get( 'multi' ) && 'multi_element_child' === this.model.get( 'multi' ) ? ' fusion-builder-child-element' : ''; dialogTitle = this.getDialogTitle(); // No need to render if it already is. if ( ! FusionPageBuilderApp.SettingsHelpers.shouldRenderSettings( modalView ) ) { return; } // If we want dialog. if ( 'dialog' === FusionApp.preferencesData.editing_mode || generated ) { jQuery( modalView.render().el ).dialog( { title: dialogTitle, width: FusionApp.dialog.dialogData.width, height: FusionApp.dialog.dialogData.height, position: FusionApp.dialog.dialogData.position, dialogClass: 'fusion-builder-dialog fusion-builder-settings-dialog' + childElementClass, minWidth: 327, type: this.model.get( 'type' ), dragStop: function( event, ui ) { FusionApp.dialog.saveDialogPosition( ui.offset ); }, resizeStart: function() { FusionApp.dialog.addResizingClasses(); }, resizeStop: function( event, ui ) { var $dialog = jQuery( event.target ).closest( '.ui-dialog' ), width = $dialog.find( '.fusion-tabs-menu > li' ).length; if ( width ) { width = 100 * width; } if ( width && ui.size.width > width ) { $dialog.find( '.fusion-tabs-menu' ).addClass( 'show-text' ); } else { $dialog.find( '.fusion-tabs-menu' ).removeClass( 'show-text' ); } FusionApp.dialog.saveDialogSize( ui.size ); if ( 450 > ui.size.width && ! $dialog.hasClass( 'fusion-builder-dialog-narrow' ) ) { $dialog.addClass( 'fusion-builder-dialog-narrow' ); } else if ( 450 <= ui.size.width && $dialog.hasClass( 'fusion-builder-dialog-narrow' ) ) { $dialog.removeClass( 'fusion-builder-dialog-narrow' ); } FusionApp.dialog.removeResizingClasses(); }, open: function( event ) { var $dialogContent = jQuery( event.target ), $dialog = $dialogContent.closest( '.ui-dialog' ), width; // On start can sometimes be laggy/late. FusionApp.dialog.addResizingHoverEvent(); if ( modalView.$el.find( '.has-group-options' ).length ) { $dialog.addClass( 'fusion-builder-group-options' ); } $dialogContent.find( '.fusion-builder-section-name' ).blur(); jQuery( '.ui-dialog' ).not( $dialog ).hide(); jQuery( '.fusion-back-menu-item' ).on( 'click', function() { modalView.openParent(); self.onSettingsClose(); } ); self.modalDialogMoreView = new FusionPageBuilder.modalDialogMore( { model: self.model } ); // We need to render context submenu on open. FusionPageBuilderApp.SettingsHelpers.renderDialogMoreOptions( modalView ); if ( null !== resizePopupClass ) { jQuery( 'body' ).addClass( resizePopupClass ); self.modalDialogMoreView.resizePopup( resizePopupClass ); } jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).addClass( 'fusion-dialog-ui-active' ); if ( 450 > $dialog.width() && ! $dialog.hasClass( 'fusion-builder-dialog-narrow' ) ) { $dialog.addClass( 'fusion-builder-dialog-narrow' ); } else if ( 450 <= $dialog.width() && $dialog.hasClass( 'fusion-builder-dialog-narrow' ) ) { $dialog.removeClass( 'fusion-builder-dialog-narrow' ); } // Check if dialog is positioned outside of viewport and reposition it if needed. if ( FusionApp.dialog.maybeRepositionDialog( $dialog ) ) { FusionApp.dialog.saveDialogPosition( $dialog.offset() ); } width = $dialog.find( '.fusion-tabs-menu > li' ).length; if ( width ) { width = 100 * width; } if ( width && $dialog.width() > width ) { $dialog.find( '.fusion-tabs-menu' ).addClass( 'show-text' ); } }, dragStart: function( event ) { // Used to close any open drop-downs in TinyMce. jQuery( event.target ).trigger( 'click' ); }, beforeClose: function( event ) { FusionApp.dialogCloseResets( modalView ); self.modalDialogMoreView = null; modalView.saveSettings( event ); FusionEvents.trigger( 'fusion-content-changed' ); } } ); } else { // Adding into sidebar view instead. modalView.model.set( 'title', dialogTitle ); modalView.model.set( 'display', 'sidebar' ); FusionApp.sidebarView.renderElementSettings( modalView ); } }, getDialogTitle: function() { var dialogTitle = fusionAllElements[ this.model.get( 'element_type' ) ].name, params; if ( 'multi_element_child' === this.model.get( 'multi' ) ) { params = jQuery.extend( true, {}, this.model.get( 'params' ) ); dialogTitle = 'Item'; if ( 'undefined' !== typeof params.title && params.title.length ) { dialogTitle = params.title; } else if ( 'undefined' !== typeof params.title_front && params.title_front.length ) { dialogTitle = params.title_front; } else if ( 'undefined' !== typeof params.name && params.name.length ) { dialogTitle = params.name; } else if ( 'undefined' !== typeof params.image && params.image.length ) { dialogTitle = params.image; // If contains backslash, retrieve only last part. if ( -1 !== dialogTitle.indexOf( '/' ) && -1 === dialogTitle.indexOf( '[' ) ) { dialogTitle = dialogTitle.split( '/' ); dialogTitle = dialogTitle.slice( -1 )[ 0 ]; } } else if ( 'image' === this.model.attributes.element_name && 'undefined' !== typeof params.element_content && params.element_content.length ) { dialogTitle = params.element_content; // If contains backslash, retrieve only last part. if ( -1 !== dialogTitle.indexOf( '/' ) && -1 === dialogTitle.indexOf( '[' ) ) { dialogTitle = dialogTitle.split( '/' ); dialogTitle = dialogTitle.slice( -1 )[ 0 ]; } } else if ( 'undefined' !== typeof params.video && params.video.length ) { dialogTitle = params.video; } else if ( 'undefined' !== typeof params.element_content && params.element_content.length ) { dialogTitle = params.element_content; } // Remove HTML tags but keep quotation marks etc. dialogTitle = dialogTitle.replace( /(<([^>]+)>)/ig, '' ); dialogTitle = ( dialogTitle && 15 < dialogTitle.length ) ? dialogTitle.substring( 0, 15 ) + '...' : dialogTitle; dialogTitle = _.fusionUcFirst( dialogTitle ); } return dialogTitle; }, /** * Extendable function for when settings is opened. * * @since 2.0.0 * @return {void} */ onSettingsOpen: function() { }, /** * Extendable function for when settings is closed. * * @since 2.0.0 * @return {void} */ onSettingsClose: function() { var $dialog = jQuery( '.ui-dialog:not( .fusion-video-dialog ):not( .fusion-builder-preferences-dialog )' ).first(); // If there are opened dialogs which are resizable. if ( 0 < $dialog.length && ! jQuery( 'body' ).hasClass( 'fusion-settings-dialog-large' ) ) { // Change it's size. jQuery( $dialog ).css( 'width', FusionApp.dialog.dialogData.width + 'px' ); jQuery( $dialog ).css( 'height', FusionApp.dialog.dialogData.height + 'px' ); // Reposition it. jQuery( $dialog ).position( { my: FusionApp.dialog.dialogData.position.my, at: FusionApp.dialog.dialogData.position.at, of: window } ); } }, /** * Renders the content. * * @since 2.0.0 * @return {void} */ renderContent: function() { }, /** * Adds loading overlay while ajax is performing. * * @since 2.0.0 * @return {void} */ addLoadingOverlay: function() { var contentType = 'element', $elementContent; if ( _.isObject( this.model.attributes ) ) { if ( 'fusion_builder_container' === this.model.attributes.element_type ) { contentType = 'container'; } else if ( 'fusion_builder_column' === this.model.attributes.element_type ) { contentType = 'columns'; } } $elementContent = this.$el.find( '.fusion-builder-' + contentType + '-content' ); if ( ! $elementContent.hasClass( 'fusion-loader' ) ) { $elementContent.addClass( 'fusion-loader' ); $elementContent.append( '' ); } }, /** * Removes loading overlay after ajax is done. * * @since 3.5 * @return {void} */ removeLoadingOverlay: function() { var contentType = 'element', $elementContent; if ( _.isObject( this.model.attributes ) ) { if ( 'fusion_builder_container' === this.model.attributes.element_type ) { contentType = 'container'; } else if ( 'fusion_builder_column' === this.model.attributes.element_type ) { contentType = 'columns'; } } $elementContent = this.$el.find( '.fusion-builder-' + contentType + '-content' ); if ( $elementContent.hasClass( 'fusion-loader' ) ) { $elementContent.removeClass( 'fusion-loader' ); $elementContent.find( '.fusion-builder-loader' ).remove(); } }, /** * Removes an element. * * @since 2.0.0 * @param {Object} event - The event triggering the element removal. * @return {void} */ removeElement: function( event ) { var parentCid = this.model.get( 'parent' ); if ( event ) { event.preventDefault(); FusionEvents.trigger( 'fusion-content-changed' ); } // Remove element view FusionPageBuilderViewManager.removeView( this.model.get( 'cid' ) ); // Destroy element model this.model.destroy(); FusionEvents.trigger( 'fusion-element-removed', this.model.get( 'cid' ) ); // Update column trigger. this.triggerColumn( parentCid ); // Destroy dynamic param model. if ( this.dynamicParam ) { this.dynamicParam.destroy(); } this.remove(); }, /** * Opens the library. Builds the settings for this view * and then calls FusionPageBuilder.LibraryView and renders it. * * @since 2.0.0 * @param {Object} event - The js event. * @return {void} */ openLibrary: function( event ) { var view, libraryModel = { target: jQuery( event.currentTarget ).data( 'target' ), focus: jQuery( event.currentTarget ).data( 'focus' ), element_cid: this.model.get( 'cid' ), element_name: 'undefined' !== typeof this.model.get( 'admin_label' ) && '' !== this.model.get( 'admin_label' ) ? this.model.get( 'admin_label' ) : '' }, viewSettings = { model: libraryModel }; if ( event ) { event.preventDefault(); event.stopPropagation(); FusionPageBuilderApp.sizesHide( event ); } view = new FusionPageBuilder.LibraryView( viewSettings ); view.render(); // Make sure to close any context menus which may be open. FusionPageBuilderApp.removeContextMenu(); }, /** * Disable external links. * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ disableLink: function( event ) { if ( ! jQuery( event.target ).closest( '.fusion-builder-module-controls-container' ).length && 'lightbox' !== jQuery( event.currentTarget ).attr( 'target' ) ) { event.preventDefault(); if ( FusionApp.modifierActive && ! jQuery( event.target ).parent().hasClass( 'fusion-lightbox' ) ) { FusionApp.checkLink( event ); } } }, /** * Creates droppable zone and makes element draggable. * * @since 2.0.0 * @return {void} */ droppableElement: function() { var self = this, $el = this.$el, cid = this.model.get( 'cid' ), $body = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ); if ( ! $el ) { return; } if ( 'undefined' === typeof this.elementTarget || ! this.elementTarget.length ) { this.elementTarget = this.$el.find( '.fusion-element-target' ); } $el.draggable( { appendTo: FusionPageBuilderApp.$el, zIndex: 999999, delay: 100, cursorAt: { top: 15, left: 15 }, iframeScroll: true, containment: $body, cancel: '.fusion-live-editable, .fusion-builder-live-child-element:not( [data-fusion-no-dragging] ), .variations select, .awb-openstreet-map', helper: function() { var $classes = FusionPageBuilderApp.DraggableHelpers.draggableClasses( cid ); return jQuery( '

' ); }, start: function() { $body.addClass( 'fusion-element-dragging fusion-active-dragging' ); $el.addClass( 'fusion-being-dragged' ); $el.prev( '.fusion-builder-live-element' ).find( '.target-after' ).addClass( 'target-disabled' ); }, stop: function() { setTimeout( function() { $body.removeClass( 'fusion-element-dragging fusion-active-dragging' ); }, 10 ); $el.removeClass( 'fusion-being-dragged' ); FusionPageBuilderApp.$el.find( '.target-disabled' ).removeClass( 'target-disabled' ); } } ); this.elementTarget.droppable( { tolerance: 'touch', hoverClass: 'ui-droppable-active', accept: '.fusion-builder-live-element, .fusion_builder_row_inner', drop: function( event, ui ) { var handleDropElement = self.handleDropElement.bind( self ); handleDropElement( ui.draggable, $el, jQuery( event.target ) ); } } ); }, handleDropElement: function( $element, $targetEl, $dropTarget ) { var parentCid = $dropTarget.closest( '.fusion-builder-column' ).data( 'cid' ), columnView = FusionPageBuilderViewManager.getView( parentCid ), elementCid = $element.data( 'cid' ), elementView = FusionPageBuilderViewManager.getView( elementCid ), MultiGlobalArgs, newIndex; // Move the actual html. if ( $dropTarget.hasClass( 'target-after' ) ) { $targetEl.after( $element ); } else { $targetEl.before( $element ); } newIndex = $element.parent().children( '.fusion-builder-live-element, .fusion_builder_row_inner' ).index( $element ); FusionPageBuilderApp.onDropCollectionUpdate( elementView.model, newIndex, parentCid ); // Save history state FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.moved + ' ' + fusionAllElements[ elementView.model.get( 'element_type' ) ].name + ' ' + fusionBuilderText.element ); // Handle multiple global elements. MultiGlobalArgs = { currentModel: elementView.model, handleType: 'save', attributes: elementView.model.attributes }; fusionGlobalManager.handleMultiGlobal( MultiGlobalArgs ); FusionEvents.trigger( 'fusion-content-changed' ); columnView._equalHeights(); }, /** * Destroy or disable the droppable and draggable. * * @since 2.0.0 * @return {void} */ disableDroppableElement: function() { var $el = this.$el; // If its been init, just disable. if ( 'undefined' !== typeof $el.draggable( 'instance' ) ) { $el.draggable( 'disable' ); } // If its been init, just disable. if ( 'undefined' !== typeof this.elementTarget && this.elementTarget.length && 'undefined' !== typeof this.elementTarget.droppable( 'instance' ) ) { this.elementTarget.droppable( 'disable' ); } }, /** * Enable the droppable and draggable. * * @since 2.0.0 * @return {void} */ enableDroppableElement: function() { var $el = this.$el; // If they have been init, then just disable. if ( 'undefined' !== typeof $el.draggable( 'instance' ) && 'undefined' !== typeof this.elementTarget && this.elementTarget.length && 'undefined' !== typeof this.elementTarget.droppable( 'instance' ) ) { $el.draggable( 'enable' ); this.elementTarget.droppable( 'enable' ); } else { // No sign of init, then need to call it. this.droppableElement(); } }, /** * Gets edit label. * * @since 2.0.0 * @return {string} */ getEditLabel: function() { var editLabel = fusionBuilderText.element_settings, elementType = this.model.get( 'element_type' ); if ( 'undefined' !== typeof fusionAllElements[ elementType ] ) { editLabel = fusionBuilderText.custom_element_settings; editLabel = editLabel.replace( '%s', fusionAllElements[ elementType ].name ); } return editLabel; }, /** * Simple prevent default function. * * @since 2.0.0 * @param {Object} event - Click event object. * @return {void} */ preventDefault: function( event ) { event.preventDefault(); }, /** * Update element settings on drag (columns and containers). * * @since 2.0.0 * @param {string} selector - Selector of option. * @param {string} value - Value to update to. * @return {void} */ updateDragSettings: function( selector, value ) { var $option = jQuery( '[data-element-cid="' + this.model.get( 'cid' ) + '"] ' + selector ), $elementSettings, $section; if ( $option.length ) { $elementSettings = $option.closest( '.fusion_builder_module_settings' ); if ( ! $elementSettings.find( '.fusion-tabs-menu a[href="#design"]' ).parent().hasClass( 'current' ) ) { $elementSettings.find( '.fusion-tabs-menu a[href="#design"]' ).parent().trigger( 'click' ); } $section = $elementSettings.find( '.fusion-tabs-menu a[href="#design"]' ).closest( '.fusion-sidebar-section, .ui-dialog-content' ); $section.scrollTop( $option.position().top + $section.scrollTop() ); $option.val( value ).trigger( 'change' ); } }, baseInit: function() { var elementType = this.model.get( 'element_type' ); this.initialValue = {}; this.logHistory = {}; if ( 'string' === typeof elementType && -1 === jQuery.inArray( elementType, FusionPageBuilderApp.inlineElements ) ) { this.listenTo( FusionEvents, 'fusion-global-update-' + elementType, this.updateDefault ); this.listenTo( FusionEvents, 'fusion-extra-update-' + elementType, this.updateExtra ); } this.initDynamicParams(); }, initDynamicParams: function() { var self = this, params = this.model.get( 'params' ), dynamicData = params.dynamic_params; this.dynamicParams = new FusionPageBuilder.DynamicParams( { elementView: this } ); if ( 'string' === typeof params.dynamic_params && '' !== params.dynamic_params ) { try { if ( FusionPageBuilderApp.base64Encode( FusionPageBuilderApp.base64Decode( dynamicData ) ) === dynamicData ) { dynamicData = FusionPageBuilderApp.base64Decode( dynamicData ); dynamicData = _.unescape( dynamicData ); dynamicData = JSON.parse( dynamicData ); } self.dynamicParams.setData( dynamicData ); } catch ( error ) { console.log( error ); // jshint ignore:line } } }, /** * Check for element ajax callbacks and run them. * * @since 2.0.0 * @return {void} */ triggerAjaxCallbacks: function( skip ) { var self = this, AjaxCallbacks = {}, args = { skip: 'undefined' === typeof skip ? false : skip }; if ( 'undefined' !== typeof fusionAllElements[ this.model.get( 'element_type' ) ].has_ajax ) { // Collect callbacks. Do not fire the same action twice. _.each( fusionAllElements[ this.model.get( 'element_type' ) ].has_ajax, function( callback ) { AjaxCallbacks = {}; AjaxCallbacks[ callback.action ] = {}; AjaxCallbacks[ callback.action ][ 'function' ] = callback[ 'function' ]; AjaxCallbacks[ callback.action ].param_name = callback.param_name; AjaxCallbacks[ callback.action ].action = callback.action; } ); // Trigger ajax callbacks to populate query_data attribute _.each( AjaxCallbacks, function( callback ) { FusionApp.callback[ callback[ 'function' ] ]( callback.param_name, self.model.attributes.params[ callback.param_name ], self.model.attributes, args, self.model.get( 'cid' ), callback.action, self.model, self ); } ); } }, updateExtra: function() { this.reRender(); }, updateDefault: function( param, value ) { var modelData = jQuery.extend( this.model.attributes, {} ), reRender = true, callbackFunction = false, params = this.model.get( 'params' ); // Only re-render if actually using default. if ( ( 'undefined' === typeof params[ param ] || '' === params[ param ] || 'default' === params[ param ] ) && ! this.dynamicParams.hasDynamicParam( param ) ) { callbackFunction = FusionPageBuilderApp.getCallbackFunction( modelData, param, value, this, true ); callbackFunction.args = 'undefined' === typeof callbackFunction.args ? {} : callbackFunction.args; callbackFunction.args.skipRerender = false; if ( false !== callbackFunction && 'function' === typeof FusionApp.callback[ callbackFunction[ 'function' ] ] ) { reRender = this.doCallbackFunction( callbackFunction, false, param, value, modelData, true ); } if ( reRender ) { this.reRender(); } } }, historyUpdateParam: function( param, value ) { var modelData = jQuery.extend( this.model.attributes, {} ), reRender = true, callbackFunction = false; this.changeParam( param, value, false, true ); callbackFunction = FusionPageBuilderApp.getCallbackFunction( modelData, param, value, this, true ); if ( false !== callbackFunction && 'function' === typeof FusionApp.callback[ callbackFunction[ 'function' ] ] ) { reRender = this.doCallbackFunction( callbackFunction, false, param, value, modelData, true ); } if ( reRender ) { this.reRender(); } }, updateParam: function( param, value, event ) { var modelData = jQuery.extend( this.model.attributes, {} ), reRender = true, callbackFunction = FusionPageBuilderApp.getCallbackFunction( modelData, param, value, this ); if ( false !== callbackFunction && 'function' === typeof FusionApp.callback[ callbackFunction[ 'function' ] ] ) { reRender = this.doCallbackFunction( callbackFunction, event, param, value, modelData ); } else { this.changeParam( param, value ); } return reRender; }, setInitialValue: function( param ) { if ( 'undefined' !== typeof this.initialValue && 'undefined' === typeof this.initialValue[ param ] && 'undefined' !== typeof param ) { this.initialValue[ param ] = 'undefined' !== typeof this.model.get( 'params' )[ param ] ? this.model.get( 'params' )[ param ] : ''; } }, logChangeEvent: function( param, value, label ) { this.logHistory._param = this.logHistory._param || {}; if ( ! ( param in this.logHistory._param ) ) { this.logHistory._param[ param ] = _.debounce( _.bind( function( param, value, label ) { var state = { type: 'param', param: param, newValue: value, cid: this.model.get( 'cid' ) }, elementMap = fusionAllElements[ this.model.get( 'element_type' ) ], paramObject = elementMap.params[ param ], paramTitle = 'object' === typeof paramObject ? paramObject.heading : param; if ( 'undefined' !== typeof label ) { paramTitle = label; } else if ( 'object' !== typeof paramObject && jQuery( '.multi-builder-dimension #' + param ).length ) { paramObject = elementMap.params[ jQuery( '.multi-builder-dimension #' + param ).closest( '.multi-builder-dimension' ).attr( 'id' ) ]; if ( 'object' === typeof paramObject && 'string' === typeof paramObject.heading ) { paramTitle = paramObject.heading; } } else if ( 'object' !== typeof paramObject && jQuery( '.font_family #' + param ).length ) { paramObject = elementMap.params[ jQuery( '.font_family #' + param ).closest( '.fusion-builder-option' ).attr( 'data-option-id' ) ]; if ( 'object' === typeof paramObject && 'string' === typeof paramObject.heading ) { paramTitle = paramObject.heading; } } else if ( 'object' !== typeof paramObject && jQuery( '.typography [name="' + param + '"]' ).length ) { paramObject = elementMap.params[ jQuery( '.typography [name="' + param + '"]' ).closest( '.fusion-builder-option' ).attr( 'data-option-id' ) ]; if ( 'object' === typeof paramObject && 'string' === typeof paramObject.heading ) { paramTitle = paramObject.heading; } } state.oldValue = this.initialValue[ param ]; delete this.initialValue[ param ]; this.model.trigger( 'change' ); FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.edited + ' ' + elementMap.name + ' - ' + paramTitle, state ); }, this ), 500 ); } this.logHistory._param[ param ]( param, value, label ); }, changeParam: function( param, value, label, silent ) { var parentView; if ( ! silent && ! this.model.get( 'inlineElement' ) ) { this.setInitialValue( param ); this.model.attributes.params[ param ] = value; // Update parent after param has been changed. if ( 'multi_element_child' === this.model.get( 'multi' ) ) { parentView = FusionPageBuilderViewManager.getView( this.model.get( 'parent' ) ); if ( parentView && 'function' === typeof parentView.updateElementContent ) { parentView.updateElementContent(); } } this.logChangeEvent( param, value, label ); } else { this.model.attributes.params[ param ] = value; } if ( 'function' === typeof this.updateInlineParams && 'fusion_builder_form_step' === this.model.get( 'element_type' ) ) { this.updateInlineParams( param, value ); } }, /** * Gets callback function for option change. * * @since 2.0.0 * @return {void} */ doCallbackFunction: function( callbackFunction, event, paramName, paramValue, modelData, skipChange ) { var reRender = true, returnData; callbackFunction.args = 'undefined' === typeof callbackFunction.args ? {} : callbackFunction.args; callbackFunction.ajax = 'undefined' === typeof callbackFunction.ajax ? false : callbackFunction.ajax; callbackFunction.action = 'undefined' === typeof callbackFunction.action ? false : callbackFunction.action; skipChange = 'undefined' === typeof skipChange ? false : skipChange; // If skip is set then param will not be changed. callbackFunction.args.skip = skipChange; // If ajax trigger via debounce, else do it here and retun data. if ( callbackFunction.ajax ) { reRender = false; this.addLoadingOverlay(); this._triggerCallback( event, callbackFunction, paramName, paramValue, modelData.cid, modelData ); } else { returnData = FusionApp.callback[ callbackFunction[ 'function' ] ]( paramName, paramValue, callbackFunction.args, this ); } if ( 'undefined' !== typeof returnData && 'undefined' !== typeof returnData.render ) { reRender = returnData.render; } return reRender; }, /** * Triggers a callback function. * * @since 2.0.0 * @param {Object} event - The event. * @param {string|Object} callbackFunction - The callback function. * @return {void} */ triggerCallback: function( event, callbackFunction, paramName, paramValue, cid, modelData ) { if ( 'undefined' === typeof cid && 'undefined' !== typeof callbackFunction.cid ) { cid = callbackFunction.cid; } if ( 'undefined' === typeof modelData ) { modelData = jQuery.extend( this.model.attributes, {} ); } // This is added due to the new elements causing max call stack. Not sure why but it shouldn't be necessary in any case. if ( 'undefined' !== typeof modelData ) { delete modelData.view; } if ( 'fusion_do_shortcode' !== callbackFunction[ 'function' ] ) { FusionApp.callback[ callbackFunction[ 'function' ] ]( paramName, paramValue, modelData, callbackFunction.args, cid, callbackFunction.action, this.model, this ); } else { FusionApp.callback[ callbackFunction[ 'function' ] ]( cid, callbackFunction.content, callbackFunction.parent ); } }, addCssProperty: function ( selectors, property, value, important ) { if ( 'object' === typeof selectors ) { selectors = Object.values( selectors ); } if ( 'object' === typeof selectors ) { selectors = selectors.join( ',' ); } if ( 'object' !== typeof this.dynamic_css[ selectors ] ) { this.dynamic_css[ selectors ] = {}; } if ( 'undefined' !== typeof important && important ) { value += ' !important'; } if ( 'undefined' === typeof this.dynamic_css[ selectors ][ property ] || ( 'undefined' !== typeof important && important ) || ! this.dynamic_css[ selectors ][ property ].includes( 'important' ) ) { this.dynamic_css[ selectors ][ property ] = value; } }, /** * Get a string with each of the option as a CSS variable, if the option is not default. * * @since 3.9 * @param {array} options The array with the options ids. * @return {string} */ getCssVarsForOptions( options ) { var css = '', varName, value, callback_args, key; for ( key in options ) { if ( ! options.hasOwnProperty( key ) || 'length' === key ) { continue; // eslint-disable-line no-continue } value = options[ key ]; if ( 'object' === typeof value ) { // If the value is an array, then the CSS var name is the key. if ( ! this.isDefault( key ) ) { varName = '--awb-' + key.replaceAll( '_', '-' ); callback_args = ( 'object' === typeof value.args ? value.args : [ this.values[ key ] ] ); css += varName + ':' + value.callback.apply( null, callback_args ) + ';'; } } else { if ( ! this.isDefault( value ) ) { // eslint-disable-line no-lonely-if varName = '--awb-' + value.replaceAll( '_', '-' ); css += varName + ':' + this.values[ value ] + ';'; } } } return css; }, /** * Get a string with custom CSS variables, created from array key => value pairs. * * @since 3.9 * @param {Object} $options The object with the custom css vars. The property * represents the option name, while the value represents the custom value. * @return {string} */ getCustomCssVars( options, prefix ) { var css = '', varName, property; if ( 'undefined' === typeof prefix ) { prefix = true; } for ( property in options ) { if ( ! options.hasOwnProperty( property ) ) { continue; // eslint-disable-line no-continue } if ( prefix ) { varName = '--awb-' + property.replaceAll( '_', '-' ); } else { varName = '--' + property; } css += varName + ':' + options[ property ] + ';'; } return css; }, /** * Get declaration for typography vars with the given values. * * @since 3.9 * @param {string} titleTag An HTML tag, Ex: 'h2', 'h3', 'div'.. etc. * @param {Object} nameValueMap The key is a css property, the array value is the CSS value. * @return string */ getHeadingFontVars( titleTag, nameValueMap ) { var varPrefix = '', cssProp, style = ''; if ( [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ].includes( titleTag ) ) { varPrefix = '--' + titleTag + '_typography-'; } else if ( 'div' === titleTag || 'p' === titleTag ) { varPrefix = '--body_typography-'; } else { return style; } for ( cssProp in nameValueMap ) { if ( nameValueMap[ cssProp ] && '' !== nameValueMap[ cssProp ] ) { style += varPrefix + cssProp + ':' + nameValueMap[ cssProp ] + ';'; } } return style; }, /** * Get a string with all the border radius CSS variables. * @since 3.9 * @param {array} options The array with the options ids. * @return {string} */ getBorderRadiusVars( options ) { var style = '', varName, edges = { 'border_radius_top_left': 'border-top-left-radius', 'border_radius_top_right': 'border-top-right-radius', 'border_radius_bottom_left': 'border-bottom-left-radius', 'border_radius_bottom_right': 'border-bottom-right-radius' }; for ( varName in edges ) { if ( options.hasOwnProperty( varName ) && '' !== options[ varName ] ) { style += '--awb-' + edges[ varName ] + ':' + options[ varName ] + ';'; } } return style; }, isDefault: function( param ) { return this.values[ param ] === fusionAllElements[ this.model.get( 'element_type' ) ].defaults[ param ]; }, /** * Get font styling vars, created from _.fusionGetFontStyle helper. * * @since 3.9 * @param string key typography options key. * @param object values the values object. * @return string */ getFontStylingVars( key, values ) { let css = ''; const font_styles = _.fusionGetFontStyle( key, values, 'object' ); Object.keys( font_styles ).forEach( ( rule ) => { const value = font_styles[ rule ]; key = key.replace( '_font', '' ); let name = key + '-' + rule; name = name.replaceAll( '_', '-' ); css += `--awb-${name}: ${value};`; } ); return css; }, /** * Get aspect ratio vars. * * @since 3.9 * @param object values the values object. * @return string */ getAspectRatioVars( values ) { if ( '' === values.aspect_ratio ) { return ''; } let css = ''; // Calc Ratio if ( 'custom' === values.aspect_ratio && '' !== values.custom_aspect_ratio ) { css += '--awb-aspect-ratio: 100 / ' + values.custom_aspect_ratio + ';'; } else { const aspectRatio = values.aspect_ratio.split( '-' ), width = aspectRatio[ 0 ] || '', height = aspectRatio[ 1 ] || ''; css += `--awb-aspect-ratio: ${width / height};`; } //Ratio Position if ( '' !== values.aspect_ratio_position ) { css += '--awb-object-position:' + values.aspect_ratio_position + ';'; } return css; }, /** * Check if parent using dynamic content. * * @since 3.11 * @param object values the values object. * @return string */ isParentHasDynamicContent( values ) { if ( values.dynamic_params ) { let dynamicData = FusionPageBuilderApp.base64Decode( values.dynamic_params ); dynamicData = _.unescape( dynamicData ); dynamicData = JSON.parse( dynamicData ); return dynamicData.parent_dynamic_content ? true : false; } return false; }, parseCSS: function () { var css = ''; if ( 'object' !== typeof this.dynamic_css ) { return ''; } _.each( this.dynamic_css, function ( properties, selector ) { if ( 'object' === typeof properties ) { css += selector + '{'; _.each( properties, function ( value, property ) { css += property + ':' + value + ';'; } ); css += '}'; } } ); return css; }, // Scroll to element and highlight it. scrollHighlight: function( scroll = true, highlight = true ) { var $trigger = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '.fusion-one-page-text-link' ), $el = this.$el, elementIdAdded = false, $highlightedEl, elId = $el.attr( 'id' ); scroll = 'undefined' === typeof scroll ? true : scroll; if ( ! elId ) { $el.attr( 'id', 'fusion-temporary-id-' + this.cid ); elId = 'fusion-temporary-id-' + this.cid; elementIdAdded = true; } setTimeout( function() { if ( scroll && $trigger.length && 'function' === typeof $trigger.fusion_scroll_to_anchor_target ) { $trigger.attr( 'href', '#' + elId ).fusion_scroll_to_anchor_target( 15 ); } if ( elementIdAdded ) { setTimeout( function() { $el.removeAttr( 'id' ); }, 10 ); } if ( highlight ) { $highlightedEl = $el; // This is intended to be only for columns. if ( $el.find( '> .fusion-column-wrapper' ).length ) { $highlightedEl = $el.find( '> .fusion-column-wrapper' ); } $highlightedEl.addClass( 'fusion-active-highlight' ); setTimeout( function() { $highlightedEl.removeClass( 'fusion-active-highlight' ); }, 6000 ); } }, 10 ); }, isString( s ) { if ( 'string' === typeof s || s instanceof String ) { return true; } return false; } } ); } ); }( jQuery ) ); ;/* global FusionPageBuilderViewManager, FusionPageBuilderApp, FusionApp, FusionEvents, fusionBuilderText */ /* eslint no-shadow: 0 */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Builder Row View FusionPageBuilder.BaseRowView = window.wp.Backbone.View.extend( { /** * On init for both regular and nested columns. * * @since 3.0 * @return null */ baseRowInit: function() { this._updateResponsiveColumnsOrder = _.debounce( this.updateResponsiveColumnsOrder, 100 ); }, reRender: function() { this.render( true ); }, /** * Calculate virtual rows. * * @since 2.0.0 * @return {null} */ createVirtualRows: function() { var container = FusionPageBuilderApp.getParentContainer( this.model.get( 'parent' ) ); // If we are flex, no need for virtual rows. if ( 'function' === typeof container.isFlex && container.isFlex() ) { return; } this.updateVirtualRows(); this.assignColumn(); }, /** * Set the initial column data to the model. * * @since 2.0.0 * @return {void} */ updateVirtualRows: function() { var rows = {}, column = {}, columns = [], count = 0, index = 0, oldRows = this.model.get( 'rows' ), columnWidth; this.model.children.each( function( child ) { column = {}; columnWidth = child.attributes.params.type; if ( ! columnWidth ) { columnWidth = '1_1'; } columnWidth = columnWidth.split( '_' ); columnWidth = columnWidth[ 0 ] / columnWidth[ 1 ]; count += columnWidth; if ( 1 < count ) { index += 1; count = columnWidth; } column = { cid: child.attributes.cid }; if ( 'undefined' === typeof rows[ index ] ) { rows[ index ] = [ column ]; } else { rows[ index ].push( column ); } columns[ child.attributes.cid ] = index; } ); this.model.set( 'columns', columns ); this.model.set( 'rows', rows ); if ( 'object' === typeof oldRows ) { this.model.set( 'oldRows', oldRows ); } }, /** * Change the column in the model. * * @since 2.0.0 * @param {Object} column - The column view. * @return {void} */ assignColumn: function() { var columnParams, self = this, oldRows = this.model.get( 'oldRows' ), updatedCols = false, emptySpacing = true; // Reset first, last positions this.model.children.each( function( column ) { columnParams = jQuery.extend( true, {}, column.get( 'params' ) ); columnParams.first = false; columnParams.last = false; column.set( 'params', columnParams ); } ); // Loop over virtual rows _.each( this.model.get( 'rows' ), function( row, rowIndex ) { var total = row.length, lastIndex = total - 1, rowSame = true, previousSpacing = ''; // Loop over columns inside virtual row _.each( row, function( col, colIndex ) { var columnFirst = false, columnLast = false, model = self.model.children.find( function( model ) { return model.get( 'cid' ) == col.cid; // jshint ignore: line } ), params = jQuery.extend( true, {}, model.get( 'params' ) ), spacing, weightedSpacing; // First index if ( 0 === colIndex ) { columnFirst = true; } if ( lastIndex === colIndex ) { columnLast = true; } params.first = columnFirst; params.last = columnLast; // Check if we need legacy column spacing set. if ( 'undefined' !== typeof params.spacing && FusionPageBuilderApp.loaded ) { spacing = params.spacing; if ( 'yes' === spacing ) { spacing = '4%'; } else if ( 'no' === spacing ) { spacing = '0px'; } if ( ! params.last && '0px' !== spacing && 0 !== spacing && '0' !== spacing ) { emptySpacing = false; } weightedSpacing = self.getWeightedSpacing( spacing, params, total ); // Only set params if both are unset. if ( 'undefined' === typeof params.spacing_left && 'undefined' === typeof params.spacing_right ) { // Use what is set as right spacing. if ( ! params.last ) { params.spacing_right = weightedSpacing; } // Check right spacing of previous column. if ( '' !== previousSpacing ) { params.spacing_left = self.getWeightedSpacing( previousSpacing, params, total ); } } previousSpacing = spacing; } else { emptySpacing = false; } model.set( 'params', params ); // Check if col is same as before. if ( rowSame ) { if ( 'object' !== typeof oldRows || 'undefined' === typeof oldRows[ rowIndex ] || 'undefined' === typeof oldRows[ rowIndex ][ colIndex ] || oldRows[ rowIndex ][ colIndex ].cid !== col.cid ) { rowSame = false; } } } ); if ( ! rowSame && FusionPageBuilderApp.loaded ) { if ( false === updatedCols ) { updatedCols = []; } _.each( row, function( col ) { updatedCols.push( col.cid ); } ); } } ); this.model.set( 'emptySpacing', emptySpacing ); this.model.set( 'updatedCols', updatedCols ); }, getVirtualRowByCID: function( cid ) { var rows = this.model.get( 'rows' ), columns = this.model.get( 'columns' ), index = columns[ cid ], row = rows[ index ]; return row; }, /** * First render, work out legacy column map only once. * * @since 2.0.0 * @return {Object} this */ legacyColumns: function() { var container = FusionPageBuilderApp.getParentContainer( this.model.get( 'parent' ) ), emptySpacing = false, nestedRows = {}; // If we are not in need of legacy conversion then skip. if ( ! container || ! container.needsLegacyConversion() ) { return; } // Create map of row to get correct spacing. this.updateVirtualRows(); this.assignColumn(); if ( ! this.nestedRow ) { // This row is all empty spacing. emptySpacing = this.model.get( 'emptySpacing' ); // Run through same process for nested rows. this.$el.find( '.fusion-builder-row-inner' ).each( function() { var nestedRowCid = jQuery( this ).attr( 'data-cid' ), nestedView = FusionPageBuilderViewManager.getView( nestedRowCid ); // Store for later looping if necessary. nestedRows[ nestedRowCid ] = nestedView; // Update legacy maps and nested column styles. nestedView.legacyColumns(); // If nested row is not empty spacing, parent row shouldn't be also. if ( false === nestedView.model.get( 'emptySpacing' ) ) { emptySpacing = false; } } ); // If its empty spacing and all nested rows also, we will set spacing on container and re-render. if ( emptySpacing ) { // Set the spacing on container. container = FusionPageBuilderApp.getParentContainer( this.model.get( 'parent' ) ); if ( container ) { container.setEmptySpacing(); } // If we have nested rows, update them visually. if ( 'object' === typeof nestedRows && ! _.isEmpty( nestedRows ) ) { _.each( nestedRows, function( nestedRow ) { nestedRow.recalculateMargins(); } ); } // Update parent row visually. this.recalculateMargins(); } } // Update visual appearance for direct children columns. this.model.children.each( function( child ) { var view = FusionPageBuilderViewManager.getView( child.attributes.cid ); view.setArgs(); view.validateArgs(); view.setExtraArgs(); view.setColumnMapData(); view.setResponsiveColumnStyles(); view.$el.find( '.fusion-column-responsive-styles' ).last().html( view.responsiveStyles ); } ); // Set param on container to stop it rerunning. if ( container && 'function' === typeof container.setType ) { container.setType(); } }, getHalfSpacing: function( value ) { var unitlessSpacing = parseFloat( value ), unitlessHalf = unitlessSpacing / 2; return value.replace( unitlessSpacing, unitlessHalf ); }, validateColumnWidth: function( columnSize ) { var fractions; if ( 'undefined' === typeof columnSize ) { columnSize = '1_3'; } // Fractional value. if ( -1 !== columnSize.indexOf( '_' ) ) { fractions = columnSize.split( '_' ); return parseFloat( fractions[ 0 ] ) / parseFloat( fractions[ 1 ] ); } // Greater than one, assume percentage and divide by 100. if ( 1 < parseFloat( columnSize ) ) { return parseFloat( columnSize ) / 100; } return columnSize; }, getWeightedSpacing: function( value, params, total ) { var width = parseFloat( this.validateColumnWidth( params.type ) ), unitlessSpacing = parseFloat( value ), unitlessWeighted; total = 'undefined' === typeof total || false === total ? false : parseInt( total ); if ( false !== total && 3 > total ) { unitlessWeighted = unitlessSpacing * width; } else { unitlessWeighted = unitlessSpacing / 2; } return value.replace( unitlessSpacing, unitlessWeighted ); }, updateColumnsPreview: function() { var container = FusionPageBuilderApp.getParentContainer( this.model.get( 'parent' ) ), updatedCols = this.model.get( 'updatedCols' ), self = this; // Update flex column preview here. if ( 'function' === typeof container.isFlex && container.isFlex() ) { return; } if ( true === FusionPageBuilderApp.loaded ) { this.model.children.each( function( child ) { var view, singleRow, columnRow; if ( false === updatedCols || _.contains( updatedCols, child.attributes.cid ) ) { view = FusionPageBuilderViewManager.getView( child.attributes.cid ); singleRow = self.getVirtualRowByCID( view.model.get( 'cid' ) ); columnRow = []; // Update first/last classes view.$el.removeClass( 'fusion-column-last' ); view.$el.removeClass( 'fusion-column-first' ); if ( true === view.model.attributes.params.last ) { view.$el.addClass( 'fusion-column-last' ); } if ( true === view.model.attributes.params.first ) { view.$el.addClass( 'fusion-column-first' ); } // Update column spacing. _.each( singleRow, function( cid ) { var model, value; cid = cid.cid; model = self.collection.find( function( model ) { return model.get( 'cid' ) == cid; // jshint ignore: line } ); value = model.attributes.params.spacing; columnRow.push( value ); } ); view.columnSpacingPreview( columnRow ); } } ); } }, /** * Sets the row data. * * @since 2.0.0 * @return {void} */ setRowData: function() { this.createVirtualRows(); this.updateColumnsPreview(); }, setSingleRowData: function( cid ) { var row = this.getVirtualRowByCID( cid ), view; _.each( row, function( column ) { view = FusionPageBuilderViewManager.getView( column.cid ); view.reRender(); } ); }, /** * Mode change for container. * * @since 3.0 * @return {void} */ modeChange: function() { this.setRowData(); this.reRender( true ); this.reRenderColumns(); // Refresh nested rows if they exist. if ( ! this.nestedRow ) { this.reRenderNestedRows(); } }, /** * Mode change for container. * * @since 3.0 * @return {void} */ updateInnerStyles: function() { this.setRowData(); this.reRender( true ); if ( this.nestedRow ) { this.appendChildren( false ); } this.model.children.each( function( child ) { var cid = child.attributes.cid; var column = FusionPageBuilderViewManager.getView( cid ); if ( column ) { column.updateInnerStyles(); } } ); // Refresh nested rows if they exist. if ( ! this.nestedRow ) { this.$el.find( '.fusion_builder_row_inner' ).each( function( ) { var cid = jQuery( this ).attr( 'data-cid' ), row = FusionPageBuilderViewManager.getView( cid ); if ( row ) { row.updateInnerStyles(); } } ); } this.delegateChildEvents(); }, /** * Re-render the nested rows. * * @since 3.0 * @return {void} */ reRenderNestedRows: function() { this.$el.find( '.fusion_builder_row_inner' ).each( function( ) { var cid = jQuery( this ).attr( 'data-cid' ), row = FusionPageBuilderViewManager.getView( cid ); if ( 'object' === typeof row ) { row.modeChange(); row.appendChildren(); } } ); }, /** * Re-render columns * * @since 3.0 * @return {void} */ reRenderColumns: function() { var cid, view; this.model.children.each( function( child ) { cid = child.attributes.cid; view = FusionPageBuilderViewManager.getView( cid ); if ( view ) { view.reRender(); } } ); }, /** * Updates columns' order params. * @return {void} */ updateResponsiveColumnsOrder: function( draggedColumn, columns, targetColumnCID, insertAfterTargetColumn ) { var viewportSize = FusionApp.getPreviewWindowSize(), draggedColumnCID = parseInt( draggedColumn.data( 'cid' ) ), draggedColumnOrder = parseInt( draggedColumn.css( 'order' ) ), columnsArray = [], index = 0, columnView; if ( 'large' === viewportSize ) { return; } jQuery( columns ).each( function( scopedIndex, column ) { // TODO: handle case when multiple columns have same order set. if ( draggedColumnCID !== jQuery( column ).data( 'cid' ) ) { columnsArray.push( [ parseInt( jQuery( column ).data( 'cid' ) ), parseInt( jQuery( column ).css( 'order' ) ) ] ); } } ); // Sort columns by CSS order. columnsArray.sort( function( col1, col2 ) { return col1[ 1 ] - col2[ 1 ]; } ); // Find index (position) of target column. for ( index = 0; index < columnsArray.length; index++ ) { if ( targetColumnCID === columnsArray[ index ][ 0 ] ) { break; } } // In case we're inserting before target column. if ( ! insertAfterTargetColumn ) { index--; } // Insert dragged column in it's place. Note that index is position in 'splice' context (not array index). columnsArray.splice( index + 1, 0, [ draggedColumnCID, draggedColumnOrder ] ); // Index is not longer relevant, using it just as iterator. for ( index = 0; index < columnsArray.length; index++ ) { // Get column view by CID. columnView = FusionPageBuilderViewManager.getView( columnsArray[ index ][ 0 ] ); // Update order param and value. columnView.model.attributes.params[ 'order_' + viewportSize ] = index; columnView.values[ 'order_' + viewportSize ] = index; // Update column's responsive styles. columnView.setResponsiveColumnStyles(); columnView.$el.find( '.fusion-column-responsive-styles' ).last().html( columnView.responsiveStyles ); // Update EO panel if opened. if ( jQuery( '.fusion-builder-module-settings[data-element-cid="' + columnsArray[ index ][ 0 ] + '"' ) ) { FusionEvents.trigger( 'fusion-param-changed-' + columnView.model.get( 'cid' ), 'order_' + viewportSize, index ); } } // Trigger change and add history event. FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.column + ' Order Changed' ); }, scrollHighlight: function( scroll = true, highlight = true ) { var $trigger = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '.fusion-one-page-text-link' ), $el = this.$el, elementIdAdded = false, elId = $el.attr( 'id' ); scroll = 'undefined' === typeof scroll ? true : scroll; if ( ! elId ) { $el.attr( 'id', 'fusion-temporary-id-' + this.cid ); elId = 'fusion-temporary-id-' + this.cid; elementIdAdded = true; } setTimeout( function() { if ( scroll && $trigger.length && 'function' === typeof $trigger.fusion_scroll_to_anchor_target ) { $trigger.attr( 'href', '#' + elId ).fusion_scroll_to_anchor_target( 15 ); } if ( elementIdAdded ) { setTimeout( function() { $el.removeAttr( 'id' ); }, 10 ); } if ( highlight ) { $el.addClass( 'fusion-active-highlight' ); setTimeout( function() { $el.removeClass( 'fusion-active-highlight' ); }, 6000 ); } }, 10 ); } } ); } ); }( jQuery ) ); ;/* global FusionApp, fusionBuilderText, fusionAllElements, cssua, FusionPageBuilderViewManager, FusionPageBuilderApp, FusionEvents, fusionSettings */ /* eslint no-unused-vars: 0 */ /* eslint no-shadow: 0 */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Nested Column View FusionPageBuilder.BaseColumnView = FusionPageBuilder.BaseView.extend( { /** * On init for both regular and nested columns. * * @since 3.0 * @return null */ baseColumnInit: function() { this.model.children = new FusionPageBuilder.Collection(); this.listenTo( FusionEvents, 'fusion-param-changed-' + this.model.get( 'cid' ), this.onOptionChange ); this.listenTo( this.model.children, 'add', this.addChildView ); // Responsive control updates on resize. this.listenTo( FusionEvents, 'fusion-preview-viewport-update', this.onPreviewResize ); this._triggerCallback = _.debounce( _.bind( this.triggerCallback, this ), 200 ); this._toolTipHide = _.debounce( _.bind( this.toolTipHide, this ), 500 ); this._refreshJs = _.debounce( _.bind( this.refreshJs, this ), 300 ); this._equalHeights = _.debounce( _.bind( this.equalHeights, this ), 300 ); this.deprecatedParams(); // Hold the DOM elements for resizables. this.marginResize = {}; this.paddingResize = {}; }, /** * Runs before view DOM is patched. * * @since 2.0.0 * @return null */ beforePatch: function() {}, // eslint-disable-line no-empty-function /** * Runs after view DOM is patched. * * @since 2.0.0 * @return null */ afterPatch: function() { var self = this; if ( 'undefined' !== typeof this.model.attributes.selectors ) { if ( this.model.get( 'dragging' ) ) { this.model.attributes.selectors.style += ';display: none;'; this.model.attributes.selectors[ 'class' ] += ' ignore-me-column'; } this.$el.removeAttr( 'data-animationType' ); this.$el.removeAttr( 'data-animationDuration' ); this.$el.removeAttr( 'data-animationOffset' ); this.setElementAttributes( this.$el, this.model.attributes.selectors ); } if ( this.forceAppendChildren ) { this.appendChildren(); this.forceAppendChildren = false; } setTimeout( function() { self.droppableColumn(); }, 300 ); this._refreshJs(); }, /** * Delegates multiple child elements. * * @since 2.0.0 * @return {void} */ delegateChildEvents: function() { var cid, view; this.model.children.each( function( child ) { cid = child.attributes.cid; view = FusionPageBuilderViewManager.getView( cid ); view.delegateEvents(); // Re init for elements. if ( 'function' === typeof view.droppableElement ) { view.droppableElement(); } // Re init for nested row. if ( 'function' === typeof view.droppableColumn ) { view.droppableColumn(); } // Multi elements if ( 'undefined' !== typeof view.model.get( 'multi' ) && 'multi_element_parent' === view.model.get( 'multi' ) ) { view.delegateChildEvents(); view.sortableChildren(); } } ); }, updateInnerStyles: function() { this.setArgs(); this.validateArgs(); this.setExtraArgs(); this.setColumnMapData(); this.setResponsiveColumnStyles(); this.$el.find( '.fusion-column-responsive-styles' ).last().html( this.responsiveStyles ); const attr = this.buildAttr(); this.$el.attr( 'style', attr.style ); this.delegateChildEvents(); }, /** * Checks if the width is custom. * * @since 2.1 * @return {bool} */ isCustomWidth: function ( width ) { if ( 'string' === typeof width && ( width.includes( 'px' ) || width.includes( 'calc' ) ) ) { return true; } return false; }, /** * Updates now deprecated params and adds BC checks. * * @since 2.1 * @return {void} */ deprecatedParams: function() { var params = this.model.get( 'params' ), alphaBackgroundColor = 1, radiaDirectionsNew = { 'bottom': 'center bottom', 'bottom center': 'center bottom', 'left': 'left center', 'right': 'right center', 'top': 'center top', 'center': 'center center', 'center left': 'left center' }, borderSize; // Correct radial direction params. if ( 'undefined' !== typeof params.radial_direction && ( params.radial_direction in radiaDirectionsNew ) ) { params.radial_direction = radiaDirectionsNew[ params.radial_direction ]; } // No align self set but ignore equal heights is on. if ( 'undefined' === typeof params.align_self && 'undefined' !== typeof params.min_height && 'none' === params.min_height ) { params.align_self = 'flex-start'; } // No align content set, but legacy center_content is on. if ( 'undefined' === typeof params.align_content && 'undefined' !== typeof params.center_content && 'yes' === params.center_content ) { params.align_content = 'center'; } // Border sizes. if ( ( 'undefined' === typeof params.border_sizes_top || 'undefined' === typeof params.border_sizes_bottom || 'undefined' === typeof params.border_sizes_left || 'undefined' === typeof params.border_sizes_right ) && 'string' === typeof params.border_size ) { if ( 'all' === params.border_position ) { borderSize = _.fusionGetValueWithUnit( params.border_size ); params.border_sizes_top = borderSize; params.border_sizes_bottom = borderSize; params.border_sizes_left = borderSize; params.border_sizes_right = borderSize; } else { params[ 'border_sizes_' + params.border_position ] = _.fusionGetValueWithUnit( params.border_size ); } delete params.border_size; } this.model.set( 'params', params ); }, /** * Handle margin adjustments on drag. * * @since 2.0.0 * @return {void} */ marginDrag: function() { var $el = this.$el, self = this, directions = { top: 's', bottom: 's' }, parentWidth = 'fusion_builder_column_inner' === this.model.get( 'type' ) ? $el.closest( '.fusion-builder-row-container-inner' ).width() : $el.closest( '.fusion-row' ).width(), isFlex = false, widthType = self.getVisibleWidth(), $spacers = this.$el.find( '> .fusion-column-wrapper > .fusion-column-spacers, > .fusion-column-margins' ); // If flex we also use left and right. if ( 'undefined' !== typeof this.isFlex && true === this.isFlex ) { directions = { top: 's', bottom: 's', left: 'e', right: 'w' }; isFlex = true; } // If class is set, do not init again. if ( this.$el.hasClass( 'resizable-active' ) ) { return; } // Single post card, margin is not used. if ( 'fusion_builder_column_inner' !== this.model.get( 'type' ) && 'post_cards' === FusionApp.data.fusion_element_type ) { return; } _.each( directions, function( handle, direction ) { var optionKey = FusionApp.getResponsiveOptionKey( 'top' === direction || 'bottom' === direction ? 'margin_' + direction : 'spacing_' + direction, self.isFlex ), actualDimension = self.values[ optionKey ], percentSpacing = false; // No value, use half column spacing (not upsized). if ( isFlex && ( ! actualDimension || '' === actualDimension ) && ( 'top' === direction || 'bottom' === direction ) ) { if ( self.values[ 'margin_' + direction ] ) { actualDimension = self.values[ 'margin_' + direction ]; } if ( optionKey.includes( 'small' ) && '' !== self.values[ 'margin_' + direction + '_medium' ] ) { actualDimension = self.values[ 'margin_' + direction + '_medium' ]; } } if ( ! actualDimension ) { actualDimension = self.getHalfSpacing(); } // Check if using a percentage. percentSpacing = -1 !== actualDimension.indexOf( '%' ); // If percentage, get the actual px dimension. if ( percentSpacing ) { actualDimension = ( parentWidth / 100 ) * parseFloat( actualDimension ); } // Overlap checks. if ( 'bottom' === direction ) { if ( 20 > parseInt( actualDimension, 10 ) ) { $spacers.find( '.fusion-column-margin-bottom, .fusion-column-padding-bottom' ).addClass( 'fusion-overlap' ); } else { $spacers.find( '.fusion-column-margin-bottom, .fusion-column-padding-bottom' ).removeClass( 'fusion-overlap' ); } } // Find element and display it. self.marginResize[ direction ] = $spacers.find( '.fusion-column-margin-' + direction ); self.marginResize[ direction ].css( 'display', 'block' ); // Set initial width or height. if ( 'left' === direction || 'right' === direction ) { if ( percentSpacing && 'custom' === widthType ) { self.marginResize[ direction ].width( 0 ); } else { self.marginResize[ direction ].width( actualDimension ); } } else { self.marginResize[ direction ].height( actualDimension ); } // Init resizable. self.marginResize[ direction ].resizable( { handles: handle, minHeight: 0, minWidth: 0, grid: ( percentSpacing ) ? [ parentWidth / 1000, 10 ] : '', resize: function( event, ui ) { var optionKey = FusionApp.getResponsiveOptionKey( 'top' === direction || 'bottom' === direction ? 'margin_' + direction : 'spacing_' + direction, self.isFlex ), percentSpacing = 'undefined' !== typeof self.values[ optionKey ] ? -1 !== self.values[ optionKey ].indexOf( '%' ) : false, $resizer = jQuery( ui.element ), value = 'top' === direction || 'bottom' === direction ? ui.size.height : ui.size.width; // If nothing is set and left and right, check row column spacing if ( '' === self.values[ optionKey ] && ( 'left' === direction || 'right' === direction ) ) { percentSpacing = -1 !== self.getHalfSpacing().indexOf( '%' ); } // Active class to prevent multiple inits. $resizer.closest( '.fusion-builder-column:not( .resizable-active )' ).addClass( 'resizable-active' ); // Work out value. value = 0 > value ? 0 : value; value = value + 'px'; if ( percentSpacing ) { value = 0 === parseFloat( value ) ? '0%' : ( Math.round( parseFloat( parseFloat( value ) / ( parentWidth / 1000 ) ) ) / 10 ) + '%'; } // Bottom margin overlap if ( 'bottom' === direction ) { if ( 20 > ui.size.height ) { $resizer.addClass( 'fusion-overlap' ); $spacers.find( '.fusion-column-padding-bottom' ).addClass( 'fusion-overlap' ); } else { $resizer.removeClass( 'fusion-overlap' ); $spacers.find( '.fusion-column-padding-bottom' ).removeClass( 'fusion-overlap' ); } } // Display tooltip. $resizer.find( '.fusion-spacing-tooltip, .fusion-column-spacing' ).addClass( 'active' ); $resizer.find( '.fusion-spacing-tooltip' ).text( value ); // Update open settings modal. self.updateDragSettings( '#' + optionKey, value ); }, stop: function( event, ui ) { var $resizer = jQuery( ui.element ); $resizer.closest( '.fusion-builder-column' ).removeClass( 'resizable-active' ); $resizer.find( '.fusion-spacing-tooltip, .fusion-column-spacing' ).removeClass( 'active' ); // Delete all spacing resizable within because parent width has changed. if ( $resizer.find( '.fusion-builder-column-inner' ).find( '.fusion-element-spacing .ui-resizable' ).length ) { $resizer.closest( '.fusion-builder-column-inner' ).find( '.fusion-element-spacing .ui-resizable' ).resizable( 'destroy' ); } } } ); } ); }, /** * Handle padding adjustments on drag. * * @since 2.0.0 * @return {void} */ paddingDrag: function() { var $el = this.$el, self = this, directions = { top: 's', right: 'w', bottom: 's', left: 'e' }, percentSpacing = false, parentWidth = $el.find( '> .fusion-column-wrapper' ).first().width(), $spacers = this.$el.find( '> .fusion-column-wrapper > .fusion-column-spacers, > .fusion-column-margins' ), valueAllowed = ( parentWidth / 100 ), isFlex = false, value, actualDimension; if ( this.$el.hasClass( 'resizable-active' ) ) { return; } if ( 'undefined' !== typeof this.isFlex && true === this.isFlex ) { isFlex = true; } _.each( directions, function( handle, direction ) { var optionKey = FusionApp.getResponsiveOptionKey( 'padding_' + direction, isFlex ), actualDimension = self.values[ optionKey ] || self.values[ 'padding_' + direction ], percentSpacing = false; if ( ! isFlex && ! actualDimension ) { actualDimension = '0px'; } // Check if using a percentage. percentSpacing = 'undefined' !== typeof actualDimension ? -1 !== actualDimension.indexOf( '%' ) : false; if ( percentSpacing ) { // Get actual dimension and set. actualDimension = ( parentWidth / 100 ) * parseFloat( actualDimension ); } if ( 'bottom' !== direction && ( isFlex || 'top' === direction ) ) { if ( 20 > parseInt( actualDimension, 10 ) ) { $spacers.find( '.fusion-column-margin-' + direction + ', .fusion-column-padding-' + direction ).addClass( 'fusion-overlap' ); } else { $spacers.find( '.fusion-column-margin-' + direction + ', .fusion-column-padding-' + direction ).removeClass( 'fusion-overlap' ); } } self.paddingResize[ direction ] = $spacers.find( '.fusion-column-padding-' + direction ); self.paddingResize[ direction ].css( 'display', 'block' ); if ( 'top' === direction || 'bottom' === direction ) { self.paddingResize[ direction ].height( actualDimension ); } else { self.paddingResize[ direction ].width( actualDimension ); } self.paddingResize[ direction ].resizable( { handles: handle, minHeight: 0, minWidth: 0, resize: function( event, ui ) { var optionKey = FusionApp.getResponsiveOptionKey( 'padding_' + direction, isFlex ), actualDimension = self.values[ optionKey ], dimension = 'top' === direction || 'bottom' === direction ? 'height' : 'width', $resizer = jQuery( ui.element ); // Recheck in case unit is changed in the modal. percentSpacing = 'undefined' !== typeof actualDimension ? -1 !== actualDimension.indexOf( '%' ) : false; // Force to grid amount. if ( percentSpacing ) { ui.size[ dimension ] = Math.round( ui.size[ dimension ] / valueAllowed ) * valueAllowed; } $resizer.closest( '.fusion-builder-column' ).addClass( 'resizable-active' ); // Change format of value. value = ui.size[ dimension ]; value = 0 > value ? 0 : value; value = value + 'px'; if ( percentSpacing ) { value = 0 === parseFloat( value ) ? '0%' : Math.round( parseFloat( parseFloat( value ) / ( parentWidth / 100 ) ) ) + '%'; } // Overlaps top left, right. if ( 'top' === direction ) { if ( 20 > ui.size.height ) { $resizer.addClass( 'fusion-overlap' ); $spacers.find( '.fusion-column-margin-top' ).addClass( 'fusion-overlap' ); } else { $resizer.removeClass( 'fusion-overlap' ); $spacers.find( '.fusion-column-margin-top' ).removeClass( 'fusion-overlap' ); } } else if ( 'right' === direction ) { if ( 20 > ui.size.width && ( isFlex || 20 > $spacers.find( '.fusion-column-spacing .fusion-spacing-value' ).width() ) ) { $resizer.addClass( 'fusion-overlap' ); $spacers.find( '.fusion-column-spacing, .fusion-column-margin-right' ).addClass( 'fusion-overlap' ); } else { $resizer.removeClass( 'fusion-overlap' ); $spacers.find( '.fusion-column-spacing, .fusion-column-margin-right' ).removeClass( 'fusion-overlap' ); } } else if ( 'left' === direction && isFlex ) { if ( 20 > ui.size.width ) { $resizer.addClass( 'fusion-overlap' ); $spacers.find( '.fusion-column-margin-left' ).addClass( 'fusion-overlap' ); } else { $resizer.removeClass( 'fusion-overlap' ); $spacers.find( '.fusion-column-margin-left' ).removeClass( 'fusion-overlap' ); } } // Set values. $resizer.find( '.fusion-spacing-tooltip, .fusion-column-spacing' ).addClass( 'active' ); $resizer.find( '.fusion-spacing-tooltip' ).text( value ); // Update open modal. self.updateDragSettings( '#' + optionKey, value ); }, stop: function( event, ui ) { var $resizer = jQuery( ui.element ); $resizer.closest( '.fusion-builder-column' ).removeClass( 'resizable-active' ); $resizer.find( '.fusion-spacing-tooltip, .fusion-column-spacing' ).removeClass( 'active' ); // Delete all spacing resizable within because parent width has changed. if ( $resizer.find( '.fusion-builder-column-inner' ).find( '.fusion-element-spacing .ui-resizable' ).length ) { $resizer.closest( '.fusion-builder-column-inner' ).find( '.fusion-element-spacing .ui-resizable' ).resizable( 'destroy' ); } } } ); } ); }, /** * Destroy column's resizables. * * @since 2.0.0 * @return {void} */ destroyResizable: function() { this.destroySpacingResizable(); this.destroyMarginResizable(); this.destroyPaddingResizable(); }, /** * Destroy column's spacing resizable. * * @since 2.0.0 * @return {void} */ destroySpacingResizable: function() { var $columnSpacer; $columnSpacer = this.$el.find( '> .fusion-column-spacing .fusion-spacing-value' ); if ( $columnSpacer.hasClass( 'ui-resizable' ) ) { $columnSpacer.resizable( 'destroy' ); $columnSpacer.hide(); this.columnSpacer = false; } }, /** * Destroy column's margin resizable. * * @since 2.0.0 * @return {void} */ destroyMarginResizable: function() { _.each( this.marginResize, function( $marginResize ) { if ( $marginResize.length && $marginResize.hasClass( 'ui-resizable' ) && -1 !== $marginResize.attr( 'class' ).indexOf( 'fusion-column-margin-' ) ) { $marginResize.resizable( 'destroy' ); $marginResize.hide(); } } ); }, /** * Destroy column's padding resizable. * * @since 2.0.0 * @return {void} */ destroyPaddingResizable: function() { _.each( this.paddingResize, function( $paddingResize ) { if ( $paddingResize.length && $paddingResize.hasClass( 'ui-resizable' ) && -1 !== $paddingResize.attr( 'class' ).indexOf( 'fusion-column-padding-' ) ) { $paddingResize.resizable( 'destroy' ); $paddingResize.hide(); } } ); }, /** * Changes the column spacing. * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ columnSpacing: function( event ) { var percentSpacing = false, $el = this.$el, self = this, $spacers = this.$el.find( '> .fusion-column-wrapper > .fusion-column-spacers' ), marginDirection = FusionPageBuilderApp.$el.hasClass( 'rtl' ) ? 'left' : 'right', parentWidth, marginRight, container, columnSpacing, existingSpacing, modelSpacing, $columnSpacer, maxWidth, rightPadding, rightOverlap; // We don't need column spacing when flex container is used. if ( 'undefined' !== typeof this.isFlex && true === this.isFlex ) { return; } $columnSpacer = this.$el.find( '> .fusion-column-spacing .fusion-spacing-value' ); if ( event && 'event' !== event ) { event.preventDefault(); } // If responsive mode and columns are 1/1 hide and return. if ( jQuery( '#fb-preview' ).width() < FusionApp.settings.content_break_point && FusionApp.settings.responsive ) { $columnSpacer.hide(); return; } $columnSpacer.show(); // If this is the last column in a virtual row, then no handles. if ( this.$el.hasClass( 'fusion-column-last' ) ) { return; } // No resizer for fallback method. if ( 'yes' === this.model.attributes.params.spacing || 'no' === this.model.attributes.params.spacing ) { return; } existingSpacing = this.model.attributes.params.spacing; if ( 'undefined' === typeof existingSpacing || '' === existingSpacing ) { existingSpacing = '4%'; } if ( 'no' === existingSpacing ) { existingSpacing = '0'; } // Already created spacer and not %, no need to continue. if ( this.columnSpacer && -1 === existingSpacing.indexOf( '%' ) ) { return; } // Get the container width. container = FusionPageBuilderViewManager.getView( this.model.get( 'parent' ) ); if ( 'fusion_builder_column_inner' === this.model.get( 'type' ) ) { parentWidth = container.$el.find( '.fusion-builder-row-container-inner' ).width(); } else { parentWidth = container.$el.find( '.fusion-row' ).width(); } // Already created spacer, % is being used and width is the same, no need to continue. if ( this.columnSpacer && parentWidth === this.parentWidth ) { return; } // Store parent width to compare. this.parentWidth = parentWidth; // Get the column right margin. In real usage use the model attribute. columnSpacing = existingSpacing; marginRight = existingSpacing; // Set column spacing width. if ( -1 !== existingSpacing.indexOf( '%' ) ) { percentSpacing = true; marginRight = parseFloat( marginRight ) / 100.0; columnSpacing = marginRight * parentWidth; } // Set max width spacing. maxWidth = parentWidth - 100; // Destroy in case it's already active if ( $columnSpacer.hasClass( 'ui-resizable' ) ) { $columnSpacer.resizable( 'destroy' ); } $columnSpacer.width( columnSpacing ); $columnSpacer.resizable( { handles: FusionPageBuilderApp.$el.hasClass( 'rtl' ) ? 'w' : 'e', minWidth: 0, maxWidth: maxWidth, grid: ( percentSpacing ) ? [ parentWidth / 100, 10 ] : '', create: function() { if ( 0 === $el.find( '> .fusion-column-spacing .fusion-spacing-value' ).width() ) { $el.find( '> .fusion-column-spacing' ).addClass( 'empty' ); } else if ( $el.find( '> .fusion-column-spacing.empty' ).length ) { $el.find( '> .fusion-column-spacing' ).removeClass( 'empty' ); } }, resize: function( event, ui ) { ui.size.width = 0 > ui.size.width ? 0 : ui.size.width; if ( 0 === modelSpacing ) { $el.find( '> .fusion-column-spacing' ).addClass( 'empty' ); } else if ( $el.find( '> .fusion-column-spacing.empty' ).length ) { $el.find( '> .fusion-column-spacing' ).removeClass( 'empty' ); } modelSpacing = ui.size.width + 'px'; if ( percentSpacing ) { modelSpacing = Math.round( parseFloat( ui.size.width / ( parentWidth / 100 ) ) ) + '%'; } $el.css( 'margin-' + marginDirection, modelSpacing ); // Update open modal. if ( jQuery( '[data-element-cid="' + self.model.get( 'cid' ) + '"]' ).length ) { jQuery( '[data-element-cid="' + self.model.get( 'cid' ) + '"] [data-option-id="spacing"] #spacing' ).val( modelSpacing ).trigger( 'change' ); } $el.find( '> .fusion-column-spacing .fusion-spacing-tooltip, > .fusion-column-spacing' ).addClass( 'active' ); $el.find( '> .fusion-column-spacing .fusion-spacing-tooltip' ).text( modelSpacing ); $el.addClass( 'active-drag' ); self._toolTipHide(); // Right padding overlap. if ( 20 > ui.size.width && 20 > $spacers.find( '.fusion-column-padding-' + marginDirection ).width() ) { jQuery( ui.element ).parent().addClass( 'fusion-overlap' ); $spacers.find( '.fusion-column-padding-' + marginDirection ).addClass( 'fusion-overlap' ); } else { jQuery( ui.element ).parent().removeClass( 'fusion-overlap' ); $spacers.find( '.fusion-column-padding-' + marginDirection ).removeClass( 'fusion-overlap' ); } }, stop: function( event, ui ) { // jshint ignore: line $el.removeClass( 'active-drag' ); } } ); rightPadding = 'undefined' === typeof this.model.attributes.params.padding_right || '' === this.model.attributes.params.padding_right ? '0px' : this.model.attributes.params.padding_right; rightOverlap = ( 20 > parseInt( rightPadding, 10 ) && ( '0%' === rightPadding || -1 === rightPadding.indexOf( '%' ) ) && ( 20 > parseInt( columnSpacing, 10 ) ) ) ? 'fusion-overlap' : ''; if ( '' !== rightOverlap ) { $spacers.find( '.fusion-column-padding-right' ).addClass( 'fusion-overlap' ); $el.find( '> .fusion-column-spacing' ).addClass( 'fusion-overlap' ); } else { $spacers.find( '.fusion-column-padding-right' ).removeClass( 'fusion-overlap' ); $el.find( '> .fusion-column-spacing' ).removeClass( 'fusion-overlap' ); } // Column spacer created this.columnSpacer = true; }, /** * Changes the size of a column. * * @since 2.0.0 * @param {Object} event - The event triggering the change in size. * @return {void} */ sizeSelect: function( event ) { var columnSize, fractionSize, container = FusionPageBuilderViewManager.getView( this.model.get( 'parent' ) ), viewport = jQuery( '#fb-preview' ).attr( 'data-viewport' ), index = [ 'desktop', 'tablet', 'mobile' ].findIndex( function ( vp ) { return viewport.includes( vp ); } ), widthKeys = [ 'type', 'type_medium', 'type_small' ]; if ( event ) { event.preventDefault(); } columnSize = jQuery( event.target ).data( 'column-size' ); // Check if there's a setings view and veify if it's the one corresponding to this element. if ( FusionPageBuilderApp.SettingsHelpers.openSettingsView && FusionPageBuilderApp.SettingsHelpers.openSettingsView.model.cid === this.model.cid ) { if ( FusionPageBuilderApp.SettingsHelpers.openSettingsView.tabsRendered.design ) { return FusionPageBuilderApp.SettingsHelpers.openSettingsView.$el.find( '.fusion-option-' + widthKeys[ index ] + ' .ui-button[data-value="' + columnSize + '"]' ).trigger( 'click' ); } jQuery( FusionPageBuilderApp.SettingsHelpers.openSettingsView.$el.find( '.width-value' )[ index ] ).val( columnSize ); } // Update model. this.model.attributes.params[ widthKeys[ index ] ] = columnSize; this.$el.find( '.column-sizes' ).hide(); this.$el.removeClass( 'active' ); this.$el.attr( 'data-column-size', columnSize ); fractionSize = columnSize.replace( '_', '/' ); // Necessary for re-sizing then cloning. this.reRender(); container.setRowData(); if ( 'fusion_builder_column_inner' !== this.model.get( 'type' ) ) { this.renderSectionSeps(); } this.$el.find( '.column-sizes .column-size' ).removeClass( 'active-size' ); this.$el.find( '.column-size-' + columnSize ).addClass( 'active-size' ); this.$el.closest( '.fusion-builder-container' ).removeClass( 'fusion-column-sizer-active' ); jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-column-resized', this.model.get( 'cid' ) ); FusionEvents.trigger( 'fusion-column-resized' ); // Save history state FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.resized_column + ' ' + fractionSize ); }, /** * Checks if the value is in pixels. * * @since 2.0.0 * @param {string} value - The value we want to check. * @return {boolean} */ pxCheck: function( value ) { if ( 'undefined' === typeof value ) { return false; } // If 0, then consider valid. if ( '0' === value || 0 === value ) { return true; } return ( -1 !== value.indexOf( 'px' ) ) ? true : false; }, /** * Checks if the value is using %. * * @since 2.0.0 * @param {string} value - The value we want to check. * @return {boolean} */ percentageCheck: function( value ) { if ( 'undefined' === typeof value ) { return false; } // If 0, then consider valid. if ( '0' === value || 0 === value ) { return true; } return ( -1 !== value.indexOf( '%' ) ) ? true : false; }, /** * Adds 2 values. * * @since 2.0.0 * @param {string|number|double} a - The 1st value. * @param {string|number|double} b - The 2nd value. * @return {number} */ addValues: function( a, b ) { return parseFloat( a ) + parseFloat( b ); }, /** * Add a module. * * @since 2.0.0 * @param {Object} event - The event triggering the module addition. * @return {void} */ addModule: function( event ) { var view, viewSettings, closestParent; if ( event ) { event.preventDefault(); event.stopPropagation(); FusionPageBuilderApp.sizesHide( event ); } FusionPageBuilderApp.parentColumnId = this.model.get( 'cid' ); viewSettings = { model: this.model, collection: this.collection, view: this, attributes: { 'data-parent_cid': this.model.get( 'cid' ) } }; if ( ! jQuery( event.currentTarget ).closest( '.fusion-builder-empty-column' ).length ) { closestParent = jQuery( event.currentTarget ).closest( '.fusion-builder-live-element' ); if ( closestParent.length ) { viewSettings.targetElement = closestParent; } else { viewSettings.targetElement = jQuery( event.currentTarget ).closest( '.fusion-builder-nested-element' ); } } view = new FusionPageBuilder.ElementLibraryView( viewSettings ); jQuery( view.render().el ).dialog( { title: 'Select Element', draggable: false, modal: true, resizable: false, dialogClass: 'fusion-builder-dialog fusion-builder-large-library-dialog fusion-builder-element-library-dialog', resizeStart: function( event, ui ) { FusionApp.dialog.addResizingClasses(); }, resizeStop: function( event, ui ) { FusionApp.dialog.removeResizingClasses(); }, open: function( event, ui ) { // jshint ignore: line FusionApp.dialog.resizeDialog(); // On start can sometimes be laggy/late. FusionApp.dialog.addResizingHoverEvent(); }, close: function( event, ui ) { // jshint ignore: line view.remove(); } } ); }, /** * Get dynamic values. * * @since 2.0.0 * @return {Object} */ getDynamicAtts: function( values ) { var self = this; if ( 'undefined' !== typeof this.dynamicParams && this.dynamicParams && ! _.isEmpty( this.dynamicParams.getAll() ) ) { _.each( this.dynamicParams.getAll(), function( data, id ) { var value = self.dynamicParams.getParamValue( data ); if ( 'undefined' !== typeof value && false !== value ) { values[ id ] = value; } } ); } return values; }, /** * Get the template. * * @since 2.0.0 * @return {void} */ getTemplate: function() { var atts = this.getTemplateAtts(); return this.template( atts ); }, setArgs: function() { var params = jQuery.extend( true, {}, this.model.get( 'params' ) ), values; // Make sure initial width is correctly inherited. if ( 'undefined' === typeof params.type ) { params.type = this.model.attributes.params.type; } if ( fusionAllElements[ this.model.get( 'type' ) ] ) { values = jQuery.extend( true, {}, fusionAllElements[ this.model.get( 'type' ) ].defaults, _.fusionCleanParameters( params ) ); } // If no blend mode is defined, check if we should set to overlay. if ( 'undefined' === typeof params.background_blend_mode && '' !== params.background_color && 1 > values.alpha_background_color && 0 !== values.alpha_background_color && '' !== params.background_image ) { values.background_blend_mode = 'overlay'; } // If padding (combined all 4) is not set in params, then use individual variables. if ( 'undefined' === typeof params.padding ) { values = _.fusionGetPadding( values ); } this.values = this.getDynamicAtts( values ); }, validateArgs: function() { var borderRadius; // Alpha related checks. this.values.alpha_background_color = jQuery.AWB_Color( this.values.background_color ).alpha(); this.values.alpha_gradient_start_color = jQuery.AWB_Color( this.values.gradient_start_color ).alpha(); this.values.alpha_gradient_end_color = jQuery.AWB_Color( this.values.gradient_end_color ).alpha(); if ( '' !== this.values.margin_bottom ) { this.values.margin_bottom = _.fusionGetValueWithUnit( this.values.margin_bottom ); } if ( '' !== this.values.margin_top ) { this.values.margin_top = _.fusionGetValueWithUnit( this.values.margin_top ); } if ( this.values.border_size ) { this.values.border_size = _.fusionValidateAttrValue( this.values.border_size, 'px' ); } if ( '' !== this.values.padding ) { this.values.padding = _.fusionGetValueWithUnit( this.values.padding ); } if ( '' !== this.values.border_sizes_top ) { this.values.border_sizes_top = _.fusionGetValueWithUnit( this.values.border_sizes_top ); } if ( '' !== this.values.border_sizes_bottom ) { this.values.border_sizes_bottom = _.fusionGetValueWithUnit( this.values.border_sizes_bottom ); } if ( '' !== this.values.border_sizes_top ) { this.values.border_sizes_left = _.fusionGetValueWithUnit( this.values.border_sizes_left ); } if ( '' !== this.values.border_sizes_top ) { this.values.border_sizes_right = _.fusionGetValueWithUnit( this.values.border_sizes_right ); } // Border radius validation. this.values.border_radius_top_left = this.values.border_radius_top_left ? _.fusionGetValueWithUnit( this.values.border_radius_top_left ) : '0px'; this.values.border_radius_top_right = this.values.border_radius_top_right ? _.fusionGetValueWithUnit( this.values.border_radius_top_right ) : '0px'; this.values.border_radius_bottom_left = this.values.border_radius_bottom_left ? _.fusionGetValueWithUnit( this.values.border_radius_bottom_left ) : '0px'; this.values.border_radius_bottom_right = this.values.border_radius_bottom_right ? _.fusionGetValueWithUnit( this.values.border_radius_bottom_right ) : '0px'; borderRadius = this.values.border_radius_top_left + ' ' + this.values.border_radius_top_right + ' ' + this.values.border_radius_bottom_right + ' ' + this.values.border_radius_bottom_left; this.values.border_radius = '0px 0px 0px 0px' === borderRadius ? '' : borderRadius; this.values.border_position = 'all' !== this.values.border_position ? '-' + this.values.border_position : ''; if ( '' === this.values.background_color_hover && '' !== this.values.background_color ) { this.values.background_color_hover = this.values.background_color; } }, validatePercentageMargin: function( value, columnSize, values ) { value = 'undefined' === typeof value ? '' : value; columnSize = 'undefined' === typeof columnSize ? 1 : columnSize; values = 'undefined' === typeof values ? this.values : values; if ( -1 !== value.indexOf( '%' ) && this.isCustomWidth( columnSize ) ) { return '0px'; } // If value is in percentage and not calc, make it relative to container. if ( 0 < parseFloat( columnSize ) && -1 !== value.indexOf( '%' ) && -1 === value.indexOf( 'calc' ) ) { // If all are in % just work it out. if ( -1 !== values.column_spacing.indexOf( '%' ) && -1 === values.column_spacing.indexOf( 'calc' ) ) { return ( parseFloat( value ) / parseFloat( columnSize ) / 100 * ( 100 - parseFloat( values.column_spacing ) ) ) + '%'; } // Not all % then we need to use calc. return 'calc( ' + ( parseFloat( value ) / parseFloat( columnSize ) / 100 ) + ' * calc( 100% - ' + values.column_spacing + ' ) )'; } return value; }, setExtraArgs: function() { var container = FusionPageBuilderApp.getParentContainer( this.model.get( 'parent' ) ), containerParams, containerValues; this.values.flex = false; this.values.column_spacing = '4%'; this.values.flex_align_items = 'flex-start'; if ( 'object' === typeof container ) { containerParams = _.fusionCleanParameters( container.model.get( 'params' ) ); containerValues = jQuery.extend( true, {}, fusionAllElements.fusion_builder_container.defaults, containerParams ); this.values.flex = 'flex' === containerValues.type; this.values.column_spacing = containerValues.flex_column_spacing; this.values.flex_align_items = containerValues.flex_align_items; } this.values.column_counter = this.model.get( 'cid' ); this.values.hover_or_link = ( 'none' !== this.values.hover_type && '' !== this.values.hover_type ) || '' !== this.values.link; this.values.shortcode_classname = 'fusion_builder_column' === this.model.get( 'type' ) ? 'fusion-builder-live-column' : 'fusion-builder-live-nested-column'; // Store for later use. this.isFlex = this.values.flex; }, setColumnMapData: function() { var self = this, containerSpacingOffset, unitlessSpacing, unitlessHalf, halfSpacing, emptyOffset, container, currentRow, containerRows, spacings, total, lastIndex, model, columnSpacing, widthKey, spacingLeftKey, spacingRightKey, extras; // If we are flex, we do not have a column map. if ( this.values.flex ) { this.setColumnSize(); extras = jQuery.extend( true, {}, fusionAllElements.fusion_builder_column.extras ); // Medium inherit from large or validate if set. if ( '' === this.values.type_medium || 0 === parseFloat( this.values.type_medium ) ) { this.values.type_medium = 'inherit_from_large' === extras.col_width_medium ? this.values.column_size : 1; } else { this.values.type_medium = this.validateColumnSize( this.values.type_medium ); } // Small default to 1 or validate if set. if ( '' === this.values.type_small || 0 === parseFloat( this.values.type_small ) ) { this.values.type_small = 'inherit_from_large' === extras.col_width_small ? this.values.column_size : 1; } else { this.values.type_small = this.validateColumnSize( this.values.type_small ); } // Not full width medium, inherit from large if set. if ( 1 !== parseInt( this.values.type_medium ) ) { if ( '' === this.values.spacing_left_medium ) { this.values.spacing_left_medium = this.values.spacing_left; } if ( '' === this.values.spacing_right_medium ) { this.values.spacing_right_medium = this.values.spacing_right; } } // Full width small, inherit from medium or large if set. if ( 1 !== parseInt( this.values.type_small ) ) { if ( '' === this.values.spacing_left_small ) { this.values.spacing_left_small = '' !== this.values.spacing_left_medium ? this.values.spacing_left_medium : this.values.spacing_left; } if ( '' === this.values.spacing_right_small ) { this.values.spacing_right_small = '' !== this.values.spacing_right_medium ? this.values.spacing_right_medium : this.values.spacing_right; } } // Half the spacing on container. halfSpacing = this.getHalfSpacing(); // Validate left and right margins that are set. _.each( [ 'large', 'medium', 'small' ], function( width ) { // Need to calc for each because column width may be different and that changes things. widthKey = 'large' === width ? 'column_size' : 'type_' + width; emptyOffset = self.validatePercentageMargin( halfSpacing, self.values[ widthKey ] ); // We have a value, validate it, else we use the empty offset. spacingLeftKey = 'large' === width ? 'spacing_left' : 'spacing_left_' + width; if ( '' !== self.values[ spacingLeftKey ] ) { self.values[ 'upsized_' + spacingLeftKey ] = self.validatePercentageMargin( self.values[ spacingLeftKey ], self.values[ widthKey ] ); } else { self.values[ 'upsized_' + spacingLeftKey ] = emptyOffset; } spacingRightKey = 'large' === width ? 'spacing_right' : 'spacing_right_' + width; if ( '' !== self.values[ spacingRightKey ] ) { self.values[ 'upsized_' + spacingRightKey ] = self.validatePercentageMargin( self.values[ spacingRightKey ], self.values[ widthKey ] ); } else { self.values[ 'upsized_' + spacingRightKey ] = emptyOffset; } } ); return; } container = FusionPageBuilderViewManager.getView( this.model.get( 'parent' ) ); containerRows = container.model.get( 'rows' ); currentRow = container.getVirtualRowByCID( this.model.get( 'cid' ) ); if ( 'yes' === this.values.spacing || '' === this.values.spacing ) { this.values.spacing = '4%'; } else if ( 'no' === this.values.spacing ) { this.values.spacing = '0px'; } this.values.spacing = _.fusionGetValueWithUnit( this.values.spacing ); this.values.widthOffset = ''; this.values.currentRowNumberOfColumns = false; function fallbackCheck( value ) { return ( 'yes' === value || 'no' === value ); } // Pop off the last because it can't have spacing. if ( 'undefined' !== typeof currentRow ) { // currentRow = currentRow.slice( 0, -1 ); this.values.currentRowNumberOfColumns = currentRow.length + 1; } this.values.fallback = false; if ( 'object' === typeof currentRow ) { this.values.fallback = currentRow.every( fallbackCheck ); } this.setColumnSize(); // Nested column check if ( 'object' === typeof currentRow ) { spacings = []; total = currentRow.length; lastIndex = total - 1; _.each( currentRow, function( column, index ) { if ( lastIndex !== index ) { model = container.model.children.find( function( model ) { return model.get( 'cid' ) == column.cid; // jshint ignore: line } ); columnSpacing = model.attributes.params.spacing; columnSpacing = ( 'undefined' === typeof columnSpacing || '' === columnSpacing ) ? '4%' : columnSpacing; spacings.push( columnSpacing ); } if ( 1 === total ) { spacings.push( '' ); } } ); spacings = spacings.join( ' + ' ); // If no fallback make sure to replace mixed values. if ( ! this.values.fallback ) { spacings = spacings.replace( /yes/g, '4%' ).replace( /no/g, '0%' ); } this.values.widthOffset = '( ( ' + spacings + ' ) * ' + this.values.column_size + ' ) '; } this.setSpacingStyling(); }, getHalfSpacing: function () { var unitlessSpacing = parseFloat( this.values.column_spacing ), unitlessHalf = unitlessSpacing / 2; return this.values.column_spacing.replace( unitlessSpacing, unitlessHalf ); }, setColumnSize: function() { var sizeClass; // Column size value switch ( this.values.type ) { case '1_1': sizeClass = 'fusion-one-full'; break; case '1_4': sizeClass = 'fusion-one-fourth'; break; case '3_4': sizeClass = 'fusion-three-fourth'; break; case '1_2': sizeClass = 'fusion-one-half'; break; case '1_3': sizeClass = 'fusion-one-third'; break; case '2_3': sizeClass = 'fusion-two-third'; break; case '1_5': sizeClass = 'fusion-one-fifth'; break; case '2_5': sizeClass = 'fusion-two-fifth'; break; case '3_5': sizeClass = 'fusion-three-fifth'; break; case '4_5': sizeClass = 'fusion-four-fifth'; break; case '5_6': sizeClass = 'fusion-five-sixth'; break; case '1_6': sizeClass = 'fusion-one-sixth'; break; } this.values.column_size = this.validateColumnSize( this.values.type ); this.values.size_class = sizeClass; }, validateColumnSize: function( columnSize ) { var fractions; if ( 'undefined' === typeof columnSize ) { columnSize = '1_3'; } // Fractional value. if ( -1 !== columnSize.indexOf( '_' ) ) { fractions = columnSize.split( '_' ); return parseFloat( fractions[ 0 ] ) / parseFloat( fractions[ 1 ] ); } // Greater than one, assume percentage and divide by 100. if ( 1 < parseFloat( columnSize ) && -1 == columnSize.indexOf( 'px' ) && -1 == columnSize.indexOf( 'calc' ) ) { return parseFloat( columnSize ) / 100; } // Return if not float. return columnSize; }, setSpacingStyling: function() { var spacingDirection, width = ( this.values.column_size * 100 ) + '%', mapOldSpacing = { 0.1666: '13.3333%', 0.8333: '82.6666%', 0.2: '16.8%', 0.4: '37.6%', 0.6: '58.4%', 0.8: '79.2%', 0.25: '22%', 0.75: '74%', 0.3333: '30.6666%', 0.6666: '65.3333%', 0.5: '48%', 1: '100%' }; this.values.column_spacing_style = ''; this.values.spacing_classes = ''; if ( 0 === parseFloat( this.values.spacing ) ) { this.values.spacing_classes = 'fusion-spacing-no'; } if ( ! this.values.last && ! ( this.values.fallback && '0px' === this.values.spacing ) ) { spacingDirection = 'right'; if ( FusionPageBuilderApp.$el.hasClass( 'rtl' ) ) { spacingDirection = 'left'; } if ( ! this.values.fallback ) { this.values.column_spacing_style = 'width:' + width + ';width:calc(' + width + ' - ' + this.values.widthOffset + ');margin-' + spacingDirection + ': ' + this.values.spacing + ';'; } else { this.values.column_spacing_style = 'width:' + mapOldSpacing[ this.values.column_size ] + '; margin-' + spacingDirection + ': ' + this.values.spacing + ';'; } } else if ( 'undefined' !== typeof this.values.currentRowNumberOfColumns && 1 < this.values.currentRowNumberOfColumns ) { if ( ! this.values.fallback ) { this.values.column_spacing_style = 'width:' + width + ';width:calc(' + width + ' - ' + this.values.widthOffset + ');'; } else if ( '0px' !== this.values.spacing && 'undefined' !== typeof mapOldSpacing[ this.values.column_size ] ) { this.values.column_spacing_style = 'width:' + mapOldSpacing[ this.values.column_size ] + ';'; } else { this.values.column_spacing_style = 'width:' + width + ';'; } } else if ( 'undefined' === typeof this.values.currentRowNumberOfColumns && 'undefined' !== mapOldSpacing[ this.values.column_size ] ) { this.values.column_spacing_style = 'width:' + mapOldSpacing[ this.values.column_size ] + ';'; } }, getResponsiveColumnVars: function() { var self = this, cssVars = []; this.responsiveStyles = ''; if ( ! this.values.flex ) { return; } _.each( [ 'large', 'medium', 'small' ], function( size ) { var widthKey, keyBase, orderKey, flex_grow_key, flex_shrink_key, spacingKey; // Width. widthKey = 'large' === size ? 'column_size' : 'type_' + size; if ( 'string' === typeof self.values[ widthKey ] && ( self.values[ widthKey ].indexOf( 'px' ) || self.values[ widthKey ].indexOf( 'px' ) ) ) { cssVars[ 'width-' + size ] = self.values[ widthKey ]; } else if ( '' !== self.values[ widthKey ] && 'auto' !== self.values[ widthKey ] && 0 < parseFloat( self.values[ widthKey ] ) ) { cssVars[ 'width-' + size ] = ( parseFloat( self.values[ widthKey ] ) * 100 ) + '%'; } else if ( 'auto' === self.values[ widthKey ] ) { cssVars[ 'width-' + size ] = 'auto'; } // Order. orderKey = 'large' === size ? 'order' : 'order_' + size; if ( '' !== self.values[ orderKey ] ) { cssVars[ 'order-' + size ] = parseInt( self.values[ orderKey ] ); } flex_grow_key = 'large' === size ? 'flex_grow' : 'flex_grow_' + size; flex_shrink_key = 'large' === size ? 'flex_shrink' : 'flex_shrink_' + size; if ( 0 < parseInt( self.values[ flex_grow_key ] ) ) { cssVars[ flex_grow_key ] = parseInt( self.values[ flex_grow_key ] ); } if ( 0 < parseInt( self.values[ flex_shrink_key ] ) ) { cssVars[ flex_shrink_key ] = parseInt( self.values[ flex_shrink_key ] ); } _.each( [ 'top', 'right', 'bottom', 'left' ], function( direction ) { // Margin. keyBase = 'left' === direction || 'right' === direction ? 'upsized_spacing' : 'margin'; spacingKey = 'large' === size ? keyBase + '_' + direction : keyBase + '_' + direction + '_' + size; if ( '' !== self.values[ spacingKey ] ) { if ( 'margin' === keyBase ) { cssVars[ 'margin-' + direction + '-' + size ] = self.values[ spacingKey ]; } else if ( 'upsized_spacing' === keyBase ) { if ( -1 !== self.values[ spacingKey ].indexOf( '%' ) && 'custom' === self.getVisibleWidth() ) { cssVars[ 'spacing-' + direction + '-' + size ] = '0px'; } else { cssVars[ 'spacing-' + direction + '-' + size ] = _.fusionGetValueWithUnit( self.values[ spacingKey ] ); } } } } ); } ); return this.getCustomCssVars( cssVars ); }, setResponsiveColumnStyles: function() { var self = this, extras = jQuery.extend( true, {}, fusionAllElements.fusion_builder_column.extras ); this.responsiveStyles = ''; if ( ! this.values.flex ) { return; } _.each( [ 'large', 'medium', 'small' ], function( size ) { var uiWrapperStyles = '', dragStyles = '', columnStyles = '', keyBase, orderKey, spacingKey; // Order. orderKey = 'large' === size ? 'order' : 'order_' + size; if ( '' !== self.values[ orderKey ] ) { columnStyles += 'order : ' + parseInt( self.values[ orderKey ] ) + ';'; } _.each( [ 'top', 'right', 'bottom', 'left' ], function( direction ) { // Margin. keyBase = 'left' === direction || 'right' === direction ? 'upsized_spacing' : 'margin'; spacingKey = 'large' === size ? keyBase + '_' + direction : keyBase + '_' + direction + '_' + size; if ( '' !== self.values[ spacingKey ] ) { if ( 'left' === direction ) { uiWrapperStyles += direction + ':' + self.values[ spacingKey ] + ';'; } if ( 'left' === direction || 'right' === direction ) { dragStyles += direction + ':' + self.values[ spacingKey ] + ';'; } } } ); // Wrap CSS selectors if ( '' !== columnStyles ) { columnStyles = '.fusion-body .' + self.values.shortcode_classname + '-' + self.values.column_counter + '{' + columnStyles + '}'; } if ( '' !== uiWrapperStyles ) { uiWrapperStyles = '.fusion-body .fusion-flex-container .fusion-row .' + self.values.shortcode_classname + '-' + self.values.column_counter + ' > .fusion-builder-module-controls-type-column {' + uiWrapperStyles + '}'; } if ( '' !== dragStyles ) { dragStyles = '.fusion-flex-container .fusion-row .' + self.values.shortcode_classname + '-' + self.values.column_counter + '.fusion-being-dragged:after, .fusion-builder-live .fusion-flex-container .fusion-nested-columns.editing .' + self.values.shortcode_classname + '-' + self.values.column_counter + ':hover:after {' + dragStyles + '}'; } // Large styles, no wrapping needed. if ( 'large' === size ) { self.responsiveStyles += uiWrapperStyles + dragStyles + columnStyles; } else { // Medium and Small size screen styles. self.responsiveStyles += '@media only screen and (max-width:' + extras[ 'visibility_' + size ] + 'px) {' + uiWrapperStyles + dragStyles + columnStyles + '}'; } } ); }, buildAttr: function() { var attr = { 'class': 'fusion-layout-column ' + this.model.get( 'type' ) + ' ' + this.values.shortcode_classname + '-' + this.values.column_counter + ' fusion-builder-column-live-' + this.values.column_counter, 'style': this.getStyleVars() }; // Sticky column. if ( 'on' === this.values.sticky ) { attr[ 'class' ] += ' awb-sticky'; if ( '' !== this.values.sticky_offset && 0 !== this.values.sticky_offset ) { // If its not a selector then get value and set to css variable. if ( ! this.values.sticky_offset.includes( '.' ) && ! this.values.sticky_offset.includes( '#' ) ) { attr.style += '--awb-sticky-offset:' + _.fusionGetValueWithUnit( this.values.sticky_offset ) + ';'; } else { attr[ 'data-sticky-offset' ] = this.values.sticky_offset; } } // Not ideal, but easier to join and keep the rest of the logic the same. if ( 'object' === typeof this.values.sticky_devices ) { this.values.sticky_devices = this.values.sticky_devices.join( ',' ); } if ( 'string' === typeof this.values.sticky_devices && '' !== this.values.sticky_devices ) { this.values.sticky_devices = this.values.sticky_devices.replaceAll( '-visibility', '' ).split( ',' ); this.values.sticky_devices.forEach( ( stickyDevice ) => { attr[ 'class' ] += ' awb-sticky-' + stickyDevice.replaceAll( ' ', '' ); } ); } } if ( 'on' === this.values.absolute ) { attr[ 'class' ] += ' awb-absolute'; } // Flexbox column. if ( this.values.flex ) { attr[ 'class' ] += ' fusion-flex-column'; // Alignment of column vertically. if ( 'auto' !== this.values.align_self ) { attr[ 'class' ] += ' fusion-flex-align-self-' + this.values.align_self; } } else { if ( '' !== this.values.type && this.values.type.includes( '_ ' ) ) { attr[ 'class' ] += ' ' + this.model.get( 'type' ) + '_' + this.values.type; attr[ 'class' ] += ' ' + this.values.type; } // Class for the specific size of column. if ( '' !== this.values.size_class ) { attr[ 'class' ] += ' ' + this.values.size_class; } // First column. if ( this.values.first ) { attr[ 'class' ] += ' fusion-column-first'; } // Last column. if ( this.values.last ) { attr[ 'class' ] += ' fusion-column-last'; } // Special calcs for spacing. if ( '' !== this.values.spacing_classes ) { attr[ 'class' ] += this.values.spacing_classes; } // Column spacing style, margin and width. if ( '' !== this.values.column_spacing_style ) { attr.style += this.values.column_spacing_style; } } // Custom CSS class. if ( '' !== this.values[ 'class' ] ) { attr[ 'class' ] += ' ' + this.values[ 'class' ]; } // Min height for newly created columns by the converter. if ( 'none' === this.values.min_height ) { attr[ 'class' ] += ' fusion-column-no-min-height'; } // Visibility classes. let visibilityValue = this.values.hide_on_mobile; // Get Render logics Array. const renderLogicsDevices = this.getRenderLogicsDevices(); if ( renderLogicsDevices.length && 'on' === FusionApp.preferencesData.rendering_logic ) { const rlDevicesEqual = []; const rlDevicesNotEqual = []; renderLogicsDevices.forEach( ( r ) => { switch ( r.value ) { case 'desktop': if ( 'equal' === r.comparison ) { rlDevicesEqual.push( 'large-visibility' ); } else { rlDevicesNotEqual.push( 'large-visibility' ); } break; case 'tablet': if ( 'equal' === r.comparison ) { rlDevicesEqual.push( 'medium-visibility' ); } else { rlDevicesNotEqual.push( 'medium-visibility' ); } break; case 'mobile': if ( 'equal' === r.comparison ) { rlDevicesEqual.push( 'small-visibility' ); } else { rlDevicesNotEqual.push( 'small-visibility' ); } break; case 'mobile_tablet': if ( 'equal' === r.comparison ) { rlDevicesEqual.push( 'medium-visibility' ); rlDevicesEqual.push( 'small-visibility' ); } else { rlDevicesNotEqual.push( 'medium-visibility' ); rlDevicesNotEqual.push( 'small-visibility' ); } break; } } ); if ( rlDevicesEqual.length ) { attr[ 'class' ] = _.fusionVisibilityAtts( rlDevicesEqual.join( ',' ), attr[ 'class' ] ); } if ( rlDevicesNotEqual.length ) { visibilityValue = visibilityValue.split( ',' ).filter( ( v ) => !rlDevicesNotEqual.includes( v ) ); } } // Visibility classes. attr[ 'class' ] = _.fusionVisibilityAtts( visibilityValue, attr[ 'class' ] ); attr[ 'class' ] += _.fusionGetStickyClass( this.values.sticky_display ); // Hover type or link. if ( this.values.hover_or_link ) { attr[ 'class' ] += ' fusion-column-inner-bg-wrapper'; } // TODO: check why it is looking at animation type/class. if ( this.values.hover_or_link && '' !== this.values.animation_type && 'liftup' === this.values.hover_type ) { attr[ 'class' ] += ' fusion-column-hover-type-liftup'; } // Lift up and border. if ( 'liftup' === this.values.hover_type && '' !== this.values.border_style ) { attr[ 'class' ] += ' fusion-column-liftup-border'; } attr = _.fusionAnimations( this.values, attr ); if ( '' !== this.values.id ) { attr.id = this.values.id; } if ( this.values.motion_effects ) { attr[ 'data-motion-effect' ] = true; } return attr; }, buildWrapperAttr: function() { var attr = { 'class': 'fusion-column-wrapper fusion-column-wrapper-live-' + this.values.column_counter, 'style': '' }; // Image URL for empty dimension calculations. attr[ 'data-bg-url' ] = this.values.background_image; // Box shadow. if ( 'liftup' !== this.values.hover_type && '' !== this.values.box_shadow ) { attr[ 'class' ] += ' fusion-column-has-shadow'; // Move this to appropriate. } // Flex. if ( this.values.flex ) { if ( '' !== this.values.align_content ) { attr[ 'class' ] += ' fusion-flex-justify-content-' + this.values.align_content; attr[ 'class' ] += ' fusion-content-layout-' + this.values.content_layout; if ( 'row' === this.values.content_layout && 'flex-start' !== this.values.valign_content ) { attr[ 'class' ] += ' fusion-flex-align-items-' + this.values.valign_content; } if ( 'wrap' !== this.values.content_wrap ) { attr[ 'class' ] += ' fusion-content-' + this.values.content_wrap; } } } return attr; }, buildHoverWrapperAttr: function() { var attr = { 'class': 'fusion-column-inner-bg hover-type-' + this.values.hover_type, 'style': '' }; return attr; }, buildAnchorAttr: function() { var attr = {}; attr[ 'class' ] = 'fusion-column-anchor'; if ( '' !== this.values.link ) { attr.href = this.values.link; } if ( '_blank' === this.values.target ) { attr.rel = 'noopener noreferrer'; attr.target = '_blank'; } else if ( 'lightbox' === this.values.target ) { attr[ 'data-rel' ] = 'iLightbox'; } if ( '' !== this.values.link_description ) { attr[ 'aria-label' ] = this.values.link_description; } return attr; }, buildHoverInnerWrapperAttr: function() { var attr = { 'class': 'fusion-column-inner-bg-image', 'style': '' }; return attr; }, getStyleVars: function() { var cssVars = [ 'z_index', 'z_index_hover' ], borderVars, innerVarPrefix, customCssVars = {}; cssVars.padding_top = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_right = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_left = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_top_medium = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_right_medium = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_bottom_medium = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_left_medium = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_top_small = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_right_small = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_bottom_small = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_left_small = { 'callback': _.fusionGetValueWithUnit }; // Overflow. if ( '' !== this.values.overflow ) { customCssVars.overflow = this.values.overflow; } else if ( this.values.border_radius ) { customCssVars.overflow = 'hidden'; } // Some variables needs to be placed directly on column, some on an inner div helper. // This is a quick way to not check for "hover_or_link" every time. innerVarPrefix = ( this.values.hover_or_link ? 'inner-' : '' ); if ( 'on' === this.values.absolute && 'on' !== this.values.sticky ) { customCssVars[ 'container-position' ] = 'absolute'; cssVars.absolute_top = { 'callback': _.fusionGetValueWithUnit }; cssVars.absolute_right = { 'callback': _.fusionGetValueWithUnit }; cssVars.absolute_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVars.absolute_left = { 'callback': _.fusionGetValueWithUnit }; } if ( '' !== this.values.background_color && ( '' === this.values.background_image || 0 !== this.values.alpha_background_color ) ) { customCssVars[ innerVarPrefix + 'bg-color' ] = this.values.background_color; } if ( '' !== this.values.background_color_hover ) { customCssVars[ innerVarPrefix + 'bg-color-hover' ] = this.values.background_color_hover; } if ( '' !== this.values.background_color_medium ) { customCssVars[ innerVarPrefix + 'bg-color-medium' ] = this.values.background_color_medium; } if ( '' !== this.values.background_color_medium_hover ) { customCssVars[ innerVarPrefix + 'bg-color-medium-hover' ] = this.values.background_color_medium_hover; } if ( '' !== this.values.background_color_small ) { customCssVars[ innerVarPrefix + 'bg-color-small' ] = this.values.background_color_small; } if ( '' !== this.values.background_color_small_hover ) { customCssVars[ innerVarPrefix + 'bg-color-small-hover' ] = this.values.background_color_small_hover; } if ( '' !== this.values.background_image ) { customCssVars[ innerVarPrefix + 'bg-image' ] = 'url(\'' + this.values.background_image + '\')'; } if ( '' !== this.values.background_image_medium ) { customCssVars[ innerVarPrefix + 'bg-image-medium' ] = 'url(\'' + this.values.background_image_medium + '\')'; } if ( '' !== this.values.background_image_small ) { customCssVars[ innerVarPrefix + 'bg-image-small' ] = 'url(\'' + this.values.background_image_small + '\')'; } if ( '' !== _.getGradientString( this.values, 'column' ) ) { customCssVars[ innerVarPrefix + 'bg-image' ] = _.getGradientString( this.values, 'column' ); if ( '' !== this.values.background_image_medium ) { customCssVars[ innerVarPrefix + 'bg-image_medium' ] = _.getGradientString( this.values, 'column', 'medium' ); } if ( '' !== this.values.background_image_small ) { customCssVars[ innerVarPrefix + 'bg-image_small' ] = _.getGradientString( this.values, 'column', 'small' ); } } if ( this.values.background_position && ! this.isDefault( 'background_position' ) ) { customCssVars[ innerVarPrefix + 'bg-position' ] = this.values.background_position; } if ( this.values.background_position_medium ) { customCssVars[ innerVarPrefix + 'bg-position-medium' ] = this.values.background_position_medium; } if ( this.values.background_position_small ) { customCssVars[ innerVarPrefix + 'bg-position-small' ] = this.values.background_position_small; } if ( ! this.isDefault( 'background_blend_mode' ) ) { customCssVars[ innerVarPrefix + 'bg-blend' ] = this.values.background_blend_mode; } if ( this.values.background_blend_mode_medium ) { customCssVars[ innerVarPrefix + 'bg-blend-medium' ] = this.values.background_blend_mode_medium; } if ( this.values.background_blend_mode_small ) { customCssVars[ innerVarPrefix + 'bg-blend-small' ] = this.values.background_blend_mode_small; } if ( '' !== this.values.background_repeat ) { customCssVars[ innerVarPrefix + 'bg-repeat' ] = this.values.background_repeat; } if ( '' !== this.values.background_repeat ) { customCssVars[ innerVarPrefix + 'bg-repeat' ] = this.values.background_repeat; } if ( '' !== this.values.background_repeat_medium ) { customCssVars[ innerVarPrefix + 'bg-repeat-medium' ] = this.values.background_repeat_medium; } if ( '' !== this.values.background_repeat_small ) { customCssVars[ innerVarPrefix + 'bg-repeat-small' ] = this.values.background_repeat_small; } if ( 'no-repeat' === this.values.background_repeat ) { customCssVars[ innerVarPrefix + 'bg-size' ] = 'cover'; } if ( '' !== this.values.background_size ) { const backgroundSize = 'custom' === this.values.background_size ? this.values.background_custom_size : this.values.background_size; customCssVars[ innerVarPrefix + 'bg-size' ] = backgroundSize; } if ( '' !== this.values.background_size_medium ) { const backgroundSizeMedium = 'custom' === this.values.background_size_medium ? this.values.background_custom_size_medium : this.values.background_size_medium; customCssVars[ innerVarPrefix + 'bg-size-medium' ] = backgroundSizeMedium; } if ( '' !== this.values.background_size_small ) { const backgroundSizeSmall = 'custom' === this.values.background_size_small ? this.values.background_custom_size_small : this.values.background_size_small; customCssVars[ innerVarPrefix + 'bg-size-small' ] = backgroundSizeSmall; } borderVars = this.getBorderVars(); if ( 'yes' === this.values.box_shadow ) { if ( 'liftup' === this.values.hover_type ) { customCssVars.inner_bg_box_shadow = _.fusionGetBoxShadowStyle( this.values ).trim(); } else { customCssVars.box_shadow = _.fusionGetBoxShadowStyle( this.values ).trim(); } } const transformVars = _.fusionGetTransformVars( this.values, '--awb-transform', '--awb-transform-hover', '--awb-transform-parent-hover' ); if ( this.values.transform_origin && '50% 50%' !== this.values.transform_origin ) { customCssVars.transform_origin = this.values.transform_origin; } const filterVars = _.getFilterVars( this.values ); if ( ! this.isDefault( 'transition_duration' ) || ! this.isDefault( 'transition_easing' ) ) { customCssVars.transition = _.fusionGetTransitionStyle( this.values ); } return this.getCssVarsForOptions( cssVars ) + this.getCustomCssVars( customCssVars ) + borderVars + transformVars + filterVars + this.getResponsiveColumnVars(); }, getBorderVars: function() { var customCssVars = {}, borderOnInner = ( 'liftup' === this.values.hover_type ? true : false ); if ( '' !== this.values.border_color ) { customCssVars[ 'border-color' ] = this.values.border_color; if ( borderOnInner ) { customCssVars[ 'inner-border-color' ] = this.values.border_color; } if ( this.values.border_color_hover ) { customCssVars[ 'border-color-hover' ] = this.values.border_color_hover; if ( borderOnInner ) { customCssVars[ 'inner-border-color-hover' ] = this.values.border_color_hover; } } if ( this.values.border_sizes_top ) { customCssVars[ 'border-top' ] = this.values.border_sizes_top; if ( borderOnInner ) { customCssVars[ 'inner-border-top' ] = this.values.border_sizes_top; } } if ( this.values.border_sizes_right ) { customCssVars[ 'border-right' ] = this.values.border_sizes_right; if ( borderOnInner ) { customCssVars[ 'inner-border-right' ] = this.values.border_sizes_right; } } if ( this.values.border_sizes_bottom ) { customCssVars[ 'border-bottom' ] = this.values.border_sizes_bottom; if ( borderOnInner ) { customCssVars[ 'inner-border-bottom' ] = this.values.border_sizes_bottom; } } if ( this.values.border_sizes_left ) { customCssVars[ 'border-left' ] = this.values.border_sizes_left; if ( borderOnInner ) { customCssVars[ 'inner-border-left' ] = this.values.border_sizes_left; } } if ( '' !== this.values.border_style ) { customCssVars[ 'border-style' ] = this.values.border_style; if ( borderOnInner ) { customCssVars[ 'inner-border-style' ] = this.values.border_style; } } } if ( '' !== this.values.border_radius ) { customCssVars.border_radius = this.values.border_radius; if ( ( 'zoomin' === this.values.hover_type || 'zoomout' === this.values.hover_type || '' !== this.values.link ) ) { customCssVars[ 'inner-bg-border-radius' ] = this.values.border_radius; } // Lift up and border radius we need to apply radius to lift up markup. if ( this.values.hover_or_link && 'liftup' === this.values.hover_type ) { customCssVars[ 'liftup-border-radius' ] = this.values.border_radius; } } if ( ( 'zoomin' === this.values.hover_type || 'zoomout' === this.values.hover_type || this.values.link ) && '' !== this.values.border_radius ) { customCssVars[ 'inner-bg-overflow' ] = 'hidden'; } return this.getCustomCssVars( customCssVars ); }, /** * Fires when preview are is resized. * * @since 3.0 * @return {void} */ onPreviewResize: function() { // Update size indicator in toolbar. this.updateSizeIndicators(); if ( ! FusionPageBuilderApp.getParentContainer( this ).isFlex() ) { return; } // Update margin and padding indicators if we are editing this. if ( this.$el.hasClass( 'fusion-builder-element-edited' ) ) { this.updateBoxModelIndicators(); } }, /** * Updates column sizes controls. * * @since 3.0 * @return {void} */ updateSizeIndicators: function() { var columnSize = this.getVisibleWidth(); this.$el.find( '.column-sizes .column-size' ).removeClass( 'active-size' ); if ( columnSize.includes( '_' ) ) { this.$el.find( '.column-size-' + columnSize ).addClass( 'active-size' ); } if ( 'custom' === columnSize ) { columnSize = ''; } this.$el.find( '.fusion-column-size-label' ).html( columnSize.replace( '_', '/' ) ); }, /** * Updates column sizes controls. * * @since 3.0 * @return {void} */ updateBoxModelIndicators: function() { this.destroyMarginResizable(); this.destroyPaddingResizable(); this.marginDrag(); this.paddingDrag(); }, /** * Parses width to readable string. * * @since 3.0 * @param {String} width * @return {String} */ parseWidthLabel: function( width ) { if ( 'undefined' === typeof width ) { width = '1_1'; } if ( 'auto' === width ) { return 'auto'; } if ( ! width.includes( '_' ) && ! width.includes( 'px' ) && ! width.includes( 'calc' ) ) { return width.split( '.' )[ 0 ] + '%'; } if ( width.includes( 'px' ) || width.includes( 'calc' ) ) { return 'custom'; } return width; }, /** * Returns visible column width. * * @since 3.0 * @return {String} */ getVisibleWidth: function() { var param, defaultVal, previewFrame, legacyBreakpoint; // Legacy support. if ( ! FusionPageBuilderApp.getParentContainer( this ).isFlex() ) { previewFrame = jQuery( '#fb-preview' )[ 0 ]; legacyBreakpoint = getComputedStyle( previewFrame.contentDocument.documentElement ).getPropertyValue( '--content_break_point' ); if ( legacyBreakpoint && legacyBreakpoint >= previewFrame.offsetWidth ) { return '1_1'; } return this.model.attributes.params.type; } param = FusionApp.getResponsiveOptionKey( 'type', true ); // Default for medium and small sizes. if ( 'type' !== param && ! this.model.attributes.params[ param ] ) { // Return large value. defaultVal = fusionAllElements.fusion_builder_column.extras[ 'col_width_' + param.replace( 'type_', '' ) ]; if ( 'inherit_from_large' === defaultVal ) { return this.parseWidthLabel( this.model.attributes.params.type ); } return '1_1'; } return this.parseWidthLabel( this.model.attributes.params[ param ] ); }, getTemplateAtts: function() { var styleSelector, data = {}, wrapperAttr; this.setArgs(); this.responsiveStyles = ''; this.styles = ''; this.validateArgs(); this.setExtraArgs(); this.setColumnMapData(); // Sets styles for responsive options. if ( this.values.flex ) { this.setResponsiveColumnStyles(); } let columnSelector = '.fusion-builder-column-live-' + this.model.get( 'cid' ); if ( 'fusion_builder_column_inner' === this.model.get( 'type' ) ) { columnSelector = '.fusion-builder-live-nested-column-' + this.model.get( 'cid' ); } // Get the filter style if ( 'fusion_builder_column' === this.model.get( 'type' ) ) { styleSelector = columnSelector; } else { styleSelector = { regular: columnSelector, hover: columnSelector + ':hover' }; } // Get Transform selector. let transformSelector = ''; let transformEditSelector = ''; if ( 'fusion_builder_column' === this.model.get( 'type' ) ) { transformSelector = columnSelector; transformEditSelector = columnSelector + '.fusion-builder-element-edited'; } else { transformSelector = { regular: columnSelector, hover: columnSelector + ':hover' }; transformEditSelector = { regular: '.fusion-builder-element-edited' + columnSelector, hover: '.fusion-builder-element-edited' + columnSelector + ':hover' }; } data.wrapperAttr = this.buildWrapperAttr(); data.center_content = this.values.center_content; data.hoverWrapperAttr = this.buildHoverWrapperAttr(); data.anchorAttr = this.buildAnchorAttr(); data.hoverInnerWrapperAttr = this.buildHoverInnerWrapperAttr(); data.styles = this.styles; data.nestedClass = 'fusion_builder_column_inner' === this.model.get( 'type' ) ? ' fusion-nested-column-content' : ''; data.cid = this.model.get( 'cid' ); data.hoverOrLink = this.values.hover_or_link; data.layout = this.getVisibleWidth().replace( '_', '/' ); data.isFlex = ( 'undefined' !== typeof this.values.flex ) ? this.values.flex : false; data.responsiveStyles = 'undefined' !== typeof this.responsiveStyles ? this.responsiveStyles : ''; data.isGlobal = ( 'undefined' !== typeof this.values.fusion_global ) ? 'yes' : 'no'; data.hideMargin = 'fusion_builder_column_inner' !== this.model.get( 'type' ) && 'post_cards' === FusionApp.data.fusion_element_type; data.column_tag = this.values.column_tag; data.hasBgSlider = this.values.background_slider_images; data.bgSlider = _.fusionGetBackgroundSliderElement( this, 'column' ); wrapperAttr = this.buildAttr(); // Flag as having filters. if ( '' !== _.getFilterVars( this.values ) ) { wrapperAttr[ 'class' ] += ' fusion-has-filters'; } // Main wrapper is the actual view. this.model.set( 'selectors', wrapperAttr ); return data; }, /** * Toggles the 'active' class. * * @since 2.0.0 * @param {Object} event - The event triggering the class toggling. * @return {void} */ sizesShow: function( event ) { var parentContainer = this.$el.closest( '.fusion-builder-container' ), sizesPopover = this.$el.find( '.column-sizes' ), columnOffsetTop = 0, html, header, headerBottom, conditional; if ( event ) { event.preventDefault(); event.stopPropagation(); } sizesPopover.removeClass( 'fusion-expand-to-bottom' ); // This needs to be the way it is setup, as nested cols could trigger sizing on several cols at once. if ( ! this.$el.hasClass( 'active' ) ) { this.$el.addClass( 'active' ); parentContainer.addClass( 'fusion-column-sizer-active' ); columnOffsetTop = this.$el.offset().top; html = this.$el.closest( 'html' ); conditional = false; if ( html.children( 'body' ).hasClass( 'fusion-top-header' ) ) { if ( jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '.fusion-footer-parallax' ).length ) { sizesPopover.on( 'mouseenter', function() { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '#main' ).css( 'z-index', 'auto' ); if ( 'fixed' === jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '.fusion-footer-parallax' ).css( 'position' ) ) { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '.fusion-footer-parallax' ).css( 'z-index', '-1' ); if ( jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '#sliders-container' ).find( '.tfs-slider[data-parallax="1"]' ).length ) { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '#sliders-container' ).css( 'z-index', 'auto' ); } } } ); sizesPopover.on( 'mouseleave', function() { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '#main' ).css( 'z-index', '' ); jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '.fusion-footer-parallax' ).css( 'z-index', '' ); jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '#sliders-container' ).css( 'z-index', '' ); } ); } header = html.find( '.fusion-header-wrapper' ); headerBottom = 0; if ( header.length ) { headerBottom = header.offset().top + header.outerHeight(); } conditional = 106 > columnOffsetTop - headerBottom; } if ( 54 > columnOffsetTop - 121 || conditional || sizesPopover.parents( '.fusion-fullwidth' ).hasClass( 'bg-parallax-parent' ) ) { sizesPopover.addClass( 'fusion-expand-to-bottom' ); } } else { this.$el.removeClass( 'active' ); parentContainer.removeClass( 'fusion-column-sizer-active' ); sizesPopover.off( 'mouseover' ).off( 'mouseleave' ); } }, /** * Toggle class to show content in bottom * * @since 2.0.0 * @return {void} */ offsetClass: function() { if ( 100 > this.$el.offset().top ) { this.$el.addClass( 'fusion-content-bottom' ); } else if ( 100 < this.$el.offset().top && this.$el.hasClass( 'fusion-content-bottom' ) ) { this.$el.removeClass( 'fusion-content-bottom' ); } }, /** * Column spacing dimensions version. * * @since 2.0.0 * @return {void} */ fallbackColumnSpacing: function( $placeholder, allNo ) { var columnSize = '100%', fullcolumnSize = columnSize, existingSpacing = '0%', columnWidth = this.model.attributes.params.type, spacingDirection; if ( 'yes' === this.model.attributes.params.spacing ) { existingSpacing = '4%'; } columnWidth = this.model.attributes.params.type; switch ( columnWidth ) { case '1_1': columnSize = '100%'; fullcolumnSize = '100%'; break; case '1_4': columnSize = '22%'; fullcolumnSize = '25%'; break; case '3_4': columnSize = '74%'; fullcolumnSize = '75%'; break; case '1_2': columnSize = '48%'; fullcolumnSize = '50%'; break; case '1_3': columnSize = '30.6666%'; fullcolumnSize = '33.3333%'; break; case '2_3': columnSize = '65.3333%'; fullcolumnSize = '66.6666%'; break; case '1_5': columnSize = '16.8%'; fullcolumnSize = '20%'; break; case '2_5': columnSize = '37.6%'; fullcolumnSize = '40%'; break; case '3_5': columnSize = '58.4%'; fullcolumnSize = '60%'; break; case '4_5': columnSize = '79.2%'; fullcolumnSize = '80%'; break; case '5_6': columnSize = '82.6666%'; fullcolumnSize = '83.3333%'; break; case '1_6': columnSize = '13.3333%'; fullcolumnSize = '16.6666%'; break; } if ( '4%' !== existingSpacing && ( ! this.model.attributes.params.last || allNo ) ) { columnSize = fullcolumnSize; } this.$el.css( 'width', columnSize ); $placeholder.css( 'width', columnSize ); spacingDirection = 'right'; if ( FusionPageBuilderApp.$el.hasClass( 'rtl' ) ) { spacingDirection = 'left'; } $placeholder.css( 'margin-' + spacingDirection, existingSpacing ); this.$el.css( 'margin-' + spacingDirection, existingSpacing ); }, /** * Column spacing dimensions version. * * @since 2.0.0 * @return {void} */ dimensionColumnSpacing: function( columnRow, columnWidth, $placeholder ) { var decimalWidth, check, spacingWidth, existingSpacing, spacings = [], spacingDirection; // Remove last from calcs. columnRow.pop(); columnWidth = columnWidth[ 0 ] / columnWidth[ 1 ]; decimalWidth = columnWidth; if ( 'object' === typeof columnRow ) { check = columnRow.every( this.pxCheck ); if ( check ) { spacingWidth = ( columnRow.reduce( this.addValues, 0 ) * decimalWidth ) + 'px'; this.$el.css( 'width', 'calc( ' + ( columnWidth * 100 ) + '% - ' + spacingWidth + ' )' ); $placeholder.css( 'width', 'calc( ' + ( columnWidth * 100 ) + '% - ' + spacingWidth + ' )' ); } else if ( columnRow.every( this.percentageCheck ) ) { columnWidth = ( columnWidth * 100 ) - ( columnRow.reduce( this.addValues, 0 ) * decimalWidth ); this.$el.css( 'width', columnWidth + '%' ); $placeholder.css( 'width', columnWidth + '%' ); } else { _.each( columnRow, function( space ) { space = ( 'undefined' === typeof space || '' === space ) ? '4%' : space; spacings.push( space ); } ); spacingWidth = spacings.join( ' + ' ); this.$el.css( 'width', 'calc( ' + ( columnWidth * 100 ) + '% - ( ( ' + spacingWidth + ' ) * ' + decimalWidth + ' )' ); $placeholder.css( 'width', 'calc( ' + ( columnWidth * 100 ) + '% - ( ( ' + spacingWidth + ' ) * ' + decimalWidth + ' )' ); } } existingSpacing = this.model.attributes.params.spacing; if ( 'undefined' === typeof this.model.attributes.params.spacing || 'yes' === this.model.attributes.params.spacing || '' === this.model.attributes.params.spacing ) { existingSpacing = '4%'; } if ( 'no' === this.model.attributes.params.spacing ) { existingSpacing = '0'; } spacingDirection = 'right'; if ( FusionPageBuilderApp.$el.hasClass( 'rtl' ) ) { spacingDirection = 'left'; } $placeholder.css( 'margin-' + spacingDirection, existingSpacing ); this.$el.css( 'margin-' + spacingDirection, existingSpacing ); }, /** * Check if value is valid for column spacing. * * @since 2.0.0 * @return {void} */ validColumnSpacing: function( value ) { if ( 'yes' !== value && 'no' !== value && ! ( /\d/ ).test( value ) && '' !== value ) { return false; } return true; }, /** * Filter out DOM before patching. * * @since 2.0.0 * @return {void} */ patcherFilter: function( diff ) { var filteredDiff = [], self = this; _.each( diff, function( info ) { if ( 'removeElement' === info.action ) { if ( 'undefined' !== typeof info.element.attributes[ 'class' ] && ( -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-column-content-centered' ) || -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-builder-column-content' ) || -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-column-wrapper' ) ) ) { self.forceAppendChildren = true; filteredDiff.push( info ); } else if ( 'undefined' !== typeof info.element.attributes[ 'class' ] && ( -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-spacing-value' ) || -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-element-spacing' ) || -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-builder-live-element' ) || -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion_builder_row_inner' ) ) ) { // ignore } else { filteredDiff.push( info ); } } else if ( 'addElement' === info.action ) { if ( 'undefined' !== typeof info.element.attributes[ 'class' ] && ( -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-column-content-centered' ) || -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-builder-column-content' ) || -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-column-wrapper' ) ) ) { self.forceAppendChildren = true; filteredDiff.push( info ); } else if ( 'undefined' !== typeof info.element.attributes[ 'class' ] && ( -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-spacing-value' ) || -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-element-spacing' ) ) ) { // ignore } else { filteredDiff.push( info ); } } else { filteredDiff.push( info ); } } ); return filteredDiff; }, /** * Adds a delay to the change trigger to accomodate equal-heights implementation. * * @since 2.0.0 * @param {number|string} cid - The CID of the element. * @return {void} */ equalHeights: function( cid ) { cid = 'undefined' === typeof cid ? this.model.attributes.cid : cid; setTimeout( function() { jQuery( document ).trigger( 'fusion-content-changed', cid ); jQuery( window ).trigger( 'fusion-content-changed', cid ); jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-content-changed', cid ); }, 300 ); }, /** * Removes the 'active' class. * * @since 2.0.0 * @return {void} */ toolTipHide: function() { this.$el.find( '.fusion-spacing-tooltip, .fusion-column-spacing' ).removeClass( 'active' ); }, /** * Resize spacer on window resize event. * * @since 2.0.0 * @return {void} */ resizeSpacer: function() { if ( this.columnSpacer ) { this.columnSpacing(); } }, /** * Preview column-spacing changes. * * @since 2.0.0 * @param {Object} columnRow - The row. * @return {void} */ columnSpacingPreview: function( columnRow ) { var columnWidth = 'undefined' !== typeof this.model.attributes.params.type ? this.model.attributes.params.type.split( '_' ) : [ '1', '1' ], fallback = true, origValue, $placeholder = jQuery( '.fusion-builder-column-placeholder[data-cid="' + this.model.get( 'cid' ) + '"]' ), allNo = true; _.each( columnRow, function( value, index ) { origValue = value; value = ( 'yes' === value ) ? '4%' : value; value = ( 'no' === value ) ? '0' : value; fallback = fallback && origValue !== value; allNo = allNo && 0 === parseInt( value, 10 ); columnRow[ index ] = value; } ); if ( ! fallback ) { this.dimensionColumnSpacing( columnRow, columnWidth, $placeholder ); } else { this.fallbackColumnSpacing( $placeholder, allNo ); } }, /** * Gets the column content. * Alias of getColumnContent method. * * @since 2.0.0 * @return {string} */ getContent: function() { return this.getColumnContent(); }, /** * Sets the attributes of an element. * * @since 2.0.0 * @param {Object} element - The element we're updating. * @param {Object} attributes - The attributes we're setting/updating. * @return {void} */ setElementAttributes: function( element, attributes ) { var self = this; element.removeClass( this.currentClasses ); if ( 'object' === typeof attributes && element.length ) { _.each( attributes, function( values, attribute ) { if ( 'class' === attribute ) { self.currentClasses = values; element.addClass( values ); } else if ( 'id' === attribute ) { element.attr( 'id', values ); } else if ( 'style' === attribute ) { element.attr( 'style', values ); } else if ( -1 !== attribute.indexOf( 'data' ) ) { attribute = attribute.replace( /_/g, '-' ); element.attr( attribute, values ); } } ); } }, /** * check if String is JSON string. * * @since 3.7 * @return boolean */ IsJsonString: function( str ) { try { const json = JSON.parse( str ); return ( 'object' === typeof json ); } catch ( e ) { return false; } }, /** * Get render logics devices. * * @since 3.7 * @return boolean */ getRenderLogicsDevices: function( value ) { //console.warn( JSON.parse( value )); value = value || this.values.render_logics; let renderLogics = value && this.IsJsonString( atob( value ) ) ? JSON.parse( atob( value ) ) : []; // Get device Render logics only. renderLogics = renderLogics.filter( ( r ) => 'device_type' === r.field ); return renderLogics; } } ); } ); }( jQuery ) ); ;/* global FusionPageBuilderViewManager, fusionAppConfig, fusionAppConfig, FusionApp, fusionGlobalManager, fusionBuilderText, FusionPageBuilderApp, FusionPageBuilderElements, FusionEvents, fusionAllElements */ /* eslint no-unused-vars: 0 */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Column View FusionPageBuilder.ColumnView = FusionPageBuilder.BaseColumnView.extend( { template: FusionPageBuilder.template( jQuery( '#fusion-builder-column-template' ).html() ), events: { 'click .fusion-builder-column-settings:not(.fusion-builder-column-inner .fusion-builder-column-setting)': 'settings', 'click .fusion-builder-column-size:not(.fusion-builder-column-inner .fusion-builder-column-size)': 'sizesShow', 'hover .fusion-builder-column-content': 'offsetClass', 'click .column-size:not(.fusion-builder-column-inner .column-size)': 'sizeSelect', 'click .fusion-builder-add-element:not(.fusion-builder-column-inner .fusion-builder-add-element)': 'addModule', 'click .fusion-builder-column-remove:not(.fusion-builder-column-inner .fusion-builder-column-remove)': 'removeColumn', 'click .fusion-builder-column-clone:not(.fusion-builder-column-inner .fusion-builder-column-clone)': 'cloneColumn', 'click .fusion-builder-column-save:not(.fusion-builder-column-inner .fusion-builder-column-save)': 'openLibrary', 'click .fusion-builder-column-drag:not(.fusion-builder-column-inner .fusion-builder-column-drag)': 'preventDefault' }, /** * Init. * * @since 2.0.0 * @return {void} */ initialize: function() { var params = this.model.get( 'params' ), spacing = '' !== params.spacing ? spacing : '4%'; this.renderedYet = false; this.columnSpacer = false; this.forceAppendChildren = false; this.listenTo( FusionEvents, 'fusion-view-update-fusion_builder_column', this.reRender ); this.$el.attr( 'data-cid', this.model.get( 'cid' ) ); this.$el.attr( 'id', 'fusion-column-' + this.model.get( 'cid' ) ); this.$el.attr( 'data-column-size', this.model.attributes.params.type ); this.$el.attr( 'data-column-spacing', spacing ); if ( 'undefined' !== typeof this.model.attributes.params && 'undefined' !== typeof this.model.attributes.params.fusion_global ) { this.$el.attr( 'fusion-global-layout', this.model.attributes.params.fusion_global ); this.$el.removeClass( 'fusion-global-column' ).addClass( 'fusion-global-column' ); } this.currentClasses = ''; this.baseColumnInit(); this.baseInit(); }, /** * Renders the view. * * @since 2.0.0 * @return {Object} this */ render: function() { var self = this, data = this.getTemplateAtts(), columnSize = ''; this.$el.html( this.template( data ) ); if ( 'undefined' !== typeof this.model.attributes.selectors ) { this.setElementAttributes( this.$el, this.model.attributes.selectors ); } // Add active column size CSS class columnSize = this.model.attributes.params.type; // TODO Check size and update class according. this.updateSizeIndicators(); this.appendChildren(); setTimeout( function() { self.droppableColumn(); }, 100 ); // Don't refresh on first render. if ( this.renderedYet ) { this._refreshJs(); } this.renderedYet = true; return this; }, droppableColumn: function() { var self = this, $el = this.$el, cid, $droppables, $body; if ( ! $el ) { return; } cid = this.model.get( 'cid' ); $droppables = $el.find( '.fusion-column-target' ); $body = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ); $el.draggable( { appendTo: FusionPageBuilderApp.$el, zIndex: 999999, delay: 100, cursorAt: { top: 15, left: 15 }, iframeScroll: true, containment: $body, cancel: '.fusion-builder-live-element, .fusion_builder_row_inner', helper: function() { var $classes = FusionPageBuilderApp.DraggableHelpers.draggableClasses( cid ), style = ''; if ( $el.css( 'margin-top' ) ) { style = 'style="transform: translateY(' + $el.css( 'margin-top' ) + ');"'; } return jQuery( '
' ); }, start: function() { $body.addClass( 'fusion-column-dragging fusion-active-dragging' ); $el.addClass( 'fusion-being-dragged' ); if ( 'large' !== FusionApp.getPreviewWindowSize() ) { $body.addClass( 'fusion-column-dragging-responsive-mode' ); $el.closest( '.fusion-builder-container' ).addClass( 'fusion-has-active-drop-targets' ); } }, stop: function() { setTimeout( function() { $body.removeClass( 'fusion-column-dragging fusion-active-dragging' ); }, 10 ); $el.removeClass( 'fusion-being-dragged' ); if ( 'large' !== FusionApp.getPreviewWindowSize() ) { $el.closest( '.fusion-builder-container' ).removeClass( 'fusion-has-active-drop-targets' ); $body.removeClass( 'fusion-column-dragging-responsive-mode' ); } } } ); $droppables.droppable( { tolerance: 'touch', hoverClass: 'ui-droppable-active', accept: '.fusion-builder-column', drop: function( event, ui ) { var handleDropColumn = self.handleDropColumn.bind( self ); handleDropColumn( ui.draggable, $el, jQuery( event.target ) ); } } ); $el.find( '.fusion-element-target-column' ).droppable( { tolerance: 'touch', hoverClass: 'ui-droppable-active', accept: '.fusion-builder-live-element, .fusion_builder_row_inner', drop: function( event, ui ) { var handleElementDropInsideColumn = self.handleElementDropInsideColumn.bind( self ); handleElementDropInsideColumn( ui.draggable, $el ); } } ); }, handleElementDropInsideColumn: function( $element, $targetEl ) { var elementView = FusionPageBuilderViewManager.getView( $element.data( 'cid' ) ), newIndex, MultiGlobalArgs; // Move the actual html. $targetEl.find( '.fusion-builder-column-content:not(.fusion_builder_row_inner .fusion-builder-column-content ):not( .fusion-nested-column-content )' ).append( $element ); newIndex = $element.parent().children( '.fusion-builder-live-element, .fusion_builder_row_inner' ).index( $element ); FusionPageBuilderApp.onDropCollectionUpdate( elementView.model, newIndex, this.model.get( 'cid' ) ); FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.moved + ' ' + fusionAllElements[ elementView.model.get( 'element_type' ) ].name + ' ' + fusionBuilderText.element ); // Handle multiple global elements. MultiGlobalArgs = { currentModel: elementView.model, handleType: 'save', attributes: elementView.model.attributes }; fusionGlobalManager.handleMultiGlobal( MultiGlobalArgs ); FusionEvents.trigger( 'fusion-content-changed' ); this._equalHeights(); }, handleDropColumn: function( $column, $targetEl, $dropTarget ) { var destinationRow, columnCid = $column.data( 'cid' ), columnView = FusionPageBuilderViewManager.getView( columnCid ), originalCid = columnView.model.get( 'parent' ), parentCid = $targetEl.closest( '.fusion-builder-row' ).data( 'cid' ), originalView, newIndex; if ( 'large' !== FusionApp.getPreviewWindowSize() && 'undefined' !== typeof this.isFlex && true === this.isFlex ) { // Update columns' order. FusionPageBuilderViewManager.getView( this.model.get( 'parent' ) )._updateResponsiveColumnsOrder( $column, $targetEl.closest( '.fusion-builder-row' ).children( '.fusion-builder-column' ), parseInt( $dropTarget.closest( '.fusion-builder-column' ).data( 'cid' ) ), $dropTarget.hasClass( 'target-after' ) ); return; } // Move the actual html. if ( $dropTarget.hasClass( 'target-after' ) ) { $targetEl.after( $column ); } else { $targetEl.before( $column ); } destinationRow = FusionPageBuilderViewManager.getView( parentCid ); newIndex = $column.parent().children( '.fusion-builder-column' ).index( $column ); FusionPageBuilderApp.onDropCollectionUpdate( columnView.model, newIndex, parentCid ); // Update destination row which is this current one. destinationRow.setRowData(); // If destination row and original row are different, update original as well. if ( parentCid !== originalCid ) { originalView = FusionPageBuilderViewManager.getView( originalCid ); originalView.setRowData(); } FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.column + ' Order Changed' ); setTimeout( function() { // If different container type we re-render so that it corrects for new situation. if ( 'object' !== typeof originalView || FusionPageBuilderApp.sameContainerTypes( originalView.model.get( 'parent' ), destinationRow.model.get( 'parent' ) ) ) { columnView.droppableColumn(); } else { FusionEvents.trigger( 'fusion-close-settings-' + columnView.model.get( 'cid' ) ); columnView.reRender(); } }, 300 ); }, /** * Things to do, places to go when options change. * * @since 2.0.0 * @param {string} paramName - The name of the parameter that changed. * @param {mixed} paramValue - The value of the option that changed. * @param {Object} event - The event triggering the option change. * @return {void} */ onOptionChange: function( paramName, paramValue, event ) { var rowView, parentCID = this.model.get( 'parent' ), cid = this.model.get( 'cid' ), dimensionType = _.find( [ 'spacing_', 'margin_', 'padding_' ], function( type ) { return paramName.includes( type ); } ), reInitDraggables = false, view = {}, values = {}, alphaBackgroundColor = 1; // Reverted to history step or user entered value manually. if ( 'undefined' === typeof event || ( 'undefined' !== typeof event && ( 'change' !== event.type || ( 'change' === event.type && 'undefined' !== typeof event.srcElement ) ) ) ) { reInitDraggables = true; } if ( 'spacing' === paramName ) { this.model.attributes.params[ paramName ] = paramValue; // Only update preview if it a valid unit. if ( this.validColumnSpacing( paramValue ) ) { rowView = FusionPageBuilderViewManager.getView( parentCID ); rowView.setSingleRowData( cid ); } if ( true === reInitDraggables ) { if ( 'yes' === paramValue || 'no' === paramValue ) { this.destroySpacingResizable(); } else { this.columnSpacer = false; this.columnSpacing(); } } } if ( dimensionType ) { this.model.attributes.params[ paramName ] = paramValue; if ( true === reInitDraggables ) { if ( 'padding_' === dimensionType ) { this.destroyPaddingResizable(); this.paddingDrag(); } else { this.destroyMarginResizable(); this.marginDrag(); } } } if ( 'padding' === paramName ) { if ( -1 === jQuery( event.target ).attr( 'name' ).indexOf( '_' ) ) { this.model.attributes.params[ paramName ] = paramValue; this.renderSectionSeps( event ); this._refreshJs(); } } if ( 'padding_left' === paramName || 'padding_right' === paramName ) { this.renderSectionSeps( event ); } if ( [ 'border_size', 'border_color', 'border_style', 'border_position' ].includes( paramName ) ) { this.model.attributes.params[ paramName ] = paramValue; } if ( 'render_logics' === paramName ) { this.reRender(); jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-column-resized', this.model.get( 'cid' ) ); FusionEvents.trigger( 'fusion-column-resized' ); } }, /** * Render the section separators. * * @since 2.0.0 * @return {void} */ renderSectionSeps: function() { var elements = FusionPageBuilderViewManager.getChildViews( this.model.get( 'cid' ) ); _.each( elements, function( element ) { if ( 'fusion_section_separator' === element.model.get( 'element_type' ) ) { element.reRender(); } } ); }, /** * Triggers a refresh. * * @since 2.0.0 * @return void */ refreshJs: function() { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-element-render-fusion_builder_column', this.model.attributes.cid ); jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-reinit-background-slider', this.model.attributes.cid ); }, /** * Changes the border styles for the element. * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ borderStyle: function( event ) { var borderSize = this.model.attributes.params.border_size + 'px', borderColor = this.model.attributes.params.border_color, borderStyle = this.model.attributes.params.border_style, borderPosition = this.model.attributes.params.border_position, positions = [ 'top', 'right', 'bottom', 'left' ], self = this, $target = ( 'lift_up' === this.model.attributes.params.hover_type ) ? self.$el.find( '.fusion-column-wrapper, .fusion-column-inner-bg-image' ) : self.$el.find( '.fusion-column-wrapper' ); if ( event ) { event.preventDefault(); } self.$el.find( '.fusion-column-wrapper, .fusion-column-inner-bg-image' ).css( 'border', '' ); if ( 'all' === borderPosition ) { _.each( positions, function( position ) { $target.css( 'border-' + position, borderSize + ' ' + borderStyle + ' ' + borderColor ); } ); } else { _.each( positions, function( position ) { if ( position === borderPosition ) { $target.css( 'border-' + position, borderSize + ' ' + borderStyle + ' ' + borderColor ); } else { $target.css( 'border-' + position, 'none' ); } } ); } }, /** * Clones a column. * * @since 2.0.0 * @param {Object} event - The event. * @param {bool} forceManually - Force manually, even if it's not an event, to update history and trigger content changes. * @return {void} */ cloneColumn: function( event, forceManually ) { var columnAttributes = jQuery.extend( true, {}, this.model.attributes ), $thisColumn, container; if ( event ) { event.preventDefault(); } columnAttributes.created = 'manually'; columnAttributes.cid = FusionPageBuilderViewManager.generateCid(); columnAttributes.targetElement = this.$el; columnAttributes.cloned = true; columnAttributes.at_index = FusionPageBuilderApp.getCollectionIndex( this.$el ); FusionPageBuilderApp.collection.add( columnAttributes ); // Parse column elements $thisColumn = this.$el; $thisColumn.find( '.fusion-builder-live-element:not(.fusion-builder-column-inner .fusion-builder-live-element), .fusion-builder-nested-element' ).each( function() { var $thisModule, moduleCID, module, elementAttributes, $thisInnerRow, innerRowCID, innerRowView; // Standard element if ( jQuery( this ).hasClass( 'fusion-builder-live-element' ) ) { $thisModule = jQuery( this ); moduleCID = 'undefined' === typeof $thisModule.data( 'cid' ) ? $thisModule.find( '.fusion-builder-data-cid' ).data( 'cid' ) : $thisModule.data( 'cid' ); // Get model from collection by cid module = FusionPageBuilderElements.find( function( model ) { return model.get( 'cid' ) == moduleCID; // jshint ignore: line } ); // Clone model attritubes elementAttributes = jQuery.extend( true, {}, module.attributes ); elementAttributes.created = 'manually'; elementAttributes.cid = FusionPageBuilderViewManager.generateCid(); elementAttributes.parent = columnAttributes.cid; elementAttributes.from = 'fusion_builder_column'; // Don't need target element, position is defined from order. delete elementAttributes.targetElementPosition; FusionPageBuilderApp.collection.add( elementAttributes ); // Inner row/nested element } else if ( jQuery( this ).hasClass( 'fusion_builder_row_inner' ) ) { $thisInnerRow = jQuery( this ); innerRowCID = 'undefined' === typeof $thisInnerRow.data( 'cid' ) ? $thisInnerRow.find( '.fusion-builder-data-cid' ).data( 'cid' ) : $thisInnerRow.data( 'cid' ); innerRowView = FusionPageBuilderViewManager.getView( innerRowCID ); // Clone inner row if ( 'undefined' !== typeof innerRowView ) { innerRowView.cloneNestedRow( 'clone', columnAttributes.cid ); } } } ); // If column is cloned manually if ( event || forceManually ) { FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.cloned + ' ' + fusionBuilderText.column ); container = FusionPageBuilderViewManager.getView( this.model.get( 'parent' ) ); container.createVirtualRows(); container.updateColumnsPreview(); FusionEvents.trigger( 'fusion-content-changed' ); } this._refreshJs(); }, /** * Append the column's children to its content. * * @since 2.0.0 * @return {void} */ appendChildren: function() { var self = this, cid, view; this.model.children.each( function( child ) { cid = child.attributes.cid; view = FusionPageBuilderViewManager.getView( cid ); self.$el.find( '.fusion-builder-column-content:not(.fusion_builder_row_inner .fusion-builder-column-content ):not( .fusion-nested-column-content )' ).append( view.$el ); } ); this.delegateChildEvents(); }, /** * Gets the column contents. * * @since 2.0.0 * @param {Object} $thisColumn - The jQuery object of the element. * @return {string} */ getColumnContent: function() { var shortcode = '', columnParams = {}, self = this, ColumnAttributesCheck; _.each( this.model.get( 'params' ), function( value, name ) { columnParams[ name ] = ( 'undefined' === value || 'undefined' === typeof value ) ? '' : value; } ); // Legacy support for new column options ColumnAttributesCheck = { min_height: '', last: 'no', hover_type: 'none', link: '', border_position: 'all' }; _.each( ColumnAttributesCheck, function( value, name ) { if ( 'undefined' === typeof columnParams[ name ] ) { columnParams[ name ] = value; } } ); this.beforeGenerateShortcode(); // Build column shortcode shortcode += '[fusion_builder_column type="' + this.model.attributes.params.type + '"'; _.each( columnParams, function( value, name ) { if ( ( 'on' === fusionAppConfig.removeEmptyAttributes && '' !== value ) || 'off' === fusionAppConfig.removeEmptyAttributes ) { shortcode += ' ' + name + '="' + value + '"'; } } ); shortcode += ']'; // Find elements inside this column this.$el.find( '.fusion-builder-live-element:not(.fusion-builder-column-inner .fusion-builder-live-element), .fusion-builder-nested-element' ).each( function() { var $thisRowInner; // Find standard elements if ( jQuery( this ).hasClass( 'fusion-builder-live-element' ) ) { shortcode += FusionPageBuilderApp.generateElementShortcode( jQuery( this ), false ); // Find inner rows } else { $thisRowInner = FusionPageBuilderViewManager.getView( jQuery( this ).data( 'cid' ) ); if ( 'undefined' !== typeof $thisRowInner ) { shortcode += $thisRowInner.getInnerRowContent(); } } } ); shortcode += '[/fusion_builder_column]'; return shortcode; }, /** * Removes a column. * * @since 2.0.0 * @param {Object} event - The event triggering the column removal. * @param {bool} forceManually - Force manually, even if it's not an event, to update history and trigger content changes. * @return {void} */ removeColumn: function( event, forceManually ) { var elements, rowView, parentCID = this.model.get( 'parent' ); if ( event ) { event.preventDefault(); } elements = FusionPageBuilderViewManager.getChildViews( this.model.get( 'cid' ) ); _.each( elements, function( element ) { if ( 'fusion_builder_row' === element.model.get( 'type' ) || 'fusion_builder_row_inner' === element.model.get( 'type' ) ) { element.removeRow(); } else { element.removeElement(); } } ); FusionPageBuilderViewManager.removeView( this.model.get( 'cid' ) ); this._equalHeights( parentCID ); FusionEvents.trigger( 'fusion-element-removed', this.model.get( 'cid' ) ); this.model.destroy(); this.remove(); // If the column is deleted manually if ( event || forceManually ) { // Update preview for spacing. rowView = FusionPageBuilderViewManager.getView( parentCID ); rowView.setRowData(); FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.deleted + ' ' + fusionBuilderText.column ); FusionEvents.trigger( 'fusion-content-changed' ); rowView.$el.find( '.fusion-builder-module-controls-container a' ).trigger( 'mouseleave' ); } }, /** * Adds a child view. * * @since 2.0.0 * @param {Object} element - The element. * @return {void} */ addChildView: function( element ) { var view, viewSettings = { model: element, collection: FusionPageBuilderElements, attributes: { 'data-cid': element.get( 'cid' ) } }, containerSuffix = ':not(.fusion_builder_row_inner .fusion-builder-column-content)'; if ( 'undefined' !== typeof element.get( 'multi' ) && 'multi_element_parent' === element.get( 'multi' ) ) { if ( 'undefined' !== typeof FusionPageBuilder[ element.get( 'element_type' ) ] ) { view = new FusionPageBuilder[ element.get( 'element_type' ) ]( viewSettings ); } else { view = new FusionPageBuilder.ParentElementView( viewSettings ); } } else if ( 'undefined' !== typeof FusionPageBuilder[ element.get( 'element_type' ) ] ) { view = new FusionPageBuilder[ element.get( 'element_type' ) ]( viewSettings ); } else if ( 'fusion_builder_row_inner' === element.get( 'element_type' ) ) { view = new FusionPageBuilder.InnerRowView( viewSettings ); } else { view = new FusionPageBuilder.ElementView( viewSettings ); } // Add new view to manager. FusionPageBuilderViewManager.addView( element.get( 'cid' ), view ); if ( 'undefined' !== typeof this.model && 'fusion_builder_column_inner' === this.model.get( 'type' ) ) { containerSuffix = ''; } if ( ! _.isUndefined( element.get( 'targetElement' ) ) && 'undefined' === typeof element.get( 'from' ) ) { if ( 'undefined' === typeof element.get( 'targetElementPosition' ) || 'after' === element.get( 'targetElementPosition' ) ) { element.get( 'targetElement' ).after( view.render().el ); } else { element.get( 'targetElement' ).before( view.render().el ); } } else if ( 'undefined' === typeof element.get( 'targetElementPosition' ) || 'end' === element.get( 'targetElementPosition' ) ) { if ( 'fusion_widget' === view.model.get( 'element_type' ) ) { // eslint-disable-next-line vars-on-top var renderedView = view.render(); renderedView.$el.find( 'script' ).remove(); this.$el.find( '.fusion-builder-column-content' + containerSuffix ).append( renderedView.el ); } else { this.$el.find( '.fusion-builder-column-content' + containerSuffix ).append( view.render().el ); } } else { this.$el.find( '.fusion-builder-column-content' + containerSuffix ).find( '.fusion-builder-empty-column' ).first().after( view.render().el ); } // Check if we should open the settings or not. if ( 'off' !== window.FusionApp.preferencesData.open_settings && 'undefined' !== typeof element.get( 'added' ) ) { if ( 'fusion_builder_row_inner' === element.get( 'type' ) ) { view.editRow(); } else { view.settings(); } } }, /** * Get the save label. * * @since 2.0.0 * @return {string} */ getSaveLabel: function() { return fusionBuilderText.save_column; }, /** * Returns the 'columns' string. * * @since 2.0.0 * @return {string} */ getCategory: function() { return 'columns'; }, /** * Column spacing dimensions version. * * @since 2.0.0 * @return {void} */ fallbackColumnSpacing: function( $placeholder, allNo ) { var columnSize = '100%', fullcolumnSize = columnSize, existingSpacing = '0%', columnWidth = this.model.attributes.params.type; if ( 'yes' === this.model.attributes.params.spacing ) { existingSpacing = '4%'; } columnWidth = this.model.attributes.params.type; switch ( columnWidth ) { case '1_1': columnSize = '100%'; fullcolumnSize = '100%'; break; case '1_4': columnSize = '22%'; fullcolumnSize = '25%'; break; case '3_4': columnSize = '74%'; fullcolumnSize = '75%'; break; case '1_2': columnSize = '48%'; fullcolumnSize = '50%'; break; case '1_3': columnSize = '30.6666%'; fullcolumnSize = '33.3333%'; break; case '2_3': columnSize = '65.3333%'; fullcolumnSize = '66.6666%'; break; case '1_5': columnSize = '16.8%'; fullcolumnSize = '20%'; break; case '2_5': columnSize = '37.6%'; fullcolumnSize = '40%'; break; case '3_5': columnSize = '58.4%'; fullcolumnSize = '60%'; break; case '4_5': columnSize = '79.2%'; fullcolumnSize = '80%'; break; case '5_6': columnSize = '82.6666%'; fullcolumnSize = '83.3333%'; break; case '1_6': columnSize = '13.3333%'; fullcolumnSize = '16.6666%'; break; } if ( '4%' !== existingSpacing && ( ! this.model.attributes.params.last || allNo ) ) { columnSize = fullcolumnSize; } this.$el.css( 'width', columnSize ); $placeholder.css( 'width', columnSize ); $placeholder.css( 'margin-right', existingSpacing ); this.$el.css( 'margin-right', existingSpacing ); }, /** * Checks if column layout type is block. * * @since 3.0.0 * @return {Boolean} */ isBlockLayout: function() { return this.values && 'block' === this.values.content_layout; } } ); } ); }( jQuery ) ); ;/* global FusionApp, FusionPageBuilderApp, FusionPageBuilderViewManager, fusionAllElements, fusionBuilderText, FusionEvents, FusionPageBuilderElements */ /* jshint -W020 */ /* eslint no-shadow: 0 */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Builder Container View FusionPageBuilder.ContainerView = FusionPageBuilder.BaseView.extend( { template: FusionPageBuilder.template( jQuery( '#fusion-builder-container-template' ).html() ), className: function() { var classes = 'fusion-builder-container fusion-builder-data-cid', values = _.fusionCleanParameters( jQuery.extend( true, {}, this.model.get( 'params' ) ) ); if ( 'yes' === values.hundred_percent_height_scroll && 'yes' === values.hundred_percent_height ) { classes += ' scrolling-helper'; } if ( this.isFlex ) { classes += ' fusion-builder-flex-container'; } if ( values.status && 'draft' === values.status ) { classes += ' fusion-builder-container-status-draft'; } // Absolute container. if ( 'undefined' !== typeof values.absolute && 'on' === values.absolute ) { classes += ' fusion-builder-absolute-container-wrapper'; } return classes; }, events: { 'click .fusion-builder-container-settings': 'settings', 'click .fusion-builder-container-remove': 'removeContainer', 'click .fusion-builder-container-clone': 'cloneContainer', 'click .fusion-builder-container-add': 'addContainer', 'click .fusion-builder-container-save': 'openLibrary', 'click .fusion-builder-publish-tooltip': 'publish', 'click .fusion-builder-unglobal-tooltip': 'unglobalize', 'click .fusion-builder-container-drag': 'preventDefault' }, /** * Init. * * @since 2.0.0 * @return {void} */ initialize: function() { var cid = this.model.get( 'cid' ), el = this.$el; el.attr( 'data-cid', cid ); el.attr( 'id', 'fusion-container-' + cid ); if ( 'undefined' !== typeof this.model.attributes.params && 'undefined' !== typeof this.model.attributes.params.fusion_global ) { el.attr( 'fusion-global-layout', this.model.attributes.params.fusion_global ); this.$el.removeClass( 'fusion-global-container' ).addClass( 'fusion-global-container' ); } this.listenTo( FusionEvents, 'fusion-view-update-fusion_builder_container', this.reRender ); this.listenTo( FusionEvents, 'fusion-param-changed-' + this.model.get( 'cid' ), this.onOptionChange ); // Responsive control updates on resize. this.listenTo( FusionEvents, 'fusion-preview-viewport-update', this.onPreviewResize ); this._triggerCallback = _.debounce( _.bind( this.triggerCallback, this ), 200 ); this.model.children = new FusionPageBuilder.Collection(); this.listenTo( this.model.children, 'add', this.addChildView ); this.renderedYet = FusionPageBuilderApp.loaded; this._refreshJs = _.debounce( _.bind( this.refreshJs, this ), 300 ); this._triggerScrollUpdate = _.debounce( _.bind( this.triggerScrollUpdate, this ), 300 ); this._reInitSticky = _.debounce( _.bind( this.reInitSticky, this ), 300 ); this._updateInnerStyles = _.debounce( _.bind( this.updateInnerStyles, this ), 500 ); this.scrollingSections = false; this.settingsControlsOffset = 0; this.width = el.width(); el.on( 'mouseenter', _.bind( this.setSettingsControlsOffset, this ) ); this.correctStackingContextForFilters(); this.deprecatedParams(); this.baseInit(); this.reInitDraggables = false; }, /** * Set correct top offset for the container setting controls. * * @since 2.0 * @param {boolean} forced - Whether to force an update and bypass checks. * @return {void} */ setSettingsControlsOffset: function( forced ) { var offset = 15, customOffset; if ( ( 'undefined' !== typeof forced || 0 === this.settingsControlsOffset || this.width !== this.$el.width() ) && ( 'undefined' !== typeof window.frames[ 0 ].getStickyHeaderHeight || 'undefined' !== typeof window.frames[ 0 ].fusionGetStickyOffset ) ) { // if we have sticky enabled, get its height. if ( 'off' !== FusionApp.preferencesData.sticky_header && 'on' !== this.values.sticky ) { // If we have a custom header, use function to retrieve lowest point. if ( jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '.fusion-tb-header' ).length && 'function' === typeof window.frames[ 0 ].fusionGetStickyOffset ) { customOffset = window.frames[ 0 ].fusionGetStickyOffset(); if ( customOffset ) { offset += customOffset; } } else if ( 'undefined' !== typeof window.frames[ 0 ].getStickyHeaderHeight ) { offset += window.frames[ 0 ].getStickyHeaderHeight( true ); } } this.settingsControlsOffset = offset + 'px'; this.width = this.$el.width(); this.$el.find( '.fusion-builder-module-controls-container-wrapper .fusion-builder-module-controls-type-container' ).css( 'top', this.settingsControlsOffset ); } if ( this.$el.find( '.fusion-builder-empty-container' ).is( ':visible' ) ) { this.$el.find( '.fusion-builder-module-controls-container-wrapper .fusion-builder-module-controls-type-container' ).css( 'margin-top', '8.5px' ); } else { this.$el.find( '.fusion-builder-module-controls-container-wrapper .fusion-builder-module-controls-type-container' ).css( 'margin-top', '' ); } }, /** * Corrects the stacking context if filters are used, to make all elements accessible. * * @since 2.2 * @return {void} */ correctStackingContextForFilters: function() { var parent = this.$el; this.$el.on( 'mouseenter', '.fusion-fullwidth', function() { if ( 'none' !== jQuery( this ).css( 'filter' ) ) { parent.addClass( 'fusion-has-filters' ); } } ); this.$el.on( 'mouseleave', '.fusion-fullwidth', function() { if ( ! parent.hasClass( 'fusion-container-editing-child' ) ) { parent.removeClass( 'fusion-has-filters' ); } } ); }, /** * Renders the view. * * @since 2.0.0 * @return {Object} this */ render: function() { var self = this, data = this.getTemplateAtts(); this.$el.html( this.template( data ) ); this.appendChildren(); if ( this.renderedYet ) { this._refreshJs(); // Trigger equal height columns js jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-option-change-equal_height_columns', this.model.attributes.cid ); } this.onRender(); this.renderedYet = true; setTimeout( function() { self.droppableContainer(); }, 100 ); this._triggerScrollUpdate(); return this; }, /** * Adds drop zones for continers and makes container draggable. * * @since 2.0.0 * @return {void} */ droppableContainer: function() { var $el = this.$el, self = this, cid = this.model.get( 'cid' ), $body = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ); if ( ! $el ) { return; } $el.draggable( { appendTo: FusionPageBuilderApp.$el, zIndex: 999999, delay: 100, cursorAt: { top: 15, left: 15 }, iframeScroll: true, containment: $body, cancel: '.fusion-builder-column', helper: function() { var $classes = FusionPageBuilderApp.DraggableHelpers.draggableClasses( cid ); return jQuery( '
' ); }, start: function() { $body.addClass( 'fusion-container-dragging fusion-active-dragging' ); $el.addClass( 'fusion-being-dragged' ); // Add a class to hide the unnecessary target after. if ( $el.prev( '.fusion-builder-container' ).length ) { $el.prev( '.fusion-builder-container' ).addClass( 'hide-target-after' ); } if ( $el.prev( '.fusion-fusion-builder-next-pager' ).length ) { $el.prev( '.fusion-fusion-builder-next-page' ).addClass( 'hide-target-after' ); } }, stop: function() { setTimeout( function() { $body.removeClass( 'fusion-container-dragging fusion-active-dragging' ); }, 10 ); $el.removeClass( 'fusion-being-dragged' ); FusionPageBuilderApp.$el.find( '.hide-target-after' ).removeClass( 'hide-target-after' ); } } ); $el.find( '.fusion-container-target' ).droppable( { tolerance: 'touch', hoverClass: 'ui-droppable-active', accept: '.fusion-builder-container, .fusion-builder-next-page, .fusion-checkout-form, .fusion-builder-form-step', drop: function( event, ui ) { self.handleDropContainer( ui.draggable, $el, jQuery( event.target ) ); } } ); }, handleDropContainer( $column, $targetEl, $dropTarget ) { // Move the actual html. if ( jQuery( $dropTarget ).hasClass( 'target-after' ) ) { $targetEl.after( $column ); } else { $targetEl.before( $column ); } FusionEvents.trigger( 'fusion-content-changed' ); FusionPageBuilderApp.scrollingContainers(); FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.full_width_section + ' Order Changed' ); }, /** * Get the template. * * @since 2.0.0 * @return {void} */ getTemplate: function() { var atts = this.getTemplateAtts(); return this.template( atts ); }, /** * Remove deprecated params. * * @since 2.0.0 * @return {void} */ deprecatedParams: function() { var params = this.model.get( 'params' ), defaults = fusionAllElements.fusion_builder_container.defaults, values = jQuery.extend( true, {}, defaults, params ), alphaBackgroundColor = 1, radiaDirectionsNew = { 'bottom': 'center bottom', 'bottom center': 'center bottom', 'left': 'left center', 'right': 'right center', 'top': 'center top', 'center': 'center center', 'center left': 'left center' }; params = _.fusionContainerMapDeprecatedArgs( params ); // If no blend mode is defined, check if we should set to overlay. if ( 'undefined' === typeof params.background_blend_mode && '' !== values.background_color ) { alphaBackgroundColor = jQuery.AWB_Color( values.background_color ).alpha(); if ( 1 > alphaBackgroundColor && 0 !== alphaBackgroundColor && ( '' !== params.background_image || '' !== params.video_bg ) ) { params.background_blend_mode = 'overlay'; } } // Check if we have an old border-size. If we do, then we need to migrate it to the new options // and delete the old param. if ( 'undefined' !== typeof params.border_size ) { if ( '' !== params.border_size ) { params.border_sizes_top = parseInt( params.border_size ) + 'px'; params.border_sizes_bottom = parseInt( params.border_size ) + 'px'; params.border_sizes_left = '0px'; params.border_sizes_right = '0px'; } delete params.border_size; } // Correct radial direction params. if ( 'undefined' !== typeof params.radial_direction && ( params.radial_direction in radiaDirectionsNew ) ) { params.radial_direction = radiaDirectionsNew[ values.radial_direction ]; } // No column align, but equal heights is on, set to stretch. if ( 'undefined' === typeof params.flex_align_items && 'undefined' !== typeof params.equal_height_columns && 'yes' === params.equal_height_columns ) { params.flex_align_items = 'stretch'; } // No align content, but it is 100% height and centered. if ( 'undefined' === typeof params.align_content && 'undefined' !== typeof params.hundred_percent_height && 'yes' === params.hundred_percent_height && 'undefined' !== typeof params.hundred_percent_height_center_content && 'yes' === params.hundred_percent_height_center_content ) { params.align_content = 'center'; } // If legacy mode is off, remove param, causes it to run migration and then setType is called. if ( ( 'undefined' === typeof params.type || 'flex' !== params.type ) && 'undefined' !== typeof fusionAllElements.fusion_builder_container.extras.container_legacy_support && ( 0 === fusionAllElements.fusion_builder_container.extras.container_legacy_support || '0' === fusionAllElements.fusion_builder_container.extras.container_legacy_support || false === fusionAllElements.fusion_builder_container.extras.container_legacy_support ) ) { delete params.type; } this.model.set( 'params', params ); }, /** * Set type to ensure migration does not run on front-end. * * @since 3.0 * @return {Void} */ setType: function() { var params = this.model.get( 'params' ), defaults = fusionAllElements.fusion_builder_container.defaults; if ( 'undefined' === typeof params.type ) { params.type = defaults.type; } this.model.set( 'params', params ); }, /** * Get dynamic values. * * @since 2.0.0 * @return {Object} */ getDynamicAtts: function( values ) { var self = this; if ( 'undefined' !== typeof this.dynamicParams && this.dynamicParams && ! _.isEmpty( this.dynamicParams.getAll() ) ) { _.each( this.dynamicParams.getAll(), function( data, id ) { var value = self.dynamicParams.getParamValue( data ); if ( 'undefined' !== typeof value && false !== value ) { values[ id ] = value; } } ); } return values; }, setValues: function() { var element = fusionAllElements[ this.model.get( 'element_type' ) ], defaults = fusionAllElements.fusion_builder_container.defaults, params = jQuery.extend( true, {}, this.model.get( 'params' ) ), extras = {}, values = {}, borderRadius; extras = jQuery.extend( true, {}, fusionAllElements.fusion_builder_container.extras ); // If 100 page template. if ( ( FusionPageBuilderApp.$el.hasClass( 'single-awb_off_canvas' ) || FusionPageBuilderApp.$el.find( '#main' ).hasClass( 'width-100' ) ) && 'undefined' !== typeof extras.container_padding_100 ) { defaults.padding_top = extras.container_padding_100.top; defaults.padding_right = extras.container_padding_100.right; defaults.padding_bottom = extras.container_padding_100.bottom; defaults.padding_left = extras.container_padding_100.left; } else if ( ! FusionPageBuilderApp.$el.find( '#main' ).hasClass( 'width-100' ) && 'undefined' !== typeof extras.container_padding_default ) { defaults.padding_top = extras.container_padding_default.top; defaults.padding_right = extras.container_padding_default.right; defaults.padding_bottom = extras.container_padding_default.bottom; defaults.padding_left = extras.container_padding_default.left; } params = _.fusionCleanParameters( params ); // Set values & extras if ( element && 'undefined' !== typeof element.defaults ) { values = jQuery.extend( true, {}, defaults, params ); } // Default value is an array, so we need to convert it to string. if ( Array.isArray( values.absolute_devices ) ) { values.absolute_devices = values.absolute_devices.join( ',' ); } values = this.getDynamicAtts( values ); this.defaults = defaults; this.values = values; this.params = params; if ( 'on' === this.values.sticky ) { this.values.background_parallax = 'none'; this.values.fade = 'no'; } this.values.border_radius_top_left = this.values.border_radius_top_left ? _.fusionGetValueWithUnit( this.values.border_radius_top_left ) : '0px'; this.values.border_radius_top_right = this.values.border_radius_top_right ? _.fusionGetValueWithUnit( this.values.border_radius_top_right ) : '0px'; this.values.border_radius_bottom_left = this.values.border_radius_bottom_left ? _.fusionGetValueWithUnit( this.values.border_radius_bottom_left ) : '0px'; this.values.border_radius_bottom_right = this.values.border_radius_bottom_right ? _.fusionGetValueWithUnit( this.values.border_radius_bottom_right ) : '0px'; borderRadius = this.values.border_radius_top_left + ' ' + this.values.border_radius_top_right + ' ' + this.values.border_radius_bottom_right + ' ' + this.values.border_radius_bottom_left; if ( '0px 0px 0px 0px' !== borderRadius && '' === this.values.overflow ) { this.values.overflow = 'hidden'; } }, /** * Set extra args. * * @since 2.0.0 * @return {void} */ setExtraValues: function() { this.values.alpha_background_color = jQuery.AWB_Color( this.values.background_color ).alpha(); }, contentStyle: function() { var self = this, contentStyle = ''; if ( 'yes' === this.values.hundred_percent_height && 'yes' === this.values.hundred_percent_height_center_content ) { // Get correct container padding. jQuery.each( [ 'top', 'right', 'bottom', 'left' ], function( index, padding ) { var paddingName = 'padding_' + padding; // Add padding to style. if ( '' !== self.values[ paddingName ] ) { contentStyle += 'padding-' + padding + ':' + _.fusionGetValueWithUnit( self.values[ paddingName ] ) + ';'; } } ); } return contentStyle; }, /** * Sets container video data args. * * @access public * @since 3.0 * @return void */ setContainerVideoData: function() { // If no blend mode is defined, check if we should set to overlay. if ( 'undefined' !== typeof this.values.background_blend_mode && 1 > this.values.alpha_background_color && 0 !== this.values.alpha_background_color && ! this.is_gradient_color && ( this.background_image || this.values.video_bg ) ) { this.values.background_blend_mode = 'overlay'; } this.values.video_bg = false; if ( this.values.video_mp4 || this.values.video_webm || this.values.video_ogv || this.values.video_url ) { this.values.video_bg = true; } }, parallaxAttr: function() { var attr = {}, bgColorAlpha = jQuery.AWB_Color( this.values.background_color ).alpha(); attr[ 'class' ] = 'fusion-bg-parallax'; attr[ 'data-bg-align' ] = this.values.background_position; attr[ 'data-direction' ] = this.values.background_parallax; attr[ 'data-mute' ] = 'mute' === this.values.video_mute ? 'true' : 'false'; attr[ 'data-opacity' ] = this.values.opacity; attr[ 'data-velocity' ] = this.values.parallax_speed * -1; attr[ 'data-mobile-enabled' ] = 'yes' === this.values.enable_mobile ? 'true' : 'false'; attr[ 'data-break_parents' ] = this.values.break_parents; attr[ 'data-bg-image' ] = this.values.background_image; attr[ 'data-bg-repeat' ] = this.values.background_repeat && 'no-repeat' !== this.values.background_repeat ? 'true' : 'false'; if ( 0 !== bgColorAlpha ) { attr[ 'data-bg-color' ] = this.values.background_color; } if ( 'none' !== this.values.background_blend_mode ) { attr[ 'data-blend-mode' ] = this.values.background_blend_mode; } if ( this.values.is_gradient_color ) { attr[ 'data-bg-gradient-type' ] = this.values.gradient_type; attr[ 'data-bg-gradient-angle' ] = this.values.linear_angle; attr[ 'data-bg-gradient-start-color' ] = this.values.gradient_start_color; attr[ 'data-bg-gradient-start-position' ] = this.values.gradient_start_position; attr[ 'data-bg-gradient-end-color' ] = this.values.gradient_end_color; attr[ 'data-bg-gradient-end-position' ] = this.values.gradient_end_position; attr[ 'data-bg-radial-direction' ] = this.values.radial_direction; } attr[ 'data-bg-height' ] = this.values.data_bg_height; attr[ 'data-bg-width' ] = this.values.data_bg_width; return attr; }, isFlex: function() { return this.values && 'flex' === this.values.type; }, attr: function() { var attr = { 'class': 'fusion-fullwidth fullwidth-box fusion-builder-row-live-' + this.model.get( 'cid' ), 'style': this.getInlineStyle(), 'id': '' }; if ( this.isFlex() ) { attr[ 'class' ] += ' fusion-flex-container'; if ( 'stretch' !== this.values.align_content ) { attr[ 'class' ] += ' fusion-flex-align-content-' + this.values.align_content; } } if ( this.values.video_bg ) { attr[ 'class' ] += ' video-background'; } // Fading Background. if ( 'yes' === this.values.fade && '' !== this.values.background_image && false === this.values.video_bg ) { attr[ 'class' ] += ' faded-background'; } // Parallax. if ( false === this.values.video_bg && '' !== this.values.background_image ) { // Parallax css class+ if ( '' !== this.values.background_parallax ) { attr[ 'class' ] += ' fusion-parallax-' + this.values.background_parallax; } if ( 'fixed' === this.values.background_parallax ) { attr.style += 'background-attachment:' + this.values.background_parallax + ';'; } } // Custom CSS class+ if ( '' !== this.values[ 'class' ] ) { attr[ 'class' ] += ' ' + this.values[ 'class' ]; } attr[ 'class' ] += ( 'yes' === this.values.hundred_percent ) ? ' hundred-percent-fullwidth' : ' nonhundred-percent-fullwidth'; attr[ 'class' ] += ( 'yes' === this.values.hundred_percent_height_scroll && 'yes' === this.values.hundred_percent_height ) ? ' fusion-scrolling-section-edit' : ''; attr[ 'class' ] += ( 'yes' === this.values.hundred_percent_height ) ? ' non-hundred-percent-height-scrolling' : ''; attr[ 'class' ] += ( 'yes' === this.values.hundred_percent_height && 'yes' !== this.values.hundred_percent_height_center_content ) ? ' hundred-percent-height' : ''; attr[ 'class' ] += ( 'yes' === this.values.hundred_percent_height && 'yes' === this.values.hundred_percent_height_center_content ) ? ' hundred-percent-height-center-content' : ''; // Equal column height. if ( 'yes' === this.values.equal_height_columns && ! this.isFlex() ) { attr[ 'class' ] += ' fusion-equal-height-columns'; } // Hundred percent height and centered content, if added to centerContentClass then the padding makes the container too large. if ( 'yes' === this.values.hundred_percent_height && 'yes' === this.values.hundred_percent_height_center_content ) { attr[ 'class' ] += ' hundred-percent-height non-hundred-percent-height-scrolling'; } // Visibility classes. let visibilityValue = this.values.hide_on_mobile; // Get Render logics Array. const renderLogicsDevices = this.getRenderLogicsDevices(); if ( renderLogicsDevices.length && 'on' === FusionApp.preferencesData.rendering_logic ) { const rlDevicesEqual = []; const rlDevicesNotEqual = []; renderLogicsDevices.forEach( ( r ) => { switch ( r.value ) { case 'desktop': if ( 'equal' === r.comparison ) { rlDevicesEqual.push( 'large-visibility' ); } else { rlDevicesNotEqual.push( 'large-visibility' ); } break; case 'tablet': if ( 'equal' === r.comparison ) { rlDevicesEqual.push( 'medium-visibility' ); } else { rlDevicesNotEqual.push( 'medium-visibility' ); } break; case 'mobile': if ( 'equal' === r.comparison ) { rlDevicesEqual.push( 'small-visibility' ); } else { rlDevicesNotEqual.push( 'small-visibility' ); } break; case 'mobile_tablet': if ( 'equal' === r.comparison ) { rlDevicesEqual.push( 'medium-visibility' ); rlDevicesEqual.push( 'small-visibility' ); } else { rlDevicesNotEqual.push( 'medium-visibility' ); rlDevicesNotEqual.push( 'small-visibility' ); } break; } } ); if ( rlDevicesEqual.length ) { attr[ 'class' ] = _.fusionVisibilityAtts( rlDevicesEqual.join( ',' ), attr[ 'class' ] ); } if ( rlDevicesNotEqual.length ) { visibilityValue = visibilityValue.split( ',' ).filter( ( v ) => !rlDevicesNotEqual.includes( v ) ); } } attr[ 'class' ] = _.fusionVisibilityAtts( visibilityValue, attr[ 'class' ] ); // Animations. attr = _.fusionAnimations( this.values, attr ); // Custom CSS ID. if ( '' !== this.values.id ) { attr.id = this.values.id; } if ( '' !== this.values.menu_anchor ) { attr.id += ' ' + this.values.menu_anchor; } // Sticky container. if ( 'on' === this.values.sticky ) { attr[ 'class' ] += ' fusion-sticky-container'; if ( '' !== this.values.sticky_transition_offset && 0 !== this.values.sticky_transition_offset ) { attr[ 'data-transition-offset' ] = parseFloat( this.values.sticky_transition_offset ); } if ( '' !== this.values.sticky_offset && 0 !== this.values.sticky_offset ) { attr[ 'data-sticky-offset' ] = this.values.sticky_offset; } if ( '' !== this.values.scroll_offset && 0 !== this.values.scroll_offset ) { attr[ 'data-scroll-offset' ] = parseFloat( this.values.scroll_offset ); } if ( '' !== this.values.sticky_devices ) { if ( 'string' === typeof this.values.sticky_devices ) { this.values.sticky_devices = this.values.sticky_devices.split( ',' ); } _.each( this.values.sticky_devices, function( stickyDevice ) { attr[ 'data-sticky-' + stickyDevice.replace( /\s/g, '' ) ] = true; } ); } } // z-index. if ( 'undefined' !== typeof this.values.z_index && '' !== this.values.z_index ) { attr[ 'class' ] += ' fusion-custom-z-index'; } // Absolute container. if ( 'undefined' !== typeof this.values.absolute && 'on' === this.values.absolute ) { attr[ 'class' ] += ' fusion-absolute-container'; if ( 'undefined' !== typeof this.values.absolute_devices && '' !== this.values.absolute_devices ) { _.each( this.values.absolute_devices.split( ',' ), function( absoluteDevice ) { attr[ 'class' ] += ' fusion-absolute-position-' + absoluteDevice; } ); } } if ( this.values.pattern_bg ) { attr[ 'class' ] += ' has-pattern-background'; } if ( this.values.mask_bg ) { attr[ 'class' ] += ' has-mask-background'; } return attr; }, getInlineStyle: function() { var customVars = {}, cssVars, boxShadow; cssVars = [ 'background_position', 'background_position_medium', 'background_position_small', 'background_repeat', 'background_repeat_medium', 'background_repeat_small', 'background_blend_mode', 'background_blend_mode_medium', 'background_blend_mode_small', 'border_sizes_top', 'border_sizes_bottom', 'border_sizes_left', 'border_sizes_right', 'border_color', 'border_style', 'border_radius_top_left', 'border_radius_top_right', 'border_radius_bottom_right', 'border_radius_bottom_left', 'overflow', 'z_index' ]; // Background. if ( '' !== this.values.background_color && ! ( 'yes' === this.values.fade && '' !== this.values.background_image && false === this.values.video_bg ) ) { customVars.background_color = this.values.background_color; } if ( '' !== this.values.background_color_medium ) { customVars.background_color_medium = this.values.background_color_medium; } if ( '' !== this.values.background_color_small ) { customVars.background_color_small = this.values.background_color_small; } if ( '' !== this.values.background_image && 'yes' !== this.values.fade ) { customVars.background_image = 'url(\'' + this.values.background_image + '\')'; } if ( '' !== this.values.background_image_medium ) { customVars.background_image_medium = 'url(\'' + this.values.background_image_medium + '\')'; } if ( '' !== this.values.background_image_small ) { customVars.background_image_small = 'url(\'' + this.values.background_image_small + '\')'; } if ( '' !== _.getGradientString( this.values, 'main_bg' ) ) { customVars.background_image = _.getGradientString( this.values, 'main_bg' ); if ( '' !== this.values.background_image_medium ) { customVars.background_image_medium = _.getGradientString( this.values, 'column', 'medium' ); } if ( '' !== this.values.background_image_small ) { customVars.background_image_small = _.getGradientString( this.values, 'column', 'small' ); } } if ( 'on' === this.values.sticky ) { if ( '' !== this.values.sticky_background_color ) { customVars.sticky_background_color = this.values.sticky_background_color + ' !important'; } if ( '' !== this.values.sticky_height ) { customVars.sticky_height = this.values.sticky_height + ' !important'; } } if ( undefined !== this.values.flex_wrap && '' !== this.values.flex_wrap ) { customVars.flex_wrap = this.values.flex_wrap; } if ( undefined !== this.values.flex_wrap_medium && '' !== this.values.flex_wrap_medium ) { customVars.flex_wrap_medium = this.values.flex_wrap_medium; } if ( undefined !== this.values.flex_wrap_small && '' !== this.values.flex_wrap_small ) { customVars.flex_wrap_small = this.values.flex_wrap_small; } if ( ! this.isFlex() ) { cssVars.padding_top = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_right = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_left = { 'callback': _.fusionGetValueWithUnit }; cssVars.margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVars.margin_bottom = { 'callback': _.fusionGetValueWithUnit }; } else { cssVars.padding_top = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_right = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_left = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_top_medium = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_right_medium = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_bottom_medium = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_left_medium = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_top_small = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_right_small = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_bottom_small = { 'callback': _.fusionGetValueWithUnit }; cssVars.padding_left_small = { 'callback': _.fusionGetValueWithUnit }; cssVars.margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVars.margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVars.margin_top_medium = { 'callback': _.fusionGetValueWithUnit }; cssVars.margin_bottom_medium = { 'callback': _.fusionGetValueWithUnit }; cssVars.margin_top_small = { 'callback': _.fusionGetValueWithUnit }; cssVars.margin_bottom_small = { 'callback': _.fusionGetValueWithUnit }; // Minimum height. if ( 'min' === this.values.hundred_percent_height ) { cssVars.min_height = { 'callback': this.sanitizeMinHeightArg }; cssVars.min_height_medium = { 'callback': this.sanitizeMinHeightArg }; cssVars.min_height_small = { 'callback': this.sanitizeMinHeightArg }; } } boxShadow = _.awbGetBoxShadowCssVar( '--awb-box-shadow', this.values ); if ( boxShadow ) { boxShadow += 'box-shadow: var(--awb-box-shadow) !important'; } // background size. if ( '' !== this.values.background_image && false === this.values.video_bg ) { if ( 'no-repeat' === this.values.background_repeat ) { customVars.background_size = 'cover'; } } if ( '' !== this.values.background_size ) { const backgroundSize = 'custom' === this.values.background_size ? this.values.background_custom_size : this.values.background_size; customVars.background_size = backgroundSize; } if ( '' !== this.values.background_size_medium ) { const backgroundSizeMedium = 'custom' === this.values.background_size_medium ? this.values.background_custom_size_medium : this.values.background_size_medium; customVars.background_size_medium = backgroundSizeMedium; } if ( '' !== this.values.background_size_small ) { const backgroundSizeSmall = 'custom' === this.values.background_size_small ? this.values.background_custom_size_small : this.values.background_size_small; customVars.background_size_small = backgroundSizeSmall; } return this.getLinkColorStyles( this.values ) + this.getCssVarsForOptions( cssVars ) + this.getCustomCssVars( customVars ) + boxShadow + _.getFilterVars( this.values ); }, getLinkColorStyles: function( values ) { let styles = ''; if ( '' !== values.link_hover_color ) { styles += '--link_hover_color: ' + values.link_hover_color + ';'; } if ( '' !== values.link_color ) { styles += '--link_color: ' + values.link_color + ';'; } return styles; }, getFadingBgVars: function() { var customVars = {}, cssVars; // Fading Background. if ( 'yes' === this.values.fade && '' !== this.values.background_image && false === this.values.video_bg ) { cssVars = [ 'background_color', 'background_position', 'background_position_medium', 'background_position_small', 'background_repeat', 'background_repeat_medium', 'background_repeat_small', 'background_blend_mode', 'background_blend_mode_medium', 'background_blend_mode_small' ]; if ( this.values.background_parallax ) { cssVars.push( 'background_parallax' ); } if ( this.values.background_image ) { customVars.background_image = 'url(' + this.values.background_image + ')'; } if ( this.values.background_image_medium ) { customVars.background_image_medium = 'url(' + this.values.background_image_medium + ')'; } if ( this.values.background_image_small ) { customVars.background_image_small = 'url(' + this.values.background_image_small + ')'; } if ( '' !== _.getGradientString( this.values, 'fade' ) ) { customVars.background_image = _.getGradientString( this.values, 'fade' ); if ( this.values.background_image_medium ) { customVars.background_image_medium = _.getGradientString( this.values, 'fade', 'medium' ); } if ( this.values.background_image_small ) { customVars.background_image_small = _.getGradientString( this.values, 'fade', 'small' ); } } if ( 'no-repeat' === this.values.background_repeat ) { customVars.background_size = 'cover'; } if ( '' !== this.values.background_size ) { const backgroundSize = 'custom' === this.values.background_size ? this.values.background_custom_size : this.values.background_size; customVars.background_size = backgroundSize; } if ( '' !== this.values.background_size ) { const backgroundSizeMedium = 'custom' === this.values.background_size_medium ? this.values.background_custom_size_medium : this.values.background_size_medium; customVars.background_size_medium = backgroundSizeMedium; } if ( '' !== this.values.background_size ) { const backgroundSizeSmall = 'custom' === this.values.background_size_small ? this.values.background_custom_size_small : this.values.background_size_small; customVars.background_size_small = backgroundSizeSmall; } } return this.getCssVarsForOptions( cssVars ) + this.getCustomCssVars( customVars ); }, sanitizeMinHeightArg: function( value ) { if ( '' !== value ) { if ( -1 !== value.indexOf( '%' ) ) { value = value.replace( '%', 'vh' ); } value = _.fusionGetValueWithUnit( value ); } return value; }, createVideoBackground: function() { var videoBackground = '', overlayStyle = '', cid = this.model.get( 'cid' ), videoAttributes, videoPreviewImageStyle, videoUrl, videoSrc, loop; // Videos. if ( 'undefined' !== typeof this.values.video_mp4 && '' !== this.values.video_mp4 ) { videoSrc += ''; } if ( 'undefined' !== typeof this.values.video_webm && '' !== this.values.video_webm ) { videoSrc += ''; } if ( 'undefined' !== typeof this.values.video_ogv && '' !== this.values.video_ogv ) { videoSrc += ''; } if ( '' !== this.values.video_url ) { videoUrl = _.fusionGetVideoProvider( this.values.video_url ), loop = ( 'yes' === this.values.video_loop ? 1 : 0 ); if ( 'youtube' === videoUrl.type ) { videoBackground += '
'; } else if ( 'vimeo' === videoUrl.type ) { videoBackground += ''; } } else { videoAttributes = 'preload="auto" autoplay playsinline'; if ( 'yes' === this.values.video_loop ) { videoAttributes += ' loop'; } if ( 'yes' === this.values.video_mute ) { videoAttributes += ' muted'; } // Video Preview Image. if ( '' !== this.values.video_preview_image ) { videoPreviewImageStyle = 'background-image: url(\'' + this.values.video_preview_image + '\');'; videoBackground += '
'; } videoBackground += '
'; } // Video Overlay. if ( '' !== _.getGradientString( this.values ) ) { overlayStyle += 'background-image:' + _.getGradientString( this.values ) + ';'; } if ( '' !== this.values.background_color && 1 > jQuery.AWB_Color( this.values.background_color ).alpha() ) { overlayStyle += 'background-color:' + this.values.background_color + ';'; } if ( '' !== overlayStyle ) { videoBackground += '
'; } return videoBackground; }, fadingBackgroundAttr: function() { var attr = { class: 'fullwidth-faded', style: this.getFadingBgVars() }; return attr; }, /** * Get template attributes. * * @since 2.0.0 * @return {void} */ getTemplateAtts: function() { var templateAttributes = {}; this.setValues(); this.setExtraValues(); this.setContainerVideoData(); // Remove old parallax bg. if ( this.$el.find( '.fusion-bg-parallax' ).length ) { if ( 'undefined' !== typeof this.$el.find( '.fusion-bg-parallax' ).data( 'parallax-index' ) ) { jQuery( '#fb-preview' )[ 0 ].contentWindow._fusionImageParallaxImages.splice( this.$el.find( '.fusion-bg-parallax' ).data( 'parallax-index' ), 1 ); } this.$el.find( '.fusion-bg-parallax' ).remove(); this.$el.find( '.parallax-inner' ).remove(); } templateAttributes.values = this.values; templateAttributes.attr = this.attr(); templateAttributes.parallax = this.parallaxAttr(); templateAttributes.createVideoBackground = _.bind( this.createVideoBackground, this ); templateAttributes.fadingBackground = this.fadingBackgroundAttr(); templateAttributes.admin_label = ( '' !== this.values.admin_label ) ? _.unescape( this.values.admin_label ) : fusionBuilderText.full_width_section; templateAttributes.topOverlap = ( 20 > parseInt( this.values.padding_top, 10 ) && ( '0%' === this.values.padding_top || -1 === this.values.padding_top.indexOf( '%' ) ) ) ? 'fusion-overlap' : ''; templateAttributes.bottomOverlap = ( 20 > parseInt( this.values.padding_bottom, 10 ) && ( '0%' === this.values.padding_bottom || -1 === this.values.padding_bottom.indexOf( '%' ) ) ) ? 'fusion-overlap' : ''; templateAttributes.isFlex = this.isFlex(); templateAttributes.isGlobal = ( 'undefined' !== typeof this.values.fusion_global ) ? 'yes' : 'no'; templateAttributes.cid = this.model.get( 'cid' ); templateAttributes.status = this.values.status; templateAttributes.container_tag = this.values.container_tag; templateAttributes.scrollPosition = ( 'right' === FusionApp.settings.header_position || jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).hasClass( 'rtl' ) ) ? 'scroll-navigation-left' : 'scroll-navigation-right'; templateAttributes.contentStyle = this.contentStyle(); templateAttributes.patternBg = _.fusionGetPatternElement( this.values ); templateAttributes.maskBg = _.fusionGetMaskElement( this.values ); templateAttributes.bgSlider = _.fusionGetBackgroundSliderElement( this ); return templateAttributes; }, triggerScrollUpdate: function() { setTimeout( function() { FusionPageBuilderApp.scrollingContainers(); }, 100 ); }, beforePatch: function() { if ( this.$el.find( '.fusion-bg-parallax' ).length ) { if ( 'object' === typeof jQuery( '#fb-preview' )[ 0 ].contentWindow._fusionImageParallaxImages && 'undefined' !== typeof this.$el.find( '.fusion-bg-parallax' ).attr( 'data-parallax-index' ) ) { jQuery( '#fb-preview' )[ 0 ].contentWindow._fusionImageParallaxImages.splice( this.$el.find( '.fusion-bg-parallax' ).attr( 'data-parallax-index' ), 1 ); } } }, /** * Runs after view DOM is patched. * * @since 2.0.0 * @return null */ afterPatch: function() { var self = this; this.appendChildren(); // Using non debounced version for smoothness. this.refreshJs(); this._triggerScrollUpdate(); setTimeout( function() { self.droppableContainer(); }, 100 ); if ( 'yes' === this.model.attributes.params.hundred_percent_height && 'yes' === this.model.attributes.params.hundred_percent_height_scroll ) { this.$el.addClass( 'scrolling-helper' ); } else { this.$el.removeClass( 'scrolling-helper' ); } this.setSettingsControlsOffset( true ); this._reInitSticky(); if ( this.reInitDraggables ) { this.updateDragHandles(); } }, /** * Triggers a refresh. * * @since 2.0.0 * @return void */ refreshJs: function( cid ) { cid = 'undefined' === typeof cid ? this.model.attributes.cid : cid; jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-element-render-fusion_builder_container', cid ); jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-reinit-carousels', cid ); jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-reinit-masonry', cid ); jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-reinit-background-slider', cid ); }, /** * Adds a container. * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ addContainer: function( event ) { var elementID, defaultParams, params, value, newContainer; if ( event ) { event.preventDefault(); FusionPageBuilderApp.newContainerAdded = true; } elementID = FusionPageBuilderViewManager.generateCid(); defaultParams = fusionAllElements.fusion_builder_container.params; params = {}; // Process default options for shortcode. _.each( defaultParams, function( param ) { value = ( _.isObject( param.value ) ) ? param[ 'default' ] : param.value; params[ param.param_name ] = value; if ( 'dimension' === param.type && _.isObject( param.value ) ) { _.each( param.value, function( val, name ) { params[ name ] = val; } ); } } ); this.collection.add( [ { type: 'fusion_builder_container', added: 'manually', element_type: 'fusion_builder_container', cid: elementID, params: params, view: this, created: 'auto' } ] ); // Make sure to add row to new container not current one. newContainer = FusionPageBuilderViewManager.getView( elementID ); newContainer.addRow(); FusionPageBuilderApp.scrollingContainers(); }, /** * Adds a row. * * @since 2.0.0 * @return {void} */ addRow: function() { this.collection.add( [ { type: 'fusion_builder_row', element_type: 'fusion_builder_row', added: 'manually', cid: FusionPageBuilderViewManager.generateCid(), parent: this.model.get( 'cid' ), view: this, element_content: '' } ] ); }, /** * Removes the container. * * @since 2.0.0 * @param {Object} event - The event. * @param {boolean|undefined} skip - Should we skip this? * @param {bool} forceManually - Force manually, even if it's not an event, to update history and trigger content changes. * @return {void} */ removeContainer: function( event, skip, forceManually ) { var rows; if ( event ) { event.preventDefault(); } rows = FusionPageBuilderViewManager.getChildViews( this.model.get( 'cid' ) ); _.each( rows, function( row ) { if ( 'fusion_builder_row' === row.model.get( 'type' ) ) { row.removeRow(); } } ); FusionPageBuilderViewManager.removeView( this.model.get( 'cid' ) ); this.model.destroy(); FusionEvents.trigger( 'fusion-element-removed', this.model.get( 'cid' ) ); this.remove(); // If its the last container add empty page view. if ( 1 > FusionPageBuilderViewManager.countElementsByType( 'fusion_builder_container' ) && 'undefined' === typeof skip ) { FusionPageBuilderApp.blankPage = true; FusionPageBuilderApp.clearBuilderLayout( true ); } // If the column is deleted manually. if ( event || forceManually ) { FusionPageBuilderApp.scrollingContainers(); FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.deleted_section ); FusionEvents.trigger( 'fusion-content-changed' ); } }, /** * Clones a container. * * @since 2.0.0 * @param {Object} event - The event. * @return {void} */ cloneContainer: function( event ) { var containerAttributes, $thisContainer; if ( event ) { event.preventDefault(); } containerAttributes = jQuery.extend( true, {}, this.model.attributes ); containerAttributes.cid = FusionPageBuilderViewManager.generateCid(); containerAttributes.created = 'manually'; containerAttributes.view = this; FusionPageBuilderApp.collection.add( containerAttributes ); $thisContainer = this.$el; // Parse rows $thisContainer.find( '.fusion-builder-row-container:not(.fusion_builder_row_inner .fusion-builder-row-container)' ).each( function() { var thisRow = jQuery( this ), rowCID = thisRow.data( 'cid' ), rowView, // Get model from collection by cid. row = FusionPageBuilderElements.find( function( model ) { return model.get( 'cid' ) == rowCID; // jshint ignore: line } ), // Clone row. rowAttributes = jQuery.extend( true, {}, row.attributes ); rowAttributes.created = 'manually'; rowAttributes.cid = FusionPageBuilderViewManager.generateCid(); rowAttributes.parent = containerAttributes.cid; FusionPageBuilderApp.collection.add( rowAttributes ); // Make sure spacing is calculated. rowView = FusionPageBuilderViewManager.getView( rowAttributes.cid ); // Parse columns thisRow.find( '.fusion-builder-column-outer' ).each( function() { // Parse column elements var thisColumn = jQuery( this ), $columnCID = thisColumn.data( 'cid' ), // Get model from collection by cid column = FusionPageBuilderElements.find( function( model ) { return model.get( 'cid' ) == $columnCID; // jshint ignore: line } ), // Clone column columnAttributes = jQuery.extend( true, {}, column.attributes ); columnAttributes.created = 'manually'; columnAttributes.cid = FusionPageBuilderViewManager.generateCid(); columnAttributes.parent = rowAttributes.cid; columnAttributes.from = 'fusion_builder_container'; columnAttributes.cloned = true; // Don't need target element, position is defined from order. delete columnAttributes.targetElementPosition; FusionPageBuilderApp.collection.add( columnAttributes ); // Find column elements thisColumn.find( '.fusion-builder-column-content:not( .fusion-nested-column-content )' ).children( '.fusion-builder-live-element, .fusion_builder_row_inner' ).each( function() { var thisElement, elementCID, element, elementAttributes, thisInnerRow, InnerRowCID, innerRowView; // Regular element if ( jQuery( this ).hasClass( 'fusion-builder-live-element' ) ) { thisElement = jQuery( this ); elementCID = thisElement.data( 'cid' ); // Get model from collection by cid element = FusionPageBuilderElements.find( function( model ) { return model.get( 'cid' ) == elementCID; // jshint ignore: line } ); // Clone model attritubes elementAttributes = jQuery.extend( true, {}, element.attributes ); elementAttributes.created = 'manually'; elementAttributes.cid = FusionPageBuilderViewManager.generateCid(); elementAttributes.parent = columnAttributes.cid; elementAttributes.from = 'fusion_builder_container'; // Don't need target element, position is defined from order. delete elementAttributes.targetElementPosition; FusionPageBuilderApp.collection.add( elementAttributes ); // Inner row element } else if ( jQuery( this ).hasClass( 'fusion_builder_row_inner' ) ) { thisInnerRow = jQuery( this ); InnerRowCID = thisInnerRow.data( 'cid' ); innerRowView = FusionPageBuilderViewManager.getView( InnerRowCID ); // Clone inner row if ( 'undefined' !== typeof innerRowView ) { innerRowView.cloneNestedRow( '', columnAttributes.cid ); } } } ); } ); // Update spacing for columns. rowView.setRowData(); } ); FusionPageBuilderApp.scrollingContainers(); FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.cloned_section ); FusionEvents.trigger( 'fusion-content-changed' ); this._refreshJs( containerAttributes.cid ); }, /** * Adds a child view. * * @param {Object} element - The element model. * @return {void} */ addChildView: function( element ) { var view, viewSettings = { model: element, collection: FusionPageBuilderElements }; view = new FusionPageBuilder.RowView( viewSettings ); FusionPageBuilderViewManager.addView( element.get( 'cid' ), view ); if ( this.$el.find( '.fusion-builder-container-content' ).length ) { this.$el.find( '.fusion-builder-container-content' ).append( view.render().el ); } else { this.$el.find( '> .fusion-builder-add-element' ).hide().end().append( view.render().el ); } // Add parent view to inner rows that have been converted from shortcodes if ( 'manually' === element.get( 'created' ) && 'row_inner' === element.get( 'element_type' ) ) { element.set( 'view', FusionPageBuilderViewManager.getView( element.get( 'parent' ) ), { silent: true } ); } }, /** * Appends model children. * * @since 2.0.0 * @return {void} */ appendChildren: function() { var self = this, cid, view; this.model.children.each( function( child ) { cid = child.attributes.cid; view = FusionPageBuilderViewManager.getView( cid ); self.$el.find( '.fusion-builder-container-content' ).append( view.$el ); view.delegateEvents(); view.delegateChildEvents(); view.droppableColumn(); } ); }, /** * Triggers event to reinit sticky container properties. * * @since 3.0 * @return {void} */ reInitSticky: function() { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-reinit-sticky', this.model.attributes.cid ); }, /** * Set empty spacing for legacy and re-render. * * @since 3.0.0 * @return {void} */ setEmptySpacing: function() { var params = this.model.get( 'params' ); params.flex_column_spacing = '0px'; this.model.set( 'params', params ); }, /** * Things to do, places to go when options change. * * @since 2.0.0 * @param {string} paramName - The name of the parameter that changed. * @param {mixed} paramValue - The value of the option that changed. * @param {Object} event - The event triggering the option change. * @return {void} */ onOptionChange: function( paramName, paramValue, event ) { var reInitDraggables = false, dimensionType = _.find( [ 'spacing_', 'margin_', 'padding_' ], function( type ) { return paramName.includes( type ); } ); // Reverted to history step or user entered value manually. if ( 'undefined' === typeof event || ( 'undefined' !== typeof event && ( 'change' !== event.type || ( 'change' === event.type && 'undefined' !== typeof event.srcElement ) ) ) ) { reInitDraggables = true; } if ( dimensionType ) { this.model.attributes.params[ paramName ] = paramValue; if ( true === reInitDraggables ) { if ( 'padding_' === dimensionType ) { this.destroyPaddingResizable(); this.paddingDrag(); } else { this.destroyMarginResizable(); this.marginDrag(); } } } switch ( paramName ) { case 'admin_label': this.model.attributes.params[ paramName ] = paramValue.replace( /[[\]]+/g, '' ); break; // Changing between legacy and flex. case 'type': this.model.attributes.params[ paramName ] = paramValue; this.values.type = paramValue; this.reRenderRows(); this.updateResponsiveSetup(); break; // Sticky options. case 'sticky': case 'sticky_devices': case 'sticky_height': case 'sticky_offset': case 'sticky_transition_offset': case 'scroll_offset': this._reInitSticky(); break; // Changing options which alter row if in flex mode. case 'flex_column_spacing': this._updateInnerStyles(); break; case 'absolute': if ( 'on' === paramValue && ! this.$el.hasClass( 'fusion-builder-absolute-container-wrapper' ) ) { this.$el.addClass( 'fusion-builder-absolute-container-wrapper' ); } else if ( 'off' === paramValue && this.$el.hasClass( 'fusion-builder-absolute-container-wrapper' ) ) { this.$el.removeClass( 'fusion-builder-absolute-container-wrapper' ); } break; case 'render_logics': this.reRender(); jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-column-resized', this.model.attributes.cid ); FusionEvents.trigger( 'fusion-column-resized' ); break; } }, /** * Re-renders the rows. * * @since 3.0 * @return {void} */ reRenderRows: function() { var rows = FusionPageBuilderViewManager.getChildViews( this.model.get( 'cid' ) ); // TODO: check this for performance. Ideally we just update params, not re-render row. _.each( rows, function( row ) { row.modeChange(); } ); }, /** * Updates the styles inside container. * * @since 3.0 * @return {void} */ updateInnerStyles: function() { var rows = FusionPageBuilderViewManager.getChildViews( this.model.get( 'cid' ) ); _.each( rows, function( row ) { row.updateInnerStyles(); } ); }, /** * Updates responsive setup. * * @since 3.0 * @return {void} */ updateResponsiveSetup: function() { var $settings = jQuery( '.fusion_builder_module_settings' ); this.isFlex() ? $settings.addClass( 'has-flex' ) : $settings.removeClass( 'has-flex' ); }, /** * Gets the contents of the container. * * @since 2.0.0 * @return {string} */ getContent: function() { var shortcode = ''; shortcode += FusionPageBuilderApp.generateElementShortcode( this.$el, true ); this.$el.find( '.fusion_builder_row' ).each( function() { var $thisRow = jQuery( this ); shortcode += '[fusion_builder_row]'; $thisRow.find( '.fusion-builder-column-outer' ).each( function() { var $thisColumn = jQuery( this ), columnCID = $thisColumn.data( 'cid' ), columnView = FusionPageBuilderViewManager.getView( columnCID ); shortcode += columnView.getColumnContent(); } ); shortcode += '[/fusion_builder_row]'; } ); shortcode += '[/fusion_builder_container]'; return shortcode; }, /** * Get the save label. * * @since 2.0.0 * @return {string} */ getSaveLabel: function() { return fusionBuilderText.save_section; }, /** * Returns the 'sections' string. * * @since 2.0.0 * @return {string} */ getCategory: function() { return 'sections'; }, /** * Handle margin adjustments on drag. * * @since 2.0.0 * @return {void} */ marginDrag: function() { var $el = this.$el, self = this, directions = { top: 's', bottom: 's' }, parentWidth = $el.closest( '.fusion-row, .fusion-builder-live-editor' ).width(); if ( this.$el.hasClass( 'active' ) ) { return; } _.each( directions, function( handle, direction ) { var optionKey = FusionApp.getResponsiveOptionKey( 'margin_' + direction, self.isFlex() ), actualDimension = self.values[ optionKey ] || self.values[ 'margin_' + direction ] || 0, percentSpacing = false; percentSpacing = actualDimension && actualDimension.includes( '%' ); if ( percentSpacing ) { // Get actual dimension and set. actualDimension = ( parentWidth / 100 ) * parseFloat( actualDimension ); $el.find( '.fusion-container-margin-' + direction ).css( 'height', actualDimension ); if ( 'bottom' === direction && 20 > actualDimension ) { $el.find( '.fusion-container-margin-bottom, .fusion-container-padding-bottom' ).addClass( 'fusion-overlap' ); } } $el.find( '.fusion-container-margin-' + direction ).css( 'display', 'block' ); $el.find( '.fusion-container-margin-' + direction ).height( actualDimension ); $el.find( '.fusion-container-margin-' + direction ).resizable( { handles: handle, minHeight: 0, minWidth: 0, grid: ( percentSpacing ) ? [ parentWidth / 100, 10 ] : '', create: function() { if ( 'bottom' === direction ) { if ( 20 > parseInt( actualDimension, 10 ) && ! percentSpacing ) { $el.find( '.fusion-container-margin-bottom, .fusion-container-padding-bottom' ).addClass( 'fusion-overlap' ); } else { $el.find( '.fusion-container-margin-bottom, .fusion-container-padding-bottom' ).removeClass( 'fusion-overlap' ); } } }, resize: function( event, ui ) { var optionKey = FusionApp.getResponsiveOptionKey( 'margin_' + direction, self.isFlex() ), actualDimension = self.values[ optionKey ] || 0, percentSpacing = false, value = 'top' === direction || 'bottom' === direction ? ui.size.height : ui.size.width; jQuery( ui.element ).addClass( 'active' ); // Recheck in case unit is changed in the modal. percentSpacing = actualDimension && actualDimension.includes( '%' ); jQuery( ui.element ).closest( '.fusion-builder-container' ).addClass( 'active' ); value = 0 > value ? 0 : value; value = value + 'px'; if ( percentSpacing ) { value = 0 === parseFloat( value ) ? '0%' : Math.round( parseFloat( parseFloat( value ) / ( parentWidth / 100 ) ) ) + '%'; } // Bottom margin overlap if ( 'bottom' === direction ) { if ( 20 > ui.size.height ) { jQuery( ui.element ).addClass( 'fusion-overlap' ); $el.find( '.fusion-container-padding-bottom' ).addClass( 'fusion-overlap' ); } else { jQuery( ui.element ).removeClass( 'fusion-overlap' ); $el.find( '.fusion-container-padding-bottom' ).removeClass( 'fusion-overlap' ); } } // Legacy update. if ( ! self.isFlex() ) { $el.find( '.fusion-fullwidth' ).css( 'margin-' + direction, value ); } jQuery( ui.element ).find( '.fusion-spacing-tooltip, .fusion-column-spacing' ).addClass( 'active' ); jQuery( ui.element ).find( '.fusion-spacing-tooltip' ).text( value ); // Update open modal. self.updateDragSettings( '#' + optionKey, value ); }, stop: function( event, ui ) { jQuery( ui.element ).removeClass( 'active' ); jQuery( ui.element ).closest( '.fusion-builder-container' ).removeClass( 'active' ); // Delete all spacing resizable within because parent width has changed. if ( jQuery( ui.element ).closest( '.fusion-builder-container' ).find( '.fusion-column-spacing .ui-resizable' ).length ) { jQuery( ui.element ).closest( '.fusion-builder-container' ).find( '.fusion-column-spacing .ui-resizable' ).resizable( 'destroy' ); } } } ); } ); }, /** * Checks if the container needs to run through legacy conversion. * * @since 3.0.0 * @return {boolean} */ needsLegacyConversion: function() { var params = this.model.get( 'params' ); return 'undefined' === typeof params.type; }, /** * Handle padding adjustments on drag. * * @since 2.0.0 * @return {void} */ paddingDrag: function() { var $el = this.$el, self = this, directions = { top: 's', right: 'w', bottom: 's', left: 'e' }, parentWidth = $el.closest( '.fusion-row, .fusion-builder-live-editor' ).width(), defaults; if ( this.$el.hasClass( 'active' ) ) { return; } defaults = this.defaults; _.each( directions, function( handle, direction ) { var actualDimension, previewSize = FusionApp.getPreviewWindowSize(), percentSpacing = false; if ( 'small' === previewSize ) { actualDimension = self.values[ 'padding_' + direction + '_small' ]; } if ( ! actualDimension && [ 'small', 'medium' ].includes( previewSize ) ) { actualDimension = self.values[ 'padding_' + direction + '_medium' ]; } if ( ! actualDimension ) { actualDimension = self.values[ 'padding_' + direction ]; } actualDimension = actualDimension || defaults[ 'padding_' + direction ] || 0; // Check if using a percentage. percentSpacing = actualDimension && actualDimension.includes( '%' ); if ( percentSpacing ) { // Get actual dimension and set. actualDimension = ( parentWidth / 100 ) * parseFloat( actualDimension ); if ( 'top' === direction || 'bottom' === direction ) { $el.find( '.fusion-container-padding-' + direction ).css( 'height', actualDimension ); } else { $el.find( '.fusion-container-padding-' + direction ).css( 'width', actualDimension ); } if ( 'top' === direction && 20 > actualDimension ) { $el.find( '.fusion-container-margin-top, .fusion-container-padding-top' ).addClass( 'fusion-overlap' ); } } $el.find( '.fusion-container-padding-' + direction ).css( 'display', 'block' ); if ( 'top' === direction || 'bottom' === direction ) { $el.find( '.fusion-container-padding-' + direction ).height( actualDimension ); } else { $el.find( '.fusion-container-padding-' + direction ).width( actualDimension ); } $el.find( '.fusion-container-padding-' + direction ).resizable( { handles: handle, minHeight: 0, minWidth: 0, create: function() { if ( 'top' === direction ) { if ( 20 > parseInt( actualDimension, 10 ) && ! percentSpacing ) { $el.find( '.fusion-container-margin-top, .fusion-container-padding-top' ).addClass( 'fusion-overlap' ); } else { $el.find( '.fusion-container-margin-top, .fusion-container-padding-top' ).removeClass( 'fusion-overlap' ); } } }, resize: function( event, ui ) { var optionKey = FusionApp.getResponsiveOptionKey( 'padding_' + direction, self.isFlex() ), actualDimension = self.values[ optionKey ], percentSpacing = false, value = 'top' === direction || 'bottom' === direction ? ui.size.height : ui.size.width; percentSpacing = actualDimension && actualDimension.includes( '%' ); jQuery( ui.element ).addClass( 'active' ); jQuery( ui.element ).closest( '.fusion-builder-container' ).addClass( 'active' ); value = 0 > value ? 0 : value; value = value + 'px'; if ( percentSpacing ) { value = 0 === parseFloat( value ) ? '0%' : Math.round( parseFloat( parseFloat( value ) / ( parentWidth / 100 ) ) ) + '%'; } // Top padding overlap if ( 'top' === direction ) { if ( 20 > ui.size.height ) { jQuery( ui.element ).addClass( 'fusion-overlap' ); $el.find( '.fusion-container-margin-top' ).addClass( 'fusion-overlap' ); } else { jQuery( ui.element ).removeClass( 'fusion-overlap' ); $el.find( '.fusion-container-margin-top' ).removeClass( 'fusion-overlap' ); } } // Set values and width. $el.children( '.fusion-fullwidth' ).css( '--awb-' + optionKey.replaceAll( '_', '-' ), value ); jQuery( ui.element ).find( '.fusion-spacing-tooltip, .fusion-column-spacing' ).addClass( 'active' ); jQuery( ui.element ).find( '.fusion-spacing-tooltip' ).text( value ); // Update open modal. self.updateDragSettings( '#' + optionKey, value ); }, stop: function( event, ui ) { jQuery( ui.element ).removeClass( 'active' ); jQuery( ui.element ).closest( '.fusion-builder-container' ).removeClass( 'active' ); // Delete all spacing resizable within because parent width has changed. if ( jQuery( ui.element ).closest( '.fusion-builder-container' ).find( '.fusion-column-spacing .ui-resizable' ).length ) { jQuery( ui.element ).closest( '.fusion-builder-container' ).find( '.fusion-column-spacing .ui-resizable' ).resizable( 'destroy' ); } } } ); } ); }, /** * Destroy container resizable. * * @since 2.0.0 * @return {void} */ destroyResizable: function() { this.destroyMarginResizable(); this.destroyPaddingResizable(); }, /** * Destroy container margin resizable. * * @since 2.0.0 * @return {void} */ destroyMarginResizable: function() { var $containerSpacer = this.$el.find( '.fusion-container-margin-top, .fusion-container-margin-bottom' ); jQuery.each( $containerSpacer, function( index, spacer ) { if ( jQuery( spacer ).hasClass( 'ui-resizable' ) ) { jQuery( spacer ).resizable( 'destroy' ); jQuery( spacer ).hide(); } } ); }, /** * Destroy container padding resizable. * * @since 2.0.0 * @return {void} */ destroyPaddingResizable: function() { var $containerSpacer = this.$el.find( '.fusion-container-padding-top, .fusion-container-padding-right, .fusion-container-padding-bottom, .fusion-container-padding-left' ); jQuery.each( $containerSpacer, function( index, spacer ) { if ( jQuery( spacer ).hasClass( 'ui-resizable' ) ) { jQuery( spacer ).resizable( 'destroy' ); jQuery( spacer ).hide(); } } ); }, /** * Filter out DOM before patching. * * @since 2.0.0 * @return {void} */ patcherFilter: function( diff ) { var filteredDiff = [], self = this; self.reInitDraggables = false; _.each( diff, function( info ) { if ( 'removeElement' === info.action ) { if ( 'undefined' !== typeof info.element.attributes && 'undefined' !== typeof info.element.attributes[ 'class' ] && -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-fullwidth' ) ) { self.reInitDraggables = true; filteredDiff.push( info ); } else if ( 'undefined' !== typeof info.element.attributes && 'undefined' !== typeof info.element.attributes[ 'class' ] && -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-container-spacing' ) ) { // Ignore. } else { filteredDiff.push( info ); } } else if ( 'addElement' === info.action ) { if ( 'undefined' !== typeof info.element.attributes && 'undefined' !== typeof info.element.attributes[ 'class' ] && -1 !== info.element.attributes[ 'class' ].indexOf( 'fusion-container-spacing' ) ) { // Ignore. } else { filteredDiff.push( info ); } } else { filteredDiff.push( info ); } } ); return filteredDiff; }, publish: function( event ) { var cid = jQuery( event.currentTarget ).data( 'cid' ), view = FusionPageBuilderViewManager.getView( cid ), params = view.model.get( 'params' ); FusionApp.confirmationPopup( { title: fusionBuilderText.container_publish, content: fusionBuilderText.are_you_sure_you_want_to_publish, actions: [ { label: fusionBuilderText.no, classes: 'no', callback: function() { FusionApp.confirmationPopup( { action: 'hide' } ); } }, { label: fusionBuilderText.yes, classes: 'yes', callback: function() { params.status = 'published'; view.model.set( 'params', params ); view.$el.find( 'a[data-cid="' + cid + '"].fusion-builder-publish-tooltip' ).remove(); FusionEvents.trigger( 'fusion-history-turn-on-tracking' ); FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.container_published ); FusionEvents.trigger( 'fusion-content-changed' ); FusionApp.confirmationPopup( { action: 'hide' } ); } } ] } ); }, unglobalize: function( event ) { var cid = jQuery( event.currentTarget ).data( 'cid' ), view = FusionPageBuilderViewManager.getView( cid ), params = view.model.get( 'params' ); event.preventDefault(); FusionApp.confirmationPopup( { title: fusionBuilderText.remove_global, content: fusionBuilderText.are_you_sure_you_want_to_remove_global, actions: [ { label: fusionBuilderText.no, classes: 'no', callback: function() { FusionApp.confirmationPopup( { action: 'hide' } ); } }, { label: fusionBuilderText.yes, classes: 'yes', callback: function() { // Remove global attributes. delete params.fusion_global; view.model.set( 'params', params ); view.$el.removeClass( 'fusion-global-container fusion-global-column fusion-global-nested-row fusion-global-element fusion-global-parent-element' ); view.$el.find( 'a[data-cid="' + cid + '"].fusion-builder-unglobal-tooltip' ).remove(); view.$el.removeAttr( 'fusion-global-layout' ); FusionEvents.trigger( 'fusion-history-turn-on-tracking' ); FusionEvents.trigger( 'fusion-history-save-step', fusionBuilderText.removed_global ); FusionEvents.trigger( 'fusion-content-changed' ); FusionApp.confirmationPopup( { action: 'hide' } ); } } ] } ); }, /** * Fires when preview are is resized. * * @since 3.0 * @return {void} */ onPreviewResize: function() { if ( ! this.isFlex() ) { return; } if ( this.$el.hasClass( 'fusion-builder-element-edited' ) ) { this.updateDragHandles(); } }, /** * Updates column sizes controls. * * @since 3.0 * @return {void} */ updateDragHandles: function() { this.destroyResizable(); this.marginDrag(); this.paddingDrag(); }, /** * Runs just after render on cancel. * * @since 3.5 * @return null */ beforeGenerateShortcode: function() { var elementType = this.model.get( 'element_type' ), options = fusionAllElements[ elementType ].params, values = jQuery.extend( true, {}, fusionAllElements[ elementType ].defaults, _.fusionCleanParameters( this.model.get( 'params' ) ) ); if ( 'object' !== typeof options ) { return; } // If images needs replaced lets check element to see if we have media being used to add to object. if ( 'undefined' !== typeof FusionApp.data.replaceAssets && FusionApp.data.replaceAssets && ( 'undefined' !== typeof FusionApp.data.fusion_element_type || 'fusion_template' === FusionApp.getPost( 'post_type' ) ) ) { this.mapStudioImages( options, values ); if ( '' !== values.video_mp4 ) { // If its not within object already, add it. if ( 'undefined' === typeof FusionPageBuilderApp.mediaMap.videos[ values.video_mp4 ] ) { FusionPageBuilderApp.mediaMap.videos[ values.video_mp4 ] = true; } } } }, /** * check if String is JSON string. * * @since 3.7 * @return boolean */ IsJsonString: function( str ) { try { const json = JSON.parse( str ); return ( 'object' === typeof json ); } catch ( e ) { return false; } }, /** * Get render logics devices. * * @since 3.7 * @return boolean */ getRenderLogicsDevices: function( value ) { value = value || this.values.render_logics; let renderLogics = value && this.IsJsonString( atob( value ) ) ? JSON.parse( atob( value ) ) : []; // Get device Render logics only. renderLogics = renderLogics.filter( ( r ) => 'device_type' === r.field ); return renderLogics; } } ); } ); }( jQuery ) ); ;/* global FusionEvents */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Studio import modal view. FusionPageBuilder.StudioImportModalView = window.wp.Backbone.View.extend( { template: FusionPageBuilder.template( jQuery( '#fusion-builder-studio-import-modal' ).html() ), className: 'fusion-builder-studio-import-modal', events: { 'click .awb-admin-modal-corner-close': 'closeModal' }, /** * Renders the view. * * @since 3.5.0 * @return {Object} this */ render: function() { this.$el.html( this.template() ); return this; }, /** * Updates modal status. * * @since 3.5.0 * @param {String} status - New status text. * @return {void} */ updateStatus: function( status ) { this.$el.find( '.awb-admin-modal-status-bar .awb-admin-modal-status-bar-label' ).html( status ); }, /** * Updates modal progress. * * @since 3.5.0 * @param {Object} avadaMedia - Avada Media object, all things we need to import. * @param {String} currentImportKey - Object key which is currently being imported. * @return {void} */ updateProgressBar: function( avadaMedia, currentImportKey ) { var mediaKeys = Object.keys( avadaMedia ), progress = ( mediaKeys.indexOf( currentImportKey ) + 1 ) / mediaKeys.length; this.$el.find( '.awb-admin-modal-status-bar .awb-admin-modal-status-bar-progress-bar' ).css( 'width', ( 100 * progress ) + '%' ); }, /** * Remove the view. * * @since 3.5.0 * @param {Object} event - The event triggering the element removal. * @return {void} */ closeModal: function( event ) { if ( event ) { event.preventDefault(); } FusionEvents.trigger( 'awb-studio-import-modal-closed' ); this.remove(); } } ); } ); }( jQuery ) ); ;/* global FusionPageBuilderApp, FusionPageBuilderViewManager, fusionBuilderText, fusionAllElements, FusionEvents */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { let isClipboardEnabled; if ( 'clipboard' in navigator ) { navigator.clipboard.readText().then( ( clipboardContent ) => { isClipboardEnabled = true; } ).catch( error => { isClipboardEnabled = false; console.log( error ); } ) } else { isClipboardEnabled = false; } // Builder Container View FusionPageBuilder.ContextMenuView = window.wp.Backbone.View.extend( { template: FusionPageBuilder.template( jQuery( '#fusion-builder-context-menu' ).html() ), className: 'fusion-builder-context-menu', events: { 'click [data-action="edit"]': 'editTrigger', 'click [data-action="save"]': 'saveTrigger', 'click [data-action="clone"]': 'cloneTrigger', 'click [data-action="remove"]': 'removeTrigger', 'click [data-action="copy"]': 'copy', 'click [data-action="paste-before"]': 'pasteBefore', 'click [data-action="paste-after"]': 'pasteAfter', 'click [data-action="paste-start"]': 'pasteStart', 'click [data-action="paste-end"]': 'pasteEnd', 'click [data-action="invert"]': 'invertTrigger' }, /** * Initialize the builder sidebar. * * @since 2.0.0 * @return {void} */ initialize: function() { this.copyData = { data: { type: false, content: false } }; this.getCopy(); this.elWidth = 130; this.elHeight = 257; }, /** * Renders the view. * * @since 2.0.0 * @return {Object} this */ render: function() { if ( isClipboardEnabled ) { const self = this; navigator.clipboard.readText().then( ( clipboardContent ) => { if ( 'string' === typeof clipboardContent && '' !== clipboardContent ) { const data = JSON.parse( clipboardContent ) if ( 'object' === typeof data && 'undefined' !== typeof data.type && 'undefined' !== typeof data.content ) { self.copyData.data.type = data.type self.copyData.data.content = data.content } } self.doRender() } ).catch( error => { console.error( 'Error storing content from clipboard: ' + error ) self.doRender() } ) } else { this.doRender(); } return this; }, /** * Do the rendering of the view. * * @since 3.11.10 * @return {void} */ doRender: function() { var leftOffset = this.model.event.pageX, topOffset = this.model.event.pageY; this.$el.html( this.template( jQuery.extend( true, this.copyData, this.model.parent.attributes ) ) ); if ( this.model.event.pageX + this.elWidth > jQuery( '#fb-preview' ).width() ) { leftOffset = jQuery( '#fb-preview' ).width() - this.elWidth; } if ( this.model.event.pageY + this.elHeight > jQuery( jQuery( '#fb-preview' )[ 0 ].contentWindow.document ).height() ) { topOffset = jQuery( jQuery( '#fb-preview' )[ 0 ].contentWindow.document ).height() - this.elHeight; } this.$el.css( { top: ( topOffset ) + 'px', left: ( leftOffset ) + 'px' } ); }, /** * Trigger edit on relevant element. * * @since 2.0.0 */ editTrigger: function( event ) { if ( 'fusion_builder_row_inner' === this.model.parent.attributes.element_type ) { this.model.parentView.editRow( event ); } else { this.model.parentView.settings( event ); } }, /** * Trigger save on relavent element. * * @since 2.0.0 */ saveTrigger: function( event ) { this.model.parentView.openLibrary( event ); }, /** * Trigger clone on relavent element. * * @since 2.0.0 */ cloneTrigger: function( event ) { switch ( this.model.parent.attributes.element_type ) { case 'fusion_builder_container': this.model.parentView.cloneContainer( event ); break; case 'fusion_builder_column_inner': case 'fusion_builder_column': this.model.parentView.cloneColumn( event ); break; case 'fusion_builder_row_inner': this.model.parentView.cloneNestedRow( event ); break; case 'fusion_builder_form_step': this.model.parentView.cloneSpecialElement( event ); break; default: this.model.parentView.cloneElement( event ); break; } }, /** * Trigger remove on relavent element. * * @since 2.0.0 */ removeTrigger: function( event ) { switch ( this.model.parent.attributes.element_type ) { case 'fusion_builder_form_step': case 'fusion_builder_container': this.model.parentView.removeContainer( event ); break; case 'fusion_builder_column_inner': case 'fusion_builder_column': this.model.parentView.removeColumn( event ); break; case 'fusion_builder_row_inner': this.model.parentView.removeRow( event ); break; default: this.model.parentView.removeElement( event ); break; } }, /** * Copy the element. * * @since 2.0.0 */ copy: function() { var type = this.model.parent.attributes.element_type, content = this.model.parentView.getContent(), $temp = jQuery( ''; elementHtml = this.generateIconHtml( atts, elementHtml ); html = this.generateLabelHtml( html, elementHtml, elementData.label ); return html; } } ); } ); }( jQuery ) ); ;var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Fusion Form Time View. FusionPageBuilder.fusion_form_time = FusionPageBuilder.FormComponentView.extend( { /** * Modify template attributes. * * @since 3.1 * @param {Object} atts - The attributes object. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}; // Create attribute objects; attributes.styles = this.buildStyles( atts.values ); attributes.html = this.generateFormFieldHtml( this.generateTimeField( atts.values ) ); return attributes; }, generateTimeField: function( values ) { var elementData, elementHtml, html = '', input_type = 'type="time"'; elementData = this.elementData( values ); this.generateTooltipHtml( values, elementData ); if ( 'custom' === values.picker || 'desktop' === values.picker ) { input_type = 'type="text"'; } elementHtml = ''; elementHtml = this.generateIconHtml( values, elementHtml ); html = this.generateLabelHtml( html, elementHtml, elementData.label ); return html; }, onRender: function() { this.afterPatch(); }, beforePatch: function() { var picker; if ( 'function' === typeof jQuery( '#fb-preview' )[ 0 ].contentWindow.flatpickr ) { picker = jQuery( '#fb-preview' )[ 0 ].contentWindow.flatpickr( '#time-' + this.model.get( 'cid' ), {} ); if ( picker && 'function' === typeof picker.destroy ) { picker.destroy(); } } }, /** * Runs after view DOM is patched. * * @since 2.0 * @return {void} */ afterPatch: function() { var self = this; setTimeout( function() { var $item = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( self.$el.find( 'input[type="time"]' ) ), type = $item.attr( 'data-type' ), useMobile = 'custom' === type, fullClock = 'full' === $item.attr( 'data-clock' ); // Native, do not init. if ( 'native' === type || 'function' !== typeof $item.flatpickr ) { return; } $item.flatpickr( { allowInput: true, disableMobile: useMobile, enableTime: true, noCalendar: true, dateFormat: 'H:i', time_24hr: fullClock } ); }, 200 ); } } ); } ); }( jQuery ) ); ;/* global fusionBuilderText */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Fusion Form Upload View. FusionPageBuilder.fusion_form_upload = FusionPageBuilder.FormComponentView.extend( { /** * Modify template attributes. * * @since 3.1 * @param {Object} atts - The attributes object. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}; // Create attribute objects; attributes.html = this.generateFormFieldHtml( this.generateUploadField( atts.values ) ); return attributes; }, generateUploadField: function ( atts ) { var elementData, elementHtml, html = ''; atts[ 'class' ] = ( '' !== atts[ 'class' ] ) ? atts[ 'class' ] + ' fusion-form-file-upload' : 'fusion-form-file-upload'; elementData = this.elementData( atts ); elementData = this.generateTooltipHtml( atts, elementData ); elementData.multiple = 'yes' === atts.multiple ? ' multiple' : ''; elementData.name = atts.name; elementData.multiple = ''; if ( 'yes' === atts.multiple ) { elementData.name += '[]'; elementData.multiple = ' multiple'; } elementData.accept = 'undefined' !== typeof atts.extensions && '' !== atts.extensions ? 'accept="' + atts.extensions + '"' : ''; elementHtml = '
'; elementHtml += ''; elementHtml += ''; elementHtml += '' + fusionBuilderText.choose_file + ''; elementHtml += '
'; elementHtml = this.generateIconHtml( atts, elementHtml ); elementHtml = this.generateIconWrapperHtml( elementHtml ); html = this.generateLabelHtml( html, elementHtml, elementData.label ); return html; } } ); } ); }( jQuery ) ); ;/* global FusionApp */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Woo Checkout Billing Component View. FusionPageBuilder.fusion_post_card_image = FusionPageBuilder.ElementView.extend( { /** * Modify template attributes. * * @since 3.3 * @param {Object} atts - The attributes. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}; this.values = atts.values; // Any extras that need passed on. attributes.cid = this.model.get( 'cid' ); attributes.wrapperAttr = this.buildAttr( atts.values ); attributes.output = this.buildOutput( atts ); return attributes; }, /** * Builds attributes. * * @since 3.3 * @param {Object} values - The values object. * @return {Object} */ buildAttr: function( values ) { var attr = _.fusionVisibilityAtts( values.hide_on_mobile, { class: 'fusion-' + FusionApp.settings.woocommerce_product_box_design + '-product-image-wrapper fusion-woo-product-image fusion-post-card-image fusion-post-card-image-' + this.model.get( 'cid' ), style: this.getStyleVariables( values ) } ); if ( '' !== values[ 'class' ] ) { attr[ 'class' ] += ' ' + values[ 'class' ]; } if ( '' !== values.aspect_ratio ) { attr[ 'class' ] += ' has-aspect-ratio'; } if ( '' !== values.id ) { attr.id = values.id; } attr = _.fusionAnimations( values, attr ); return attr; }, /** * Builds output. * * @since 3.3 * @param {Object} values - The values object. * @return {String} */ buildOutput: function( atts ) { var output = ''; if ( 'undefined' !== typeof atts.markup && 'undefined' !== typeof atts.markup.output && 'undefined' === typeof atts.query_data ) { output = jQuery( jQuery.parseHTML( atts.markup.output ) ).filter( '.fusion-woo-product-image' ).html(); output = ( 'undefined' === typeof output ) ? atts.markup.output : output; } else if ( 'undefined' !== typeof atts.query_data && 'undefined' !== typeof atts.query_data.fusion_post_card_image ) { output = atts.query_data.fusion_post_card_image; } return output; }, /** * Gets style variables. * * @since 3.9 * @return {String} */ getStyleVariables: function( values ) { var cssVarsOptions = [ 'crossfade_bg_color', 'swap_nav_color', 'swap_nav_color_hover', 'aspect_ratio_position' ], customVars = [], aspectRatio, width, height; cssVarsOptions.swap_nav_height = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.border_radius_top_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.border_radius_top_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.border_radius_bottom_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.border_radius_bottom_left = { 'callback': _.fusionGetValueWithUnit }; if ( 'custom' === values.aspect_ratio && '' !== values.custom_aspect_ratio ) { customVars.aspect_ratio = `100 / ${values.custom_aspect_ratio}`; } else { aspectRatio = values.aspect_ratio.split( '-' ); width = aspectRatio[ 0 ] || ''; height = aspectRatio[ 1 ] || ''; customVars.aspect_ratio = `${width} / ${height}`; } return this.getCssVarsForOptions( cssVarsOptions ) + this.getCustomCssVars( customVars ); } } ); } ); }( jQuery ) ); ;/* global fusionBuilderText */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Woo Related Component View. FusionPageBuilder.fusion_tb_woo_upsells = FusionPageBuilder.WooProductsView.extend( { /** * Define shortcode handle. * * @since 3.2 */ shortcode_handle: 'fusion_tb_woo_upsells', /** * Define shortcode classname. * * @since 3.2 */ shortcode_classname: 'fusion-woo-upsells-tb', /** * Builds attributes. * * @since 3.2 * @param {Object} values - The values object. * @return {Object} */ buildAttr: function( values ) { var attr = FusionPageBuilder.WooProductsView.prototype.buildAttr.call( this, values ); if ( 'up-sells' === this.query_data.query_type ) { attr[ 'class' ] += ' up-sells upsells products'; } else { attr[ 'class' ] += ' fusion-woo-cross-sells products cross-sells'; } return attr; }, /** * Get section title based on the post type. * * @since 3.2 * @return {string} */ getSectionTitle: function() { if ( 'up-sells' === this.query_data.query_type ) { return fusionBuilderText.upsells_products; } return fusionBuilderText.cross_sells_products; } } ); } ); }( jQuery ) ); ;var FusionPageBuilder = FusionPageBuilder || {}; ( function () { jQuery( document ).ready( function () { // Post Card Cart Component View. FusionPageBuilder.fusion_post_card_cart = FusionPageBuilder.ElementView.extend( { onInit: function() { var params = this.model.get( 'params' ); // Check for newer margin params. If unset but regular is, copy from there. if ( 'object' === typeof params ) { // Split border width into 4. if ( 'undefined' === typeof params.button_border_top && 'undefined' !== typeof params.button_border_width && '' !== params.button_border_width ) { params.button_border_top = parseInt( params.button_border_width ) + 'px'; params.button_border_right = params.button_border_top; params.button_border_bottom = params.button_border_top; params.button_border_left = params.button_border_top; delete params.button_border_width; } // Split border width into 4. if ( 'undefined' === typeof params.button_details_border_top && 'undefined' !== typeof params.button_details_border_width && '' !== params.button_details_border_width ) { params.button_details_border_top = parseInt( params.button_details_border_width ) + 'px'; params.button_details_border_right = params.button_details_border_top; params.button_details_border_bottom = params.button_details_border_top; params.button_details_border_left = params.button_details_border_top; delete params.button_details_border_width; } this.model.set( 'params', params ); } }, afterPatch: function () { var $quantityBoxes = this.$el.find( 'div.quantity:not(.buttons_added), td.quantity:not(.buttons_added)' ).find( '.qty' ), $form = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( this.$el.find( '.variations_form' ) ); if ( $quantityBoxes.length && 'function' === typeof jQuery( '#fb-preview' )[ 0 ].contentWindow.avadaAddQuantityBoxes ) { jQuery( '#fb-preview' )[ 0 ].contentWindow.avadaAddQuantityBoxes( '.qty', $quantityBoxes ); } if ( $form.length && 'function' === typeof $form.wc_variation_form ) { $form.wc_variation_form(); $form.on( 'hide_variation', function( e ) { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( e.currentTarget ).find( '.avada-variation' ).closest( 'tr' ).addClass( 'awb-hide-element' ); } ).on( 'found_variation.wc-variation-form', function( e ) { if ( jQuery.trim( jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( e.currentTarget ).find( '.avada-variation' ).text() ).length ) { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( e.currentTarget ).find( '.avada-variation' ).closest( 'tr' ).removeClass( 'awb-hide-element' ); } } ); this.$el.find( '.awb-post-card-cart-cart-wrapper' ).appendTo( $form ); } }, /** * Modify template attributes. * * @since 3.3 * @param {Object} atts - The attributes. * @return {Object} */ filterTemplateAtts: function ( atts ) { var attributes = {}; this.values = atts.values; this.extras = atts.extras; this.query_data = atts.query_data; this.setIconDefaults(); // Validate values. this.validateArgs(); // Any extras that need passed on. attributes.cid = this.model.get( 'cid' ); attributes.wrapperAttr = this.buildAttr( atts.values ); attributes.output = this.buildOutput( atts ); return attributes; }, /** * Modify template attributes. * * @since 3.5 * @return {void} */ validateArgs: function() { this.values.button_icon = this.values.button_icon.replace( 'fusion-prefix-', '' ); }, /** * Set default icons for text links * * @since 3.3 */ setIconDefaults: function() { if ( 'custom' !== this.values.button_style ) { this.values.icon_position = 'left'; this.values.button_icon = 'fa-shopping-cart fas'; } if ( 'custom' !== this.values.product_link_style ) { this.values.icon_details_position = 'left'; this.values.button_details_icon = 'fa-list-ul fas'; } }, /** * Builds attributes. * * @since 3.3 * @param {Object} values - The values object. * @return {Object} */ buildAttr: function ( values ) { var attr = _.fusionVisibilityAtts( values.hide_on_mobile, { class: 'fusion-woo-cart fusion-post-card-cart', style: this.getStyleVars() } ); if ( '' !== values[ 'class' ] ) { attr[ 'class' ] += ' ' + values[ 'class' ]; } attr[ 'class' ] += ' awb-variation-layout-' + this.values.variation_layout; attr[ 'class' ] += ' awb-variation-clear-' + this.values.variation_clear; attr[ 'class' ] += ' awb-label-' + this.values.show_label; if ( '' !== values.variation_text_align ) { attr[ 'class' ] += ' awb-variation-text-align-' + values.variation_text_align; } attr[ 'class' ] += ' awb-add-to-cart-style-' + ( '' === this.values.button_style ? 'link' : 'button' ); attr[ 'class' ] += ' awb-product-style-' + ( '' === this.values.product_link_style ? 'link' : 'button' ); if ( '' !== values.id ) { attr.id = values.id; } attr = _.fusionAnimations( values, attr ); return attr; }, /** * Builds output. * * @since 3.3 * @param {Object} values - The values object. * @return {String} */ buildOutput: function ( atts ) { var quantity = '', buttons = '', output = ''; if ( 'yes' === atts.values.show_variations && 'variable' === this.getProductType() && 'undefined' !== typeof atts.query_data && 'undefined' !== typeof atts.query_data.fusion_post_card_cart ) { output = atts.query_data.fusion_post_card_cart; } if ( 'yes' === atts.values.show_add_to_cart_button ) { buttons += this.buildAddToCart( ); } if ( 'yes' === atts.values.show_product_link_button ) { buttons += this.buildProductDetails( ); } if ( 'yes' === atts.values.show_quantity_input ) { quantity = this.buildQuantity( ); } // Add wrapper. if ( 'yes' === atts.values.show_variations && 'variable' === this.getProductType() ) { quantity = '
' + quantity; } output += quantity; if ( this.has_buttons_wrapper() ) { output += '
'; } output += buttons; if ( this.has_buttons_wrapper() ) { output += '
'; } // Closing wrapper. if ( 'yes' === atts.values.show_variations && 'variable' === this.getProductType() ) { output += '
'; } return output; }, /** * Builds Quantity * * @since 3.3 * @return {String} */ buildQuantity: function ( ) { var output = '
' + '
' + '' + '' + '
'; return output; }, /** * Builds Add to cart button * * @since 3.3 * @return {String} */ buildAddToCart: function ( ) { var output = '', button_class = [ 'fusion-post-card-cart-add-to-cart' ]; if ( '' === this.values.button_size ) { button_class.push( 'fusion-button-default-size' ); } if ( 'custom' === this.values.button_style ) { button_class.push( 'button-default' ); } output = ''; if ( '' !== this.values.button_icon && 'left' === this.values.icon_position ) { output += ''; } output += this.extras.add_to_cart_text; if ( '' !== this.values.button_icon && 'right' === this.values.icon_position ) { output += ''; } output += ''; return output; }, /** * Builds Details/Quick view button * * @since 3.3 * @return {String} */ buildProductDetails: function ( ) { var output = ''; var button_class = '' === this.values.button_details_size ? ' fusion-button-default-size' : ''; button_class += 'custom' === this.values.product_link_style ? ' button-default' : ''; if ( '1' === this.values.enable_quick_view || 'yes' === this.values.enable_quick_view ) { output = ''; if ( '' !== this.values.button_details_icon && 'left' === this.values.icon_details_position ) { output += ''; } output += this.extras.quick_view_text; if ( '' !== this.values.button_details_icon && 'right' === this.values.icon_details_position ) { output += ''; } output += ''; } else { output = ''; if ( '' !== this.values.button_details_icon && 'left' === this.values.icon_details_position ) { output += ''; } output += this.extras.details_text; if ( '' !== this.values.button_details_icon && 'right' === this.values.icon_details_position ) { output += ''; } output += ''; } return output; }, /** * Checks if buttons wrapper needed * * @since 3.3 * @param {Object} values - The values object. * @return {Boolean} */ has_buttons_wrapper: function () { return ( 'yes' === this.values.show_product_link_button || 'yes' === this.values.show_add_to_cart_button ) && ! ( 'floated' === this.values.cart_layout && 'floated' === this.values.buttons_layout && 'no' === this.values.buttons_stretch ); }, /** * Builds styles. * * @since 3.3 * @param {Object} values - The values object. * @return {String} */ getStyleVars: function () { var customVars = {}, cssVarsOptions = [], buttonSizeMap = { small: { padding: '9px 20px', line_height: '14px', font_size: '12px' }, medium: { padding: '11px 23px', line_height: '16px', font_size: '13px' }, large: { padding: '13px 29px', line_height: '17px', font_size: '14px' }, xlarge: { padding: '17px 40px', line_height: '21px', font_size: '18px' } }, width, buttonDimensions; cssVarsOptions.margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left = { 'callback': _.fusionGetValueWithUnit }; if ( 'floated' === this.values.cart_layout ) { customVars[ 'justify-content' ] = this.values.justify; customVars[ 'align-items' ] = 'center'; } else { customVars[ 'flex-direction' ] = 'column'; customVars[ 'align-items' ] = this.values.align; } if ( 'yes' === this.values.show_add_to_cart_button ) { cssVarsOptions.button_margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_margin_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_margin_left = { 'callback': _.fusionGetValueWithUnit }; } if ( 'yes' === this.values.show_product_link_button ) { cssVarsOptions.button_details_margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_details_margin_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_details_margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_details_margin_left = { 'callback': _.fusionGetValueWithUnit }; } // Button wrapper if both buttons are used. if ( this.has_buttons_wrapper() ) { if ( 'floated' === this.values.buttons_layout ) { customVars[ 'button-align-items' ] = 'center'; if ( 'stacked' === this.values.cart_layout ) { customVars[ 'button-justify-content' ] = this.values.buttons_justify; } } else if ( 'stacked' === this.values.buttons_layout ) { customVars[ 'button-flex-direction' ] = 'column'; customVars[ 'button-align-items' ] = this.values.buttons_alignment; } // Button wrapper expand full width. if ( 'yes' === this.values.buttons_stretch ) { customVars[ 'button-a-justify-content' ] = 'center'; // Stacked buttons next to quantity. if ( 'floated' === this.values.cart_layout ) { if ( 'stacked' === this.values.buttons_layout ) { customVars[ 'button-flex' ] = '1'; customVars[ 'button-align-items' ] = 'stretch'; } else { customVars[ 'button-flex' ] = '1'; customVars[ 'button-a-flex' ] = '1'; } } else if ( 'stacked' === this.values.buttons_layout ) { customVars[ 'button-align-items' ] = 'stretch'; } else { customVars[ 'button-a-flex' ] = '1'; } } } if ( 'custom' === this.values.quantity_style ) { cssVarsOptions.quantity_margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.quantity_margin_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.quantity_margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.quantity_margin_left = { 'callback': _.fusionGetValueWithUnit }; // Quantity height. if ( ! this.isDefault( 'quantity_height' ) ) { customVars[ 'quantity-height' ] = _.fusionGetValueWithUnit( this.values.quantity_height ); } // Quantity width. width = '36px'; if ( ! this.isDefault( 'quantity_width' ) ) { width = _.fusionGetValueWithUnit( this.values.quantity_width ); if ( width.includes( '%' ) ) { customVars[ 'quantity-width' ] = 'calc( 100% - var(--awb-quantity-height) - var(--awb-quantity-height) )'; } else { customVars[ 'quantity-width' ] = width; } } // Quantity wrapper. if ( ! this.isDefault( 'quantity_width' ) || ! this.isDefault( 'quantity_height' ) ) { customVars[ 'quantity-wrapper-width' ] = 'calc( ' + width + ' + var(--awb-quantity-height) + var(--awb-quantity-height) )'; } cssVarsOptions.quantity_radius_top_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.quantity_radius_bottom_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.quantity_radius_bottom_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.quantity_radius_top_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.quantity_font_size = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.quantity_border_sizes_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.quantity_border_sizes_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.quantity_border_sizes_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.quantity_border_sizes_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.push( 'quantity_color' ); cssVarsOptions.push( 'quantity_background' ); cssVarsOptions.push( 'quantity_border_color' ); cssVarsOptions.qbutton_border_sizes_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.qbutton_border_sizes_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.qbutton_border_sizes_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.qbutton_border_sizes_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.push( 'qbutton_color' ); cssVarsOptions.push( 'qbutton_background' ); cssVarsOptions.push( 'qbutton_border_color' ); cssVarsOptions.push( 'qbutton_color_hover' ); cssVarsOptions.push( 'qbutton_background_hover' ); cssVarsOptions.push( 'qbutton_border_color_hover' ); } if ( 'custom' === this.values.button_style ) { // Button size. if ( ! this.isDefault( 'button_size' ) ) { if ( 'object' === typeof buttonSizeMap[ this.values.button_size ] ) { buttonDimensions = buttonSizeMap[ this.values.button_size ]; customVars[ 'button-padding' ] = buttonDimensions.padding; customVars[ 'button-line-height' ] = buttonDimensions.line_height; customVars[ 'button-font-size' ] = buttonDimensions.font_size; } } cssVarsOptions.button_border_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_border_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_border_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_border_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.push( 'button_color' ); cssVarsOptions.push( 'button_border_color' ); cssVarsOptions.push( 'button_color_hover' ); cssVarsOptions.push( 'button_border_color_hover' ); // Button gradient. if ( 'string' === typeof this.values.button_gradient_top && '' !== this.values.button_gradient_top ) { cssVarsOptions.push( 'button_gradient_top' ); } if ( 'string' === typeof this.values.button_gradient_bottom && '' !== this.values.button_gradient_bottom ) { cssVarsOptions.push( 'button_gradient_bottom' ); } else if ( 'string' === typeof this.values.button_gradient_top && '' !== this.values.button_gradient_top ) { customVars[ 'button-gradient-bottom' ] = this.values.button_gradient_top; } if ( 'string' === typeof this.values.button_gradient_top_hover && '' !== this.values.button_gradient_top_hover ) { cssVarsOptions.push( 'button_gradient_top_hover' ); } if ( 'string' === typeof this.values.button_gradient_bottom_hover && '' !== this.values.button_gradient_bottom_hover ) { cssVarsOptions.push( 'button_gradient_bottom_hover' ); } else if ( 'string' === typeof this.values.button_gradient_top_hover && '' !== this.values.button_gradient_top_hover ) { customVars[ 'button-gradient-bottom-hover' ] = this.values.button_gradient_top_hover; } } else { cssVarsOptions.push( 'link_color' ); cssVarsOptions.push( 'link_hover_color' ); cssVarsOptions.link_font_size = { 'callback': _.fusionGetValueWithUnit }; } if ( 'custom' === this.values.product_link_style ) { // Button size. if ( ! this.isDefault( 'button_details_size' ) ) { if ( 'object' === typeof buttonSizeMap[ this.values.button_details_size ] ) { buttonDimensions = buttonSizeMap[ this.values.button_details_size ]; customVars[ 'button-details-padding' ] = buttonDimensions.padding; customVars[ 'button-details-line-height' ] = buttonDimensions.line_height; customVars[ 'button-details-font-size' ] = buttonDimensions.font_size; } } cssVarsOptions.button_details_border_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_details_border_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_details_border_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_details_border_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.push( 'button_details_color' ); cssVarsOptions.push( 'button_details_border_color' ); if ( 'string' === typeof this.values.button_details_gradient_top && '' !== this.values.button_details_gradient_top ) { cssVarsOptions.push( 'button_details_gradient_top' ); } if ( 'string' === typeof this.values.button_details_gradient_bottom && '' !== this.values.button_details_gradient_bottom ) { cssVarsOptions.push( 'button_details_gradient_bottom' ); } else if ( 'string' === typeof this.values.button_details_gradient_top && '' !== this.values.button_details_gradient_top ) { customVars[ 'button-details-gradient-bottom' ] = this.values.button_details_gradient_top; } if ( 'string' === typeof this.values.button_details_gradient_top_hover && '' !== this.values.button_details_gradient_top_hover ) { cssVarsOptions.push( 'button_details_gradient_top_hover' ); } if ( 'string' === typeof this.values.button_details_gradient_bottom_hover && '' !== this.values.button_details_gradient_bottom_hover ) { cssVarsOptions.push( 'button_details_gradient_bottom_hover' ); } else if ( 'string' === typeof this.values.button_details_gradient_top_hover && '' !== this.values.button_details_gradient_top_hover ) { customVars[ 'button-details-gradient-bottom-hover' ] = this.values.button_details_gradient_top_hover; } cssVarsOptions.push( 'button_details_color_hover' ); cssVarsOptions.push( 'button_details_border_color_hover' ); } else { cssVarsOptions.push( 'product_link_color' ); cssVarsOptions.push( 'product_link_hover_color' ); cssVarsOptions.product_link_font_size = { 'callback': _.fusionGetValueWithUnit }; } if ( 'floated' === this.values.variation_layout && ! this.isDefault( 'variation_label_area_width' ) ) { cssVarsOptions.variation_label_area_width = { 'callback': _.fusionGetValueWithUnit }; } // Variation Label Typo. cssVarsOptions.push( 'label_color' ); cssVarsOptions.label_font_size = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.push( 'label_line_height' ); cssVarsOptions.label_letter_spacing = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.push( 'label_text_transform' ); // Font family and weight. jQuery.each( _.fusionGetFontStyle( 'label_typography', this.values, 'object' ), function( rule, value ) { customVars[ 'label-typography-' + rule ] = value; } ); // Select variation type styling. if ( ! this.isDefault( 'select_style' ) ) { cssVarsOptions.select_height = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.select_font_size = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.push( 'select_line_height' ); cssVarsOptions.select_letter_spacing = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.push( 'select_text_transform' ); // Font family and weight. jQuery.each( _.fusionGetFontStyle( 'select_typography', this.values, 'object' ), function( rule, value ) { customVars[ 'select-typography-' + rule ] = value; } ); cssVarsOptions.push( 'select_color' ); cssVarsOptions.push( 'select_background' ); cssVarsOptions.push( 'select_border_color' ); cssVarsOptions.select_border_sizes_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.select_border_sizes_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.select_border_sizes_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.select_border_sizes_left = { 'callback': _.fusionGetValueWithUnit }; // Border separator with arrow. if ( ! this.isDefault( 'select_border_color' ) && ! this.isDefault( 'select_border_sizes_right' ) && ! this.isDefault( 'select_border_sizes_left' ) ) { customVars[ 'arrow-border-left' ] = _.fusionGetValueWithUnit( this.values.select_border_sizes_left ) + ' solid ' + this.values.select_border_color; } cssVarsOptions.border_radius_top_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.border_radius_top_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.border_radius_bottom_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.border_radius_bottom_left = { 'callback': _.fusionGetValueWithUnit }; } // Swatch styling if enabled. if ( ! this.isDefault( 'swatch_style' ) ) { cssVarsOptions.swatch_margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.swatch_margin_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.swatch_margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.swatch_margin_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.push( 'swatch_background_color' ); cssVarsOptions.push( 'swatch_border_color' ); cssVarsOptions.push( 'swatch_background_color_active' ); cssVarsOptions.swatch_border_sizes_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.swatch_border_sizes_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.swatch_border_sizes_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.swatch_border_sizes_left = { 'callback': _.fusionGetValueWithUnit }; if ( ! this.isDefault( 'swatch_border_color_active' ) ) { cssVarsOptions.push( 'swatch_border_color_active' ); customVars.swatch_border_color_hover = jQuery.AWB_Color( this.values.swatch_border_color_active ).alpha( 0.5 ).toVarOrRgbaString(); } cssVarsOptions.color_swatch_height = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.color_swatch_padding_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.color_swatch_padding_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.color_swatch_padding_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.color_swatch_padding_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.color_swatch_padding_left = { 'callback': _.fusionGetValueWithUnit }; // Color swatch. if ( ! this.isDefault( 'color_swatch_width' ) ) { customVars.color_swatch_width = 'auto' === this.values.color_swatch_width ? 'auto' : _.fusionGetValueWithUnit( this.values.color_swatch_width ); } cssVarsOptions.color_swatch_border_radius_top_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.color_swatch_border_radius_top_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.color_swatch_border_radius_bottom_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.color_swatch_border_radius_bottom_left = { 'callback': _.fusionGetValueWithUnit }; // Image swatch. cssVarsOptions.image_swatch_height = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.image_swatch_padding_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.image_swatch_padding_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.image_swatch_padding_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.image_swatch_padding_left = { 'callback': _.fusionGetValueWithUnit }; if ( ! this.isDefault( 'image_swatch_width' ) ) { customVars.color_swatch_width = 'auto' === this.values.image_swatch_width ? 'auto' : _.fusionGetValueWithUnit( this.values.image_swatch_width ); customVars.color_swatch_image_width = 'auto' !== this.values.image_swatch_width ? '100%' : 'auto'; } cssVarsOptions.image_swatch_border_radius_top_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.image_swatch_border_radius_top_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.image_swatch_border_radius_bottom_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.image_swatch_border_radius_bottom_left = { 'callback': _.fusionGetValueWithUnit }; // Button swatch. cssVarsOptions.button_swatch_height = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_swatch_padding_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_swatch_padding_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_swatch_padding_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_swatch_padding_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_swatch_border_radius_top_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_swatch_border_radius_top_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_swatch_border_radius_bottom_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_swatch_border_radius_bottom_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.button_swatch_font_size = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.push( 'button_swatch_color' ); cssVarsOptions.push( 'button_swatch_color_active' ); if ( ! this.isDefault( 'button_swatch_width' ) ) { customVars.button_swatch_width = 'auto' === this.values.button_swatch_width ? 'auto' : _.fusionGetValueWithUnit( this.values.button_swatch_width ); } } return this.getCustomCssVars( customVars ) + this.getCssVarsForOptions( cssVarsOptions ); }, /** * Get product type. * * @since 3.8.1 * @param {Object} values - The values object. * @return {String} */ getProductType: function () { var product_type = 'simple'; if ( 'undefined' !== typeof this.query_data && 'undefined' !== typeof this.query_data.product_type ) { product_type = this.query_data.product_type; } return product_type; } } ); } ); }( jQuery ) ); ;/* global FusionApp */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { FusionPageBuilder.fusion_facebook_page = FusionPageBuilder.ElementView.extend( { /** * Modify template attributes. * * @since 2.0 * @param {Object} atts - The attributes object. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}; this.values = atts.values; // Create attribute objects attributes.atts = this.buildAttr( atts.values ); // Any extras that need passed on. attributes.cid = this.model.get( 'cid' ); attributes.values = atts.values; return attributes; }, /** * Builds attributes. * * @since 2.0 * @param {Object} values - The values object. * @return {Object} */ buildAttr: function( values ) { var attr = { style: '' }; if ( '' !== values.id ) { attr.id = values.id; } attr[ 'class' ] = 'fusion-facebook-page fb-page fusion-facebook-page-' + this.model.get( 'cid' ) + ' ' + values[ 'class' ]; attr = _.fusionVisibilityAtts( values.hide_on_mobile, attr ); attr[ 'data-language' ] = values.language || 'en_US'; if ( '' !== values.href ) { attr[ 'data-href' ] = values.href; } if ( '' !== values.tabs ) { attr[ 'data-tabs' ] = values.tabs; } if ( '' !== values.width ) { attr[ 'data-width' ] = values.width; } if ( '' !== values.height ) { attr[ 'data-height' ] = values.height; } if ( 'small' === values.header ) { attr[ 'data-small_header' ] = 'true'; } if ( 'hide' === values.cover ) { attr[ 'data-hide_cover' ] = 'true'; } if ( 'hide' === values.cta ) { attr[ 'data-hide_cta' ] = 'true'; } if ( 'on' === values.lazy ) { attr[ 'data-lazy' ] = 'true'; } if ( 'hide' === values.facepile ) { attr[ 'data-show_facepile' ] = 'false'; } if ( '' !== values.alignment ) { attr.style += 'display:flex; justify-content:' + values.alignment + ';'; } attr.style += this.getStyleVariables(); //Animation attr = _.fusionAnimations( values, attr ); return attr; }, /** * Gets style variables. * * @since 3.9 * @return {String} */ getStyleVariables: function() { const cssVarsOptions = []; cssVarsOptions.margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_top_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_top_small = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right_small = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom_small = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left_small = { 'callback': _.fusionGetValueWithUnit }; return this.getCssVarsForOptions( cssVarsOptions ); }, /** * refresh the script to change language dynamically. * * @since 3.7 * @return void */ refreshScript: function() { const lang = this.model.attributes.params.language || 'en_US'; delete FusionApp.previewWindow.FB; ( function ( d, s, id ) { let js = d.getElementById( id ); if ( js ) { js.parentNode.removeChild( js ); } // remove script tag if exists js = d.createElement( s ); js.id = id; js.src = `https://connect.facebook.net/${lang}/sdk.js#xfbml=1&version=v12.0`; d.body.appendChild( js ); }( FusionApp.previewWindow.document, 'script', 'facebook-jssdk' ) ); this._refreshJs(); }, /** * Triggers a refresh. * * @since 2.0.0 * @return void */ refreshJs: function() { if ( 'undefined' !== typeof FusionApp.previewWindow.FB ) { FusionApp.previewWindow.FB.XFBML.parse(); } }, onInit: function() { this._refreshJs(); }, onRender: function() { this._refreshJs(); }, /** * Things to do, places to go when options change. * * @since 2.0.0 * @param {string} paramName - The name of the parameter that changed. * @param {mixed} paramValue - The value of the option that changed. * @param {Object} event - The event triggering the option change. * @return {void} */ onOptionChange: function( paramName ) { if ( 'language' === paramName ) { this.refreshScript(); } else { this._refreshJs(); } } } ); } ); }( jQuery ) ); ;/* global FusionApp */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Fusion twitter timeline. FusionPageBuilder.fusion_twitter_timeline = FusionPageBuilder.FormComponentView.extend( { /** * Modify template attributes. * * @since 2.0 * @param {Object} atts - The attributes object. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}; this.values = atts.values; // Create attribute objects attributes.atts = this.buildAttr( atts.values ); attributes.iframeAtts = this.buildIframeAttr( atts.values ); // Any extras that need passed on. attributes.values = atts.values; return attributes; }, /** * Builds attributes. * * @since 2.0 * @param {Object} values - The values object. * @return {Object} */ buildAttr: function( values ) { var attr = _.fusionVisibilityAtts( values.hide_on_mobile, { class: 'fusion-twitter-timeline fusion-twitter-timeline-' + this.model.get( 'cid' ) + ' ' + values[ 'class' ], style: '' } ); if ( '' !== values.id ) { attr.id = values.id; } if ( '' !== values.alignment ) { attr.style += 'display:flex; justify-content:' + values.alignment + ';'; } attr.style += this.getStyleVariables(); //Animation attr = _.fusionAnimations( values, attr ); return attr; }, /** * Builds Iframe attributes. * * @since 2.0 * @param {Object} values - The values object. * @return {Object} */ buildIframeAttr: function( values ) { var attr = {}; attr[ 'class' ] = 'twitter-timeline'; attr.href = 'https://twitter.com/' + values.username; if ( '' !== values.language ) { attr[ 'data-lang' ] = values.language; } if ( '' !== values.width ) { attr[ 'data-width' ] = values.width; } if ( '' !== values.height ) { attr[ 'data-height' ] = values.height; } if ( '' !== values.theme ) { attr[ 'data-theme' ] = values.theme; } if ( 'hide' !== values.borders && '' !== values.border_color ) { attr[ 'data-border-color' ] = values.border_color; } let chrome = ''; if ( 'hide' === values.header ) { chrome += ' noheader'; } if ( 'hide' === values.footer ) { chrome += ' nofooter'; } if ( 'hide' === values.borders ) { chrome += ' noborders'; } if ( 'hide' === values.scrollbar ) { chrome += ' noscrollbar'; } if ( 'yes' === values.transparent ) { chrome += ' transparent'; } if ( '' !== chrome ) { attr[ 'data-chrome' ] = chrome; } return attr; }, /** * Gets style variables. * * @since 3.9 * @return {String} */ getStyleVariables: function() { const cssVarsOptions = []; cssVarsOptions.margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_top_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_top_small = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right_small = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom_small = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left_small = { 'callback': _.fusionGetValueWithUnit }; return this.getCssVarsForOptions( cssVarsOptions ); }, /** * Triggers a refresh. * * @since 2.0.0 * @return void */ refreshJs: function() { if ( 'undefined' !== typeof FusionApp.previewWindow.twttr ) { FusionApp.previewWindow.twttr.widgets.load(); } }, onInit: function() { this._refreshJs(); }, onRender: function() { this._refreshJs(); }, afterPatch: function() { this._refreshJs(); } } ); } ); }( jQuery ) ); ;/* globals FusionApp */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Fusion flickr. FusionPageBuilder.fusion_flickr = FusionPageBuilder.FormComponentView.extend( { /** * Modify template attributes. * * @since 2.0 * @param {Object} atts - The attributes object. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}; this.values = atts.values; // Create attribute objects attributes.atts = this.buildAttr( atts.values ); // Any extras that need passed on. attributes.cid = this.model.get( 'cid' ); attributes.values = atts.values; attributes.flickrItems = FusionApp.previewWindow.fusionFlickrItems; return attributes; }, /** * Builds attributes. * * @since 2.0 * @param {Object} values - The values object. * @return {Object} */ buildAttr: function( values ) { var attr = {}; attr[ 'class' ] = 'fusion-flickr-element flickr-' + this.model.get( 'cid' ) + ' ' + values[ 'class' ]; attr = _.fusionVisibilityAtts( values.hide_on_mobile, attr ); if ( '' !== values.id ) { attr.id = values.id; } if ( '' !== values.hover_type ) { attr[ 'class' ] += ' hover-' + values.hover_type; } attr.style = ''; if ( '' !== values.flickr_id ) { attr[ 'data-id' ] = values.flickr_id; } if ( '' !== values.type ) { attr[ 'data-type' ] = values.type; } if ( '' !== values.album_id ) { attr[ 'data-album_id' ] = values.album_id; } if ( '' !== values.count ) { attr[ 'data-count' ] = values.count; } if ( '' !== values.api_key ) { attr[ 'data-api_key' ] = values.api_key; } if ( '' !== values.link_type ) { attr[ 'data-link_type' ] = values.link_type; } if ( 'page' === values.link_type && '_blank' === values.link_target ) { attr[ 'data-link_target' ] = values.link_target; } attr.style += this.buildAspectRatioStyles( values ); attr.style += this.buildColumnStyles( values ); attr.style += this.getStyleVariables(); //Animation attr = _.fusionAnimations( values, attr ); return attr; }, /** * Gets style variables. * * @since 3.9 * @return {String} */ getStyleVariables: function() { const cssVarsOptions = []; cssVarsOptions.margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_top_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left_medium = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_top_small = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right_small = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom_small = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left_small = { 'callback': _.fusionGetValueWithUnit }; return this.getCssVarsForOptions( cssVarsOptions ); }, /** * Builds column styles. * * @since 3.5 * @param {Object} values - The values object. * @return {string} */ buildColumnStyles: function( values ) { var styles = ''; _.each( [ 'large', 'medium', 'small' ], function( size ) { var columns = ( 'large' === size ) ? values.columns : values[ 'columns_' + size ], columns_spacing = ( 'large' === size ) ? values.columns_spacing : values[ 'columns_spacing_' + size ], device_abbr = ''; if ( 'small' === size ) { device_abbr = 'sm-'; } if ( 'medium' === size ) { device_abbr = 'md-'; } if ( '' !== columns ) { styles += '--awb-' + device_abbr + 'column-width:' + ( 100 / parseInt( columns ) ) + '%;'; } if ( '' !== columns_spacing ) { styles += '--awb-' + device_abbr + 'column-space:' + columns_spacing + ';'; } } ); return styles; }, /** * Builds aspect ratio styles. * * @since 3.8 * @param {Object} atts - The atts object. * @return {string} */ buildAspectRatioStyles: function( values ) { var style = '', aspectRatio, width, height; if ( '' === values.aspect_ratio ) { return ''; } // Calc Ratio if ( 'custom' === values.aspect_ratio && '' !== values.custom_aspect_ratio ) { style += '--awb-aspect-ratio: 100 / ' + values.custom_aspect_ratio + '%;'; } else { aspectRatio = values.aspect_ratio.split( '-' ); width = aspectRatio[ 0 ] || ''; height = aspectRatio[ 1 ] || ''; style += `--awb-aspect-ratio: ${width / height};`; } //Ratio Position if ( '' !== values.aspect_ratio_position ) { style += '--awb-object-position:' + values.aspect_ratio_position + ';'; } return style; }, /** * Things to do, places to go when options change. * * @since 2.0.0 * @param {string} paramName - The name of the parameter that changed. * @param {mixed} paramValue - The value of the option that changed. * @param {Object} event - The event triggering the option change. * @return {void} */ onOptionChange: function( paramName ) { if ( 'flickr_id' === paramName || 'count' === paramName ) { FusionApp.previewWindow.fusionFlickrItems = ''; } } } ); } ); }( jQuery ) ); ;/* global fusionAllElements */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { FusionPageBuilder.fusion_tagcloud = FusionPageBuilder.ElementView.extend( { /** * Modify template attributes. * * @since 3.5 * @param {Object} atts - The attributes. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}; this.values = atts.values; attributes.tagcloudAttr = this.buildtagcloudAttr( atts.values ); attributes.marginStyles = this.buildMarginStyles( atts ); attributes.styles = this.getStyleTag( atts.values ); attributes.tagCloudItems = atts.query_data; return attributes; }, /** * Build the tagcloud element attributes. * * @since 3.5 * @param {Object} values * @return {Object} */ buildtagcloudAttr: function( values ) { var attr = { 'class': 'fusion-tagcloud-element fusion-tagcloud-cid-' + this.model.get( 'cid' ) }; attr = _.fusionVisibilityAtts( values.hide_on_mobile, attr ); if ( '' !== values.id ) { attr.id = values.id; } if ( '' !== values.style ) { attr[ 'class' ] += ' style-' + values.style; } if ( 'variable' === values.font_size_type ) { attr[ 'class' ] += ' variable-font-size'; } //Animation attr = _.fusionAnimations( values, attr ); return attr; }, /** * Builds margin styles. * * @since 3.5 * @param {Object} atts - The atts object. * @return {string} */ buildMarginStyles: function( atts ) { var extras = jQuery.extend( true, {}, fusionAllElements.fusion_imageframe.extras ), elementSelector = '.fusion-tagcloud-cid-' + this.model.get( 'cid' ), responsiveStyles = ''; _.each( [ 'large', 'medium', 'small' ], function( size ) { var marginStyles = '', marginKey; _.each( [ 'top', 'right', 'bottom', 'left' ], function( direction ) { // Margin. marginKey = 'margin_' + direction + ( 'large' === size ? '' : '_' + size ); if ( '' !== atts.values[ marginKey ] ) { marginStyles += 'margin-' + direction + ' : ' + _.fusionGetValueWithUnit( atts.values[ marginKey ] ) + ';'; } } ); if ( '' === marginStyles ) { return; } // Wrap CSS selectors if ( '' !== marginStyles ) { marginStyles = elementSelector + ' {' + marginStyles + '}'; } // Large styles, no wrapping needed. if ( 'large' === size ) { responsiveStyles += marginStyles; } else { // Medium and Small size screen styles. responsiveStyles += '@media only screen and (max-width:' + extras[ 'visibility_' + size ] + 'px) {' + marginStyles + '}'; } } ); if ( '' !== responsiveStyles ) { responsiveStyles = ''; } return responsiveStyles; }, /** * Get style element. * * @since 3.5 * @param {object} values * @param {object} extras * @return string */ getStyleTag: function( values ) { var selectors; this.dynamic_css = {}; this.baseSelector = '.fusion-tagcloud-cid-' + this.model.attributes.cid; selectors = [ this.baseSelector ]; if ( '' !== values.alignment ) { this.addCssProperty( selectors, 'justify-content', values.alignment, true ); } if ( '' !== values.tags_spacing ) { this.addCssProperty( selectors, 'gap', _.fusionGetValueWithUnit( values.tags_spacing ), true ); } selectors = [ this.baseSelector + ' a.tag-cloud-link' ]; if ( '' !== values.font_size && 'variable' !== values.font_size_type ) { this.addCssProperty( selectors, 'font-size', _.fusionGetValueWithUnit( values.font_size ), true ); } if ( '' !== values.letter_spacing ) { this.addCssProperty( selectors, 'letter-spacing', _.fusionGetValueWithUnit( values.letter_spacing ), true ); } //padding if ( 'arrows' !== values.style ) { if ( '' !== values.padding_top ) { this.addCssProperty( selectors, 'padding-top', _.fusionGetValueWithUnit( values.padding_top ), true ); } if ( '' !== values.padding_right ) { this.addCssProperty( selectors, 'padding-right', _.fusionGetValueWithUnit( values.padding_right ), true ); } if ( '' !== values.padding_bottom ) { this.addCssProperty( selectors, 'padding-bottom', _.fusionGetValueWithUnit( values.padding_bottom ), true ); } if ( '' !== values.padding_left ) { this.addCssProperty( selectors, 'padding-left', _.fusionGetValueWithUnit( values.padding_left ), true ); } } //borders if ( 'arrows' !== values.style ) { if ( '' !== values.border_top ) { this.addCssProperty( selectors, 'border-top-width', _.fusionGetValueWithUnit( values.border_top ), true ); } if ( '' !== values.border_right ) { this.addCssProperty( selectors, 'border-right-width', _.fusionGetValueWithUnit( values.border_right ), true ); } if ( '' !== values.border_bottom ) { this.addCssProperty( selectors, 'border-bottom-width', _.fusionGetValueWithUnit( values.border_bottom ), true ); } if ( '' !== values.border_left ) { this.addCssProperty( selectors, 'border-left-width', _.fusionGetValueWithUnit( values.border_left ), true ); } if ( '' !== values.border_radius_top_left ) { this.addCssProperty( selectors, 'border-top-left-radius', _.fusionGetValueWithUnit( values.border_radius_top_left ), true ); } if ( '' !== values.border_radius_top_right ) { this.addCssProperty( selectors, 'border-top-right-radius', _.fusionGetValueWithUnit( values.border_radius_top_right ), true ); } if ( '' !== values.border_radius_bottom_left ) { this.addCssProperty( selectors, 'border-bottom-left-radius', _.fusionGetValueWithUnit( values.border_radius_bottom_left ), true ); } if ( '' !== values.border_radius_bottom_right ) { this.addCssProperty( selectors, 'border-bottom-right-radius', _.fusionGetValueWithUnit( values.border_radius_bottom_right ), true ); } } if ( 'arrows' === values.style ) { if ( '' !== values.arrows_border_radius_top_right ) { this.addCssProperty( selectors, 'border-top-right-radius', _.fusionGetValueWithUnit( values.arrows_border_radius_top_right ), true ); } if ( '' !== values.arrows_border_radius_bottom_right ) { this.addCssProperty( selectors, 'border-bottom-right-radius', _.fusionGetValueWithUnit( values.arrows_border_radius_bottom_right ), true ); } } //colors const randomColors = '' !== values.random_colors ? values.random_colors : ''; if ( '' !== values.background_color && !randomColors.includes( 'background' ) ) { this.addCssProperty( selectors, '--tag-color', values.background_color, true ); } if ( '' !== values.text_color && !randomColors.includes( 'text' ) ) { this.addCssProperty( selectors, '--tag-text-color', values.text_color, true ); } if ( '' !== values.border_color && 'arrows' !== values.style && !randomColors.includes( 'background' ) ) { this.addCssProperty( selectors, 'border-color', values.border_color, true ); } selectors = [ this.baseSelector + ' a.tag-cloud-link:hover', this.baseSelector + ' a.tag-cloud-link.hover' ]; if ( '' !== values.background_hover_color && !randomColors.includes( 'background' ) ) { this.addCssProperty( selectors, '--tag-color-hover', values.background_hover_color, true ); } if ( '' !== values.text_hover_color && !randomColors.includes( 'text' ) ) { this.addCssProperty( selectors, '--tag-text-color-hover', values.text_hover_color, true ); } if ( '' !== values.border_hover_color && 'arrows' !== values.style && !randomColors.includes( 'background' ) ) { this.addCssProperty( selectors, 'border-color', values.border_hover_color, true ); } // padding for arrows style. if ( 'arrows' === values.style ) { selectors = [ this.baseSelector + '.style-arrows a.tag-cloud-link .text' ]; if ( '' !== values.padding_top ) { this.addCssProperty( selectors, 'padding-top', _.fusionGetValueWithUnit( values.padding_top ), true ); } if ( '' !== values.padding_right ) { this.addCssProperty( selectors, 'padding-right', _.fusionGetValueWithUnit( values.padding_right ), true ); } if ( '' !== values.padding_bottom ) { this.addCssProperty( selectors, 'padding-bottom', _.fusionGetValueWithUnit( values.padding_bottom ), true ); } if ( '' !== values.padding_left ) { this.addCssProperty( selectors, 'padding-left', _.fusionGetValueWithUnit( values.padding_left ), true ); } if ( '' !== values.padding_top || '' !== values.padding_bottom ) { selectors = [ this.baseSelector + '.style-arrows a.tag-cloud-link' ]; let tags_height = 'calc(2.4em'; // 2.4em the default height from the css file. if ( '' !== values.padding_top ) { tags_height += ' + ' + _.fusionGetValueWithUnit( values.padding_top ); } if ( '' !== values.padding_bottom ) { tags_height += ' + ' + _.fusionGetValueWithUnit( values.padding_bottom ); } tags_height += ')'; this.addCssProperty( selectors, 'height', tags_height, true ); } } const style = this.parseCSS(); return style ? '' : ''; }, /** * Init. * * @since 3.5 * @return {void} */ onInit: function() { // Also refresh on init, since the onPageLoad event don't trigger sometimes. var previewBody = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ); previewBody.trigger( 'fusion-element-render-fusion_tagcloud', this.model.attributes.cid ); }, /** * Runs after view DOM is patched. * * @since 3.5 * @return {void} */ afterPatch: function() { var previewBody = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ); previewBody.trigger( 'fusion-element-render-fusion_tagcloud', this.model.attributes.cid ); } } ); } ); }( jQuery ) ); ;/* globals FusionApp */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Fusion instagram. FusionPageBuilder.fusion_instagram = FusionPageBuilder.FormComponentView.extend( { onRender: function() { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( 'body' ).trigger( 'fusion-element-render-fusion_instagram', this.$el.find( '.awb-instagram-element' ) ); }, /** * Modify template attributes. * * @since 2.0 * @param {Object} atts - The attributes object. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}; // Create attribute objects attributes.atts = this.buildAttr( atts ); // Any extras that need passed on. attributes.cid = this.model.get( 'cid' ); attributes.values = atts.values; attributes.instagramItems = FusionApp.previewWindow.fusionInstagramItems; return attributes; }, /** * Builds attributes. * * @since 2.0 * @param {Object} values - The values object. * @return {Object} */ buildAttr: function( atts ) { var attr = {}; const values = atts.values; attr[ 'class' ] = 'awb-instagram-element loading instagram-' + this.model.get( 'cid' ) + ' ' + values[ 'class' ]; attr = _.fusionVisibilityAtts( values.hide_on_mobile, attr ); attr.style = ''; if ( '' !== values.id ) { attr.id = values.id; } if ( '' !== values.layout ) { attr[ 'class' ] += ' layout-' + values.layout; } if ( '' !== values.hover_type ) { attr[ 'class' ] += ' hover-' + values.hover_type; } if ( '' !== values.limit ) { attr[ 'data-limit' ] = values.limit; } if ( '' !== values.counter ) { attr[ 'data-counter' ] = this.model.get( 'cid' ); } if ( '' !== values.album_id ) { attr[ 'data-album_id' ] = values.album_id; } if ( 'lightbox' !== values.link_type ) { attr[ 'data-lightbox' ] = 'true'; } if ( '' !== values.link_type ) { attr[ 'data-link_type' ] = values.link_type; } if ( 'page' === values.link_type && '_blank' === values.link_target ) { attr[ 'data-link_target' ] = values.link_target; } if ( '' !== values.buttons_layout ) { attr[ 'class' ] += ' buttons-layout-' + values.buttons_layout; } if ( '' !== values.buttons_layout_medium ) { attr[ 'class' ] += ' buttons-layout-medium-' + values.buttons_layout_medium; } if ( '' !== values.buttons_layout_small ) { attr[ 'class' ] += ' buttons-layout-small-' + values.buttons_layout_small; } // Margin. attr.style += this.buildMarginStyles( atts ); // Columns. attr.style += this.buildColumnStyles( atts ); // Aspect ratio. attr.style += this.buildAspectRatioStyles( values ); // Columns. attr.style += this.buildBorderStyles( values ); // buttons. attr.style += this.buildButtonsStyles( values ); //Animation attr = _.fusionAnimations( values, attr ); return attr; }, /** * Builds margin styles. * * @since 3.5 * @param {Object} atts - The atts object. * @return {string} */ buildMarginStyles: function( atts ) { var styles = ''; _.each( [ 'large', 'medium', 'small' ], function( size ) { var marginStyles = '', device_abbr = '', marginKey; if ( 'small' === size ) { device_abbr = 'sm-'; } if ( 'medium' === size ) { device_abbr = 'md-'; } _.each( [ 'top', 'right', 'bottom', 'left' ], function( direction ) { // Margin. marginKey = 'margin_' + direction + ( 'large' === size ? '' : '_' + size ); if ( '' !== atts.values[ marginKey ] ) { marginStyles += '--awb-margin-' + device_abbr + direction + ' : ' + _.fusionGetValueWithUnit( atts.values[ marginKey ] ) + ';'; } } ); if ( '' === marginStyles ) { return; } styles += marginStyles; } ); return styles; }, /** * Builds column styles. * * @since 3.5 * @param {Object} atts - The atts object. * @return {string} */ buildColumnStyles: function( atts ) { var styles = ''; _.each( [ 'large', 'medium', 'small' ], function( size ) { var columns = ( 'large' === size ) ? atts.values.columns : atts.values[ 'columns_' + size ], columns_spacing = ( 'large' === size ) ? atts.values.columns_spacing : atts.values[ 'columns_spacing_' + size ], device_abbr = ''; if ( 'small' === size ) { device_abbr = 'sm-'; } if ( 'medium' === size ) { device_abbr = 'md-'; } if ( '' !== columns ) { styles += '--awb-' + device_abbr + 'column-width:' + ( 100 / parseInt( columns ) ) + '%;'; } if ( '' !== columns_spacing ) { styles += '--awb-' + device_abbr + 'column-space:' + columns_spacing + ';'; } } ); return styles; }, /** * Builds aspect ratio styles. * * @since 3.8 * @param {Object} atts - The atts object. * @return {string} */ buildAspectRatioStyles: function( values ) { var style = '', aspectRatio, width, height; if ( '' === values.aspect_ratio ) { return ''; } // Calc Ratio if ( 'custom' === values.aspect_ratio && '' !== values.custom_aspect_ratio ) { style += '--awb-aspect-ratio: 100 / ' + values.custom_aspect_ratio + '%;'; } else { aspectRatio = values.aspect_ratio.split( '-' ); width = aspectRatio[ 0 ] || ''; height = aspectRatio[ 1 ] || ''; style += `--awb-aspect-ratio: ${width / height};`; } //Ratio Position if ( '' !== values.aspect_ratio_position ) { style += '--awb-object-position:' + values.aspect_ratio_position + ';'; } return style; }, /** * Builds border styles. * * @since 3.8 * @param {Object} atts - The atts object. * @return {string} */ buildBorderStyles: function( values ) { var style = ''; if ( '' !== values.border_radius && '0' !== values.border_radius && '0px' !== values.border_radius && 0 !== values.border_radius ) { style += `--awb-bd-radius:${'round' === values.border_radius ? '50%' : _.fusionGetValueWithUnit( values.border_radius )};`; } if ( '' !== values.bordersize && '0' !== values.bordersize && '0px' !== values.bordersize && 0 !== values.bordersize ) { style += `--awb-bd-width:${_.fusionGetValueWithUnit( values.bordersize )};`; } if ( '' !== values.bordercolor ) { style += `--awb-bd-color:${values.bordercolor};`; } return style; }, /** * Builds buttons styles. * * @since 3.8 * @param {Object} values - The values object. * @return {string} */ buildButtonsStyles: function( values ) { var style = ''; if ( '' !== values.buttons_alignment ) { style += `--awb-buttons-alignment:${values.buttons_alignment};`; } if ( '' !== values.load_more_btn_color ) { style += `--awb-more-btn-color:${values.load_more_btn_color};`; } if ( '' !== values.load_more_btn_bg_color ) { style += `--awb-more-btn-bg:${values.load_more_btn_bg_color};`; } if ( '' !== values.load_more_btn_hover_color ) { style += `--awb-more-btn-hover-color:${values.load_more_btn_hover_color};`; } if ( '' !== values.load_more_btn_hover_bg_color ) { style += `--awb-more-btn-hover-bg:${values.load_more_btn_hover_bg_color};`; } if ( '' !== values.follow_btn_color ) { style += `--awb-follow-btn-color:${values.follow_btn_color};`; } if ( '' !== values.follow_btn_bg_color ) { style += `--awb-follow-btn-bg:${values.follow_btn_bg_color};`; } if ( '' !== values.follow_btn_hover_color ) { style += `--awb-follow-btn-hover-color:${values.follow_btn_hover_color};`; } if ( '' !== values.follow_btn_hover_bg_color ) { style += `--awb-follow-btn-hover-bg:${values.follow_btn_hover_bg_color};`; } return style; }, /** * Things to do, places to go when options change. * * @since 2.0.0 * @param {string} paramName - The name of the parameter that changed. * @param {mixed} paramValue - The value of the option that changed. * @param {Object} event - The event triggering the option change. * @return {void} */ onOptionChange: function( paramName ) { if ( 'limit' === paramName ) { FusionApp.previewWindow.fusionInstagramItems = ''; } } } ); } ); }( jQuery ) ); ;/* global FusionEvents, fusionBuilderText */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { var refreshTocElementsEventsAdded = false; FusionPageBuilder.fusion_table_of_contents = FusionPageBuilder.ElementView.extend( { /** * Modify template attributes. * * @since 3.9 * @param {Object} atts - The attributes. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}; this.values = atts.values; attributes.tocAttr = this.buildTOCAttr( atts.values ); return attributes; }, onRender: function() { var iframeWindow = jQuery( '#fb-preview' )[ 0 ].contentWindow; iframeWindow.jQuery( iframeWindow.document ).ready( this.afterPatch.bind( this ) ); if ( ! refreshTocElementsEventsAdded ) { this.listenTo( FusionEvents, 'fusion-columns-added', this.refreshAllTocElements.bind( this ) ); this.listenTo( FusionEvents, 'fusion-content-changed', this.refreshAllTocElements.bind( this ) ); this.listenTo( FusionEvents, 'fusion-element-removed', this.refreshAllTocElements.bind( this ) ); this.listenTo( FusionEvents, 'fusion-column-resized', this.refreshAllTocElements.bind( this ) ); refreshTocElementsEventsAdded = true; } }, buildTOCAttr: function( values ) { var attr = { 'class': 'awb-toc-el awb-toc-el--cid' + this.model.get( 'cid' ), 'data-awb-toc-options': this.escapeHtml( this.getTocOptionsAttribute( values ) ), 'style': this.getInlineStyle( values ) }; attr = _.fusionVisibilityAtts( values.hide_on_mobile, attr ); if ( 'li_default' === values.counter_type ) { attr[ 'class' ] += ' awb-toc-el--default-list-type'; } if ( values[ 'class' ] ) { attr[ 'class' ] += ' ' + values[ 'class' ]; } if ( values.id ) { attr.id = values.id; } attr = _.fusionAnimations( values, attr ); return attr; }, getTocOptionsAttribute: function( values ) { var options = {}, allowed_heading_tags = this.getAllowedHeadingsObject( values ); options.allowed_heading_tags = allowed_heading_tags; options.ignore_headings = values.ignore_headings_by_classes; options.ignore_headings_words = values.ignore_headings_by_words; options.highlight_current_heading = values.highlight_current_heading; options.hide_hidden_titles = values.hide_hidden_titles; options.limit_container = values.limit_container; options.select_custom_headings = values.select_custom_headings; options.icon = _.fusionFontAwesome( values.icon ); options.counter_type = values.counter_type; return JSON.stringify( options ); }, getAllowedHeadingsObject: function( values ) { var object = {}, startIndex = 0, tags = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ], i, allowedTags; allowedTags = values.allowed_heading_tags.split( ',' ); for ( i = 0; i < tags.length; i++ ) { if ( allowedTags.includes( tags[ i ] ) ) { object[ tags[ i ] ] = startIndex; startIndex++; } } return object; }, getInlineStyle: function( values ) { var customVars = [], counterSeparator, cssVarsOptions; this.values = values; jQuery.each( _.fusionGetFontStyle( 'item_font', values, 'object' ), function( rule, value ) { customVars[ 'item-' + rule ] = value; } ); if ( ! this.isDefault( 'counter_type' ) && 'li_default' !== values.counter_type && 'custom_icon' !== values.counter_type ) { counterSeparator = ''; if ( 'dot' === values.counter_separator ) { counterSeparator = '.'; } else if ( 'comma' === values.counter_separator ) { counterSeparator = ','; } else if ( 'custom' === values.counter_separator ) { counterSeparator = _.unescape( values.custom_counter_separator ).replace( /"/g, '\\"' ); } customVars.counter_type = 'counters(awb-toc, "' + counterSeparator + '", ' + values.counter_type + ') "' + counterSeparator + ' "'; customVars.counter_type = customVars.counter_type.replace( /"/g, '"' ); // escape double quotes. } cssVarsOptions = [ 'margin_top', 'margin_right', 'margin_bottom', 'margin_left', 'padding_top', 'padding_right', 'padding_bottom', 'padding_left', 'item_font_size', 'item_line_height', 'item_letter_spacing', 'item_text_transform', 'item_color', 'item_color_hover', 'item_bg_color_hover', 'counter_color', 'hover_counter_color', 'list_indent', 'item_highlighted_bg_color', 'item_hover_highlighted_bg_color', 'item_highlighted_color', 'item_hover_highlighted_color', 'highlighted_counter_color', 'highlighted_hover_counter_color', 'item_padding_top', 'item_padding_right', 'item_padding_bottom', 'item_padding_left', 'item_radius_top_left', 'item_radius_top_right', 'item_radius_bottom_right', 'item_radius_bottom_left', 'item_margin_top', 'item_margin_bottom' ]; if ( 'yes' === values.item_text_overflow ) { customVars[ 'item-overflow' ] = 'hidden'; customVars[ 'item-white-space' ] = 'nowrap'; customVars[ 'item-text-overflow' ] = 'ellipsis'; } return this.getCssVarsForOptions( cssVarsOptions ) + this.getCustomCssVars( customVars ); }, /** * Runs after view DOM is patched. * * @since 3.9 * @return {void} */ afterPatch: function() { this.indexTocElements(); this.refreshAllTocElements(); }, refreshAllTocElements: function() { var iframeWindow = jQuery( '#fb-preview' )[ 0 ].contentWindow; if ( ! iframeWindow.awbTOCDummyContent1 ) { this.setLiveEmptyElementDummyContent(); } iframeWindow.awbTableOfContentsRefreshAllElements(); }, /** * Index TOC elements. This will create the same attribute as added in PHP version. * * @since 3.9 * @return {void} */ indexTocElements: function() { var elements = jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( '.awb-toc-el' ), index = 1; elements.each( function() { jQuery( this ).attr( 'data-awb-toc-id', index ); index++; } ); }, escapeHtml: function ( str ) { return str.replace( /&/g, '&' ).replace( //g, '>' ).replace( /"/g, '"' ).replace( /'/g, ''' ); }, setLiveEmptyElementDummyContent: function() { var titles = getDummyTitles(); jQuery( '#fb-preview' )[ 0 ].contentWindow.awbTOCDummyContent1 = JSON.parse( JSON.stringify( titles ) ); titles[ 0 ].children = getDummyTitles(); titles[ 1 ].children = getDummyTitles(); jQuery( '#fb-preview' )[ 0 ].contentWindow.awbTOCDummyContent2 = JSON.parse( JSON.stringify( titles ) ); titles[ 0 ].children[ 0 ].children = getDummyTitles(); titles[ 0 ].children[ 1 ].children = getDummyTitles(); jQuery( '#fb-preview' )[ 0 ].contentWindow.awbTOCDummyContent3 = JSON.parse( JSON.stringify( titles ) ); function getDummyTitles() { return [ { id: 'dummy', title: fusionBuilderText.toc_element_title_placeholder, children: [] }, { id: 'dummy', title: fusionBuilderText.toc_element_title_placeholder, children: [] } ]; } } } ); } ); }( jQuery ) ); ;var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Fusion Stripe Button View. FusionPageBuilder.fusion_stripe_button = FusionPageBuilder.ElementView.extend( { /** * Modify template attributes. * * @since 3.1 * @param {Object} atts - The attributes object. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}; if ( ! this.btnInstance ) { this.btnInstance = new FusionPageBuilder.fusion_button( { model: this.model, attributes: atts } ); this.btnInstance.elementTemplate = FusionPageBuilder.template( jQuery( '#tmpl-fusion_button-shortcode' ).html() ); } // Create attribute attributes.html = this.btnInstance.render().$el.html(); return attributes; } } ); } ); }( jQuery ) ); ;var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // OpenStreetMap View. FusionPageBuilder.fusion_openstreetmap = FusionPageBuilder.ParentElementView.extend( { /** * Runs after view DOM is patched. * * @since 3.10 * @return {void} */ onRender: function() { this.afterPatch(); }, /** * Modify template attributes. * * @since 3.10 * @param {Object} atts - The attributes. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}; // Validate values. this.validateValues( atts.values ); this.values = atts.values; attributes.cid = this.model.get( 'cid' ); attributes.elementAttr = this.elementAttr( atts.values ); return attributes; }, /** * Modifies the values. * * @since 3.10 * @param {Object} values - The values object. * @return {void} */ validateValues: function( values ) { if ( 'undefined' === typeof values.shape_color ) { values.shape_color = values.parent.shape_color; } if ( 'undefined' === typeof values.shape_size ) { values.shape_size = values.parent.shape_size; } if ( 'undefined' === typeof values.map_style ) { values.map_style = values.parent.map_style; } }, /** * Create the element attributes. * * @since 3.10 * @param {Object} values - The options. * @return {Object} */ elementAttr: function( values ) { var atts = { 'style': this.getInlineStyle( values ), 'class': 'awb-openstreet-map fusion-child-element' }; atts[ 'class' ] += ' ' + this.getBaseClass(); atts = _.fusionVisibilityAtts( values.hide_on_mobile, atts ); if ( values[ 'class' ] ) { atts[ 'class' ] += ' ' + values[ 'class' ]; } if ( values.id ) { atts.id = values.id; } atts = _.fusionAnimations( values, atts ); atts[ 'data-map-style' ] = values.map_style; atts[ 'data-map-type' ] = values.map_type; atts[ 'data-zoom' ] = values.zoom; atts[ 'data-zoomsnap' ] = values.zoom_snap; atts[ 'data-zoomcontrol' ] = 'yes' === values.zoom_control ? '1' : ''; atts[ 'data-scrollwheelzoom' ] = 'yes' === values.scrollwheel ? '1' : ''; atts[ 'data-dragging' ] = 'yes' === values.dragging ? '1' : ''; atts[ 'data-touchzoom' ] = 'yes' === values.touchzoom ? '1' : ''; atts[ 'data-dbclickzoom' ] = 'yes' === values.dbclickzoom ? '1' : ''; atts[ 'data-fitbounds' ] = 'yes' === values.fitbounds ? '1' : ''; atts[ 'data-shape-color' ] = window.awbPalette.getRealColor( values.shape_color ); atts[ 'data-shape-weight' ] = values.shape_size; return atts; }, /** * Get inline style. * * @since 3.10 * @param {Object} values * @return string */ getInlineStyle: function( values ) { var cssVarsOptions = {}; cssVarsOptions = [ 'popup_background_color', 'popup_close_btn_color', 'popup_title_line_height', 'popup_title_text_transform', 'popup_title_color', 'popup_title_alignment', 'popup_content_line_height', 'popup_content_text_transform', 'popup_content_color', 'popup_content_alignment' ]; cssVarsOptions.width = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.height = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.margin_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.popup_title_font_size = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.popup_title_letter_spacing = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.popup_title_margin_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.popup_title_margin_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.popup_content_font_size = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.popup_content_letter_spacing = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.popup_padding_top = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.popup_padding_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.popup_padding_bottom = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.popup_padding_left = { 'callback': _.fusionGetValueWithUnit }; return this.getCssVarsForOptions( cssVarsOptions ) + this.getFontStylingVars( 'popup_title_font', values ) + this.getFontStylingVars( 'popup_content_font', values ); }, /** * Get the class name with an unique id among elements. * * @since 3.10 * @return {string} */ getBaseClass: function() { return 'awb-openstreet-map-' + this.model.get( 'cid' ); }, /** * Run after the element has been patched. * * @since 3.10 * @return {void} */ afterPatch: function() { // Call the parent afterPatch. FusionPageBuilder.ParentElementView.prototype.afterPatch.bind( this )(); this._refreshJs(); }, /** * Trigger update markers point. * * @since 3.10 * @return {void} */ updateMarkers: function() { const self = this; setTimeout( function() { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( self.$el.find( '.awb-openstreet-map' ) ) .trigger( 'awb_openstreetmap/updateMarker' ) .trigger( 'awb_openstreetmap/updateCoords' ); }, 300 ); } } ); } ); }( jQuery ) ); ;/* global fusionAllElements, FusionPageBuilderElements, FusionPageBuilderApp, FusionPageBuilderViewManager, FusionEvents, FusionApp */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { jQuery( document ).ready( function() { // Toggle child View FusionPageBuilder.fusion_openstreetmap_marker = FusionPageBuilder.ChildElementView.extend( { isSettingsOpen: false, /** * Modify template attributes. * * @since 3.10 * @param {Object} atts - The attributes. * @return {Object} */ filterTemplateAtts: function( atts ) { var attributes = {}, parent = this.model.get( 'parent' ), parentModel = FusionPageBuilderElements.find( function( model ) { return model.get( 'cid' ) == parent; } ), markerContent = ''; this.parentValues = jQuery.extend( true, {}, fusionAllElements.fusion_openstreetmap.defaults, _.fusionCleanParameters( parentModel.get( 'params' ) ) ); this.values = atts.values; attributes.cid = this.model.get( 'cid' ); attributes.icon = atts.values.icon; attributes.iconAttr = this.childElemIconAttr( atts.values ); attributes.childInlineStyle = this.getChildInlineStyle(); attributes.values = atts.values; attributes.animationClass = this.animationToClassName( this.parentValues.items_animation ); markerContent = atts.values.tooltip_content; try { if ( markerContent && '' !== markerContent && FusionPageBuilderApp.base64Encode( FusionPageBuilderApp.base64Decode( markerContent ) ) === markerContent ) { markerContent = FusionPageBuilderApp.base64Decode( markerContent ); } } catch ( error ) { console.log( error ); // jshint ignore:line } attributes.markerContent = markerContent; this.childElemAttr( atts.values ); return attributes; }, /** * OnRender callback. * * @since 3.10 * @return {void} */ onRender: function() { const self = this; this.listenTo( FusionEvents, 'fusion-element-removed', function( cid ) { if ( cid !== self.model.get( 'cid' ) && ( 'undefined' === typeof self.model.parentView || ! self.model.parentView ) ) { return; } const parentView = FusionPageBuilderViewManager.getView( self.model.get( 'parent' ) ); if ( 'undefined' !== typeof parentView ) { parentView.updateMarkers(); } } ); }, /** * Create the child element attributes. * * @since 3.10 * @param {Object} values - The options. * @return {Object} */ childElemAttr: function( values ) { const action = '' === values.action ? this.parentValues.action : values.action; this.$el.addClass( 'awb-openstreet-map-marker' ); this.$el.addClass( 'awb-openstreet-map-marker-' + this.model.get( 'cid' ) ); // Remove the attributes, because this element is not totally replaced. this.$el.removeAttr( 'data-latitude' ); this.$el.removeAttr( 'data-longitude' ); this.$el.removeAttr( 'data-icon' ); this.$el.removeAttr( 'data-action' ); this.$el.attr( 'data-latitude', values.latitude ); this.$el.attr( 'data-longitude', values.longitude ); this.$el.attr( 'data-icon', _.fusionFontAwesome( values.icon ) ); this.$el.attr( 'data-action', action ); }, /** * Create the child inline css vars. * * @since 3.10 * @return {string} */ getChildInlineStyle: function() { var cssVarsOptions; cssVarsOptions = [ 'color', 'background_color', 'hover_color', 'hover_background_color' ]; cssVarsOptions.size = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.border_radius_top_left = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.border_radius_top_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.border_radius_bottom_right = { 'callback': _.fusionGetValueWithUnit }; cssVarsOptions.border_radius_bottom_left = { 'callback': _.fusionGetValueWithUnit }; return this.getCssVarsForOptions( cssVarsOptions ); }, /** * Create the child icon element attributes. * * @since 3.10 * @param {Object} values - The options. * @return {Object} */ childElemIconAttr: function( values ) { var atts = { 'class': _.fusionFontAwesome( values.icon ) }; return atts; }, /** * Get the animation class corresponding with the animation id. * * @since 3.10 * @param {string} animationName - The animation name. * @return {string} - Empty string if do not exist. */ animationToClassName: function( animationName ) { if ( 'pumping' === animationName ) { return 'awb-openstreet-map-marker-anim-pumping'; } if ( 'pulsating' === animationName ) { return 'awb-openstreet-map-marker-anim-pulsating'; } if ( 'showing' === animationName ) { return 'awb-openstreet-map-marker-anim-showing'; } if ( 'sonar' === animationName ) { return 'awb-openstreet-map-marker-anim-sonar'; } if ( 'pumping_showing' === animationName ) { return 'awb-openstreet-map-marker-anim-pump-showing'; } return ''; }, /** * Run on settings open. * * @since 3.10 * @return {void} */ onSettingsOpen: function() { this.isSettingsOpen = true; const parentView = FusionPageBuilderViewManager.getView( this.model.get( 'parent' ) ); parentView.$el.addClass( 'fusion-osm-marker-editing' ); setTimeout( this.dragMarkerOn.bind( this ), 100 ); }, /** * Run on settings close. * * @since 3.10 * @return {void} */ onSettingsClose: function() { var $el = this.$el; this.isSettingsOpen = false; if ( ! $el ) { return; } const parentView = FusionPageBuilderViewManager.getView( this.model.get( 'parent' ) ); parentView.$el.removeClass( 'fusion-osm-marker-editing' ); this.dragMarkerOff(); }, /** * Enable drag marker. * * @since 3.10 * @return {void} */ dragMarkerOn: function() { if ( ! FusionApp.previewWindow.fusion_open_street_map[ this.model.get( 'parent' ) ] ) { return; } const markers = FusionApp.previewWindow.fusion_open_street_map[ this.model.get( 'parent' ) ][ this.model.get( 'cid' ) ]; if ( markers ) { markers.forEach( function( marker ) { if ( marker ) { marker.dragging.enable(); marker.on( 'dragend', function() { jQuery( '#latitude' ).val( marker.getLatLng().lat ).trigger( 'change' ); jQuery( '#longitude' ).val( marker.getLatLng().lng ).trigger( 'change' ); } ); } } ); } }, /** * Disable drag marker. * * @since 3.10 * @return {void} */ dragMarkerOff: function() { if ( ! FusionApp.previewWindow.fusion_open_street_map[ this.model.get( 'parent' ) ] ) { return; } const markers = FusionApp.previewWindow.fusion_open_street_map[ this.model.get( 'parent' ) ][ this.model.get( 'cid' ) ]; if ( markers ) { markers.forEach( function( marker ) { if ( marker ) { marker.dragging.disable(); } } ); } }, /** * Run after the element has been patched. * * @since 3.10 * @return {void} */ afterPatch: function() { jQuery( '#fb-preview' )[ 0 ].contentWindow.jQuery( this.$el.closest( '.awb-openstreet-map' ) ) .trigger( 'awb_openstreetmap/updateMarker' ) .trigger( 'awb_openstreetmap/updateCoords' ); if ( this.isSettingsOpen ) { setTimeout( this.dragMarkerOn.bind( this ), 100 ); } } } ); } ); }( jQuery ) ); ;/* global fusionAppConfig FusionApp */ var FusionPageBuilder = FusionPageBuilder || {}; ( function() { FusionPageBuilder.postLock = window.wp.Backbone.View.extend( { template: FusionPageBuilder.template( jQuery( '#fusion-builder-front-end-post-lock' ).html() ), className: 'fusion-post-lock-dialog', tagName: 'div', /** * Init. * * @since 2.0.0 * @return {void} */ initialize: function() { const context = this; // When post edit is taken. jQuery( document ).on( 'heartbeat-tick', function ( event, data ) { if ( data[ 'post-edit-taken' ] && !fusionAppConfig.post_lock_data ) { jQuery.ajax( { type: 'POST', url: fusionAppConfig.ajaxurl, dataType: 'json', data: { post_id: FusionApp.initialData.postDetails.post_id, takeover: true, fusion_load_nonce: fusionAppConfig.fusion_load_nonce, action: 'fusion_get_post_lock_data' } } ) .done( function( res ) { fusionAppConfig.post_lock_data = res; context.render( true ); } ); } } ); }, /** * Renders the view. * * @since 2.0.0 * @return {Object} this */ render: function( force ) { if ( !fusionAppConfig.post_lock_data && !force ) { return this; } this.$el.html( this.template() ); this.$el = this.$el.dialog( { draggable: false, resizable: false, modal: true, width: 480, minHeight: 100, dialogClass: 'fusion-builder-dialog fusion-builder-post-lock-dialog', closeOnEscape: false, create: function () { jQuery( '.ui-widget-header' ).hide(); } } ).closest( '.ui-dialog' ); return this; } } ); }( jQuery ) );