wiki.techinc.nl/includes/OutputTransform/OutputTransformPipeline.php
Isabelle Hurbain-Palatin cd3240f044 Introduce runOutputPipeline and clone by default
This is the third patch of a series of patches to remove
ParserOutput::getText() calls from core. This series of patches should
be functionally equivalent to I2b4bcddb234f10fd8592570cb0496adf3271328e.

Here we temporarily introduce runOutputPipeline in ParserOutput. It
creates and runs the pipeline with default options, and is called by
getText. (This is not entirely truthful because we go through a
runPipelineInternal transient method for null-argument-passing reasons,
but let's not over-complicate this commit message.)

getText is responsible for maintaining the current behaviour,
that is "disallow the cloning of the ParserOutput and putting text back
to as it was" to mitigate T353257. As we get rid of getText, this
behaviour should be moved, if necessary, to the caller site.

The new method is currently added to ParserOutput so that further
refactorings are, for the moment, simpler. It will eventually be moved
to another place within the Content framework.

We also rename 'suppressClone' to 'allowClone' (which is actually its
negation) to avoid multiple levels of negations that make the code
confusing. Note that the default value of 'allowClone' is true, and is
currently overriden in two places: getText and
OutputPage::getParserOutputText (which calls the pipeline directly and
not through ParserOutput).

Bug: T293512
Bug: T371022
Change-Id: Ibf04af1079aaa1934dc78685b00e636ff4d38a9a
2024-09-06 19:06:38 +00:00

85 lines
3.8 KiB
PHP

<?php
namespace MediaWiki\OutputTransform;
use MediaWiki\Parser\ParserOutput;
use MediaWiki\Parser\ParserOutputFlags;
use MediaWiki\Parser\Parsoid\PageBundleParserOutputConverter;
use ParserOptions;
/**
* @unstable
*/
class OutputTransformPipeline {
/** @var OutputTransformStage[] */
private array $stages = [];
public function addStage( OutputTransformStage $stage ): OutputTransformPipeline {
$this->stages[] = $stage;
return $this;
}
/**
* Runs the pipeline on the ParserOutput, yielding a transformed ParserOutput.
* @param ParserOutput $in Parser output to which the transformations are
* applied. It is typically copied before applying transformations and is
* hence not mutated by this method, but if $options['allowClone'] is
* set it to false WILL be mutated!
* @param ?ParserOptions $popts - will eventually replace options as container
* for transformation options
* @param array $options Transformations to apply to the HTML
* - allowClone: (bool) Whether to clone the ParserOutput before
* applying transformations. Default is true.
* - allowTOC: (bool) Show the TOC, assuming there were enough headings
* to generate one and `__NOTOC__` wasn't used. Default is true,
* but might be statefully overridden.
* - injectTOC: (bool) Replace the TOC_PLACEHOLDER with TOC contents;
* otherwise the marker will be left in the article (and the skin
* will be responsible for replacing or removing it). Default is
* true.
* - enableSectionEditLinks: (bool) Include section edit links, assuming
* section edit link tokens are present in the HTML. Default is true,
* but might be statefully overridden.
* - userLang: (Language) Language object used for localizing UX messages,
* for example the heading of the table of contents. If omitted, will
* use the language of the main request context.
* - skin: (Skin) Skin object used for transforming section edit links.
* - 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, `<style>`
* tags with the `data-mw-deduplicate` attribute set are deduplicated by
* value of the attribute: all but the first will be replaced by `<link
* rel="mw-deduplicated-inline-style" href="mw-data:..."/>` tags, where
* the scheme-specific-part of the href is the (percent-encoded) value
* of the `data-mw-deduplicate` attribute.
* - absoluteURLs: (bool) use absolute URLs in all links. Default: false
* - includeDebugInfo: (bool) render PP limit report in HTML. Default: false
*/
public function run( ParserOutput $in, ?ParserOptions $popts, array $options ): ParserOutput {
// Initialize some $options from the ParserOutput
$options += [
'enableSectionEditLinks' => !$in->getOutputFlag( ParserOutputFlags::NO_SECTION_EDIT_LINKS ),
'wrapperDivClass' => $in->getWrapperDivClass(),
'isParsoidContent' => PageBundleParserOutputConverter::hasPageBundle( $in ),
];
if ( $options['allowClone'] ?? true ) {
$out = clone $in;
} else {
// T353257: This should be a clone, but we've need to suppress it
// for some legacy codepaths.
$out = $in;
}
foreach ( $this->stages as $stage ) {
if ( $stage->shouldRun( $out, $popts, $options ) ) {
// Some stages may (for now) modify $options. See OutputTransformStage documentation for more info.
$out = $stage->transform( $out, $popts, $options );
}
}
return $out;
}
}