WordPress.org

Make WordPress Core

Changeset 40631


Ignore:
Timestamp:
05/11/17 18:54:24 (2 months ago)
Author:
westonruter
Message:

Widgets: Extend the Text widget with TinyMCE.

Introduces rich text formatting: bold, italic, lists, links.

Props westonruter, azaozz, timmydcrawford, obenland, melchoyce.
See #35760.
Fixes #35243.

Location:
trunk
Files:
4 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Gruntfile.js

    r40527 r40631  
    457457                ext: '.min.js', 
    458458                src: [ 
    459                     'wp-admin/js/*.js', 
     459                    'wp-admin/js/**/*.js', 
    460460                    'wp-includes/js/*.js', 
    461461                    'wp-includes/js/mediaelement/wp-mediaelement.js', 
  • trunk/src/wp-admin/css/customize-widgets.css

    r40569 r40631  
    212212#customize-theme-controls .reordering .widget-reorder-nav { 
    213213    display: block; 
     214} 
     215 
     216/* Text Widget */ 
     217.wp-customizer div.mce-inline-toolbar-grp, 
     218.wp-customizer div.mce-tooltip { 
     219    z-index: 500100 !important; 
     220} 
     221.wp-customizer .ui-autocomplete.wplink-autocomplete { 
     222    z-index: 500110; /* originally 100110, but z-index of .wp-full-overlay is 500000 */ 
     223} 
     224.wp-customizer #wp-link-backdrop { 
     225    z-index: 500100; /* originally 100100, but z-index of .wp-full-overlay is 500000 */ 
     226} 
     227.wp-customizer #wp-link-wrap { 
     228    z-index: 500105; /* originally 100105, but z-index of .wp-full-overlay is 500000 */ 
    214229} 
    215230 
  • trunk/src/wp-includes/default-filters.php

    r40608 r40631  
    165165add_filter( 'wp_sprintf', 'wp_sprintf_l', 10, 2 ); 
    166166 
    167 add_filter( 'widget_text', 'balanceTags' ); 
     167add_filter( 'widget_text',         'balanceTags'          ); 
     168add_filter( 'widget_text_content', 'capital_P_dangit', 11 ); 
     169add_filter( 'widget_text_content', 'wptexturize'          ); 
     170add_filter( 'widget_text_content', 'convert_smilies',  20 ); 
     171add_filter( 'widget_text_content', 'wpautop'              ); 
    168172 
    169173add_filter( 'date_i18n', 'wp_maybe_decline_date' ); 
  • trunk/src/wp-includes/script-loader.php

    r40607 r40631  
    603603 
    604604        $scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), false, 1 ); 
     605        $scripts->add( 'text-widgets', "/wp-admin/js/widgets/text-widgets$suffix.js", array( 'jquery', 'backbone', 'editor', 'wp-util' ) ); 
     606        $scripts->add_inline_script( 'text-widgets', 'wp.textWidgets.init();', 'after' ); 
    605607 
    606608        $scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'wp-backbone', 'wp-a11y' ), false, 1 ); 
  • trunk/src/wp-includes/widgets/class-wp-widget-text.php

    r37489 r40631  
    2929            'customize_selective_refresh' => true, 
    3030        ); 
    31         $control_ops = array( 'width' => 400, 'height' => 350 ); 
     31        $control_ops = array( 
     32            'width' => 400, 
     33            'height' => 350, 
     34        ); 
    3235        parent::__construct( 'text', __( 'Text' ), $widget_ops, $control_ops ); 
     36    } 
     37 
     38    /** 
     39     * Add hooks for enqueueing assets when registering all widget instances of this widget class. 
     40     * 
     41     * @since 4.8.0 
     42     * @access public 
     43     */ 
     44    public function _register() { 
     45 
     46        // Note that the widgets component in the customizer will also do the 'admin_print_scripts-widgets.php' action in WP_Customize_Widgets::print_scripts(). 
     47        add_action( 'admin_print_scripts-widgets.php', array( $this, 'enqueue_admin_scripts' ) ); 
     48 
     49        // Note that the widgets component in the customizer will also do the 'admin_footer-widgets.php' action in WP_Customize_Widgets::print_footer_scripts(). 
     50        add_action( 'admin_footer-widgets.php', array( $this, 'render_control_template_scripts' ) ); 
     51 
     52        parent::_register(); 
    3353    } 
    3454 
     
    6282        $text = apply_filters( 'widget_text', $widget_text, $instance, $this ); 
    6383 
     84        if ( isset( $instance['filter'] ) ) { 
     85            if ( 'content' === $instance['filter'] ) { 
     86 
     87                /** 
     88                 * Filters the content of the Text widget to apply changes expected from the visual (TinyMCE) editor. 
     89                 * 
     90                 * By default a subset of the_content filters are applied, including wpautop and wptexturize. 
     91                 * 
     92                 * @since 4.8.0 
     93                 * 
     94                 * @param string         $widget_text The widget content. 
     95                 * @param array          $instance    Array of settings for the current widget. 
     96                 * @param WP_Widget_Text $this        Current Text widget instance. 
     97                 */ 
     98                $text = apply_filters( 'widget_text_content', $widget_text, $instance, $this ); 
     99 
     100            } elseif ( $instance['filter'] ) { 
     101                $text = wpautop( $text ); // Back-compat for instances prior to 4.8. 
     102            } 
     103        } 
     104 
    64105        echo $args['before_widget']; 
    65106        if ( ! empty( $title ) ) { 
    66107            echo $args['before_title'] . $title . $args['after_title']; 
    67         } ?> 
    68             <div class="textwidget"><?php echo !empty( $instance['filter'] ) ? wpautop( $text ) : $text; ?></div> 
     108        } 
     109 
     110        ?> 
     111            <div class="textwidget"><?php echo $text; ?></div> 
    69112        <?php 
    70113        echo $args['after_widget']; 
     
    90133            $instance['text'] = wp_kses_post( $new_instance['text'] ); 
    91134        } 
    92         $instance['filter'] = ! empty( $new_instance['filter'] ); 
     135 
     136        /* 
     137         * Re-use legacy 'filter' (wpautop) property to now indicate content filters will always apply. 
     138         * Prior to 4.8, this is a boolean value used to indicate whether or not wpautop should be 
     139         * applied. By re-using this property, downgrading WordPress from 4.8 to 4.7 will ensure 
     140         * that the content for Text widgets created with TinyMCE will continue to get wpautop. 
     141         */ 
     142        $instance['filter'] = 'content'; 
     143 
    93144        return $instance; 
    94145    } 
    95146 
    96147    /** 
     148     * Loads the required scripts and styles for the widget control. 
     149     * 
     150     * @since 4.8.0 
     151     * @access public 
     152     */ 
     153    public function enqueue_admin_scripts() { 
     154        wp_enqueue_editor(); 
     155        wp_enqueue_script( 'text-widgets' ); 
     156    } 
     157 
     158    /** 
    97159     * Outputs the Text widget settings form. 
    98160     * 
    99161     * @since 2.8.0 
    100      * @access public 
     162     * @since 4.8.0 Form only contains hidden inputs which are synced with JS template. 
     163     * @access public 
     164     * @see WP_Widget_Visual_Text::render_control_template_scripts() 
    101165     * 
    102166     * @param array $instance Current settings. 
     167     * @return void 
    103168     */ 
    104169    public function form( $instance ) { 
    105         $instance = wp_parse_args( (array) $instance, array( 'title' => '', 'text' => '' ) ); 
    106         $filter = isset( $instance['filter'] ) ? $instance['filter'] : 0; 
    107         $title = sanitize_text_field( $instance['title'] ); 
     170        $instance = wp_parse_args( 
     171            (array) $instance, 
     172            array( 
     173                'title' => '', 
     174                'text' => '', 
     175            ) 
     176        ); 
    108177        ?> 
    109         <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> 
    110         <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /></p> 
    111  
    112         <p><label for="<?php echo $this->get_field_id( 'text' ); ?>"><?php _e( 'Content:' ); ?></label> 
    113         <textarea class="widefat" rows="16" cols="20" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo esc_textarea( $instance['text'] ); ?></textarea></p> 
    114  
    115         <p><input id="<?php echo $this->get_field_id('filter'); ?>" name="<?php echo $this->get_field_name('filter'); ?>" type="checkbox"<?php checked( $filter ); ?> />&nbsp;<label for="<?php echo $this->get_field_id('filter'); ?>"><?php _e('Automatically add paragraphs'); ?></label></p> 
     178        <input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" class="title" type="hidden" value="<?php echo esc_attr( $instance['title'] ); ?>"> 
     179        <input id="<?php echo $this->get_field_id( 'text' ); ?>" name="<?php echo $this->get_field_name( 'text' ); ?>" class="text" type="hidden" value="<?php echo esc_attr( $instance['text'] ); ?>"> 
    116180        <?php 
    117181    } 
     182 
     183    /** 
     184     * Render form template scripts. 
     185     * 
     186     * @since 4.8.0 
     187     * @access public 
     188     */ 
     189    public function render_control_template_scripts() { 
     190        ?> 
     191        <script type="text/html" id="tmpl-widget-text-control-fields"> 
     192            <# var elementIdPrefix = 'el' + String( Math.random() ).replace( /\D/g, '' ) + '_' #> 
     193            <p> 
     194                <label for="{{ elementIdPrefix }}title"><?php esc_html_e( 'Title:' ); ?></label> 
     195                <input id="{{ elementIdPrefix }}title" type="text" class="widefat title"> 
     196            </p> 
     197            <p> 
     198                <label for="{{ elementIdPrefix }}text" class="screen-reader-text"><?php esc_html_e( 'Content:' ); ?></label> 
     199                <textarea id="{{ elementIdPrefix }}text" class="widefat text" style="height: 200px" rows="16" cols="20"></textarea> 
     200            </p> 
     201        </script> 
     202        <?php 
     203    } 
    118204} 
Note: See TracChangeset for help on using the changeset viewer.