/* =========================================================
* composer-view.js v0.2.1
* =========================================================
* Copyright 2013 Wpbakery
*
* Visual composer backbone/underscore version
* ========================================================= */
(function ( $ ) {
var i18n = window.i18nLocale,
store = vc.storage,
Shortcodes = vc.shortcodes;
vc.templateOptions = {
default: {
evaluate: /<%([\s\S]+?)%>/g,
interpolate: /<%=([\s\S]+?)%>/g,
escape: /<%-([\s\S]+?)%>/g
},
custom: {
evaluate: /<#([\s\S]+?)#>/g,
interpolate: /\{\{\{([\s\S]+?)\}\}\}/g,
escape: /\{\{([^\}]+?)\}\}(?!\})/g
}
};
vc.builder = {
toString: function ( model, type ) {
var params = model.get( 'params' ),
content = _.isString( params.content ) ? params.content : '';
return wp.shortcode.string( {
tag: model.get( 'shortcode' ),
attrs: _.omit( params, 'content' ),
content: content,
type: _.isString( type ) ? type : ''
} );
}
};
/**
* Default view for shortcode as block inside Visual composer design mode.
* @type {*}
*/
vc.clone_index = 1;
vc.saved_custom_css = false;
var ShortcodeView = vc.shortcode_view = Backbone.View.extend( {
tagName: 'div',
$content: '',
use_default_content: false,
params: {},
events: {
'click .column_delete,.vc_control-btn-delete': 'deleteShortcode',
'click .column_add,.vc_control-btn-prepend': 'addElement',
'click .column_edit,.vc_control-btn-edit, .column_edit_trigger': 'editElement',
'click .column_clone,.vc_control-btn-clone': 'clone',
'mousemove': 'checkControlsPosition'
},
removeView: function () {
vc.closeActivePanel( this.model );
this.remove();
},
checkControlsPosition: function () {
if ( ! this.$controls_buttons ) {
return;
}
var window_top, element_position_top, new_position,
element_height = this.$el.height(),
window_height = $( window ).height();
if ( element_height > window_height ) {
window_top = $( window ).scrollTop();
element_position_top = this.$el.offset().top;
new_position = (window_top - element_position_top) + $( window ).height() / 2;
if ( 40 < new_position && new_position < element_height ) {
this.$controls_buttons.css( 'top', new_position );
} else if ( new_position > element_height ) {
this.$controls_buttons.css( 'top', element_height - 40 );
} else {
this.$controls_buttons.css( 'top', 40 );
}
}
},
initialize: function () {
this.model.bind( 'destroy', this.removeView, this );
this.model.bind( 'change:params', this.changeShortcodeParams, this );
this.model.bind( 'change_parent_id', this.changeShortcodeParent, this );
this.createParams();
},
hasUserAccess: function () {
var shortcodeTag;
shortcodeTag = this.model.get( 'shortcode' );
if ( - 1 < _.indexOf( [
"vc_row",
"vc_column",
"vc_row_inner",
"vc_column_inner"
], shortcodeTag ) ) {
return true; // we cannot block controls for these shortcodes;
}
if ( ! _.every( vc.roles.current_user, function ( role ) {
return ! (! _.isUndefined( vc.roles[ role ] ) && ! _.isUndefined( vc.roles[ role ][ 'shortcodes' ] ) && _.isUndefined( vc.roles[ role ][ 'shortcodes' ][ shortcodeTag ] ));
} ) ) {
return false;
}
return true;
},
createParams: function () {
var tag, settings, params;
tag = this.model.get( 'shortcode' );
settings = _.isObject( vc.map[ tag ] ) && _.isArray( vc.map[ tag ].params ) ? vc.map[ tag ].params : [];
params = this.model.get( 'params' );
this.params = {};
_.each( settings, function ( param ) {
this.params[ param.param_name ] = param;
}, this );
},
setContent: function () {
this.$content = this.$el.find( '> .wpb_element_wrapper > .vc_container_for_children,'
+ ' > .vc_element-wrapper > .vc_container_for_children' );
},
setEmpty: function () {
},
unsetEmpty: function () {
},
checkIsEmpty: function () {
if ( this.model.get( 'parent_id' ) ) {
vc.app.views[ this.model.get( 'parent_id' ) ].checkIsEmpty();
}
},
/**
* Convert html into correct element
* @param html
*/
html2element: function ( html ) {
var attributes = {},
$template;
if ( _.isString( html ) ) {
this.template = _.template( html );
$template = $( this.template( this.model.toJSON(), vc.templateOptions.default ).trim() );
} else {
this.template = html;
$template = html;
}
_.each( $template.get( 0 ).attributes, function ( attr ) {
attributes[ attr.name ] = attr.value;
} );
this.$el.attr( attributes ).html( $template.html() );
this.setContent();
this.renderContent();
},
render: function () {
var $shortcode_template_el = $( '#vc_shortcode-template-' + this.model.get( 'shortcode' ) );
if ( $shortcode_template_el.is( 'script' ) ) {
this.html2element( _.template( $shortcode_template_el.html(),
this.model.toJSON(),
vc.templateOptions.default ) );
} else {
var params = this.model.get( 'params' );
$.ajax( {
type: 'POST',
url: window.ajaxurl,
data: {
action: 'wpb_get_element_backend_html',
data_element: this.model.get( 'shortcode' ),
data_width: _.isUndefined( params.width ) ? '1/1' : params.width,
_vcnonce: window.vcAdminNonce
},
dataType: 'html',
context: this
} ).done( function ( html ) {
this.html2element( html );
} );
}
this.model.view = this;
this.$controls_buttons = this.$el.find( '.vc_controls > :first' );
return this;
},
renderContent: function () {
this.$el.attr( 'data-model-id', this.model.get( 'id' ) );
this.$el.data( 'model', this.model );
return this;
},
changedContent: function ( view ) {
},
_loadDefaults: function () {
var tag,
hasChilds;
tag = this.model.get( 'shortcode' );
hasChilds = ! ! vc.shortcodes.where( { parent_id: this.model.get( 'id' ) } ).length;
if ( ! hasChilds && true === this.use_default_content && _.isObject( vc.map[ tag ] ) && _.isString( vc.map[ tag ].default_content ) && vc.map[ tag ].default_content.length ) {
this.use_default_content = false;
Shortcodes.createFromString( vc.map[ tag ].default_content, this.model );
}
},
_callJsCallback: function () {
//Fire INIT callback if it is defined
var tag = this.model.get( 'shortcode' );
if ( _.isObject( vc.map[ tag ] ) && _.isObject( vc.map[ tag ].js_callback ) && ! _.isUndefined( vc.map[ tag ].js_callback.init ) ) {
var fn = vc.map[ tag ].js_callback.init;
window[ fn ]( this.$el );
}
},
ready: function ( e ) {
this._loadDefaults();
this._callJsCallback();
if ( this.model.get( 'parent_id' ) && _.isObject( vc.app.views[ this.model.get( 'parent_id' ) ] ) ) {
vc.app.views[ this.model.get( 'parent_id' ) ].changedContent( this );
}
_.defer( _.bind( function () {
vc.events.trigger( 'shortcodeView:ready' );
vc.events.trigger( 'shortcodeView:ready:' + this.model.get( 'shortcode' ) );
}, this ) );
return this;
},
// View utils {{
addShortcode: function ( view, method ) {
var before_shortcode;
before_shortcode = _.last( vc.shortcodes.filter( function ( shortcode ) {
return shortcode.get( 'parent_id' ) === this.get( 'parent_id' ) && parseFloat( shortcode.get( 'order' ) ) < parseFloat( this.get( 'order' ) );
}, view.model ) );
if ( before_shortcode ) {
view.render().$el.insertAfter( '[data-model-id=' + before_shortcode.id + ']' );
} else if ( 'append' === method ) {
this.$content.append( view.render().el );
} else {
this.$content.prepend( view.render().el );
}
},
changeShortcodeParams: function ( model ) {
var tag,
params,
settings,
view;
// Triggered when shortcode being updated
tag = model.get( 'shortcode' );
params = model.get( 'params' );
settings = vc.map[ tag ];
_.defer( function () {
vc.events.trigger( 'backend.shortcodeViewChangeParams:' + tag );
} );
if ( _.isArray( settings.params ) ) {
_.each( settings.params, function ( param_settings ) {
var name,
value,
$wrapper,
label_value,
$admin_label;
name = param_settings.param_name;
value = params[ name ];
$wrapper = this.$el.find( '> .wpb_element_wrapper, > .vc_element-wrapper' );
label_value = value;
$admin_label = $wrapper.children( '.admin_label_' + name );
if ( _.isObject( vc.atts[ param_settings.type ] ) && _.isFunction( vc.atts[ param_settings.type ].render ) ) {
value = vc.atts[ param_settings.type ].render.call( this, param_settings, value );
}
if ( $wrapper.children( '.' + param_settings.param_name ).is( 'input,textarea,select' ) ) {
$wrapper.children( '[name=' + param_settings.param_name + ']' ).val( value );
} else if ( $wrapper.children( '.' + param_settings.param_name ).is( 'iframe' ) ) {
$wrapper.children( '[name=' + param_settings.param_name + ']' ).attr( 'src', value );
} else if ( $wrapper.children( '.' + param_settings.param_name ).is( 'img' ) ) {
var $img;
$img = $wrapper.children( '[name=' + param_settings.param_name + ']' );
if ( value && value.match( /^\d+$/ ) ) {
$.ajax( {
type: 'POST',
url: window.ajaxurl,
data: {
action: 'wpb_single_image_src',
content: value,
size: 'thumbnail',
_vcnonce: window.vcAdminNonce
},
dataType: 'html',
context: this
} ).done( function ( url ) {
$img.attr( 'src', url );
} );
} else if ( value ) {
$img.attr( 'src', value );
}
} else {
$wrapper.children( '[name=' + param_settings.param_name + ']' ).html( value ? value : '' );
}
if ( $admin_label.length ) {
var inverted_value;
if ( '' === value || _.isUndefined( value ) ) {
$admin_label.hide().addClass( 'hidden-label' );
} else {
if ( _.isObject( param_settings.value ) && ! _.isArray( param_settings.value ) && 'checkbox' === param_settings.type ) {
inverted_value = _.invert( param_settings.value );
label_value = _.map( value.split( /[\s]*\,[\s]*/ ), function ( val ) {
return _.isString( inverted_value[ val ] ) ? inverted_value[ val ] : val;
} ).join( ', ' );
} else if ( _.isObject( param_settings.value ) && ! _.isArray( param_settings.value ) ) {
inverted_value = _.invert( param_settings.value );
label_value = _.isString( inverted_value[ value ] ) ? inverted_value[ value ] : value;
}
$admin_label.html( '' + $admin_label.find( 'label' ).text() + ' : ' + label_value );
$admin_label.show().removeClass( 'hidden-label' );
}
}
}, this );
}
view = vc.app.views[ model.get( 'parent_id' ) ];
if ( false !== model.get( 'parent_id' ) && _.isObject( view ) ) {
view.checkIsEmpty();
}
},
changeShortcodeParent: function ( model ) {
if ( false === this.model.get( 'parent_id' ) ) {
return model;
}
var $parent_view = $( '[data-model-id=' + this.model.get( 'parent_id' ) + ']' ),
view = vc.app.views[ this.model.get( 'parent_id' ) ];
this.$el.appendTo( $parent_view.find( '> .wpb_element_wrapper > .wpb_column_container,'
+ ' > .vc_element-wrapper > .wpb_column_container' ) );
view.checkIsEmpty();
},
// }}
// Event Actions {{
deleteShortcode: function ( e ) {
if ( _.isObject( e ) ) {
e.preventDefault();
}
var answer = confirm( i18n.press_ok_to_delete_section );
if ( true === answer ) {
this.model.destroy();
}
},
addElement: function ( e ) {
_.isObject( e ) && e.preventDefault();
vc.add_element_block_view.render( this.model,
! _.isObject( e ) || ! $( e.currentTarget ).closest( '.bottom-controls' ).hasClass( 'bottom-controls' ) );
},
editElement: function ( e ) {
if ( _.isObject( e ) ) {
e.preventDefault();
}
if ( ! vc.active_panel || ! vc.active_panel.model || ! this.model || ( vc.active_panel.model && this.model && vc.active_panel.model.get( 'id' ) != this.model.get( 'id' ) ) ) {
vc.closeActivePanel();
vc.edit_element_block_view.render( this.model );
}
},
clone: function ( e ) {
if ( _.isObject( e ) ) {
e.preventDefault();
}
vc.clone_index = vc.clone_index / 10;
return this.cloneModel( this.model, this.model.get( 'parent_id' ) );
},
cloneModel: function ( model, parent_id, save_order ) {
var new_order,
model_clone,
params,
tag;
new_order = _.isBoolean( save_order ) && true === save_order ? model.get( 'order' ) : parseFloat( model.get( 'order' ) ) + vc.clone_index;
params = _.extend( {}, model.get( 'params' ) );
tag = model.get( 'shortcode' );
model_clone = Shortcodes.create( {
shortcode: tag,
id: window.vc_guid(),
parent_id: parent_id,
order: new_order,
cloned: true,
cloned_from: model.toJSON(),
params: params
} );
_.each( Shortcodes.where( { parent_id: model.id } ), function ( shortcode ) {
this.cloneModel( shortcode, model_clone.get( 'id' ), true );
}, this );
return model_clone;
}
} );
var VisualComposer = vc.visualComposerView = Backbone.View.extend( {
el: $( '#wpb_visual_composer' ),
views: {},
disableFixedNav: false,
events: {
"click #wpb-add-new-row": 'createRow',
'click #vc_post-settings-button': 'editSettings',
'click #vc_add-new-element, .vc_add-element-button, .vc_add-element-not-empty-button': 'addElement',
'click .vc_add-text-block-button': 'addTextBlock',
'click .wpb_switch-to-composer': 'switchComposer',
'click #vc_templates-editor-button': 'openTemplatesWindow',
'click #vc_templates-more-layouts': 'openTemplatesWindow',
'click .vc_template[data-template_unique_id] > .wpb_wrapper': 'loadDefaultTemplate',
'click #wpb-save-post': 'save',
'click .vc_control-preview': 'preview'
},
initialize: function () {
this.accessPolicy = $( '.vc_js_composer_group_access_show_rule' ).val();
if ( 'no' === this.accessPolicy ) {
return false;
}
this.buildRelevance();
_.bindAll( this,
'switchComposer',
'dropButton',
'processScroll',
'updateRowsSorting',
'updateElementsSorting' );
vc.events.on( 'shortcodes:add', vcAddShortcodeDefaultParams, this );
vc.events.on( 'shortcodes:add', vc.atts.addShortcodeIdParam, this ); // update vc_grid_id on shortcode adding
vc.events.on( 'shortcodes:add', this.addShortcode, this );
vc.events.on( 'shortcodes:destroy', this.checkEmpty, this );
Shortcodes.on( 'change:params', this.changeParamsEvents, this );
Shortcodes.on( 'reset', this.addAll, this );
this.render();
},
changeParamsEvents: function ( model ) {
vc.events.triggerShortcodeEvents( 'update', model );
},
render: function () {
var front = '';
// Find required elemnts of the view.
this.$vcStatus = $( '#wpb_vc_js_status' );
this.$metablock_content = $( '.metabox-composer-content' );
this.$content = $( "#visual_composer_content" );
this.$post = $( '#postdivrich' );
this.$loading_block = $( '#vc_logo' );
if ( 'only' !== this.accessPolicy ) {
if ( vc_frontend_enabled ) {
front = '' + window.i18nLocale.main_button_title_frontend_editor + ' ';
}
this.$buttonsContainer = $( '
' ).insertAfter( 'div#titlediv' );
this.$switchButton = this.$buttonsContainer.find( '.wpb_switch-to-composer' );
this.$switchButton.click( this.switchComposer );
}
vc.add_element_block_view = new vc.AddElementUIPanelBackendEditor( { el: '#vc_ui-panel-add-element' } );
vc.edit_element_block_view = new vc.EditElementUIPanel( { el: '#vc_ui-panel-edit-element' } );
/**
* @deprecated 4.4
* @type {vc.TemplatesEditorPanelViewBackendEditor}
*/
vc.templates_editor_view = new vc.TemplatesEditorPanelViewBackendEditor( { el: '#vc_templates-editor' } );
vc.templates_panel_view = new vc.TemplateWindowUIPanelBackendEditor( { el: '#vc_ui-panel-templates' } );
vc.post_settings_view = new vc.PostSettingsUIPanelBackendEditor( { el: '#vc_ui-panel-post-settings' } );
this.setSortable();
this.setDraggable();
vc.is_mobile = 0 < $( 'body.mobile' ).length;
vc.saved_custom_css = $( '#wpb_custom_post_css_field' ).val();
vc.updateSettingsBadge();
/**
* @since 4.5
*/
_.defer( function () {
vc.events.trigger( 'app.render' );
} );
return this;
},
addAll: function () {
this.views = {};
this.$content.removeClass( 'loading' ).empty();
this.addChild( false );
this.checkEmpty();
this.$loading_block.removeClass( 'vc_ajax-loading' );
this.$metablock_content.removeClass( 'vc_loading-shortcodes' );
},
addChild: function ( parent_id ) {
_.each( vc.shortcodes.where( { parent_id: parent_id } ), function ( shortcode ) {
this.appendShortcode( shortcode );
this.setSortable();
this.addChild( shortcode.get( 'id' ) );
}, this );
},
getView: function ( model ) {
var view;
if ( _.isObject( vc.map[ model.get( 'shortcode' ) ] ) && _.isString( vc.map[ model.get( 'shortcode' ) ].js_view ) && vc.map[ model.get( 'shortcode' ) ].js_view.length && ! _.isUndefined( window[ window.vc.map[ model.get( 'shortcode' ) ].js_view ] ) ) {
view = new window[ window.vc.map[ model.get( 'shortcode' ) ].js_view ]( { model: model } );
} else {
view = new ShortcodeView( { model: model } );
}
model.set( { view: view } );
return view;
},
setDraggable: function () {
$( '#wpb-add-new-element, #wpb-add-new-row' ).draggable( {
helper: function () {
return $( '
' ).appendTo( 'body' );
},
zIndex: 99999,
// cursorAt: { left: 10, top : 20 },
cursor: "move",
// appendTo: "body",
revert: "invalid",
start: function ( event, ui ) {
$( "#drag_placeholder" ).addClass( "column_placeholder" ).html( window.i18nLocale.drag_drop_me_in_column );
}
} );
this.$content.droppable( {
greedy: true,
accept: ".dropable_el,.dropable_row",
hoverClass: "wpb_ui-state-active",
drop: this.dropButton
} );
},
dropButton: function ( event, ui ) {
if ( ui.draggable.is( '#wpb-add-new-element' ) ) {
this.addElement();
} else if ( ui.draggable.is( '#wpb-add-new-row' ) ) {
this.createRow();
}
},
appendShortcode: function ( model ) {
var view, parentModelView, params;
view = this.getView( model );
params = _.extend( vc.getDefaults( model.get( 'shortcode' ) ), model.get( 'params' ) );
model.set( 'params', params, { silent: true } );
parentModelView = false !== model.get( 'parent_id' ) ?
this.views[ model.get( 'parent_id' ) ] : false;
this.views[ model.id ] = view;
if ( model.get( 'parent_id' ) ) {
var parentView;
parentView = this.views[ model.get( 'parent_id' ) ];
parentView.unsetEmpty();
}
if ( parentModelView ) {
parentModelView.addShortcode( view, 'append' );
} else {
this.$content.append( view.render().el );
}
view.ready();
view.changeShortcodeParams( model ); // Refactor
view.checkIsEmpty();
this.setNotEmpty();
},
addShortcode: function ( model ) {
var view, parentModelView, params;
params = _.extend( vc.getDefaults( model.get( 'shortcode' ) ), model.get( 'params' ) );
model.set( 'params', params, { silent: true } );
view = this.getView( model );
parentModelView = false !== model.get( 'parent_id' ) ?
this.views[ model.get( 'parent_id' ) ] : false;
view.use_default_content = true !== model.get( 'cloned' );
this.views[ model.id ] = view;
if ( parentModelView ) {
parentModelView.addShortcode( view );
parentModelView.checkIsEmpty();
var self;
self = this;
_.defer( function () {
view.changeShortcodeParams && view.changeShortcodeParams( model );
view.ready();
self.setSortable();
self.setNotEmpty();
} );
} else {
this.addRow( view );
_.defer( function () {
view.changeShortcodeParams && view.changeShortcodeParams( model );
} );
}
},
addRow: function ( view ) {
var before_shortcode;
before_shortcode = _.last( vc.shortcodes.filter( function ( shortcode ) {
return false === shortcode.get( 'parent_id' ) && parseFloat( shortcode.get( 'order' ) ) < parseFloat( this.get( 'order' ) );
}, view.model ) );
if ( before_shortcode ) {
view.render().$el.insertAfter( '[data-model-id=' + before_shortcode.id + ']' );
} else {
this.$content.append( view.render().el );
}
},
addTextBlock: function ( e ) {
var row, column, params;
e.preventDefault();
row = Shortcodes.create( {
shortcode: 'vc_row'
} );
column = Shortcodes.create( {
shortcode: 'vc_column',
params: { width: '1/1' },
parent_id: row.id,
root_id: row.id
} );
params = vc.getDefaults( 'vc_column_text' );
if ( 'undefined' !== typeof(window.vc_settings_presets[ 'vc_column_text' ]) ) {
params = _.extend( params, window.vc_settings_presets[ 'vc_column_text' ] );
}
return Shortcodes.create( {
shortcode: 'vc_column_text',
parent_id: column.id,
root_id: row.id,
params: params
} );
},
/**
* Create row
*/
createRow: function () {
var row = Shortcodes.create( { shortcode: 'vc_row' } );
Shortcodes.create( {
shortcode: 'vc_column',
params: { width: '1/1' },
parent_id: row.id,
root_id: row.id
} );
return row;
},
/**
* Add Element with a help of modal view.
*/
addElement: function ( e ) {
_.isObject( e ) && e.preventDefault();
vc.add_element_block_view.render( false );
},
/**
* @deprecated 4.4 use openTemplatesWindow
* @param e
*/
openTemplatesEditor: function ( e ) {
e && e.preventDefault();
vc.templates_editor_view.render().show();
},
openTemplatesWindow: function ( e ) {
e && e.preventDefault();
if ( $( e.currentTarget ).is( '#vc_templates-more-layouts' ) ) {
vc.templates_panel_view.once( 'show', function () {
$( '[data-vc-ui-element-target="[data-tab=default_templates]"]' ).click();
} );
}
vc.templates_panel_view.render().show();
},
loadDefaultTemplate: function ( e ) {
e && e.preventDefault();
vc.templates_panel_view.loadTemplate( e );
},
editSettings: function ( e ) {
e && e.preventDefault();
vc.post_settings_view.render().show();
},
sortingStarted: function ( event, ui ) {
$( '#visual_composer_content' ).addClass( 'vc_sorting-started' );
},
sortingStopped: function ( event, ui ) {
$( '#visual_composer_content' ).removeClass( 'vc_sorting-started' );
},
updateElementsSorting: function ( event, ui ) {
_.defer( function ( app, event, ui ) {
var $current_container = ui.item.parent().closest( '[data-model-id]' ),
parent = $current_container.data( 'model' ),
model = ui.item.data( 'model' ),
models = app.views[ parent.id ].$content.find( '> [data-model-id]' ),
i = 0;
// Change parent if block moved to another container.
if ( ! _.isNull( ui.sender ) ) {
var old_parent_id = model.get( 'parent_id' );
store.lock();
model.save( { parent_id: parent.id } );
app.views[ old_parent_id ].checkIsEmpty();
app.views[ parent.id ].checkIsEmpty();
}
models.each( function () {
var shortcode = $( this ).data( 'model' );
store.lock();
shortcode.save( { 'order': i ++ } );
} );
model.save();
}, this, event, ui );
},
updateRowsSorting: function () {
_.defer( function ( app ) {
var $rows = app.$content.find( app.rowSortableSelector );
$rows.each( function () {
var index = $( this ).index();
if ( $rows.length - 1 > index ) {
store.lock();
}
$( this ).data( 'model' ).save( { 'order': index } );
} );
}, this );
},
renderPlaceholder: function ( event, element ) {
var tag = $( element ).data( 'element_type' );
var is_container = _.isObject( vc.map[ tag ] ) && ( ( _.isBoolean( vc.map[ tag ].is_container ) && true === vc.map[ tag ].is_container ) || ! _.isEmpty( vc.map[ tag ].as_parent ) );
var $helper = $( ' ' + vc.map[ tag ].name + '
' ).prependTo( 'body' );
return $helper;
},
rowSortableSelector: "> .wpb_vc_row",
setSortable: function () {
// 1st level sorting (rows). work also in wp41.
$( '.wpb_main_sortable' ).sortable( {
forcePlaceholderSize: true,
placeholder: "widgets-placeholder",
cursor: "move",
items: this.rowSortableSelector, // wpb_sortablee
handle: '.column_move',
distance: 0.5,
start: this.sortingStarted,
stop: this.sortingStopped,
update: this.updateRowsSorting,
over: function ( event, ui ) {
ui.placeholder.css( { maxWidth: ui.placeholder.parent().width() } );
}
} );
// 2st level sorting (elements).
$( '.wpb_column_container' ).sortable( {
forcePlaceholderSize: true,
forceHelperSize: false,
connectWith: ".wpb_column_container",
placeholder: "vc_placeholder",
items: "> div.wpb_sortable", //wpb_sortablee
helper: this.renderPlaceholder,
distance: 3,
scroll: true,
scrollSensitivity: 70,
cursor: 'move',
cursorAt: { top: 20, left: 16 },
tolerance: 'intersect', // this helps with dragging textblock into tabs
start: function () {
$( '#visual_composer_content' ).addClass( 'vc_sorting-started' );
$( '.vc_not_inner_content' ).addClass( 'dragging_in' );
},
stop: function ( event, ui ) {
$( '#visual_composer_content' ).removeClass( 'vc_sorting-started' );
$( '.dragging_in' ).removeClass( 'dragging_in' );
var tag = ui.item.data( 'element_type' ),
parent_tag = ui.item.parent().closest( '[data-element_type]' ).data( 'element_type' ),
allowed_container_element = ! _.isUndefined( vc.map[ parent_tag ].allowed_container_element ) ? vc.map[ parent_tag ].allowed_container_element : true;
if ( ! vc.check_relevance( parent_tag, tag ) ) {
$( this ).sortable( 'cancel' );
}
var is_container = _.isObject( vc.map[ tag ] ) && ( ( _.isBoolean( vc.map[ tag ].is_container ) && true === vc.map[ tag ].is_container ) || ! _.isEmpty( vc.map[ tag ].as_parent ) );
if ( is_container && ! (true === allowed_container_element || allowed_container_element === ui.item.data( 'element_type' ).replace( /_inner$/,
'' )) ) {
$( this ).sortable( 'cancel' );
}
$( '.vc_sorting-empty-container' ).removeClass( 'vc_sorting-empty-container' );
},
update: this.updateElementsSorting,
over: function ( event, ui ) {
var tag = ui.item.data( 'element_type' ),
parent_tag = ui.placeholder.closest( '[data-element_type]' ).data( 'element_type' ),
allowed_container_element = ! _.isUndefined( vc.map[ parent_tag ].allowed_container_element ) ? vc.map[ parent_tag ].allowed_container_element : true;
if ( ! vc.check_relevance( parent_tag, tag ) ) {
ui.placeholder.addClass( 'vc_hidden-placeholder' );
return false;
}
var is_container = _.isObject( vc.map[ tag ] ) && ( ( _.isBoolean( vc.map[ tag ].is_container ) && true === vc.map[ tag ].is_container ) || ! _.isEmpty( vc.map[ tag ].as_parent ) );
if ( is_container && ! (true === allowed_container_element || allowed_container_element === ui.item.data( 'element_type' ).replace( /_inner$/,
'' )) ) {
ui.placeholder.addClass( 'vc_hidden-placeholder' );
return false;
}
if ( ! _.isNull( ui.sender ) && ui.sender.length && ! ui.sender.find( '[data-element_type]:visible' ).length ) {
ui.sender.addClass( 'vc_sorting-empty-container' );
}
ui.placeholder.removeClass( 'vc_hidden-placeholder' );
ui.placeholder.css( { maxWidth: ui.placeholder.parent().width() } );
}
} );
return this;
},
setNotEmpty: function () {
$( '#vc_no-content-helper' ).addClass( 'vc_not-empty' );
},
setIsEmpty: function () {
$( '#vc_no-content-helper' ).removeClass( 'vc_not-empty' )
},
checkEmpty: function ( model ) {
if ( _.isObject( model ) && false !== model.get( 'parent_id' ) && model.get( 'parent_id' ) != model.id ) {
var parent_view = this.views[ model.get( 'parent_id' ) ];
parent_view.checkIsEmpty();
}
if ( 0 === Shortcodes.length ) {
this.setIsEmpty();
} else {
this.setNotEmpty();
}
},
switchComposer: function ( e ) {
if ( _.isObject( e ) ) {
e.preventDefault();
}
if ( 'shown' === this.status ) {
if ( 'only' !== this.accessPolicy ) {
! _.isUndefined( this.$switchButton ) && this.$switchButton.text( window.i18nLocale.main_button_title_backend_editor );
! _.isUndefined( this.$buttonsContainer ) && this.$buttonsContainer.removeClass( 'vc_backend-status' );
}
this.close();
this.status = 'closed';
} else {
if ( 'only' !== this.accessPolicy ) {
! _.isUndefined( this.$switchButton ) && this.$switchButton.text( window.i18nLocale.main_button_title_revert );
! _.isUndefined( this.$buttonsContainer ) && this.$buttonsContainer.addClass( 'vc_backend-status' );
}
this.show();
this.status = 'shown';
}
},
show: function () {
this.$el.show();
this.$post.hide();
this.$vcStatus.val( "true" );
this.navOnScroll();
if ( vc.storage.isContentChanged() ) {
vc.app.setLoading();
vc.app.views = {};
// @todo 4.5 why setTimeout not defer?
window.setTimeout( function () {
Shortcodes.fetch( { reset: true } );
vc.events.trigger( 'backendEditor.show' );
}, 100 );
}
},
setLoading: function () {
this.setNotEmpty();
this.$loading_block.addClass( 'vc_ajax-loading' );
this.$metablock_content.addClass( 'vc_loading-shortcodes' );
},
close: function () {
this.$vcStatus.val( "false" );
this.$el.hide();
if ( _.isObject( window.editorExpand ) ) {
_.defer( function () {
window.editorExpand.on();
window.editorExpand.on(); // double call fixes "space" in height
} );
}
this.$post.show();
_.defer( function () {
vc.events.trigger( 'backendEditor.close' );
} );
},
checkVcStatus: function () {
if ( 'only' === this.accessPolicy || 'true' === this.$vcStatus.val() ) {
this.switchComposer();
}
},
setNavTop: function () {
this.navTop = this.$nav.length && this.$nav.offset().top - 28;
},
save: function () {
$( '#wpb-save-post' ).text( window.i18nLocale.loading );
$( '#publish' ).click();
},
preview: function () {
$( '#post-preview' ).click();
},
navOnScroll: function () {
var $win = $( window );
this.$nav = $( '#vc_navbar' );
this.setNavTop();
this.processScroll();
$win.unbind( 'scroll.composer' ).on( 'scroll.composer', this.processScroll );
},
processScroll: function ( e ) {
if ( true === this.disableFixedNav ) {
this.$nav.removeClass( 'vc_subnav-fixed' );
return;
}
if ( ! this.navTop || 0 > this.navTop ) {
this.setNavTop();
}
this.scrollTop = $( window ).scrollTop() + 80;
if ( 0 < this.navTop && this.scrollTop >= this.navTop && ! this.isFixed ) {
this.isFixed = 1;
this.$nav.addClass( 'vc_subnav-fixed' );
} else if ( this.scrollTop <= this.navTop && this.isFixed ) {
this.isFixed = 0;
this.$nav.removeClass( 'vc_subnav-fixed' );
}
},
buildRelevance: function () {
vc.shortcode_relevance = {};
_.map( vc.map, function ( object ) {
if ( _.isObject( object.as_parent ) && _.isString( object.as_parent.only ) ) {
vc.shortcode_relevance[ 'parent_only_' + object.base ] = object.as_parent.only.replace( /\s/,
'' ).split( ',' );
}
if ( _.isObject( object.as_parent ) && _.isString( object.as_parent.except ) ) {
vc.shortcode_relevance[ 'parent_except_' + object.base ] = object.as_parent.except.replace( /\s/,
'' ).split( ',' );
}
if ( _.isObject( object.as_child ) && _.isString( object.as_child.only ) ) {
vc.shortcode_relevance[ 'child_only_' + object.base ] = object.as_child.only.replace( /\s/,
'' ).split( ',' );
}
if ( _.isObject( object.as_child ) && _.isString( object.as_child.except ) ) {
vc.shortcode_relevance[ 'child_except_' + object.base ] = object.as_child.except.replace( /\s/,
'' ).split( ',' );
}
} );
/**
* Check parent/children relationship between two tags
* @param tag
* @param related_tag
* @return boolean - Returns true if relevance is positive
*/
vc.check_relevance = function ( tag, related_tag ) {
if ( _.isArray( vc.shortcode_relevance[ 'parent_only_' + tag ] ) && ! _.contains( vc.shortcode_relevance[ 'parent_only_' + tag ],
related_tag ) ) {
return false;
}
if ( _.isArray( vc.shortcode_relevance[ 'parent_except_' + tag ] ) && _.contains( vc.shortcode_relevance[ 'parent_except_' + tag ],
related_tag ) ) {
return false;
}
if ( _.isArray( vc.shortcode_relevance[ 'child_only_' + related_tag ] ) && ! _.contains( vc.shortcode_relevance[ 'child_only_' + related_tag ],
tag ) ) {
return false;
}
if ( _.isArray( vc.shortcode_relevance[ 'child_except_' + related_tag ] ) && _.contains( vc.shortcode_relevance[ 'child_except' + related_tag ],
tag ) ) {
return false;
}
return true;
};
}
} );
$( function () {
if ( $( '#wpb_visual_composer' ).is( 'div' ) ) {
var app = vc.app = new VisualComposer();
'no' !== app.accessPolicy && vc.app.checkVcStatus();
}
} );
/**
* Called when initial content rendered or when content changed in tinymce
*/
Shortcodes.on( 'sync', function ( collection ) {
if ( _.isObject( collection ) && ! _.isEmpty( collection.models ) ) {
_.each( collection.models, function ( model ) {
vc.events.triggerShortcodeEvents( 'sync', model );
} );
}
} );
/**
* Called when shortcode created
*/
Shortcodes.on( 'add', function ( model ) {
if ( _.isObject( model ) ) {
vc.events.triggerShortcodeEvents( 'add', model );
}
} );
})( window.jQuery );
Spinrise Kasino Nachprüfung: max 125% up to Kohlenstoff$5,555, 257 FS Bonus – Huuzoek
Spinrise Kasino Nachprüfung: max 125% up to Kohlenstoff$5,555, 257 FS Bonus
In folgenden Schritten sollen Die leser Ein Bankkonto per Eulersche konstante-Mail verifizieren. In das erfolgreichen Anmeldung im SpinRise Spielbank sollen Diese die Verifizierung realisieren. Glücksspieler üblich within Spinrise folgende breite Summe eingeschaltet spannenden Spielbank-Aufführen, bei Klassiker, moderne Spielautomaten ferner dies Live-Spielbank. Die übersichtliche Internetseite erleichtert unser schnelle Vorfinden bevorzugter Spiele. Spielen Sie jederzeit und wählen Sie Deren Lieblingsvariante über hoher Auszahlungsquote.
Willkommensbonus im Spinrise Spielbank: Spinrise Freispiele
Das Kundenservice im Spinrise Spinrise Freispiele Spielbank steht tag für tag ferner dahinter sämtliche Zeitform zur Vorschrift. Anfragen sind am schnellsten unter einsatz von diesseitigen Live-Chat beantwortet. Unplanmäßig besteht diese Opportunität, per Basis des natürlichen logarithmus-E-mail-nachricht Kontakt aufzunehmen, & ein ausführlicher Faq-Bezirk liefert Antworten nach immer wieder gestellte Vernehmen.
Persönliche Limits vermögen inoffizieller mitarbeiter Spielerkonto eingestellt sie sind.
Zum beispiel können jene Glücksspieler SpinRise casino aktionscode bekommen, in ihre Beginn Piepen und Freispiele dem Bonuskonto gutgeschrieben werden.
Auszahlungen man sagt, sie seien nicht früher als derselben Absolutbetrag zugänglich, wohingegen nachfolgende Auszahlungsoptionen 5 vor 12 gleich man sagt, sie seien.
Die autoren anfertigen unter irgendeiner Curacao-Erlaubniskarte, nachfolgende diese Willigkeit je Fairplay und einen Sturz ein Nutzerinteressen bestätigt.
Zur Authentifikation sie sind Kopien bei Dokumenten angeschaltet unser Eulersche konstante-Mail-Postanschrift des Sicherheitsdienstes gesendet. Auf Ziel ein Verifizierung bekommen Diese die Ratifikation, über ein Eltern Diesen ersten Gewinn divergieren vermögen. Um within SpinRise spielen hinter beherrschen, müssen Eltern Ein Haben über minimal 20 € strapazieren.
Spinrise Spielsaal General Overview
Diese Funktionsumfang ferner Bedienoberfläche der mobilen Version sie sind gleichartig über der Browserversion in unserem Elektronische datenverarbeitungsanlage. In konnte das Spinrise no abschlagzahlung maklercourtage qua herausragenden Promocodes aktiviert werden. Die sie sind within Ihr Kontoverbindung eingegeben, hinter Sie unser Komposition vorweg leer offiziellen Fließen kopiert haben.
Zum Sturz vertraulicher Nutzerdaten, inbegriffen Finanzinformationen, verwendet diese Website moderne SSL-Verschlüsselung.
Nachfolgende Bearbeitungsgeschwindigkeit ist abhängig von angewandten Bestimmungen das Zahlungsart.
Sie auftreiben den Provision Spinrise no vorleistung auf Partnerseiten ferner in ihr Mailingliste das Leitung.
Der Fläche „Verantwortungsbewusstes Spielen“ ist und bleibt umfangreich gestaltet & bietet verschiedene Aussagen rund damit angewandten Zocker- ferner Jugendschutz.
SpinRise belohnt gar nicht nur Stammkunden über Boni, anstelle auch Neukunden, unser zigeunern ohne rest durch zwei teilbar erst unter der Website registriert sehen. As part of SpinRise free spins man sagt, sie seien unter anderem Bonusguthaben pro einfache Aktionen gutgeschrieben, genau so wie z. Die Einzahlung in ein Anmeldung und aktiv bestimmten Wochentagen. Ein Gegend „Verantwortungsbewusstes Zum besten geben“ ist und bleibt umfangreich gestaltet ferner bietet ausgewählte Informationen um … herum um diesseitigen Glücksspieler- ferner Jugendschutz. Ob dies Spinrise Kasino ernst wird, kann meinereiner via ja stellung nehmen. Dies Hollycorn Spielsaal verfügt unter einsatz von die Glücksspiellizenz Curacaos, bietet Durchsichtigkeit ferner Gewissheit.
Payment Methods on SpinRise Kasino
Für jedes zusätzlichen Wärme verhätscheln unser Spiele via deutschsprachigen Dealern. Auswählen Diese Gameshows, Roulette ferner Poker qua Live-Dealern unter anderem auskosten Diese diese authentische Stimmung eines echten Casinos geradlinig verbunden. Spinrise Casino Deutschland achtet vorsichtig unter Treue. Ganz Spielautomaten ferner Tischspiele werden zertifiziert, ended up being unser Sportlichkeit der Ergebnisse bestätigt und Störungen des Spielgeschehens ausschließt. Welches Präsentation umfasst Tausende bei Slots sofern Dutzende von Vortragen über echten Dealern & beliebten Tischformaten. Diese einfache Schrittfolge ermöglicht einen Zugang auf Tippen unter jedermann Gerät, in diesem dies Spinrise Kasino zugänglich wird.
Das Spinrise Angeschlossen-Spielbank arbeitet via den international führenden Anbietern verbinden, sodass diese Spielesammlung wiederkehrend via Neuerscheinungen aktualisiert wird. As part of diesem Broschüre ausfindig machen Die leser Spielautomaten entsprechend Thunderstorm, Fire Hopper, Big Bass Fest unter anderem etliche andere. Die autoren ausbauen unseren Broschüre ständig und angebot sekundär Spiele via Live-Dealern und Tischspiele angeschaltet. Meine wenigkeit erfahrene Zocker können dabei des Wettvorgangs Fragen hatten. Unsrige Experten antworten schnell und unter die arme greifen Jedem mit vergnügen as part of Gutschriften, Bonuszahlungen & erklären Jedermann die Einzelheiten ihr Teilnahme an dem Treueprogramm. Spielen in SpinRise Casino und man sagt, sie seien Sie Angehöriger unseres Treueprogramms.
Im Aktionen-Fläche sie sind auf diese weise zahlreiche einige Bonusaktionen aufgelistet, wozu Freispiele und Bonusgelder gehören. Spinrise bietet der anspruchsvolles Star-Sender unter einsatz von fünf Leveln, das insbesondere treuen Spielern mehrere Vorteile gewährt. Gamer erhalten den Startbonus durch 111 % so weit wie 777 Ecu unter anderem 111 Freispiele. Welches Spinrise Verbunden-Spielbank dabei zigeunern in diese Vorlieben das Spieler und bietet folgende beeindruckende Auswahl an Unterhaltung via echten Dealern. Die Katalog umfasst Roulette, Blackjack, Poker ferner Showspiele tabellenführer Provider ferner schafft sic diese Atmosphäre eines echten Casinos. Nachfolgende offizielle Spinrise-Website bietet den Kunden die riesige Selektion angeschaltet Glücksspielen.
Warum SpinRise Spielbank nachfolgende beste Wahl ist?
Unsereins haben die große Bevorzugung an Slots und Tischspielen spitzenreiter Entwickler synoptisch. Sämtliche Zielgruppe vermag interessante Bonusangebote nützlichkeit, diese nach Zufriedenheit einfacher Bedingungen zugänglich sind. Neukunden beibehalten so weit wie 2.999 € ferner 243 Freispiele je deren ersten drei Einzahlungen. Falls Diese Das Bankverbindung damit 300 € strapazieren, bekommen Diese ein High-Roller-Päckchen durch 125 % so weit wie 3.333 € unter anderem 125 Freispiele.