Krinkle has uploaded a new change for review. https://gerrit.wikimedia.org/r/322234
Change subject: [WIP] Implement 'peers' feature for loading extra styles-type gadgets ...................................................................... [WIP] Implement 'peers' feature for loading extra styles-type gadgets Ref discussion on T42284. Test plan: * Create gadget A with a .css file only. (Maybe mark as 'hidden') * Create gadget B with .js file, and peers=A. * Verify that enabling B will result in B being loaded as general module, and A being loaded as page style module. Change-Id: Ib6207e72c576ff387ecdba685a063bdfbb828199 --- M GadgetHooks.php M Gadgets_body.php M SpecialGadgets.php M api/ApiQueryGadgets.php M includes/MediaWikiGadgetsDefinitionRepo.php M includes/content/GadgetDefinitionContentHandler.php M includes/content/GadgetDefinitionValidator.php 7 files changed, 61 insertions(+), 7 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Gadgets refs/changes/34/322234/1 diff --git a/GadgetHooks.php b/GadgetHooks.php index 3e3d1b7..90e7f3f 100644 --- a/GadgetHooks.php +++ b/GadgetHooks.php @@ -182,12 +182,31 @@ } catch ( InvalidArgumentException $e ) { continue; } + $peers = []; + foreach ( $gadget->getPeers() as $peerName ) { + try { + $peers[] = $repo->getGadget( $peerName ); + } catch ( InvalidArgumentException $e ) { + // Ignore + // @todo: Emit warning for invalid peer? + } + } if ( $gadget->isEnabled( $user ) && $gadget->isAllowed( $user ) ) { if ( $gadget->hasModule() ) { if ( $gadget->getType() === 'styles' ) { $out->addModuleStyles( Gadget::getModuleName( $gadget->getName() ) ); } elseif ( $gadget->getType() === 'general' ) { $out->addModules( Gadget::getModuleName( $gadget->getName() ) ); + // Load peer modules + foreach ( $peers as $peer ) { + if ( $peer->getType() === 'styles' ) { + $out->addModuleStyles( Gadget::getModuleName( $peer->getName() ) ); + } + // Else if not type=styles: Use dependencies instead. + // Note: No need for recursion as styles modules don't support + // either of 'dependencies' and 'peers'. + // @todo: Emit warning for non-styles peer? + } } else { $out->addModuleStyles( Gadget::getModuleName( $gadget->getName() ) ); $out->addModules( Gadget::getModuleName( $gadget->getName() ) ); diff --git a/Gadgets_body.php b/Gadgets_body.php index 9d80757..2f70504 100644 --- a/Gadgets_body.php +++ b/Gadgets_body.php @@ -26,6 +26,7 @@ private $scripts = array(), $styles = array(), $dependencies = array(), + $peers = array(), $messages = array(), $name, $definition, @@ -45,6 +46,7 @@ case 'scripts': case 'styles': case 'dependencies': + case 'peers': case 'messages': case 'name': case 'definition': @@ -88,6 +90,7 @@ 'scripts' => array_map( $prefixGadgetNs, $data['module']['scripts'] ), 'styles' => array_map( $prefixGadgetNs, $data['module']['styles'] ), 'dependencies' => $data['module']['dependencies'], + 'peers' => $data['module']['peers'], 'messages' => $data['module']['messages'], 'position' => $data['module']['position'], 'type' => $data['module']['type'], @@ -260,6 +263,19 @@ } /** + * Get list of extra modules that should be loaded when this gadget is enabled + * + * Primary use case is to allow a Gadget that includes JavaScript to also load + * a (usually, hidden) styles-type module to be applied to the page. Dependencies + * don't work for this use case as those would not be part of page rendering. + * + * @return Array + */ + public function getPeers() { + return $this->peers; + } + + /** * @return array */ public function getMessages() { diff --git a/SpecialGadgets.php b/SpecialGadgets.php index 1d44f0e..c672d45 100644 --- a/SpecialGadgets.php +++ b/SpecialGadgets.php @@ -28,6 +28,10 @@ } } + private function makeAnchor( $gadgetName ) { + return 'gadget-' . Sanitizer::escapeId( $gadgetName, [ 'noninitial' ] ); + } + /** * Displays form showing the list of installed gadgets */ @@ -79,8 +83,8 @@ * @var $gadget Gadget */ foreach ( $entries as $gadget ) { - $t = Title::makeTitleSafe( NS_MEDIAWIKI, "Gadget-{$gadget->getName()}$langSuffix" ); - + $name = $gadget->getName(); + $t = Title::makeTitleSafe( NS_MEDIAWIKI, "Gadget-{$name}$langSuffix" ); if ( !$t ) { continue; } @@ -93,26 +97,34 @@ array( 'action' => 'edit' ) ); $links[] = Linker::link( - $this->getPageTitle( "export/{$gadget->getName()}" ), + $this->getPageTitle( "export/{$name}" ), $this->msg( 'gadgets-export' )->escaped() ); - $ttext = $this->msg( "gadget-{$gadget->getName()}" )->parse(); + $ttext = $this->msg( "gadget-{$name}" )->parse(); if ( !$listOpen ) { $listOpen = true; $output->addHTML( Xml::openElement( 'ul' ) ); } - $lnk = '  ' . + $actions = '  ' . $this->msg( 'parentheses' )->rawParams( $lang->pipeList( $links ) )->escaped(); - $output->addHTML( Xml::openElement( 'li' ) . - $ttext . $lnk . "<br />" . + $output->addHTML( + Xml::openElement( 'li', [ 'id' => $this->makeAnchor( $name ) ] ) . + $ttext . $actions . "<br />" . $this->msg( 'gadgets-uses' )->escaped() . $this->msg( 'colon-separator' )->escaped() ); $lnk = array(); + foreach ( $gadget->getPeers() as $peer ) { + $lnk[] = Html::element( + 'a', + [ 'href' => '#' . $this->makeAnchor( $peer ) ], + $peer + ); + } foreach ( $gadget->getScriptsAndStyles() as $codePage ) { $t = Title::newFromText( $codePage ); diff --git a/api/ApiQueryGadgets.php b/api/ApiQueryGadgets.php index 383faf0..e97642a 100644 --- a/api/ApiQueryGadgets.php +++ b/api/ApiQueryGadgets.php @@ -156,6 +156,7 @@ 'scripts' => $g->getScripts(), 'styles' => $g->getStyles(), 'dependencies' => $g->getDependencies(), + 'peers' => $g->getPeers(), 'messages' => $g->getMessages(), ) ); @@ -168,6 +169,7 @@ 'scripts' => 'script', 'styles' => 'style', 'dependencies' => 'dependency', + 'peers' => 'peer', 'messages' => 'message', ); diff --git a/includes/MediaWikiGadgetsDefinitionRepo.php b/includes/MediaWikiGadgetsDefinitionRepo.php index dbb3ae8..1a7b476 100644 --- a/includes/MediaWikiGadgetsDefinitionRepo.php +++ b/includes/MediaWikiGadgetsDefinitionRepo.php @@ -199,6 +199,9 @@ case 'dependencies': $info['dependencies'] = $params; break; + case 'peers': + $info['peers'] = $params; + break; case 'rights': $info['requiredRights'] = $params; break; diff --git a/includes/content/GadgetDefinitionContentHandler.php b/includes/content/GadgetDefinitionContentHandler.php index 4ed98de..bb777f7 100644 --- a/includes/content/GadgetDefinitionContentHandler.php +++ b/includes/content/GadgetDefinitionContentHandler.php @@ -55,6 +55,7 @@ 'scripts' => array(), 'styles' => array(), 'dependencies' => array(), + 'peers' => array(), 'messages' => array(), 'position' => 'bottom', 'type' => '', diff --git a/includes/content/GadgetDefinitionValidator.php b/includes/content/GadgetDefinitionValidator.php index 2427070..44804e5 100644 --- a/includes/content/GadgetDefinitionValidator.php +++ b/includes/content/GadgetDefinitionValidator.php @@ -21,6 +21,7 @@ 'module.scripts' => array( 'is_array', 'array', 'is_string', 'string' ), 'module.styles' => array( 'is_array', 'array', 'is_string', 'string' ), 'module.dependencies' => array( 'is_array', 'array', 'is_string', 'string' ), + 'module.peers' => array( 'is_array', 'array', 'is_string', 'string' ), 'module.messages' => array( 'is_array', 'array', 'is_string', 'string' ), 'module.position' => array( 'is_string', 'string' ), 'module.type' => array( 'is_string', 'string' ), -- To view, visit https://gerrit.wikimedia.org/r/322234 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib6207e72c576ff387ecdba685a063bdfbb828199 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Gadgets Gerrit-Branch: master Gerrit-Owner: Krinkle <krinklem...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits