Make WordPress Core

Ticket #27403: 27403.8.diff

File 27403.8.diff, 10.3 KB (added by sirbrillig, 9 years ago)

Updated patch with left-margin position safeguards

  • src/wp-admin/js/customize-controls.js

     
    40394039
    40404040                $( '.collapse-sidebar' ).on( 'click', function() {
    40414041                        api.state( 'paneVisible' ).set( ! api.state( 'paneVisible' ).get() );
     4042                        api.previewer.send( 'collapse-sidebar', ! api.state( 'paneVisible' ).get() );
    40424043                });
    40434044
    40444045                api.state( 'paneVisible' ).bind( function( paneVisible ) {
  • src/wp-includes/class-wp-customize-manager.php

     
    837837                        'nonce' => $this->get_nonces(),
    838838                        'l10n' => array(
    839839                                'shiftClickToEdit' => __( 'Shift-click to edit this element.' ),
     840                                'clickIconToEdit' => __( 'Click to edit' ),
     841                                'clickEditMenu' => __( 'Click to edit this menu.' ),
     842                                'clickEditWidget' => __( 'Click to edit this widget.' ),
     843                                'clickEditTitle' => __( 'Click to edit the site title.' ),
     844                                'clickEditMisc' => __( 'Click to edit this element.' ),
    840845                        ),
    841846                        '_dirty' => array_keys( $this->unsanitized_post_values() ),
    842847                );
  • src/wp-includes/css/customize-preview.css

     
    1010        -webkit-box-shadow: none;
    1111        box-shadow: none;
    1212}
     13
     14.customize-partial-icon {
     15        position: relative;
     16        float: left;
     17        width: 0;
     18        height: 0;
     19        padding: 0;
     20        margin: 0;
     21        border: 0;
     22}
     23
     24.customize-partial-icon:active {
     25        padding: 0;
     26        border: 0;
     27}
     28
     29.customize-partial-icon:before {
     30        position: absolute;
     31        left: -36px;
     32        fill: #fff;
     33        width: 30px;
     34        height: 30px;
     35        font-size: 18px;
     36        font-family: genericons;
     37        content: '\f411';
     38        z-index: 5;
     39        background-color: #0085ba;
     40        border-radius: 50%;
     41        border: 2px solid #fff;
     42        box-shadow: 0 2px 1px rgba(46,68,83,0.15);
     43        text-align: center;
     44        display: flex;
     45        flex-direction: row;
     46        justify-content: center;
     47        align-items: center;
     48        cursor: pointer;
     49        animation-name: bounce-appear;
     50        animation-delay: 0.8s;
     51        animation-duration: 1s;
     52        animation-fill-mode: both;
     53        animation-duration: .75s;
     54        padding: 0;
     55}
     56
     57.page-sidebar-collapsed .customize-partial-icon:before,
     58.customize-partial-icon--hidden:before {
     59        visibility: hidden;
     60}
     61
     62.customize-partial-icon--left-margin:before {
     63        left: 0;
     64}
     65
     66.customize-partial-icon svg {
     67        width: 18px;
     68        height: 18px;
     69}
     70
     71@keyframes bounce-appear {
     72        from, 20%, 40%, 60%, 80%, to {
     73                animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
     74        }
     75        0% {
     76                opacity: 0;
     77                transform: scale3d(.3, .3, .3);
     78        }
     79        20% {
     80                transform: scale3d(1.1, 1.1, 1.1);
     81        }
     82        40% {
     83                transform: scale3d(.9, .9, .9);
     84        }
     85        60% {
     86                opacity: 1;
     87                transform: scale3d(1.03, 1.03, 1.03);
     88        }
     89        80% {
     90                transform: scale3d(.97, .97, .97);
     91        }
     92        to {
     93                opacity: 1;
     94                transform: scale3d(1, 1, 1);
     95        }
     96}
  • src/wp-includes/customize/class-wp-customize-selective-refresh.php

     
    184184                        'renderQueryVar' => self::RENDER_QUERY_VAR,
    185185                        'l10n'           => array(
    186186                                'shiftClickToEdit' => __( 'Shift-click to edit this element.' ),
     187                                'clickEditMenu' => __( 'Click to edit this menu.' ),
     188                                'clickEditWidget' => __( 'Click to edit this widget.' ),
     189                                'clickEditTitle' => __( 'Click to edit the site title.' ),
     190                                'clickEditMisc' => __( 'Click to edit this element.' ),
    187191                                /* translators: %s: document.write() */
    188192                                'badDocumentWrite' => sprintf( __( '%s is forbidden' ), 'document.write()' ),
    189193                        ),
  • src/wp-includes/js/customize-preview-widgets.js

     
    357357                                widgetPartial = new self.WidgetPartial( partialId, {
    358358                                        params: {}
    359359                                } );
    360                                 api.selectiveRefresh.partial.add( widgetPartial.id, widgetPartial );
    361360                        }
    362361
    363362                        // Make sure that there is a container element for the widget in the sidebar, if at least a placeholder.
     
    400399                                wasInserted = true;
    401400                        } );
    402401
     402                        api.selectiveRefresh.partial.add( widgetPartial.id, widgetPartial );
     403
    403404                        if ( wasInserted ) {
    404405                                sidebarPartial.reflowWidgets();
    405406                        }
  • src/wp-includes/js/customize-selective-refresh.js

     
    1919
    2020        _.extend( self, api.Events );
    2121
     22        // Extend jQuery to notice element removal and call the 'destroyed' event
     23        $.event.special.destroyed = {
     24                remove: function( o ) {
     25                        if ( o.handler ) {
     26                                o.handler();
     27                        }
     28                }
     29        };
     30
    2231        /**
    2332         * A Customizer Partial.
    2433         *
     
    4352
    4453                id: null,
    4554
    46                  /**
     55                /**
    4756                 * Constructor.
    4857                 *
    4958                 * @since 4.5.0
     
    8594                        var partial = this;
    8695                        _.each( _.pluck( partial.placements(), 'container' ), function( container ) {
    8796                                $( container ).attr( 'title', self.data.l10n.shiftClickToEdit );
     97                                partial.createEditIconForElement( container );
    8898                        } );
    8999                        $( document ).on( 'click', partial.params.selector, function( e ) {
    90100                                if ( ! e.shiftKey ) {
     
    100110                },
    101111
    102112                /**
     113                 * Create and show the edit icon for this element.
     114                 */
     115                createEditIconForElement: function( element ) {
     116                        var partial = this;
     117                        var $icon = this.createEditIcon();
     118                        var $element = $( element );
     119                        $element.before( $icon );
     120                        partial.positionEditIcon( $element, $icon );
     121                        $icon.on( 'click', function( evt ) {
     122                                partial.showControl();
     123                        } );
     124                        $element.on( 'destroyed', function() {
     125                                $icon.remove();
     126                                partial.editIcon = null;
     127                        } );
     128                        api.selectiveRefresh.bind( 'partial-content-rendered', function( placement ) {
     129                                partial.refreshEditIcon( placement.container );
     130                        } );
     131                        api.selectiveRefresh.bind( 'partial-content-moved', function( placement ) {
     132                                partial.refreshEditIcon( placement.container );
     133                        } );
     134                        // TODO: this should be somewhere global
     135                        api.preview.bind( 'collapse-sidebar', function( collapsed ) {
     136                                $( document.body ).toggleClass( 'page-sidebar-collapsed' );
     137                        } );
     138                        partial.editIcon = $icon;
     139                },
     140
     141                hideEditIcon: function() {
     142                        var partial = this;
     143                        if ( partial.editIcon ) {
     144                                partial.editIcon.addClass( 'customize-partial-icon--hidden' );
     145                        }
     146                },
     147
     148                showEditIcon: function() {
     149                        var partial = this;
     150                        if ( partial.editIcon ) {
     151                                partial.editIcon.removeClass( 'customize-partial-icon--hidden' );
     152                        }
     153                },
     154
     155                refreshEditIcon: function( element ) {
     156                        var partial = this;
     157                        if ( ! partial.editIcon ) {
     158                                this.createEditIconForElement( element );
     159                        }
     160                },
     161
     162                positionEditIcon: function( $element, $icon ) {
     163                        var partial = this;
     164                        if ( $element.css( 'position' ) === 'absolute' ) {
     165                                $icon.css( partial.getCalculatedCssForEditIcon( $element ) );
     166                                partial.whenPageChanges( function() {
     167                                        $icon.css( partial.getCalculatedCssForEditIcon( $element ) );
     168                                } );
     169                        }
     170                        if ( ! $element.is( ':visible' ) || $element.css( 'display' ) === 'none' ) {
     171                                $icon.addClass( 'customize-partial-icon--hidden' );
     172                        }
     173                        var left = $element.offset().left;
     174                        if ( left < 1 ) {
     175                                $icon.addClass( 'customize-partial-icon--left-margin' );
     176                        }
     177                },
     178
     179                whenPageChanges: function( callback ) {
     180                        var debouncedCallaback = _.debounce( function() {
     181                                // Timeout allows any page animations to finish
     182                                setTimeout( callback, 100 );
     183                        }, 350 );
     184                        // When window is resized
     185                        $( window ).resize( debouncedCallaback );
     186                        // When any customizer setting changes
     187                        api.bind( 'change', debouncedCallaback );
     188                        var $document = $( window.document );
     189                        // After scroll in case there are fixed position elements
     190                        $document.on( 'scroll', debouncedCallaback );
     191                        // After page click (eg: hamburger menus)
     192                        $document.on( 'click', debouncedCallaback );
     193                },
     194
     195                getCalculatedCssForEditIcon: function( $target ) {
     196                        var hiddenIconPos = ( 'rtl' === window.document.dir ) ? { right: -1000, left: 'auto' } : { left: -1000, right: 'auto' };
     197                        if ( ! $target.is( ':visible' ) ) {
     198                                return hiddenIconPos;
     199                        }
     200                        var top = $target.css( 'top' );
     201                        var left = $target.css( 'left' );
     202                        return { top: top, left: left, right: 'auto' };
     203                },
     204
     205                getIconClassName: function() {
     206                        var partial = this;
     207                        var cleanId = partial.id.replace( /\]/g, '' ).replace( /\[/g, '-' );
     208                        return 'customize-partial-icon-' + cleanId;
     209                },
     210
     211                getIconTitle: function() {
     212                        var l10n = self.data.l10n;
     213                        switch ( this.getType() ) {
     214                                case 'widget':
     215                                        return l10n.clickEditWidget;
     216                                case 'blogname':
     217                                        return l10n.clickEditTitle;
     218                                case 'blogdescription':
     219                                        return l10n.clickEditTitle;
     220                                case 'nav_menu':
     221                                        return l10n.clickEditMenu;
     222                                default:
     223                                        return l10n.clickEditMisc;
     224                        }
     225                },
     226
     227                getType: function() {
     228                        var partial = this;
     229                        var settingId = partial.params.primarySetting || _.first( partial.settings() ) || 'unknown';
     230                        if ( partial.params.type ) {
     231                                return partial.params.type;
     232                        }
     233                        if ( settingId.match( /^nav_menu_instance/ ) ) {
     234                                return 'nav_menu';
     235                        }
     236                        if ( settingId.match( /^widget_/ ) ) {
     237                                return 'widget';
     238                        }
     239                        return settingId;
     240                },
     241
     242                createEditIcon: function() {
     243                        var iconTitle = this.getIconTitle();
     244                        return $( '<button aria-label="' + iconTitle + '" title="' + iconTitle + '" type="button" class="customize-partial-icon ' + this.getIconClassName() + '"/>' );
     245                },
     246
     247                /**
    103248                 * Find all placements for this partial int he document.
    104249                 *
    105250                 * @since 4.5.0
     
    180325                        if ( ! settingId ) {
    181326                                settingId = _.first( partial.settings() );
    182327                        }
     328                        if ( this.getType() === 'nav_menu' ) {
     329                                var menuSlug = partial.params.navMenuArgs.theme_location;
     330                                if ( menuSlug ) {
     331                                        settingId = 'nav_menu_locations[' + menuSlug + ']';
     332                                }
     333                        }
    183334                        api.preview.send( 'focus-control-for-setting', settingId );
    184335                },
    185336