Merge "Refactor pageActions menu to accommodate AMC mode"
This commit is contained in:
commit
9067705cf8
|
@ -92,25 +92,15 @@ class MinervaTemplate extends BaseTemplate {
|
|||
|
||||
/**
|
||||
* Get the HTML for rendering the available page actions
|
||||
* @param array $data Data used to build page actions
|
||||
* @return string
|
||||
*/
|
||||
protected function getPageActionsHtml( $data ) {
|
||||
protected function getPageActionsHtml() {
|
||||
$templateParser = new TemplateParser( __DIR__ );
|
||||
$actions = $this->getPageActions();
|
||||
$html = '';
|
||||
$isJSOnly = true;
|
||||
|
||||
if ( $actions ) {
|
||||
foreach ( $actions as $key => $val ) {
|
||||
if ( isset( $val['is_js_only'] ) ) {
|
||||
if ( !$val['is_js_only'] ) {
|
||||
$isJSOnly = false;
|
||||
}
|
||||
unset( $val['is_js_only'] ); // no need to output this attribute
|
||||
}
|
||||
$html .= $this->makeListItem( $key, $val );
|
||||
}
|
||||
$additionalClasses = $isJSOnly ? 'jsonly' : '';
|
||||
$html = '<ul id="page-actions" class="hlist ' . $additionalClasses . '">' . $html . '</ul>';
|
||||
$html = $templateParser->processTemplate( 'pageActionMenu', [ 'pageactions' => $actions ] );
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
|
|
@ -1137,18 +1137,17 @@ class SkinMinerva extends SkinTemplate {
|
|||
/**
|
||||
* Prepare configured and available page actions
|
||||
*
|
||||
* When adding new page actions make sure each menu item has
|
||||
* <code>is_js_only</code> key set to <code>true</code> or <code>false</code>.
|
||||
* The key will be used to decide whether to display the page actions
|
||||
* wrapper on the front end. The key will be considered false if not set.
|
||||
* If a page action should display a placeholder element
|
||||
* (i.e. it will be hydrated on the client with JS) add the 'jsonly' CSS class to
|
||||
* the 'class' key of its array.
|
||||
*
|
||||
* @param BaseTemplate $tpl
|
||||
*/
|
||||
protected function preparePageActions( BaseTemplate $tpl ) {
|
||||
$menu = [];
|
||||
|
||||
if ( $this->isAllowedPageAction( 'edit' ) ) {
|
||||
$menu['edit'] = $this->createEditPageAction();
|
||||
if ( $this->isAllowedPageAction( 'switch-language' ) ) {
|
||||
$menu[] = $this->createSwitchLanguageAction();
|
||||
}
|
||||
|
||||
if ( $this->isAllowedPageAction( 'watch' ) ) {
|
||||
|
@ -1156,11 +1155,11 @@ class SkinMinerva extends SkinTemplate {
|
|||
// Pass these actions in as context for #createWatchPageAction.
|
||||
$actions = $tpl->data['content_navigation']['actions'];
|
||||
|
||||
$menu['watch'] = $this->createWatchPageAction( $actions );
|
||||
$menu[] = $this->createWatchPageAction( $actions );
|
||||
}
|
||||
|
||||
if ( $this->isAllowedPageAction( 'switch-language' ) ) {
|
||||
$menu['switch-language'] = $this->createSwitchLanguageAction();
|
||||
if ( $this->isAllowedPageAction( 'edit' ) ) {
|
||||
$menu[] = $this->createEditPageAction();
|
||||
}
|
||||
|
||||
$tpl->set( 'page_actions', $menu );
|
||||
|
@ -1170,7 +1169,8 @@ class SkinMinerva extends SkinTemplate {
|
|||
* Creates the "edit" page action: the well-known pencil icon that, when tapped, will open an
|
||||
* editor with the lead section loaded.
|
||||
*
|
||||
* @return array A map compatible with BaseTemplate#makeListItem
|
||||
* @return array A map of HTML attributes and a "text" property to be used with the
|
||||
* pageActionMenu.mustache template.
|
||||
*/
|
||||
protected function createEditPageAction() {
|
||||
$title = $this->getTitle();
|
||||
|
@ -1187,18 +1187,12 @@ class SkinMinerva extends SkinTemplate {
|
|||
$userCanEdit = $userQuickEditCheck && !$userBlockInfo;
|
||||
|
||||
return [
|
||||
'id' => 'ca-edit',
|
||||
'text' => '',
|
||||
'itemtitle' => $this->msg( 'mobile-frontend-pageaction-edit-tooltip' ),
|
||||
'class' => MinervaUI::iconClass( $userCanEdit ? 'edit-enabled' : 'edit', 'element' ),
|
||||
'links' => [
|
||||
'edit' => [
|
||||
'href' => $title->getLocalURL( $editArgs ),
|
||||
'msg' => 'mobile-frontend-editor-edit',
|
||||
'class' => 'edit-page',
|
||||
],
|
||||
],
|
||||
'is_js_only' => false,
|
||||
'id' => 'ca-edit',
|
||||
'href' => $title->getLocalURL( $editArgs ),
|
||||
'class' => 'edit-page '
|
||||
. MinervaUI::iconClass( $userCanEdit ? 'edit-enabled' : 'edit', 'element' ),
|
||||
'title' => $this->msg( 'mobile-frontend-pageaction-edit-tooltip' ),
|
||||
'text' => $this->msg( 'mobile-frontend-editor-edit' )
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -1208,7 +1202,8 @@ class SkinMinerva extends SkinTemplate {
|
|||
* will direct the user's UA to Special:Login.
|
||||
*
|
||||
* @param array $actions
|
||||
* @return array A map compatible with BaseTemplate#makeListItem
|
||||
* @return array A map of HTML attributes and a "text" property to be used with the
|
||||
* pageActionMenu.mustache template.
|
||||
*/
|
||||
protected function createWatchPageAction( $actions ) {
|
||||
$title = $this->getTitle();
|
||||
|
@ -1222,8 +1217,9 @@ class SkinMinerva extends SkinTemplate {
|
|||
$baseResult = [
|
||||
'id' => 'ca-watch',
|
||||
// Use blank icon to reserve space for watchstar icon once JS loads
|
||||
'class' => MinervaUI::iconClass( $icon, 'element', 'watch-this-article' ),
|
||||
'is_js_only' => true
|
||||
'class' => MinervaUI::iconClass( $icon, 'element', 'watch-this-article' ) . ' jsonly',
|
||||
'title' => $this->msg( 'watchthispage' ),
|
||||
'text' => $this->msg( 'watchthispage' )
|
||||
];
|
||||
|
||||
if ( isset( $actions['watch'] ) ) {
|
||||
|
@ -1231,11 +1227,10 @@ class SkinMinerva extends SkinTemplate {
|
|||
} elseif ( isset( $actions['unwatch'] ) ) {
|
||||
$result = array_merge( $actions['unwatch'], $baseResult );
|
||||
$result['class'] .= ' watched';
|
||||
$result[ 'text' ] = $this->msg( 'unwatchthispage' );
|
||||
} else {
|
||||
// placeholder for not logged in
|
||||
$result = array_merge( $baseResult, [
|
||||
// FIXME: makeLink (used by makeListItem) when no text is present defaults to use the key
|
||||
'text' => '',
|
||||
'href' => $ctaUrl,
|
||||
] );
|
||||
}
|
||||
|
@ -1247,26 +1242,26 @@ class SkinMinerva extends SkinTemplate {
|
|||
* Creates the "switch-language" action: the icon that, when tapped, opens the language
|
||||
* switcher.
|
||||
*
|
||||
* @return array A map compatible with BaseTemplate#makeListItem
|
||||
* @return array A map of HTML attributes and a 'text' property to be used with the
|
||||
* pageActionMenu.mustache template.
|
||||
*/
|
||||
protected function createSwitchLanguageAction() {
|
||||
$languageSwitcherLinks = [];
|
||||
$languageSwitcherClasses = 'language-selector';
|
||||
$languageSwitcherLink = false;
|
||||
$languageSwitcherClasses = ' language-selector';
|
||||
|
||||
if ( $this->doesPageHaveLanguages ) {
|
||||
$languageSwitcherLinks['mobile-frontend-language-article-heading'] = [
|
||||
'href' => SpecialPage::getTitleFor( 'MobileLanguages', $this->getTitle() )->getLocalURL()
|
||||
];
|
||||
$languageSwitcherLink = SpecialPage::getTitleFor(
|
||||
'MobileLanguages',
|
||||
$this->getTitle()
|
||||
)->getLocalURL();
|
||||
} else {
|
||||
$languageSwitcherClasses .= ' disabled';
|
||||
}
|
||||
|
||||
return [
|
||||
'text' => '',
|
||||
'itemtitle' => $this->msg( 'mobile-frontend-language-article-heading' ),
|
||||
'class' => MinervaUI::iconClass( 'language-switcher', 'element', $languageSwitcherClasses ),
|
||||
'links' => $languageSwitcherLinks,
|
||||
'is_js_only' => false
|
||||
'class' => MinervaUI::iconClass( 'language-switcher', 'element', $languageSwitcherClasses ),
|
||||
'href' => $languageSwitcherLink,
|
||||
'title' => $this->msg( 'mobile-frontend-language-article-heading' ),
|
||||
'text' => $this->msg( 'mobile-frontend-language-article-heading' )
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<nav class="page-actions-menu">
|
||||
<ul id="page-actions" class="page-actions-menu__list">
|
||||
{{#pageactions}}
|
||||
<li class="page-actions-menu__list-item">
|
||||
<a id="{{id}}" href="{{href}}" class="{{class}}" role="button" title="{{title}}">
|
||||
{{text}}
|
||||
</a>
|
||||
</li>
|
||||
{{/pageactions}}
|
||||
</ul>
|
||||
</nav>
|
|
@ -15,7 +15,70 @@
|
|||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
#page-actions {
|
||||
// used to disable the languages icon.
|
||||
.mw-ui-icon-element.disabled {
|
||||
cursor: default;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.page-actions-menu {
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid @colorGray14;
|
||||
border-bottom: 1px solid @colorGray12;
|
||||
}
|
||||
|
||||
.page-actions-menu__list {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 44px; // total height is 46px. 2px added by border on .page-actions-menu
|
||||
}
|
||||
|
||||
.page-actions-menu__list-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-basis: 4em;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
// overriding default icon styles
|
||||
.mw-ui-icon-element {
|
||||
// The page actions menu icons are ever so slightly larger
|
||||
// than standard icons.
|
||||
@pageActionsIconSize: @iconSize + 0.15;
|
||||
position: relative;
|
||||
min-width: @pageActionsIconSize;
|
||||
width: @pageActionsIconSize;
|
||||
height: @pageActionsIconSize;
|
||||
|
||||
&:hover {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&:before {
|
||||
margin: 0;
|
||||
// `.mw-ui-icon` absolutely positions this pseudo-element but only
|
||||
// positions right & left. This ensures icon stretches 100% height and
|
||||
// stretches the entire height of its parent element.
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// default layout - spacing out the first menu item
|
||||
.page-actions-menu__list-item:first-child {
|
||||
flex-grow: 1;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
// overriding common.less `display:inherit` (which causes `display: flex;` in this instance).
|
||||
.client-js .jsonly#ca-watch {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
// TODO: T213352 Delete this nested block after varnish cache has cleared and selectors
|
||||
// no longer apply.
|
||||
#page-actions:not( .page-actions-menu__list ) {
|
||||
font-size: @pageActionFontSize;
|
||||
float: none;
|
||||
border: 0;
|
||||
|
@ -70,7 +133,7 @@
|
|||
|
||||
// FIXME: cached HTML. Can be removed when work on T212216
|
||||
// has been deployed and varnish cache cleared.
|
||||
.heading-holder #page-actions:first-child {
|
||||
.heading-holder #page-actions:not( .page-actions-menu__list ):first-child {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
|
|
|
@ -125,7 +125,12 @@
|
|||
* @returns {jQuery.Object|null}
|
||||
*/
|
||||
function downloadPageAction( skin, supportedNamespaces, windowObj ) {
|
||||
var icon, spinner = icons.spinner();
|
||||
var icon, spinner = icons.spinner(),
|
||||
// TODO: T213352 Temporary cache compatibility - to be deleted.
|
||||
// Any conditionals using this boolean should be DELETED when the
|
||||
// old page action menu is no longer being served to users.
|
||||
// eslint-disable-next-line jquery/no-global-selector
|
||||
oldPageActionsDOM = $( '#page-actions.hlist' ).length > 0;
|
||||
if (
|
||||
isAvailable(
|
||||
windowObj, skin.page, navigator.userAgent,
|
||||
|
@ -136,12 +141,17 @@
|
|||
glyphPrefix: 'minerva',
|
||||
title: msg( 'minerva-download' ),
|
||||
name: GLYPH,
|
||||
tagName: oldPageActionsDOM ? 'div' : 'button',
|
||||
events: {
|
||||
// will be bound to `this`
|
||||
click: getOnClickHandler( skin, spinner )
|
||||
}
|
||||
} );
|
||||
return $( '<li>' ).append( icon.$el ).append( spinner.$el.hide() );
|
||||
if ( oldPageActionsDOM ) {
|
||||
return $( '<li>' ).append( icon.$el ).append( spinner.$el.hide() );
|
||||
} else {
|
||||
return $( '<li>' ).addClass( 'page-actions-menu__list-item' ).append( icon.$el ).append( spinner.$el.hide() );
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -236,14 +236,19 @@
|
|||
*/
|
||||
function appendDownloadButton() {
|
||||
var $downloadAction = downloadPageAction( skin,
|
||||
config.get( 'wgMinervaDownloadNamespaces', [] ), window );
|
||||
config.get( 'wgMinervaDownloadNamespaces', [] ), window ),
|
||||
// TODO: T213352 Temporary cache compatibility - to be deleted.
|
||||
// Any conditionals using this boolean should be DELETED when the
|
||||
// old page action menu is no longer being served to users.
|
||||
// eslint-disable-next-line jquery/no-global-selector
|
||||
oldPageActionsDOM = $( '#page-actions.hlist' ).length > 0;
|
||||
|
||||
if ( $downloadAction ) {
|
||||
// Because the page actions are floated to the right, their order in the
|
||||
// DOM is reversed in the display. The watchstar is last in the DOM and
|
||||
// left-most in the display. Since we want the download button to be to
|
||||
// the left of the watchstar, we put it after it in the DOM.
|
||||
$downloadAction.insertAfter( '#ca-watch' );
|
||||
if ( oldPageActionsDOM ) {
|
||||
$downloadAction.insertAfter( '#ca-watch' );
|
||||
} else {
|
||||
$downloadAction.insertAfter( '.page-actions-menu__list-item:first-child' );
|
||||
}
|
||||
track( 'minerva.downloadAsPDF', {
|
||||
action: 'buttonVisible'
|
||||
} );
|
||||
|
|
Loading…
Reference in New Issue