/* ========================================================= * 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( ': ' + 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 = $( '
' + window.i18nLocale.main_button_title_backend_editor + '' + front + '
' ).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 ); Totally free Revolves No-deposit 2025 As much as step i24slot casino login 1,100000 Extra Spins – Huuzoek

Totally free Revolves No-deposit 2025 As much as step i24slot casino login 1,100000 Extra Spins

Including the $100 incentive, it incentive also offers the fresh professionals free $75 playing to the find online game, no deposits are needed. Very, for those who discover an excellent $10 extra, you ought to spend $ten (or fool around with several of their earnings) before cashing out. Some online casinos, for example Risk.you, provide rakeback while the a zero-deposit incentive. Rakeback provides you with half the normal commission of the share right back for each date you place a bet on a selected online game.

I24slot casino login: Have a tendency to all of the codes work with me?

  • Some bonuses might need one to enter a gambling establishment code through the the new deposit techniques.
  • Really legalized online casinos usually keep certificates, however, there’s specific conditions.
  • Imagine an educated on-line casino incentive offers are just for brand new sign-ups?
  • Find out if the deal has at least deposit, one payment approach limitations, betting conditions, and winnings caps.
  • They give the best chance to turn this type of no deposit bonuses to the withdrawable currency.

Ratings off their on-line casino participants will likely be a good investment when selecting an informed online casino. They can give you an understanding of any alternative players feel while playing, and any positive aspects or significant issues he has discovered. An educated real money casinos will offer a significant set of such. They may consist of localized jackpots, only available during the gambling establishment, otherwise networked jackpots on a comparable games round the people website it provides.

An educated sign-upwards also provides during the gambling enterprises give several or several thousand dollars within the incentive money. Though the signal has some exclusions, the bigger, the higher and provide players a kick off point because of their owed diligence. The most famous sort of added bonus found at U.S. gambling enterprises is the put match incentive, and this tied to the very first put. The new gambling establishment tend to match your initial put that have added bonus money upwards to help you a quantity.

i24slot casino login

The new web sites launch, legacy operators do the new techniques, and regularly we just put private selling to your checklist in order to continue some thing fresh. Furthermore, casinos on the internet have taken strict tips to make certain a safe and you may secure playing ecosystem. Complex security technical features your and economic advice secure, in order to work at having a good time without having to worry concerning your privacy.

And therefore on-line casino permit is the better?

There is that one extra special i24slot casino login bonus you to a few of the gambling enterprises provide prospective the brand new people, and it is the newest no-deposit extra. Extremely no-put extra also provides has limitation victory and withdrawal restrictions. Thus even though you struck a great seven-contour payout to your a progressive jackpot, extent your cash out might possibly be capped. Other people simply need you to opt into claim the fresh special venture. When the a code is required (understand the desk over), there will be an industry on your own indication-upwards strategy to get into they.

Free Revolves for the several video game

Even though a deposit-centered FS bonus needs you to definitely stake several of your money, referring with down rollover and the potential for large winnings. The possibility eventually depends on yours tastes — if you really worth quick free have fun with zero upfront costs or prefer bigger rewards with increased beneficial words. Whether or not 100 percent free spin bonuses sound great, not every promo is all it appears to be. For this reason it’s so important to properly read the fine print prior to claiming people reward the thing is that on the web.

Gambling establishment.org brings an intensive guide to gambling on line in the Philippines, along with more information on the games regulations, procedures, as well as the most recent bonus offers. Participants are able to find knowledge for the certain online casino games and you may suggestions to boost their playing sense. Finest casinos gives varied, high-quality online casino games.

i24slot casino login

Included in the Searching for International Class, which casino is recognized for their brush design, epic game collection, and you may nice bonuses. If you’re also a professional player otherwise fresh to online casinos, Retail center Royal brings a simple-to-fool around with program, excellent customer support, and punctual winnings. Away from no deposit bonuses in order to fun VIP rewards, Retail center Royal serves people searching for a premium feel. This type of exclusive alive bonuses try tailored for real time online casino games such as black-jack, roulette, and you may baccarat, providing you a lot more finance otherwise advantages to enhance their actual-go out betting thrill. Have the adrenaline away from to experience facing real traders when you’re improving your own opportunities to winnings large with a real time specialist added bonus.

Extremely casinos limit no-put incentives to 1 per player, family, payment method, and you can Internet protocol address. Recycling a deal violates conditions and you may voids profits, however, independent names can be stated personally when the for each web site’s policy lets. Casinos offset the price of gifting totally free borrowing by attaching large betting multipliers. This type of laws recycle advertising financing due to family-edge video game, making it possible for workers to recoup debts if you are nevertheless providing people a bona fide chance to make a profit.

A slot event that have 100 percent free admission and you can an ensured prize pool is just one chance. Certain workers has freeroll competitions and essentially honor the brand new winnings since the a no deposit added bonus. It might probably have betting standards, lowest and limitation cashout thresholds, and you may the other possible terms we have talked about. Contrary to popular belief, casinos on the internet aren’t remote knowledge. Of a lot programs provide real time talk functionalities, helping players to communicate and you may interact with each other people and other people.

A online casino no deposit bonus is frequently triggered automatically just after registration. In other cases, you might have to enter a bonus code, that is constantly on the promotions web page otherwise offered solely from the mate internet sites. Some gambling enterprises provide no deposit casino incentives because the an indication-upwards bonus, while many other people were him or her within commitment apps or daily advertisements. Web based casinos feature a thorough collection of video game, guaranteeing there’s something to match all the liking and you may level of skill. Out of antique favorites for example slots and you may black-jack so you can creative variations and you may thrilling alive specialist experience, your options appear limitless.

i24slot casino login

You’ll found a flat amount of spins for the a particular slot or a variety of harbors. Either, a free spins no-deposit incentive are together with a totally free dollars venture, providing more possibilities to winnings. Although not, withdrawing real money earnings generally involves appointment tight betting conditions. These requirements condition how often you ought to wager the newest bonus number before cashing away, and several no-deposit bonuses features restrict cashout constraints.

Sure, you could potentially gamble a large number of free online slots in your own internet browser instead of getting one application. To possess a great experience, you may also enjoy them on your personal computer, mobile phone, otherwise pill. Additionally, specific local casino other sites could possibly get allow you to gamble free slot video game without having to sign in. The purpose of free slot game zero install should be to provide players the same excitement since the playing a bona fide money online game. The game’s winning environment are taken to lifestyle because of the sound files, animations, and you will videos graphics. If you’re looking for the matter #1 on-line casino an internet-based gaming portal customized perfectly to own Southern area African people, you’ve arrive at the right place.

While the site might have been launched, see a game which you enjoy and commence to play. The new video poker’s ratings and you may information may also be seen without the need to create a free account. Since the zero personal information is actually saved to the the options on account of it’s not necessary to have membership creation, your information is left safer. Usually examine other bonuses and select the one that is best suited for your playing layout.

When picking a casino ports added bonus, you can either opt for deposit matches otherwise free spins. Once you see your revolves is activated inside a position game you want to try, I’d state do it now. The simple reason why is you can discover which games you want to play, as well as your wager per spin (inside the limits stated in the deal). Constantly, plenty of constant also offers are available after you visit the promotions webpage. They frequently were put bonuses including the welcome provide, and that adds a specific % for the equilibrium.

i24slot casino login

He’s assessed numerous web based casinos, providing participants credible knowledge to the latest video game and you can fashion. Their reviews work at visibility, equity, and you will helping you see better picks. If or not you’lso are claiming an educated on-line casino extra or simply to experience to have fun, understanding when to take a rest is vital. Visit our in control playing web page to learn more and get the newest assistance one to’s right for you. To play gambling games needs to be enjoyable, however it’s vital that you understand their limitations. That’s as to the reasons all the signed up You online casino must give a responsible Playing page having devices and you can resources to assist participants stay-in power over the gameplay.

You simply get the bonus currency added to your bank account just after you authorized and entered an alternative account for the original time. Our very own advantages will always be examining the video game for sale in the top casinos on the internet international. On the video game we strongly recommend, i check their dominance with people, the fresh ratings from other sites, its framework, UX and you will gameplay and you will, obviously, the return to athlete %. Gamblers inside towns that have authorized gambling on line can enjoy so it well-centered and you will enjoyable position, having a spin of effective a real income. Devoted players deserve rewards, and many casinos provide personal no deposit bonuses included in its loyalty software otherwise VIP nightclubs. Regular participants can also discovered daily otherwise weekly cashback because the a brighten to have proceeded gamble.

You can enjoy alive dealer desk online game, including live blackjack otherwise roulette, and you will in depth video game shows. There’s today even the possibility to enjoy alive online game streamed directly from Vegas and you may Atlantic Area dining tables. Undoubtedly the very best preferred choice, slot game are easy to play and you may come in all shapes and you may brands. There are several if not thousands of titles in the finest web based casinos, with the provides, added bonus rounds, totally free spins, and you can anything else imaginable. Thus giving them anything extra to increase its a real income gambling establishment deposit or even allows these to wager free.