|
10 | 10 | use MediaWiki\Context\RequestContext; |
11 | 11 | use MediaWiki\Deferred\DeferredUpdates; |
12 | 12 | use MediaWiki\Exception\MWExceptionHandler; |
13 | | -use MediaWiki\Html\Html; |
14 | 13 | use MediaWiki\Output\OutputPage; |
| 14 | +use MediaWiki\ResourceLoader\Context; |
| 15 | +use MediaWiki\ResourceLoader\Module; |
15 | 16 | use Throwable; |
16 | 17 |
|
17 | 18 | trait MWCProfiling { |
@@ -71,6 +72,44 @@ public function logToSpeedscopeService( |
71 | 72 | ?string $requiredParameter = 'forceflame', |
72 | 73 | ?string $publicEndpoint = null |
73 | 74 | ): self { |
| 75 | + // Always register the module, since it's loaded in a separate request |
| 76 | + global $wgResourceModules; |
| 77 | + $wgResourceModules['mwc.speedscopeNotification'] = [ |
| 78 | + 'class' => new class extends Module { |
| 79 | + /** @inheritDoc */ |
| 80 | + public function getScript( Context $context ): string { |
| 81 | + return <<<JS |
| 82 | +$( () => { |
| 83 | + const profileId = mw.config.get( 'speedscopeProfileId' ); |
| 84 | + const endpoint = mw.config.get( 'speedscopeEndpoint' ); |
| 85 | + const speedscopeUrl = new URL( 'https://speedscope.app' ); |
| 86 | + speedscopeUrl.hash = `profileURL=\${endpoint}/profile/\${profileId}`; |
| 87 | + const speedscopeLink = $( '<a>' ) |
| 88 | + .attr( 'href', speedscopeUrl.toString() ) |
| 89 | + .attr( 'target', '_blank' ) |
| 90 | + .text( 'Speedscope' ); |
| 91 | + const jsonLink = $( '<a>' ) |
| 92 | + .attr( 'href', `\${endpoint}/profile/\${profileId}` ) |
| 93 | + .attr( 'target', '_blank' ) |
| 94 | + .text( 'JSON' ); |
| 95 | + const metadataLink = $( '<a>' ) |
| 96 | + .attr( 'href', `\${endpoint}/metadata/\${profileId}` ) |
| 97 | + .attr( 'target', '_blank' ) |
| 98 | + .text( 'Metadata' ); |
| 99 | + mw.notify( |
| 100 | + $( '<div>' ).append( speedscopeLink, ' (', jsonLink, ', ', metadataLink, ')' ), |
| 101 | + { |
| 102 | + autoHide: false, |
| 103 | + title: 'Profile recorded successfully', |
| 104 | + type: 'success' |
| 105 | + } |
| 106 | + ); |
| 107 | +} ); |
| 108 | +JS; |
| 109 | + } |
| 110 | + }, |
| 111 | + ]; |
| 112 | + |
74 | 113 | // phpcs:ignore MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals |
75 | 114 | $forced = $requiredParameter !== null && isset( $_GET[$requiredParameter] ); |
76 | 115 | if ( extension_loaded( 'excimer' ) && ( |
@@ -156,42 +195,11 @@ private function doLogToSpeedscopeService( |
156 | 195 | }; |
157 | 196 | $wgHooks['BeforePageDisplay'][] = static function ( $out, $skin ) use ( $id, $publicEndpoint ) { |
158 | 197 | /** @var OutputPage $out */ |
159 | | - $out->addJsConfigVars( [ 'speedscopeProfileId' => $id ] ); |
160 | | - $endpointJs = Html::encodeJsVar( $publicEndpoint ); |
161 | | - $profileIdJs = Html::encodeJsVar( $id ); |
162 | | - $out->addHTML( Html::rawElement( |
163 | | - 'script', |
164 | | - [], |
165 | | - <<<JS |
166 | | -(function() { |
167 | | - 'use strict'; |
168 | | -
|
169 | | - setTimeout(() => { |
170 | | - const profileId = $profileIdJs; |
171 | | - const endpoint = $endpointJs; |
172 | | - const speedscopeUrl = new URL( 'https://speedscope.app' ); |
173 | | - speedscopeUrl.hash = `profileURL=\${endpoint}/profile/\${profileId}`; |
174 | | - const speedscopeLink = $( '<a>' ) |
175 | | - .attr( 'href', speedscopeUrl.toString() ) |
176 | | - .attr( 'target', '_blank' ) |
177 | | - .text( 'Speedscope' ); |
178 | | - const jsonLink = $( '<a>' ) |
179 | | - .attr( 'href', `\${endpoint}/profile/\${profileId}` ) |
180 | | - .attr( 'target', '_blank' ) |
181 | | - .text( 'JSON' ); |
182 | | - mw.notify( |
183 | | - $( '<div>' ).append( speedscopeLink, ' (', jsonLink, ')' ), |
184 | | - { |
185 | | - autoHide: false, |
186 | | - title: 'Profile recorded successfully', |
187 | | - type: 'success' |
188 | | - } |
189 | | - ); |
190 | | - }, 1000); |
191 | | -
|
192 | | -})(); |
193 | | -JS |
194 | | - ) ); |
| 198 | + $out->addJsConfigVars( [ |
| 199 | + 'speedscopeEndpoint' => $publicEndpoint, |
| 200 | + 'speedscopeProfileId' => $id, |
| 201 | + ] ); |
| 202 | + $out->addModules( 'mwc.speedscopeNotification' ); |
195 | 203 | }; |
196 | 204 | } |
197 | 205 | $wgHooks['ParserBeforeInternalParse'][] = static function ( |
|
0 commit comments