diff --git a/includes/MinervaResourceLoaderParsedMessageModule.php b/includes/MinervaResourceLoaderParsedMessageModule.php new file mode 100644 index 0000000..2cab60b --- /dev/null +++ b/includes/MinervaResourceLoaderParsedMessageModule.php @@ -0,0 +1,107 @@ + $option ) { + switch ( $member ) { + case 'messages': + $this->processMessages( $option ); + $this->hasHackedScriptMode = true; + // Prevent them being reinitialised when parent construct is called. + unset( $options[$member] ); + break; + } + } + + parent::__construct( $options ); + } + + /** + * Process messages which have been marked as needing parsing + * + * @param ResourceLoaderContext $context + * @return string JavaScript code + */ + public function addParsedMessages( ResourceLoaderContext $context ) { + if ( !$this->parsedMessages ) { + return ''; + } + $messages = []; + foreach ( $this->parsedMessages as $key ) { + $messages[ $key ] = $context->msg( $key )->parse(); + } + return Xml::encodeJsCall( 'mw.messages.set', [ $messages ] ); + } + + /** + * Separate messages which have been marked as needing parsing from standard messages + * @param array $messages Array of messages to process + */ + private function processMessages( $messages ) { + foreach ( $messages as $key => $value ) { + if ( is_array( $value ) ) { + foreach ( $value as $directive ) { + if ( $directive == 'parse' ) { + $this->parsedMessages[] = $key; + } + } + } else { + $this->messages[] = $value; + } + } + } + + /** + * Gets all scripts for a given context concatenated together including processed messages + * + * @param ResourceLoaderContext $context Context in which to generate script + * @return string JavaScript code for $context + */ + public function getScript( ResourceLoaderContext $context ) { + $script = parent::getScript( $context ); + return $this->addParsedMessages( $context ) . $script; + } + + /** + * Get the URL or URLs to load for this module's JS in debug mode. + * @param ResourceLoaderContext $context + * @return array list of urls + * @see ResourceLoaderModule::getScriptURLsForDebug + */ + public function getScriptURLsForDebug( ResourceLoaderContext $context ) { + if ( $this->hasHackedScriptMode ) { + $derivative = new DerivativeResourceLoaderContext( $context ); + $derivative->setDebug( true ); + $derivative->setModules( [ $this->getName() ] ); + // @todo FIXME: Make this templates and update + // makeModuleResponse so that it only outputs template code. + // When this is done you can merge with parent array and + // retain file names. + $derivative->setOnly( 'scripts' ); + $rl = $derivative->getResourceLoader(); + $urls = [ + $rl->createLoaderURL( $this->getSource(), $derivative ), + ]; + } else { + $urls = parent::getScriptURLsForDebug( $context ); + } + return $urls; + } +} diff --git a/includes/MinervaUI.php b/includes/MinervaUI.php new file mode 100644 index 0000000..d800514 --- /dev/null +++ b/includes/MinervaUI.php @@ -0,0 +1,53 @@ + MobileUI::iconClass( 'clock-gray', 'before' ), - 'arrowIconClass' => MobileUI::iconClass( + 'clockIconClass' => MinervaUI::iconClass( 'clock-gray', 'before' ), + 'arrowIconClass' => MinervaUI::iconClass( 'arrow-gray', 'element', 'mw-ui-icon-small mf-mw-ui-icon-rotate-anti-clockwise indicator' ), 'isMainPage' => $this->getSkin()->getTitle()->isMainPage(), 'link' => $historyLink['href'], @@ -146,7 +146,7 @@ class MinervaTemplate extends BaseTemplate { * @return string */ protected function getSecondaryActionsHtml() { - $baseClass = MobileUI::buttonClass( '', 'button' ); + $baseClass = MinervaUI::buttonClass( '', 'button' ); $html = Html::openElement( 'div', [ 'class' => 'post-content', 'id' => 'page-secondary-actions' @@ -281,7 +281,7 @@ class MinervaTemplate extends BaseTemplate { // which is problematic in Opera Mini (see T140490) 'searchButton' => Html::rawElement( 'button', [ 'id' => 'searchIcon', - 'class' => MobileUI::iconClass( 'magnifying-glass', 'element' ), + 'class' => MinervaUI::iconClass( 'magnifying-glass', 'element' ), ], wfMessage( 'searchbutton' ) ), 'secondaryButtonData' => $data['secondaryButtonData'], 'mainmenuhtml' => $this->getMainMenuHtml( $data ), diff --git a/includes/skins/SkinMinerva.php b/includes/skins/SkinMinerva.php index 102bef4..2214508 100644 --- a/includes/skins/SkinMinerva.php +++ b/includes/skins/SkinMinerva.php @@ -236,7 +236,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { 'data-section' => $section, // Note visibility of the edit section link button is controlled by .edit-page in ui.less so // we default to enabled even though this may not be true. - 'class' => MobileUI::iconClass( 'edit-enabled', 'element', 'edit-page' ), + 'class' => MinervaUI::iconClass( 'edit-enabled', 'element', 'edit-page' ), ], $message ); $html .= Html::closeElement( 'span' ); return $html; @@ -408,7 +408,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { [ 'returnto' => $currentTitle->getPrefixedText() ] ); $tpl->set( 'secondaryButtonData', [ - 'notificationIconClass' => MobileUI::iconClass( 'notifications' ), + 'notificationIconClass' => MinervaUI::iconClass( 'notifications' ), 'title' => $notificationsMsg, 'url' => $url, 'notificationCount' => $countLabel, @@ -452,7 +452,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { ->addComponent( $this->msg( 'mobile-frontend-main-menu-contributions' )->escaped(), SpecialPage::getTitleFor( 'Contributions', $user->getName() )->getLocalUrl(), - MobileUI::iconClass( 'mf-contributions', 'before' ), + MinervaUI::iconClass( 'mf-contributions', 'before' ), [ 'data-event-name' => 'contributions' ] ); } @@ -490,7 +490,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { 'mobile-frontend-watchlist-purpose', $watchlistQuery ), - MobileUI::iconClass( 'mf-watchlist', 'before' ), + MinervaUI::iconClass( 'mf-watchlist', 'before' ), [ 'data-event-name' => 'watchlist' ] ); } @@ -512,7 +512,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { $this->msg( 'mobile-frontend-main-menu-settings' )->escaped(), SpecialPage::getTitleFor( 'MobileOptions' )-> getLocalUrl( [ 'returnto' => $returnToTitle ] ), - MobileUI::iconClass( 'mf-settings', 'before' ), + MinervaUI::iconClass( 'mf-settings', 'before' ), [ 'data-event-name' => 'settings' ] ); @@ -527,7 +527,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { SpecialPage::getTitleFor( 'Preferences' ), 'prefsnologintext2' ), - MobileUI::iconClass( 'mf-settings', 'before' ), + MinervaUI::iconClass( 'mf-settings', 'before' ), [ 'data-event-name' => 'preferences' ] ); } @@ -613,7 +613,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { ->addComponent( $this->msg( 'mobile-frontend-home-button' )->escaped(), Title::newMainPage()->getLocalUrl(), - MobileUI::iconClass( 'mf-home', 'before' ), + MinervaUI::iconClass( 'mf-home', 'before' ), [ 'data-event-name' => 'home' ] ); @@ -622,7 +622,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { ->addComponent( $this->msg( 'mobile-frontend-random-button' )->escaped(), SpecialPage::getTitleFor( 'Randompage' )->getLocalUrl() . '#/random', - MobileUI::iconClass( 'mf-random', 'before' ), + MinervaUI::iconClass( 'mf-random', 'before' ), [ 'id' => 'randomButton', 'data-event-name' => 'random', @@ -639,7 +639,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { ->addComponent( $this->msg( 'mobile-frontend-main-menu-nearby' )->escaped(), SpecialPage::getTitleFor( 'Nearby' )->getLocalURL(), - MobileUI::iconClass( 'mf-nearby', 'before', 'nearby' ), + MinervaUI::iconClass( 'mf-nearby', 'before', 'nearby' ), [ 'data-event-name' => 'nearby' ] ); } @@ -689,13 +689,13 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { ->addComponent( $username, Title::newFromText( $username, NS_USER )->getLocalUrl(), - MobileUI::iconClass( 'mf-profile', 'before', 'truncated-text primary-action' ), + MinervaUI::iconClass( 'mf-profile', 'before', 'truncated-text primary-action' ), [ 'data-event-name' => 'profile' ] ) ->addComponent( $this->msg( 'mobile-frontend-main-menu-logout' )->escaped(), $url, - MobileUI::iconClass( + MinervaUI::iconClass( 'mf-logout', 'element', 'secondary-action truncated-text' ), [ 'data-event-name' => 'logout' ] ); @@ -711,7 +711,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { ->addComponent( $this->msg( 'mobile-frontend-main-menu-login' )->escaped(), $url, - MobileUI::iconClass( 'mf-anonymous', 'before' ), + MinervaUI::iconClass( 'mf-anonymous', 'before' ), [ 'data-event-name' => 'login' ] ); } @@ -913,7 +913,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { Html::element( 'a', [ 'title' => $this->msg( 'mobile-frontend-main-menu-button-tooltip' ), 'href' => $url, - 'class' => MobileUI::iconClass( 'mainmenu', 'element', 'main-menu-button' ), + 'class' => MinervaUI::iconClass( 'mainmenu', 'element', 'main-menu-button' ), 'id' => 'mw-mf-main-menu-button', ], $this->msg( 'mobile-frontend-main-menu-button-tooltip' ) ) ); @@ -1105,7 +1105,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { 'id' => 'ca-edit', 'text' => '', 'itemtitle' => $this->msg( 'mobile-frontend-pageaction-edit-tooltip' ), - 'class' => MobileUI::iconClass( 'edit-enabled', 'element' ), + 'class' => MinervaUI::iconClass( 'edit-enabled', 'element' ), 'links' => [ 'edit' => [ 'href' => $title->getLocalURL( $editArgs ) @@ -1127,7 +1127,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { $baseResult = [ 'id' => 'ca-watch', // Use blank icon to reserve space for watchstar icon once JS loads - 'class' => MobileUI::iconClass( '', 'element', 'watch-this-article' ), + 'class' => MinervaUI::iconClass( '', 'element', 'watch-this-article' ), 'is_js_only' => true ]; $title = $this->getTitle(); @@ -1170,7 +1170,7 @@ class SkinMinerva extends SkinTemplate implements ICustomizableSkin { return [ 'text' => '', 'itemtitle' => $this->msg( 'mobile-frontend-language-article-heading' ), - 'class' => MobileUI::iconClass( 'language-switcher', 'element', $languageSwitcherClasses ), + 'class' => MinervaUI::iconClass( 'language-switcher', 'element', $languageSwitcherClasses ), 'links' => $languageSwitcherLinks, 'is_js_only' => false ]; diff --git a/skin.json b/skin.json index 319e415..1312f37 100644 --- a/skin.json +++ b/skin.json @@ -1,5 +1,7 @@ { "AutoloadClasses": { + "MinervaResourceLoaderParsedMessageModule": "includes/MinervaResourceLoaderParsedMessageModule.php", + "MinervaUI": "includes/MinervaUI.php", "MinervaHooks": "includes/Minerva.hooks.php", "MinervaTemplate": "includes/skins/MinervaTemplate.php", "SkinMinerva": "includes/skins/SkinMinerva.php", @@ -350,7 +352,7 @@ ] }, "skins.minerva.editor": { - "class": "MFResourceLoaderParsedMessageModule", + "class": "MinervaResourceLoaderParsedMessageModule", "dependencies": [ "mediawiki.util", "mediawiki.router", @@ -426,7 +428,7 @@ ] }, "skins.minerva.toggling": { - "class": "MFResourceLoaderParsedMessageModule", + "class": "MinervaResourceLoaderParsedMessageModule", "dependencies": [ "mobile.toggle", "skins.minerva.icons.images.variants", diff --git a/tests/phpunit/skins/SkinMinervaTest.php b/tests/phpunit/skins/SkinMinervaTest.php index c1f5166..9ce2d91 100644 --- a/tests/phpunit/skins/SkinMinervaTest.php +++ b/tests/phpunit/skins/SkinMinervaTest.php @@ -3,7 +3,7 @@ namespace Tests\MediaWiki\Minerva; use MediaWikiTestCase; -use MobileUI; +use MinervaUI; use MWTimestamp; use OutputPage; use QuickTemplate; @@ -289,7 +289,7 @@ class SkinMinervaTest extends MediaWikiTestCase { $hasUnseen ) { return [ - 'notificationIconClass' => MobileUI::iconClass( 'notifications' ), + 'notificationIconClass' => MinervaUI::iconClass( 'notifications' ), 'title' => $notificationsMsg, 'url' => SpecialPage::getTitleFor( $notificationsTitle ) ->getLocalURL(