diff options
Diffstat (limited to 'plugins/jetpack/modules/theme-tools/site-logo')
14 files changed, 1002 insertions, 0 deletions
diff --git a/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control-rtl.css b/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control-rtl.css new file mode 100644 index 00000000..d5441db1 --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control-rtl.css @@ -0,0 +1,12 @@ +/** + * RTL styles for the Site Logo control. Just swaps the button sides. + */ +#customize-control-site_logo .remove { + float: right; + margin-left: 3px; +} + +#customize-control-site_logo .new, +#customize-control-site_logo .change { + float: left; +} diff --git a/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control-rtl.min.css b/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control-rtl.min.css new file mode 100644 index 00000000..1893fe9c --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control-rtl.min.css @@ -0,0 +1 @@ +#customize-control-site_logo .remove{float:right;margin-left:3px}#customize-control-site_logo .change,#customize-control-site_logo .new{float:left}
\ No newline at end of file diff --git a/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control.css b/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control.css new file mode 100644 index 00000000..b9a10fe6 --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control.css @@ -0,0 +1,49 @@ +/** + * Styles for the Site Logo control. + */ +#customize-control-site_logo .current { + margin-bottom: 6px; +} + +#customize-control-site_logo .current span { + border: 1px solid #eee; + -webkit-border-radius: 2px; + border-radius: 2px; + color: #555; + display: block; + overflow: hidden; + line-height: 40px; + min-height: 40px; + padding: 0 6px; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; +} + +#customize-control-site_logo .current img { + max-width: 100%; +} + +#customize-control-site_logo button.new, +#customize-control-site_logo button.change, +#customize-control-site_logo button.remove { + height: auto; + width: 48%; + white-space: normal; +} + +#customize-control-site_logo .remove { + float: left; + margin-right: 3px; +} + +#customize-control-site_logo .new, +#customize-control-site_logo .change { + float: right; +} + +#customize-control-site_logo .customize-control-description { + display: block; + clear: both; + margin-bottom: 10px; +}
\ No newline at end of file diff --git a/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control.min.css b/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control.min.css new file mode 100644 index 00000000..7fcee5ae --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/css/site-logo-control.min.css @@ -0,0 +1 @@ +#customize-control-site_logo .current{margin-bottom:6px}#customize-control-site_logo .current span{border:1px solid #eee;-webkit-border-radius:2px;border-radius:2px;color:#555;display:block;overflow:hidden;line-height:40px;min-height:40px;padding:0 6px;text-align:center;text-overflow:ellipsis;white-space:nowrap}#customize-control-site_logo .current img{max-width:100%}#customize-control-site_logo button.change,#customize-control-site_logo button.new,#customize-control-site_logo button.remove{height:auto;width:48%;white-space:normal}#customize-control-site_logo .remove{float:left;margin-right:3px}#customize-control-site_logo .change,#customize-control-site_logo .new{float:right}#customize-control-site_logo .customize-control-description{display:block;clear:both;margin-bottom:10px}
\ No newline at end of file diff --git a/plugins/jetpack/modules/theme-tools/site-logo/inc/class-site-logo-control.php b/plugins/jetpack/modules/theme-tools/site-logo/inc/class-site-logo-control.php new file mode 100644 index 00000000..5e23507d --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/inc/class-site-logo-control.php @@ -0,0 +1,109 @@ +<?php +/** + * Custom logo uploader control for the Customizer. + * + * @package Jetpack + */ +class Site_Logo_Image_Control extends WP_Customize_Control { + /** + * Constructor for our custom control. + * + * @param object $wp_customize + * @param string $control_id + * @param array $args + * @uses Site_Logo_Image_Control::l10n() + */ + public function __construct( $wp_customize, $control_id, $args = array() ) { + // declare these first so they can be overridden + $this->l10n = array( + 'upload' => __( 'Add logo', 'jetpack' ), + 'set' => __( 'Set as logo', 'jetpack' ), + 'choose' => __( 'Choose logo', 'jetpack' ), + 'change' => __( 'Change logo', 'jetpack' ), + 'remove' => __( 'Remove logo', 'jetpack' ), + 'placeholder' => __( 'No logo set', 'jetpack' ), + ); + + parent::__construct( $wp_customize, $control_id, $args ); + } + + /** + * This will be critical for our JS constructor. + */ + public $type = 'site_logo'; + + /** + * Allows overriding of global labels by a specific control. + */ + public $l10n = array(); + + /** + * The type of files that should be allowed by the media modal. + */ + public $mime_type = 'image'; + + /** + * Enqueue our media manager resources, scripts, and styles. + * + * @uses wp_enqueue_media() + * @uses wp_enqueue_style() + * @uses wp_enqueue_script() + * @uses plugins_url() + */ + public function enqueue() { + // Enqueues all needed media resources. + wp_enqueue_media(); + + // Enqueue our control script and styles. + wp_enqueue_style( 'site-logo-control', plugins_url( '../css/site-logo-control.css', __FILE__ ) ); + wp_enqueue_script( 'site-logo-control', plugins_url( '../js/site-logo-control.js', __FILE__ ), array( 'media-views', 'customize-controls', 'underscore' ), '', true ); + } + + /** + * Check if we have an active site logo. + * + * @uses get_option() + * @return boolean + */ + public function has_site_logo() { + $logo = get_option( 'site_logo' ); + + if ( empty( $logo['url'] ) ) { + return false; + } else { + return true; + } + } + + /** + * Display our custom control in the Customizer. + * + * @uses Site_Logo_Image_Control::l10n() + * @uses Site_Logo_Image_Control::mime_type() + * @uses Site_Logo_Image_Control::label() + * @uses Site_Logo_Image_Control::description() + * @uses esc_attr() + * @uses esc_html() + */ + public function render_content() { + // We do this to allow the upload control to specify certain labels + $l10n = json_encode( $this->l10n ); + + // Control title + printf( + '<span class="customize-control-title" data-l10n="%s" data-mime="%s">%s</span>', + esc_attr( $l10n ), + esc_attr( $this->mime_type ), + esc_html( $this->label ) + ); + + // Control description + if ( ! empty( $this->description ) ) : ?> + <span class="description customize-control-description"><?php echo $this->description; ?></span> + <?php endif; ?> + + <div class="current"></div> + <div class="actions"></div> + <?php + } +} diff --git a/plugins/jetpack/modules/theme-tools/site-logo/inc/class-site-logo.php b/plugins/jetpack/modules/theme-tools/site-logo/inc/class-site-logo.php new file mode 100644 index 00000000..75fe80b1 --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/inc/class-site-logo.php @@ -0,0 +1,377 @@ +<?php +/** + * Our Site Logo class for managing a theme-agnostic logo through the Customizer. + * + * @package Jetpack + */ +class Site_Logo { + /** + * Stores our single instance. + */ + private static $instance; + + /** + * Stores our current logo settings. + */ + public $logo; + + /** + * Return our instance, creating a new one if necessary. + * + * @uses Site_Logo::$instance + * @return object Site_Logo + */ + public static function instance() { + if ( ! isset( self::$instance ) ) { + self::$instance = new Site_Logo(); + self::$instance->register_hooks(); + } + + return self::$instance; + } + + /** + * Get our current logo settings stored in options. + * + * @uses get_option() + */ + private function __construct() { + $this->logo = get_option( 'site_logo', null ); + } + + /** + * Register our actions and filters. + * + * @uses Site_Logo::head_text_styles() + * @uses Site_Logo::customize_register() + * @uses Site_Logo::preview_enqueue() + * @uses Site_Logo::body_classes() + * @uses Site_Logo::media_manager_image_sizes() + * @uses add_action + * @uses add_filter + */ + public function register_hooks() { + // This would only happen if a theme supports BOTH site-logo and custom-logo for some reason + if ( current_theme_supports( 'custom-logo' ) ) { + return; + } + + add_action( 'wp_head', array( $this, 'head_text_styles' ) ); + add_action( 'customize_register', array( $this, 'customize_register' ) ); + add_action( 'customize_preview_init', array( $this, 'preview_enqueue' ) ); + add_action( 'delete_attachment', array( $this, 'reset_on_attachment_delete' ) ); + add_filter( 'body_class', array( $this, 'body_classes' ) ); + add_filter( 'image_size_names_choose', array( $this, 'media_manager_image_sizes' ) ); + add_filter( 'display_media_states', array( $this, 'add_media_state' ) ); + } + + /** + * Add our logo uploader to the Customizer. + * + * @param object $wp_customize Customizer object. + * @uses current_theme_supports() + * @uses current_theme_supports() + * @uses WP_Customize_Manager::add_setting() + * @uses WP_Customize_Manager::add_control() + * @uses Site_Logo::sanitize_checkbox() + */ + public function customize_register( $wp_customize ) { + // Include our custom control. + require dirname( __FILE__ ) . '/class-site-logo-control.php'; + + // Add a setting to hide header text if the theme isn't supporting the feature itself + if ( ! current_theme_supports( 'custom-header' ) ) { + $wp_customize->add_setting( + 'site_logo_header_text', + array( + 'default' => 1, + 'sanitize_callback' => array( $this, 'sanitize_checkbox' ), + 'transport' => 'postMessage', + ) + ); + + $wp_customize->add_control( + new WP_Customize_Control( + $wp_customize, + 'site_logo_header_text', + array( + 'label' => __( 'Display Header Text', 'jetpack' ), + 'section' => 'title_tagline', + 'settings' => 'site_logo_header_text', + 'type' => 'checkbox', + ) + ) + ); + } + + // Add the setting for our logo value. + $wp_customize->add_setting( + 'site_logo', + array( + 'capability' => 'manage_options', + 'default' => array( + 'id' => 0, + 'sizes' => array(), + 'url' => false, + ), + 'sanitize_callback' => array( $this, 'sanitize_logo_setting' ), + 'transport' => 'postMessage', + 'type' => 'option', + ) + ); + + // Add our image uploader. + $wp_customize->add_control( + new Site_Logo_Image_Control( + $wp_customize, + 'site_logo', + array( + 'label' => __( 'Logo', 'jetpack' ), + 'section' => 'title_tagline', + 'settings' => 'site_logo', + ) + ) + ); + } + + /** + * Enqueue scripts for the Customizer live preview. + * + * @uses wp_enqueue_script() + * @uses plugins_url() + * @uses current_theme_supports() + * @uses Site_Logo::header_text_classes() + * @uses wp_localize_script() + */ + public function preview_enqueue() { + wp_enqueue_script( 'site-logo-preview', plugins_url( '../js/site-logo.js', __FILE__ ), array( 'media-views' ), '', true ); + + // Don't bother passing in header text classes if the theme supports custom headers. + if ( ! current_theme_supports( 'custom-header' ) ) { + $classes = jetpack_sanitize_header_text_classes( $this->header_text_classes() ); + wp_enqueue_script( 'site-logo-header-text', plugins_url( '../js/site-logo-header-text.js', __FILE__ ), array( 'media-views' ), '', true ); + wp_localize_script( 'site-logo-header-text', 'site_logo_header_classes', $classes ); + } + } + + /** + * Get header text classes. If not defined in add_theme_support(), defaults from Underscores will be used. + * + * @uses get_theme_support + * @return string String of classes to hide + */ + public function header_text_classes() { + $args = get_theme_support( 'site-logo' ); + + if ( isset( $args[0]['header-text'] ) ) { + // Use any classes defined in add_theme_support(). + $classes = $args[0]['header-text']; + } else { + // Otherwise, use these defaults, which will work with any Underscores-based theme. + $classes = array( + 'site-title', + 'site-description', + ); + } + + // If we've got an array, reduce them to a string for output + if ( is_array( $classes ) ) { + $classes = (string) '.' . implode( ', .', $classes ); + } else { + $classes = (string) '.' . $classes; + } + + return $classes; + } + + /** + * Hide header text on front-end if necessary. + * + * @uses current_theme_supports() + * @uses get_theme_mod() + * @uses Site_Logo::header_text_classes() + * @uses esc_html() + */ + public function head_text_styles() { + // Bail if our theme supports custom headers. + if ( current_theme_supports( 'custom-header' ) ) { + return; + } + + // Is Display Header Text unchecked? If so, we need to hide our header text. + if ( ! get_theme_mod( 'site_logo_header_text', 1 ) ) { + $classes = $this->header_text_classes(); + ?> + <!-- Site Logo: hide header text --> + <style type="text/css"> + <?php echo jetpack_sanitize_header_text_classes( $classes ); ?> { + position: absolute; + clip: rect(1px, 1px, 1px, 1px); + } + </style> + <?php + } + } + + /** + * Determine image size to use for the logo. + * + * @uses get_theme_support() + * @return string Size specified in add_theme_support declaration, or 'thumbnail' default + */ + public function theme_size() { + $args = get_theme_support( 'site-logo' ); + $valid_sizes = get_intermediate_image_sizes(); + + // Add 'full' to the list of accepted values. + $valid_sizes[] = 'full'; + + // If the size declared in add_theme_support is valid, use it; otherwise, just go with 'thumbnail'. + $size = ( isset( $args[0]['size'] ) && in_array( $args[0]['size'], $valid_sizes ) ) ? $args[0]['size'] : 'thumbnail'; + + return $size; + } + + /** + * Make custom image sizes available to the media manager. + * + * @param array $sizes + * @uses get_intermediate_image_sizes() + * @return array All default and registered custom image sizes. + */ + public function media_manager_image_sizes( $sizes ) { + // Get an array of all registered image sizes. + $intermediate = get_intermediate_image_sizes(); + + // Have we got anything fun to work with? + if ( is_array( $intermediate ) && ! empty( $intermediate ) ) { + foreach ( $intermediate as $key => $size ) { + // If the size isn't already in the $sizes array, add it. + if ( ! array_key_exists( $size, $sizes ) ) { + $sizes[ $size ] = $size; + } + } + } + + return $sizes; + } + + /** + * Add site logos to media states in the Media Manager. + * + * @return array The current attachment's media states. + */ + public function add_media_state( $media_states ) { + // Only bother testing if we have a site logo set. + if ( $this->has_site_logo() ) { + global $post; + + // If our attachment ID and the site logo ID match, this image is the site logo. + if ( $post->ID == $this->logo['id'] ) { + $media_states[] = __( 'Site Logo', 'jetpack' ); + } + } + + return $media_states; + } + + /** + * Reset the site logo if the current logo is deleted in the media manager. + * + * @param int $site_id + * @uses Site_Logo::remove_site_logo() + */ + public function reset_on_attachment_delete( $post_id ) { + if ( $this->logo['id'] == $post_id ) { + $this->remove_site_logo(); + } + } + + /** + * Determine if a site logo is assigned or not. + * + * @uses Site_Logo::$logo + * @return boolean True if there is an active logo, false otherwise + */ + public function has_site_logo() { + return ( isset( $this->logo['id'] ) && 0 !== $this->logo['id'] ) ? true : false; + } + + /** + * Reset the site logo option to zero (empty). + * + * @uses update_option() + */ + public function remove_site_logo() { + update_option( + 'site_logo', + array( + 'id' => (int) 0, + 'sizes' => array(), + 'url' => '', + ) + ); + } + + /** + * Adds custom classes to the array of body classes. + * + * @uses Site_Logo::has_site_logo() + * @return array Array of <body> classes + */ + public function body_classes( $classes ) { + // Add a class if a Site Logo is active + if ( $this->has_site_logo() ) { + $classes[] = 'has-site-logo'; + } + + return $classes; + } + + /** + * Sanitize our header text Customizer setting. + * + * @param $input + * @return mixed 1 if checked, empty string if not checked. + */ + public function sanitize_checkbox( $input ) { + return ( 1 == $input ) ? 1 : ''; + } + + /** + * Validate and sanitize a new site logo setting. + * + * @param $input + * @return mixed 1 if checked, empty string if not checked. + */ + public function sanitize_logo_setting( $input ) { + $input['id'] = absint( $input['id'] ); + $input['url'] = esc_url_raw( $input['url'] ); + + // If the new setting doesn't point to a valid attachment, just reset the whole thing. + if ( false == wp_get_attachment_image_src( $input['id'] ) ) { + $input = array( + 'id' => (int) 0, + 'sizes' => array(), + 'url' => '', + ); + } + + return $input; + } +} + +/** + * Allow themes and plugins to access Site_Logo methods and properties. + * + * @uses Site_Logo::instance() + * @return object Site_Logo + */ +function site_logo() { + return Site_Logo::instance(); +} + +/** + * One site logo, please. + */ +site_logo(); diff --git a/plugins/jetpack/modules/theme-tools/site-logo/inc/compat.php b/plugins/jetpack/modules/theme-tools/site-logo/inc/compat.php new file mode 100644 index 00000000..d1098536 --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/inc/compat.php @@ -0,0 +1,44 @@ +<?php +/** + * Functions for maintaining backwards compatibility with unprefixed template tags from the original Site Logo plugin. + * These should never be used in themes; instead, use the template tags in functions.php. + * See: https://github.com/Automattic/jetpack/pull/956 + * + * @package Jetpack + */ + +if ( ! function_exists( 'the_site_logo' ) ) : + /** + * Unprefixed, backwards-compatible function for outputting the site logo. + * + * @uses jetpack_the_site_logo() + */ + function the_site_logo() { + jetpack_the_site_logo(); + } +endif; + +if ( ! function_exists( 'has_site_logo' ) ) : + /** + * Unprefixed, backwards-compatible function for determining if a site logo has been set. + * + * @uses jetpack_has_site_logo() + * @return bool True if a site logo is set, false otherwise. + */ + function has_site_logo() { + return jetpack_has_site_logo(); + } +endif; + +if ( ! function_exists( 'get_site_logo' ) ) : + /** + * Unprefixed, backwards-compatible function for getting either the site logo's image URL or its ID. + * + * @param string $show Return the site logo URL or ID. + * @uses jetpack_get_site_logo() + * @return string Site logo ID or URL (the default). + */ + function get_site_logo( $show = 'url' ) { + return jetpack_get_site_logo( $show ); + } +endif; diff --git a/plugins/jetpack/modules/theme-tools/site-logo/inc/functions.php b/plugins/jetpack/modules/theme-tools/site-logo/inc/functions.php new file mode 100644 index 00000000..3b27b32f --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/inc/functions.php @@ -0,0 +1,176 @@ +<?php +/** + * Functions and template tags for using site logos. + * + * @package Jetpack + */ + +/** + * Retrieve the site logo URL or ID (URL by default). Pass in the string 'id' for ID. + * + * @uses get_option() + * @uses esc_url_raw() + * @uses set_url_scheme() + * @return mixed The URL or ID of our site logo, false if not set + * @since 1.0 + */ +function jetpack_get_site_logo( $show = 'url' ) { + $logo = site_logo()->logo; + + // Return false if no logo is set + if ( ! isset( $logo['id'] ) || 0 == $logo['id'] ) { + return false; + } + + // Return the ID if specified, otherwise return the URL by default + if ( 'id' == $show ) { + return $logo['id']; + } else { + return esc_url_raw( set_url_scheme( $logo['url'] ) ); + } +} + +/** + * Retrieve an array of the dimensions of the Site Logo. + * + * @uses Site_Logo::theme_size() + * @uses get_option( 'thumbnail_size_w' ) + * @uses get_option( 'thumbnail_size_h' ) + * @uses global $_wp_additional_image_sizes; + * + * @since 3.6.0 + * + * @return array $dimensions { + * An array of dimensions of the Site Logo. + * + * @type string $width Width of the logo in pixels. + * @type string $height Height of the logo in pixels. + * } + */ +function jetpack_get_site_logo_dimensions() { + // Get the image size to use with the logo. + $size = site_logo()->theme_size(); + + // If the size is the default `thumbnail`, get its dimensions. Otherwise, get them from $_wp_additional_image_sizes + if ( empty( $size ) ) { + return false; + } elseif ( 'thumbnail' == $size ) { + $dimensions = array( + 'width' => get_option( 'thumbnail_size_w' ), + 'height' => get_option( 'thumbnail_size_h' ), + ); + } else { + global $_wp_additional_image_sizes; + + if ( ! isset( $_wp_additional_image_sizes[ $size ] ) ) { + return false; + } + + $dimensions = array( + 'width' => $_wp_additional_image_sizes[ $size ]['width'], + 'height' => $_wp_additional_image_sizes[ $size ]['height'], + ); + } + + return $dimensions; +} + +/** + * Determine if a site logo is assigned or not. + * + * @uses get_option + * @return boolean True if there is an active logo, false otherwise + */ +function jetpack_has_site_logo() { + return site_logo()->has_site_logo(); +} + +/** + * Output an <img> tag of the site logo, at the size specified + * in the theme's add_theme_support() declaration. + * + * @uses Site_Logo::logo + * @uses Site_Logo::theme_size() + * @uses jetpack_has_site_logo() + * @uses jetpack_is_customize_preview() + * @uses esc_url() + * @uses home_url() + * @uses esc_attr() + * @uses wp_get_attachment_image() + * @uses apply_filters() + * @since 1.0 + */ +function jetpack_the_site_logo() { + $logo = site_logo()->logo; + $logo_id = get_theme_mod( 'custom_logo' ); // Check for WP 4.5 Site Logo + $logo_id = $logo_id ? $logo_id : $logo['id']; // Use WP Core logo if present, otherwise use Jetpack's. + $size = site_logo()->theme_size(); + $html = ''; + + // If no logo is set, but we're in the Customizer, leave a placeholder (needed for the live preview). + if ( ! jetpack_has_site_logo() ) { + if ( jetpack_is_customize_preview() ) { + $html = sprintf( + '<a href="%1$s" class="site-logo-link" style="display:none;"><img class="site-logo" data-size="%2$s" /></a>', + esc_url( home_url( '/' ) ), + esc_attr( $size ) + ); + } + } + + // We have a logo. Logo is go. + else { + $html = sprintf( + '<a href="%1$s" class="site-logo-link" rel="home" itemprop="url">%2$s</a>', + esc_url( home_url( '/' ) ), + wp_get_attachment_image( + $logo_id, + $size, + false, + array( + 'class' => "site-logo attachment-$size", + 'data-size' => $size, + 'itemprop' => 'logo', + ) + ) + ); + } + + /** + * Filter the Site Logo output. + * + * @module theme-tools + * + * @since 3.2.0 + * + * @param string $html Site Logo HTML output. + * @param array $logo Array of Site Logo details. + * @param string $size Size specified in add_theme_support declaration, or 'thumbnail' default. + */ + echo apply_filters( 'jetpack_the_site_logo', $html, $logo, $size ); +} + +/** + * Whether the site is being previewed in the Customizer. + * Duplicate of core function until 4.0 is released. + * + * @global WP_Customize_Manager $wp_customize Customizer instance. + * @return bool True if the site is being previewed in the Customizer, false otherwise. + */ +function jetpack_is_customize_preview() { + global $wp_customize; + + return is_a( $wp_customize, 'WP_Customize_Manager' ) && $wp_customize->is_preview(); +} + +/** + * Sanitize the string of classes used for header text. + * Limit to A-Z,a-z,0-9,(space),(comma),_,- + * + * @return string Sanitized string of CSS classes. + */ +function jetpack_sanitize_header_text_classes( $classes ) { + $classes = preg_replace( '/[^A-Za-z0-9\,\ ._-]/', '', $classes ); + + return $classes; +} diff --git a/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-control.js b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-control.js new file mode 100644 index 00000000..c4cce6c2 --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-control.js @@ -0,0 +1,160 @@ +/** + * JS for handling the Site Logo Customizer control. + */ +( function( wp, $ ) { + // nice shortcut + var api = wp.customize; + /** + * The Customizer looks for wp.customizer.controlConstructor[type] functions + * where type == the type member of a WP_Customize_Control + */ + api.controlConstructor.site_logo = api.Control.extend( { + /** + * This method is called when the control is ready to run. + * Do all of your setup and event binding here. + */ + ready: function() { + // this.container is a jQuery object of your container + + // grab the bits of data from the title for specifying this control + var data = this.container.find( '.customize-control-title' ).data(); + + // Use specific l10n data for this control where available + this.l10n = data.l10n; + // Grab mime type + this.mime = data.mime; + + // Set up image container and button elements. Cache for re-use. + this.$imgContainer = $( '#customize-control-site_logo .current' ); + this.$btnContainer = $( '#customize-control-site_logo .actions' ); + this.$img = $( '<img class="site-logo-thumbnail" />' ).prependTo( this.$imgContainer ); + this.$placeholder = $( '<span>' + this.l10n.placeholder + '</span>' ).prependTo( + this.$imgContainer + ); + this.$btnAdd = $( + '<button type="button" class="button new">' + this.l10n.upload + '</button>' + ).prependTo( this.$btnContainer ); + this.$btnChange = $( + '<button type="button" class="button change">' + this.l10n.change + '</button>' + ).prependTo( this.$btnContainer ); + this.$btnRemove = $( + '<button type="button" class="button remove">' + this.l10n.remove + '</button>' + ).prependTo( this.$btnContainer ); + + // handy shortcut so we don't have to us _.bind every time we add a callback + _.bindAll( this, 'removeImg', 'upload', 'render', 'pick' ); + + this.$btnAdd.on( 'click', this.upload ); + this.$btnChange.on( 'click', this.upload ); + this.$btnRemove.on( 'click', this.removeImg ); + + // Call render method whenever setting is changed. + this.setting.bind( 'change', this.render ); + // Do initial rendering. + this.render(); + }, + /** + * Remember that _.bind was used to maintain `this` as the control + * object rather than the usual jQuery way of binding to the DOM element. + */ + upload: function( event ) { + event.preventDefault(); + + if ( ! this.frame ) { + this.initFrame(); + } + + this.frame.open(); + }, + /** + * Set the media frame so that it can be reused and accessed when needed. + */ + initFrame: function() { + this.frame = wp.media( { + // The title of the media modal + title: this.l10n.choose, + // restrict to specified mime type + library: { + type: this.mime, + }, + // Customize the submit button. + button: { + // Set the text of the button. + text: this.l10n.set, + }, + // Just one, thanks. + multiple: false, + } ); + + // When an image is selected, run a callback. + this.frame.on( 'select', this.pick ); + }, + /** + * Fired when an image is selected in the media modal. Gets the selected + * image information, and sets it within the control. + */ + pick: function() { + // get the attachment from the modal frame + var attachment = this.frame + .state() + .get( 'selection' ) + .single(); + if ( 'image' === attachment.get( 'type' ) ) { + // set the setting - the callback will take care of rendering + this.setting( this.reduceMembers( attachment.toJSON() ) ); + } + }, + /** + * Reduces the attachment object to just the few desired members. + * @param {object} attachment An attachment object provided by the + * medial modal. + * @return {object} A reduced media object. + */ + reduceMembers: function( attachment ) { + var desired = [ 'id', 'sizes', 'url' ], + output = {}; + $.each( desired, function( i, key ) { + output[ key ] = attachment[ key ]; + } ); + return output; + }, + /** + * Called on init and whenever a setting is changed. Shows the thumbnail + * when there is one or the upload button when there isn't. + */ + render: function() { + var value = this.setting(); + + if ( value && value.url ) { + this.$placeholder.hide(); + if ( ! value.sizes || ! value.sizes.medium ) { + this.$img.attr( 'src', value.url ); + } else { + this.$img.attr( 'src', value.sizes.medium.url ); + } + this.$img.show(); + this.$btnRemove.show(); + this.$btnChange.show(); + this.$btnAdd.hide(); + } else { + this.$img.hide(); + this.$placeholder.show(); + this.$btnRemove.hide(); + this.$btnChange.hide(); + this.$btnAdd.show(); + } + }, + /** + * Called when the "Remove Image" link is clicked. Sets thes setting back + * to its default state. + * @param {object} event jQuery Event object from click event + */ + removeImg: function( event ) { + event.preventDefault(); + this.setting( { + url: '', + id: 0, + } ); + }, + } ); +} )( this.wp, jQuery ); diff --git a/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-control.min.js b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-control.min.js new file mode 100644 index 00000000..171d98e8 --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-control.min.js @@ -0,0 +1 @@ +(function(a,c){var b=a.customize;b.controlConstructor.site_logo=b.Control.extend({ready:function(){var d=this.container.find(".customize-control-title").data();this.l10n=d.l10n;this.mime=d.mime;this.$imgContainer=c("#customize-control-site_logo .current");this.$btnContainer=c("#customize-control-site_logo .actions");this.$img=c('<img class="site-logo-thumbnail" />').prependTo(this.$imgContainer);this.$placeholder=c("<span>"+this.l10n.placeholder+"</span>").prependTo(this.$imgContainer);this.$btnAdd=c('<button type="button" class="button new">'+this.l10n.upload+"</button>").prependTo(this.$btnContainer);this.$btnChange=c('<button type="button" class="button change">'+this.l10n.change+"</button>").prependTo(this.$btnContainer);this.$btnRemove=c('<button type="button" class="button remove">'+this.l10n.remove+"</button>").prependTo(this.$btnContainer);_.bindAll(this,"removeImg","upload","render","pick");this.$btnAdd.on("click",this.upload);this.$btnChange.on("click",this.upload);this.$btnRemove.on("click",this.removeImg);this.setting.bind("change",this.render);this.render()},upload:function(d){d.preventDefault();if(!this.frame){this.initFrame()}this.frame.open()},initFrame:function(){this.frame=a.media({title:this.l10n.choose,library:{type:this.mime},button:{text:this.l10n.set},multiple:false});this.frame.on("select",this.pick)},pick:function(){var d=this.frame.state().get("selection").first().toJSON();d=this.reduceMembers(d);this.setting(d)},reduceMembers:function(f){var e=["id","sizes","url"],d={};c.each(e,function(h,g){d[g]=f[g]});return d},render:function(){var d=this.setting();if(d&&d.url){this.$placeholder.hide();if(!d.sizes||!d.sizes.medium){this.$img.attr("src",d.url)}else{this.$img.attr("src",d.sizes.medium.url)}this.$img.show();this.$btnRemove.show();this.$btnChange.show();this.$btnAdd.hide()}else{this.$img.hide();this.$placeholder.show();this.$btnRemove.hide();this.$btnChange.hide();this.$btnAdd.show()}},removeImg:function(d){d.preventDefault();this.setting({url:"",id:0})}})})(this.wp,jQuery);
\ No newline at end of file diff --git a/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-header-text.js b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-header-text.js new file mode 100644 index 00000000..82673a7e --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-header-text.js @@ -0,0 +1,24 @@ +/* global site_logo_header_classes */ +/** + * JS for handling the "Display Header Text" setting's realtime preview. + */ +( function( $ ) { + var api = wp.customize, + $classes = site_logo_header_classes; + + api( 'site_logo_header_text', function( value ) { + value.bind( function( to ) { + if ( true === to ) { + $( $classes ).css( { + position: 'static', + clip: 'auto', + } ); + } else { + $( $classes ).css( { + position: 'absolute', + clip: 'rect(1px 1px 1px 1px)', + } ); + } + } ); + } ); +} )( jQuery ); diff --git a/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-header-text.min.js b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-header-text.min.js new file mode 100644 index 00000000..39c56ec0 --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo-header-text.min.js @@ -0,0 +1 @@ +!function(t){var i=wp.customize,o=site_logo_header_classes;i("site_logo_header_text",function(i){i.bind(function(i){t(o).css(!0===i?{position:"static",clip:"auto"}:{position:"absolute",clip:"rect(1px 1px 1px 1px)"})})})}(jQuery);
\ No newline at end of file diff --git a/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo.js b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo.js new file mode 100644 index 00000000..6c959c0c --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo.js @@ -0,0 +1,46 @@ +/** + * JS for handling the Site Logo real-time display in the Customizer preview frame. + */ +( function( $ ) { + var api = wp.customize, + $body, + $anchor, + $logo, + size; + + function cacheSelectors() { + $body = $( 'body' ); + $anchor = $( '.site-logo-link' ); + $logo = $( '.site-logo' ); + size = $logo.attr( 'data-size' ); + } + + api( 'site_logo', function( value ) { + value.bind( function( newVal ) { + // grab selectors the first time through + if ( ! $body ) { + cacheSelectors(); + } + + // Let's update our preview logo. + if ( newVal && newVal.url ) { + // If the source was smaller than the size required by the theme, give the biggest we've got. + if ( ! newVal.sizes[ size ] ) { + size = 'full'; + } + + $logo.attr( { + height: newVal.sizes[ size ].height, + width: newVal.sizes[ size ].width, + src: newVal.sizes[ size ].url, + } ); + + $anchor.show(); + $body.addClass( 'has-site-logo' ); + } else { + $anchor.hide(); + $body.removeClass( 'has-site-logo' ); + } + } ); + } ); +} )( jQuery ); diff --git a/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo.min.js b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo.min.js new file mode 100644 index 00000000..a6fe41eb --- /dev/null +++ b/plugins/jetpack/modules/theme-tools/site-logo/js/site-logo.min.js @@ -0,0 +1 @@ +(function(d){var e=wp.customize,c,f,g,a;e("site_logo",function(e){e.bind(function(b){c||(c=d("body"),f=d(".site-logo-link"),g=d(".site-logo"),a=g.attr("data-size"));b&&b.url?(b.sizes[a]||(a="full"),g.attr({height:b.sizes[a].height,width:b.sizes[a].width,src:b.sizes[a].url}),f.show(),c.addClass("has-site-logo")):(f.hide(),c.removeClass("has-site-logo"))})})})(jQuery);
\ No newline at end of file |