From 6eea6d93a1373bbaf4bbac66d2720ff2a7f0e995 Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Tue, 27 Sep 2016 16:04:44 -0700 Subject: [PATCH] Used parsed section titles for anchors This allows us to link to the right section when the section title contains templates or magic words. * Add getParsedSectionTitle() * Use it in getTitleWithSection() ** Stop using Parser::guessSectionNameFromWikiText() because it wants preprocessed wikitext, not fully parsed and stripped text * Move getTruncatedSectionTitle() from EventPresentationModel to PresentationModelSectionTrait and make it use getParsedSectionTitle() Bug: T134216 Change-Id: I877ff6b0ce4e64400f6e5f6284ae47a11cd4335b --- .../EditUserTalkPresentationModel.php | 2 +- .../formatters/EventPresentationModel.php | 9 --- .../formatters/MentionPresentationModel.php | 2 +- .../PresentationModelSectionTrait.php | 62 ++++++++++++++----- 4 files changed, 50 insertions(+), 25 deletions(-) diff --git a/includes/formatters/EditUserTalkPresentationModel.php b/includes/formatters/EditUserTalkPresentationModel.php index 0ed6f5f62..d03c47c32 100644 --- a/includes/formatters/EditUserTalkPresentationModel.php +++ b/includes/formatters/EditUserTalkPresentationModel.php @@ -47,7 +47,7 @@ class EchoEditUserTalkPresentationModel extends EchoEventPresentationModel { } elseif ( $this->hasSection() ) { $msg = $this->getMessageWithAgent( "notification-header-{$this->type}-with-section" ); $msg->params( $this->getViewingUserForGender() ); - $msg->plaintextParams( $this->getTruncatedSectionTitle( $this->getSection() ) ); + $msg->plaintextParams( $this->getTruncatedSectionTitle() ); return $msg; } else { $msg = parent::getHeaderMessage(); diff --git a/includes/formatters/EventPresentationModel.php b/includes/formatters/EventPresentationModel.php index 7826f5ca1..020e1f829 100644 --- a/includes/formatters/EventPresentationModel.php +++ b/includes/formatters/EventPresentationModel.php @@ -509,15 +509,6 @@ abstract class EchoEventPresentationModel implements JsonSerializable { return $this->language->embedBidi( $this->language->truncate( $text, self::PAGE_NAME_RECOMMENDED_LENGTH, '...', false ) ); } - protected function getTruncatedSectionTitle( $section ) { - return $this->language->embedBidi( $this->language->truncate( - EchoDiscussionParser::getTextSnippet( $section, $this->language, 150, $this->event->getTitle() ), - self::SECTION_TITLE_RECOMMENDED_LENGTH, - '...', - false - ) ); - } - /** * @param User|null $user * @return array|null diff --git a/includes/formatters/MentionPresentationModel.php b/includes/formatters/MentionPresentationModel.php index fe38ba847..82abdac66 100644 --- a/includes/formatters/MentionPresentationModel.php +++ b/includes/formatters/MentionPresentationModel.php @@ -50,7 +50,7 @@ class EchoMentionPresentationModel extends EchoEventPresentationModel { } if ( $this->hasSection() ) { - $msg->plaintextParams( $this->getTruncatedSectionTitle( $this->getSection() ) ); + $msg->plaintextParams( $this->getTruncatedSectionTitle() ); } return $msg; diff --git a/includes/formatters/PresentationModelSectionTrait.php b/includes/formatters/PresentationModelSectionTrait.php index a286330d4..bce88236a 100644 --- a/includes/formatters/PresentationModelSectionTrait.php +++ b/includes/formatters/PresentationModelSectionTrait.php @@ -3,29 +3,52 @@ * Trait that adds section title handling to an EchoEventPresentationModel subclass. */ trait EchoPresentationModelSectionTrait { - private $sectionTitle = null; + private $rawSectionTitle = null; + private $parsedSectionTitle = null; /** - * Get the section title + * Get the raw (unparsed) section title * @return string Section title */ - protected function getSection() { - if ( $this->sectionTitle !== null ) { - return $this->sectionTitle; + protected function getRawSectionTitle() { + if ( $this->rawSectionTitle !== null ) { + return $this->rawSectionTitle; } $sectionTitle = $this->event->getExtraParam( 'section-title' ); if ( !$sectionTitle ) { - $this->sectionTitle = false; + $this->rawSectionTitle = false; return false; } // Check permissions if ( !$this->userCan( Revision::DELETED_TEXT ) ) { - $this->sectionTitle = false; + $this->rawSectionTitle = false; return false; } - $this->sectionTitle = $sectionTitle; - return $this->sectionTitle; + $this->rawSectionTitle = $sectionTitle; + return $this->rawSectionTitle; + } + + /** + * Get the section title parsed to plain text + * @return string Section title (plain text) + */ + protected function getParsedSectionTitle() { + if ( $this->parsedSectionTitle !== null ) { + return $this->parsedSectionTitle; + } + $rawSectionTitle = $this->getRawSectionTitle(); + if ( !$rawSectionTitle ) { + $this->parsedSectionTitle = false; + return false; + } + $this->parsedSectionTitle = EchoDiscussionParser::getTextSnippet( + $rawSectionTitle, + $this->language, + 150, + $this->event->getTitle() + ); + return $this->parsedSectionTitle; } /** @@ -37,7 +60,7 @@ trait EchoPresentationModelSectionTrait { * @return boolean Whether there is a section */ protected function hasSection() { - return (bool)$this->getSection(); + return (bool)$this->getRawSectionTitle(); } /** @@ -45,11 +68,13 @@ trait EchoPresentationModelSectionTrait { * @return Title */ protected function getTitleWithSection() { - global $wgParser; $title = $this->event->getTitle(); - $section = $this->getSection(); - // guessSectionNameFromWikiText() returns '#foo', strip the '#' - $fragment = substr( $wgParser->guessSectionNameFromWikiText( $section ), 1 ); + $section = $this->getParsedSectionTitle(); + // Like Parser::guessSectionNameFromWikiText() but without the link stripping + $fragment = Sanitizer::escapeId( + Sanitizer::normalizeSectionNameWhitespace( $section ), + 'noninitial' + ); if ( $section ) { $title = Title::makeTitle( $title->getNamespace(), @@ -59,4 +84,13 @@ trait EchoPresentationModelSectionTrait { } return $title; } + + protected function getTruncatedSectionTitle() { + return $this->language->embedBidi( $this->language->truncate( + $this->getParsedSectionTitle(), + self::SECTION_TITLE_RECOMMENDED_LENGTH, + '...', + false + ) ); + } }