Make WordPress Core

Ticket #27403: 27403.7.diff

File 27403.7.diff, 10.6 KB (added by sirbrillig, 9 years ago)

Updated patch with before positioned icons

  • 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        fill: #fff;
     32        width: 30px;
     33        height: 30px;
     34        font-size: 18px;
     35        font-family: genericons;
     36        content: '\f411';
     37        z-index: 5;
     38        background-color: #0085ba;
     39        border-radius: 50%;
     40        border: 2px solid #fff;
     41        box-shadow: 0 2px 1px rgba(46,68,83,0.15);
     42        text-align: center;
     43        display: flex;
     44        flex-direction: row;
     45        justify-content: center;
     46        align-items: center;
     47        cursor: pointer;
     48        animation-name: bounce-appear;
     49        animation-delay: 0.8s;
     50        animation-duration: 1s;
     51        animation-fill-mode: both;
     52        animation-duration: .75s;
     53        padding: 0;
     54}
     55
     56.customize-partial-icon svg {
     57        width: 18px;
     58        height: 18px;
     59}
     60
     61@keyframes bounce-appear {
     62        from, 20%, 40%, 60%, 80%, to {
     63                animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
     64        }
     65        0% {
     66                opacity: 0;
     67                transform: scale3d(.3, .3, .3);
     68        }
     69        20% {
     70                transform: scale3d(1.1, 1.1, 1.1);
     71        }
     72        40% {
     73                transform: scale3d(.9, .9, .9);
     74        }
     75        60% {
     76                opacity: 1;
     77                transform: scale3d(1.03, 1.03, 1.03);
     78        }
     79        80% {
     80                transform: scale3d(.97, .97, .97);
     81        }
     82        to {
     83                opacity: 1;
     84                transform: scale3d(1, 1, 1);
     85        }
     86}
  • 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
     55                editIconSource: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="0" fill="none" width="24" height="24"/><g><path d="M13 6l5 5-9.507 9.507c-.686-.686-.69-1.794-.012-2.485l-.002-.003c-.69.676-1.8.673-2.485-.013-.677-.677-.686-1.762-.036-2.455l-.008-.008c-.694.65-1.78.64-2.456-.036L13 6zm7.586-.414l-2.172-2.172c-.78-.78-2.047-.78-2.828 0L14 5l5 5 1.586-1.586c.78-.78.78-2.047 0-2.828zM3 18v3h3c0-1.657-1.343-3-3-3z"/></g></svg>',
     56
    4657                 /**
    4758                 * Constructor.
    4859                 *
     
    8596                        var partial = this;
    8697                        _.each( _.pluck( partial.placements(), 'container' ), function( container ) {
    8798                                $( container ).attr( 'title', self.data.l10n.shiftClickToEdit );
     99                                partial.createEditIconForElement( container );
    88100                        } );
    89101                        $( document ).on( 'click', partial.params.selector, function( e ) {
    90102                                if ( ! e.shiftKey ) {
     
    100112                },
    101113
    102114                /**
     115                 * Create and show the edit icon for this element.
     116                 */
     117                createEditIconForElement: function( element ) {
     118                        var partial = this;
     119                        var $icon = this.createEditIcon();
     120                        var $element = $( element );
     121                        $element.before( $icon );
     122                        partial.positionEditIcon( $element, $icon );
     123                        $icon.on( 'click', function( evt ) {
     124                                partial.showControl();
     125                        } );
     126                        $element.on( 'destroyed', function() {
     127                                $icon.remove();
     128                                partial.editIcon = null;
     129                        } );
     130                        api.selectiveRefresh.bind( 'partial-content-rendered', function( placement ) {
     131                                partial.refreshEditIcon( placement.container );
     132                        } );
     133                        api.selectiveRefresh.bind( 'partial-content-moved', function( placement ) {
     134                                partial.refreshEditIcon( placement.container );
     135                        } );
     136                        api.preview.bind( 'collapse-sidebar', function( collapsed ) {
     137                                return collapsed ? partial.hideEditIcon() : partial.showEditIcon();
     138                        } );
     139                        partial.editIcon = $icon;
     140                        partial.isEditIconVisible = true;
     141                },
     142
     143                toggleEditIcon: function() {
     144                        var partial = this;
     145                        return ( partial.isEditIconVisible ) ? partial.hideEditIcon() : partial.showEditIcon();
     146                },
     147
     148                hideEditIcon: function() {
     149                        var partial = this;
     150                        if ( partial.editIcon && partial.editIcon.style ) {
     151                                partial.isEditIconVisible = false;
     152                                partial.editIcon.style.visibility = 'hidden';
     153                        }
     154                },
     155
     156                showEditIcon: function() {
     157                        var partial = this;
     158                        if ( partial.editIcon && partial.editIcon.style ) {
     159                                partial.isEditIconVisible = true;
     160                                partial.editIcon.style.visibility = 'visible';
     161                        }
     162                },
     163
     164                refreshEditIcon: function( element ) {
     165                        var partial = this;
     166                        if ( ! partial.editIcon ) {
     167                                this.createEditIconForElement( element );
     168                        }
     169                },
     170
     171                positionEditIcon: function( $element, $icon ) {
     172                        var partial = this;
     173                        if ( $element.css( 'position' ) === 'absolute' ) {
     174                                $icon.css( partial.getCalculatedCssForEditIcon( $element ) );
     175                                partial.whenPageChanges( function() {
     176                                        $icon.css( partial.getCalculatedCssForEditIcon( $element ) );
     177                                } );
     178                        }
     179                },
     180
     181                whenPageChanges: function( callback ) {
     182                        var debouncedCallaback = _.debounce( function() {
     183                                // Timeout allows any page animations to finish
     184                                setTimeout( callback, 100 );
     185                        }, 350 );
     186                        // When window is resized
     187                        $( window ).resize( debouncedCallaback );
     188                        // When any customizer setting changes
     189                        api.bind( 'change', debouncedCallaback );
     190                        var $document = $( window.document );
     191                        // After scroll in case there are fixed position elements
     192                        $document.on( 'scroll', debouncedCallaback );
     193                        // After page click (eg: hamburger menus)
     194                        $document.on( 'click', debouncedCallaback );
     195                },
     196
     197                getCalculatedCssForEditIcon: function( $target ) {
     198                        var hiddenIconPos = ( 'rtl' === window.document.dir ) ? { right: -1000, left: 'auto' } : { left: -1000, right: 'auto' };
     199                        if ( ! $target.is( ':visible' ) ) {
     200                                return hiddenIconPos;
     201                        }
     202                        var top = $target.css( 'top' );
     203                        var left = $target.css( 'left' );
     204                        if ( top < 0 ) {
     205                                return hiddenIconPos;
     206                        }
     207                        return { top: top, left: left, right: 'auto' };
     208                },
     209
     210                getIconClassName: function() {
     211                        var partial = this;
     212                        var cleanId = partial.id.replace( /\]/g, '' ).replace( /\[/g, '-' );
     213                        return 'customize-partial-icon-' + cleanId;
     214                },
     215
     216                getIconTitle: function() {
     217                        var l10n = self.data.l10n;
     218                        switch ( this.getType() ) {
     219                                case 'widget':
     220                                        return l10n.clickEditWidget;
     221                                case 'blogname':
     222                                        return l10n.clickEditTitle;
     223                                case 'blogdescription':
     224                                        return l10n.clickEditTitle;
     225                                case 'nav_menu':
     226                                        return l10n.clickEditMenu;
     227                                default:
     228                                        return l10n.clickEditMisc;
     229                        }
     230                },
     231
     232                getType: function() {
     233                        var partial = this;
     234                        var settingId = partial.params.primarySetting || _.first( partial.settings() ) || 'unknown';
     235                        if ( partial.params.type ) {
     236                                return partial.params.type;
     237                        }
     238                        if ( settingId.match( /^nav_menu_instance/ ) ) {
     239                                return 'nav_menu';
     240                        }
     241                        if ( settingId.match( /^widget_/ ) ) {
     242                                return 'widget';
     243                        }
     244                        return settingId;
     245                },
     246
     247                createEditIcon: function() {
     248                        var iconTitle = this.getIconTitle();
     249                        return $( '<button aria-label="' + iconTitle + '" title="' + iconTitle + '" type="button" class="customize-partial-icon ' + this.getIconClassName() + '"/>' );
     250                },
     251
     252                /**
    103253                 * Find all placements for this partial int he document.
    104254                 *
    105255                 * @since 4.5.0
     
    180330                        if ( ! settingId ) {
    181331                                settingId = _.first( partial.settings() );
    182332                        }
     333                        if ( this.getType() === 'nav_menu' ) {
     334                                var menuSlug = partial.params.navMenuArgs.theme_location;
     335                                if ( menuSlug ) {
     336                                        settingId = 'nav_menu_locations[' + menuSlug + ']';
     337                                }
     338                        }
    183339                        api.preview.send( 'focus-control-for-setting', settingId );
    184340                },
    185341