123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742 |
- ( function( $ ) {
- /**
- * Handles logic for the theme layout admin edit interface.
- *
- * @class FLThemeBuilderLayoutAdminEdit
- * @since 1.0
- */
- FLThemeBuilderLayoutAdminEdit = {
- /**
- * Cache for location object data that is retrieved via AJAX.
- *
- * @since 1.0
- * @access private
- * @property {Object} _locationObjectCache
- */
- _locationObjectCache : {},
- /**
- * Store a copy of select2 here in case another plugin loads an
- * older version of it breaking ours.
- *
- * @since 1.1.3
- * @access private
- * @property {Function} _select2
- */
- _select2 : $.fn.select2,
- /**
- * Initializes the theme layout admin edit interface.
- *
- * @since 1.0
- * @access private
- * @method _init
- */
- _init: function()
- {
- this._bind();
- this._initNonce();
- this._initLayoutSettings();
- this._initLocationRules();
- this._initUserRules();
- this._initSelect2();
- },
- /**
- * Binds events for the theme layout admin edit interface.
- *
- * @since 1.0
- * @access private
- * @method _bind
- */
- _bind: function()
- {
- // General events
- $( '.fl-launch-builder, .fl-view-template' ).on( 'click', this._launchBuilderClicked );
- $( '.fl-mb-row-heading-help' ).tipTip();
- // Header events
- $( 'select[name="fl-theme-layout-settings[sticky]"]' ).on( 'change', this._stickyChanged );
- $( 'select[name="fl-theme-layout-settings[overlay]"]' ).on( 'change', this._overlayChanged );
- // Location events
- $( '.fl-theme-builder-saved-locations' ).delegate( '.fl-theme-builder-location', 'change', this._locationSelectChanged );
- $( '.fl-theme-builder-saved-locations' ).delegate( '.fl-theme-builder-remove-location', 'click', this._removeLocationClicked );
- $( '.fl-theme-builder-add-location.button' ).on( 'click', this._addLocationClicked );
- $( '.fl-theme-builder-add-exclusion.button' ).on( 'click', this._addExclusionClicked );
- // User events
- $( '.fl-theme-builder-saved-user-rules' ).delegate( '.fl-theme-builder-user-rule', 'change', this._userRuleSelectChanged );
- $( '.fl-theme-builder-add-user-rule.button' ).on( 'click', this._addUserRuleClicked );
- $( '.fl-theme-builder-saved-user-rules' ).delegate( '.fl-theme-builder-remove-user-rule', 'click', this._removeUserRuleClicked );
- },
- /**
- * Initializes the theme builder nonce.
- *
- * @since 1.0
- * @access private
- * @method _initNonce
- */
- _initNonce: function()
- {
- $( '#post' ).append( '<input type="hidden" name="fl-theme-builder-nonce" value="' + FLThemeBuilderConfig.nonce + '" />' );
- },
- /**
- * Init the layout settings based on type.
- *
- * @since 1.0
- * @access private
- * @method _initLayoutSettings
- */
- _initLayoutSettings: function()
- {
- var type = $( 'input[name=fl-theme-layout-type]' ).val(),
- sticky = $( '.fl-theme-layout-header-sticky' ),
- stickyOn = $( '.fl-theme-layout-header-sticky-on' ),
- shrink = $( '.fl-theme-layout-header-shrink' ),
- overlay = $( '.fl-theme-layout-header-overlay' ),
- overlayBg = $( '.fl-theme-layout-header-overlay-bg' ),
- hookRow = $( '.fl-theme-layout-hook-row' ),
- hook = $( 'select[name=fl-theme-layout-hook]' ),
- orderRow = $( '.fl-theme-layout-order-row' ),
- order = $( 'input[name=fl-theme-layout-order]' );
- if ( 'header' == type ) {
- sticky.show().find( 'select' ).trigger( 'change' );
- overlay.show().find( 'select' ).trigger( 'change' );
- } else {
- sticky.hide();
- stickyOn.hide();
- shrink.hide();
- overlay.hide();
- overlayBg.hide();
- }
- if ( 'part' == type ) {
- hookRow.show();
- orderRow.show();
- } else {
- hookRow.hide();
- hook.val( '' );
- orderRow.hide();
- order.val( '0' );
- }
- },
- /**
- * Initializes all location rule forms.
- *
- * @since 1.0
- * @access private
- * @method _initLocationRules
- */
- _initLocationRules: function()
- {
- var exclusions = $( '.fl-theme-builder-exclusion-rules' ),
- button = $( '.fl-theme-builder-add-exclusion' );
- $( '.fl-theme-builder-location-rules' ).each( this._initLocations );
- if ( FLThemeBuilderConfig.exclusions.saved.length > 0 ) {
- exclusions.show();
- button.hide();
- }
- },
- /**
- * Initializes rules for a location form.
- *
- * @since 1.0
- * @access private
- * @method _initLocations
- */
- _initLocations: function()
- {
- var wrap = $( this ),
- savedWrap = wrap.find( '.fl-theme-builder-saved-locations' ),
- template = wp.template( 'fl-theme-builder-saved-location' ),
- type = null,
- config = null,
- parts = null,
- locationWrap = null,
- locationSelect = null,
- location = null,
- locationType = null,
- objectSelect = null,
- data = null,
- id = null,
- i = 0;
- if ( wrap.hasClass( 'fl-theme-builder-exclusion-rules' ) ) {
- type = 'exclusion';
- config = FLThemeBuilderConfig.exclusions;
- }
- else {
- type = 'location';
- config = FLThemeBuilderConfig.locations;
- }
- if ( 0 === config.saved.length ) {
- savedWrap.append( template( { type : type } ) );
- if ( 'exclusion' == type ) {
- savedWrap.find( '.fl-theme-builder-remove-rule-button' ).show();
- }
- } else {
- for ( ; i < config.saved.length; i++ ) {
- savedWrap.append( template( { type : type } ) );
- parts = config.saved[ i ].split( ':' );
- locationWrap = wrap.find( '.fl-theme-builder-saved-location' ).last();
- locationSelect = locationWrap.find( '.fl-theme-builder-location' );
- objectSelect = locationWrap.find( '.fl-theme-builder-location-objects' );
- if ( 'post' == parts[0] || 'taxonomy' == parts[0] || 'tax_parent' == parts[0] ) {
- if ( parts.length <= 3 ) {
- location = parts[0] + ':' + parts[1];
- data = config[ parts[0] ][ parts[1] ];
- id = 3 === parts.length ? parts[2] : undefined;
- } else {
- location = parts[0] + ':' + parts[1] + ':' + parts[2] + ':' + parts[3];
- locationType = 'post' === parts[0] && 'ancestor' === parts[2] ? 'post' : parts[2];
- locationType = 'tax_parent' === parts[2] ? 'taxonomy' : locationType;
- data = config[ locationType ][ parts[3] ];
- id = 5 === parts.length ? parts[4] : undefined;
- }
- }
- else {
- location = parts[0] + ':' + parts[1];
- }
- locationWrap.find( '[data-location="' + location + '"]' ).prop( 'selected', true );
- if ( 'post' == parts[0] || 'taxonomy' == parts[0] || 'tax_parent' == parts[0] ) {
- FLThemeBuilderLayoutAdminEdit._showLocationObjectSelect( objectSelect.parent(), data, id );
- }
- }
- savedWrap.find( '.fl-theme-builder-remove-rule-button' ).show();
- }
- FLThemeBuilderLayoutAdminEdit._removeLocationOptions();
- FLThemeBuilderLayoutAdminEdit._removeLocationObjectOptions();
- },
- /**
- * Removes locations that aren't used for singular
- * or archive layouts.
- *
- * @since 1.0
- * @access private
- * @method _removeLocationOptions
- */
- _removeLocationOptions: function()
- {
- var type = $( 'input[name=fl-theme-layout-type]' ).val(),
- options = $( '.fl-theme-builder-location option' );
- if ( 'archive' == type ) {
- options.filter( '[data-location="general:site"]' ).remove();
- options.filter( '[data-location="general:single"]' ).remove();
- options.filter( '[data-location="general:404"]' ).remove();
- options.filter( '[data-type="post"]' ).remove();
- } else if ( 'singular' == type ) {
- options.filter( '[data-location="general:site"]' ).remove();
- options.filter( '[data-location="general:archive"]' ).remove();
- options.filter( '[data-location="general:author"]' ).remove();
- options.filter( '[data-location="general:date"]' ).remove();
- options.filter( '[data-location="general:search"]' ).remove();
- options.filter( '[data-location="general:404"]' ).remove();
- options.filter( '[data-type="archive"]' ).remove();
- options.filter( '[data-type="taxonomy"]' ).remove();
- } else if ( '404' == type ) {
- options.not( '[data-location="general:404"]' ).remove();
- $( '.fl-theme-builder-locations-form' ).hide();
- }
- if ( '404' != type ) {
- $( '.fl-theme-builder-locations-form' ).show();
- }
- $( '.fl-theme-builder-exclusion-rules option[data-location="general:site"]' ).remove();
- $( '.fl-theme-builder-location optgroup' ).filter( function() {
- return '' === $.trim( $( this ).text() );
- } ).remove();
- },
- /**
- * Removes location object options that don't make
- * sense in certain situations.
- *
- * @since 1.0
- * @access private
- * @method _removeLocationObjectOptions
- */
- _removeLocationObjectOptions: function()
- {
- $( '.fl-theme-builder-location-objects' ).each( function() {
- var select = $( this ),
- option = null,
- location = select.attr( 'data-location' );
- if ( /post:[a-zA-Z0-9_-]+:(post|ancestor|tax_parent):[a-zA-Z0-9_-]+$/.test( location ) ) {
- option = select.find( 'option' ).eq( 0 );
- if ( '' === option.attr( 'value' ) ) {
- option.remove();
- }
- }
- } );
- },
- /**
- * Shows or hides an additional select if necessary when
- * the location select is changed.
- *
- * @since 1.0
- * @access private
- * @method _locationSelectChanged
- */
- _locationSelectChanged: function()
- {
- var self = FLThemeBuilderLayoutAdminEdit,
- select = $( this ),
- wrap = select.closest( '.fl-theme-builder-location-rules' ),
- parent = select.parent(),
- locations = wrap.find( '.fl-theme-builder-saved-location' ),
- location = select.val(),
- locationString = '',
- remove = wrap.find( '.fl-theme-builder-saved-locations .fl-theme-builder-remove-rule-button' ),
- actionType = 'terms';
- if ( '' == location ) {
- parent.removeClass( 'fl-theme-builder-rule-objects-visible' );
- if ( 1 === locations.length ) {
- remove.hide();
- }
- } else {
- location = JSON.parse( location );
- locationString = location.type + ':' + location.id;
- if ( 'taxonomy' == location.type || 'post' == location.type ) {
- if ( typeof self._locationObjectCache[ locationString ] != 'undefined' ) {
- self._showLocationObjectSelect( parent, self._locationObjectCache[ locationString ] );
- } else {
- self._showRowLoading( select );
- if ( 'post' == location.type ) {
- if ( location.id.indexOf( ':taxonomy' ) > -1 ) {
- actionType = 'terms';
- location.id = location.id.split( ':taxonomy:' )[1];
- }
- else {
- actionType = 'posts';
- }
- if ( location.id.indexOf( ':tax_parent' ) > -1 ) {
- actionType = 'parent_terms';
- location.id = location.id.split( ':tax_parent:' )[1];
- }
- }
- $.post( ajaxurl, {
- action : 'fl_theme_builder_get_location_' + actionType,
- id : location.id,
- nonce : FLThemeBuilderConfig.nonce
- }, function( response ) {
- FLThemeBuilderLayoutAdminEdit._showLocationObjectSelect( parent, JSON.parse( response ) );
- } );
- }
- } else {
- parent.removeClass( 'fl-theme-builder-rule-objects-visible' );
- }
- remove.show();
- }
- },
- /**
- * Shows the location object select and populates
- * it with the provided data.
- *
- * @since 1.0
- * @access private
- * @method _showLocationObjectSelect
- * @param {Object} parent
- * @param {Object} data
- * @param {Number} id
- */
- _showLocationObjectSelect: function( parent, data, id )
- {
- var locationSelect = parent.find( '.fl-theme-builder-location' ),
- location = JSON.parse( locationSelect.val() ),
- locationString = location.type + ':' + location.id,
- objectSelect = parent.find( '.fl-theme-builder-location-objects' ),
- objectLocation = null,
- parent = objectSelect.parent(),
- allLabel = FLThemeBuilderConfig.strings.allObjects.replace( '%s', data.label ),
- options = '<option value="" data-location="' + locationString + '">' + allLabel + '</option>',
- selected = null,
- termLabel = '',
- i = 0;
- if ( null != data.objects ) {
- for ( ; i < data.objects.length; i++ ) {
- termLabel = data.objects[i].label ? data.objects[i].label : data.objects[i].name;
- objectLocation = ' data-location="' + locationString + ':' + data.objects[ i ].id + '"';
- selected = 'undefined' != typeof id && id == data.objects[ i ].id ? ' selected' : '';
- options += '<option value=\'' + JSON.stringify( data.objects[ i ] ).replace(/"/g, '\\"') + '\'' + selected + objectLocation + '>' + termLabel + '</option>';
- }
- }
- objectSelect.html( options );
- objectSelect.attr( 'data-location', locationString );
- objectSelect.attr( 'data-type', data.type );
- parent.addClass( 'fl-theme-builder-rule-objects-visible' );
- this._locationObjectCache[ locationString ] = data;
- FLThemeBuilderLayoutAdminEdit._hideRowLoading( locationSelect );
- if ( 'disabled' == objectSelect.find( 'option' ).eq( 0 ).attr( 'disabled' ) ) {
- objectSelect.find( 'option' ).eq( 1 ).prop( 'selected', true );
- }
- FLThemeBuilderLayoutAdminEdit._removeLocationObjectOptions();
- },
- /**
- * Adds a location select when the Add button is clicked.
- *
- * @since 1.0
- * @access private
- * @method _addLocationClicked
- * @param {Object} e
- */
- _addLocationClicked: function( e )
- {
- var self = FLThemeBuilderLayoutAdminEdit,
- wrap = $( this ).closest( '.fl-theme-builder-location-rules' ),
- savedWrap = wrap.find( '.fl-theme-builder-saved-locations' ),
- template = wp.template( 'fl-theme-builder-saved-location' ),
- type = wrap.hasClass( 'fl-theme-builder-exclusion-rules' ) ? 'exclusion' : 'location';
- savedWrap.append( template( { type : type } ) );
- savedWrap.find( '.fl-theme-builder-remove-rule-button' ).show();
- self._removeLocationOptions();
- self._initSelect2();
- },
- /**
- * Removes a location from the saved locations list.
- *
- * @since 1.0
- * @access private
- * @method _removeLocationClicked
- * @param {Object} e
- */
- _removeLocationClicked: function( e )
- {
- var button = $( e.target ),
- wrap = button.closest( '.fl-theme-builder-location-rules' ),
- parent = button.parents( '.fl-theme-builder-saved-location' ),
- select = parent.find( '.fl-theme-builder-location' ),
- locations = wrap.find( '.fl-theme-builder-saved-location' ),
- remove = wrap.find( '.fl-theme-builder-saved-locations .fl-theme-builder-remove-rule-button' ),
- isExclusion = button.closest( '.fl-theme-builder-exclusion-rules' ).length ? true : false;
- if ( locations.length > 1 ) {
- button.closest( '.fl-theme-builder-saved-location' ).remove();
- }
- if ( 1 === locations.length ) {
- select.val( '' ).parent().removeClass( 'fl-theme-builder-rule-objects-visible' );
- select.next( '.select2' ).find( '.select2-selection__rendered' ).html( FLThemeBuilderConfig.strings.choose );
- if ( ! isExclusion ) {
- remove.hide();
- }
- if ( isExclusion ) {
- $( '.fl-theme-builder-exclusion-rules' ).hide();
- $( '.fl-theme-builder-add-exclusion' ).show();
- }
- } else if ( ! isExclusion && 2 === locations.length && '' == wrap.find( '.fl-theme-builder-location' ).eq( 0 ).val() ) {
- remove.hide();
- }
- },
- /**
- * Shows the exclusion rule settings if they are hidden.
- *
- * @since 1.0
- * @access private
- * @method _addExclusionClicked
- * @param {Object} e
- */
- _addExclusionClicked: function( e )
- {
- var button = $( '.fl-theme-builder-add-exclusion' ),
- exclusions = $( '.fl-theme-builder-exclusion-rules' );
- button.hide();
- exclusions.show();
- FLThemeBuilderLayoutAdminEdit._initSelect2();
- },
- /**
- * Initializes user rules.
- *
- * @since 1.0
- * @access private
- * @method _initUserRules
- */
- _initUserRules: function()
- {
- var saved = FLThemeBuilderConfig.userRules,
- savedWrap = $( '.fl-theme-builder-saved-user-rules' ),
- template = wp.template( 'fl-theme-builder-saved-user-rule' ),
- ruleWrap = null,
- ruleSelect = null,
- selected = null,
- i = 0;
- if ( 0 === saved.length ) {
- savedWrap.append( template() );
- savedWrap.find( '[data-rule="general:all"]' ).prop( 'selected', true );
- return;
- }
- for ( ; i < saved.length; i++ ) {
- savedWrap.append( template() );
- parts = saved[ i ].split( ':' );
- ruleWrap = $( '.fl-theme-builder-saved-user-rule' ).last();
- ruleSelect = ruleWrap.find( '.fl-theme-builder-user-rule' );
- selected = ruleWrap.find( '[data-rule="' + parts[0] + ':' + parts[1] + '"]' );
- selected.prop( 'selected', true );
- }
- savedWrap.find( '.fl-theme-builder-remove-rule-button' ).show();
- },
- /**
- * Fires when a user rule select changes.
- *
- * @since 1.0
- * @access private
- * @method _userRuleSelectChanged
- * @param {Object} e
- */
- _userRuleSelectChanged: function( e )
- {
- var rule = $( e.target ).val(),
- rules = $( '.fl-theme-builder-saved-user-rule' ),
- remove = $( '.fl-theme-builder-saved-user-rules .fl-theme-builder-remove-rule-button' );
- if ( '' == rule ) {
- if ( 1 === rules.length ) {
- remove.hide();
- }
- } else {
- remove.show();
- }
- },
- /**
- * Adds a user rule when the Add button is clicked.
- *
- * @since 1.0
- * @access private
- * @method _addUserRuleClicked
- * @param {Object} e
- */
- _addUserRuleClicked: function( e )
- {
- var savedWrap = $( '.fl-theme-builder-saved-user-rules' ),
- template = wp.template( 'fl-theme-builder-saved-user-rule' );
- savedWrap.append( template() );
- savedWrap.find( '.fl-theme-builder-remove-rule-button' ).show();
- FLThemeBuilderLayoutAdminEdit._initSelect2();
- },
- /**
- * Removes a user rule from the saved user rules list.
- *
- * @since 1.0
- * @access private
- * @method _removeUserRuleClicked
- * @param {Object} e
- */
- _removeUserRuleClicked: function( e )
- {
- var button = $( e.target ),
- parent = button.parents( '.fl-theme-builder-saved-user-rule' ),
- select = parent.find( '.fl-theme-builder-user-rule' ),
- rules = $( '.fl-theme-builder-saved-user-rule' ),
- remove = $( '.fl-theme-builder-saved-user-rules .fl-theme-builder-remove-rule-button' );
- if ( rules.length > 1 ) {
- button.closest( '.fl-theme-builder-saved-user-rule' ).remove();
- }
- if ( 1 === rules.length ) {
- select.val( '' );
- select.next( '.select2' ).find( '.select2-selection__rendered' ).html( FLThemeBuilderConfig.strings.choose );
- remove.hide();
- } else if ( 2 === rules.length && '' == $( '.fl-theme-builder-user-rule' ).val() ) {
- remove.hide();
- }
- },
- /**
- * Initializes select2 select objects.
- *
- * @since 1.0.4
- * @access private
- * @method _initSelect2
- */
- _initSelect2: function()
- {
- var selects = $( '.fl-theme-builder-saved-rules select:not(.select2-init)' ),
- select2 = this._select2;
- selects.each( function() {
- var select = $( this ),
- config = {
- width: 'style'
- };
- select2.call( select, config );
- select.addClass( 'select2-init' );
- select.on( 'select2:open', function() {
- $( '.select2-search__field' ).attr( 'placeholder', FLThemeBuilderConfig.strings.search );
- } );
- } );
- },
- /**
- * Callback for when the button to launch the
- * builder is clicked.
- *
- * @since 1.0
- * @access private
- * @method _launchBuilderClicked
- */
- _launchBuilderClicked: function( e )
- {
- var form = $( 'form[name=post]' ),
- url = $( this ).attr( 'href' );
- form.append( '<input type="hidden" name="redirect" value="' + url + '" />' );
- form.submit();
- e.preventDefault();
- },
- /**
- * Callback for then the header sticky select is changed.
- *
- * @since 1.0
- * @access private
- * @method _stickyChanged
- */
- _stickyChanged: function()
- {
- $( '.fl-theme-layout-header-sticky-on' ).toggle( '1' == $(this).val());
- $( '.fl-theme-layout-header-shrink' ).toggle( '1' == $( this ).val() );
- },
- /**
- * Callback for then the header overlay select is changed.
- *
- * @since 1.0.2
- * @access private
- * @method _overlayChanged
- */
- _overlayChanged: function()
- {
- $( '.fl-theme-layout-header-overlay-bg' ).toggle( '1' == $( this ).val() );
- },
- /**
- * Shows the loading icon in the meta box header.
- *
- * @since 1.0
- * @access private
- * @method _showLoading
- */
- _showLoading: function()
- {
- var header = $( '#fl-theme-builder-settings h2.hndle span' );
- if ( ! header.find( '.spinner' ).length ) {
- header.append( '<span class="spinner"></span>' );
- }
- },
- /**
- * Hides the loading icon in the meta box header.
- *
- * @since 1.0
- * @access private
- * @method _hideLoading
- */
- _hideLoading: function()
- {
- $( '#fl-theme-builder-settings h2.hndle .spinner' ).remove();
- },
- /**
- * Shows the loading overlay for a meta box row.
- *
- * @since 1.0
- * @access private
- * @method _showRowLoading
- * @param {Object} ele
- */
- _showRowLoading: function( ele )
- {
- ele.closest( '.fl-mb-row-content' ).prepend( '<div class="fl-mb-loading"></div>' );
- },
- /**
- * Hides the loading overlay for a meta box row.
- *
- * @since 1.0
- * @access private
- * @method _hideRowLoading
- * @param {Object} ele
- */
- _hideRowLoading: function( ele )
- {
- ele.closest( '.fl-mb-row-content' ).find( '.fl-mb-loading' ).remove();
- }
- };
- // Initialize
- $( function() { FLThemeBuilderLayoutAdminEdit._init(); } );
- } )( jQuery );
|