title = $title; $this->user = $user; $this->messageLocalizer = $msgLocalizer; $this->permissions = $permissions; $this->skinOptions = $skinOptions; $this->relevantUserPageHelper = $relevantUserPageHelper; $this->languagesHelper = $languagesHelper; $this->watchlistExpiryEnabled = $options->get( 'WatchlistExpiry' ); $this->watchlistManager = $watchlistManager; } /** * @return Group * @throws MWException */ public function getGroup(): Group { $group = new Group( 'p-views' ); $permissions = $this->permissions; $userPageOrUserTalkPageWithOverflowMode = $this->skinOptions->get( SkinOptions::TOOLBAR_SUBMENU ) && $this->relevantUserPageHelper->isUserPage(); if ( !$userPageOrUserTalkPageWithOverflowMode && $permissions->isAllowed( IMinervaPagePermissions::SWITCH_LANGUAGE ) ) { $group->insertEntry( new LanguageSelectorEntry( $this->title, $this->languagesHelper->doesTitleHasLanguagesOrVariants( $this->title ), $this->messageLocalizer, MinervaUI::iconClass( 'language-base20', 'element', 'mw-ui-icon-with-label-desktop', 'wikimedia' ) ) ); } if ( $permissions->isAllowed( IMinervaPagePermissions::WATCH ) ) { $group->insertEntry( $this->createWatchPageAction() ); } if ( $permissions->isAllowed( IMinervaPagePermissions::HISTORY ) ) { $group->insertEntry( $this->getHistoryPageAction() ); } $isUserPage = $this->relevantUserPageHelper->isUserPage(); $isUserPageAccessible = $this->relevantUserPageHelper->isUserPageAccessibleToCurrentUser(); if ( $isUserPage && $isUserPageAccessible ) { // T235681: Contributions icon should be added to toolbar on user pages // and user talk pages for all users $user = $this->relevantUserPageHelper->getPageUser(); $group->insertEntry( $this->createContributionsPageAction( $user ) ); } 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 or user talk pages * for given $user * * @param User $user Determines what the contribution page action will link to * @return IMenuEntry */ protected function createContributionsPageAction( UserIdentity $user ): IMenuEntry { $label = $this->messageLocalizer->msg( 'mobile-frontend-user-page-contributions' ); $entry = new SingleMenuEntry( 'page-actions-contributions', $label->escaped(), SpecialPage::getTitleFor( 'Contributions', $user->getName() )->getLocalURL() ); $entry->setTitle( $label ) ->trackClicks( 'contributions' ) ->setIcon( 'userContributions', 'element', // FIXME: mw-ui-icon-minerva-contributions and mw-ui-icon-minerva-userContributions // can be removed after cache has cleared (I6c908acd70c0dca5bcb1754d1b25d3da2389feb8) 'mw-ui-icon-with-label-desktop mw-ui-icon-minerva-contributions ' . 'mw-ui-icon-minerva-userContributions' ); 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' )->escaped(), $title->getLocalURL( $editArgs ), 'edit-page' ); $entry->setIcon( $editOrCreate ? 'edit-base20' : 'editLock-base20', 'element', 'mw-ui-icon-with-label-desktop', 'wikimedia' ) ->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 { $isWatched = $this->user->isRegistered() && $this->watchlistManager->isWatched( $this->user, $this->title ); $isTempWatched = $this->watchlistExpiryEnabled && $isWatched && $this->watchlistManager->isTempWatched( $this->user, $this->title ); $newModeToSet = $isWatched ? 'unwatch' : 'watch'; $href = $this->user->isAnon() ? $this->getLoginUrl( [ 'returnto' => $this->title ] ) : $this->title->getLocalURL( [ 'action' => $newModeToSet ] ); if ( $isWatched ) { $msg = $this->messageLocalizer->msg( 'unwatch' ); $icon = $isTempWatched ? 'halfStar-progressive' : '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 ( $isTempWatched ) { $iconClass .= ' temp-watched'; } elseif ( $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 { $entry = new SingleMenuEntry( 'page-actions-history', $this->messageLocalizer->msg( 'minerva-page-actions-history' )->escaped(), $this->getHistoryUrl( $this->title ) ); $entry->setIcon( 'history-base20', 'element', 'mw-ui-icon-with-label-desktop', 'wikimedia' ) ->trackClicks( 'history' ); return $entry; } /** * 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 ); } }