[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 /** 2 * @file Functionality for the plugin install screens. 3 * 4 * @output wp-admin/js/plugin-install.js 5 */ 6 7 /* global tb_click, tb_remove, tb_position */ 8 9 jQuery( function( $ ) { 10 11 var tbWindow, 12 $iframeBody, 13 $tabbables, 14 $firstTabbable, 15 $lastTabbable, 16 $focusedBefore = $(), 17 $uploadViewToggle = $( '.upload-view-toggle' ), 18 $wrap = $ ( '.wrap' ), 19 $body = $( document.body ); 20 21 window.tb_position = function() { 22 var width = $( window ).width(), 23 H = $( window ).height() - ( ( 792 < width ) ? 60 : 20 ), 24 W = ( 792 < width ) ? 772 : width - 20; 25 26 tbWindow = $( '#TB_window' ); 27 28 if ( tbWindow.length ) { 29 tbWindow.width( W ).height( H ); 30 $( '#TB_iframeContent' ).width( W ).height( H ); 31 tbWindow.css({ 32 'margin-left': '-' + parseInt( ( W / 2 ), 10 ) + 'px' 33 }); 34 if ( typeof document.body.style.maxWidth !== 'undefined' ) { 35 tbWindow.css({ 36 'top': '30px', 37 'margin-top': '0' 38 }); 39 } 40 } 41 42 return $( 'a.thickbox' ).each( function() { 43 var href = $( this ).attr( 'href' ); 44 if ( ! href ) { 45 return; 46 } 47 href = href.replace( /&width=[0-9]+/g, '' ); 48 href = href.replace( /&height=[0-9]+/g, '' ); 49 $(this).attr( 'href', href + '&width=' + W + '&height=' + ( H ) ); 50 }); 51 }; 52 53 $( window ).on( 'resize', function() { 54 tb_position(); 55 }); 56 57 /* 58 * Custom events: when a Thickbox iframe has loaded and when the Thickbox 59 * modal gets removed from the DOM. 60 */ 61 $body 62 .on( 'thickbox:iframe:loaded', tbWindow, function() { 63 /* 64 * Return if it's not the modal with the plugin details iframe. Other 65 * thickbox instances might want to load an iframe with content from 66 * an external domain. Avoid to access the iframe contents when we're 67 * not sure the iframe loads from the same domain. 68 */ 69 if ( ! tbWindow.hasClass( 'plugin-details-modal' ) ) { 70 return; 71 } 72 73 iframeLoaded(); 74 }) 75 .on( 'thickbox:removed', function() { 76 // Set focus back to the element that opened the modal dialog. 77 // Note: IE 8 would need this wrapped in a fake setTimeout `0`. 78 $focusedBefore.trigger( 'focus' ); 79 }); 80 81 function iframeLoaded() { 82 var $iframe = tbWindow.find( '#TB_iframeContent' ); 83 84 // Get the iframe body. 85 $iframeBody = $iframe.contents().find( 'body' ); 86 87 // Get the tabbable elements and handle the keydown event on first load. 88 handleTabbables(); 89 90 // Set initial focus on the "Close" button. 91 $firstTabbable.trigger( 'focus' ); 92 93 /* 94 * When the "Install" button is disabled (e.g. the Plugin is already installed) 95 * then we can't predict where the last focusable element is. We need to get 96 * the tabbable elements and handle the keydown event again and again, 97 * each time the active tab panel changes. 98 */ 99 $( '#plugin-information-tabs a', $iframeBody ).on( 'click', function() { 100 handleTabbables(); 101 }); 102 103 // Close the modal when pressing Escape. 104 $iframeBody.on( 'keydown', function( event ) { 105 if ( 27 !== event.which ) { 106 return; 107 } 108 tb_remove(); 109 }); 110 } 111 112 /* 113 * Get the tabbable elements and detach/attach the keydown event. 114 * Called after the iframe has fully loaded so we have all the elements we need. 115 * Called again each time a Tab gets clicked. 116 * @todo Consider to implement a WordPress general utility for this and don't use jQuery UI. 117 */ 118 function handleTabbables() { 119 var $firstAndLast; 120 // Get all the tabbable elements. 121 $tabbables = $( ':tabbable', $iframeBody ); 122 // Our first tabbable element is always the "Close" button. 123 $firstTabbable = tbWindow.find( '#TB_closeWindowButton' ); 124 // Get the last tabbable element. 125 $lastTabbable = $tabbables.last(); 126 // Make a jQuery collection. 127 $firstAndLast = $firstTabbable.add( $lastTabbable ); 128 // Detach any previously attached keydown event. 129 $firstAndLast.off( 'keydown.wp-plugin-details' ); 130 // Attach again the keydown event on the first and last focusable elements. 131 $firstAndLast.on( 'keydown.wp-plugin-details', function( event ) { 132 constrainTabbing( event ); 133 }); 134 } 135 136 // Constrain tabbing within the plugin modal dialog. 137 function constrainTabbing( event ) { 138 if ( 9 !== event.which ) { 139 return; 140 } 141 142 if ( $lastTabbable[0] === event.target && ! event.shiftKey ) { 143 event.preventDefault(); 144 $firstTabbable.trigger( 'focus' ); 145 } else if ( $firstTabbable[0] === event.target && event.shiftKey ) { 146 event.preventDefault(); 147 $lastTabbable.trigger( 'focus' ); 148 } 149 } 150 151 /* 152 * Open the Plugin details modal. The event is delegated to get also the links 153 * in the plugins search tab, after the Ajax search rebuilds the HTML. It's 154 * delegated on the closest ancestor and not on the body to avoid conflicts 155 * with other handlers, see Trac ticket #43082. 156 */ 157 $( '.wrap' ).on( 'click', '.thickbox.open-plugin-details-modal', function( e ) { 158 // The `data-title` attribute is used only in the Plugin screens. 159 var title = $( this ).data( 'title' ) ? 160 wp.i18n.sprintf( 161 // translators: %s: Plugin name. 162 wp.i18n.__( 'Plugin: %s' ), 163 $( this ).data( 'title' ) 164 ) : 165 wp.i18n.__( 'Plugin details' ); 166 167 e.preventDefault(); 168 e.stopPropagation(); 169 170 // Store the element that has focus before opening the modal dialog, i.e. the control which opens it. 171 $focusedBefore = $( this ); 172 173 tb_click.call(this); 174 175 // Set ARIA role, ARIA label, and add a CSS class. 176 tbWindow 177 .attr({ 178 'role': 'dialog', 179 'aria-label': wp.i18n.__( 'Plugin details' ) 180 }) 181 .addClass( 'plugin-details-modal' ); 182 183 // Set title attribute on the iframe. 184 tbWindow.find( '#TB_iframeContent' ).attr( 'title', title ); 185 }); 186 187 /* Plugin install related JS */ 188 $( '#plugin-information-tabs a' ).on( 'click', function( event ) { 189 var tab = $( this ).attr( 'name' ); 190 event.preventDefault(); 191 192 // Flip the tab. 193 $( '#plugin-information-tabs a.current' ).removeClass( 'current' ); 194 $( this ).addClass( 'current' ); 195 196 // Only show the fyi box in the description section, on smaller screen, 197 // where it's otherwise always displayed at the top. 198 if ( 'description' !== tab && $( window ).width() < 772 ) { 199 $( '#plugin-information-content' ).find( '.fyi' ).hide(); 200 } else { 201 $( '#plugin-information-content' ).find( '.fyi' ).show(); 202 } 203 204 // Flip the content. 205 $( '#section-holder div.section' ).hide(); // Hide 'em all. 206 $( '#section-' + tab ).show(); 207 }); 208 209 /* 210 * When a user presses the "Upload Plugin" button, show the upload form in place 211 * rather than sending them to the devoted upload plugin page. 212 * The `?tab=upload` page still exists for no-js support and for plugins that 213 * might access it directly. When we're in this page, let the link behave 214 * like a link. Otherwise we're in the normal plugin installer pages and the 215 * link should behave like a toggle button. 216 */ 217 if ( ! $wrap.hasClass( 'plugin-install-tab-upload' ) ) { 218 $uploadViewToggle 219 .attr({ 220 role: 'button', 221 'aria-expanded': 'false' 222 }) 223 .on( 'click', function( event ) { 224 event.preventDefault(); 225 $body.toggleClass( 'show-upload-view' ); 226 $uploadViewToggle.attr( 'aria-expanded', $body.hasClass( 'show-upload-view' ) ); 227 }); 228 } 229 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Dec 22 01:00:02 2024 | Cross-referenced by PHPXref 0.7.1 |