WordPress.org

Make WordPress Core

Changeset 41132


Ignore:
Timestamp:
07/24/2017 10:45:55 PM (4 years ago)
Author:
westonruter
Message:

Widgets: Rename Text widget's legacy mode to non-visual mode, restore boolean filter prop, and improve compatibility for widget_text filters applied in Custom HTML widget.

Props westonruter, obenland, timmydcrawford for testing.
Amends [41050].
See #35243, #40951, #40907.
Fixes #41394.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/js/widgets/text-widgets.js

    r41094 r41132  
    369369
    370370        // Bypass using TinyMCE when widget is in legacy mode.
    371         if ( widgetForm.find( '.legacy' ).length > 0 ) {
     371        if ( ! widgetForm.find( '.visual' ).val() ) {
    372372            return;
    373373        }
     
    430430
    431431        // Bypass using TinyMCE when widget is in legacy mode.
    432         if ( widgetForm.find( '.legacy' ).length > 0 ) {
     432        if ( ! widgetForm.find( '.visual' ).val() ) {
    433433            return;
    434434        }
  • trunk/src/wp-includes/widgets/class-wp-widget-custom-html.php

    r41116 r41132  
    6262        $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
    6363
     64        // Prepare instance data that looks like a normal Text widget.
     65        $simulated_text_widget_instance = array_merge( $instance, array(
     66            'text' => isset( $instance['content'] ) ? $instance['content'] : '',
     67            'filter' => false, // Because wpautop is not applied.
     68            'visual' => false, // Because it wasn't created in TinyMCE.
     69        ) );
     70        unset( $simulated_text_widget_instance['content'] ); // Was moved to 'text' prop.
     71
    6472        /** This filter is documented in wp-includes/widgets/class-wp-widget-text.php */
    65         $content = apply_filters( 'widget_text', $instance['content'], $instance, $this );
     73        $content = apply_filters( 'widget_text', $instance['content'], $simulated_text_widget_instance, $this );
    6674
    6775        /**
  • trunk/src/wp-includes/widgets/class-wp-widget-text.php

    r41086 r41132  
    8080    public function is_legacy_instance( $instance ) {
    8181
    82         // If the widget has been updated while in legacy mode, it stays in legacy mode.
    83         if ( ! empty( $instance['legacy'] ) ) {
    84             return true;
    85         }
    86 
    87         // If the widget has been added/updated in 4.8 then filter prop is 'content' and it is no longer legacy.
     82        // Legacy mode when not in visual mode.
     83        if ( isset( $instance['visual'] ) ) {
     84            return ! $instance['visual'];
     85        }
     86
     87        // Or, the widget has been added/updated in 4.8.0 then filter prop is 'content' and it is no longer legacy.
    8888        if ( isset( $instance['filter'] ) && 'content' === $instance['filter'] ) {
    8989            return false;
     
    194194
    195195        $text = ! empty( $instance['text'] ) ? $instance['text'] : '';
    196         $is_visual_text_widget = ( isset( $instance['filter'] ) && 'content' === $instance['filter'] );
     196        $is_visual_text_widget = ( ! empty( $instance['visual'] ) && ! empty( $instance['filter'] ) );
     197
     198        // In 4.8.0 only, visual Text widgets get filter=content, without visual prop; upgrade instance props just-in-time.
     199        if ( ! $is_visual_text_widget ) {
     200            $is_visual_text_widget = ( isset( $instance['filter'] ) && 'content' === $instance['filter'] );
     201        }
     202        if ( $is_visual_text_widget ) {
     203            $instance['filter'] = true;
     204            $instance['visual'] = true;
     205        }
    197206
    198207        /*
     
    222231        $text = apply_filters( 'widget_text', $text, $instance, $this );
    223232
    224         if ( isset( $instance['filter'] ) ) {
    225             if ( 'content' === $instance['filter'] ) {
    226 
    227                 /**
    228                  * Filters the content of the Text widget to apply changes expected from the visual (TinyMCE) editor.
    229                  *
    230                  * By default a subset of the_content filters are applied, including wpautop and wptexturize.
    231                  *
    232                  * @since 4.8.0
    233                  *
    234                  * @param string         $text     The widget content.
    235                  * @param array          $instance Array of settings for the current widget.
    236                  * @param WP_Widget_Text $this     Current Text widget instance.
    237                  */
    238                 $text = apply_filters( 'widget_text_content', $text, $instance, $this );
    239 
    240             } elseif ( $instance['filter'] ) {
    241                 $text = wpautop( $text ); // Back-compat for instances prior to 4.8.
    242             }
     233        if ( $is_visual_text_widget ) {
     234
     235            /**
     236             * Filters the content of the Text widget to apply changes expected from the visual (TinyMCE) editor.
     237             *
     238             * By default a subset of the_content filters are applied, including wpautop and wptexturize.
     239             *
     240             * @since 4.8.0
     241             *
     242             * @param string         $text     The widget content.
     243             * @param array          $instance Array of settings for the current widget.
     244             * @param WP_Widget_Text $this     Current Text widget instance.
     245             */
     246            $text = apply_filters( 'widget_text_content', $text, $instance, $this );
     247
     248        } elseif ( ! empty( $instance['filter'] ) ) {
     249            $text = wpautop( $text ); // Back-compat for instances prior to 4.8.
    243250        }
    244251
     
    272279     */
    273280    public function update( $new_instance, $old_instance ) {
     281        $new_instance = wp_parse_args( $new_instance, array(
     282            'title' => '',
     283            'text' => '',
     284            'filter' => false, // For back-compat.
     285            'visual' => null, // Must be explicitly defined.
     286        ) );
     287
    274288        $instance = $old_instance;
     289
    275290        $instance['title'] = sanitize_text_field( $new_instance['title'] );
    276291        if ( current_user_can( 'unfiltered_html' ) ) {
     
    280295        }
    281296
    282         /*
    283          * If the Text widget is in legacy mode, then a hidden input will indicate this
    284          * and the new content value for the filter prop will by bypassed. Otherwise,
    285          * re-use legacy 'filter' (wpautop) property to now indicate content filters will always apply.
    286          * Prior to 4.8, this is a boolean value used to indicate whether or not wpautop should be
    287          * applied. By re-using this property, downgrading WordPress from 4.8 to 4.7 will ensure
    288          * that the content for Text widgets created with TinyMCE will continue to get wpautop.
    289          */
    290         if ( isset( $new_instance['legacy'] ) || isset( $old_instance['legacy'] ) || ( isset( $new_instance['filter'] ) && 'content' !== $new_instance['filter'] ) ) {
    291             $instance['filter'] = ! empty( $new_instance['filter'] );
    292             $instance['legacy'] = true;
    293         } else {
    294             $instance['filter'] = 'content';
    295             unset( $instance['legacy'] );
     297        $instance['filter'] = ! empty( $new_instance['filter'] );
     298
     299        // Upgrade 4.8.0 format.
     300        if ( isset( $old_instance['filter'] ) && 'content' === $old_instance['filter'] ) {
     301            $instance['visual'] = true;
     302        }
     303        if ( 'content' === $new_instance['filter'] ) {
     304            $instance['visual'] = true;
     305        }
     306
     307        if ( isset( $new_instance['visual'] ) ) {
     308            $instance['visual'] = ! empty( $new_instance['visual'] );
     309        }
     310
     311        // Filter is always true in visual mode.
     312        if ( ! empty( $instance['visual'] ) ) {
     313            $instance['filter'] = true;
    296314        }
    297315
     
    334352            <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'] ); ?>">
    335353            <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'] ); ?>">
     354            <input id="<?php echo $this->get_field_id( 'filter' ); ?>" name="<?php echo $this->get_field_name( 'filter' ); ?>" class="filter" type="hidden" value="on">
     355            <input id="<?php echo $this->get_field_id( 'visual' ); ?>" name="<?php echo $this->get_field_name( 'visual' ); ?>" class="visual" type="hidden" value="on">
    336356        <?php else : ?>
    337             <input name="<?php echo $this->get_field_name( 'legacy' ); ?>" type="hidden" class="legacy" value="true">
     357            <input id="<?php echo $this->get_field_id( 'visual' ); ?>" name="<?php echo $this->get_field_name( 'visual' ); ?>" class="visual" type="hidden" value="">
    338358            <p>
    339359                <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
  • trunk/tests/phpunit/tests/widgets/custom-html-widget.php

    r41118 r41132  
    6060        );
    6161
     62        // Convert Custom HTML widget instance into Text widget instance data.
     63        $text_widget_instance = array_merge( $instance, array(
     64            'text' => $instance['content'],
     65            'filter' => false,
     66            'visual' => false,
     67        ) );
     68        unset( $text_widget_instance['content'] );
     69
    6270        update_option( 'use_balanceTags', 0 );
    6371        add_filter( 'widget_custom_html_content', array( $this, 'filter_widget_custom_html_content' ), 5, 3 );
     
    7684        $this->assertNotContains( '<br>', $output );
    7785        $this->assertNotContains( '</u>', $output );
    78         $this->assertEquals( $instance, $this->widget_text_args[1] );
     86        $this->assertEquals( $text_widget_instance, $this->widget_text_args[1] );
    7987        $this->assertEquals( $instance, $this->widget_custom_html_content_args[1] );
    8088        $this->assertSame( $widget, $this->widget_text_args[2] );
    8189        $this->assertSame( $widget, $this->widget_custom_html_content_args[2] );
    82         remove_filter( 'widget_custom_html_content', array( $this, 'filter_widget_custom_html_content' ), 5, 3 );
     90        remove_filter( 'widget_custom_html_content', array( $this, 'filter_widget_custom_html_content' ), 5 );
    8391        remove_filter( 'widget_text', array( $this, 'filter_widget_text' ), 10 );
    8492
  • trunk/tests/phpunit/tests/widgets/text-widget.php

    r41070 r41132  
    8383            'after_widget'  => "</section>\n",
    8484        );
     85
     86        add_filter( 'widget_text_content', array( $this, 'filter_widget_text_content' ), 5, 3 );
     87        add_filter( 'widget_text', array( $this, 'filter_widget_text' ), 5, 3 );
     88
     89        // Test with filter=false, implicit legacy mode.
     90        $this->widget_text_content_args = null;
     91        ob_start();
    8592        $instance = array(
    8693            'title'  => 'Foo',
     
    8895            'filter' => false,
    8996        );
    90 
    91         add_filter( 'widget_text_content', array( $this, 'filter_widget_text_content' ), 5, 3 );
    92         add_filter( 'widget_text', array( $this, 'filter_widget_text' ), 5, 3 );
    93 
    94         // Test with filter=false.
    95         ob_start();
    9697        $widget->widget( $args, $instance );
    9798        $output = ob_get_clean();
     
    103104        $this->assertNotContains( '[filter:widget_text_content]', $output );
    104105
    105         // Test with filter=true.
    106         $instance['filter'] = true;
     106        // Test with filter=true, implicit legacy mode.
     107        $this->widget_text_content_args = null;
     108        $instance = array(
     109            'title'  => 'Foo',
     110            'text'   => $text,
     111            'filter' => true,
     112        );
    107113        ob_start();
    108114        $widget->widget( $args, $instance );
     
    118124        $this->assertNotContains( '[filter:widget_text_content]', $output );
    119125
    120         // Test with filter=content, the upgraded widget.
    121         $instance['filter'] = 'content';
     126        // Test with filter=content, the upgraded widget, in 4.8.0 only.
     127        $this->widget_text_content_args = null;
     128        $instance = array(
     129            'title'  => 'Foo',
     130            'text'   => $text,
     131            'filter' => 'content',
     132        );
     133        $expected_instance = array_merge( $instance, array(
     134            'filter' => true,
     135            'visual' => true,
     136        ) );
    122137        ob_start();
    123138        $widget->widget( $args, $instance );
     
    126141        $this->assertContains( '<br />', $output );
    127142        $this->assertCount( 3, $this->widget_text_args );
    128         $this->assertEquals( $instance['text'], $this->widget_text_args[0] );
    129         $this->assertEquals( $instance, $this->widget_text_args[1] );
     143        $this->assertEquals( $expected_instance['text'], $this->widget_text_args[0] );
     144        $this->assertEquals( $expected_instance, $this->widget_text_args[1] );
    130145        $this->assertEquals( $widget, $this->widget_text_args[2] );
    131146        $this->assertCount( 3, $this->widget_text_content_args );
    132         $this->assertEquals( $instance['text'] . '[filter:widget_text]', $this->widget_text_content_args[0] );
    133         $this->assertEquals( $instance, $this->widget_text_content_args[1] );
     147        $this->assertEquals( $expected_instance['text'] . '[filter:widget_text]', $this->widget_text_content_args[0] );
     148        $this->assertEquals( $expected_instance, $this->widget_text_content_args[1] );
    134149        $this->assertEquals( $widget, $this->widget_text_content_args[2] );
    135         $this->assertContains( wpautop( $instance['text'] . '[filter:widget_text][filter:widget_text_content]' ), $output );
     150        $this->assertContains( wpautop( $expected_instance['text'] . '[filter:widget_text][filter:widget_text_content]' ), $output );
     151
     152        // Test with filter=true&visual=true, the upgraded widget, in 4.8.1 and above.
     153        $this->widget_text_content_args = null;
     154        $instance = array(
     155            'title'  => 'Foo',
     156            'text'   => $text,
     157            'filter' => true,
     158            'visual' => true,
     159        );
     160        $expected_instance = $instance;
     161        ob_start();
     162        $widget->widget( $args, $instance );
     163        $output = ob_get_clean();
     164        $this->assertContains( '<p>', $output );
     165        $this->assertContains( '<br />', $output );
     166        $this->assertCount( 3, $this->widget_text_args );
     167        $this->assertEquals( $expected_instance['text'], $this->widget_text_args[0] );
     168        $this->assertEquals( $expected_instance, $this->widget_text_args[1] );
     169        $this->assertEquals( $widget, $this->widget_text_args[2] );
     170        $this->assertCount( 3, $this->widget_text_content_args );
     171        $this->assertEquals( $expected_instance['text'] . '[filter:widget_text]', $this->widget_text_content_args[0] );
     172        $this->assertEquals( $expected_instance, $this->widget_text_content_args[1] );
     173        $this->assertEquals( $widget, $this->widget_text_content_args[2] );
     174        $this->assertContains( wpautop( $expected_instance['text'] . '[filter:widget_text][filter:widget_text_content]' ), $output );
     175
     176        // Test with filter=true&visual=true, the upgraded widget, in 4.8.1 and above.
     177        $this->widget_text_content_args = null;
     178        $instance = array(
     179            'title'  => 'Foo',
     180            'text'   => $text,
     181            'filter' => true,
     182            'visual' => false,
     183        );
     184        $expected_instance = $instance;
     185        ob_start();
     186        $widget->widget( $args, $instance );
     187        $output = ob_get_clean();
     188        $this->assertContains( '<p>', $output );
     189        $this->assertContains( '<br />', $output );
     190        $this->assertCount( 3, $this->widget_text_args );
     191        $this->assertEquals( $expected_instance['text'], $this->widget_text_args[0] );
     192        $this->assertEquals( $expected_instance, $this->widget_text_args[1] );
     193        $this->assertEquals( $widget, $this->widget_text_args[2] );
     194        $this->assertNull( $this->widget_text_content_args );
     195        $this->assertContains( wpautop( $expected_instance['text'] . '[filter:widget_text]' ), $output );
     196
     197        // Test with filter=false&visual=false, the upgraded widget, in 4.8.1 and above.
     198        $this->widget_text_content_args = null;
     199        $instance = array(
     200            'title'  => 'Foo',
     201            'text'   => $text,
     202            'filter' => false,
     203            'visual' => false,
     204        );
     205        $expected_instance = $instance;
     206        ob_start();
     207        $widget->widget( $args, $instance );
     208        $output = ob_get_clean();
     209        $this->assertNotContains( '<p>', $output );
     210        $this->assertNotContains( '<br />', $output );
     211        $this->assertCount( 3, $this->widget_text_args );
     212        $this->assertEquals( $expected_instance['text'], $this->widget_text_args[0] );
     213        $this->assertEquals( $expected_instance, $this->widget_text_args[1] );
     214        $this->assertEquals( $widget, $this->widget_text_args[2] );
     215        $this->assertNull( $this->widget_text_content_args );
     216        $this->assertContains( $expected_instance['text'] . '[filter:widget_text]', $output );
    136217    }
    137218
     
    251332
    252333        $instance = array_merge( $base_instance, array(
    253             'legacy' => true,
    254         ) );
    255         $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when legacy prop is present.' );
     334            'visual' => false,
     335        ) );
     336        $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when visual=false prop is present.' );
     337
     338        $instance = array_merge( $base_instance, array(
     339            'visual' => true,
     340        ) );
     341        $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when visual=true prop is present.' );
    256342
    257343        $instance = array_merge( $base_instance, array(
    258344            'filter' => 'content',
    259345        ) );
    260         $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when filter is explicitly content.' );
     346        $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when filter is explicitly content (in WP 4.8.0 only).' );
    261347
    262348        $instance = array_merge( $base_instance, array(
     
    365451            'text' => 'Text',
    366452            'filter' => false,
    367             'legacy' => true,
     453            'visual' => false,
    368454        );
    369455        $this->assertTrue( $widget->is_legacy_instance( $instance ) );
     
    371457        $widget->form( $instance );
    372458        $form = ob_get_clean();
    373         $this->assertContains( 'class="legacy"', $form );
     459        $this->assertContains( 'class="visual" type="hidden" value=""', $form );
     460        $this->assertNotContains( 'class="visual" type="hidden" value="1"', $form );
    374461
    375462        $instance = array(
     
    382469        $widget->form( $instance );
    383470        $form = ob_get_clean();
    384         $this->assertNotContains( 'class="legacy"', $form );
     471        $this->assertContains( 'class="visual" type="hidden" value="1"', $form );
     472        $this->assertNotContains( 'class="visual" type="hidden" value=""', $form );
     473
     474        $instance = array(
     475            'title' => 'Title',
     476            'text' => 'Text',
     477            'filter' => true,
     478        );
     479        $this->assertFalse( $widget->is_legacy_instance( $instance ) );
     480        ob_start();
     481        $widget->form( $instance );
     482        $form = ob_get_clean();
     483        $this->assertContains( 'class="visual" type="hidden" value="1"', $form );
     484        $this->assertNotContains( 'class="visual" type="hidden" value=""', $form );
     485
     486        $instance = array(
     487            'title' => 'Title',
     488            'text' => 'Text',
     489            'filter' => true,
     490            'visual' => true,
     491        );
     492        $this->assertFalse( $widget->is_legacy_instance( $instance ) );
     493        ob_start();
     494        $widget->form( $instance );
     495        $form = ob_get_clean();
     496        $this->assertContains( 'class="visual" type="hidden" value="1"', $form );
     497        $this->assertNotContains( 'class="visual" type="hidden" value=""', $form );
    385498    }
    386499
     
    395508            'title' => "The\nTitle",
    396509            'text'  => "The\n\nText",
    397             'filter' => 'content',
     510            'filter' => true,
     511            'visual' => true,
    398512        );
    399513
     
    402516        ) ) );
    403517
    404         // Should return valid instance in legacy mode since filter=false and there are line breaks.
    405518        $expected = array(
    406519            'title'  => sanitize_text_field( $instance['title'] ),
    407520            'text'   => $instance['text'],
    408             'filter' => 'content',
     521            'filter' => true,
     522            'visual' => true,
    409523        );
    410524        $result = $widget->update( $instance, array() );
     
    412526        $this->assertTrue( ! empty( $expected['filter'] ), 'Expected filter prop to be truthy, to handle case where 4.8 is downgraded to 4.7.' );
    413527
    414         // Make sure KSES is applying as expected.
    415528        add_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ), 10, 2 );
    416529        $this->assertTrue( current_user_can( 'unfiltered_html' ) );
     
    418531        $expected['text'] = $instance['text'];
    419532        $result = $widget->update( $instance, array() );
    420         $this->assertEquals( $expected, $result );
     533        $this->assertEquals( $expected, $result, 'KSES should apply as expected.' );
    421534        remove_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ) );
    422535
     
    426539        $expected['text'] = wp_kses_post( $instance['text'] );
    427540        $result = $widget->update( $instance, array() );
    428         $this->assertEquals( $expected, $result );
     541        $this->assertEquals( $expected, $result, 'KSES should not apply since user can unfiltered_html.' );
    429542        remove_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10 );
    430543    }
     
    438551        $widget = new WP_Widget_Text();
    439552
    440         // Updating a widget with explicit filter=true persists with legacy mode.
     553        // --
    441554        $instance = array(
    442555            'title' => 'Legacy',
    443556            'text' => 'Text',
    444             'filter' => true,
    445         );
    446         $result = $widget->update( $instance, array() );
    447         $expected = array_merge( $instance, array(
    448             'legacy' => true,
    449             'filter' => true,
    450         ) );
    451         $this->assertEquals( $expected, $result );
    452 
    453         // Updating a widget with explicit filter=false persists with legacy mode.
    454         $instance['filter'] = false;
    455         $result = $widget->update( $instance, array() );
    456         $expected = array_merge( $instance, array(
    457             'legacy' => true,
    458             'filter' => false,
    459         ) );
    460         $this->assertEquals( $expected, $result );
    461 
    462         // Updating a widget in legacy form results in filter=false when checkbox not checked.
    463         $instance['filter'] = true;
    464         $result = $widget->update( $instance, array() );
    465         $expected = array_merge( $instance, array(
    466             'legacy' => true,
    467             'filter' => true,
    468         ) );
    469         $this->assertEquals( $expected, $result );
    470 
    471         // Updating a widget that previously had legacy form results in filter persisting.
    472         unset( $instance['legacy'] );
    473         $instance['filter'] = true;
    474         $result = $widget->update( $instance, array(
    475             'legacy' => true,
    476         ) );
    477         $expected = array_merge( $instance, array(
    478             'legacy' => true,
    479             'filter' => true,
    480         ) );
    481         $this->assertEquals( $expected, $result );
     557            'filter' => false,
     558        );
     559        $result = $widget->update( $instance, array() );
     560        $this->assertEquals( $instance, $result, 'Updating a widget without visual prop and explicit filter=false leaves visual prop absent' );
     561
     562        // --
     563        $instance = array(
     564            'title' => 'Legacy',
     565            'text' => 'Text',
     566            'filter' => true,
     567        );
     568        $result = $widget->update( $instance, array() );
     569        $this->assertEquals( $instance, $result, 'Updating a widget without visual prop and explicit filter=true leaves legacy prop absent.' );
     570
     571        // --
     572        $instance = array(
     573            'title' => 'Legacy',
     574            'text' => 'Text',
     575            'visual' => true,
     576        );
     577        $old_instance = array_merge( $instance, array(
     578            'filter' => false,
     579        ) );
     580        $expected = array_merge( $instance, array(
     581            'filter' => true,
     582        ) );
     583        $result = $widget->update( $instance, $old_instance );
     584        $this->assertEquals( $expected, $result, 'Updating a pre-existing widget with visual mode forces filter to be true.' );
     585
     586        // --
     587        $instance = array(
     588            'title' => 'Legacy',
     589            'text' => 'Text',
     590            'filter' => true,
     591        );
     592        $old_instance = array_merge( $instance, array(
     593            'visual' => true,
     594        ) );
     595        $result = $widget->update( $instance, $old_instance );
     596        $expected = array_merge( $instance, array(
     597            'visual' => true,
     598        ) );
     599        $this->assertEquals( $expected, $result, 'Updating a pre-existing visual widget retains visual mode when updated.' );
     600
     601        // --
     602        $instance = array(
     603            'title' => 'Legacy',
     604            'text' => 'Text',
     605        );
     606        $old_instance = array_merge( $instance, array(
     607            'visual' => true,
     608        ) );
     609        $result = $widget->update( $instance, $old_instance );
     610        $expected = array_merge( $instance, array(
     611            'visual' => true,
     612            'filter' => true,
     613        ) );
     614        $this->assertEquals( $expected, $result, 'Updating a pre-existing visual widget retains visual=true and supplies missing filter=true.' );
     615
     616        // --
     617        $instance = array(
     618            'title' => 'Legacy',
     619            'text' => 'Text',
     620            'visual' => true,
     621        );
     622        $expected = array_merge( $instance, array(
     623            'filter' => true,
     624        ) );
     625        $result = $widget->update( $instance, array() );
     626        $this->assertEquals( $expected, $result, 'Updating a widget with explicit visual=true and absent filter prop causes filter to be set to true.' );
     627
     628        // --
     629        $instance = array(
     630            'title' => 'Legacy',
     631            'text' => 'Text',
     632            'visual' => false,
     633        );
     634        $result = $widget->update( $instance, array() );
     635        $expected = array_merge( $instance, array(
     636            'filter' => false,
     637        ) );
     638        $this->assertEquals( $expected, $result, 'Updating a widget in legacy mode results in filter=false as if checkbox not checked.' );
     639
     640        // --
     641        $instance = array(
     642            'title' => 'Title',
     643            'text' => 'Text',
     644            'filter' => false,
     645        );
     646        $old_instance = array_merge( $instance, array(
     647            'visual' => false,
     648            'filter' => true,
     649        ) );
     650        $result = $widget->update( $instance, $old_instance );
     651        $expected = array_merge( $instance, array(
     652            'visual' => false,
     653            'filter' => false,
     654        ) );
     655        $this->assertEquals( $expected, $result, 'Updating a widget that previously had legacy form results in filter allowed to be false.' );
     656
     657        // --
     658        $instance = array(
     659            'title' => 'Title',
     660            'text' => 'Text',
     661            'filter' => 'content',
     662        );
     663        $result = $widget->update( $instance, array() );
     664        $expected = array_merge( $instance, array(
     665            'filter' => true,
     666            'visual' => true,
     667        ) );
     668        $this->assertEquals( $expected, $result, 'Updating a widget that had \'content\' as its filter value persists non-legacy mode. This only existed in WP 4.8.0.' );
     669
     670        // --
     671        $instance = array(
     672            'title' => 'Title',
     673            'text' => 'Text',
     674        );
     675        $old_instance = array_merge( $instance, array(
     676            'filter' => 'content',
     677        ) );
     678        $result = $widget->update( $instance, $old_instance );
     679        $expected = array_merge( $instance, array(
     680            'visual' => true,
     681            'filter' => true,
     682        ) );
     683        $this->assertEquals( $expected, $result, 'Updating a pre-existing widget with the filter=content prop in WP 4.8.0 upgrades to filter=true&visual=true.' );
     684
     685        // --
     686        $instance = array(
     687            'title' => 'Title',
     688            'text' => 'Text',
     689            'filter' => 'content',
     690        );
     691        $result = $widget->update( $instance, array() );
     692        $expected = array_merge( $instance, array(
     693            'filter' => true,
     694            'visual' => true,
     695        ) );
     696        $this->assertEquals( $expected, $result, 'Updating a widget with filter=content (from WP 4.8.0) upgrades to filter=true&visual=true.' );
    482697    }
    483698
Note: See TracChangeset for help on using the changeset viewer.