Make WordPress Core

Changeset 45585


Ignore:
Timestamp:
07/02/2019 01:30:15 AM (5 years ago)
Author:
pento
Message:

Clean up stray <p> tags added by wpautop() inside block level tags.

autop() can sometimes get confused and not clean up stray <p> or </p> tags inside block level elements, which produces sub-optimal HTML. While browsers can generally handle it, there's no need to make things harder for them if we don't have to.

Props pento, ayubi, pbearne, jond, azaozz, 1994rstefan, dionysous, MikeHansenMe, jorbin, miqrogroove, niallkennedy.
Fixes #27350.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/formatting.php

    r45580 r45585  
    493493    $pee = preg_replace( '|<br\s*/?>\s*<br\s*/?>|', "\n\n", $pee );
    494494
    495     $allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)';
     495    $allblocks        = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)\b';
     496    $allblocksexceptp = str_replace( '|p|', '|', $allblocks );
    496497
    497498    // Add a double line break above block-level opening tags.
     
    559560    $pee = preg_replace( '|<p>\s*</p>|', '', $pee );
    560561
     562    // If an opening or closing block element tag is wrapped in a <p>, unwrap it.
     563    $pee = preg_replace( '!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', '$1', $pee );
     564
    561565    // Add a closing <p> inside <div>, <address>, or <form> tag if missing.
    562566    $pee = preg_replace( '!<p>([^<]+)</(div|address|form)>!', '<p>$1</p></$2>', $pee );
    563 
    564     // If an opening or closing block element tag is wrapped in a <p>, unwrap it.
    565     $pee = preg_replace( '!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', '$1', $pee );
    566567
    567568    // In some cases <li> may get wrapped in <p>, fix them.
     
    577578    // If an opening or closing block element tag is followed by a closing <p> tag, remove it.
    578579    $pee = preg_replace( '!(</?' . $allblocks . '[^>]*>)\s*</p>!', '$1', $pee );
     580
     581    // If a closing <p> tag is inside a block element tag, without a preceding opening <p> tag, remove it.
     582    $pee = preg_replace( '#(<(' . $allblocksexceptp . ')[^>]*>)(((?!<p>|</\2>).)*)</p>#s', '$1$3', $pee );
     583
     584    // If an opening <p> tag is inside a block element tag, without a following closing <p> tag, remove it.
     585    $pee = preg_replace( '#<p>(((?!</p>).)*</' . $allblocksexceptp . '>)#s', '$1', $pee );
    579586
    580587    // Optionally insert line breaks.
  • trunk/tests/phpunit/tests/formatting/Autop.php

    r45577 r45585  
    601601        $this->assertEquals( $expected, trim( wpautop( $content ) ) );
    602602    }
     603
     604    /**
     605     * wpautop() should remove stray <p> and </p> tags inside blocks
     606     *
     607     * @ticket 27350
     608     * @dataProvider data_wpautop_removes_stray_p_tags_in_blocks
     609     */
     610    function test_wpautop_removes_stray_p_tags_in_blocks( $data, $expected ) {
     611        $this->assertEquals( $expected, wpautop( $data ) );
     612    }
     613
     614    function data_wpautop_removes_stray_p_tags_in_blocks() {
     615        return array(
     616            array(
     617                '<div><p>123</p> </div>',
     618                "<div>\n<p>123</p>\n</div>\n",
     619            ),
     620            array(
     621                '<div><p>123</p></div>',
     622                "<div>\n<p>123</p>\n</div>\n",
     623            ),
     624            array(
     625                'hello<div>test</div>',
     626                "<p>hello</p>\n<div>test</div>\n",
     627            ),
     628            array(
     629                '<div><p>Hello world</p><span>WordPress</span></div>',
     630                "<div>\n<p>Hello world</p>\n<span>WordPress</span></div>\n",
     631            ),
     632            array(
     633                "<div>hello\n<pre>test</pre>\nworld</div>",
     634                "<div>hello\n<pre>test</pre>\n<p>world</p></div>\n",
     635            ),
     636            array(
     637                'hello<div>test</div>',
     638                "<p>hello</p>\n<div>test</div>\n",
     639            ),
     640            array(
     641                '<div><img src="/wp-content/uploads/example.jpg" alt="something" /><div>Something</div></div>',
     642                "<div><img src=\"/wp-content/uploads/example.jpg\" alt=\"something\" />\n<div>Something</div>\n</div>\n",
     643            ),
     644            array(
     645                '<div><span></span><div></div></div>',
     646                "<div><span></span>\n<div></div>\n</div>\n",
     647            ),
     648            array(
     649                '<div>X<div></div></div>',
     650                "<div>X\n<div></div>\n</div>\n",
     651            ),
     652            array(
     653                "<div><div></div>\n </div>",
     654                "<div>\n<div></div>\n</div>\n",
     655            ),
     656            array(
     657                "[banner]\n<h1>Test</h1>",
     658                "<p>[banner]</p>\n<h1>Test</h1>\n",
     659            ),
     660        );
     661    }
    603662}
Note: See TracChangeset for help on using the changeset viewer.