✏️ 正在编辑: awb-typography.js
路径:
/home/lssfapb/www/wp-content/themes/Avada/includes/lib/inc/fusion-app/assets/js/awb-typography.js
提示:
您可以编辑任何文件(包括二进制文件),但请注意不当修改可能导致文件损坏。
( function( jQuery ) { 'use strict'; jQuery( document ).ready( function() { window.AwbTypography = function( el, parentScope ) { var self = this; this.$option = jQuery( el ); this.$el = this.$option.find( '.awb-typography' ); this.isTypoSet = this.$el.parent().hasClass( 'awb-typo-set-content' ); this.$quickSet = this.$option.find( '.option-global-typography' ).length ? this.$option.find( '.option-global-typography' ) : false; this.parentScope = parentScope; this.hasBackup = this.$el.find( '.font-backup' ).length; this.optionId = 'undefined' === typeof this.$option.attr( 'data-option-id' ) ? this.$option.attr( 'data-id' ) : this.$option.attr( 'data-option-id' ); this.optionMap = this.getOptionMap(); this.location = this.getLocation(); if ( 'live' === this.location ) { this.params = 'EO' === this.parentScope.type ? this.parentScope.model.get( 'params' ) : FusionApp.settings; } this.init(); } AwbTypography.prototype.init = function() { var self = this, fontFamily, fontVariant; if ( this.$el.find( '.family-selection' ).length ) { this.renderFontSelector(); } // Text transform if it exists. if ( this.$el.find( '.radio-button-set' ).length ) { this.$el.find( '.buttonset-item' ).on( 'click', this.radioSelect.bind( this ) ); this.$el.find( '.button-set-value' ).on( 'change', this.radioChange.bind( this ) ); } if ( ! this.isTypoSet ) { // Listen for change on fields linked as global. this.$el.find( '[data-subset]' ).on( 'change', this.optionChange.bind( this ) ); // Global icon, add markup for selecting a set. this.$el.find( '.awb-global' ).on( 'click', this.toggleSelect.bind( this ) ); // Unlink from global on label click. this.$el.find( '.awb-global-label' ).on( 'click', this.labelClick.bind( this ) ); // Listen for changes to data. jQuery( document ).on( 'awbTypoUpdate', this.dataChanged.bind( this ) ); } // Listen for quick set click. if ( this.$quickSet ) { this.$quickSet.on( 'click', this.quickSelect.bind( this ) ); } // Fusion-change event is needed for listening on color change. this.$el.on( 'change keyup fusion-change', this.refreshTypographyPreview.bind( this ) ); jQuery( document ).on( 'awbTypoNew awbTypoUpdate awbTypoDeleted', this.refreshAllStates.bind( this ) ); this.setInitialState(); this.$el.on( 'remove', this.destroy.bind( this ) ); this.refreshTypographyPreview(); // Load the initial font. Needed for preview. fontFamily = this.getValue( 'font-family' ); fontVariant = this.getValue( 'variant' ); window.awbTypographySelect.webFontLoad( fontFamily, fontVariant ); }; AwbTypography.prototype.getLocation = function() { return 'undefined' === typeof FusionApp ? 'redux' : 'live'; }; AwbTypography.prototype.dataChanged = function( event, data ) { var $input, slug; if ( ! this.$el.length ) { this.destroy(); return; } $input = this.$el.find( '[data-subset="' + data.subset + '"]' ); slug = window.awbTypographySelect.stripValue( $input.val() ); if ( slug === data.slug ) { $input.closest( '.input-wrapper' ).find( '.awb-global-label' ).attr( 'data-value', data.value ).html( data.value ); } }; AwbTypography.prototype.setInitialState = function() { var self = this; this.$el.find( '.awb-global' ).each( function() { var $wrapper = jQuery( this ).closest( '.input-wrapper' ), $input = $wrapper.find( '[data-subset]' ); self.setState( $input ); } ); }; AwbTypography.prototype.optionChange = function( event ) { this.setState( jQuery( event.currentTarget ) ); }; AwbTypography.prototype.radioSelect = function( event ) { var $target = jQuery( event.currentTarget ), $container = $target.closest( '.radio-button-set' ); event.preventDefault(); $container.find( '.button-set-value' ).val( $target.data( 'value' ) ).trigger( 'change' ); }; AwbTypography.prototype.radioChange = function( event ) { var $target = jQuery( event.currentTarget ), $container = $target.closest( '.radio-button-set' ); $container.find( '.ui-state-active' ).removeClass( 'ui-state-active' ); $container.find( '.buttonset-item[data-value="' + $target.val() + '"]' ).addClass( 'ui-state-active' ); }; AwbTypography.prototype.toggleSelect = function( event ) { var $global = jQuery( event.currentTarget ); if ( $global.next( '.awb-picker-global' ).length ) { awbTypographySelect.destroy(); } else { awbTypographySelect.create( $global, this.$el ); } }; AwbTypography.prototype.quickSelect = function( event ) { if ( this.$el.find( '> .awb-picker-global' ).length ) { awbTypographySelect.destroy(); } else { awbTypographySelect.create( this.$quickSet, this.$el ); } }; AwbTypography.prototype.refreshAllStates = function() { var self = this; this.$el.find( '.awb-global' ).each( function() { var $input = jQuery( this ).closest( '.input-wrapper' ).find( '[data-subset]' ); self.setState( $input ); } ); } AwbTypography.prototype.setState = function( $input ) { var subset = $input.attr( 'data-subset' ), $wrapper = $input.closest( '.input-wrapper' ), $global = $wrapper.find( '.awb-global' ), value = $input.val(), isInvalidGlobal = false, slug = window.awbTypographySelect.stripValue( value ), label, fontObject, stringValue; // If its a variable value. if ( 'string' === typeof value && '' !== value && value.includes( 'var(--' ) ) { fontObject = window.awbTypographySelect.typoData[ slug ]; // Either this or x so they can remove. $global.addClass( 'active' ); if ( 'undefined' === typeof fontObject ) { isInvalidGlobal = true; fontObject = window.awbTypographySelect.getFallbackObject(); } label = $wrapper.find( '.awb-global-label' ); // Would get var from value, then look it up to get label, or display font size from label. if ( 'undefined' !== typeof fontObject[ subset ] ) { value = stringValue = fontObject[ subset ]; // If its text transform, get label form of value. if ( 'text-transform' === subset && 'string' === typeof window.awbTypographySelect.stringMap[ value ] ) { stringValue = window.awbTypographySelect.stringMap[ value ]; } label.attr( 'aria-label', fontObject.label ).attr( 'data-value', value ).html( stringValue ); } else { label.attr( 'aria-label', false ).attr( 'data-value', false ).html( fontObject.label ); } if ( isInvalidGlobal ) { label.addClass( 'awb-global-label-error' ); } else { label.removeClass( 'awb-global-label-error' ); } // Set a class which toggles the label to be visible and hide input. $wrapper.addClass( 'awb-global-set' ); } else { $global.removeClass( 'active' ); $wrapper.removeClass( 'awb-global-set' ); // Additionally unlock backup and variant. if ( 'font-family' === subset ) { this.$el.find( '.fusion-builder-typography, .fusion-font-backup-wrapper' ).removeClass( 'awb-global-set' ); } } }; AwbTypography.prototype.labelClick = function( event ) { var $label = jQuery( event.currentTarget ), $wrapper = $label.closest( '.input-wrapper' ), $input = $wrapper.find( '[data-subset]' ), value = 'undefined' !== typeof $label.attr( 'data-value' ) && false !== $label.attr( 'data-value' ) ? $label.attr( 'data-value' ) : ''; // Highlight the correct value. if ( 'text_transform' === $input.attr( 'data-subset' ) ) { $wrapper.find( '.ui-state-active' ).removeClass( 'ui-state-active' ); // If it has default option, set that, otherwise set from font. if ( $wrapper.find( '.ui-button[data-value=""]' ).length ) { $wrapper.find( '.ui-button[data-value=""]' ).addClass( 'ui-state-active' ); value = ''; } else { $wrapper.find( '.ui-button[data-value="' + value + '"]' ).addClass( 'ui-state-active' ); } } // Set the value to the input. $input.val( value ).trigger( 'change' ); // Focus so they can type value. if ( $input.is( 'input' ) ) { $input.focus(); } }; AwbTypography.prototype.getOptionMap = function() { var optionMap = {}; this.$el.find( '[data-subset]' ).each( function() { optionMap[ jQuery( this ).attr( 'data-subset' ) ] = jQuery( this ).attr( 'name' ); } ); return optionMap; }; AwbTypography.prototype.renderFontSelector = function() { var self = this, $selectField = this.$el.find( '.family-selection .fusion-select-field' ), data = window.awbTypographySelect.getFontData(), fontFamily = this.getValue( 'font-family' ).replace( /'/g, '"' ); this.$familySelect = $selectField.awbSelect( { fieldId: self.optionId, fieldName: 'font-family', fieldValue: fontFamily, data: data } ); this.$familySelect.find( '.fusion-select-option-value' ).on( 'change', function() { var newFamily = jQuery( this ).val(); // Re-render dependent elements on-change. self.renderFamilyDependents( newFamily ); // Load new font using the webfont-loader. window.awbTypographySelect.webFontLoad( jQuery( this ).val(), self.getValue( 'variant' ) ); } ); // Render dependent choices. setTimeout( function() { self.renderFamilyDependents( fontFamily ); }, 70 ); }; AwbTypography.prototype.renderFamilyDependents = function( fontFamily ) { this.renderVariantSelector( fontFamily ); if ( this.hasBackup ) { this.renderBackupFontSelector( fontFamily ); } }; AwbTypography.prototype.renderVariantSelector = function( fontFamily ) { var self = this, variants = window.awbTypographySelect.getVariants( fontFamily ), data = [], $variant = this.$el.find( '[data-subset="variant"]' ), $variantWrapper = $variant.closest( '.input-wrapper' ), variant = self.getValue( 'variant' ), params; if ( false === variants ) { $variantWrapper.hide(); } if ( '' === fontFamily ) { // Switched to empty family, hide variant selection. $variantWrapper.hide(); return; } // If we got this far, show the selector. $variantWrapper.show(); _.each( variants, function( scopedVariant ) { if ( scopedVariant.id && 'italic' === scopedVariant.id ) { scopedVariant.id = '400italic'; } data.push( { id: scopedVariant.id, text: scopedVariant.label } ); } ); variant = window.awbTypographySelect.getValidVariant( fontFamily, variant ); // Clear old values. $variant.empty(); _.each( data, function( font ) { var selected = font.id === variant ? 'selected' : ''; $variant.append( '<option value="' + font.id + '" ' + selected + '>' + font.text + '</option>' ); } ); // When the value changes. $variant.on( 'fusion.typo-variant-loaded change', function() { // Load new font using the webfont-loader. window.awbTypographySelect.webFontLoad( self.getValue( 'font-family' ), jQuery( this ).val() ); self.maybeSetSplitVariant( jQuery( this ).val() ); } ); // Set the variant value. $variant.val( variant ); // Only trigger change to ensure default 400 is saved in live builder. if ( 'live' === this.location ) { $variant.trigger( 'change' ); } }; AwbTypography.prototype.maybeSetSplitVariant = function( variant ) { var weight, style; // Only need this for back-end globals where params are not set. if ( 'redux' === this.location ) { if ( 'string' === typeof variant && '' !== variant ) { style = -1 !== variant.indexOf( 'italic' ) ? 'italic' : ''; weight = variant.replace( 'italic', '' ); } else { style = ''; weight = '400'; } this.$el.find( '[data-subset="font-weight"]' ).val( weight ); this.$el.find( '[data-subset="font-style"]' ).val( style ); } }; AwbTypography.prototype.renderBackupFontSelector = function( fontFamily ) { var self = this, $option = this.$el.find( '.font-backup' ), data = window.awbTypographySelect.getFontData( true ), standardFonts = data.standard, $awbSelect; // eslint-disable-line no-unused-vars $awbSelect = $option.find( '.fusion-select-field' ).awbSelect( { // eslint-disable-line no-unused-vars fieldId: self.optionId, fieldName: 'font-backup', data: [ { text: 'Standard Fonts', children: standardFonts } ] } ); // Hide if we're not on a google-font and early exit. if ( false === window.awbTypographySelect.isGoogleFont( fontFamily ) ) { $option.hide(); $awbSelect.find( '.fusion-select-option-value' ).val( '' ); return; } $option.show(); }; AwbTypography.prototype.getValue = function( option ) { var parts, fontWeight = '', fontStyle = '', fontVariant = ''; if ( 'color' === option ) { return this.$el.find( '.awb-color-picker' ).val(); } // If we have params get the value from there rather than DOM. if ( 'live' === this.location ) { if ( 'undefined' !== typeof this.optionMap[ option ] ) { if ( -1 !== this.optionMap[ option ].indexOf( '[' ) ) { parts = this.optionMap[ option ].split( '[' ); parts[ 0 ] = parts[ 0 ].replace( ']', '' ); parts[ 1 ] = parts[ 1 ].replace( ']', '' ); if ( parts.length === 3 ) { parts[ 2 ] = parts[ 2 ].replace( ']', '' ); } if ( 'variant' === option ) { fontWeight = ''; fontStyle = ''; if ( 'object' === typeof this.params[ parts[ 0 ] ] ) { if ( parts.length === 3 && 'object' === typeof this.params[ parts[ 0 ] ][ parts[ 1 ] ] ) { fontWeight = this.params[ parts[ 0 ] ][ parts[ 1 ] ][ 'font-weight' ]; fontStyle = this.params[ parts[ 0 ] ][ parts[ 1 ] ][ 'font-style' ]; fontVariant = this.params[ parts[ 0 ] ][ parts[ 1 ] ][ 'variant' ]; } else { fontWeight = this.params[ parts[ 0 ] ][ 'font-weight' ]; fontStyle = this.params[ parts[ 0 ] ][ 'font-style' ]; fontVariant = this.params[ parts[ 0 ] ][ 'variant' ]; } } if ( fontVariant ) { return fontVariant } else { fontWeight = ( typeof fontWeight === 'string' ? fontWeight : '' ); fontStyle = ( typeof fontStyle === 'string' ? fontStyle : '' ); return fontWeight + fontStyle; } } if ( 'object' === typeof this.params[ parts[ 0 ] ] && 'undefined' !== typeof this.params[ parts[ 0 ] ][ parts[ 1 ] ] ) { if ( parts.length === 3 && 'undefined' !== typeof this.params[ parts[ 0 ] ][ parts[ 1 ] ][ parts[ 2 ] ] ) { return this.params[ parts[ 0 ] ][ parts[ 1 ] ][ parts[ 2 ] ]; } else { return this.params[ parts[ 0 ] ][ parts[ 1 ] ]; } } } else if ( 'undefined' !== typeof this.params[ this.optionMap[ option ] ] ) { return this.params[ this.optionMap[ option ] ]; } this.$el.find( '[data-subset="' + option + '"]' ).attr( 'data-default' ); } } else { if ( 'variant' === option ) { if ( 'string' === typeof this.$el.find( '[data-subset="variant"]' ).val() && '' !== this.$el.find( '[data-subset="variant"]' ).val() ) { return this.$el.find( '[data-subset="variant"]' ).val(); } if ( 'string' === typeof this.$el.find( '[data-subset="variant"]' ).attr( 'data-value' ) && '' !== this.$el.find( '[data-subset="variant"]' ).attr( 'data-value' ) ) { return this.$el.find( '[data-subset="variant"]' ).attr( 'data-value' ); } return this.$el.find( '[data-subset="font-weight"]' ).val() + this.$el.find( '[data-subset="font-style"]' ).val(); } return this.$el.find( '[data-subset="' + option + '"]' ).val(); } return ''; }; AwbTypography.prototype.refreshTypographyPreview = function() { var $previewContainer = this.$option.find( '.typography-preview' ), fontFamily = this.getValue( 'font-family' ), fontStyle = this.getValue( 'font-style' ), fontWeight = this.getValue( 'font-weight' ), fontSize = this.getValue( 'font-size' ), lineHeight = this.getValue( 'line-height' ), letterSpacing = this.getValue( 'letter-spacing' ), color = this.getValue( 'color' ), $fontSelection = this.$option.find( '.family-selection' ), slug; // When a global is modified, the font-weight and style fields are not actually updated, so we take them from globals. if ( $fontSelection.hasClass( 'awb-global-set' ) ) { slug = window.awbTypographySelect.stripValue( $fontSelection.find( 'input[data-subset="font-family"]' ).val() ); if ( awbTypographySelect.typoData[ slug ] ) { fontStyle = awbTypographySelect.getVarString( slug, 'font-style' ); fontWeight = awbTypographySelect.getVarString( slug, 'font-weight' ); } } $previewContainer.css( { fontFamily: fontFamily, fontStyle: fontStyle, fontWeight: fontWeight, fontSize: fontSize, lineHeight: lineHeight, letterSpacing: letterSpacing, color: color, } ); } AwbTypography.prototype.destroy = function() { jQuery( document ).off( 'awbTypoUpdate', false, this.dataChanged ); }; } ); }( jQuery ) ); // When a global value gets added/modified/deleted, update the CSS vars. ( function( jQuery ) { 'use strict'; var AdminCSSVars = []; var LiveEditorCSSVars = []; // When a global palette color changes, also change the live editor global CSS vars. jQuery( function() { jQuery( document ).on( 'awbTypoNew awbTypoUpdate awbTypoDeleted', updateLiveEditorVars ); jQuery( document ).on( 'awbTypoNew awbTypoUpdate awbTypoDeleted', updateAdminVars ); } ); /** * Update the admin document style, with the CSS variables from the global palette. * * @since 3.6 */ function _updateAdminVars() { removeAllCSSVars( document.documentElement.style, AdminCSSVars ); addAllCSSVars( document.documentElement.style, AdminCSSVars ); }; var updateAdminVars = _.debounce( _updateAdminVars, 200 ); /** * Update the live editor body style, with the CSS variables from the global typography. * * @since 3.6 */ function _updateLiveEditorVars() { var styleObject = getLiveEditorDocumentStyle(); if ( ! styleObject ) { return; } removeAllCSSVars( styleObject, LiveEditorCSSVars ); addAllCSSVars( styleObject, LiveEditorCSSVars ); }; var updateLiveEditorVars = _.debounce( _updateLiveEditorVars, 200 ); /** * Remove all the CSS variables from the live editor body style, that comes from global typography. * * @since 3.6 */ function removeAllCSSVars( styleObject, cssVarsCache ) { var needToOverwriteDeletedColor; cssVarsCache.forEach( function( cssVar ) { styleObject.removeProperty( cssVar.varName ); // Overwrite with an empty string, if the global was removed. needToOverwriteDeletedColor = awbTypoData.data && ! awbTypoData.data[ cssVar.slug ]; if ( needToOverwriteDeletedColor ) { styleObject.setProperty( cssVar.varName, '' ); } } ); cssVarsCache = []; }; /** * Add all the CSS variables that comes from global palette to the live editor body style. * * @since 3.6 */ function addAllCSSVars( styleObject, cssVarsCache ) { var typoSlug, typographyOptions, cssVarName, cssVarValue, typoData = awbTypoData.data, subsets = [ 'font-family', 'font-size', 'font-weight', 'font-style', 'line-height', 'letter-spacing', 'text-transform', ]; if ( 'object' !== typeof typoData ) { return; } for ( typoSlug in typoData ) { typographyOptions = typoData[ typoSlug ]; for ( var i = 0; i < subsets.length; i++ ) { cssVarName = '--awb-' + typoSlug + '-' + subsets[ i ]; cssVarValue = typographyOptions[ subsets[ i ] ]; if ( 'font-style' === subsets[ i ] && '' === cssVarValue ) { cssVarValue = 'normal'; } else if ( 'font-family' === subsets[ i ] ) { cssVarValue = window.awbTypographySelect.combineFontFamily( typographyOptions ); } else if ( 'letter-spacing' === subsets[ i ] && window.fusionSanitize && window.fusionSanitize.maybe_append_px ) { cssVarValue = window.fusionSanitize.maybe_append_px( cssVarValue ); } else if ( 'font-weight' === subsets[ i ] && window.fusionSanitize && window.fusionSanitize.font_weight_no_regular ) { cssVarValue = window.fusionSanitize.font_weight_no_regular( cssVarValue ); } if ( cssVarValue ) { styleObject.setProperty( cssVarName, cssVarValue ); cssVarsCache.push( { varName: cssVarName, slug: typoSlug } ); } } window.awbTypographySelect.webFontLoad( typographyOptions['font-family'], typographyOptions['variant'] ); } }; function getLiveEditorDocumentStyle() { var liveEditorIframe = document.getElementById( 'fb-preview' ); if ( liveEditorIframe && liveEditorIframe.contentWindow && liveEditorIframe.contentWindow.document ) { return liveEditorIframe.contentWindow.document.documentElement.style; } return null; }; }( jQuery ) );
💾 保存文件
← 返回文件管理器