WordPress.org

Make WordPress Core

Changeset 40631


Ignore:
Timestamp:
05/11/2017 06:54:24 PM (4 years 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.