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