title = $title; $this->user = $user; $this->messageLocalizer = $msgLocalizer; $this->permissions = $permissions; $this->skinOptions = $skinOptions; $this->userPageHelper = $userPageHelper; $this->languagesHelper = $languagesHelper; } /** * @return Group * @throws MWException */ public function getGroup(): Group { $group = new Group( 'p-views' ); $permissions = $this->permissions; $userPageWithOveflowMode = $this->skinOptions->get( SkinOptions::TOOLBAR_SUBMENU ) && $this->userPageHelper->isUserPage(); if ( !$userPageWithOveflowMode && $permissions->isAllowed( IMinervaPagePermissions::SWITCH_LANGUAGE ) ) { $group->insertEntry( new LanguageSelectorEntry( $this->title, $this->languagesHelper->doesTitleHasLanguagesOrVariants( $this->title ), $this->messageLocalizer, MinervaUI::iconClass( 'language-switcher', 'element', 'mw-ui-icon-with-label-desktop' ) ) ); } if ( $permissions->isAllowed( IMinervaPagePermissions::WATCH ) ) { $group->insertEntry( $this->createWatchPageAction() ); } if ( $permissions->isAllowed( IMinervaPagePermissions::HISTORY ) ) { $group->insertEntry( $this->getHistoryPageAction() ); } if ( $userPageWithOveflowMode ) { // User links are hidden when Overflow menu is visible. We want to show Contributions // link on toolbar only when overflow is visible $group->insertEntry( $this->createContributionsPageAction() ); } Hooks::run( 'MobileMenu', [ 'pageactions.toolbar', &$group ] ); // We want the edit icon/action always to be the last element on the toolbar list if ( $permissions->isAllowed( IMinervaPagePermissions::CONTENT_EDIT ) ) { $group->insertEntry( $this->createEditPageAction() ); } return $group; } /** * Create Contributions page action visible on user pages * * @return IMenuEntry */ protected function createContributionsPageAction(): IMenuEntry { $pageUser = $this->userPageHelper->getPageUser(); $label = $this->messageLocalizer->msg( 'mobile-frontend-user-page-contributions' ); $entry = new SingleMenuEntry( 'page-actions-contributions', $label, SpecialPage::getTitleFor( 'Contributions', $pageUser )->getLocalURL() ); $entry->setTitle( $label ) ->trackClicks( 'contributions' ) ->setIcon( 'contributions', 'with-label-desktop' ); return $entry; } /** * Creates the "edit" page action: the well-known pencil icon that, when tapped, will open an * editor with the lead section loaded. * * @return IMenuEntry An edit page actions menu entry * @throws MWException * @throws \Exception */ protected function createEditPageAction(): IMenuEntry { $title = $this->title; $editArgs = [ 'action' => 'edit' ]; if ( $title->isWikitextPage() ) { // If the content model is wikitext we'll default to editing the lead section. // Full wikitext editing is hard on mobile devices. $editArgs['section'] = SkinMinerva::LEAD_SECTION_NUMBER; } $editOrCreate = $this->permissions->isAllowed( IMinervaPagePermissions::EDIT_OR_CREATE ); $entry = new SingleMenuEntry( 'page-actions-edit', $this->messageLocalizer->msg( 'mobile-frontend-editor-edit' ), $title->getLocalURL( $editArgs ), 'edit-page' ); $entry->setIcon( $editOrCreate ? 'edit-enabled' : 'edit', 'element', 'mw-ui-icon-with-label-desktop' ) ->trackClicks( 'edit' ) ->setTitle( $this->messageLocalizer->msg( 'mobile-frontend-pageaction-edit-tooltip' ) ) ->setNodeID( 'ca-edit' ); return $entry; } /** * Creates the "watch" or "unwatch" action: the well-known star icon that, when tapped, will * add the page to or remove the page from the user's watchlist; or, if the user is logged out, * will direct the user's UA to Special:Login. * * @return IMenuEntry An watch/unwatch page actions menu entry * @throws MWException */ protected function createWatchPageAction(): IMenuEntry { $title = $this->title; $user = $this->user; $isWatched = $title && $user->isLoggedIn() && $user->isWatched( $title ); $newModeToSet = $isWatched ? 'unwatch' : 'watch'; $href = $user->isAnon() ? $this->getLoginUrl( [ 'returnto' => $title ] ) : $title->getLocalURL( [ 'action' => $newModeToSet ] ); if ( $isWatched ) { $msg = $this->messageLocalizer->msg( 'unwatch' ); $icon = 'unStar-progressive'; } else { $msg = $this->messageLocalizer->msg( 'watch' ); $icon = 'star-base20'; } $iconClass = MinervaUI::iconClass( $icon, 'element', 'mw-ui-icon-with-label-desktop watch-this-article', 'wikimedia' ); if ( $isWatched ) { $iconClass .= ' watched'; } $entry = new SingleMenuEntry( 'page-actions-watch', $msg->text(), $href, $iconClass . ' mw-watchlink' ); return $entry->trackClicks( $newModeToSet ) ->setTitle( $msg ) ->setNodeID( 'ca-watch' ); } /** * Creates a history action: An icon that links to the mobile history page. * * @return IMenuEntry A menu entry object that represents a map of HTML attributes * and a 'text' property to be used with the pageActionMenu.mustache template. * @throws MWException */ protected function getHistoryPageAction(): IMenuEntry { return SingleMenuEntry::create( 'page-actions-history', $this->messageLocalizer->msg( 'minerva-page-actions-history' )->escaped(), $this->getHistoryUrl( $this->title ) ) ->setIcon( 'clock', 'element', 'mw-ui-icon-with-label-desktop' ) ->trackClicks( 'history' ); } /** * Get the URL for the history page for the given title using Special:History * when available. * FIXME: temporary duplicated code, same as SkinMinerva::getHistoryUrl() * @param Title $title The Title object of the page being viewed * @return string * @throws MWException */ protected function getHistoryUrl( Title $title ) { return ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' ) && SpecialMobileHistory::shouldUseSpecialHistory( $title, $this->user ) ? SpecialPage::getTitleFor( 'History', $title )->getLocalURL() : $title->getLocalURL( [ 'action' => 'history' ] ); } /** * Prepares a url to the Special:UserLogin with query parameters * @param array $query * @return string * @throws MWException */ private function getLoginUrl( $query ) { return SpecialPage::getTitleFor( 'Userlogin' )->getLocalURL( $query ); } }