Merge "Update: add secondary page actions submenu in AMC mode"
13
README.md
|
@ -119,6 +119,19 @@ This will work for all pages except the main page.
|
|||
```
|
||||
Controls whether the history link appears in the page actions menu.
|
||||
|
||||
#### $wgMinervaOverflowInPageActions
|
||||
|
||||
* Type: `Array`
|
||||
* Default:
|
||||
```php
|
||||
[
|
||||
'beta' => false,
|
||||
'base' => false,
|
||||
'amc' => false,
|
||||
]
|
||||
```
|
||||
Controls whether the overflow link appears in the page actions menu.
|
||||
|
||||
#### $wgMinervaShowShareButton
|
||||
|
||||
* Type: `Array`
|
||||
|
|
10
i18n/en.json
|
@ -6,7 +6,7 @@
|
|||
"minerva-talk-add-topic": "Add discussion",
|
||||
"mobile-frontend-cookies-required": "Cookies are required to switch view modes. Please enable them and try again.",
|
||||
"mobile-frontend-editor-edit": "Edit",
|
||||
"minerva-download": "Download",
|
||||
"minerva-download": "Download PDF",
|
||||
"skin-minerva-share": "Share",
|
||||
"skin-minerva-mobile-option-MinervaShareButton": "Share",
|
||||
"skin-minerva-mobile-option-MinervaShareButton-description": "Share current article via browser share feature (supported browsers only)",
|
||||
|
@ -47,6 +47,14 @@
|
|||
"mobile-frontend-user-page-member-since": "{{GENDER:$2|Joined}} $1",
|
||||
"mobile-frontend-user-page-talk": "Talk",
|
||||
"mobile-frontend-user-page-uploads": "Uploads",
|
||||
"minerva-page-actions-overflow": "Secondary page actions submenu",
|
||||
"minerva-page-actions-info": "Page information",
|
||||
"minerva-page-actions-permalink": "Permanent link",
|
||||
"minerva-page-actions-backlinks": "What links here",
|
||||
"minerva-page-actions-cite": "Cite page",
|
||||
"minerva-page-actions-uploads": "Uploads",
|
||||
"minerva-page-actions-user-rights": "User rights",
|
||||
"minerva-page-actions-logs": "Logs",
|
||||
"skinname-minerva": "MinervaNeue",
|
||||
"minerva-skin-desc": "A responsive mobile first skin",
|
||||
"skin-minerva-issue-learn-more": "Learn more",
|
||||
|
|
|
@ -56,6 +56,14 @@
|
|||
"mobile-frontend-user-page-member-since": "Message below the heading. $1 is the user registration date. $2 is the gender associated with the user account.",
|
||||
"mobile-frontend-user-page-talk": "Text of the link to the user's talk page\n{{Identical|Talk}}",
|
||||
"mobile-frontend-user-page-uploads": "Text of the link to the user's uploads page\n{{Identical|Upload}}",
|
||||
"minerva-page-actions-overflow": "Text describing the secondary page menu button's action",
|
||||
"minerva-page-actions-info": "In the secondary page menu, the page information button label",
|
||||
"minerva-page-actions-permalink": "In the secondary page menu, the permanent link button label",
|
||||
"minerva-page-actions-backlinks": "In the secondary page menu, the 'what links here' incoming links button label",
|
||||
"minerva-page-actions-cite": "In the secondary page menu, the cite this page button label",
|
||||
"minerva-page-actions-uploads": "In the secondary page menu for user pages, the user uploads button label",
|
||||
"minerva-page-actions-user-rights": "In the secondary page menu for user pages, the user rights button label",
|
||||
"minerva-page-actions-logs": "In the secondary page menu for user pages, the user logs button label",
|
||||
"skinname-minerva": "{{name}}",
|
||||
"minerva-skin-desc": "{{desc|name=Minerva Neue|url=https://www.mediawiki.org/wiki/Skin:Minerva_Neue|what=skin}}",
|
||||
"skin-minerva-issue-learn-more": "Label for link that allows expanding of ambox issue templates.",
|
||||
|
|
|
@ -28,6 +28,8 @@ use MediaWiki\Minerva\SkinOptions;
|
|||
* on<HookName>()
|
||||
*/
|
||||
class MinervaHooks {
|
||||
const FEATURE_OVERFLOW_PAGE_ACTIONS = 'MinervaOverflowInPageActions';
|
||||
|
||||
/**
|
||||
* Register mobile web beta features
|
||||
* @see https://www.mediawiki.org/wiki/
|
||||
|
@ -82,6 +84,13 @@ class MinervaHooks {
|
|||
$config->get( 'MinervaHistoryInPageActions' )
|
||||
)
|
||||
);
|
||||
$featureManager->registerFeature(
|
||||
new MobileFrontend\Features\Feature(
|
||||
self::FEATURE_OVERFLOW_PAGE_ACTIONS,
|
||||
'skin-minerva',
|
||||
$config->get( self::FEATURE_OVERFLOW_PAGE_ACTIONS )
|
||||
)
|
||||
);
|
||||
} catch ( RuntimeException $e ) {
|
||||
// features already registered...
|
||||
// due to a bug it's possible for this to run twice
|
||||
|
@ -222,6 +231,9 @@ class MinervaHooks {
|
|||
SkinOptions::OPTIONS_HISTORY_PAGE_ACTIONS => $featureManager->isFeatureAvailableForCurrentUser(
|
||||
'MinervaHistoryInPageActions'
|
||||
),
|
||||
SkinOptions::OPTION_OVERFLOW_SUBMENU => $featureManager->isFeatureAvailableForCurrentUser(
|
||||
self::FEATURE_OVERFLOW_PAGE_ACTIONS
|
||||
),
|
||||
] );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ final class SkinOptions {
|
|||
const OPTIONS_MOBILE_BETA = 'beta';
|
||||
const OPTIONS_TALK_AT_TOP = 'talkAtTop';
|
||||
const OPTIONS_HISTORY_PAGE_ACTIONS = 'historyInPageActions';
|
||||
const OPTION_OVERFLOW_SUBMENU = 'overflowSubmenu';
|
||||
|
||||
/** @var array skin specific options */
|
||||
private $skinOptions = [
|
||||
|
@ -56,6 +57,7 @@ final class SkinOptions {
|
|||
self::OPTION_PAGE_ISSUES => false,
|
||||
self::OPTIONS_TALK_AT_TOP => false,
|
||||
self::OPTIONS_HISTORY_PAGE_ACTIONS => false,
|
||||
self::OPTION_OVERFLOW_SUBMENU => false,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -98,11 +98,11 @@ class MinervaTemplate extends BaseTemplate {
|
|||
*/
|
||||
protected function getPageActionsHtml() {
|
||||
$templateParser = new TemplateParser( __DIR__ );
|
||||
$actions = $this->getPageActions();
|
||||
$pageActions = $this->getPageActions();
|
||||
$html = '';
|
||||
|
||||
if ( $actions ) {
|
||||
$html = $templateParser->processTemplate( 'pageActionMenu', [ 'pageActions' => $actions ] );
|
||||
if ( $pageActions && $pageActions['toolbar'] ) {
|
||||
$html = $templateParser->processTemplate( 'pageActionMenu', $pageActions );
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ use MediaWiki\Minerva\SkinUserPageHelper;
|
|||
* @ingroup Skins
|
||||
*/
|
||||
class SkinMinerva extends SkinTemplate {
|
||||
|
||||
/** @const LEAD_SECTION_NUMBER integer which corresponds to the lead section
|
||||
in editing mode */
|
||||
const LEAD_SECTION_NUMBER = 0;
|
||||
|
@ -231,6 +230,10 @@ class SkinMinerva extends SkinTemplate {
|
|||
return $this->skinOptions->get( SkinOptions::OPTIONS_HISTORY_PAGE_ACTIONS );
|
||||
}
|
||||
|
||||
if ( $action === SkinOptions::OPTION_OVERFLOW_SUBMENU ) {
|
||||
return $this->skinOptions->get( SkinOptions::OPTION_OVERFLOW_SUBMENU );
|
||||
}
|
||||
|
||||
if (
|
||||
!in_array( $action, $config->get( 'MinervaPageActions' ) )
|
||||
|| ( $this->getUserPageHelper()->isUserPage() && !$title->exists() )
|
||||
|
@ -834,10 +837,11 @@ class SkinMinerva extends SkinTemplate {
|
|||
* @param BaseTemplate $tpl
|
||||
*/
|
||||
protected function preparePageActions( BaseTemplate $tpl ) {
|
||||
$menu = [];
|
||||
$toolbar = [];
|
||||
$overflowMenu = null;
|
||||
|
||||
if ( $this->isAllowedPageAction( 'switch-language' ) ) {
|
||||
$menu[] = $this->createSwitchLanguageAction();
|
||||
$toolbar[] = $this->createSwitchLanguageAction();
|
||||
}
|
||||
|
||||
if ( $this->isAllowedPageAction( 'watch' ) ) {
|
||||
|
@ -845,18 +849,25 @@ class SkinMinerva extends SkinTemplate {
|
|||
// Pass these actions in as context for #createWatchPageAction.
|
||||
$actions = $tpl->data['content_navigation']['actions'];
|
||||
|
||||
$menu[] = $this->createWatchPageAction( $actions );
|
||||
$toolbar[] = $this->createWatchPageAction( $actions );
|
||||
}
|
||||
|
||||
if ( $this->isAllowedPageAction( 'history' ) ) {
|
||||
$menu[] = $this->getHistoryPageAction();
|
||||
$toolbar[] = $this->getHistoryPageAction();
|
||||
}
|
||||
|
||||
if ( $this->isAllowedPageAction( 'edit' ) ) {
|
||||
$menu[] = $this->createEditPageAction();
|
||||
$toolbar[] = $this->createEditPageAction();
|
||||
}
|
||||
|
||||
$tpl->set( 'page_actions', $menu );
|
||||
if ( $this->isAllowedPageAction( SkinOptions::OPTION_OVERFLOW_SUBMENU ) ) {
|
||||
$overflowMenu = $this->newToolbarOverflowMenu( $tpl );
|
||||
}
|
||||
|
||||
$tpl->set( 'page_actions', [
|
||||
'toolbar' => $toolbar,
|
||||
'overflowMenu' => $overflowMenu
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -977,6 +988,85 @@ class SkinMinerva extends SkinTemplate {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an overflow action: An icon that links to the overflow menu.
|
||||
*
|
||||
* @param BaseTemplate $tpl
|
||||
* @return array|null A map of HTML attributes and a 'text' property to be used with the
|
||||
* pageActionMenu.mustache template.
|
||||
*/
|
||||
private function newToolbarOverflowMenu( BaseTemplate $tpl ) {
|
||||
$pageActions = $this->getUserPageHelper()->isUserPage()
|
||||
? $this->getUserNamespaceOverflowPageActions( $tpl )
|
||||
: $this->getDefaultOverflowPageActions( $tpl );
|
||||
return empty( $pageActions ) ? null : [
|
||||
'item-id' => 'page-actions-overflow',
|
||||
'class' => MinervaUI::iconClass( 'page-actions-overflow' ),
|
||||
'text' => $this->msg( 'minerva-page-actions-overflow' ),
|
||||
'pageActions' => $pageActions
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BaseTemplate $tpl
|
||||
* @return array
|
||||
*/
|
||||
private function getDefaultOverflowPageActions( BaseTemplate $tpl ) {
|
||||
return array_values( array_filter( [
|
||||
$this->newOverflowPageAction( 'info', 'info', $tpl->data['nav_urls']['info']['href'] ?? null ),
|
||||
$this->newOverflowPageAction(
|
||||
'permalink', 'link', $tpl->data['nav_urls']['permalink']['href'] ?? null
|
||||
),
|
||||
$this->newOverflowPageAction(
|
||||
'backlinks', 'articleRedirect', $tpl->data['nav_urls']['whatlinkshere']['href'] ?? null
|
||||
),
|
||||
$this->newOverflowPageAction(
|
||||
'cite', 'quotes', $tpl->data['nav_urls']['citethispage']['href'] ?? null
|
||||
)
|
||||
] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BaseTemplate $tpl
|
||||
* @return array
|
||||
*/
|
||||
private function getUserNamespaceOverflowPageActions( BaseTemplate $tpl ) {
|
||||
$pageUser = $this->getUserPageHelper()->getPageUser();
|
||||
return [
|
||||
$this->newOverflowPageAction(
|
||||
'uploads', 'upload', SpecialPage::getTitleFor( 'Uploads', $pageUser )->getLocalURL()
|
||||
),
|
||||
$this->newOverflowPageAction(
|
||||
'user-rights', 'userAvatar', $tpl->data['nav_urls']['userrights']['href'] ?? null
|
||||
),
|
||||
$this->newOverflowPageAction(
|
||||
'logs', 'listBullet', $tpl->data['nav_urls']['log']['href'] ?? null
|
||||
),
|
||||
$this->newOverflowPageAction( 'info', 'info', $tpl->data['nav_urls']['info']['href'] ?? null ),
|
||||
$this->newOverflowPageAction(
|
||||
'permalink', 'link', $tpl->data['nav_urls']['permalink']['href'] ?? null
|
||||
),
|
||||
$this->newOverflowPageAction(
|
||||
'backlinks', 'articleRedirect', $tpl->data['nav_urls']['whatlinkshere']['href'] ?? null
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $icon Wikimedia UI icon name.
|
||||
* @param string|null $href
|
||||
* @return array
|
||||
*/
|
||||
private function newOverflowPageAction( $name, $icon, $href ) {
|
||||
return $href ? [
|
||||
'item-id' => 'page-actions-overflow-' . $name,
|
||||
'class' => MinervaUI::iconClass( '', 'before', 'wikimedia-ui-' . $icon . '-base20' ),
|
||||
'text' => $this->msg( 'minerva-page-actions-' . $name ),
|
||||
'href' => $href
|
||||
] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the editor can handle the existing content handler type.
|
||||
*
|
||||
|
|
|
@ -1,11 +1,28 @@
|
|||
<nav class="page-actions-menu">
|
||||
<ul id="page-actions" class="page-actions-menu__list">
|
||||
{{#pageActions}}
|
||||
{{#toolbar}}
|
||||
<li id="{{item-id}}" class="page-actions-menu__list-item">
|
||||
<a id="{{id}}" href="{{href}}" class="{{class}}" role="button" title="{{title}}">
|
||||
{{text}}
|
||||
</a>
|
||||
</li>
|
||||
{{/pageActions}}
|
||||
{{/toolbar}}
|
||||
{{#overflowMenu}}
|
||||
<li id="{{item-id}}" class="page-actions-menu__list-item">
|
||||
<input type="checkbox" id="toolbar-overflow-menu__checkbox" role="button" aria-label="{{text}}" aria-expanded="false" >
|
||||
<label class="toolbar-overflow-menu__button {{class}}" title="{{title}}" for="toolbar-overflow-menu__checkbox">
|
||||
{{text}}
|
||||
</label>
|
||||
<ul class="toolbar-overflow-menu__list">
|
||||
{{#pageActions}}
|
||||
<li>
|
||||
<a id="{{id}}" href="{{href}}" class="toolbar-overflow-menu__list-item {{class}}" title="{{title}}">
|
||||
{{text}}
|
||||
</a>
|
||||
</li>
|
||||
{{/pageActions}}
|
||||
</ul>
|
||||
</li>
|
||||
{{/overflowMenu}}
|
||||
</ul>
|
||||
</nav>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@import 'mediawiki.ui/variables';
|
||||
|
||||
@z-indexBase: 0;
|
||||
@z-indexOverOverlay: 2;
|
||||
@z-indexOverOverlay: 3;
|
||||
|
||||
/**
|
||||
* System font stack for sans-serif fonts
|
||||
|
@ -38,7 +38,6 @@
|
|||
|
||||
// Headings
|
||||
@firstHeadingFontSize: 2.6525em; // 42px
|
||||
@pageActionFontSize: 1.1em; // Icons are 24px square.
|
||||
@fontSizeH1: 1.7em;
|
||||
@fontSizeH2: 1.5em;
|
||||
@fontSizeH3: 1.2em;
|
||||
|
@ -49,7 +48,7 @@
|
|||
|
||||
// Header
|
||||
@headerHeight: 3.35em;
|
||||
@headerMarginTop: -1px; // used to hide the header border top when a banner is not present
|
||||
@headerMarginTop: -1px; // used to hide the header border top when a banner is not present
|
||||
@searchBoxWidth: 375/16em;
|
||||
@iconSizeTotal: @iconSize + @iconGutterWidth + @iconGutterWidth;
|
||||
@deviceWidthTabletEms: unit( @width-breakpoint-tablet/16, em );
|
||||
|
@ -61,6 +60,8 @@
|
|||
// Page actions
|
||||
@taglineFontSize: 0.85em;
|
||||
@pageActionBorder: 1px;
|
||||
@pageActionFontSize: 0.9em;
|
||||
@pageActionToolbarHeight: 44px; // total height is 46px. 2px added by border on .page-actions-menu
|
||||
|
||||
// colors
|
||||
@chromeColor: @grayLightest;
|
||||
|
@ -125,7 +126,9 @@
|
|||
@notificationColorUnread: #fff;
|
||||
|
||||
// z-index:
|
||||
@z-indexOverlay: 1;
|
||||
@z-indexOccluded: -1;
|
||||
@z-indexDrawer: 1;
|
||||
@z-indexOverlay: 2;
|
||||
|
||||
// Print specific
|
||||
@colorPrintSubtle: #999;
|
||||
|
|
|
@ -21,8 +21,12 @@
|
|||
opacity: 0.25;
|
||||
}
|
||||
|
||||
#page-actions {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.page-actions-menu {
|
||||
box-sizing: border-box;
|
||||
.box-sizing( border-box );
|
||||
border-top: 1px solid @colorGray14;
|
||||
border-bottom: 1px solid @colorGray12;
|
||||
}
|
||||
|
@ -30,11 +34,10 @@
|
|||
.page-actions-menu__list {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 44px; // total height is 46px. 2px added by border on .page-actions-menu
|
||||
height: @pageActionToolbarHeight;
|
||||
}
|
||||
|
||||
.page-actions-menu__list-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-basis: 4em;
|
||||
justify-content: flex-end;
|
||||
|
@ -68,6 +71,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.minerva--amc-enabled .page-actions-menu__list-item {
|
||||
flex-basis: auto;
|
||||
}
|
||||
|
||||
// Layout for less than 5 items - one item at the beginning, rest at the end.
|
||||
// |1-----2--3--4|
|
||||
.page-actions-menu__list-item:first-child {
|
||||
|
@ -75,6 +82,99 @@
|
|||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
// When AMC is enabled, space all items equally.
|
||||
.minerva--amc-enabled .page-actions-menu__list-item:first-child {
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
#toolbar-overflow-menu__checkbox {
|
||||
// Always occlude the checkbox. The checkbox display cannot be none since its focus state is used
|
||||
// for other selectors.
|
||||
position: absolute;
|
||||
z-index: @z-indexOccluded;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.toolbar-overflow-menu__button {
|
||||
// Use the hand icon for the overflow button which is actually a checkbox label.
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#toolbar-overflow-menu__checkbox:focus + .toolbar-overflow-menu__button {
|
||||
// The overflow button / label itself cannot receive focus but the underlying checkbox can. Keep
|
||||
// the button and checkbox focus presentation in sync. From
|
||||
// resources/src/mediawiki.toc.styles/screen.less.
|
||||
outline: dotted 1px; /* Firefox style for focus */
|
||||
outline: auto @colorProgressiveHighlight; /* Webkit style for focus */
|
||||
}
|
||||
|
||||
.touch-events #toolbar-overflow-menu__checkbox:focus + .toolbar-overflow-menu__button {
|
||||
// Buttons have no focus outline on mobile.
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.toolbar-overflow-menu__list {
|
||||
// The top of the menu is flush with the bottom of the page actions toolbar.
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
//
|
||||
// A variable max-height is set in JavaScript so a minimum height is needed.
|
||||
min-height: 200px;
|
||||
//
|
||||
// If the height exceeds the maximum allowed, add a vertical scrollbar.
|
||||
overflow-y: auto;
|
||||
//
|
||||
// The menu floats over content but below overlays.
|
||||
z-index: @z-indexDrawer;
|
||||
//
|
||||
font-size: @pageActionFontSize;
|
||||
font-weight: bold;
|
||||
background: @skinContentBgColor;
|
||||
box-shadow: 0 5px 17px 0 rgba( 0, 0, 0, 0.24 ), 0 0 1px @colorGray10;
|
||||
border-radius: @borderRadius;
|
||||
//
|
||||
// Animate menu visibility, opacity, and translation changes in and out. Visibility must be
|
||||
// animated since it's a boolean and nothing can be seen in the hidden state.
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transform: translateY( -8px );
|
||||
.transition( visibility .1s ease-in-out, opacity .1s ease-in-out, transform .1s ease-in-out; );
|
||||
}
|
||||
|
||||
.toolbar-overflow-menu__list-item {
|
||||
// Fill the list item cell.
|
||||
.box-sizing( border-box );
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
//
|
||||
padding: 1em;
|
||||
white-space: nowrap;
|
||||
// Left-align text. Button elements are centered.
|
||||
text-align: left;
|
||||
//
|
||||
color: @grayMediumDark;
|
||||
|
||||
&:visited, &:active {
|
||||
// Visited and active links need extra specificity.
|
||||
color: @grayMediumDark;
|
||||
}
|
||||
//
|
||||
// Make the app feel like an app, not a JPEG. When hovering over a menu item, add a little
|
||||
// interactivity.
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
background: @grayLightest;
|
||||
}
|
||||
}
|
||||
|
||||
#toolbar-overflow-menu__checkbox:checked ~ .toolbar-overflow-menu__list {
|
||||
// Reveal the overflow menu when checked.
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transform: translateY( 0 );
|
||||
}
|
||||
|
||||
// overriding common.less `display:inherit` (which causes `display: flex;` in this instance).
|
||||
.client-js .jsonly#ca-watch {
|
||||
display: list-item;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" id="svg10"><title id="title2">ellipsis</title><circle cx="-10" cy="10" r="2" id="circle4" transform="rotate(-90)"/><circle cx="-17" cy="10" r="2" id="circle6" transform="rotate(-90)"/><circle cx="-3" cy="10" r="2" id="circle8" transform="rotate(-90)"/></svg>
|
After Width: | Height: | Size: 395 B |
175
resources/skins.minerva.scripts/Toolbar.js
Normal file
|
@ -0,0 +1,175 @@
|
|||
( function ( M ) {
|
||||
var
|
||||
mobile = M.require( 'mobile.startup' ),
|
||||
downloadPageAction = M.require( 'skins.minerva.scripts/downloadPageAction' ),
|
||||
Icon = mobile.Icon,
|
||||
skin = M.require( 'mobile.init/skin' ),
|
||||
/** The top level menu. */
|
||||
toolbarSelector = '.page-actions-menu',
|
||||
/** The secondary overflow submenu component container. */
|
||||
overflowSubmenuSelector = '#page-actions-overflow',
|
||||
/** The visible label icon associated with the checkbox. */
|
||||
overflowButtonSelector = '.toolbar-overflow-menu__button',
|
||||
/** The underlying hidden checkbox that controls secondary overflow submenu visibility. */
|
||||
overflowCheckboxSelector = '#toolbar-overflow-menu__checkbox',
|
||||
overflowListSelector = '.toolbar-overflow-menu__list';
|
||||
|
||||
/**
|
||||
* @param {Window} window
|
||||
* @param {Element} toolbar
|
||||
* @param {OO.EventEmitter} eventBus
|
||||
* @return {void}
|
||||
*/
|
||||
function bind( window, toolbar, eventBus ) {
|
||||
var
|
||||
overflowSubmenu = toolbar.querySelector( overflowSubmenuSelector ),
|
||||
overflowButton = toolbar.querySelector( overflowButtonSelector ),
|
||||
overflowCheckbox = toolbar.querySelector( overflowCheckboxSelector ),
|
||||
overflowList = toolbar.querySelector( overflowListSelector );
|
||||
|
||||
if ( overflowSubmenu ) {
|
||||
bindOverflowSubmenu(
|
||||
window, overflowSubmenu, overflowButton, overflowCheckbox, overflowList, eventBus
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Window} window
|
||||
* @param {Element} toolbar
|
||||
* @return {void}
|
||||
*/
|
||||
function render( window, toolbar ) {
|
||||
var overflowList = toolbar.querySelector( overflowListSelector );
|
||||
renderEditButton();
|
||||
renderDownloadButton( window, overflowList );
|
||||
if ( overflowList ) {
|
||||
resizeOverflowList( overflowList );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically dismiss the submenu when clicking or focusing elsewhere, resize the menu on
|
||||
* scroll and window resize, and update the aria-expanded attribute based on submenu visibility.
|
||||
* @param {Window} window
|
||||
* @param {Element} submenu
|
||||
* @param {Element} button
|
||||
* @param {HTMLInputElement} checkbox
|
||||
* @param {Element} list
|
||||
* @param {OO.EventEmitter} eventBus
|
||||
* @return {void}
|
||||
*/
|
||||
function bindOverflowSubmenu( window, submenu, button, checkbox, list, eventBus ) {
|
||||
var
|
||||
resize = resizeOverflowList.bind( undefined, list ),
|
||||
updateAriaExpanded = function () {
|
||||
checkbox.setAttribute( 'aria-expanded', ( !!checkbox.checked ).toString() );
|
||||
};
|
||||
|
||||
window.addEventListener( 'click', function ( event ) {
|
||||
if ( event.target !== button && event.target !== checkbox ) {
|
||||
// Something besides the button or checkbox was tapped. Dismiss the submenu.
|
||||
checkbox.checked = false;
|
||||
updateAriaExpanded();
|
||||
}
|
||||
} );
|
||||
|
||||
// If focus is given to any element outside the menu, dismiss the submenu. Setting a
|
||||
// focusout listener on submenu would be preferable, but this interferes with the click
|
||||
// listener.
|
||||
window.addEventListener( 'focusin', function ( event ) {
|
||||
if ( event.target instanceof Node && !submenu.contains( event.target ) ) {
|
||||
// Something besides the button or checkbox was focused. Dismiss the menu.
|
||||
checkbox.checked = false;
|
||||
updateAriaExpanded();
|
||||
}
|
||||
} );
|
||||
|
||||
eventBus.on( 'scroll:throttled', resize );
|
||||
eventBus.on( 'resize:throttled', resize );
|
||||
|
||||
checkbox.addEventListener( 'change', updateAriaExpanded );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} list
|
||||
* @return {void}
|
||||
*/
|
||||
function resizeOverflowList( list ) {
|
||||
var rect = list.getClientRects()[ 0 ];
|
||||
if ( rect ) {
|
||||
list.style.maxHeight = window.document.documentElement.clientHeight - rect.top + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize page edit action link (#ca-edit)
|
||||
*
|
||||
* Mark the edit link as disabled if the user is not actually able to edit the page for some
|
||||
* reason (e.g. page is protected or user is blocked).
|
||||
*
|
||||
* Note that the link is still clickable, but clicking it will probably open a view-source
|
||||
* form or display an error message, rather than open an edit form.
|
||||
*
|
||||
* FIXME: Review this code as part of T206262
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
function renderEditButton() {
|
||||
var
|
||||
// FIXME: create a utility method to generate class names instead of
|
||||
// constructing temporary objects. This affects disabledEditIcon,
|
||||
// enabledEditIcon, enabledEditIcon, and disabledClass and
|
||||
// a number of other places in the code base.
|
||||
disabledEditIcon = new Icon( {
|
||||
name: 'edit',
|
||||
glyphPrefix: 'minerva'
|
||||
} ),
|
||||
enabledEditIcon = new Icon( {
|
||||
name: 'edit-enabled',
|
||||
glyphPrefix: 'minerva'
|
||||
} ),
|
||||
enabledClass = enabledEditIcon.getGlyphClassName(),
|
||||
disabledClass = disabledEditIcon.getGlyphClassName();
|
||||
|
||||
if ( mw.config.get( 'wgMinervaReadOnly' ) ) {
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
$( '#ca-edit' )
|
||||
.removeClass( enabledClass )
|
||||
.addClass( disabledClass );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize and inject the download button
|
||||
*
|
||||
* There are many restrictions when we can show the download button, this function should handle
|
||||
* all device/os/operating system related checks and if device supports printing it will inject
|
||||
* the Download icon
|
||||
* @param {Window} window
|
||||
* @param {Element|null} overflowList
|
||||
* @return {void}
|
||||
*/
|
||||
function renderDownloadButton( window, overflowList ) {
|
||||
var $downloadAction = downloadPageAction( skin,
|
||||
mw.config.get( 'wgMinervaDownloadNamespaces', [] ), window, !!overflowList );
|
||||
|
||||
if ( $downloadAction ) {
|
||||
if ( overflowList ) {
|
||||
$downloadAction.appendTo( overflowList );
|
||||
} else {
|
||||
$downloadAction.insertAfter( '.page-actions-menu__list-item:first-child' );
|
||||
}
|
||||
|
||||
mw.track( 'minerva.downloadAsPDF', {
|
||||
action: 'buttonVisible'
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
M.define( 'skins.minerva.scripts/Toolbar', {
|
||||
selector: toolbarSelector,
|
||||
bind: bind,
|
||||
render: render
|
||||
} );
|
||||
}( mw.mobileFrontend ) );
|
|
@ -120,10 +120,17 @@
|
|||
* @param {Skin} skin
|
||||
* @param {number[]} supportedNamespaces
|
||||
* @param {Window} [windowObj] window object
|
||||
* @param {boolean} [hasText] Use icon + button style.
|
||||
* @returns {jQuery.Object|null}
|
||||
*/
|
||||
function downloadPageAction( skin, supportedNamespaces, windowObj ) {
|
||||
var icon, spinner = icons.spinner();
|
||||
function downloadPageAction( skin, supportedNamespaces, windowObj, hasText ) {
|
||||
var
|
||||
modifier = hasText ? 'toolbar-overflow-menu__list-item' : 'mw-ui-icon-element',
|
||||
icon,
|
||||
spinner = icons.spinner( {
|
||||
hasText: hasText,
|
||||
modifier: modifier
|
||||
} );
|
||||
|
||||
if (
|
||||
isAvailable(
|
||||
|
@ -139,11 +146,13 @@
|
|||
events: {
|
||||
// will be bound to `this`
|
||||
click: getOnClickHandler( spinner )
|
||||
}
|
||||
},
|
||||
hasText: hasText,
|
||||
label: hasText ? mw.msg( 'minerva-download' ) : '',
|
||||
modifier: modifier
|
||||
} );
|
||||
|
||||
return $( '<li>' ).addClass( 'page-actions-menu__list-item' ).append( icon.$el ).append( spinner.$el.hide() );
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
( function ( M, track, config ) {
|
||||
( function ( M ) {
|
||||
var
|
||||
mobile = M.require( 'mobile.startup' ),
|
||||
PageGateway = mobile.PageGateway,
|
||||
toast = mobile.toast,
|
||||
time = mobile.time,
|
||||
skin = M.require( 'mobile.init/skin' ),
|
||||
TitleUtil = M.require( 'skins.minerva.scripts/TitleUtil' ),
|
||||
issues = M.require( 'skins.minerva.scripts/pageIssues' ),
|
||||
downloadPageAction = M.require( 'skins.minerva.scripts/downloadPageAction' ),
|
||||
Toolbar = M.require( 'skins.minerva.scripts/Toolbar' ),
|
||||
router = require( 'mediawiki.router' ),
|
||||
OverlayManager = mobile.OverlayManager,
|
||||
CtaDrawer = mobile.CtaDrawer,
|
||||
Icon = mobile.Icon,
|
||||
Button = mobile.Button,
|
||||
Anchor = mobile.Anchor,
|
||||
overlayManager = OverlayManager.getSingleton(),
|
||||
|
@ -197,28 +195,6 @@
|
|||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize and inject the download button
|
||||
*
|
||||
* There are many restrictions when we can show the download button, this function should handle
|
||||
* all device/os/operating system related checks and if device supports printing it will inject
|
||||
* the Download icon
|
||||
* @ignore
|
||||
*/
|
||||
function appendDownloadButton() {
|
||||
var $downloadAction = downloadPageAction( skin,
|
||||
config.get( 'wgMinervaDownloadNamespaces', [] ), window );
|
||||
|
||||
if ( $downloadAction ) {
|
||||
|
||||
$downloadAction.insertAfter( '.page-actions-menu__list-item:first-child' );
|
||||
|
||||
track( 'minerva.downloadAsPDF', {
|
||||
action: 'buttonVisible'
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a URL to determine if it links to a local User namespace page or not.
|
||||
*
|
||||
|
@ -317,54 +293,19 @@
|
|||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize page edit action link (#ca-edit)
|
||||
*
|
||||
* Mark the edit link as disabled if the user is not actually able to edit the page for some
|
||||
* reason (e.g. page is protected or user is blocked).
|
||||
*
|
||||
* Note that the link is still clickable, but clicking it will probably open a view-source
|
||||
* form or display an error message, rather than open an edit form.
|
||||
*
|
||||
* FIXME: Review this code as part of T206262
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
function initEditLink() {
|
||||
var
|
||||
// FIXME: create a utility method to generate class names instead of
|
||||
// constructing temporary objects. This affects disabledEditIcon,
|
||||
// enabledEditIcon, enabledEditIcon, and disabledClass and
|
||||
// a number of other places in the code base.
|
||||
disabledEditIcon = new Icon( {
|
||||
name: 'edit',
|
||||
glyphPrefix: 'minerva'
|
||||
} ),
|
||||
enabledEditIcon = new Icon( {
|
||||
name: 'edit-enabled',
|
||||
glyphPrefix: 'minerva'
|
||||
} ),
|
||||
enabledClass = enabledEditIcon.getGlyphClassName(),
|
||||
disabledClass = disabledEditIcon.getGlyphClassName();
|
||||
|
||||
if ( mw.config.get( 'wgMinervaReadOnly' ) ) {
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
$( '#ca-edit' )
|
||||
.removeClass( enabledClass )
|
||||
.addClass( disabledClass );
|
||||
}
|
||||
}
|
||||
|
||||
$( function () {
|
||||
var toolbarElement = document.querySelector( Toolbar.selector );
|
||||
// Update anything else that needs enhancing (e.g. watchlist)
|
||||
initModifiedInfo();
|
||||
initRegistrationInfo();
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
initHistoryLink( $( '.last-modifier-tagline a' ) );
|
||||
appendDownloadButton();
|
||||
if ( toolbarElement ) {
|
||||
Toolbar.bind( window, toolbarElement, eventBus );
|
||||
Toolbar.render( window, toolbarElement );
|
||||
}
|
||||
initRedlinksCta();
|
||||
initUserRedLinks();
|
||||
initEditLink();
|
||||
// Setup the issues banner on the page
|
||||
// Pages which dont exist (id 0) cannot have issues
|
||||
if ( !page.isMissing ) {
|
||||
|
@ -373,4 +314,4 @@
|
|||
} );
|
||||
|
||||
M.define( 'skins.minerva.scripts/overlayManager', overlayManager );
|
||||
}( mw.mobileFrontend, mw.track, mw.config ) );
|
||||
}( mw.mobileFrontend ) );
|
||||
|
|
1
resources/wikimedia.ui/articleRedirect-ltr.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path d="M5 1a2 2 0 0 0-2 2v1c0 5 2 8 7 8V9l5 4-5 4v-3c-3.18 0-5.51-.85-7-2.68V17a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/></svg>
|
After Width: | Height: | Size: 290 B |
1
resources/wikimedia.ui/articleRedirect-rtl.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>article redirect</title><path d="M3 17c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2v-5.7c-1.5 1.8-3.8 2.7-7 2.7v3l-5-4 5-4v3c5 0 7-3 7-8V3c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2z"/></svg>
|
After Width: | Height: | Size: 296 B |
1
resources/wikimedia.ui/info.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>info</title><path d="M9.5 16A6.61 6.61 0 0 1 3 9.5 6.61 6.61 0 0 1 9.5 3 6.61 6.61 0 0 1 16 9.5 6.63 6.63 0 0 1 9.5 16zm0-14A7.5 7.5 0 1 0 17 9.5 7.5 7.5 0 0 0 9.5 2zm.5 6v4.08h1V13H8.07v-.92H9V9H8V8zM9 6h1v1H9z"/></svg>
|
After Width: | Height: | Size: 348 B |
1
resources/wikimedia.ui/link.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>link</title><path d="M4.83 15h2.91a4.88 4.88 0 0 1-1.55-2H5a3 3 0 1 1 0-6h3a3 3 0 0 1 2.82 4h2.1a4.82 4.82 0 0 0 .08-.83v-.34A4.83 4.83 0 0 0 8.17 5H4.83A4.83 4.83 0 0 0 0 9.83v.34A4.83 4.83 0 0 0 4.83 15z"/><path d="M15.17 5h-2.91a4.88 4.88 0 0 1 1.55 2H15a3 3 0 1 1 0 6h-3a3 3 0 0 1-2.82-4h-2.1a4.82 4.82 0 0 0-.08.83v.34A4.83 4.83 0 0 0 11.83 15h3.34A4.83 4.83 0 0 0 20 10.17v-.34A4.83 4.83 0 0 0 15.17 5z"/></svg>
|
After Width: | Height: | Size: 545 B |
1
resources/wikimedia.ui/listBullet-ltr.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bullet list</title><path d="M7 15h12v2H7zm0-6h12v2H7zm0-6h12v2H7z"/><circle cx="3" cy="4" r="2"/><circle cx="3" cy="10" r="2"/><circle cx="3" cy="16" r="2"/></svg>
|
After Width: | Height: | Size: 291 B |
1
resources/wikimedia.ui/listBullet-rtl.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bullet list</title><path d="M1 15h12v2H1zm0-6h12v2H1zm0-6h12v2H1z"/><circle cx="17" cy="4" r="2"/><circle cx="17" cy="10" r="2"/><circle cx="17" cy="16" r="2"/></svg>
|
After Width: | Height: | Size: 294 B |
1
resources/wikimedia.ui/logo-Wikidata.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" stroke-width="30.2" viewBox="0 0 20 20"><title>Wikidata logo</title><path stroke="#000" stroke-width=".743" d="M.371 4v12.257m1.482 0V4m.74 0v12.257m.741 0V4m1.481 0v12.257m.741 0V4m.74 0v12.257M7.778 4v12.257m1.481 0V4m8.888 0v12.257m1.482 0V4M10.74 4v12.257m.741 0V4m.741 0v12.257m1.481 0V4m1.482 0v12.257m.74 0V4m.74 0v12.257"/></svg>
|
After Width: | Height: | Size: 438 B |
1
resources/wikimedia.ui/logo-Wikimedia.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>Wikimedia logo</title><clipPath id="a"><path d="M0-33l471 471v363h82V438l471-471v1057H0"/></clipPath><g clip-path="url(#a)" transform="matrix(.021 0 0 .021 -.756 -.588)"><path d="M511 224a288 288 0 1 0 2 0"/><path fill="none" stroke="#000" stroke-width="116" d="M511 102a410 410 0 1 0 2 0"/></g><circle cx="10" cy="3.32" r="3.32"/></svg>
|
After Width: | Height: | Size: 465 B |
1
resources/wikimedia.ui/quotes-ltr.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>quotes</title><path d="M7 6l1-2H6C3.79 4 2 6.79 2 9v7h7V9H5c0-3 2-3 2-3zm7 3c0-3 2-3 2-3l1-2h-2c-2.21 0-4 2.79-4 5v7h7V9z"/></svg>
|
After Width: | Height: | Size: 258 B |
1
resources/wikimedia.ui/quotes-rtl.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>quotes</title><path d="M11 9v7h7V9c0-2.2-1.8-5-4-5h-2l1 2s2 0 2 3zM2 9v7h7V9c0-2.2-1.8-5-4-5H3l1 2s2 0 2 3z"/></svg>
|
After Width: | Height: | Size: 244 B |
1
resources/wikimedia.ui/upload.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>upload</title><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M10 1L5 7h4v8h2V7h4z"/></svg>
|
After Width: | Height: | Size: 244 B |
1
resources/wikimedia.ui/userAvatar.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>user avatar</title><path d="M10 11c-5.92 0-8 3-8 5v3h16v-3c0-2-2.08-5-8-5z"/><circle cx="10" cy="5.5" r="4.5"/></svg>
|
After Width: | Height: | Size: 245 B |
48
skin.json
|
@ -45,6 +45,11 @@
|
|||
"beta": false,
|
||||
"amc": true
|
||||
},
|
||||
"MinervaOverflowInPageActions": {
|
||||
"base": false,
|
||||
"beta": false,
|
||||
"amc": false
|
||||
},
|
||||
"MinervaShowCategoriesButton": {
|
||||
"base": false,
|
||||
"beta": true
|
||||
|
@ -231,6 +236,44 @@
|
|||
"resources/skins.minerva.amc.styles/index.less"
|
||||
]
|
||||
},
|
||||
"wikimedia.ui": {
|
||||
"class": "ResourceLoaderImageModule",
|
||||
"selectorWithoutVariant": ".wikimedia-ui-{name}:before",
|
||||
"selectorWithVariant": ".wikimedia-ui-{name}-{variant}:before",
|
||||
"useDataURI": false,
|
||||
"variants": {
|
||||
"base20": {
|
||||
"color": "#54595d",
|
||||
"global": true
|
||||
}
|
||||
},
|
||||
"images": {
|
||||
"articleRedirect": {
|
||||
"file": {
|
||||
"ltr": "resources/wikimedia.ui/articleRedirect-ltr.svg",
|
||||
"rtl": "resources/wikimedia.ui/articleRedirect-rtl.svg"
|
||||
}
|
||||
},
|
||||
"info": "resources/wikimedia.ui/info.svg",
|
||||
"link": "resources/wikimedia.ui/link.svg",
|
||||
"listBullet": {
|
||||
"file": {
|
||||
"ltr": "resources/wikimedia.ui/listBullet-ltr.svg",
|
||||
"rtl": "resources/wikimedia.ui/listBullet-rtl.svg"
|
||||
}
|
||||
},
|
||||
"logo-Wikidata": "resources/wikimedia.ui/logo-Wikidata.svg",
|
||||
"logo-Wikimedia": "resources/wikimedia.ui/logo-Wikimedia.svg",
|
||||
"quotes": {
|
||||
"file": {
|
||||
"ltr": "resources/wikimedia.ui/quotes-ltr.svg",
|
||||
"rtl": "resources/wikimedia.ui/quotes-rtl.svg"
|
||||
}
|
||||
},
|
||||
"upload": "resources/wikimedia.ui/upload.svg",
|
||||
"userAvatar": "resources/wikimedia.ui/userAvatar.svg"
|
||||
}
|
||||
},
|
||||
"skins.minerva.icons.images": {
|
||||
"class": "ResourceLoaderImageModule",
|
||||
"selectorWithoutVariant": ".mw-ui-icon-minerva-{name}:before",
|
||||
|
@ -255,7 +298,8 @@
|
|||
"clock": {
|
||||
"file": "resources/skins.minerva.icons.images/clock.svg",
|
||||
"variants": [ "invert" ]
|
||||
}
|
||||
},
|
||||
"page-actions-overflow": "resources/skins.minerva.icons.images/page-actions-overflow.svg"
|
||||
}
|
||||
},
|
||||
"skins.minerva.icons.images.scripts": {
|
||||
|
@ -373,6 +417,7 @@
|
|||
"desktop"
|
||||
],
|
||||
"dependencies": [
|
||||
"wikimedia.ui",
|
||||
"skins.minerva.mainMenu.icons",
|
||||
"skins.minerva.mainMenu.styles",
|
||||
"jquery.cookie",
|
||||
|
@ -431,6 +476,7 @@
|
|||
"resources/skins.minerva.scripts/pageIssues.js",
|
||||
"resources/skins.minerva.scripts/UriUtil.js",
|
||||
"resources/skins.minerva.scripts/TitleUtil.js",
|
||||
"resources/skins.minerva.scripts/Toolbar.js",
|
||||
"resources/skins.minerva.scripts/init.js",
|
||||
"resources/skins.minerva.scripts/initLogging.js",
|
||||
"resources/skins.minerva.scripts/mobileRedirect.js",
|
||||
|
|