| | 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 | /** |