Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
OutputTransformPipeline
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 2
30
0.00% covered (danger)
0.00%
0 / 1
 addStage
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 run
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace MediaWiki\OutputTransform;
4
5use MediaWiki\Parser\ParserOptions;
6use MediaWiki\Parser\ParserOutput;
7use MediaWiki\Parser\ParserOutputFlags;
8use MediaWiki\Parser\Parsoid\PageBundleParserOutputConverter;
9
10/**
11 * @unstable
12 */
13class OutputTransformPipeline {
14
15    /** @var OutputTransformStage[] */
16    private array $stages = [];
17
18    public function addStage( OutputTransformStage $stage ): OutputTransformPipeline {
19        $this->stages[] = $stage;
20        return $this;
21    }
22
23    /**
24     * Runs the pipeline on the ParserOutput, yielding a transformed ParserOutput.
25     * @param ParserOutput $in Parser output to which the transformations are
26     *     applied. It is typically copied before applying transformations and is
27     * hence not mutated by this method, but if $options['allowClone'] is
28     * set it to false WILL be mutated!
29     * @param ?ParserOptions $popts - will eventually replace options as container
30     *    for transformation options
31     * @param array $options Transformations to apply to the HTML
32     *  - allowClone: (bool) Whether to clone the ParserOutput before
33     *     applying transformations. Default is true.
34     *  - allowTOC: (bool) Show the TOC, assuming there were enough headings
35     *     to generate one and `__NOTOC__` wasn't used. Default is true,
36     *     but might be statefully overridden.
37     *  - injectTOC: (bool) Replace the TOC_PLACEHOLDER with TOC contents;
38     *     otherwise the marker will be left in the article (and the skin
39     *     will be responsible for replacing or removing it).  Default is
40     *     true.
41     *  - enableSectionEditLinks: (bool) Include section edit links, assuming
42     *     section edit link tokens are present in the HTML. Default is true,
43     *     but might be statefully overridden.
44     *  - userLang: (Language) Language object used for localizing UX messages,
45     *    for example the heading of the table of contents. If omitted, will
46     *    use the language of the main request context.
47     *  - skin: (Skin) Skin object used for transforming section edit links.
48     *  - unwrap: (bool) Return text without a wrapper div. Default is false,
49     *    meaning a wrapper div will be added if getWrapperDivClass() returns
50     *    a non-empty string.
51     *  - wrapperDivClass: (string) Wrap the output in a div and apply the given
52     *    CSS class to that div. This overrides the output of getWrapperDivClass().
53     *    Setting this to an empty string has the same effect as 'unwrap' => true.
54     *  - deduplicateStyles: (bool) When true, which is the default, `<style>`
55     *    tags with the `data-mw-deduplicate` attribute set are deduplicated by
56     *    value of the attribute: all but the first will be replaced by `<link
57     *    rel="mw-deduplicated-inline-style" href="mw-data:..."/>` tags, where
58     *    the scheme-specific-part of the href is the (percent-encoded) value
59     *    of the `data-mw-deduplicate` attribute.
60     *  - absoluteURLs: (bool) use absolute URLs in all links. Default: false
61     *  - includeDebugInfo: (bool) render PP limit report in HTML. Default: false
62     */
63    public function run( ParserOutput $in, ?ParserOptions $popts, array $options ): ParserOutput {
64        // Initialize some $options from the ParserOutput
65        $options += [
66            'enableSectionEditLinks' => !$in->getOutputFlag( ParserOutputFlags::NO_SECTION_EDIT_LINKS ),
67            'wrapperDivClass' => $in->getWrapperDivClass(),
68            'isParsoidContent' => PageBundleParserOutputConverter::hasPageBundle( $in ),
69        ];
70        if ( $options['allowClone'] ?? true ) {
71            $out = clone $in;
72        } else {
73            // T353257: This should be a clone, but we've need to suppress it
74            // for some legacy codepaths.
75            $out = $in;
76        }
77        foreach ( $this->stages as $stage ) {
78            if ( $stage->shouldRun( $out, $popts, $options ) ) {
79                // Some stages may (for now) modify $options. See OutputTransformStage documentation for more info.
80                $out = $stage->transform( $out, $popts, $options );
81            }
82        }
83        return $out;
84    }
85}