From 0dc7ba02b4483700a2fc3ab6bf76a3dd072ef054 Mon Sep 17 00:00:00 2001 From: daniel Date: Tue, 28 Aug 2018 18:48:10 +0200 Subject: [PATCH] Apply content wrapping in ParserOutput::getText() Instead of applying wrapping the the parser and unwrapping in ParserOutput::getText(), turn this around and apply wrapping in getText(), and only if desired. This avoids search&replace logic for unwrapping, and it also makes it a lot easier to merge the output of multiple slots for MCR output. This changes behavior in two hopefully irrelevant ways: 1) the limit report comments will be inside the wrapper div, instead of following it. 2) if HTML with a wrapper div is explicitly injected into a ParserOutput object, it will not be possible to unwrap the text. Bug: T174035 Change-Id: I1641b7995af9bd297f1acd610d583fbf874f34e0 --- includes/api/ApiParse.php | 2 +- includes/content/TextContent.php | 1 + includes/parser/Parser.php | 2 +- includes/parser/ParserOutput.php | 60 +++++++--- tests/phpunit/includes/api/ApiParseTest.php | 6 +- .../includes/parser/ParserMethodsTest.php | 12 ++ .../includes/parser/ParserOutputTest.php | 107 ++++++++++-------- 7 files changed, 123 insertions(+), 67 deletions(-) diff --git a/includes/api/ApiParse.php b/includes/api/ApiParse.php index 3a604715bc..5c25b5a0e5 100644 --- a/includes/api/ApiParse.php +++ b/includes/api/ApiParse.php @@ -341,7 +341,7 @@ class ApiParse extends ApiBase { $result_array['text'] = $p_result->getText( [ 'allowTOC' => !$params['disabletoc'], 'enableSectionEditLinks' => !$params['disableeditsection'], - 'unwrap' => $params['wrapoutputclass'] === '', + 'wrapperDivClass' => $params['wrapoutputclass'], 'deduplicateStyles' => !$params['disablestylededuplication'], ] ); $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text'; diff --git a/includes/content/TextContent.php b/includes/content/TextContent.php index 20bce3701a..0198a0de11 100644 --- a/includes/content/TextContent.php +++ b/includes/content/TextContent.php @@ -253,6 +253,7 @@ class TextContent extends AbstractContent { $html = ''; } + $output->clearWrapperDivClass(); $output->setText( $html ); } diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php index 6bee1692c4..47f81e612a 100644 --- a/includes/parser/Parser.php +++ b/includes/parser/Parser.php @@ -517,7 +517,7 @@ class Parser { # with CSS (T37247) $class = $this->mOptions->getWrapOutputClass(); if ( $class !== false && !$this->mOptions->getInterfaceMessage() ) { - $text = Html::rawElement( 'div', [ 'class' => $class ], $text ); + $this->mOutput->addWrapperDivClass( $class ); } $this->mOutput->setText( $text ); diff --git a/includes/parser/ParserOutput.php b/includes/parser/ParserOutput.php index 182648a94f..fe9913d174 100644 --- a/includes/parser/ParserOutput.php +++ b/includes/parser/ParserOutput.php @@ -212,6 +212,11 @@ class ParserOutput extends CacheTime { /** @var int|null Assumed rev ID for {{REVISIONID}} if no revision is set */ private $mSpeculativeRevId; + /** string CSS classes to use for the wrapping div, stored in the array keys. + * If no class is given, no wrapper is added. + */ + private $mWrapperDivClasses = []; + /** @var int Upper bound of expiry based on parse duration */ private $mMaxAdaptiveExpiry = INF; @@ -258,7 +263,12 @@ class ParserOutput extends CacheTime { * - enableSectionEditLinks: (bool) Include section edit links, assuming * section edit link tokens are present in the HTML. Default is true, * but might be statefully overridden. - * - unwrap: (bool) Remove a wrapping mw-parser-output div. Default is false. + * - unwrap: (bool) Return text without a wrapper div. Default is false, + * meaning a wrapper div will be added if getWrapperDivClass() returns + * a non-empty string. + * - wrapperDivClass: (string) Wrap the output in a div and apply the given + * CSS class to that div. This overrides the output of getWrapperDivClass(). + * Setting this to an empty string has the same effect as 'unwrap' => true. * - deduplicateStyles: (bool) When true, which is the default, `