Jdlrobson has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/372186 )
Change subject: WIP: Break the MobileFrontend dependency on Minerva
......................................................................
WIP: Break the MobileFrontend dependency on Minerva
Remaining issues:
* Unknown dependency errors are thrown due to the missing
JS libraries e.g. mobile.watchstar
thus JS based UI components are unusable e.g. search autocomplete,
and edit button
* Language button navigates to a missing special page without
MobileFrontend (see T104660)
Bug: T171000
Change-Id: I89e2e15faabab73b0cba91afc2f2c5e785edef29
---
A includes/MFResourceLoaderParsedMessageModule.php
A includes/MobileUI.php
M includes/skins/SkinMinerva.php
M skin.json
4 files changed, 260 insertions(+), 10 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/skins/MinervaNeue
refs/changes/86/372186/1
diff --git a/includes/MFResourceLoaderParsedMessageModule.php
b/includes/MFResourceLoaderParsedMessageModule.php
new file mode 100644
index 0000000..7e3bcbe
--- /dev/null
+++ b/includes/MFResourceLoaderParsedMessageModule.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * ResourceLoaderModule subclass for mobile
+ * Allows basic parsing of messages without arguments
+ */
+class MFResourceLoaderParsedMessageModule extends ResourceLoaderFileModule {
+ /** @var array Saves a list of messages which have been marked as
needing parsing. */
+ protected $parsedMessages = [];
+ /** @var array Saves a list of message keys used by this module. */
+ protected $messages = [];
+ /** @var array Saves the target for the module (e.g. desktop and
mobile). */
+ protected $targets = [ 'mobile', 'desktop' ];
+ /** @var boolean Whether the module abuses getScript. */
+ protected $hasHackedScriptMode = false;
+
+ /**
+ * Registers core modules and runs registration hooks.
+ * @param $options List of options; if not given or empty, an empty
module will be constructed
+ */
+ public function __construct( $options ) {
+ foreach ( $options as $member => $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/MobileUI.php b/includes/MobileUI.php
new file mode 100644
index 0000000..fe7f204
--- /dev/null
+++ b/includes/MobileUI.php
@@ -0,0 +1,129 @@
+<?php
+
+/**
+ * MobileUI.php
+ */
+
+// FIXME: Use OOUI PHP when available.
+/**
+ * Helper methods for generating parts of the UI.
+ */
+class MobileUI {
+
+ /**
+ * Get CSS classes for icons
+ * @param string $iconName
+ * @param string $iconType element or before
+ * @param string $additionalClassNames additional class names you want
to associate
+ * with the iconed element
+ * @return string class name for use with HTML element
+ */
+ public static function iconClass( $iconName, $iconType = 'element',
$additionalClassNames = '' ) {
+ $base = 'mw-ui-icon';
+ $modifiers = 'mw-ui-icon-' . $iconType;
+ if ( $iconName ) {
+ $modifiers .= ' mw-ui-icon-' . $iconName;
+ }
+ return $base . ' ' . $modifiers . ' ' . $additionalClassNames;
+ }
+
+ /**
+ * Get CSS classes for a mediawiki ui semantic element
+ * @param string $base The base class
+ * @param string $modifier Type of anchor (progressive, constructive,
destructive)
+ * @param string $additionalClassNames additional class names you want
to associate
+ * with the iconed element
+ * @return string class name for use with HTML element
+ */
+ public static function semanticClass( $base, $modifier,
$additionalClassNames = '' ) {
+ $modifier = empty( $modifier ) ? '' : 'mw-ui-' . $modifier;
+ return $base . ' ' . $modifier . ' ' . $additionalClassNames;
+ }
+
+ /**
+ * Get CSS classes for buttons
+ * @param string $modifier Type of button (progressive, constructive,
destructive)
+ * @param string $additionalClassNames additional class names you want
to associate
+ * with the button element
+ * @return string class name for use with HTML element
+ */
+ public static function buttonClass( $modifier = '',
$additionalClassNames = '' ) {
+ return self::semanticClass( 'mw-ui-button', $modifier,
$additionalClassNames );
+ }
+
+ /**
+ * Get CSS classes for anchors
+ * @param string $modifier Type of anchor (progressive, constructive,
destructive)
+ * @param string $additionalClassNames additional class names you want
to associate
+ * with the anchor element
+ * @return string class name for use with HTML element
+ */
+ public static function anchorClass( $modifier = '',
$additionalClassNames = '' ) {
+ return self::semanticClass( 'mw-ui-anchor', $modifier,
$additionalClassNames );
+ }
+
+ /**
+ * Return a message box.
+ * @param string $html of contents of box
+ * @param string $className corresponding to box
+ * @param string $heading (optional)
+ * @return string of html representing a box.
+ */
+ public static function messageBox( $html, $className, $heading = '' ) {
+ $templateParser = new TemplateParser( __DIR__ .
'/../resources/mobile.messageBox/' );
+
+ $templateOptions = [
+ 'className' => $className,
+ 'msg' => $html
+ ];
+ if ( $heading ) {
+ $templateOptions += [
+ 'heading' => $heading,
+ 'hasHeading' => true,
+ ];
+ }
+ return $templateParser->processTemplate( 'MessageBox',
$templateOptions );
+ }
+
+ /**
+ * Return a warning box.
+ * @param string $html of contents of box
+ * @return string of html representing a warning box.
+ */
+ public static function warningBox( $html ) {
+ return self::messageBox( $html, 'warningbox' );
+ }
+
+ /**
+ * Return an error box.
+ * @param string $html of contents of error box
+ * @param string $heading (optional)
+ * @return string of html representing an error box.
+ */
+ public static function errorBox( $html, $heading = '' ) {
+ return self::messageBox( $html, 'errorbox', $heading );
+ }
+
+ /**
+ * Return a success box.
+ * @param string $html of contents of box
+ * @return string of html representing a success box.
+ */
+ public static function successBox( $html ) {
+ return self::messageBox( $html, 'successbox' );
+ }
+
+ /**
+ * Mark some html as being content
+ * @param string $html
+ * @param string $className additional class names
+ * @return string of html
+ */
+ public static function contentElement( $html, $className = '' ) {
+ $templateParser = new TemplateParser( __DIR__ );
+ return $templateParser->processTemplate( 'ContentBox', [
+ 'className' => $className,
+ 'html' => $html,
+ ] );
+ }
+}
diff --git a/includes/skins/SkinMinerva.php b/includes/skins/SkinMinerva.php
index e6d66f4..2435f1d 100644
--- a/includes/skins/SkinMinerva.php
+++ b/includes/skins/SkinMinerva.php
@@ -727,8 +727,6 @@
$isMainPage = $title->isMainPage();
// Get rev_timestamp of current revision (preloaded by
MediaWiki core)
$timestamp = $this->getOutput()->getRevisionTimestamp();
- $mp = new MobilePage( $this->getTitle(), false );
- $mp->setLatestTimestamp( $timestamp );
// Main pages tend to include transclusions (see bug 51924)
if ( $isMainPage ) {
$lastModified = $this->msg( 'mobile-frontend-history'
)->plain();
@@ -746,15 +744,33 @@
$historyUrl = $title->getLocalURL( [ 'action' =>
'history' ] );
}
- $edit = $mp->getLatestEdit();
+ $curId = $title->getLatestRevID();
+ $rev = Revision::newKnownCurrent(
+ wfGetDB( DB_REPLICA ),
+ $title->getArticleID(),
+ $curId
+ );
+ $revUserId = $rev->getUser();
+
$link = [
// Use $edit['timestamp'] (Unix format) instead of
$timestamp (MW format)
- 'data-timestamp' => $isMainPage ? '' :
$edit['timestamp'],
+ 'data-timestamp' => $isMainPage ? '' : wfTimestamp(
TS_UNIX, $rev->getTimestamp() ),
'href' => $historyUrl,
'text' => $lastModified,
- 'data-user-name' => $edit['name'],
- 'data-user-gender' => $edit['gender'],
];
+ if ( $revUserId ) {
+ $revUser = User::newFromId( $revUserId );
+ $link += [
+ 'data-user-name' => $revUser->getName(),
+ 'data-user-gender' => $revUser->getOption(
'gender' ),
+ ];
+ } else {
+ $link += [
+ 'data-user-name' => '',
+ 'data-user-gender' => '',
+ ];
+ }
+
return $link;
}
/**
diff --git a/skin.json b/skin.json
index 4e54d71..1d1fcfe 100644
--- a/skin.json
+++ b/skin.json
@@ -1,5 +1,7 @@
{
"AutoloadClasses": {
+ "MFResourceLoaderParsedMessageModule":
"includes/MFResourceLoaderParsedMessageModule.php",
+ "MobileUI": "includes/MobileUI.php",
"MinervaHooks": "includes/Minerva.hooks.php",
"MinervaTemplate": "includes/skins/MinervaTemplate.php",
"SkinMinerva": "includes/skins/SkinMinerva.php",
@@ -545,10 +547,7 @@
"name": "MinervaNeue",
"namemsg": "skinname-minerva",
"requires": {
- "MediaWiki": ">= 1.25.0",
- "extensions": {
- "MobileFrontend": ">= 2.0.0"
- }
+ "MediaWiki": ">= 1.25.0"
},
"type": "skin",
"url": "https://www.mediawiki.org/wiki/Skin:MinervaNeue",
--
To view, visit https://gerrit.wikimedia.org/r/372186
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I89e2e15faabab73b0cba91afc2f2c5e785edef29
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/skins/MinervaNeue
Gerrit-Branch: master
Gerrit-Owner: Jdlrobson <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits