WordPress.org

Make WordPress Core

Ticket #51086: 51086.6.diff

File 51086.6.diff, 9.0 KB (added by stevegrunwell, 6 months ago)

Refreshed diff, corresponding to v0.2.0 of the polyfill: https://github.com/stevegrunwell/wp-admin-tabbed-settings-pages/releases/tag/v0.2.0

  • Gruntfile.js

     
    269269                                        [ WORKING_DIR + 'wp-admin/js/postbox.js' ]: [ './src/js/_enqueues/admin/postbox.js' ],
    270270                                        [ WORKING_DIR + 'wp-admin/js/revisions.js' ]: [ './src/js/_enqueues/wp/revisions.js' ],
    271271                                        [ WORKING_DIR + 'wp-admin/js/set-post-thumbnail.js' ]: [ './src/js/_enqueues/admin/set-post-thumbnail.js' ],
     272                                        [ WORKING_DIR + 'wp-admin/js/settings-tabs.js' ]: [ './src/js/_enqueues/admin/settings-tabs.js' ],
    272273                                        [ WORKING_DIR + 'wp-admin/js/svg-painter.js' ]: [ './src/js/_enqueues/wp/svg-painter.js' ],
    273274                                        [ WORKING_DIR + 'wp-admin/js/tags-box.js' ]: [ './src/js/_enqueues/admin/tags-box.js' ],
    274275                                        [ WORKING_DIR + 'wp-admin/js/tags-suggest.js' ]: [ './src/js/_enqueues/admin/tags-suggest.js' ],
  • src/js/_enqueues/admin/settings-tabs.js

     
     1/**
     2 * Scripting for WP-Admin Tabs.
     3 *
     4 * @output wp-admin/js/settings-tabs.js
     5 */
     6
     7( function ( window, document ) {
     8        const tabWrapper = document.querySelector( '.nav-tab-wrapper' );
     9        const tabs = tabWrapper.querySelectorAll( '.nav-tab' );
     10        const panels = document.querySelectorAll( 'section[role="tabpanel"]' );
     11
     12        /**
     13         * Set the current tab by its ID.
     14         *
     15         * @param {string} tabId - The ID of the active tab.
     16         */
     17        function setActiveTab( tabId ) {
     18                tabs.forEach( function ( tab ) {
     19                        const current = tab.id === tabId;
     20                        tab.classList.toggle( 'nav-tab-active', current );
     21                        tab.setAttribute( 'aria-selected', current );
     22                } );
     23
     24                panels.forEach( function ( panel ) {
     25                        if ( panel.getAttribute('aria-labelledby') === tabId ) {
     26                                panel.removeAttribute( 'hidden' );
     27                                panel.classList.remove( 'hide-if-js' );
     28                        } else {
     29                                panel.setAttribute( 'hidden', true );
     30                        }
     31                } );
     32        }
     33
     34        /**
     35         * Get the ID of the active tab.
     36         *
     37         * @return {string} The ID of the active tab.
     38         */
     39        function getActiveTab() {
     40                var active = tabWrapper.querySelector('.nav-tab-active') || tabs[0];
     41
     42                return active.id || '';
     43        }
     44
     45        // Return early if there are no tabs on the page.
     46        if ( ! tabs || ! panels ) {
     47                return;
     48        }
     49
     50        // Determine which tab should be selected.
     51        let currentTab = window.location.hash.substr( 1 );
     52        currentTab = currentTab ? 'nav-tab-' + currentTab : tabs[0].getAttribute( 'id' );
     53
     54        // Set the current tab and register the event listeners.
     55        setActiveTab( currentTab );
     56        tabWrapper.addEventListener( 'click', function ( e ) {
     57                if ( 'A' !== e.target.tagName ) {
     58                        return;
     59                }
     60
     61                setActiveTab( e.target.id );
     62        } );
     63
     64        // Listen for other changes to the window hash.
     65        window.addEventListener( 'hashchange', function () {
     66                const id = window.location.hash.substr( 1 );
     67
     68                if ( id !== getActiveTab() ) {
     69                        setActiveTab( 'nav-tab-' + id );
     70                }
     71        } );
     72}( window, document) );
  • src/wp-admin/includes/template.php

    Property changes on: src/js/_enqueues/admin/settings-tabs.js
    ___________________________________________________________________
    Added: svn:eol-style
    ## -0,0 +1 ##
    +native
    \ No newline at end of property
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
    16981698}
    16991699
    17001700/**
     1701 * Render settings sections for a particular page using a tabbed interface.
     1702 *
     1703 * This function operates the same as do_settings_sections() as part of the Settings API.
     1704 *
     1705 * @global array $wp_settings_sections Storage array of all settings sections added to admin pages.
     1706 * @global array $wp_settings_fields   Storage array of settings fields and info about their pages/sections.
     1707 *
     1708 * @param string $page The slug name of the page whose settings sections you want to output.
     1709 */
     1710function do_tabbed_settings_sections( $page ) {
     1711        global $wp_settings_sections, $wp_settings_fields;
     1712
     1713        if ( ! isset( $wp_settings_sections[ $page ] ) ) {
     1714                return;
     1715        }
     1716
     1717        $sections = (array) $wp_settings_sections[ $page ];
     1718
     1719        // If there's only one section, don't bother rendering tabs.
     1720        if ( 1 >= count( $sections ) ) {
     1721                return do_settings_sections( $page );
     1722        }
     1723
     1724        // Render the list of tabs, then each section.
     1725        echo '<nav class="nav-tab-wrapper hide-if-no-js" role="tablist">';
     1726        foreach ( $sections as $section ) {
     1727                printf(
     1728                        '<a href="#%1$s" id="nav-tab-%1$s" class="nav-tab" role="tab">%2$s</a>',
     1729                        esc_attr( $section['id'] ),
     1730                        esc_html( $section['title'] )
     1731                );
     1732        }
     1733        echo '</nav>';
     1734
     1735        foreach ( (array) $wp_settings_sections[ $page ] as $section ) {
     1736                printf( '<section id="tab-%1$s" class="hide-if-js" role="tabpanel" aria-labelledby="nav-tab-%1$s">', esc_attr( $section['id'] ) );
     1737                if ( $section['title'] ) {
     1738                        printf( '<h2 class="tabbed-section-heading">%1$s</h2>%2$s', esc_html( $section['title'] ), PHP_EOL );
     1739                }
     1740
     1741                if ( is_callable( $section['callback'] ) ) {
     1742                        call_user_func( $section['callback'], $section );
     1743                }
     1744
     1745                if ( isset( $wp_settings_fields[ $page ][ $section['id'] ] ) ) {
     1746                        echo '<table class="form-table" role="presentation">';
     1747                        do_settings_fields( $page, $section['id'] );
     1748                        echo '</table>';
     1749                }
     1750                echo '</section>';
     1751        }
     1752
     1753        // Finally, ensure the necessary scripts are enqueued.
     1754        wp_enqueue_script( 'settings-tabs' );
     1755}
     1756
     1757/**
    17011758 * Print out the settings fields for a particular settings section.
    17021759 *
    17031760 * Part of the Settings API. Use this in a settings page to output
  • src/wp-includes/script-loader.php

     
    10791079        // JS-only version of hoverintent (no dependencies).
    10801080        $scripts->add( 'hoverintent-js', '/wp-includes/js/hoverintent-js.min.js', array(), '2.2.1', 1 );
    10811081
     1082        $scripts->add( 'settings-tabs', "/wp-admin/js/settings-tabs$suffix.js", array(), false, 1 );
     1083
    10821084        $scripts->add( 'customize-base', "/wp-includes/js/customize-base$suffix.js", array( 'jquery', 'json2', 'underscore' ), false, 1 );
    10831085        $scripts->add( 'customize-loader', "/wp-includes/js/customize-loader$suffix.js", array( 'customize-base' ), false, 1 );
    10841086        $scripts->add( 'customize-preview', "/wp-includes/js/customize-preview$suffix.js", array( 'wp-a11y', 'customize-base' ), false, 1 );
  • tests/phpunit/tests/admin/includesTemplate.php

     
    33 * @group admin
    44 */
    55class Tests_Admin_includesTemplate extends WP_UnitTestCase {
     6        /**
     7         * Clean up some global settings before each test.
     8         *
     9         * @global $wp_settings_sections
     10         */
     11        public function setUp() {
     12                global $wp_settings_sections;
     13
     14                parent::setUp();
     15
     16                $wp_settings_sections = array();
     17                wp_dequeue_script( 'settings-tabs' );
     18        }
    619
    720        function test_equal() {
    821                $this->assertEquals( ' selected=\'selected\'', selected( 'foo', 'foo', false ) );
     
    244257                );
    245258        }
    246259
     260        /**
     261         * @ticket
     262         * @covers ::do_tabbed_settings_sections()
     263         */
     264        public function test_do_tabbed_settings_sections_with_multiple_sections() {
     265                add_settings_section(
     266                        'tabbed-settings-1',
     267                        'Tabbed settings 1',
     268                        '__return_empty_string',
     269                        'tabbed-settings'
     270                );
     271                add_settings_section(
     272                        'tabbed-setting-2',
     273                        'Tabbed settings 2',
     274                        '__return_empty_string',
     275                        'tabbed-settings'
     276                );
     277
     278                ob_start();
     279                do_tabbed_settings_sections( 'tabbed-settings' );
     280                $output = ob_get_clean();
     281
     282                $this->assertContains( '<nav class="nav-tab-wrapper', $output );
     283                $this->assertContains(
     284                        '<a href="#tabbed-settings-1" id="nav-tab-tabbed-settings-1" class="nav-tab" role="tab">Tabbed settings 1</a>',
     285                        $output
     286                );
     287                $this->assertContains( '<section id="tab-tabbed-settings-1" class="hide-if-js" role="tabpanel"', $output );
     288
     289                $this->assertTrue(
     290                        wp_script_is( 'settings-tabs', 'enqueued' ),
     291                        'The tab script should have been enqueued.'
     292                );
     293        }
     294
     295        /**
     296         * @ticket
     297         * @covers ::do_tabbed_settings_sections()
     298         */
     299        public function test_do_tabbed_settings_sections_with_a_single_section() {
     300                add_settings_section(
     301                        'tabbed-settings-1',
     302                        'Tabbed settings 1',
     303                        '__return_empty_string',
     304                        'tabbed-settings'
     305                );
     306
     307                ob_start();
     308                do_tabbed_settings_sections( 'tabbed-settings' );
     309                $output = ob_get_clean();
     310
     311                $this->assertNotContains( '<nav class="nav-tab-wrapper', $output );
     312                $this->assertNotContains(
     313                        '<a href="#tabbed-settings-1" id="nav-tab-tabbed-settings-1" class="nav-tab" role="tab">Tabbed settings 1</a>',
     314                        $output
     315                );
     316                $this->assertNotContains( '<section id="tab-tabbed-settings-1" class="hide-if-js" role="tabpanel"', $output );
     317
     318                $this->assertFalse(
     319                        wp_script_is( 'settings-tabs', 'enqueued' ),
     320                        'The tab script is unnecessary if content is not being tabbed.'
     321                );
     322        }
    247323}