diff --git a/includes/RefreshedTemplate.php b/includes/RefreshedTemplate.php
index 8cb3804..a010461 100644
--- a/includes/RefreshedTemplate.php
+++ b/includes/RefreshedTemplate.php
@@ -1,1437 +1,1385 @@
'',
'citethispage' => '',
'close' => '',
'delete' => '',
'edit' => '',
+ 'ellipsis' => '',
'emailuser' => '',
'feeds' => '',
'history' => '',
'info' => '',
'more' => '',
'move' => '',
'permalink' => '',
'print' => '',
'protect' => '',
'purge' => '',
'recentchangeslinked' => '',
'refreshed-collapsible-collapse' => '',
'refreshed-collapsible-expand' => '',
'refreshed-dropdown-expand' => '',
'refreshed-menu' => '',
'search' => '',
'undelete' => '',
'unprotect' => '',
- 'unwatch' => '',
'upload' => '',
'user-anon' => '',
'user-loggedin' => '',
'userrights' => '',
'viewsource' => '',
- 'watch' => '',
'wikilove' => ''
];
private static $iconListLTR = [
'addsection' => '',
'contributions' => '',
'log' => '',
'nstab' => '',
'refreshed-explore' => '',
'refreshed-submenu-expand' => '',
'report-problem' => '',
'smwbrowserlink' => '',
'talk' => '',
'view' => '',
'whatlinkshere' => ''
];
private static $iconListRTL = [
'addsection' => '',
'contributions' => '',
'log' => '',
'nstab' => '',
'refreshed-explore' => '',
'refreshed-submenu-expand' => '',
'report-problem' => '',
'smwbrowserlink' => '',
'talk' => '',
'view' => '',
'whatlinkshere' => ''
];
/**
* Parses MediaWiki:Refreshed-wiki-dropdown.
* Forked from Games' parseSidebarMenu(), which in turn was forked from
* Monaco's parseSidebarMenu(), but none of these three methods are
* identical.
*
* @param string $messageKey Message name
* @return array
*/
private function parseSiteNavigationMenu( $messageKey ) {
$lines = $this->getLines( $messageKey );
$nodes = [];
$i = 0;
if ( is_array( $lines ) ) {
foreach ( $lines as $line ) {
# ignore empty lines
if ( strlen( $line ) == 0 ) {
continue;
}
$node = $this->parseSiteNavigationItem( $line );
for ( $x = $i; $x >= 0; $x-- ) {
if ( $x == 0 ) {
break;
}
}
$nodes[$i + 1] = $node;
$i++;
}
}
return $nodes;
}
/**
* Helper method for parseSiteNavigationMenu.
* Parse one pipe-separated line from MediaWiki message to an array with
* indexes "wikiName" (string), "logoURL" (string|null),
* "wikiURL" (string|null)
* (This array will eventually be used to construct a link in the site
* dropdown via renderSiteNavigationItems.)
* Each line follows this format of text seperated by pipe symbols:
* name|logo URL|wiki URL.
* Special cases:
* - If no logo URL is provided (name||wiki URL), 'logoURL' => null.
* - If no wiki URL is provided (name|logo URL|badly formed wiki URL, or
* name|logo URL|, or name|logo URL), 'wikiURL' => '#'.
* - Finally if neither is provided (name or name||) then both of the above
* apply.
* @param string $line Line (beginning with a *) from a MediaWiki: message
* @return array attributes for the resulting link
*/
public static function parseSiteNavigationItem( $line ) {
// trim spaces and asterisks from line and split it to maximum three chunks
$line_temp = explode( '|', trim( $line, '* ' ), 3 );
// Likewise we assume the logoURL will be null and the wiki URL will be #,
// but if we find alternatives when parsing, we'll switch to them.
$logoURL = null;
$wikiURL = '#';
$wikiName = $line_temp[0];
// has logo URL if at least 2 chunks and the 2nd isn't empty
if ( count( $line_temp ) >= 2 && $line_temp[1] !== '' ) {
$logoURL = trim( $line_temp[1] );
}
// get link from third chunk if it exists and is a URL
if (
isset( $line_temp[2] ) &&
preg_match( '/^(?:' . wfUrlProtocols() . ')/', $line_temp[2] )
)
{
$wikiURL = $line_temp[2];
}
return [
'wikiName' => $wikiName,
'logoURL' => $logoURL,
'wikiURL' => $wikiURL,
];
}
/**
* @param string $messageKey Name of a MediaWiki: message
* @return array|null Array if $messageKey has been given, otherwise null
*/
private function getMessageAsArray( $messageKey ) {
$messageObj = $this->getSkin()->msg( $messageKey )->inContentLanguage();
if ( !$messageObj->isDisabled() ) {
$lines = explode( "\n", $messageObj->text() );
if ( count( $lines ) > 0 ) {
return $lines;
}
}
return null;
}
/**
* @param string $messageKey Name of a MediaWiki: message
* @return array
*/
private function getLines( $messageKey ) {
$title = Title::newFromText( $messageKey, NS_MEDIAWIKI );
$revision = Revision::newFromTitle( $title );
if ( is_object( $revision ) ) {
$contentText = ContentHandler::getContentText( $revision->getContent() );
if ( trim( $contentText ) != '' ) {
$temp = $this->getMessageAsArray( $messageKey );
if ( count( $temp ) > 0 ) {
wfDebugLog( 'Refreshed', sprintf( 'Get LOCAL %s, which contains %s lines', $messageKey, count( $temp ) ) );
$lines = $temp;
}
}
}
if ( empty( $lines ) ) {
$lines = $this->getMessageAsArray( $messageKey );
// if $lines isn't countable, should log a different debug message that
// does not include count( $lines ) since in PHP 7.2 and beyond, counting
// non-countable objects prompts a warning that will break the page
if ( is_array( $lines ) || $lines instanceof Countable ) {
wfDebugLog( 'Refreshed', sprintf( 'Get %s, which contains %s lines', $messageKey, count( $lines ) ) );
} else {
wfDebugLog( 'Refreshed', sprintf( 'Get %s, which is empty', $messageKey ) );
}
}
return $lines;
}
/**
* Return an inline SVG containing the inputted icon, as a string.
* @param string|null $iconName string or null if no icon
* @return string
*/
private function makeIcon( $iconName ) {
// return null if $iconName isn't a string or is the empty string
if ( !is_string( $iconName ) || $iconName === '' ) {
return '';
}
// Sometimes $iconName may be of the form "nstab-something" if it represents
// an article button (like "user page"). In this case, there are many
// possible suffixes like "-user", "-project", etc. We can't possibly
// predict all those suffixes since some of them may represent namespaces
// that one wiki in particular has defined. As such, we will strip the
// suffix to leave just "nstab" for every namespace. That way article
// buttons always use the same icon.
if ( strpos( $iconName, 'nstab' ) === 0 ) {
$iconName = 'nstab';
}
// Get the icon if it is in the list of all icons.
// If not, get the icon if it is in the list of the LTR/RTL icons
// (depending on the user interface language).
if ( array_key_exists( $iconName, self::$iconListAllDirections ) ) {
return self::$iconListAllDirections[$iconName];
} else {
$languageDirection = $this->getSkin()->getLanguage()->getDir();
if ( $languageDirection === 'ltr' && array_key_exists( $iconName, self::$iconListLTR ) ) {
return self::$iconListLTR[$iconName];
} elseif ( $languageDirection === 'rtl' && array_key_exists( $iconName, self::$iconListRTL ) ) {
return self::$iconListRTL[$iconName];
}
}
return '';
}
/**
* Render an inline SVG containing the inputted icon to the page.
* @param string|null $iconName string or null if no icon
* @return string
*/
private function renderIcon( $iconName ) {
echo $this->makeIcon( $iconName );
}
/**
* Generate a list item using BaseTemplate::makeListItem() that contains the
* inline SVG icon specified by $iconName just before the actual link text,
* assuming $iconName is specified.
* (If the icon name isn't recognized, or the list item or icon HTML can't
* be parsed for whatever reason, the list item is returned without
* adding the icon.)
* @param string $iconName the name of the icon
* @param string $key the "$key" for the standard makeLink/makeListItem
* (see docs)
* @param array $item the "$item" for the standard makeLink/makeListItem
* (see docs)
* @param array $options the "$options" for the standard makeLink/makeListItem
* (see docs); optional
* @return string string representing the list item
*/
private function makeListItemWithIconAtStart( $iconName = '', $key, $item, $options = [] ) {
return $this->makeElementWithIconHelper( 'list item', $iconName, $key, $item, $options, 'start' );
}
/**
* Generate a link using BaseTemplate::makeLink() that contains the
* inline SVG icon specified by $iconName just before the actual link text,
* assuming $iconName is specified.
* (If the icon name isn't recognized, or the link or icon HTML can't
* be parsed for whatever reason, the link is returned without
* adding the icon.)
* @param string $iconName the name of the icon
* @param string $key the "$key" for the standard makeLink/makeListItem
* (see docs)
* @param array $item the "$item" for the standard makeLink/makeListItem
* (see docs)
* @param array $options the "$options" for the standard makeLink/makeListItem
* (see docs); optional
* @return string string representing the link
*/
private function makeLinkWithIconAtStart( $iconName = '', $key, $item, $options = [] ) {
return $this->makeElementWithIconHelper( 'link', $iconName, $key, $item, $options, 'start' );
}
/**
* Generate a list item using BaseTemplate::makeListItem() that contains the
* inline SVG icon specified by $iconName just after the actual link text,
* assuming $iconName is specified.
* (If the icon name isn't recognized, or the list item or icon HTML can't
* be parsed for whatever reason, the list item is returned without
* adding the icon.)
* @param string $iconName the name of the icon
* @param string $key the "$key" for the standard makeLink/makeListItem
* (see docs)
* @param array $item the "$item" for the standard makeLink/makeListItem
* (see docs)
* @param array $options the "$options" for the standard makeLink/makeListItem
* (see docs); optional
* @return string string representing the list item
*/
private function makeListItemWithIconAtEnd( $iconName = '', $key, $item, $options = [] ) {
return $this->makeElementWithIconHelper( 'list item', $iconName, $key, $item, $options, 'end' );
}
/**
* Generate a link using BaseTemplate::makeLink() that contains the
* inline SVG icon specified by $iconName just after the actual link text,
* assuming $iconName is specified.
* (If the icon name isn't recognized, or the link or icon HTML can't
* be parsed for whatever reason, the link is returned without
* adding the icon.)
* @param string $iconName the name of the icon
* @param string $key the "$key" for the standard makeLink/makeListItem
* (see docs)
* @param array $item the "$item" for the standard makeLink/makeListItem
* (see docs)
* @param array $options the "$options" for the standard makeLink/makeListItem
* (see docs); optional
* @return string string representing the link
*/
private function makeLinkWithIconAtEnd( $iconName = '', $key, $item, $options = [] ) {
return $this->makeElementWithIconHelper( 'link', $iconName, $key, $item, $options, 'end' );
}
/**
* Helper method for makeListItemWithIconAtStart, makeLinkWithIconAtStart,
* makeListItemWithIconAtEnd, and makeLinkWithIconAtEnd.
*
* Depending on $mode, generate a) a list item containing a link using
* BaseTemplate::makeListItem() or b) just a link using
* BaseTemplate::makeLink(). Before or after (depending on settings) the
* actual link text, there is the inline SVG icon specified by $iconName,
* assuming $iconName is specified. (If the icon name isn't recognized, or the=
* list item/link or icon HTML can't be parsed for whatever reason, the list
* item/link is returned without adding the icon.)
* @param string $mode Expects either 'list item' or 'link'
* @param string $iconName the name of the icon
* @param string $key the "$key" for the standard makeLink/makeListItem
* (see docs)
* @param array $item the "$item" for the standard makeLink/makeListItem
* (see docs)
* @param array $options the "$options" for the standard makeLink/makeListItem
* (see docs); optional
* @param string $iconPosition where to put the icon within the list item or
* link; expects either 'start' or 'end'
* @return string string representing the list item/link
*/
private function makeElementWithIconHelper( $mode, $iconName, $key, $item, $options, $iconPosition ) {
// Based on the $mode, either make a list item or link without any icon
// added yet.
if ( $mode === 'list item' ) {
$outputUnedited = $this->makeListItem( $key, $item, $options );
} elseif ( $mode === 'link' ) {
$outputUnedited = $this->makeLink( $key, $item, $options );
}
// Get the HTML of the icon we want to add (returns empty string if no icon)
$icon = $this->makeIcon( $iconName );
// if there is no icon to add, don't bother doing more processing; just
// return the list item/link without the icon
if ( $icon === '' ) {
return $outputUnedited;
}
// Now we know there actually is an icon we want to insert. We want to find
// where it belongs. To do this, we will parse the HTML of the list item/
// link.
// (As of MW 1.31) BaseTemplate::makeListItem and BaseTemplate::makeLink
// allow angle brackets in attributes. In case this (or something else)
// breaks the HTML parser, rather than deal with the breaking, we will just
// not add images/icons in that case.
// (two separate DOMs: one for the list item/link, one for the icon)
$listItemOrLinkDOM = $this->loadHTMLHandleErrors( $outputUnedited );
$iconDOM = $this->loadHTMLHandleErrors( $icon );
if ( !$listItemOrLinkDOM || !$iconDOM ) {
return $outputUnedited;
}
// otherwise insert the icon into our list item/link
// (read variable names for explanation of what's going on below)
$xpath = new DOMXPath( $listItemOrLinkDOM );
// Find the first a tag in the link. We know such a tag exists because one
// is produced by makeListItem or makeLink, which we haven't modified.
$firstATagInListItemOrLink = $xpath->query( '(//a)[1]' )->item( 0 );
// Find the first/last child of the first a tag from the last line. Note
// this may not exist (if a tag is empty), in which case it's null.
if ( $iconPosition === 'start' ) {
$firstATagChild = $firstATagInListItemOrLink->firstChild;
} elseif ( $iconPosition === 'end' ) {
$firstATagChild = $firstATagInListItemOrLink->lastChild;
}
$iconInIconDOM = $iconDOM->documentElement;
// Currently the icon is in the iconDOM. We have to put a copy of it in
// $listItemOrLinkDOM so we can add the icon to the list item/link
$iconInListItemOrLinkDOM = $listItemOrLinkDOM->importNode( $iconInIconDOM, true );
// add the icon to the very beginning/end of the first a tag depending on
// config settings
if ( $firstATagChild === null ) {
$firstATagInListItemOrLink->appendChild( $iconInListItemOrLinkDOM );
} else {
if ( $iconPosition === 'start' ) {
$firstATagInListItemOrLink->insertBefore( $iconInListItemOrLinkDOM, $firstATagChild );
} elseif ( $iconPosition === 'end' ) {
$firstATagInListItemOrLink->appendChild( $iconInListItemOrLinkDOM );
}
}
return $listItemOrLinkDOM->saveHTML();
}
/**
* Helper method for makeElementWithIconHelper.
* Given $text, load it into a DOMDocument as HTML. If all goes as planned
* (the input doesn't break the parser), return the resulting DOMDocument.
* Otherwise, echo errors and return false.
* @param string $text the text to interpret as HTML (shouldn't contain html
* or body tags)
* @return DOMDocument|bool DOMDocument if no errors, otherwise false
*/
private function loadHTMLHandleErrors( $text ) {
// error handling per https://secure.php.net/manual/en/simplexml.examples-errors.php
$doc = new DOMDocument();
// config doesn't include doctype, html, or body tags per
// https://stackoverflow.com/a/22490902
$html = $doc->loadHTML( $text, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
if ( $html === false ) {
foreach ( libxml_get_errors() as $error ) {
echo "\n", $error->message;
}
return false;
}
return $doc;
}
/**
* Return the user's avatar element as a string (if using SocialProfile).
* Otherwise, return the appropriate placeholder element as a string.
* @param User $user
* @return string
*/
private function makeAvatar( $user ) {
// if using SocialProfile (logged in or not), return SocialProfile avatar
if ( class_exists( 'wAvatar' ) ) {
$avatar = new wAvatar( $user->getId(), 'l' );
return $avatar->makeAvatarURL( [
'class' => 'avatar avatar-image'
] );
} elseif ( $this->data['loggedin'] ) { // if no SocialProfile and user is logged in...
// if wiki has not set custom image for logged in users...
if ( $this->getMsg( 'refreshed-icon-logged-in' )->isDisabled() ) {
return $this->makeIcon( 'user-loggedin' );
} else { // if wiki has set custom image for logged in users...
return Html::element( 'img', [
'src' => $this->getMsg( 'refreshed-icon-logged-in' )->escaped(),
'class' => 'avatar avatar-no-socialprofile avatar-image'
] );
}
} else { // if no SocialProfile and user is not logged in...
// if wiki has not set a custom image for logged out users
if ( $this->getMsg( 'refreshed-icon-logged-out' )->isDisabled() ) {
return $this->makeIcon( 'user-anon' );
} else { // if wiki has set custom image for logged out users
return Html::element( 'img', [
'src' => $this->getMsg( 'refreshed-icon-logged-out' )->escaped(),
'class' => 'avatar avatar-no-socialprofile avatar-image'
] );
}
}
}
/**
* Get the username text (string) to be displayed in the header.
* @param User $user
* @return string
*/
private function makeUsernameText( $user ) {
// if logged in...
if ( $this->data['loggedin'] ) {
return $user->getName();
}
// if not logged in...
return $this->getMsg( 'login' )->text();
}
/**
* Get the personal tools and rearrange them into "dropdown" and "extra"
* tools. The "dropdown" tools are the ones that should go into the user info
* dropdown, and the "extra" tools (like Echo ones) are ones that should be
* placed next to the user dropdown.
* Inspired by and partially adapted from the Timeless skin's getUserLinks
* function.
* @return array $rearrangedPersonalTools where the key "dropdown" contains
* the dropdown tools, and the key "extra" contains the extra tools.
*/
private function getAndRearrangePersonalTools() {
$dropdownTools = $this->getPersonalTools();
$extraTools = [];
// list of tool names that should be removed from the dropdown tools and be
// added to the extra tools
// (these tools are echo badges)
$toolsToMove = [ 'notifications-alert', 'notifications-notice' ];
foreach ( $toolsToMove as $currentToolToMove ) {
if ( isset( $dropdownTools[$currentToolToMove] ) ) {
$extraTools[$currentToolToMove] = $dropdownTools[$currentToolToMove];
unset( $dropdownTools[$currentToolToMove] );
}
}
return [ 'dropdown' => $dropdownTools, 'extra' => $extraTools ];
}
/**
* Render the list items to be displayed next to the user dropdown
* (e.g., for Echo).
* Inspired by how Timeless handles Echo.
* @param array $extraPersonalTools
*/
private function renderExtraPersonalTools( $extraPersonalTools ) {
foreach ( $extraPersonalTools as $key => $item ) {
echo $this->makeListItem( $key, $item );
}
}
/**
* Render the list items to be displayed in the header's user dropdown.
* @param array $personalTools
*/
private function renderUserDropdownItems( $dropdownPersonalTools ) {
foreach ( $dropdownPersonalTools as $keyAndIconName => $item ) {
$item['class'] = 'refreshed-dropdown-item header-dropdown-item user-info-dropdown-item';
echo $this->makeListItemWithIconAtStart( $keyAndIconName, $keyAndIconName, $item, [ 'text-wrapper' => [ 'tag' => 'span' ] ] );
}
}
/**
* Render the items of the site navigation dropdown/collapsible to appear
* in the header/sidebar.
* @param array $siteNavigation an array containing info for the site
* navigation colapsible
* @param string $mode whether generating for a 'dropdown' or a 'collapsible'
* (affects class names)
*/
private function renderSiteNavigationItems( $siteNavigation, $mode ) {
// (each item in $siteNavigation was an output of
// parseSiteNavigationItem)
// we're making a bunch of list items here (
elements, but NOT ones
// created via makeListItem or makeListItemWithIconAtStart...)
// the classes to add to each of the dropdown anchors
$logoClassList = 'refreshed-logo refreshed-logo-other';
$listItemClassList = '';
if ( $mode === 'dropdown' ) {
$listItemClassList = 'refreshed-dropdown-item header-dropdown-item site-navigation-item';
} elseif ( $mode === 'collapsible' ) {
$listItemClassList = 'refreshed-collapsible-item site-navigation-item';
}
foreach ( $siteNavigation as $wikiLogoInfo ) {
// send each of the parsed pieces of wiki logo info to renderWikiLogo
// for rendering
echo Html::rawElement( 'li', [
'class' => 'refreshed-' . $mode . '-item site-navigation-item'
], $this->makeWikiLinkWithLogo( $wikiLogoInfo['wikiName'], $wikiLogoInfo['logoURL'], $wikiLogoInfo['wikiURL'], $logoClassList ) );
}
}
/**
* Output as a string an anchor for a wiki, with the wiki's logo inside.
* @param string $wikiName the wiki's name
* @param string|null $logoURL URL to the wiki's logo image (if null, render
* logo as text)
* @param string $wikiURL the URL the anchor goes to
* @param string $classList a list of the classes to add to the outputted
* anchor element
* @param string $wikiTitle (optional) text to use as the anchor's title
* attribute instead of $wikiName
* @return string HTML of the logo anchor
*/
private function makeWikiLinkWithLogo( $wikiName, $logoURL, $wikiURL, $classList, $wikiTitle = '' ) {
$anchorAttribs = [
'href' => $wikiURL,
'title' => $wikiTitle !== '' ? $wikiTitle : $wikiName,
'class' => $classList
];
// If wikiURL is null, we're making a text logo. Otherwise, we're making an
// image logo.
if ( $logoURL === null ) {
- $text = Html::element( 'span', [ 'class' => 'header-text' ], $wikiName );
+ $text = Html::element( 'span', [ 'class' => 'header-text site-navigation-logo-text' ], $wikiName );
return Html::rawElement( 'a', $anchorAttribs, $text );
} else {
$image = Html::element( 'img', [
'src' => $logoURL,
'alt' => $wikiName,
'class' => 'site-navigation-logo-img site-navigation-logo-full'
] );
return Html::rawElement( 'a', $anchorAttribs, $image );
}
}
/**
* Render the items of the header category dropdown/collapsible to appear in
* the header/sidebar.
* @param array $headerCategoryDropdown an array containing info for a header
* category dropdown
* @param string $prefix a prefix to attach to some of the classes of each li
* (such as 'header-category')
* @param string $mode whether generating for a 'dropdown' or a 'collapsible'
* (affects class names)
* @param int $index which number header category's dropdown is being
* generated
*/
private function renderHeaderCategoryItems( $headerCategoryDropdown, $index, $mode, $prefix ) {
$commonClassList = '';
if ( $mode === 'dropdown' ) {
$commonClassList = 'refreshed-dropdown-item header-dropdown-item ';
} elseif ( $mode === 'collapsible' ) {
$commonClassList = 'refreshed-collapsible-item ';
}
$prefixedClassList = $prefix . '-dropdown-item ' . $prefix . '-' . strval( $index ) . '-dropdown-item';
$classList = $commonClassList . $prefixedClassList;
foreach ( $headerCategoryDropdown as $key => $value ) {
// Since the header category items appear multiple times on the page,
// they shouldn't have any IDs (otherwise multiple elements would have
// the same ID)
unset( $value['id'] );
echo Html::rawElement( 'li', [
'class' => $classList,
], $this->makeLink( $key, $value, [ 'text-wrapper' => [ 'tag' => 'span' ] ] ) );
}
}
/**
* Sort all of the content actions into categories for easier use.
* Inspired by and adapted from Skin:Timeless.
* @param array $tools the tools to sort
* @return array where each key is a category and each item is an array of
* the page tools in that category (if nothing is in a category, that
* category's key corresponds to an empty array)
*/
private function sortPageTools( $tools ) {
// which category each tool belongs in
$categories = [
'namespaces' => [ 'talk' ], // also anything starting with "nstab-"
'main-actions' => [ 've-edit', 'edit', 'view', 'history', 'addsection', 'viewsource' ],
'page-tools' => [ 'delete', 'rename', 'protect', 'unprotect', 'move', 'whatlinkshere', 'recentchangeslinked', 'print', 'permalink', 'info', 'citethispage', 'feeds' ],
'user-tools' => [ 'contributions', 'blockip', 'userrights', 'log', 'wikilove' ],
'watch' => [ 'watch', 'unwatch' ],
'other' => [ 'upload', 'specialpages' ] // and anything that doesn't fit in other categories
];
// populate the output array with an empty array for each category
$output = [];
foreach ( $categories as $category => $toolNamesInCurrentCategory ) {
$output[$category] = [];
}
// populate the output array with tools
foreach ( $tools as $toolName => $toolDetails ) {
+
// special case: if a key starts with "nstab-" then put it in namespaces
if ( strpos( $toolName, 'nstab-' ) === 0 ) {
+ if ( isset( $toolDetails['class'] ) ) {
+ $toolDetails['class'] .= ' ' . 'ca-subject';
+ } else {
+ $toolDetails['class'] = 'ca-subject';
+ }
$output['namespaces'][$toolName] = $toolDetails;
} else { // otherwise place the tool in its correct category
foreach ( $categories as $category => $toolNamesInCurrentCategory ) {
foreach ( $toolNamesInCurrentCategory as $toolNameInCurrentCategory ) {
if ( $toolName == $toolNameInCurrentCategory ) {
$output[$category][$toolName] = $toolDetails;
$toolPlaced = true;
// once tool is placed, move on to next tool (next iteration of
// outermost foreach)
continue 3;
}
}
}
// if tool hasn't been placed anywhere after all that, put it in 'other'
$output['other'][$toolName] = $toolDetails;
}
}
return $output;
}
/**
* Render the page tools in the toolbox dropdown.
* @param array $pageTools an array of page tools generated by sortPageTools()
*/
private function renderToolboxDropdownItems( $pageTools ) {
$toolboxCategories = [ 'page-tools', 'user-tools' ];
foreach ( $toolboxCategories as $category ) {
if ( !empty( $pageTools[$category] ) ) {
- echo Html::element( 'dt', [ 'class' => 'refreshed-dropdown-header' ], $this->getMsg( 'refreshed-' . $category )->text() );
+ //echo Html::element( 'dt', [ 'class' => 'refreshed-dropdown-header' ], $this->getMsg( 'refreshed-' . $category )->text() );
$this->renderPageToolsInCategory( 'list item', $pageTools, $category );
}
}
}
/**
- * Render the page tools that are in the given category, either as list items
- * (dd NOT li) or as links (a).
- * @param string $mode expects either 'list item' or 'link'
+ * Render a link for talk pages pointing back to the corresponding subject page
+ * @param object $title the article's title
+ */
+ private function renderBackToSubjectLink( $title ) {
+ echo Linker::link(
+ $title,
+ $this->getMsg( 'backlinksubtitle', $title->getPrefixedText() )->escaped(),
+ [ 'id' => 'back-to-subject' ]
+ );
+ }
+
+ /**
+ * Render the page tools that are in the given category, either as list items,
+ * description, or as links (a).
+ * @param string $mode expects 'list item', 'link', or 'other tag'
* @param array $pageTools an array of page tools generated by sortPageTools()
* @param string $category the category of list items being generated
+ * @param string $tag (optional) for 'other tag' mode, the type of wrapper tag
+ * to use
+ * @param string $itemType (optional) for 'other tag' mode, the type of item
+ * ('dropdown') or ('inline') that the items inside the tag will be; this
+ * determines whether items will have the 'dropdown-tool-text' or
+ * 'inline-tool-text' classes added; note if this is not specified, or if
+ * its value is neither 'dropdown' nor 'inline', 'other tag' mode will not
+ * render anything.
*/
- private function renderPageToolsInCategory( $mode, $pageTools, $category ) {
+ private function renderPageToolsInCategory( $mode, $pageTools, $category, $tag = '', $itemType = '' ) {
// if category is invalid, do nothing
if ( !array_key_exists( $category, $pageTools ) ) {
return;
}
- $options = [ 'text-wrapper' => [ 'tag' => 'span' ] ];
+ $options = [ 'text-wrapper' => [ 'tag' => 'span', 'attributes' => [ ] ] ];
if ( $mode == 'list item' ) {
+ $options['text-wrapper']['attributes']['class'] = 'dropdown-tool-text';
foreach ( $pageTools[$category] as $keyAndIconName => $item ) {
echo $this->makeListItemWithIconAtStart( $keyAndIconName, $keyAndIconName, $item, $options );
}
} elseif ( $mode == 'link' ) {
+ $options['text-wrapper']['attributes']['class'] = 'inline-tool-text';
foreach ( $pageTools[$category] as $keyAndIconName => $item ) {
echo $this->makeLinkWithIconAtStart( $keyAndIconName, $keyAndIconName, $item, $options );
}
+ } elseif ( $mode == 'other tag' && ( $itemType == 'dropdown' || $itemType == 'inline' ) ) {
+ $options['text-wrapper']['attributes']['class'] = $itemType . '-tool-text';
+ $options['tag'] = $tag;
+ foreach ( $pageTools[$category] as $keyAndIconName => $item ) {
+ echo $this->makeListItemWithIconAtStart( $keyAndIconName, $keyAndIconName, $item, $options );
+ }
}
}
public function execute() {
global $wgMemc, $wgRefreshedUseExploreWithoutHeaderCategories;
$skin = $this->getSkin();
$config = $skin->getConfig();
$user = $skin->getUser();
// Title processing
$titleBase = $skin->getTitle();
$title = $titleBase->getSubjectPage();
$titleNamespace = $titleBase->getNamespace();
$key = $wgMemc->makeKey( 'refreshed', 'header' );
$headerCategories = $wgMemc->get( $key );
if ( !$headerCategories ) {
$headerCategories = [];
$skin->addToSidebar( $headerCategories, 'refreshed-navigation' );
$wgMemc->set( $key, $headerCategories, 60 * 60 * 24 ); // 24 hours
}
$dropdownCacheKey = $wgMemc->makeKey( 'refreshed', 'dropdownmenu' );
$siteNavigation = $wgMemc->get( $dropdownCacheKey );
if ( !$siteNavigation ) {
$siteNavigation = $this->parseSiteNavigationMenu( 'Refreshed-wiki-dropdown' );
$wgMemc->set( $dropdownCacheKey, $siteNavigation, 60 * 60 * 24 ); // 24 hours
}
// url to this wiki's homepage/page you visit when logo is clicked;
// to be used with renderCurrentWikiLogoAndLink
$thisWikiURLMsg = $skin->msg( 'refreshed-this-wiki-url' );
if ( $thisWikiURLMsg->isDisabled() ) {
$thisWikiURL = htmlspecialchars( Title::newMainPage()->getFullURL() );
} else {
$thisWikiURL = $skin->msg( 'refreshed-this-wiki-url' )->escaped();
}
// url to this wiki's logo image (or null if no such image);
// to be used with renderCurrentWikiLogoAndLink
$thisLogoURLMsg = $skin->msg( 'refreshed-this-wiki-wordmark' );
if ( $thisLogoURLMsg->isDisabled() ) {
$thisLogoURL = null;
} else {
$thisLogoURL = $skin->msg( 'refreshed-this-wiki-wordmark' )->escaped();
}
// this wiki's name; to be used with renderCurrentWikiLogoAndLink
$thisWikiName = $config->get( 'Sitename' );
// anchor containing this wiki's logo
$thisWikiLinkWithLogo = $this->makeWikiLinkWithLogo( $thisWikiName, $thisLogoURL, $thisWikiURL, 'refreshed-logo refreshed-logo-current header-button', $skin->msg( 'Tooltip-p-logo' ) );
$thisWikiLinkWithSidebarLogo = $this->makeWikiLinkWithLogo( $thisWikiName, $thisLogoURL, $thisWikiURL, 'refreshed-logo refreshed-logo-current refreshed-logo-sidebar-current header-button', $skin->msg( 'Tooltip-p-logo' ) );
$thisWikiMobileLogo = $skin->msg( 'refreshed-this-wiki-mobile-logo' );
$thisWikiMobileLogoImgElement = '';
if ( !$thisWikiMobileLogo->isDisabled() ) {
$thisWikiMobileLogoImgElement = Html::element( 'img', [
'src' => $thisWikiMobileLogo->escaped(),
'alt' => $config->get( 'Sitename' ),
'class' => 'site-navigation-logo-img site-navigation-logo-icon'
] );
}
$personalTools = $this->getAndRearrangePersonalTools();
$dropdownPersonalTools = $personalTools['dropdown'];
$extraPersonalTools = $personalTools['extra'];
// @TODO remove toolbox
- $toolbox = $this->getToolbox();
$pageTools = array_merge( $this->data['content_navigation']['views'], $this->data['content_actions'], $this->getToolbox() );
$pageTools = $this->sortPageTools( $pageTools );
+ unset( $this->data['sidebar']['SEARCH'] );
+ unset( $this->data['sidebar']['TOOLBOX'] );
+ unset( $this->data['sidebar']['LANGUAGES'] );
+ $sidebarContentsWikiTools = [];
+ if ( !empty( $pageTools['other'] ) ) {
+ $sidebarContentsWikiTools = [ $this->getMsg( 'refreshed-wiki-tools' )->text() => $pageTools['other'] ];
+ }
+ $sidebarContentsLanguages = [];
+ if ( !empty( $this->data['language_urls'] ) ) {
+ $sidebarContentsLanguages = [ $this->getMsg( 'otherlanguages' )->text() => $this->data['language_urls'] ];
+ }
+ $sidebarContents = array_merge( $this->data['sidebar'], $sidebarContentsWikiTools, $sidebarContentsLanguages );
+
// allow error handling in makeElementWithIconHelper:
// see https://secure.php.net/manual/en/simplexml.examples-errors.php
libxml_use_internal_errors( true );
// Output the tag and whatnot
$this->html( 'headelement' );
?>
isDisabled() ) { // if a mobile logo has been defined
?>