title = $title; $this->user = $user; $this->messageLocalizer = $msgLocalizer; $this->permissionsManager = $permissionManager; $this->permissions = $permissions; $this->skinOptions = $skinOptions; $this->userPageHelper = $userPageHelper; } /** * @param bool $doesPageHaveLanguages Whether the page is also available in other languages * or variants * @return Group * @throws MWException */ public function getGroup( $doesPageHaveLanguages ): Group { $group = new Group(); $permissions = $this->permissions; if ( $permissions->isAllowed( IMinervaPagePermissions::SWITCH_LANGUAGE ) ) { $group->insertEntry( new LanguageSelectorEntry( $this->title, $doesPageHaveLanguages, $this->messageLocalizer ) ); } if ( $permissions->isAllowed( IMinervaPagePermissions::WATCH ) ) { $group->insertEntry( $this->createWatchPageAction() ); } if ( $permissions->isAllowed( IMinervaPagePermissions::HISTORY ) ) { $group->insertEntry( $this->getHistoryPageAction() ); } if ( $this->skinOptions->get( SkinOptions::OPTION_OVERFLOW_SUBMENU ) && $this->userPageHelper->isUserPage() ) { // 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::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' ); return PageActionMenuEntry::create( 'page-actions-contributions', SpecialPage::getTitleFor( 'Contributions', $pageUser )->getLocalURL(), MinervaUI::iconClass( 'contributions' ), $label )->setTitle( $label ); } /** * Creates the "edit" page action: the well-known pencil icon that, when tapped, will open an * editor with the lead section loaded. * * @return PageActionMenuEntry An edit page actions menu entry * @throws MWException * @throws \Exception */ protected function createEditPageAction(): IMenuEntry { $title = $this->title; $user = $this->user; $pm = $this->permissionsManager; $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; } $userQuickEditCheck = $pm->userCan( 'edit', $user, $title, PermissionManager::RIGOR_QUICK ) && ( $title->exists() || $pm->userCan( 'create', $user, $title, PermissionManager::RIGOR_QUICK ) ); $userBlockInfo = $user->isAnon() ? false : $pm->isBlockedFrom( $user, $title, true ); $userCanEdit = $userQuickEditCheck && !$userBlockInfo; $entry = new PageActionMenuEntry( 'page-actions-edit', $title->getLocalURL( $editArgs ), 'edit-page ' . MinervaUI::iconClass( $userCanEdit ? 'edit-enabled' : 'edit', 'element' ), $this->messageLocalizer->msg( 'mobile-frontend-editor-edit' ) ); return $entry ->setTitle( $this->messageLocalizer->msg( 'mobile-frontend-pageaction-edit-tooltip' ) ) ->setNodeID( 'ca-edit' ); } /** * 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 PageActionMenuEntry 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 ); $mode = $isWatched ? 'watch' : 'unwatch'; $href = $user->isAnon() ? $this->getLoginUrl( [ 'returnto' => $title ] ) : $title->getLocalURL( [ 'action' => $mode ] ); if ( $isWatched ) { $msg = $this->messageLocalizer->msg( 'unwatchthispage' ); $icon = 'watched'; } else { $msg = $this->messageLocalizer->msg( 'watchthispage' ); $icon = 'watch'; } $iconClass = MinervaUI::iconClass( $icon, 'element', 'watch-this-article' ) . ' jsonly'; if ( $isWatched ) { $iconClass .= ' watched'; } $entry = new PageActionMenuEntry( 'page-actions-watch', $href, $iconClass, $msg ); return $entry ->setTitle( $msg ) ->setNodeID( 'ca-watch' ); } /** * Creates a history action: An icon that links to the mobile history page. * * @return PageActionMenuEntry 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 new PageActionMenuEntry( 'page-actions-history', $this->getHistoryUrl( $this->title ), MinervaUI::iconClass( 'clock' ), $this->messageLocalizer->msg( 'mobile-frontend-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 ); } }