Index: trunk/extensions/Gadgets/Gadgets_body.php |
— | — | @@ -11,7 +11,7 @@ |
12 | 12 | * @license GNU General Public Licence 2.0 or later |
13 | 13 | */ |
14 | 14 | |
15 | | -class GadgetHooks { |
| 15 | +class GadgetHooks extends OutputPage { |
16 | 16 | /** |
17 | 17 | * ArticleSaveComplete hook handler. |
18 | 18 | * |
— | — | @@ -123,9 +123,20 @@ |
124 | 124 | |
125 | 125 | foreach ( $gadgets as $g ) { |
126 | 126 | $module = $g->getModule(); |
| 127 | + $scriptsModule = $g->getScriptsModule(); |
| 128 | + $stylesModule = $g->getStylesModule(); |
| 129 | + |
127 | 130 | if ( $module ) { |
128 | 131 | $resourceLoader->register( $g->getModuleName(), $module ); |
129 | 132 | } |
| 133 | + |
| 134 | + if ( $scriptsModule ) { |
| 135 | + $resourceLoader->register( $g->getScriptsModuleName(), $scriptsModule ); |
| 136 | + } |
| 137 | + |
| 138 | + if ( $stylesModule ) { |
| 139 | + $resourceLoader->register( $g->getStylesModuleName(), $stylesModule ); |
| 140 | + } |
130 | 141 | } |
131 | 142 | return true; |
132 | 143 | |
— | — | @@ -150,13 +161,17 @@ |
151 | 162 | $lb->setCaller( __METHOD__ ); |
152 | 163 | $pages = array(); |
153 | 164 | |
| 165 | + $stylesModules = array(); |
154 | 166 | foreach ( $gadgets as $gadget ) { |
155 | 167 | if ( $gadget->isEnabled( $wgUser ) && $gadget->isAllowed( $wgUser ) ) { |
156 | 168 | if ( $gadget->hasModule() ) { |
157 | | - $out->addModuleStyles( $gadget->getModuleName() ); |
158 | 169 | $out->addModules( $gadget->getModuleName() ); |
159 | 170 | } |
160 | 171 | |
| 172 | + if ( $gadget->hasStylesModule() ) { |
| 173 | + $stylesModules[] = $gadget->getStylesModuleName(); |
| 174 | + } |
| 175 | + |
161 | 176 | foreach ( $gadget->getLegacyScripts() as $page ) { |
162 | 177 | $lb->add( NS_MEDIAWIKI, $page ); |
163 | 178 | $pages[] = $page; |
— | — | @@ -164,6 +179,18 @@ |
165 | 180 | } |
166 | 181 | } |
167 | 182 | |
| 183 | + if ( count( $stylesModules ) ) { |
| 184 | + $out->addHeadItem( 'ext.gadget', $out->makeResourceLoaderLink( |
| 185 | + $stylesModules, ResourceLoaderModule::TYPE_STYLES |
| 186 | + ) . Html::inlineScript( |
| 187 | + ResourceLoader::makeLoaderConditionalScript( |
| 188 | + ResourceLoader::makeLoaderStateScript( |
| 189 | + array_fill_keys( $stylesModules, 'ready' ) |
| 190 | + ) |
| 191 | + ) |
| 192 | + ) ); |
| 193 | + } |
| 194 | + |
168 | 195 | $lb->execute( __METHOD__ ); |
169 | 196 | |
170 | 197 | $done = array(); |
— | — | @@ -328,13 +355,27 @@ |
329 | 356 | } |
330 | 357 | |
331 | 358 | /** |
332 | | - * @return String: Name of ResourceLoader module for this gadget |
| 359 | + * @return String: Name of meta ResourceLoader module for this gadget |
333 | 360 | */ |
334 | 361 | public function getModuleName() { |
335 | 362 | return "ext.gadget.{$this->name}"; |
336 | 363 | } |
337 | 364 | |
338 | 365 | /** |
| 366 | + * @return String: Name of scripts ResourceLoader module for this gadget |
| 367 | + */ |
| 368 | + public function getScriptsModuleName() { |
| 369 | + return "ext.gadget.{$this->name}.scripts"; |
| 370 | + } |
| 371 | + |
| 372 | + /** |
| 373 | + * @return String: Name of styles ResourceLoader module for this gadget |
| 374 | + */ |
| 375 | + public function getStylesModuleName() { |
| 376 | + return "ext.gadget.{$this->name}.styles"; |
| 377 | + } |
| 378 | + |
| 379 | + /** |
339 | 380 | * Checks whether this is an instance of an older version of this class deserialized from cache |
340 | 381 | * @return Boolean |
341 | 382 | */ |
— | — | @@ -381,12 +422,24 @@ |
382 | 423 | * @return Boolean: Whether this gadget has resources that can be loaded via ResourceLoader |
383 | 424 | */ |
384 | 425 | public function hasModule() { |
385 | | - return count( $this->styles ) |
386 | | - + ( $this->supportsResourceLoader() ? count( $this->scripts ) : 0 ) |
387 | | - > 0; |
| 426 | + return $this->hasScriptsModule() || $this->hasStylesModule() || count( $this->dependencies ); |
388 | 427 | } |
389 | 428 | |
390 | 429 | /** |
| 430 | + * @return Boolean: Whether this gadget has scripts module to be loaded via ResourceLoader |
| 431 | + */ |
| 432 | + public function hasScriptsModule() { |
| 433 | + return $this->supportsResourceLoader() && ( count( $this->scripts ) > 0 ); |
| 434 | + } |
| 435 | + |
| 436 | + /** |
| 437 | + * @return Boolean: Whether this gadget has styles module to be loaded via ResourceLoader |
| 438 | + */ |
| 439 | + public function hasStylesModule() { |
| 440 | + return count( $this->styles ) > 0; |
| 441 | + } |
| 442 | + |
| 443 | + /** |
391 | 444 | * @return String: Definition for this gadget from MediaWiki:gadgets-definition |
392 | 445 | */ |
393 | 446 | public function getDefinition() { |
— | — | @@ -415,17 +468,43 @@ |
416 | 469 | } |
417 | 470 | |
418 | 471 | /** |
419 | | - * Returns module for ResourceLoader, see getModuleName() for its name. |
420 | | - * If our gadget has no scripts or styles suitable for RL, false will be returned. |
| 472 | + * Returns meta module for ResourceLoader, see getModuleName() for its name. |
| 473 | + * Meta module contains no real data to be loaded but has dependencies of |
| 474 | + * this gadget's scripts and styles module as well as other dependencies. |
| 475 | + * If our gadget has no scripts or styles or dependencies suitable for RL, |
| 476 | + * false will be returned. |
421 | 477 | * @return Mixed: GadgetResourceLoaderModule or false |
422 | 478 | */ |
423 | 479 | public function getModule() { |
424 | | - $pages = array(); |
| 480 | + // Don't omit this. Styles module may be marked as ready with |
| 481 | + // mw.loader.state() without dependencies fully resolved. |
| 482 | + $dependencies = $this->dependencies; |
425 | 483 | |
426 | | - foreach ( $this->styles as $style ) { |
427 | | - $pages['MediaWiki:' . $style] = array( 'type' => 'style' ); |
| 484 | + if ( $this->hasScriptsModule() ) { |
| 485 | + $dependencies[] = $this->getScriptsModuleName(); |
428 | 486 | } |
429 | 487 | |
| 488 | + if ( $this->hasStylesModule() ) { |
| 489 | + $dependencies[] = $this->getStylesModuleName(); |
| 490 | + } |
| 491 | + |
| 492 | + if ( !count( $dependencies ) ) { |
| 493 | + return false; |
| 494 | + } |
| 495 | + |
| 496 | + return new GadgetResourceLoaderModule( array(), $dependencies ); |
| 497 | + } |
| 498 | + |
| 499 | + /** |
| 500 | + * Returns scripts module for ResourceLoader, see getScriptsModuleName() |
| 501 | + * for its name. This module contains all scripts in the gadget if this |
| 502 | + * gadget support ResourceLoader, or false if it doesn't, or there's no |
| 503 | + * script at all. |
| 504 | + * @return Mixed: GadgetResourceLoaderModule or false |
| 505 | + */ |
| 506 | + public function getScriptsModule() { |
| 507 | + $pages = array(); |
| 508 | + |
430 | 509 | if ( $this->supportsResourceLoader() ) { |
431 | 510 | foreach ( $this->scripts as $script ) { |
432 | 511 | $pages['MediaWiki:' . $script] = array( 'type' => 'script' ); |
— | — | @@ -433,13 +512,33 @@ |
434 | 513 | } |
435 | 514 | |
436 | 515 | if ( !count( $pages ) ) { |
437 | | - return null; |
| 516 | + return false; |
438 | 517 | } |
439 | 518 | |
440 | 519 | return new GadgetResourceLoaderModule( $pages, $this->dependencies ); |
441 | 520 | } |
442 | 521 | |
443 | 522 | /** |
| 523 | + * Returns styles module for ResourceLoader, see getStylesModuleName() |
| 524 | + * for its name. This module contains all styles in the gadget, or |
| 525 | + * false if there's no style. |
| 526 | + * @return Mixed: GadgetResourceLoaderModule or false |
| 527 | + */ |
| 528 | + public function getStylesModule() { |
| 529 | + $pages = array(); |
| 530 | + |
| 531 | + foreach ( $this->styles as $style ) { |
| 532 | + $pages['MediaWiki:' . $style] = array( 'type' => 'style' ); |
| 533 | + } |
| 534 | + |
| 535 | + if ( !count( $pages ) ) { |
| 536 | + return false; |
| 537 | + } |
| 538 | + |
| 539 | + return new GadgetResourceLoaderModule( $pages, $this->dependencies ); |
| 540 | + } |
| 541 | + |
| 542 | + /** |
444 | 543 | * Returns list of scripts that don't support ResourceLoader |
445 | 544 | * @return Array |
446 | 545 | */ |