Make WordPress Core

Ticket #27403: 27403.diff

File 27403.diff, 5.5 KB (added by sirbrillig, 9 years ago)

Basic implementation of direct manipulation icons using partials

  • src/wp-includes/css/customize-preview.css

     
    1010        -webkit-box-shadow: none;
    1111        box-shadow: none;
    1212}
     13
     14.customize-partial-icon {
     15        fill: #fff;
     16        position: absolute;
     17        top: 0;
     18        left: 0;
     19        width: 30px;
     20        height: 30px;
     21        font-size: 18px;
     22        z-index: 5;
     23        background: #0087BE;
     24        border-radius: 50%;
     25        border: 2px solid #fff;
     26        box-shadow: 0 2px 1px rgba(46,68,83,0.15);
     27        text-align: center;
     28        display: flex;
     29        flex-direction: row;
     30        justify-content: center;
     31        align-items: center;
     32        cursor: pointer;
     33        animation-name: bounce-appear;
     34        animation-delay: 0.8s;
     35        animation-duration: 1s;
     36        animation-fill-mode: both;
     37        animation-duration: .75s;
     38}
     39
     40.customize-partial-icon svg {
     41        width: 18px;
     42        height: 18px;
     43}
     44
     45@keyframes bounce-appear {
     46        from, 20%, 40%, 60%, 80%, to {
     47                animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
     48        }
     49        0% {
     50                opacity: 0;
     51                transform: scale3d(.3, .3, .3);
     52        }
     53        20% {
     54                transform: scale3d(1.1, 1.1, 1.1);
     55        }
     56        40% {
     57                transform: scale3d(.9, .9, .9);
     58        }
     59        60% {
     60                opacity: 1;
     61                transform: scale3d(1.03, 1.03, 1.03);
     62        }
     63        80% {
     64                transform: scale3d(.97, .97, .97);
     65        }
     66        to {
     67                opacity: 1;
     68                transform: scale3d(1, 1, 1);
     69        }
     70}
     71Contact GitHub API Training Shop Blog About
  • src/wp-includes/js/customize-selective-refresh.js

     
    8585                        var partial = this;
    8686                        _.each( _.pluck( partial.placements(), 'container' ), function( container ) {
    8787                                $( container ).attr( 'title', self.data.l10n.shiftClickToEdit );
     88                                partial.showEditIconForElement( container );
    8889                        } );
    8990                        $( document ).on( 'click', partial.params.selector, function( e ) {
    9091                                if ( ! e.shiftKey ) {
     
    100101                },
    101102
    102103                /**
     104                 * Create and show the edit icon for this element.
     105                 *
     106                 * Specifically:
     107                 *  - create icon element
     108                 *  - add icon to DOM
     109                 *  - position icon relative to target
     110                 *  - add click handler to icon
     111                 *  - monitor DOM for changes and reposition icon when changed
     112                 *  - monitor DOM for sidebar collapse and hide/show icon
     113                 */
     114                showEditIconForElement: function( element ) {
     115                        var partial = this;
     116                        var $icon = this.createEditIcon();
     117                        $( window.document.body ).append( $icon );
     118                        $icon.on( 'click', partial.showControl.bind( this ) );
     119                        this.positionIcon( element, $icon );
     120                        this.repositionIconWhenDomChanges( element, $icon );
     121                },
     122
     123                positionIcon: function( element, $icon ) {
     124                        var css = this.getCalculatedCssForIcon( $( element ) );
     125                        $icon.css( css );
     126                },
     127
     128                repositionIconWhenDomChanges: function( element, $icon ) {
     129                        var reposition = _.debounce( this.positionIcon.bind( this, element, $icon ), 350 );
     130                        // Reposition after page changes (if browser supports it)
     131                        var page = window.document.querySelector( '#page' );
     132                        if ( page && 'undefined' !== typeof MutationObserver ) {
     133                                var observer = new MutationObserver( reposition );
     134                                observer.observe( page, { attributes: true, childList: true, characterData: true } );
     135                        }
     136                        // Reposition when window is resized
     137                        $( window ).resize( reposition );
     138                        // Reposition when any customizer setting changes
     139                        api.bind( 'change', reposition );
     140                        var $document = $( window.document );
     141                        // Reposition after scroll in case there are fixed position elements
     142                        $document.on( 'scroll', reposition );
     143                        // Reposition after page click (eg: hamburger menus)
     144                        $document.on( 'click', reposition );
     145                        // TODO: reposition in other cases as well
     146                },
     147
     148                getCalculatedCssForIcon: function( $target ) {
     149                        var hiddenIconPos = ( 'rtl' === window.document.dir ) ? { right: -1000, left: 'auto' } : { left: -1000, right: 'auto' };
     150                        if ( ! $target.is( ':visible' ) ) {
     151                                return hiddenIconPos;
     152                        }
     153                        var offset = $target.offset();
     154                        var top = offset.top;
     155                        var left = offset.left;
     156                        if ( top < 0 ) {
     157                                return hiddenIconPos;
     158                        }
     159                        return this.adjustCoordinates( { top: top, left: left, right: 'auto' } );
     160                },
     161
     162                adjustCoordinates: function( coords ) {
     163                        var minWidth = 35;
     164                        // Try to avoid overlapping hamburger menus
     165                        var maxWidth = window.innerWidth - 110;
     166                        if ( coords.left < minWidth ) {
     167                                coords.left = minWidth;
     168                        }
     169                        if ( coords.left >= maxWidth ) {
     170                                coords.left = maxWidth;
     171                        }
     172                        return coords;
     173                },
     174
     175                getIconClassName: function() {
     176                        var partial = this;
     177                        // TODO: simplify the id string to avoid brackets, etc
     178                        return 'customize-partial-icon-' + partial.id;
     179                },
     180
     181                createEditIcon: function() {
     182                        // TODO: get translated text for title/hover text
     183                        var 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>';
     184                        return $( '<div class="customize-partial-icon ' + this.getIconClassName() + '">' + editIconSource + '</div>' );
     185                },
     186
     187                /**
    103188                 * Find all placements for this partial int he document.
    104189                 *
    105190                 * @since 4.5.0