How to use scaffold method in Cypress

Best JavaScript code snippet using cypress

editor.scaffold.js

Source:editor.scaffold.js Github

copy

Full Screen

1/**2 * Scaffold editor functions that need to work along different Forms developments: (Post and Users) and Relationships3 * Tries to avoid code duplication4 *5 * @since 2.36 */7var Toolset = Toolset || {};8Toolset.CRED = Toolset.CRED || {};9Toolset.CRED.ScaffoldEditor = function( shortcode_container ) {10	this.checkedRadioAttributeInputsTrack = {};11    this.shortcode_container = shortcode_container;12    this.scaffold_field_id = Toolset.hooks.applyFilters( 'cred_editor_scaffold_scaffold_field_id_attribute_name', '' ) || cred_post_form_content_editor_i18n.data.scaffold.scaffold_field_id; // In case hook is not defined yet :(13    this.initEvents();14};15/**16 * Craft the scaffold output.17 *18 * @since 2.119 */20Toolset.CRED.ScaffoldEditor.prototype.craftScaffoldOutput = function() {21    var prevColNumber = 0;22    var columnCounter = 0;23    var numColumns = 0;24    var bootstrapClass = '';25    var $container = arguments.length === 1 ? arguments[0] : null;26    if ( $container && typeof $container !== 'object' ) {27        $container = jQuery( '#' + $container );28    }29    var currentInstance = this,30        output = '',31        $scaffoldList = jQuery( '.js-cred-editor-scaffold-item-list', $container ),32        thereIsWpmlLocalization = jQuery( '.js-cred-editor-scaffold-options-wpml' ).prop( 'checked' ),33        formSlug = jQuery( '#slug' ).val();34    output = '[' + this.shortcode_container + ']';35    var addLabel = function( attributes, label, formSlug, thereIsWpmlLocalization ) {36        var labelHTML = '<label>';37        var finalLabel = attributes.label ? attributes.label : label;38        if ( thereIsWpmlLocalization ) {39            labelHTML += "[wpml-string context='cred-form-" + _.escape( formSlug ) + "' name='" + _.escape( finalLabel ) + "']";40            labelHTML += finalLabel;41            labelHTML += '[/wpml-string]';42        } else {43            labelHTML += finalLabel;44        }45        labelHTML += '</label>';46        delete attributes.label;47        return labelHTML;48    }49    var generateFieldShortcode = function( $this, bootstrapClass ) {50        var shortcodeOutput = '';51        if ( ! $this.data( 'include' ) || $this.hasClass( 'cred-scaffold-conditional-child' ) ) {52            return '';53        }54        var shortcode = $this.data( 'shortcode' ),55            fieldType = $this.data( 'fieldtype' ),56            label = $this.data( 'label' ),57            attributes = currentInstance.getScaffoldShortcodeAttributes( $this );58        if ( 'cred_generic_field' === shortcode ) {59            attributes.type = attributes[ currentInstance.scaffold_field_id ];60        }61        var extraTabs = bootstrapClass ? "\t" : '';62        var openingBootstraDiv = bootstrapClass63            ? "\n\t" + extraTabs + '<div class="' + bootstrapClass + '">'64            : '';65        var closingBootstraDiv = bootstrapClass66            ? "\n\t" + extraTabs + '</div>'67            : '';68        var extraTabs = bootstrapClass ? "\t" : '';69        var openingBootstraDiv = bootstrapClass70            ? "\n\t" + extraTabs + '<div class="' + bootstrapClass + '">'71            : '';72        var closingBootstraDiv = bootstrapClass73            ? "\n\t" + extraTabs + '</div>'74			: '';75		var fromGroupClassname = bootstrapClass76			? 'form-group ' + bootstrapClass77			: 'form-group';78        if ( 'media' === attributes[ currentInstance.scaffold_field_id ] ) {79            shortcodeOutput += openingBootstraDiv;80            shortcodeOutput += "\n\t" + extraTabs + ( attributes.value || '' );81            shortcodeOutput += closingBootstraDiv;82        } else if ( 'html' === attributes[ currentInstance.scaffold_field_id ] ) {83            shortcodeOutput += openingBootstraDiv;84            shortcodeOutput += "\n\t" + extraTabs + extraTabs;85			if ( attributes.value ) {86				shortcodeOutput += attributes.value;87			} else {88				var $htmlTextarea = $this.find( 'textarea.cred-scaffold-html-content' ),89					htmlTextareaId = $htmlTextarea.attr( 'id' );90				shortcodeOutput += _.has( WPV_Toolset.CodeMirror_instance, htmlTextareaId ) ? WPV_Toolset.CodeMirror_instance[ htmlTextareaId ].getValue() : '';91			}92			shortcodeOutput += closingBootstraDiv;93        } else if ( 'conditionals' === attributes[ currentInstance.scaffold_field_id ] ) {94            var $item = $this;95            var $list = [];96            // Copying 'child' elements in a new element to generate conditional shortcode content.97            while ( $item.next().hasClass( 'cred-editor-scaffold-item-wrapper-row' ) ) {98                $item = $item.next();99                if ( $item.find( '.cred-scaffold-conditional-child' ).length ) {100                    $row = $item.clone();101                    $row.find( '.js-cred-editor-scaffold-item-container' ).each( function() {102                        $list.push( jQuery( this ).removeClass( 'cred-scaffold-conditional-child' ) );103                    } );104                }105            }106            var outputConditional = output;107            var prevColNumberConditional = prevColNumber;108            var columnCounterConditional = columnCounter;109            var numColumnsConditional = numColumns;110            prevColNumber = 0;111            columnCounter = 0;112            numColumns = 0;113            output = '';114            jQuery( $list ).each( addBootstrapTags );115            prevColNumber = prevColNumberConditional;116            columnCounter = columnCounterConditional;117            numColumns = numColumnsConditional;118            $this.data( "contentToWrap", output );119            output = outputConditional;120            shortcodeOutput += openingBootstraDiv;121            shortcodeOutput += "\n\t" + Toolset.hooks.applyFilters( 'cred-action-get-conditional-shortcode', $this );122            shortcodeOutput += closingBootstraDiv;123        } else if ( [ 'formElement', 'form-elements' ].includes( fieldType ) || [ 'cred_generic_field' ].includes( shortcode ) ) {124            var hasLabel = ! openingBootstraDiv && attributes.label;125            if ( hasLabel ) {126                shortcodeOutput += "\n\t" + extraTabs + '<div class="' + fromGroupClassname + '">';127            } else {128                shortcodeOutput += openingBootstraDiv;129            }130            shortcodeOutput += "\n\t" + extraTabs + extraTabs;131            if ( !!attributes.label ) {132                shortcodeOutput += addLabel( attributes, label, formSlug, thereIsWpmlLocalization ) + "\n\t" + extraTabs + extraTabs;133            }134            shortcodeOutput += currentInstance.craftShortcodeString( shortcode, attributes, $this );135            if ( hasLabel ) {136                shortcodeOutput += "\n\t" + extraTabs + '</div>';137            } else {138                shortcodeOutput += closingBootstraDiv;139            }140        } else {141            shortcodeOutput += "\n\t" + extraTabs + '<div class="' + fromGroupClassname + '">';142            shortcodeOutput += "\n\t\t" + extraTabs + addLabel( attributes, label, formSlug, thereIsWpmlLocalization );143            shortcodeOutput += "\n\t\t" + extraTabs + currentInstance.craftShortcodeString( shortcode, attributes, $this );144            shortcodeOutput += "\n\t" + extraTabs + '</div>';145        }146        return shortcodeOutput;147    };148    var renderGrid = Toolset.hooks.applyFilters( 'cred_editor_is_grid_enabled' ) && jQuery( '.cred-editor-scaffold-item-wrapper-row[data-cred-cols!=1]' ).length;149    if ( renderGrid ) {150        output += "\n" + '<div class="container-fluid">';151    }152    var addBootstrapTags = function() {153        var $cell = jQuery( this );154        var $itemWrapper = $cell.closest( '.cred-editor-scaffold-item-wrapper-item' );155        if ( ! $itemWrapper.length ) {156            output += generateFieldShortcode( jQuery( this ), '' );157            return;158        }159        var sizeColumn = Number( $itemWrapper[0].dataset.credFieldCols || 1 );160        if ( renderGrid && ! $cell.hasClass( 'cred-scaffold-conditional-child' ) ) {161            numColumns = Number( $cell.closest( '.cred-editor-scaffold-item-wrapper-row' )[0].dataset.credCols || 1 );162            numColumns = Number( numColumns );163            if ( numColumns === columnCounter || numColumns !== prevColNumber ) {164                columnCounter = 0;165                output += "\n\t" + '<div class="row">';166            }167            var bootstrapVersion = Toolset.hooks.applyFilters( 'cred_editor_get_bootstrap_version' );168            bootstrapClass = ( 4 === bootstrapVersion ? 'col-md-' : 'col-sm-' ) + ( 12 * sizeColumn / numColumns );169        }170        output += generateFieldShortcode( jQuery( this ), bootstrapClass );171        if ( renderGrid && ! $cell.hasClass( 'cred-scaffold-conditional-child' ) ) {172            columnCounter += sizeColumn;173            if ( numColumns === columnCounter ) {174                output += "\n\t" + '</div>';175            }176            prevColNumber = numColumns;177        }178        bootstrapClass = '';179    };180    jQuery( '.js-cred-editor-scaffold-item-container:not(.cred-editor-scaffold-item-deleted)', $scaffoldList ).each( addBootstrapTags );181    if ( renderGrid ) {182        output += "\n" + '</div>';183    }184    output += "\n" + '[/' + this.shortcode_container + ']';185    return output;186};187/**188 * Get the attributes for a scaffold item.189 *190 * @param $scaffoldItem jQuery object191 *192 * @return object193 *194 * @since 2.1195 */196Toolset.CRED.ScaffoldEditor.prototype.getScaffoldShortcodeAttributes = function( $scaffoldItem ) {197    var attributes = $scaffoldItem.data( 'attributes' );198    var attrAttributes = $scaffoldItem.attr( 'data-attributes' ); // jQuery data can override attr data199    if ( attrAttributes ) {200        attributes = Object.assign( attributes, JSON.parse( attrAttributes ) );201    }202    var currentInstance = this;203    attributes = ( _.size( attributes ) == 0 ) ? {} : attributes;204    if ( $scaffoldItem.find( '.js-cred-editor-scaffold-item-options' ).length > 0 ) {205        jQuery( '.js-toolset-shortcode-gui-attribute-wrapper', $scaffoldItem ).each( function() {206			var attributeWrapper = jQuery( this ),207				$shortodeWrapper = attributeWrapper.closest( '.js-cred-editor-scaffold-item-options' ),208                shortcodeAttributeKey = attributeWrapper.data( 'attribute' ),209                shortcodeAttributeValue = '',210                shortcodeAttributeDefaultValue = attributeWrapper.data( 'default' );211            switch ( attributeWrapper.data('type') ) {212                case 'select':213                    shortcodeAttributeValue = jQuery('option:checked', attributeWrapper ).val();214                    break;215                case 'radio':216                    shortcodeAttributeValue = jQuery('input:checked', attributeWrapper ).val();217                    break;218                case 'checkbox':219                    shortcodeAttributeValue = jQuery('input:checked', attributeWrapper ).val();220                    break;221                case 'textarea':222                    shortcodeAttributeValue = jQuery('textarea', attributeWrapper ).val();223                    break;224                case 'conditionals':225                    shortcodeAttributeValue = currentInstance.getConditionalAttributes( $scaffoldItem );226                    break;227				case 'html':228					var $htmlTextarea = attributeWrapper.find( 'textarea.cred-scaffold-html-content' ),229						htmlTextareaId = $htmlTextarea.attr( 'id' );230					shortcodeAttributeValue += _.has( WPV_Toolset.CodeMirror_instance, htmlTextareaId ) ? WPV_Toolset.CodeMirror_instance[ htmlTextareaId ].getValue() : '';231                    break;232                default:233                    shortcodeAttributeValue = jQuery('input', attributeWrapper ).val();234            };235            if ( shortcodeAttributeKey === 'manual' ) {236				shortcodeAttributeKey = 'options';237				var attributeSource = $shortodeWrapper.find( 'input[name="cred_generic_field-source"]:checked' ).val();238				switch ( attributeSource ) {239					case 'shortcode':240						shortcodeAttributeValue = $shortodeWrapper.find( '[id="cred_generic_field-shortcode"]' ).val();241						break;242					default:243						var defaultOptions = [];244						// Removing default values and moving to a new attribute245						if ( shortcodeAttributeValue ) {246							if ( shortcodeAttributeValue[0] === '{' ) {247								shortcodeAttributeValue = '[' + shortcodeAttributeValue + ']';248							}249							shortcodeAttributeValue = JSON.stringify(250								JSON.parse( shortcodeAttributeValue )251									.map( function( option ) {252										if ( option.default ) {253											defaultOptions.push( option.value );254										}255										delete option['default'];256										return option;257									})258								);259						}260						if ( defaultOptions.length ) {261							attributes[ 'default' ] = defaultOptions;262						}263						break;264				}265			}266			if (267				false === shortcodeAttributeValue268				|| null === shortcodeAttributeValue269				|| undefined === shortcodeAttributeValue270			) {271				// Remove broken attributes272				attributes = _.omit( attributes, shortcodeAttributeKey );273			} else if ( [ 'source', 'required', 'default' ].includes( shortcodeAttributeKey ) ) {274				// Force in not broken attributes for generic fields275				attributes[ shortcodeAttributeKey ] = shortcodeAttributeValue;276			} else if (277				// Exclude the rest of the default attribute values278				'' === shortcodeAttributeValue279				|| shortcodeAttributeValue === shortcodeAttributeDefaultValue280			) {281				attributes = _.omit( attributes, shortcodeAttributeKey );282			} else {283				// Add the remaining284				attributes[ shortcodeAttributeKey ] = shortcodeAttributeValue;285			}286        });287    }288    return attributes;289};290/**291 * Compose a shortcode given its handle and its attributs in an object, when inserting the scaffold.292 *293 * @param shortcode  string294 * @param rawAttributes object295 * @param fieldType string296 * @param {Object} $container jQuery object that contains the shortcode generator GUI297 *298 * @return string299 *300 * @since 2.3301 * @since 2.3.2 Apply the canonical Toolset filters over the attributes and the generated shortcode.302 */303Toolset.CRED.ScaffoldEditor.prototype.craftShortcodeString = function( shortcode, rawAttributes, $container ) {304	var output = '[' + shortcode,305		// Normalize the attributes306		attributes = Toolset.hooks.applyFilters(307			'toolset-filter-shortcode-gui-' + shortcode + '-computed-attribute-values',308			jQuery.extend( true, {}, rawAttributes ),309			{310				shortcode: shortcode,311				rawAttributes: rawAttributes312			}313		);314    _.each( attributes, function( value, key, list ) {315        if ( value ) {316            output += ' ' + key + '=\'' + value + '\''; // JSON data uses double quotes317        }318    });319    output += ']';320	// Normalize the generated shortcodes321    output = Toolset.hooks.applyFilters( 'toolset-filter-shortcode-gui-' + shortcode + '-crafted-shortcode', output, { shortcode: shortcode, attributes: attributes, rawAttributes: rawAttributes, container: $container } );322    // Normalizing output.323    output = output.replace( new RegExp( '\\s' + this.scaffold_field_id + '=\'[^\']*\'' ), '' );324    // Removing shortcode attributes contained in the JSON data325    var jsonData = output326        .replace( /\[(\w|\/).*(\w|')]/g, '' ) // JSON, containing arrays, inside attributes can be confused with shorcodes327        .trim();328    if ( jsonData ) {329        try {330            jsonData.match(/"([^"]+?)":/g) // Gets "slug": | JSON parsing is more complicated due to getting the right JSON data331                .map( function( m ) {332                    return m.replace(/"([^"]+)":/, '$1');  // Gets the slug from the previous step333                })334                .concat( this.scaffold_field_id ) // Needs to be removed, it is only for internal use335                .forEach( function( key ) {336                    output = output.replace(new RegExp( '\\s' + key + '=\'[^\']*\'', 'g' ), '' ); // Remove the shortcode attribute337                });338        } catch ( e ) {}339    }340    return output;341};342/**343 * Craft the scaffold output.344 *345 * @since 2.3346 * @since 2.3.2 Add an optional container argument so we can craft the scaffold properly347 *     when leaving the wizard on relationship forms.348 */349Toolset.CRED.ScaffoldEditor.prototype.scaffoldToJSON = function() {350	var $container = arguments.length === 1 ? arguments[0] : jQuery( 'body' );351    var currentInstance = this,352        result = { fields: [], options: [] },353        $scaffoldList = jQuery( '.js-cred-editor-scaffold-item-list', $container );354    jQuery( '.js-cred-editor-scaffold-item-container', $scaffoldList ).each( function() {355        var $item = jQuery( this ),356			rawAttributes = currentInstance.getScaffoldShortcodeAttributes( $item ),357			attributes = jQuery.extend( true, {}, rawAttributes );358        attributes.isNested = $item.hasClass( 'cred-scaffold-conditional-child' );359        attributes.numColumns = $item.closest( '.cred-editor-scaffold-item-wrapper-row' ).data( 'credCols' ) || 1;360        attributes.sizeColumn = $item.closest( '.cred-editor-scaffold-item-wrapper-item' ).data( 'credFieldCols' ) || 1;361        attributes.fieldtype = $item.data( 'fieldtype' );362        result.fields.push( attributes );363    } );364    // Group nested items365    var conditionalItem = null;366    var organizedFields = []367    result.fields.forEach( function( field, index ) {368        if ( field[ currentInstance.scaffold_field_id ] === 'conditionals' ) {369            conditionalItem = field;370            conditionalItem.children = [];371            organizedFields.push( conditionalItem );372        } else if ( field.isNested ) {373            conditionalItem.children.push( Object.assign( {}, field ) );374            result.fields = result.fields.filter( function( elem, i ) {375                return i != index;376            });377        } else {378            organizedFields.push( field );379        }380    });381    result.fields = organizedFields;382    jQuery( '.js-cred-editor-wrap-scaffold-options input:checked', $container ).each( function() {383        var optionName = this.classList[0].replace(/.*options-/, '');384        result.options.push( optionName );385    } );386    return result;387}388/**389 * Set initially scaffold items390 * It is a static function so it can be called with creating a new instance391 *392 * @param {Array} fields List of fields saved393 * @since 2.3394 */395Toolset.CRED.ScaffoldEditor.setInitialScaffoldItems = function( scaffoldData, fields ) {396    var currentInstance = this;397    var missedFields = [];398    var $container = jQuery( '.cred-editor-scaffold-general-container:visible' );399    var $fieldsContainer = jQuery( '.js-cred-editor-scaffold-item-list:visible' );400    // This static method is called in cred.js before Toolset.CRED.ScaffoldEditor were instanced401    if ( !currentInstance.scaffold_field_id ) {402        currentInstance.scaffold_field_id = Toolset.hooks.applyFilters( 'cred_editor_scaffold_scaffold_field_id_attribute_name', '' ) || cred_post_form_content_editor_i18n.data.scaffold.scaffold_field_id;403    }404    var handleField = function( field, position ) {405        if ( !field[ currentInstance.scaffold_field_id ] ) {406            field[ currentInstance.scaffold_field_id ] = !!field.type407                ? field.type408                : field.field;409        }410        var fieldName = field[ currentInstance.scaffold_field_id ] || field.field || field.name || field.role;411        var fieldAttribute = field.role412            ? 'role'413            : currentInstance.scaffold_field_id;414        var fieldSelector = 'div[data-attributes*=\'"' + fieldAttribute + '":"' + fieldName + '"\'][data-fieldtype=' + field.fieldtype + ']:not([data-blocked="true"])';415        var $field;416        if ( [ 'media', 'html', 'conditionals' ].includes( field[ currentInstance.scaffold_field_id ] )417                || ( jQuery( '.cred-editor-scaffold-generic-list [data-' + currentInstance.scaffold_field_id + '="' + field[ currentInstance.scaffold_field_id ] +'"]' ).length418                    && field.fieldtype === 'generic' ) ) {419            // Media can be duplicated so it must be selected from the sidebar420            $field = $container.find( '.cred-editor-scaffold-sidebar ' + fieldSelector );421        } else {422            // It needs to find form-included elements before sidebar ones.423            $field = $container.find( '#js-cred-editor-scaffold-item-list-container ' + fieldSelector );424            if ( ! $field.length ) {425                $field = $container.find( fieldSelector );426            }427        }428        if ( $field.length ) {429            $field.attr('data-existing', 'true');430            if ( $field.data( 'permanent' ) ) {431                $field = $field.clone();432				/**433				 * Initialize tippy.js and make sure the tooltip really should be there (depends on context)434				 */435                $field.find( '.js-cred-editor-tippy' ).each( function() {436					OTGSUI.otgsPopoverTooltip.initSingle( this );437					this._tippy.set( {438						onShow: function( tip ) {439							Toolset.CRED.ScaffoldEditor.maybeShowTooltip( tip );440						}441					} );442                } );443                Toolset.hooks.doAction( 'cred_editor_scaffold_do_knockout_binding', $field[0] );444            }445            $fieldsContainer.append( $field );446        } else {447            missedFields.push( { field: field[ currentInstance.scaffold_field_id ], position: position } );448        }449        // Setting shortcode attributes450        Object.keys( field ).forEach( function( key ) {451            if ( key === 'options' ||  key === 'manual' ) {452                if ( !! field[ key ] ) {453                    var template = wp.template( 'cred-editor-generic-fields-options-manual-row' );454                    var $tableOptionsContainer = $field.find( '.js-cred-editor-generic-fields-options-manual-table tbody' );455					$tableOptionsContainer.html( '' );456					$field.find( '[id=cred_generic_field-manual]' ).val( field[ key ] );457					switch ( field.source ) {458						case 'shortcode':459							$field.find( '[id=cred_generic_field-shortcode]' ).val( field[ key ] );460							break;461						default:462							var options = typeof field[ key ] === 'string' ? JSON.parse( field[ key ] ) : field[ key ];463							options.forEach( function( option ) {464								$tableOptionsContainer.append( template( { type: field[ currentInstance.scaffold_field_id ] } ) );465								$newRow = $tableOptionsContainer.children().last();466								Object.keys( option ).forEach( function( optionAttribute ) {467									var $element = $newRow.find( '.js-cred-editor-generic-fields-options-manual-row-' + optionAttribute + ' input' );468									$element.prop( 'value', option[ optionAttribute ] ).change();469								});470							});471							if ( !! field['default'] ) {472								var defaultOptions = typeof field['default'] === 'string' ? JSON.parse( field['default'] ) : field['default'];473								$tableOptionsContainer.find( '.js-cred-editor-generic-fields-options-manual-row-value input[type=text]' ).each( function() {474									var $inputElement = jQuery( this );475									if ( defaultOptions.includes( $inputElement.val() ) ) {476										$defaultElement = $inputElement.parents( 'tr:first' ).find( '.js-cred-editor-generic-fields-options-manual-row-default input' ).prop( 'checked', 'checked' ).change();477									}478								})479							}480							break;481					}482                }483			} else if ( key === 'conditionals' ) {484				var conditionals = field[ key ];485				if ( !conditionals.useGui ) {486					$field.find( '.js-cred-editor-conditional-groups-expression-switcher').click();487					$field.find( '[id=cred-editor-conditional-groups-custom-expressions]' ).val( conditionals.custom );488				} else {489					conditionals.conditions.forEach( function( condition, i ) {490						if ( i ) { // Needs more conditions, first is loaded491							Toolset.hooks.doAction( 'cred-action-add-conditional-row', $field );492						}493						Object.keys( condition ).forEach( function( conditionKey ) {494							$field.find( '.cred-editor-conditional-groups-' + conditionKey + ':last' ).find( 'input, select').val( condition[ conditionKey ] );495						});496					});497				}498            } else if ( key === 'children' ) {499                field.children.forEach( handleField );500            } else if ( key === 'isNested' ) {501                $field.toggleClass( 'cred-scaffold-conditional-child', field[ key ] );502            } else if ( key === 'numColumns' ) {503                $field.data( 'numColumns', field[ key ] );504            } else if ( key === 'sizeColumn' ) {505                $field.data( 'sizeColumn', field[ key ] );506            } else if ( key === 'value' && 'html' === field[ currentInstance.scaffold_field_id ] ) {507                var $textarea = $field.find( 'textarea' );508                $textarea.val( field[ key ] );509            } else {510                var value = field[ key ];511                if ( ! value || typeof value !== 'string' ) {512                    return;513                }514                var escapedValue = value.replace(/"/g, '\\"');515                var $shortcodeInput = $field.find( '.toolset-shortcode-gui-attribute-wrapper[data-attribute="' + key + '"]').find('input[type=text], input[type=hidden], input[type=radio][value="' + escapedValue + '"], input[type=checkbox][value="' + escapedValue + '"], select, textarea' );516                if ( $shortcodeInput.length ) {517                    if ( $shortcodeInput.is(':not(:radio,:checkbox)') ) {518                        $shortcodeInput.val( value );519                    } else {520                        $shortcodeInput.prop( 'checked', 'checked' ).change();521                    }522                }523            }524            if ( 'thumbnail' === key ) {525                $shortcodeInput.prev().attr( 'src', field[ key ] ).removeClass( 'hidden' );526            }527        });528    };529    ( scaffoldData.fields || [] ).forEach( handleField );530    $fieldsContainer.find( 'div:not([data-existing]) i.js-cred-editor-scaffold-item-include-remove:visible' ).click();531    var $optionsContainer = jQuery( '.js-cred-editor-wrap-scaffold-options' );532    // Fake a change event on options checkboxes to initialize their values533    $optionsContainer.find( 'input:checkbox' ).each( function() {534		jQuery( this ).trigger( 'change' );535    });536    Toolset.hooks.doAction( 'cred-action-after-manual-options-created', $container );537    Toolset.hooks.doAction( 'cred_editor_scaffold_init_sorting' );538    // Wrapping elements539    // Conditionals540    jQuery('[data-' + currentInstance.scaffold_field_id + '="conditionals"]').each(function() {541        var $conditional = jQuery(this);542        var $elements = [$conditional];543        $next = $conditional.next();544        var hasChildren = false;545        while( $next.hasClass( 'cred-scaffold-conditional-child' ) ) {546            hasChildren = true;547            $elements.push( $next );548            $next = $next.next();549        }550        var $wrapper = jQuery( '<div class="cred-editor-scaffold-item-wrapper-conditionals js-cred-editor-scaffold-item-wrapper-conditionals"></div>' ).insertBefore( $conditional );551        $wrapper.append( $elements );552        $conditional.closest( '.cred-editor-scaffold-item-wrapper-conditionals' ).toggleClass( 'cred-editor-scaffold-conditional-has-children', hasChildren );553    } );554    // It must to be instanced because this is object Window555    var scaffold = new Toolset.CRED.ScaffoldEditor();556    scaffold.addFieldItemsWrapperAndRow();557    // HTML content fields must have an ID for make them codemirror instances558    jQuery( '.cred-editor-scaffold-item-list .cred-scaffold-html-content' ).each( function() {559        var id = 'cred_scaffold_' + parseInt( Math.random() * 100000 )560        var $textarea = jQuery( this );561        $textarea.attr( 'id', id );562        if ( ! _.has( WPV_Toolset.CodeMirror_instance, id ) ) {563            WPV_Toolset.CodeMirror_instance[ id ] = icl_editor.codemirror( id, true, { name: 'htmlmixed', autoRefresh: true } );564		}565		WPV_Toolset.CodeMirror_instance[ id ].refresh();566    });567}568/**569 * Gets the conditional data from a GUI as attributes570 *571 * @param {Object} $container jQuery object that contains the shortcode generator GUI572 *573 * @return {array}574 *575 * @since 2.3576 */577Toolset.CRED.ScaffoldEditor.prototype.getConditionalAttributes = function( $container ) {578    var attributes = {};579    attributes.useGui = $container.find( '.js-cred-editor-conditional-groups-general-container' ).data( "useGui" ) !== false;580    if ( ! attributes.useGui ) {581        attributes.custom = $container.find( '[id=cred-editor-conditional-groups-custom-expressions]' ).val();582    } else {583        attributes.conditions = [];584        $container.find( '.cred-editor-conditional-groups-item' ).each( function() {585            var condition = {};586            jQuery( this ).find( 'input, select' ).each( function() {587                var $conditionElement = jQuery( this );588                var conditionPartId = $conditionElement.parent()[0].classList[0].replace(/.*-([^-]+)$/, '$1');589                condition[ conditionPartId ] = $conditionElement.val();590            });591            attributes.conditions.push( condition );592        });593    }594    return attributes;595}596/**597 * Wrap items with a new div for placing the droppable zones, and adds rows598 *599 * @since 2.3600 */601Toolset.CRED.ScaffoldEditor.prototype.addFieldItemsWrapperAndRow = function( $container ) {602    var currentInstance = this;603    if ( Toolset.hooks.applyFilters( 'cred_editor_is_grid_enabled' ) ) {604        var prevColNumber = 0;605        var $prevRow = null;606        var columnCounter = 0;607        ( !! $container? $container : jQuery( '.cred-editor-scaffold-item-list' ) )608            .find( '.js-cred-editor-scaffold-item-wrapper-conditionals, .cred-editor-scaffold-item-container:not(.cred-editor-scaffold-item-deleted):not([data-' + currentInstance.scaffold_field_id + '=conditionals])' )609            .each( function() {610                var $field = jQuery(this);611                if ( ! $container && $field.hasClass( 'cred-scaffold-conditional-child' ) ) {612                    return;613                }614                // Grouping fields in columns615                var sizeColumn = Number( $field.hasClass( 'cred-editor-scaffold-item-wrapper-conditionals' )616                    ? $field.find( '.cred-editor-scaffold-item-container' ).data( 'sizeColumn' )617                    : $field.data('sizeColumn') );618                if ( ! sizeColumn ) {619                    sizeColumn = 1;620                }621                $field.wrap( '<div class="cred-editor-scaffold-item-wrapper-item" data-cred-field-cols="' + ( sizeColumn ) + '"></div>' );622                var $wrapper = $field.parent();623                var numColumns = Number( $field.hasClass( 'js-cred-editor-scaffold-item-wrapper-conditionals' )624                    ? $field.find( '.cred-editor-scaffold-item-container' ).data( 'numColumns' )625                    : $field.data('numColumns') );626                if ( ! numColumns ) {627                    numColumns = 1;628                }629                if ( numColumns === columnCounter || numColumns !== prevColNumber ) {630                    columnCounter = 0;631                    $prevRow = jQuery( '<div class="cred-editor-scaffold-item-wrapper-row" data-cred-cols="' + numColumns + '"></div>' );632                    $wrapper.before( $prevRow );633                }634                $wrapper.append( '<div class="cred-editor-scaffold-item-wrapper-resizer"></div>' );635                $prevRow.append( $wrapper );636                prevColNumber = numColumns;637                columnCounter += sizeColumn;638                if ( $field.hasClass( 'js-cred-editor-scaffold-item-wrapper-conditionals' ) ) {639                    currentInstance.addFieldItemsWrapperAndRow( $field );640                }641            } );642    } else {643        jQuery( '.cred-editor-scaffold-item-list' )644            .find( '.js-cred-editor-scaffold-item-wrapper-conditionals, .js-cred-editor-scaffold-item-container:not(.cred-scaffold-conditional-child, [data-' + currentInstance.scaffold_field_id + '=conditionals])' )645            .wrap( '<div class="cred-editor-scaffold-item-wrapper-row" data-cred-cols="1"><div class="cred-editor-scaffold-item-wrapper-item"></div></div>' );646    }647}648/**649 * Store the checked radios of each dragging item, to restore them once dragging ends.650 *651 * Caused by a weird unexpected behavior of the draggable library, when cloning items:652 * the number of radios contained in each item doubles, and the original ones win the checked status,653 * hence cloned (so dragged) items are added without checked radios.654 *655 * @param object event656 * @param object ui657 * @since 2.3.2658 */659Toolset.CRED.ScaffoldEditor.prototype.storeCheckedRadios = function( event, ui ) {660	var currentInstance = this;661	ui.helper.find( 'input:radio:checked' ).each( function () {662		var name = jQuery( this ).attr( 'name' );663		currentInstance.checkedRadioAttributeInputsTrack[ name ] = jQuery( this ).val();664    });665}666/**667 * Restore the checked radios of each dragging item, once dragging ends.668 *669 * Caused by a weird unexpected behavior of the draggable library, when cloning items:670 * the number of radios contained in each item doubles, and the original ones win the checked status,671 * hence cloned (so dragged) items are added without checked radios.672 *673 * @param object event674 * @param object ui675 * @since 2.3.2676 */677Toolset.CRED.ScaffoldEditor.prototype.restoreCheckedRadios = function( event, ui ) {678	var currentInstance = this;679	_.each( currentInstance.checkedRadioAttributeInputsTrack, function( value, name, list ) {680		jQuery( ui.helper.context ).find( 'input:radio[name="' + name + '"][value="' + value + '"]' ).prop( 'checked', true );681	});682	currentInstance.checkedRadioAttributeInputsTrack = {};683}684/**685 * Displays dropping zones in the Drag&Drop editor686 *687 * @since 2.3688 */689Toolset.CRED.ScaffoldEditor.prototype.addDraggableItems = function() {690    var self = this;691    // I don't know why 'mouseup' event is triggered twice so I need to check event position692    var initialMousePosition = '';693    var draggingOptions = {694        start: function( event, ui ) {695			jQuery.ui.credStopsDragging = false;696			self.storeCheckedRadios( event, ui );697            self.addDroppingZones();698        },699        stop: function( event, ui ) {700			self.removeDroppingZones();701			self.restoreCheckedRadios( event, ui );702        },703        helper: 'clone',704        refreshPositions: true705    };706    self.draggingOptions = draggingOptions;707    jQuery( '.cred-editor-scaffold-item-list-container .js-cred-editor-scaffold-item-container' )708        .draggable( Object.assign( {}, draggingOptions ));709    // When mouseup in the container, remove the dropping zones. They can be displayed when clicking, but it there are not dragging, they are not removed.710    jQuery( '.cred-editor-scaffold-item-list-container .js-cred-editor-scaffold-item-container .js-cred-editor-scaffold-item-move' )711        // Showing dropping zones is handled when clicking and not when dragging.712        .on( 'mousedown', function( event ) {713            initialMousePosition = event.pageX + '-' + event.pageY;714            self.addDroppingZones();715        } )716    jQuery( '.cred-editor-scaffold-item-list-container' )717        .on( 'mouseup', function( event ) {718            if ( initialMousePosition === event.pageX + '-' + event.pageY ) {719                self.removeDroppingZones();720            }721        } );722    jQuery( '.cred-editor-scaffold-sidebar .js-cred-editor-scaffold-item-container:not([data-blocked="true"])' )723        .draggable( draggingOptions );724}725/**726 * Displays dropping zones in the Drag&Drop editor727 *728 * @since 2.3729 */730Toolset.CRED.ScaffoldEditor.prototype.addDroppingZones = function() {731    if ( jQuery( '.js-cred-editor-scaffold-dropping-zones:visible' ).length ) {732        return;733    }734    var currentInstance = this;735    jQuery( '.cred-editor-scaffold-item-list-container .cred-editor-scaffold-item-list' ).addClass( 'cred-editor-scaffold-is-dragging' );736    jQuery( '.cred-editor-scaffold-item-wrapper-resizer' ).addClass( 'hidden' );737    // Removes a class using a regex738    var removeClassRegEx = function( droppableItem, regex ) {739        if ( !!droppableItem ) {740            Array.apply( [], droppableItem.classList ).forEach( function( className ) {741                if ( className.match( regex ) ) {742                    droppableItem.classList.remove( className );743                }744            } );745        }746    };747    // Horizontal zones: under each item748    var droppingZonePattern = '<div class="cred-editor-scaffold-dropping-zones js-cred-editor-scaffold-dropping-zones cred-editor-scaffold-dropping-zones-%TYPE% dropzonein"></div>',749        horizontalDroppingZone = droppingZonePattern.replace( '%TYPE%', 'horizontal' ),750        verticalDroppingZone = droppingZonePattern.replace( '%TYPE%', 'vertical' ),751        conditionalDroppingZoneClassName = 'cred-editor-scaffold-dropping-zones-conditional',752        horizontalConditionalDroppingZone = droppingZonePattern.replace( '%TYPE%', 'horizontal ' + conditionalDroppingZoneClassName );753    jQuery( '.cred-editor-scaffold-item-list > .cred-editor-scaffold-item-wrapper-row' ).before( horizontalDroppingZone );754    jQuery( '.cred-editor-scaffold-item-list > .cred-editor-scaffold-item-wrapper-row:last-child' ).after( horizontalDroppingZone );755    jQuery( '.cred-editor-scaffold-item-list-container .js-cred-editor-scaffold-item-container[data-' + currentInstance.scaffold_field_id + '=conditionals], .cred-editor-scaffold-item-wrapper-item .cred-editor-scaffold-item-wrapper-row' )756        .after( horizontalConditionalDroppingZone );757    // Vertical zones758    if ( Toolset.hooks.applyFilters( 'cred_editor_is_grid_enabled' ) ) {759        jQuery( '.cred-editor-scaffold-item-wrapper-item' )760            .before( verticalDroppingZone );761        jQuery( '.cred-editor-scaffold-item-wrapper-item:last-child' )762            .after( verticalDroppingZone );763        // Limit number of columns is 12. It is easier to remove them that to avoid when adding.764        jQuery( '.cred-editor-scaffold-item-wrapper-row[data-cred-cols=12] ' ).each( function() {765            var $row = jQuery( this );766            if ( $row.find( '> .cred-editor-scaffold-item-wrapper-item' ).length === 12 ) {767                $row.find( '> .cred-editor-scaffold-dropping-zones-vertical' ).remove();768            }769        })770        jQuery( '.cred-editor-scaffold-item-wrapper-item .cred-editor-scaffold-item-wrapper-row .cred-editor-scaffold-dropping-zones-vertical' ).addClass( conditionalDroppingZoneClassName );771    }772    jQuery( '.js-cred-editor-scaffold-dropping-zones' ).droppable({773        hoverClass: 'cred-editor-scaffold-drop-hover',774        drop: function( event, ui ) {775            jQuery.ui.credStopsDragging = true;776            var $droppable = jQuery( this ),777                $draggable = ui.draggable,778                $row = $draggable.closest( '.cred-editor-scaffold-item-wrapper-row' ),779                $droppableRow = $droppable.closest( '.cred-editor-scaffold-item-wrapper-row' );780            // Because of some dropping zones have an extended zone, jQuery droppable library trigger drop event twice and it causes problems with it781            $droppable.removeClass( 'cred-editor-scaffold-drop-hover' );782            $draggable.closest( '.cred-editor-scaffold-item-wrapper-item' ).find( '.cred-editor-scaffold-item-wrapper-resizer' ).remove();783            if ( $draggable.data( currentInstance.scaffold_field_id ) === 'conditionals' && $row.length ) {784                // Dragging an eisting conditional field => get the wrapper as draggable785                $draggable = $draggable.closest( '.cred-editor-scaffold-item-wrapper-conditionals' );786            } else if ( $draggable.data( 'permanent' ) && $row.length == 0 ) {787                // Dragging a new permanent field => clone it instead788                $draggable = $draggable.clone();789				/**790				 * Initialize tippy.js and make sure the tooltip really should be there (depends on context)791				 */792                $draggable.find( '.js-cred-editor-tippy' ).each( function() {793					OTGSUI.otgsPopoverTooltip.initSingle( this );794					this._tippy.set( {795						onShow: function( tip ) {796							Toolset.CRED.ScaffoldEditor.maybeShowTooltip( tip );797						}798					} );799                } );800            }801            var $blockContainer = jQuery( '.cred-editor-scaffold-' + currentInstance.getFieldTypeForSidebarBlocks( $draggable.data( 'fieldtype' ) ) + '-list' );802            $droppable.before( $draggable );803            if ( $blockContainer.length && ! $blockContainer.children( ':not(.ui-draggable-dragging)' ).length ) {804                $blockContainer.parent().parent().addClass( 'hidden' );805            }806            $draggable.removeClass( 'cred-scaffold-conditional-child' );807            $droppable.closest( '.js-cred-editor-scaffold-item-wrapper-conditionals' ).removeClass( 'cred-editor-scaffold-item-wrapper-conditionals-hover' );808            if ( $droppable.hasClass( 'cred-editor-scaffold-dropping-zones-conditional' ) ) {809                $draggable.addClass( 'cred-scaffold-conditional-child' );810                var $conditionalContainer = $droppable.closest( '.js-cred-editor-scaffold-item-wrapper-conditionals' );811                $conditionalContainer.addClass( 'cred-editor-scaffold-conditional-has-children' );812            }813            if ( $droppable.hasClass( 'cred-editor-scaffold-dropping-zones-horizontal' ) ) {814                $draggable.wrap( '<div class="cred-editor-scaffold-item-wrapper-row" data-cred-cols="1"><div class="cred-editor-scaffold-item-wrapper-item"></div></div>' );815            } else if ( $droppable.hasClass( 'cred-editor-scaffold-dropping-zones-vertical' ) ) {816                $draggable.wrap( '<div class="cred-editor-scaffold-item-wrapper-item"></div>' );817            }818            if ( $draggable.data( currentInstance.scaffold_field_id ) === 'conditionals' ) {819                $draggable.wrap( '<div class="cred-editor-scaffold-item-wrapper-conditionals js-cred-editor-scaffold-item-wrapper-conditionals"></div>' );820            }821            $draggable.parent().append( '<div class="cred-editor-scaffold-item-wrapper-resizer"></div>' );822            if ( ! $draggable.draggable( 'instance' ) ) {823                $draggable.draggable( Object.assign( {}, currentInstance.draggingOptions ));824            }825            $droppableRow.attr( 'data-cred-cols-preview', '1' );826            $droppable.remove();827            // Needed because there is a item duplicated with class name ui-draggable-dragging828            if ( $row[0] !== $droppableRow[0] ) {829                currentInstance.rearrangeColumns( $droppableRow );830            }831            if ( $row.length ) {832                currentInstance.rearrangeColumns( $row );833            }834            // Generate unique IDs835            jQuery( '#js-cred-editor-scaffold-item-list-container .cred-scaffold-html-content:not([id])' ).each( function() {836                jQuery( this ).attr( 'id', 'cred_scaffold_' + parseInt( Math.random() * 100000 ) );837            });838            $draggable.find( '.cred-scaffold-html-content' ).each( function() {839				var $textarea = jQuery( this ),840					id = $textarea.attr( 'id' );841                if ( ! _.has( WPV_Toolset.CodeMirror_instance, id ) ) {842                    WPV_Toolset.CodeMirror_instance[ id ] = icl_editor.codemirror( id, true, { name: 'htmlmixed', autoRefresh: true } );843                }844            });845        },846        over: function ( event, ui ) {847            var $droppable = jQuery( this );848            if ( $droppable.hasClass( 'cred-editor-scaffold-dropping-zones-vertical' ) ) {849                var $row = $droppable.closest( '.cred-editor-scaffold-item-wrapper-row' ),850                    numCols = Number( $row.attr( 'data-cred-cols' ) );851                // preview css rule with higher value will override cred-cols value852                $row.attr( 'data-cred-cols-preview', numCols + 1 ); // prop is used for CSS rules853            }854            $droppable.closest( '.js-cred-editor-scaffold-item-wrapper-conditionals' ).addClass( 'cred-editor-scaffold-item-wrapper-conditionals-hover' );855        },856        out: function( event, ui ) {857            var $droppable = jQuery( this ),858                $row = $droppable.closest( '.cred-editor-scaffold-item-wrapper-row' );859            $row.attr( 'data-cred-cols-preview', '1' ); // prop is used for CSS rules860            $droppable.closest( '.js-cred-editor-scaffold-item-wrapper-conditionals' ).removeClass( 'cred-editor-scaffold-item-wrapper-conditionals-hover' );861        },862        tolerance: 'pointer'863    });864    jQuery( '.js-cred-editor-scaffold-options-close:visible' ).click();865}866/**867 * Removes dropping zones868 *869 * @since 2.3870 */871Toolset.CRED.ScaffoldEditor.prototype.removeDroppingZones = function() {872    var currentInstance = this;873    jQuery( '.cred-editor-scaffold-item-wrapper-resizer' ).removeClass( 'hidden' );874    jQuery( '.cred-editor-scaffold-item-list-container .cred-editor-scaffold-item-list' ).removeClass( 'cred-editor-scaffold-is-dragging' );875    jQuery( '.js-cred-editor-scaffold-dropping-zones' ).removeClass( 'dropzonein' ).addClass( 'dropzoneout' );876    jQuery( '.cred-editor-scaffold-dropping' ).removeClass( 'cred-editor-scaffold-dropping' );877    setTimeout( function() {878        jQuery( '.js-cred-editor-scaffold-dropping-zones' ).remove();879        currentInstance.removeEmptyWrappers();880    }, 550 );881}882/**883 * Remove empty item wrappers884 */885Toolset.CRED.ScaffoldEditor.prototype.removeEmptyWrappers = function() {886    jQuery('.cred-editor-scaffold-item-wrapper-item:empty').each( function() {887        var $this = jQuery(this);888        var $parent = $this.parent();889        if ( $parent.children().length === 1 ) {890            $parent.remove();891        } else {892            $this.remove();893        }894    } );895}896/**897 * Returns the proper fieldtype for sidebar columns898 *899 * @param {String} fieldType900 * @return {String}901 * @since 2.3902 */903Toolset.CRED.ScaffoldEditor.prototype.getFieldTypeForSidebarBlocks = function( fieldType ) {904    if ( [ 'basic', 'legacyParent', 'hierarchicalParent' ].includes( fieldType ) ) {905        fieldType = 'post-elements';906    }907    if ( [ 'formElement', 'form-elements' ].includes( fieldType ) ) {908        fieldType = 'extra';909    }910    return fieldType;911};912/**913 * Init javascript events914 *915 * @since 2.3916 */917Toolset.CRED.ScaffoldEditor.prototype.initEvents = function() {918    var currentInstance = this;919    // Greatest Common Divisor. It is used to reduce the columns sizes to a simplest ones920    // For example 3x6x3 is reduced to 1x2x1921    // @link https://www.w3resource.com/javascript-exercises/javascript-math-exercise-9.php922    var gcdMoreThanTwoNumbers = function( input ) {923        if ( toString.call( input ) !== "[object Array]" ) {924            return  false;925        }926        var len, a, b;927        len = input.length;928        if ( !len ) {929            return null;930        }931        a = input[ 0 ];932        for ( var i = 1; i < len; i++ ) {933            b = input[ i ];934            a = gcdTwoNumbers( a, b );935        }936        return a;937    }938    var gcdTwoNumbers = function( x, y ) {939        if ( ( typeof x !== 'number' ) || ( typeof y !== 'number' ) ) {940            return false;941        }942        x = Math.abs(x);943        y = Math.abs(y);944        while( y ) {945            var t = y;946            y = x % y;947            x = t;948        }949        return x;950    }951    // Handles fields columns width952    // Gets the previous value, so it can be set if new value is not allowed953    // 'mousedown' must be used because number inputs have buttons for increasing/decresing the value, and clicking them triggers 'change' event but not 'focus'954    // This should not be needed anymore.955    if ( window.cred_scaffold_events_are_init ) {956        return;957    }958    var resizingHelper = null;959    var resizingInitialItemPosX = 0;960    var resizingGap = 50;961    jQuery( document ).on( 'mousedown', '.cred-editor-scaffold-item-wrapper-resizer', function( event ) {962        resizingHelper = this;963        var $resizedItem = jQuery( resizingHelper ).closest( '.cred-editor-scaffold-item-wrapper-item' );964        // 'dataset' is used because 'jQuery.data' use internal vars, not HTML attributes, needed for CSS rules.965        resizingHelper.dataset.previousNumberColumns = $resizedItem.dataset.credFieldCols;966        resizingInitialItemPosX = event.clientX;967        jQuery( '.cred-editor-scaffold-item-list' ).append( '<div class="cred-editor-scaffold-item-list-overlay"></div>' );968        resizingGap = $resizedItem.closest( '.cred-editor-scaffold-item-wrapper-row' ).width() / 12;969    } );970    jQuery( document ).on( 'mouseup', function( event ) {971        if ( resizingHelper ) {972            resizingHelper = null;973            jQuery( '.cred-editor-scaffold-item-list-overlay' ).remove();974        }975    });976    /**977     * When resizing the columns, it will take 1/12 part of the next column. So first, change the row to 12-columns is mandatory978     * Also, using Greatest Common Divisor helps to reduce the number of columns in the row: 6x6 is transformed in 1x1.979     * And it will be easier to handled when adding new items.980     */981    jQuery( document ).on( 'mousemove', _.throttle( function( event ) {982        if ( ! resizingHelper ) {983            return;984        }985        var diffX = event.clientX - resizingInitialItemPosX;986        if ( Math.abs( diffX ) < resizingGap ) {987            return;988        }989        var $resizingHelper = jQuery( resizingHelper );990        var previousNumberColumns = Number( resizingHelper.dataset.previousNumberColumns ) || 1;991        var $item = $resizingHelper.closest( '.cred-editor-scaffold-item-wrapper-item' );992        var $row = $resizingHelper.closest( '.cred-editor-scaffold-item-wrapper-row' );993        // Counting number of columns994        var numberColumns = [];995        var $rowItems = $row.find( '> .cred-editor-scaffold-item-wrapper-item' );996        var itemPosition = $rowItems.index( $item );997        $rowItems.each( function() {998            numberColumns.push( Number( this.dataset.credFieldCols ) || 1 );999        } );1000        var totalNumberColumns = numberColumns.reduce( function( a, b ) {1001            return a + b;1002        } );1003        var credCols = $row[0].dataset.credCols;1004        // Convert it to a 12 columns model1005        if ( credCols !== 12 ) {1006            var multiplier = 12 / credCols;1007            numberColumns = numberColumns.map( function( n ) {1008                return n * multiplier;1009            } );1010        }1011        if ( diffX > 0 && numberColumns[ itemPosition + 1 ] > 1 ) {1012            numberColumns[ itemPosition ]++;1013            numberColumns[ itemPosition + 1 ]--;1014        } else if ( diffX < 0 && numberColumns[ itemPosition ] > 1 ) {1015            numberColumns[ itemPosition ]--;1016            numberColumns[ itemPosition + 1 ]++;1017        } else {1018            return;1019        }1020        // Reduce the columns to a simplest way1021        var gcd = gcdMoreThanTwoNumbers( numberColumns );1022        numberColumns = numberColumns.map( function( n ) {1023            return n / gcd;1024        } );1025        totalNumberColumns = numberColumns.reduce( function( a, b ) {1026            return a + b;1027        } );1028        if ( totalNumberColumns > 12  ) {1029            return;1030        }1031        var i = 0;1032        $rowItems.each( function() {1033            this.dataset.credFieldCols = numberColumns[ i ];1034            i++;1035        } );1036        $row[0].dataset.credCols = totalNumberColumns;1037        resizingInitialItemPosX = event.clientX;1038    }, 50, true ) );1039    jQuery( document ).on( 'click', '.js-cred-editor-scaffold-sidebar-collapse', function( e ) {1040        e.preventDefault();1041        var $editorSidebar = jQuery( '#js-cred-editor-scaffold-sidebar' );1042        $editorSidebar1043            .find( '.fa-angle-up' )1044                .trigger( 'click' );1045        jQuery( '.js-cred-editor-scaffold-sidebar-expand, .js-cred-editor-scaffold-sidebar-collapse' ).toggleClass( 'hidden' );1046    });1047    jQuery( document ).on( 'click', '.js-cred-editor-scaffold-sidebar-expand', function( e ) {1048        e.preventDefault();1049        var $editorSidebar = jQuery( '#js-cred-editor-scaffold-sidebar' );1050        $editorSidebar1051            .find( '.fa-angle-down' )1052                .trigger( 'click' );1053        jQuery( '.js-cred-editor-scaffold-sidebar-expand, .js-cred-editor-scaffold-sidebar-collapse' ).toggleClass( 'hidden' );1054    });1055    jQuery( document ).on( 'click', '.js-cred-editor-scaffold-sidebar-toggle', function( e ) {1056        e.preventDefault();1057        var $toggler = jQuery( this ),1058            $editorSidebar = jQuery( '#js-cred-editor-scaffold-sidebar' ),1059            $editorListContainer = jQuery( '#js-cred-editor-scaffold-item-list-container' );1060        $toggler.find( 'i' ).toggleClass( 'fa-angle-right fa-angle-left' );1061        $editorSidebar.find( '.js-cred-editor-scaffold-sidebar-collapse' ).toggle();1062        $editorSidebar.find( '.js-cred-editor-scaffold-sidebar-group' ).toggle();1063        $editorSidebar.toggleClass( 'cred-editor-scaffold-sidebar-hidden' );1064        $editorListContainer.toggleClass( 'cred-editor-scaffold-item-list-container-full-width', $editorSidebar.hasClass( 'cred-editor-scaffold-sidebar-hidden' ) );1065    });1066    /**1067     * Removing elements from editor1068     *1069     * @since 2.11070     */1071    jQuery( document ).on( 'click', '.js-cred-editor-scaffold-item-include-remove:visible', function( e ) {1072        e.preventDefault();1073        var $control = jQuery( this ),1074            $container = $control.closest( '.js-cred-editor-scaffold-item-container' ),1075            fieldId = $container.data( currentInstance.scaffold_field_id ),1076            $maybeContainerWrapper = $container.closest( '.cred-editor-scaffold-item-wrapper-conditionals' ),1077            $droppableRow = $container.closest( '.cred-editor-scaffold-item-wrapper-row' ),1078            fieldType = currentInstance.getFieldTypeForSidebarBlocks( $container.data('fieldtype') ),1079            $target = jQuery( '.cred-editor-scaffold-' + fieldType + '-list' );1080        // Remove children1081        $container.parent('.js-cred-editor-scaffold-item-wrapper-conditionals').find( '.cred-editor-scaffold-item-wrapper-row .js-cred-editor-scaffold-item-include-remove').click();1082        if ( $container.hasClass( 'js-cred-editor-scaffold-item-container-options-opened' ) ) {1083            jQuery('.js-cred-editor-scaffold-options-close:visible').click();1084        }1085        if ( 'conditionals' != fieldId ) {1086            $maybeContainerWrapper = $container;1087        }1088        $maybeContainerWrapper.addClass( 'cred-editor-scaffold-item-deleted' );1089        $maybeContainerWrapper1090            .find( '.js-cred-editor-scaffold-item-container' )1091                .addClass( 'cred-editor-scaffold-item-deleted' );1092        if ( $container.hasClass( 'js-cred-editor-scaffold-item-container-can-toggle' ) ) {1093            $container.find( '.js-cred-editor-scaffold-item-options-toggle.fa-angle-up' ).trigger( 'click' );1094        }1095        $maybeContainerWrapper.fadeOut( 100, function() {1096            $container.closest( '.cred-editor-scaffold-item-wrapper-item' ).find( '.cred-editor-scaffold-item-wrapper-resizer' ).remove();1097            $container.removeClass( 'cred-scaffold-conditional-child' );1098            var $conditionalContainer = $container.closest( '.js-cred-editor-scaffold-item-wrapper-conditionals' );1099            if ( $conditionalContainer.find( '.cred-scaffold-conditional-child' ).length ) {1100                $conditionalContainer.addClass( 'cred-editor-scaffold-conditional-has-children' );1101            } else {1102                $conditionalContainer.removeClass( 'cred-editor-scaffold-conditional-has-children' );1103            }1104            if ( ! $container.data('permanent') ) {1105                $container1106                    .addClass( 'cred-editor-scaffold-item-restored' )1107                    .removeClass( 'cred-editor-scaffold-item-deleted' )1108                // Cancel link buttons has a special behavior1109                if ( 'cancel' === fieldId ) {1110                    if ( ! $target.find( '[data-' + currentInstance.scaffold_field_id + '=cancel]' ).length ) {1111                        $target.prepend( $container );1112                    }1113                } else {1114                    $target.prepend( $container );1115                }1116                $container.fadeIn( 100, function() {1117                    $container.removeClass( 'cred-editor-scaffold-item-restored' );1118                });1119                if ( $target.children().length ) {1120                    $target.closest( '.cred-editor-scaffold-' + fieldType + '-container' ).removeClass( 'hidden' );1121                }1122				/**1123				 * Initialize tippy.js and make sure the tooltip really should be there (depends on context)1124				 */1125				OTGSUI.otgsPopoverTooltip.initSingle( $container[0] );1126				$container[0]._tippy.set( {1127					onShow: function( tip ) {1128						Toolset.CRED.ScaffoldEditor.maybeShowTooltip( tip );1129					}1130				} );1131            } else {1132                $maybeContainerWrapper.remove();1133            }1134            // Refresh draggable instance1135            if ( $container.draggable( 'instance' ) ) {1136                $container.draggable( 'destroy' );1137            }1138            $container.draggable( currentInstance.draggingOptions );1139            Toolset.hooks.doAction( 'cred_editor_insert_scaffold' );1140            currentInstance.removeEmptyWrappers();1141            currentInstance.rearrangeColumns( $droppableRow );1142            var numCols = 0;1143            var $dropppableRowChildren = $droppableRow.children( '.cred-editor-scaffold-item-wrapper-item' );1144            $dropppableRowChildren.each( function() {1145                numCols += Number( this.dataset.credFieldCols ) || 1;1146            } );1147            if ( $dropppableRowChildren.length === 1 ) {1148                numCols = 1;1149            }1150            $droppableRow.attr( 'data-cred-cols', numCols );1151        });1152    });1153    /**1154     * Adding elements to editor1155     *1156     * @since 2.11157     */1158    jQuery( document ).on( 'click', '.js-cred-editor-scaffold-item-push', function( e ) {1159        e.preventDefault();1160        var $container = jQuery( this ).closest( '.js-cred-editor-scaffold-item-container' ),1161			$editorList = jQuery( '.js-cred-editor-scaffold-item-list' ),1162			$blockContainer = jQuery( '.cred-editor-scaffold-' + currentInstance.getFieldTypeForSidebarBlocks( $container.data( 'fieldtype' ) ) + '-list' );1163        if ( $container.data( 'permanent' ) ) {1164            $container = $container.clone();1165			/**1166			 * Initialize tippy.js and make sure the tooltip really should be there (depends on context)1167			 */1168            $container.find( '.js-cred-editor-tippy' ).each( function() {1169				OTGSUI.otgsPopoverTooltip.initSingle( this );1170				this._tippy.set( {1171					onShow: function( tip ) {1172						Toolset.CRED.ScaffoldEditor.maybeShowTooltip( tip );1173					}1174				} );1175            } );1176        }1177        $container.fadeOut( 750, function() {1178			$container.addClass( 'cred-editor-scaffold-item-added' )1179			$editorList.append( $container );1180            if ( 0 == $blockContainer.children().length ) {1181                $blockContainer.parent().parent().addClass( 'hidden' );1182            }1183            $container.wrap( '<div class="cred-editor-scaffold-item-wrapper-row" data-cred-cols="1"><div class="cred-editor-scaffold-item-wrapper-item"></div></div>' );1184            if ( $container.data( currentInstance.scaffold_field_id ) === 'conditionals' ) {1185                $container.wrap( '<div class="cred-editor-scaffold-item-wrapper-conditionals js-cred-editor-scaffold-item-wrapper-conditionals"></div>' );1186            }1187            $container.fadeIn( 750, function() {1188                $container1189                    .removeClass( 'cred-editor-scaffold-item-added' )1190					.draggable( Object.assign( {}, currentInstance.draggingOptions ));1191				// Relationship forms: apply knockout bindings1192				if ( $container.data( 'permanent' ) ) {1193					Toolset.hooks.doAction( 'cred_editor_scaffold_do_knockout_binding', $container[0] );1194				}1195				// Initialize Codemirror instance if adding an HTML block1196				if ( 'html' === $container.data( currentInstance.scaffold_field_id ) ) {1197					var $htmlTextarea = $container.find( 'textarea.cred-scaffold-html-content' ),1198						htmlTextareaId = 'cred_scaffold_' + parseInt( Math.random() * 100000 );1199					$htmlTextarea.attr( 'id', htmlTextareaId );1200					if ( ! _.has( WPV_Toolset.CodeMirror_instance, htmlTextareaId ) ) {1201						WPV_Toolset.CodeMirror_instance[ htmlTextareaId ] = icl_editor.codemirror( htmlTextareaId, true, { name: 'htmlmixed', autoRefresh: true } );1202					}1203					WPV_Toolset.CodeMirror_instance[ htmlTextareaId ].refresh();1204				}1205            });1206        });1207    });1208    // Collapse Generic fields1209    Toolset.hooks.addAction( 'cred-action-toolbar-scaffold-content-loaded', function() {1210        jQuery( '.js-cred-editor-toggler[data-target="scaffold-generic"] .fa-angle-up' ).click();1211    } );1212    // Avoids second calls1213    window.cred_scaffold_events_are_init = true;1214};1215/**1216 * Columns must fit 12 columns Bootstrap design1217 *1218 * @since 2.31219 */1220Toolset.CRED.ScaffoldEditor.prototype.rearrangeColumns = function( $row ) {1221    var divisors = [1, 2, 3, 4, 6, 12];1222    var $rowItems = $row.find( '> .cred-editor-scaffold-item-wrapper-item > .js-cred-editor-scaffold-item-container:not(.ui-draggable-dragging), > .cred-editor-scaffold-item-wrapper-item > .js-cred-editor-scaffold-item-wrapper-conditionals' );1223    var numberOfColumns = $rowItems.length;1224    var credCols = divisors.reduce( function( a, b ) {1225        return a >= numberOfColumns ? a : b;1226    } );1227    var sizeColumn = Math.floor( credCols / numberOfColumns );1228    var remainder = credCols % numberOfColumns;1229    $row.attr( 'data-cred-cols', credCols );1230    $rowItems.filter( ':lt(' + ( numberOfColumns - remainder ) + ')' ).each( function() {1231        this.parentNode.dataset.credFieldCols = sizeColumn;1232    } );1233    $rowItems.filter( ':gt(' + ( numberOfColumns - remainder - 1 ) + ')' ).each( function() {1234        this.parentNode.dataset.credFieldCols = sizeColumn + 1;1235    } );1236}1237/**1238 * Gets scaffold data equivalent from HTML content1239 * It is not possible to parse an exact copy from HTML to1240 *1241 * @param {string} content1242 * @since 2.31243 */1244Toolset.CRED.ScaffoldEditor.prototype.parseHTMLtoScaffold = function( content ) {1245    var self = this;1246    /**1247     * Converts text into a HTMLNode1248     *1249     * @param {string} content1250     */1251    var convertToDom = function( content ) {1252        var parserElement = document.createElement( 'parser' );1253        parserElement.innerHTML = content;1254        return parserElement;1255    };1256    /**1257     * Parsers a string to gets the attributes of a shortcode1258     *1259     * @param {string} shortcodeContent1260     */1261    var getAttributesFromShortcode = function( shortcodeContent ) {1262        var item = {};1263        var match = shortcodeContent.match( /\[[^\[]*\]/g )1264        if ( ! match ) {1265            var field = {};1266            field[ self.scaffold_field_id ] = 'html';1267            field.value = shortcodeContent.trim();1268            return field;1269        }1270        match.forEach( function( shortcode ) {1271            var attributes = shortcode1272                // Captures first quote (single or double) and continues until next instance of the quote captured1273                .match(  /[\w_-]+=(['"])((?!\1).)+\1/gu );1274            if ( attributes ) {1275                attributes.forEach( function( attr ) {1276                    attr = attr.split('=');1277                    item[attr[0]] = attr[1].slice(1, -1);1278                } );1279            }1280        } );1281        return item;1282    }1283    /**1284     * Get conditionals from string1285     *1286     * @param {string} conditionalText1287     */1288    var getConditionals = function( conditionalText ) {1289        var conditionals = [];1290        conditionalText.match( /([AND|OR]?)[^\(]*\([^\)]*\)[^\)]+\)/g )1291            .forEach( function( matchedCondition ) {1292                var conditionElements = matchedCondition.match( /(\w+)?\s*\(\s*\$\(([^\)]*)\)\s+(\w+)\s+'([^']+)'\s+\)/ );1293                if ( conditionElements ) {1294                    var condition = {};1295                    if ( conditionElements[1] ) {1296                        condition.connect = conditionElements[1];1297                    }1298                    condition.origin = conditionElements[2];1299                    condition.operator = conditionElements[3];1300                    condition.value = conditionElements[4];1301                    conditionals.push( condition );1302                }1303            } );1304        return conditionals;1305    }1306    /**1307     * Gets the label text1308     *1309     * @param {HTMLNode} node1310     * @return {string\null}1311     */1312    var getLabel = function ( node ) {1313        if ( node.nodeType !== Node.ELEMENT_NODE ) {1314            return null;1315        }1316        var label = node.querySelector( 'label' );1317        if ( label ) {1318            return label.innerHTML;1319        }1320        return null;1321    }1322    /**1323     * Having a text, it finds shortcodes and parses them1324     *1325     * @param {string} shorcodeHTML1326     */1327    var parseShortcode = function( shortcodeHTML ) {1328        if ( shortcodeHTML.match( /field="(category_add_new|post_tag_popular)"/ ) ) {1329            return null;1330        }1331        var conditionalRegEx = /\[cred_show_group[^\[]*\]([^]*)\[\/cred_show_group\]/g;1332        var genericFieldRegEx = /\[cred_generic_field[^\[]*\]([^]*)\[\/cred_generic_field\]/g;1333        var match = conditionalRegEx.exec( shortcodeHTML );1334        if ( match ) {1335            do {1336                var conditional = parseShortcode( match[0].match( /(\[cred_show_group[^\[]*\]).*/, '$1' )[0] );1337                conditional.children = self.parseHTMLtoScaffold( '<div class="container-fluid">' + match[1] + '</div>' );1338                conditional.children.forEach( function(child) {1339                    child.isNested = true;1340                } );1341                conditional.conditionals = { conditions: [], useGui: true };1342                conditional.conditionals.conditions = getConditionals( conditional.if );1343                delete conditional.if;1344                conditional[ self.scaffold_field_id ] = 'conditionals';1345                conditional.fieldtype = 'extra';1346                return conditional;1347            } while ( match = conditionalRegEx.exec( shortcodeHTML ) );1348        } else {1349            var item = {};1350            if ( ( match = genericFieldRegEx.exec( shortcodeHTML ) ) ) {1351                item = getAttributesFromShortcode( match[0].match( /(\[cred_generic_field[^\[]*\]).*/, '$1' )[0] );1352                try {1353                    Object.assign( item, JSON.parse( match[1].trim() ) );1354                } catch( e ) {1355                    return null;1356                }1357                var htmlNode = convertToDom( shortcodeHTML );1358                var label = htmlNode.querySelector( 'label' );1359                if ( label ) {1360                    item.label = label.innerHTML;1361                }1362                item.fieldtype = 'generic';1363            } else {1364                item = getAttributesFromShortcode( shortcodeHTML );1365            }1366            var htmlNode = convertToDom( shortcodeHTML );1367            var label = getLabel( htmlNode );1368            if ( label ) {1369                item.label = label;1370            }1371            if ( !item[ self.scaffold_field_id ] ) {1372                if ( !! item.role ) {1373                    item[ self.scaffold_field_id ] = item.role;1374                } else if ( !! item.type ) {1375                    item[ self.scaffold_field_id ] = item.type;1376                } else if ( !! item.name ) {1377                    item[ self.scaffold_field_id ] = item.name;1378                } else if ( !! item.field ) {1379                    item[ self.scaffold_field_id ] = item.field;1380                } else {1381                    // Checks if there is a different form shortcode1382                    var formShortcode = shortcodeHTML.match( /\[cred-form-(\w+)/ );1383                    if ( formShortcode ) {1384                        if ( [ 'feedback', 'submit', 'cancel' ].includes( formShortcode[1] ) ) {1385                            item[ self.scaffold_field_id ] = formShortcode[1];1386                        }1387                    }1388                }1389            }1390            if ( ! Object.keys(item).length ) {1391                return null;1392            }1393            if ( ! item.fieldtype ) {1394                item.fieldtype = self.getFieldTypeFromField( item );1395            }1396            item.isNested = false;1397            return item;1398        }1399    };1400    var items = [];1401    // Checks if it uses Bootstrap1402    var element = convertToDom( content );1403    var rows = element.querySelectorAll( '.container-fluid > .row' );1404    if ( rows.length ) {1405        rows.forEach( function(row) {1406            var numColumns = 0;1407            Array.apply([], row.childNodes).filter( function(element) {1408                return Array.apply([], element.classList).filter( function(className) {1409                    return className.match(/col-/);1410                }).length;1411            }).forEach( function(item) {1412                var label = getLabel( item );1413                var sizeColumn = item.getAttribute('class').match( /col-\w{2}-(\d+)/ );1414                // An item might have several shortcodes1415                var shortcodes = item.innerHTML.match(wp.shortcode.regexp('[\\w-]+'));1416                if ( shortcodes ) {1417                    shortcodes.forEach( function( shortcodeHTML ) {1418                        var itemParsed = parseShortcode( shortcodeHTML );1419                        if ( itemParsed ) {1420                            itemParsed.sizeColumn = sizeColumn.length? Number( sizeColumn[1] ) : 1;1421                            numColumns += itemParsed.sizeColumn;1422                            itemParsed.numColumns = -1; // initial value that will be changed1423                            if ( label ) {1424                                itemParsed.label = label;1425                            }1426                            if ( itemParsed ) {1427                                items.push( itemParsed );1428                            }1429                        }1430                    } );1431                } else {1432                    // HTML field1433                    var htmlItem = {}1434                    htmlItem[ self.scaffold_field_id ] = 'html';1435                    htmlItem.fieldType = htmlItem.fieldtype = 'extra';1436                    htmlItem.sizeColumn = Number( sizeColumn[1] );1437                    htmlItem.numColumns = -1;1438                    numColumns += htmlItem.sizeColumn;1439                    htmlItem.value = item.innerHTML.trim();1440                    if ( label ) {1441                        htmlItem.label = label;1442                    }1443                    items.push( htmlItem );1444                }1445            } );1446            items.forEach( function( item ) {1447                if ( item.numColumns === -1 ) {1448                    item.numColumns = numColumns;1449                }1450            } );1451        } );1452    } else {1453        // Conditional groups have to be wrapped by a layer so childNodes gets the complete shortcode1454        element.innerHTML = element.innerHTML1455            .replace( '[cred_show_group', '<div>[cred_show_group' )1456            .replace( '[/cred_show_group]', '[/cred_show_group]</div>' );1457        Array.apply([], element.childNodes).filter( function(child) {1458            if (child.nodeType === Node.TEXT_NODE) {1459                return child.textContent.trim();1460            }1461            return true;1462        } ).forEach( function( item ) {1463            var label = getLabel( item );1464            var itemHTML = item.nodeType === Node.TEXT_NODE1465                ? item.textContent1466                : item.innerHTML;1467            // An item might have several shortcodes1468            var shortcodes = itemHTML.match(wp.shortcode.regexp('[\\w-]+'))1469            if ( shortcodes ) {1470                shortcodes.forEach( function( shortcodeHTML ) {1471                    var itemParsed = parseShortcode( shortcodeHTML );1472                    if ( itemParsed ) {1473                        itemParsed.sizeColumn = 1;1474                        itemParsed.numColumns = 1;1475                        if ( label ) {1476                            itemParsed.label = label;1477                        }1478                        items.push( itemParsed );1479                    }1480                } );1481            }1482        } );1483    }1484    return items;1485};1486/**1487 * Returns the field type depending on the shortcode, necessary when parsing back to D&D scaffold1488 *1489 * @param {object} field1490 * @return {string}1491 * @since 2.31492 */1493Toolset.CRED.ScaffoldEditor.prototype.getFieldTypeFromField = function( field ) {1494    if ( field.field === 'post_parent' ) {1495        return 'hierarchicalParent';1496    }1497    if ( field.shortcode === 'cred_generic_field' ) {1498        return 'generic';1499    }1500    if ( [ 'parent', 'child' ].includes( field[ this.scaffold_field_id ] ) ) {1501        return 'relationship';1502    }1503    if ( [ 'post_content', '_featured_image', 'post_excerpt', 'post_title' ].includes( field[ this.scaffold_field_id ] ) ) {1504        return 'basic';1505    }1506    if ( [ 'form_messages', 'form_submit' ].includes( field[ this.scaffold_field_id ] ) ) {1507        return 'formElement';1508    }1509    if ( [ 'feedback', 'submit', 'cancel' ].includes( field[ this.scaffold_field_id ] ) ) {1510        return 'form-elements';1511    }1512    if ( [ 'category', 'post_tag' ].includes( field[ this.scaffold_field_id ] ) ) {1513        return 'taxonomy';1514    }1515    return 'meta';1516}1517/**1518 * Displays the tooltip depending on some conditions1519 *1520 * @param {object} tip Tippy reference1521 * @since 2.31522 */1523Toolset.CRED.ScaffoldEditor.maybeShowTooltip = function( tip ) {1524    var hide = tip.reference.classList.contains('cred-editor-scaffold-item-container') && ! jQuery( tip.reference ).closest( '.js-cred-editor-scaffold-sidebar' ).length;1525    if ( !! tip.reference.dataset.tippyCondition ) {1526        if ( 'text-not-visible' === tip.reference.dataset.tippyCondition ) {1527            var titleNode = tip.reference.querySelector( '.js-cred-editor-scaffold-field-title' );1528            if ( titleNode) {1529                hide = titleNode.offsetWidth === titleNode.scrollWidth;1530            }1531        }1532    }1533    if ( ! tip.reference.dataset.tippyContent ) {1534        hide = true;1535    }1536    // In relationship forms, due to ko, the content may be not set during object initialization.1537    if ( ! tip.props.content && !! tip.reference.dataset.tippyContent ) {1538        tip.setContent( tip.reference.dataset.tippyContent )1539    }1540    tip.popper.style.display = hide ? 'none' : null;1541    if ( ! hide ) {1542        document.querySelectorAll('.tippy-popper').forEach( function( popper ) {1543            if (popper.style.display !== 'none' && popper.getAttribute( 'id' ) !== tip.id) {1544            popper._tippy.hide();1545            }1546        } );1547    }...

Full Screen

Full Screen

frenzy.js

Source:frenzy.js Github

copy

Full Screen

...231      }232    });233  }),234  describe("[call-sequence-1] Scaffold that installs a frenzy service that delays 50ms and some helpers.",235    scaffold(each, function(space) { setupScaffold(50); }, function(space) { takedownScaffold(space); }),236    note("The timings are big to make sure the desired control paths are traversed."),237    describe("Scaffold that makes several calls to the frenzy service, then delays 20 ms.",238      scaffold(each, function(space) { return exercise(space, 1, 20); }),239      describe("Scaffold that makes several calls to the frenzy service, then delays 100 ms.",240        scaffold(each, function(space) { return exercise(space, 3, 100); }),241        describe("Scaffold that makes several calls to the frenzy service, then delays 20 ms.",242          scaffold(each, function(space) { return exercise(space, 5, 20); }),243          describe("Scaffold that makes several calls to the frenzy service, then delays 20 ms.",244            scaffold(each, function(space) { return exercise(space, 7, 20); }),245            demo("Notice the first two sets of calls are handled by one transaction and then the second two sets of calls are handled by another transaction.", function(space) {246              return space.watch(10, 2000, function() {247                if (scaffold.failCount + scaffold.successCount==8) {248                  for (var i= 1; i<=4; i++) {249                    the(scaffold.slots[i].result.value).is(i);250                    the(scaffold.slots[i+4].result.value).is(i+4);251                    the(scaffold.slots[i].serviceInfo.transactionId).is(1);252                    the(scaffold.slots[i+4].serviceInfo.transactionId).is(2);253                  };254                  return true;255                } else {256                  return false;257                }258              });259            })260          )261        )262      )263    )264  ),265  describe("[call-sequence-2] Scaffold that installs a frenzy service that delays 10ms and some helpers.",266    scaffold(each, function(space) { setupScaffold(10); }, function(space) { takedownScaffold(space); }),267    note("The timings are big to make sure the desired control paths are traversed."),268    describe("Scaffold that makes several calls to the frenzy service, then delays 50 ms.",269      scaffold(each, function(space) { return exercise(space, 1, 50); }),270      describe("Scaffold that makes several calls to the frenzy service, then delays 50 ms.",271        scaffold(each, function(space) { return exercise(space, 3, 50); }),272        describe("Scaffold that makes several calls to the frenzy service, then delays 50 ms.",273          scaffold(each, function(space) { return exercise(space, 5, 50); }),274          describe("Scaffold that makes several calls to the frenzy service, then delays 50 ms.",275            scaffold(each, function(space) { return exercise(space, 7, 50); }),276            demo("Notice that each set of calls are handled by an individual transaction.", function(space) {277              return space.watch(10, 2000, function() {278                if (scaffold.failCount + scaffold.successCount==8) {279                  for (var i= 1; i<=8; i++) {280                    the(scaffold.slots[i].result.value).is(i);281                    the(scaffold.slots[i].serviceInfo.transactionId).is(Math.floor((i+1) / 2)); //1, 1, 2, 2, 3, 3, 4, 4282                  };283                  return true;284                } else {285                  return false;286                }287              });288            })289          )290        )291      )292    )293  ),294  describe("[long-call] Call a server procedure that takes a long time to complete.",295    scaffold(each, function(space) { setupScaffold(10); }, function(space) { takedownScaffold(space); }),296    demo("Call the long-running proc (only); resulting in periodic polling for the result until it is returned.", function(space) {297      var 298        currentTransactionId= scaffold.frenzy.transactionId;299      scaffold.frenzy.call("longCall", {value:1}, scaffold.onResults, scaffold.OnError);300      return space.watch(50, 2000, function() {301        if ((scaffold.failCount + scaffold.successCount)==1) {302          the(scaffold.slots[1].result.value).is(1);303          the(scaffold.slots[1].serviceInfo.transactionId).isNot(currentTransactionId+1);304          return true;305        } else {306          return false;307        }308      });309    }),310    note(//Normally, a server would not return until it had something to return (perhaps only a keep-alive message after a long timeout).311         //With such a design, the "polling" algorithm is effectively an asynchronous event signalling algorithm.312    ),313    demo("Call the long-running proc and some short ones; resulting in periodic polling for the result until it is returned.", function(space) {314      var315        currentTransactionId= scaffold.frenzy.transactionCounter;316      scaffold.frenzy.call("identity", {value:1}, scaffold.onResults, scaffold.OnError);317      scaffold.frenzy.call("identity", {value:2}, scaffold.onResults, scaffold.OnError);318      scaffold.frenzy.call("longCall", {value:3}, scaffold.onResults, scaffold.OnError);319      return space.watch(50, 2000, function() {320        if ((scaffold.failCount+scaffold.successCount)==3) {321          the(scaffold.slots[1].result.value).is(1);322          the(scaffold.slots[1].serviceInfo.transactionId).is(currentTransactionId+1);323          the(scaffold.slots[2].result.value).is(2);324          the(scaffold.slots[2].serviceInfo.transactionId).is(currentTransactionId+1);325          the(scaffold.slots[3].result.value).is(3);326          the(scaffold.slots[3].serviceInfo.transactionId).isNot(currentTransactionId+1);327          return true;328        } else {329          return false;330        }331      });332    })333  ),334  describe("[circulating] Circulating Frenzy",335    describe("Circulation with no client-side calls.",336      scaffold(each, function(space) { setupScaffold(50, true); }, function(space) { takedownScaffold(space); }),337      demo(function(space) {338        //this variable is defined at the top of this test unit...339        serverMessageData= "This is some server data and this is junk to show that we didn't properly disconnect".split(" ");340        scaffold.serverData= [];341        scaffold.serverDataAccumulator= function(word) {342          scaffold.serverData.push(word);343          if (scaffold.serverData.length==5) {344            scaffold.frenzy.disconnect("someMessageClass", scaffold.serverDataAccumulator);345          }346        };347        scaffold.frenzy.connect("someMessageClass", scaffold.serverDataAccumulator);348        return space.watch(50, 2000, function() {349          if (scaffold.frenzy.transactionCounter>10) {350            scaffold.frenzy.stop();...

Full Screen

Full Screen

active_scaffold.js

Source:active_scaffold.js Github

copy

Full Screen

1if (typeof Prototype == 'undefined')2{3  warning = "ActiveScaffold Error: Prototype could not be found. Please make sure that your application's layout includes prototype.js (e.g. <%= javascript_include_tag :defaults %>) *before* it includes active_scaffold.js (e.g. <%= active_scaffold_includes %>).";4  alert(warning);5}6if (Prototype.Version.substring(0, 3) != '1.6')7{8  warning = "ActiveScaffold Error: Prototype version 1.6.x is required. Please update prototype.js (rake rails:update:javascripts).";9  alert(warning);10}11/*12 * Simple utility methods13 */14var ActiveScaffold = {15  records_for: function(tbody_id) {16    var rows = [];17    var child = $(tbody_id).down('.record');18    while (child) {19      rows.push(child);20      child = child.next('.record');21    }22    return rows;23  },24  stripe: function(tbody_id) {25    var even = false;26    var rows = this.records_for(tbody_id);27    for (var i = 0; i < rows.length; i++) {28      var child = rows[i];29      //Make sure to skip rows that are create or edit rows or messages30      if (child.tagName != 'SCRIPT'31        && !child.hasClassName("create")32        && !child.hasClassName("update")33        && !child.hasClassName("inline-adapter")34        && !child.hasClassName("active-scaffold-calculations")) {35        if (even) child.addClassName("even-record");36        else child.removeClassName("even-record");37        even = !even;38      }39    }40  },41  hide_empty_message: function(tbody, empty_message_id) {42    if (this.records_for(tbody).length != 0) {43      $(empty_message_id).hide();44    }45  },46  reload_if_empty: function(tbody, url) {47    var content_container_id = tbody.replace('tbody', 'content');48    if (this.records_for(tbody).length == 0) {49      new Ajax.Updater($(content_container_id), url, {50        method: 'get',51        asynchronous: true,52        evalScripts: true53      });54    }55  },56  removeSortClasses: function(scaffold_id) {57    $$('#' + scaffold_id + ' td.sorted').each(function(element) {58      element.removeClassName("sorted");59    });60    $$('#' + scaffold_id + ' th.sorted').each(function(element) {61      element.removeClassName("sorted");62      element.removeClassName("asc");63      element.removeClassName("desc");64    });65  },66  decrement_record_count: function(scaffold_id) {67    // decrement the last record count, firsts record count are in nested lists68    count = $$('#' + scaffold_id + ' span.active-scaffold-records').last();69    count.innerHTML = parseInt(count.innerHTML) - 1;70  },71  increment_record_count: function(scaffold_id) {72    // increment the last record count, firsts record count are in nested lists73    count = $$('#' + scaffold_id + ' span.active-scaffold-records').last();74    count.innerHTML = parseInt(count.innerHTML) + 1;75  },76  server_error_response: '',77  report_500_response: function(active_scaffold_id) {78    messages_container = $(active_scaffold_id).down('td.messages-container');79    new Insertion.Top(messages_container, this.server_error_response);80  }81}82/*83 * DHTML history tie-in84 */85function addActiveScaffoldPageToHistory(url, active_scaffold_id) {86  if (typeof dhtmlHistory == 'undefined') return; // it may not be loaded87  var array = url.split('?');88  var qs = new Querystring(array[1]);89  var sort = qs.get('sort')90  var dir = qs.get('sort_direction')91  var page = qs.get('page')92  if (sort || dir || page) dhtmlHistory.add(active_scaffold_id+":"+page+":"+sort+":"+dir, url);93}94/*95 * Add-ons/Patches to Prototype96 */97/* patch to support replacing TR/TD/TBODY in Internet Explorer, courtesy of http://dev.rubyonrails.org/ticket/4273 */98Element.replace = function(element, html) {99  element = $(element);100  if (element.outerHTML) {101    try {102    element.outerHTML = html.stripScripts();103    } catch (e) {104      var tn = element.tagName;105      if(tn=='TBODY' || tn=='TR' || tn=='TD')106      {107              var tempDiv = document.createElement("div");108              tempDiv.innerHTML = '<table id="tempTable" style="display: none">' + html.stripScripts() + '</table>';109              element.parentNode.replaceChild(tempDiv.getElementsByTagName(tn).item(0), element);110      }111      else throw e;112    }113  } else {114    var range = element.ownerDocument.createRange();115    /* patch to fix <form> replaces in Firefox. see http://dev.rubyonrails.org/ticket/8010 */116    range.selectNodeContents(element.parentNode);117    element.parentNode.replaceChild(range.createContextualFragment(html.stripScripts()), element);118  }119  setTimeout(function() {html.evalScripts()}, 10);120  return element;121};122/*123 * URL modification support. Incomplete functionality.124 */125Object.extend(String.prototype, {126  append_params: function(params) {127    url = this;128    if (url.indexOf('?') == -1) url += '?';129    else if (url.lastIndexOf('&') != url.length) url += '&';130    url += $H(params).collect(function(item) {131      return item.key + '=' + item.value;132    }).join('&');133    return url;134  }135});136/*137 * Prototype's implementation was throwing an error instead of false138 */139Element.Methods.Simulated = {140  hasAttribute: function(element, attribute) {141    var t = Element._attributeTranslations;142    attribute = (t.names && t.names[attribute]) || attribute;143    // Return false if we get an error here144    try {145      return $(element).getAttributeNode(attribute).specified;146    } catch (e) {147      return false;148    }149  }150};151/**152 * A set of links. As a set, they can be controlled such that only one is "open" at a time, etc.153 */154ActiveScaffold.Actions = new Object();155ActiveScaffold.Actions.Abstract = function(){}156ActiveScaffold.Actions.Abstract.prototype = {157  initialize: function(links, target, loading_indicator, options) {158    this.target = $(target);159    this.loading_indicator = $(loading_indicator);160    this.options = options;161    this.links = links.collect(function(link) {162      return this.instantiate_link(link);163    }.bind(this));164  },165  instantiate_link: function(link) {166    throw 'unimplemented'167  }168}169/**170 * A DataStructures::ActionLink, represented in JavaScript.171 * Concerned with AJAX-enabling a link and adapting the result for insertion into the table.172 */173ActiveScaffold.ActionLink = new Object();174ActiveScaffold.ActionLink.Abstract = function(){}175ActiveScaffold.ActionLink.Abstract.prototype = {176  initialize: function(a, target, loading_indicator) {177    this.tag = $(a);178    this.url = this.tag.href;179    this.method = 'get';180    if(this.url.match('_method=delete')){181      this.method = 'delete';182    } else if(this.url.match('_method=post')){183      this.method = 'post';184    }185    this.target = target;186    this.loading_indicator = loading_indicator;187    this.hide_target = false;188    this.position = this.tag.getAttribute('position');189		this.page_link = this.tag.getAttribute('page_link');190    this.onclick = this.tag.onclick;191    this.tag.onclick = null;192    this.tag.observe('click', function(event) {193      this.open();194      Event.stop(event);195    }.bind(this));196    this.tag.action_link = this;197  },198  open: function() {199    if (this.is_disabled()) return;200    if (this.tag.hasAttribute( "dhtml_confirm")) {201      if (this.onclick) this.onclick();202      return;203    } else {204      if (this.onclick && !this.onclick()) return;//e.g. confirmation messages205      this.open_action();206    }207  },208	open_action: function() {209		if (this.position) this.disable();210		if (this.page_link) {211			window.location = this.url;212		} else {213			if (this.loading_indicator) this.loading_indicator.style.visibility = 'visible';214	    new Ajax.Request(this.url, {215	      asynchronous: true,216	      evalScripts: true,217              method: this.method,218	      onSuccess: function(request) {219	        if (this.position) {220	          this.insert(request.responseText);221	          if (this.hide_target) this.target.hide();222	        } else {223	          request.evalResponse();224	        }225	      }.bind(this),226	      onFailure: function(request) {227	        ActiveScaffold.report_500_response(this.scaffold_id());228	        if (this.position) this.enable()229	      }.bind(this),230	      onComplete: function(request) {231	        if (this.loading_indicator) this.loading_indicator.style.visibility = 'hidden';232	      }.bind(this)233			});234		}235	},236  insert: function(content) {237    throw 'unimplemented'238  },239  close: function() {240    this.enable();241    this.adapter.remove();242    if (this.hide_target) this.target.show();243  },244  register_cancel_hooks: function() {245    // anything in the insert with a class of cancel gets the closer method, and a reference to this object for good measure246    var self = this;247    this.adapter.select('.cancel').each(function(elem) {248      elem.observe('click', this.close_handler.bind(this));249      elem.link = self;250    }.bind(this))251  },252  reload: function() {253    this.close();254    this.open();255  },256  get_new_adapter_id: function() {257    var id = 'adapter_';258    var i = 0;259    while ($(id + i)) i++;260    return id + i;261  },262  enable: function() {263    return this.tag.removeClassName('disabled');264  },265  disable: function() {266    return this.tag.addClassName('disabled');267  },268  is_disabled: function() {269    return this.tag.hasClassName('disabled');270  },271  scaffold_id: function() {272    return this.tag.up('div.active-scaffold').id;273  }274}275/**276 * Concrete classes for record actions277 */278ActiveScaffold.Actions.Record = Class.create();279ActiveScaffold.Actions.Record.prototype = Object.extend(new ActiveScaffold.Actions.Abstract(), {280  instantiate_link: function(link) {281    var l = new ActiveScaffold.ActionLink.Record(link, this.target, this.loading_indicator);282    l.refresh_url = this.options.refresh_url;283    if (link.hasClassName('delete')) {284      l.url = l.url.replace(/\/delete(\?.*)?$/, '$1');285      l.url = l.url.replace(/\/delete\/(.*)/, '/destroy/$1');286    }287    if (l.position) l.url = l.url.append_params({adapter: '_list_inline_adapter'});288    l.set = this;289    return l;290  }291});292ActiveScaffold.ActionLink.Record = Class.create();293ActiveScaffold.ActionLink.Record.prototype = Object.extend(new ActiveScaffold.ActionLink.Abstract(), {294  close_previous_adapter: function() {295    this.set.links.each(function(item) {296      if (item.url != this.url && item.is_disabled() && item.adapter) item.close();297    }.bind(this));298  },299  insert: function(content) {300    this.close_previous_adapter();301    if (this.position == 'replace') {302      this.position = 'after';303      this.hide_target = true;304    }305    if (this.position == 'after') {306      new Insertion.After(this.target, content);307      this.adapter = this.target.next();308    }309    else if (this.position == 'before') {310      new Insertion.Before(this.target, content);311      this.adapter = this.target.previous();312    }313    else {314      return false;315    }316    this.adapter.down('a.inline-adapter-close').observe('click', this.close_handler.bind(this));317    this.register_cancel_hooks();318    new Effect.Highlight(this.adapter.down('td'));319  },320  close_handler: function(event) {321    this.close_with_refresh();322    if (event) Event.stop(event);323  },324  /* it might simplify things to just override the close function. then the Record and Table links could share more code ... wouldn't need custom close_handler functions, for instance */325  close_with_refresh: function() {326    new Ajax.Request(this.refresh_url, {327      asynchronous: true,328      evalScripts: true,329      method: this.method,330      onSuccess: function(request) {331        Element.replace(this.target, request.responseText);332        var new_target = $(this.target.id);333        if (this.target.hasClassName('even-record')) new_target.addClassName('even-record');334        this.target = new_target;335        this.close();336      }.bind(this),337      onFailure: function(request) {338        ActiveScaffold.report_500_response(this.scaffold_id());339      }340    });341  },342  enable: function() {343    this.set.links.each(function(item) {344      if (item.url != this.url) return;345      item.tag.removeClassName('disabled');346    }.bind(this));347  },348  disable: function() {349    this.set.links.each(function(item) {350      if (item.url != this.url) return;351      item.tag.addClassName('disabled');352    }.bind(this));353  }354});355/**356 * Concrete classes for table actions357 */358ActiveScaffold.Actions.Table = Class.create();359ActiveScaffold.Actions.Table.prototype = Object.extend(new ActiveScaffold.Actions.Abstract(), {360  instantiate_link: function(link) {361    var l = new ActiveScaffold.ActionLink.Table(link, this.target, this.loading_indicator);362    if (l.position) l.url = l.url.append_params({adapter: '_list_inline_adapter'});363    return l;364  }365});366ActiveScaffold.ActionLink.Table = Class.create();367ActiveScaffold.ActionLink.Table.prototype = Object.extend(new ActiveScaffold.ActionLink.Abstract(), {368  insert: function(content) {369    if (this.position == 'top') {370      new Insertion.Top(this.target, content);371      this.adapter = this.target.immediateDescendants().first();372    }373    else {374      throw 'Unknown position "' + this.position + '"'375    }376    this.adapter.down('a.inline-adapter-close').observe('click', this.close_handler.bind(this));377    this.register_cancel_hooks();378    new Effect.Highlight(this.adapter.down('td'));379  },380  close_handler: function(event) {381    this.close();382    if (event) Event.stop(event);383  }...

Full Screen

Full Screen

default.js

Source:default.js Github

copy

Full Screen

1'use strict';2/**3 * @function `gulp scaffold`4 * @desc Scaffold new module or page, add references to module to `main.scss` and `main.js` unless specified otherwise.5 *6 * * Prompts for type and details of new element.7 * * Non-interactive mode: `gulp scaffold --interactive=false --type={Module|Page|Demo Module|Demo Page} --name="Hello World" --createScript={true|false} --createStyles={true|false}`8 */9var gulp = require('gulp');10var taskName = 'scaffold',11	taskConfig = {12		types: {13			module: {14				name: 'Module',15				src: './source/modules/.scaffold',16				dest: './source/modules/',17				hasAssets: true18			},19			page: {20				name: 'Page',21				src: './source/pages/.scaffold',22				dest: './source/pages/',23				allowUnderscores: true24			},25			demoModule: {26				name: 'Demo Module',27				src: './source/modules/.scaffold',28				dest: './source/demo/modules/',29				hasAssets: true30			},31			demoPage: {32				name: 'Demo Page',33				src: './source/pages/.scaffold',34				dest: './source/demo/pages/',35				allowUnderscores: true36			}37		},38		registerStyles: {39			src: './source/assets/css/main.scss',40			insertionPoint: '//*autoinsertmodule*',41			insertionPrefix: '@import "',42			insertionSuffix: '";\n'43		},44		registerScript: {45			src: './source/assets/js/helpers/estaticoapp.js',46			insertionPoint: '/* autoinsertmodule */',47			importInsertionPoint: '/* autoinsertmodulereference */',48			insertionTemplate: 'this.modules.{{keyName}} = {{className}};\n		',49			importInsertionTemplate: 'import {{className}} from \'{{modulePath}}\';\n'50		},51		// Generated dynamically52		scaffold: {53			name: null,54			className: null,55			originalName: null,56			keyName: null,57			previousName: 'scaffold',58			previousClassName: 'scaffold',59			previousOriginalName: 'Scaffold',60			previousKeyName: 'scaffold',61			deletePrevious: false,62			src: null,63			dest: null,64			createStyles: false,65			createScript: false,66			replaceContentExtensions: ['.js', '.scss', '.hbs', '.md'],67			replaceContent: function(content, config) {68				return content69					.replace(/\{\{name\}\}/g, config.name)70					.replace(/\{\{className\}\}/g, config.className)71					.replace(/\{\{keyName\}\}/g, config.keyName)72					.replace(/\{\{originalName\}\}/g, config.originalName);73			}74		}75	},76	getTaskScaffoldConfig = function(config, cb) {77		var helpers = require('require-dir')('../../helpers'),78			scaffoldConfig = {},79			hasAssets;80		// Get custom config and pass to task81		helpers.scaffold.getType(config.types, {82				prompt: 'What do you want to create?'83			})84			.then(function(response) {85				scaffoldConfig.src = response.src;86				scaffoldConfig.dest = response.dest;87				hasAssets = response.hasAssets;88				return helpers.scaffold.getName(response.name, response.dest, {89					allowUnderscores: response.allowUnderscores90				});91			})92			.then(function(response) {93				scaffoldConfig.originalName = response.original; // the input by the user. Ideally with spaces94				scaffoldConfig.name = response.sanitized; // snakeCase or lowercase95				scaffoldConfig.className = response.className; // pascalCase96				scaffoldConfig.keyName = response.keyName; // camelCase97				if (hasAssets) {98					return helpers.scaffold.getAssetsToCreate();99				}100			})101			.then(function(response) {102				if (response) {103					scaffoldConfig.createStyles = response.styles;104					scaffoldConfig.createScript = response.script;105				}106				cb(scaffoldConfig);107			})108			.catch(helpers.errors);109	},110	task = function(config, cb) {111		var tap = require('gulp-tap'),112			through = require('through2'),113			path = require('path'),114			rename = require('gulp-rename'),115			helpers = require('require-dir')('../../helpers'),116			livereload = require('gulp-livereload'),117			deleteTask = require('./delete'),118			_ = require('lodash'),119			merge = require('merge-stream');120		var src = path.join(config.scaffold.src, '/**'),121			dest = path.join(config.scaffold.dest, config.scaffold.name),122			stylesFound,123			scriptFound;124		gulp.src(src)125			// Replace {{name|className|keyName|originalName}}126			.pipe(tap(function(file) {127				if (!file.stat.isDirectory() && config.scaffold.replaceContentExtensions.indexOf(path.extname(file.path)) !== -1) {128					var content = file.contents.toString();129					content = config.scaffold.replaceContent(content, config.scaffold);130					file.contents = Buffer.from(content);131				}132			}))133			// Skip creation of SCSS file if specified134			.pipe(through.obj(function(file, enc, done) {135				var match = (path.extname(file.path) === '.scss');136				if (match) {137					stylesFound = true;138					if (config.scaffold.createStyles) {139						this.push(file);140					}141				} else {142					this.push(file);143				}144				done();145			}))146			// Skip creation of JS file if specified147			.pipe(through.obj(function(file, enc, done) {148				var match = (path.extname(file.path) === '.js' && !path.basename(file.path).match(/.data.js$/));149				if (match) {150					scriptFound = true;151					if (config.scaffold.createScript) {152						this.push(file);153					}154				} else {155					this.push(file);156				}157				done();158			}))159			// Rename files as specified in scaffolding config160			.pipe(rename(function(filePath) {161				filePath.basename = filePath.basename.replace(config.scaffold.previousName, config.scaffold.name);162			}))163			.pipe(gulp.dest(dest))164			.on('end', function() {165				var dest = path.join(config.scaffold.dest, config.scaffold.name),166					destAssets = path.join(dest, config.scaffold.name),167					tasks = [],168					callback = function(fn) {169						if (tasks.length > 0) {170							merge(tasks).on('finish', fn);171						} else {172							fn();173						}174					},175					registerStyles,176					registerScript,177					deleteConfig;178				// Add @import to main.scss179				if (config.scaffold.createStyles && stylesFound) {180					registerStyles = gulp.src(config.registerStyles.src)181						.pipe(tap(function(file) {182							file.contents = helpers.scaffold.addModule(file, destAssets, config.registerStyles);183						}))184						.pipe(gulp.dest(path.dirname(config.registerStyles.src)))185						.pipe(livereload());186					tasks.push(registerStyles);187				}188				// Add @requires to main.js189				if (config.scaffold.createScript && scriptFound) {190					registerScript = gulp.src(config.registerScript.src)191						.pipe(tap(function(file) {192							file.contents = helpers.scaffold.addModule(file, destAssets, _.extend({}, config.registerScript, config.scaffold));193						}))194						.pipe(gulp.dest(path.dirname(config.registerScript.src)))195						.pipe(livereload());196					tasks.push(registerScript);197				}198				// Delete original files if specified199				if (config.scaffold.deletePrevious) {200					deleteConfig = _.merge({}, config, {201						scaffold: {202							name: config.scaffold.previousName,203							className: config.scaffold.previousClassName,204							keyName: config.scaffold.previousKeyName,205							originalName: config.scaffold.previousOriginalName,206							deregisterStyles: config.scaffold.createStyles,207							deregisterScript: config.scaffold.createScript208						}209					});210					callback(function() {211						deleteTask.task(deleteConfig, cb);212					});213				} else {214					callback(cb);215				}216			});217	};218gulp.task(taskName, function(cb) {219	var _ = require('lodash');220	getTaskScaffoldConfig(taskConfig, function(scaffoldConfig) {221		var config = _.merge(taskConfig, {222				scaffold: scaffoldConfig223			});224		task(config, cb);225	});226});227module.exports = {228	taskName: taskName,229	taskConfig: taskConfig,230	task: task,231	getTaskScaffoldConfig: getTaskScaffoldConfig...

Full Screen

Full Screen

scaffold.js

Source:scaffold.js Github

copy

Full Screen

...75    whitespaceVal = global.conf.get('lastInit.whitespace');76  }77  global.conf.set('lastInit.whitespace', whitespaceVal);78  if (isCustomScaffold) {79    return scaffoldLib.scaffold(80      url,81      process.cwd(),82      Object.assign(scaffoldOptions, {83        whitespace: whitespaceVal,84      })85    );86  }87  return initLib.scaffold(88    process.cwd(),89    Object.assign(scaffoldOptions, {90      whitespace: whitespaceVal,91    })92  );93};94const shouldAskWhitespace = whitespace => ({ doScaffold }) => {95  if (doScaffold === 'x') {96    ora().warn('Aborting…');97    return process.exit();98  } else if (doScaffold && !whitespace) {99    return whitespaceConfirm();100  }101  return { whitespace, doScaffold };...

Full Screen

Full Screen

test.spec.js

Source:test.spec.js Github

copy

Full Screen

1'use strict';2require('dotenv').config();3const expect = require('unexpected').clone();4const parallel = require('mocha.parallel');5const path = require('upath');6// eslint-disable-next-line import/no-extraneous-dependencies7const scaffold = require('@pingy/scaffold');8// TODO: test offline9parallel('identifyUrlType', function identifyUrlType() {10  this.timeout(10000);11  it('should work with GitHub URL (1)', () => {12    const url = 'git://github.com/pingyhq/pingy-scaffold-bootstrap.git';13    return expect(scaffold.identifyUrlType(url), 'to be fulfilled with', {14      type: 'npm',15      url,16    });17  });18  it('should work with Shorthand GitHub URL (2)', () => {19    const url = 'pingyhq/pingy-scaffold-bootstrap';20    return expect(scaffold.identifyUrlType(url), 'to be fulfilled with', {21      type: 'npm',22      url,23    });24  });25  it('should work with alias', () => {26    const alias = 'bootstrap';27    const url = 'pingy-scaffold-bootstrap';28    return expect(scaffold.identifyUrlType(alias), 'to be fulfilled with', {29      type: 'npm',30      url,31    });32  });33  it('should work with path', () => {34    const pth = path.join(__dirname, 'fixtures', 'a');35    return expect(scaffold.identifyUrlType(pth), 'to be fulfilled with', {36      type: 'fs',37      url: pth,38    });39  });40});41parallel('scaffoldFs', () => {42  it('should return path and json on success', () => {43    const pth = path.join(__dirname, 'fixtures', 'a');44    return expect(scaffold.fs(pth), 'to be fulfilled with', {45      scaffoldPath: pth,46      json: expect.it('to have keys', ['name', 'description']),47    });48  });49  it('should error when no pingy-scaffold.json', () => {50    const pth = path.join(__dirname);51    return expect(52      scaffold.fs(pth),53      'to be rejected with error satisfying',54      /doesn't contain a pingy-scaffold.json/55    );56  });57  it('should error with invalid path', () => {58    const pth = path.join(__dirname, 'fixtures', 'b');59    return expect(60      scaffold.fs(pth),61      'to be rejected with error satisfying',62      /should contain a name and a description/63    );64  });65  it('should error with invalid path', () => {66    const pth = path.join(__dirname, 'foo');67    return expect(68      scaffold.fs(pth),69      'to be rejected with error satisfying',70      /does not exist/71    );72  });73});74parallel('scaffoldNpm', function scaffoldGit() {75  this.timeout(10000);76  it('should error with 404 url', () => {77    const url = 'https://github.com/foo/does-not-exist.git';78    return expect(scaffold.npm(url), 'to be rejected');79  });80  it('should error when no package.json', () => {81    const url = 'https://github.com/rmccue/test-repository.git';82    return expect(scaffold.npm(url), 'to be rejected');83  });84  it('should error when no pingy-scaffold.json', () => {85    const url = 'sindresorhus/delay';86    return expect(87      scaffold.npm(url),88      'to be rejected with error satisfying',89      /doesn't contain a pingy-scaffold.json/90    );91  });92  it('should work with valid scaffold repo', () => {93    const url =94      'git://github.com/pingyhq/pingy-scaffold-bootstrap-jumbotron.git';95    return expect(scaffold.npm(url), 'to be fulfilled with', {96      scaffoldPath: expect.it('to contain', scaffold.cacheDir),97      json: expect.it('to have keys', ['name', 'description']),98    });99  });...

Full Screen

Full Screen

index.js

Source:index.js Github

copy

Full Screen

1'use strict';2module.exports = require('./lib');3module.exports.Node = require('./lib/node');4module.exports.Service = require('./lib/service');5module.exports.errors = require('./lib/errors');6module.exports.services = {};7module.exports.services.Bitcoin = require('./lib/services/bitcoind');8module.exports.services.Web = require('./lib/services/web');9module.exports.scaffold = {};10module.exports.scaffold.create = require('./lib/scaffold/create');11module.exports.scaffold.add = require('./lib/scaffold/add');12module.exports.scaffold.remove = require('./lib/scaffold/remove');13module.exports.scaffold.start = require('./lib/scaffold/start');14module.exports.scaffold.callMethod = require('./lib/scaffold/call-method');15module.exports.scaffold.findConfig = require('./lib/scaffold/find-config');16module.exports.scaffold.defaultConfig = require('./lib/scaffold/default-config');17module.exports.cli = {};18module.exports.cli.main = require('./lib/cli/main');19module.exports.cli.daemon = require('./lib/cli/daemon');20module.exports.cli.bitcore = require('./lib/cli/bitcore');21module.exports.cli.bitcored = require('./lib/cli/bitcored');...

Full Screen

Full Screen

dir_3750276df25f0523a9ae755064c7ad8f.js

Source:dir_3750276df25f0523a9ae755064c7ad8f.js Github

copy

Full Screen

1var dir_3750276df25f0523a9ae755064c7ad8f =2[3    [ "Source", "dir_63c73cc6a7c58dbf9f968edf57888046.html", "dir_63c73cc6a7c58dbf9f968edf57888046" ],4    [ "Scaffold.h", "_scaffold_8h.html", [5      [ "Scaffold", "class_scaffold.html", "class_scaffold" ]6    ] ],7    [ "ScaffoldCollision.h", "_scaffold_collision_8h.html", [8      [ "ScaffoldCollision", "class_scaffold_collision.html", "class_scaffold_collision" ]9    ] ],10    [ "ScaffoldDraw.h", "_scaffold_draw_8h.html", [11      [ "ScaffoldDraw", "class_scaffold_draw.html", "class_scaffold_draw" ]12    ] ],13    [ "ScaffoldFactory.h", "_scaffold_factory_8h.html", [14      [ "ScaffoldFactory", "class_scaffold_factory.html", "class_scaffold_factory" ]15    ] ]...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', function() {2  it('Does not do much!', function() {3    cy.contains('type').click()4    cy.url().should('include', '/commands/actions')5    cy.get('.action-email')6      .type('

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', () => {2  it('Does not do much!', () => {3    expect(true).to.equal(true)4  })5})6describe('My First Test', () => {7  it('Does not do much!', () => {8    expect(true).to.equal(true)9  })10})11describe('My First Test', () => {12  it('Does not do much!', () => {13    expect(true).to.equal(true)14  })15})16describe('My First Test', () => {17  it('Does not do much!', () => {18    expect(true).to.equal(true)19  })20})21describe('My First Test', () => {22  it('Does not do much!', () => {23    expect(true).to.equal(true)24  })25})26describe('My First Test', () => {27  it('Does not do much!', () => {28    expect(true).to.equal(true)29  })30})31describe('My First Test', () => {32  it('Does not do much!', () => {33    expect(true).to.equal(true)34  })35})36describe('My First Test', () => {37  it('Does not do much!', () => {38    expect(true).to.equal(true)39  })40})41describe('My First Test', () => {42  it('Does not do much!', () => {43    expect(true).to.equal(true)44  })45})46describe('My First Test', () => {47  it('Does not do much!', () => {48    expect(true).to.equal(true)49  })50})51describe('My First Test', () => {52  it('Does not do much!', () => {53    expect(true).to.equal(true)54  })55})56describe('My First Test', () => {57  it('Does not do much!', () => {58    expect(true).to.equal(true)59  })60})61describe('My First Test', () => {62  it('Does not do much!', () =>

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', () => {2  it('Does not do much!', () => {3    expect(true).to.equal(true)4  })5})6{7}8{9  "scripts": {10  },11  "devDependencies": {12  }13}14describe('My First Test', () => {15  it('Does not do much!', () => {16    expect(true).to.equal(true)17  })18})

Full Screen

Using AI Code Generation

copy

Full Screen

1describe('My First Test', function() {2  it('Does not do much!', function() {3    cy.scaffold('test');4  })5})6Cypress.Commands.add('scaffold', (name) => {7})8describe('My First Test', function() {9  it('Does not do much!', function() {10    cy.scaffold('test');11  })12})13Cypress.Commands.add('scaffold', (name) => {14})15describe('My First Test', function() {16  it('Does not do much!', function() {17    cy.scaffold('test');18  })19})20Cypress.Commands.add('scaffold', (name) => {21})22describe('My First Test', function() {23  it('Does not do much!', function() {24    cy.scaffold('test');25  })26})27Cypress.Commands.add('scaffold', (name) => {28})29describe('My First Test', function() {30  it('Does not do much!', function() {31    cy.scaffold('test');32  })33})34Cypress.Commands.add('scaffold', (name) => {35})

Full Screen

Using AI Code Generation

copy

Full Screen

1it('should create a new user', () => {2  cy.scaffold('user', { name: 'John Doe' }).then(user => {3    expect(user).to.have.property('id')4  })5})6Cypress.Commands.add('scaffold', (model, attributes = {}) => {7})8import './commands'9describe('Cypress scaffold', () => {10  it('creates a user', () => {11    cy.scaffold('user', { name: 'John Doe' }).then(user => {12      expect(user).to.have.property('id')13    })14  })15})16describe('Cypress scaffold', () => {17  it('creates a user', () => {18    cy.scaffold('user', { name: 'John Doe' }).then(user => {19      expect(user).to.have.property('id')20    })21  })22})23describe('Cypress scaffold', () => {24  it('creates a user', () => {25    cy.scaffold('user', { name: 'John Doe' }).then(user => {26      expect(user).to.have.property('id')27    })28  })29})30describe('Cypress scaffold', () => {31  it('creates a user', () => {32    cy.scaffold('user', { name: 'John Doe' }).then(user => {33      expect(user).to.have.property('id')34    })35  })36})37describe('Cypress scaffold', () => {38  it('creates a user', () => {39    cy.scaffold('user', { name: 'John Doe' }).then(user => {40      expect(user).to.have.property('id')41    })42  })43})44describe('Cypress scaffold', () => {45  it('creates a user', () => {46    cy.scaffold('user', { name: 'John Doe' }).then(user => {47      expect(user).to.have.property('id')48    })49  })50})

Full Screen

Cypress Tutorial

Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.

Chapters:

  1. What is Cypress? -
  2. Why Cypress? - Learn why Cypress might be a good choice for testing your web applications.
  3. Features of Cypress Testing - Learn about features that make Cypress a powerful and flexible tool for testing web applications.
  4. Cypress Drawbacks - Although Cypress has many strengths, it has a few limitations that you should be aware of.
  5. Cypress Architecture - Learn more about Cypress architecture and how it is designed to be run directly in the browser, i.e., it does not have any additional servers.
  6. Browsers Supported by Cypress - Cypress is built on top of the Electron browser, supporting all modern web browsers. Learn browsers that support Cypress.
  7. Selenium vs Cypress: A Detailed Comparison - Compare and explore some key differences in terms of their design and features.
  8. Cypress Learning: Best Practices - Take a deep dive into some of the best practices you should use to avoid anti-patterns in your automation tests.
  9. How To Run Cypress Tests on LambdaTest? - Set up a LambdaTest account, and now you are all set to learn how to run Cypress tests.

Certification

You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.

YouTube

Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.

Run Cypress automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful