Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
81.21% covered (warning)
81.21%
670 / 825
69.93% covered (warning)
69.93%
100 / 143
CRAP
0.00% covered (danger)
0.00%
0 / 1
ParserOutput
81.31% covered (warning)
81.31%
670 / 824
69.93% covered (warning)
69.93%
100 / 143
1172.06
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 hasText
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRawText
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getText
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
1
 addCacheMessage
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addWrapperDivClass
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 clearWrapperDivClass
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWrapperDivClass
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setSpeculativeRevIdUsed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSpeculativeRevIdUsed
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setSpeculativePageIdUsed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSpeculativePageIdUsed
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRevisionTimestampUsed
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRevisionTimestampUsed
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRevisionUsedSha1Base36
66.67% covered (warning)
66.67%
4 / 6
0.00% covered (danger)
0.00%
0 / 1
4.59
 getRevisionUsedSha1Base36
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLanguageLinks
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getInterwikiLinks
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCategoryNames
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCategoryMap
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCategorySortKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIndicators
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTitleText
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTOCData
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCacheMessage
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSections
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getLinks
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLinksSpecial
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTemplates
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTemplateIds
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getImages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFileSearchOptions
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getExternalLinks
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setNoGallery
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getNoGallery
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHeadItems
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getModules
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getModuleStyles
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getJsConfigVars
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 getWarnings
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIndexPolicy
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getRevisionTimestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTimestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLimitReportData
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLimitReportJSData
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEnableOOUI
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getExtraCSPDefaultSrcs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getExtraCSPScriptSrcs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getExtraCSPStyleSrcs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRawText
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setText
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setLanguageLinks
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setTitleText
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setTOCData
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setSections
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 setIndexPolicy
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
3.04
 setRevisionTimestamp
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setTimestamp
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addCategory
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setCategories
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setIndicator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setEnableOOUI
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addLanguageLink
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 addWarningMsgVal
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 addWarningMsg
69.23% covered (warning)
69.23%
9 / 13
0.00% covered (danger)
0.00%
0 / 1
2.12
 setNewSection
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setHideNewSection
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHideNewSection
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNewSection
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isLinkInternal
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 addExternalLink
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 addLink
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
6
 addImage
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 addTemplate
71.43% covered (warning)
71.43%
5 / 7
0.00% covered (danger)
0.00%
0 / 1
2.09
 addInterwikiLink
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 addHeadItem
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 addModules
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addModuleStyles
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addJsConfigVars
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 setJsConfigVar
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
 appendJsConfigVar
72.73% covered (warning)
72.73%
8 / 11
0.00% covered (danger)
0.00%
0 / 1
5.51
 addOutputPageMetadata
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 setDisplayTitle
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getDisplayTitle
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getLanguage
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 setLanguage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRedirectHeader
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRedirectHeader
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRenderId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRenderId
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getAllFlags
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setPageProperty
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 setNumericPageProperty
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 setUnsortedPageProperty
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPageProperty
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 unsetPageProperty
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPageProperties
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 setOutputFlag
40.00% covered (danger)
40.00%
10 / 25
0.00% covered (danger)
0.00%
0 / 1
31.60
 getOutputFlag
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
9
 appendOutputStrings
94.74% covered (success)
94.74%
18 / 19
0.00% covered (danger)
0.00%
0 / 1
10.01
 getOutputStrings
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
7.04
 setExtensionData
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 appendExtensionData
72.73% covered (warning)
72.73%
8 / 11
0.00% covered (danger)
0.00%
0 / 1
5.51
 getExtensionData
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getTimes
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
 resetParseStartTime
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 recordTimeProfile
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
3.01
 getTimeProfile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTimeSinceStart
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 setLimitReportData
91.67% covered (success)
91.67%
11 / 12
0.00% covered (danger)
0.00%
0 / 1
6.02
 hasReducedExpiry
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 setPreventClickjacking
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPreventClickjacking
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 updateRuntimeAdaptiveExpiry
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addExtraCSPDefaultSrc
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addExtraCSPStyleSrc
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addExtraCSPScriptSrc
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 finalizeAdaptiveCacheExpiry
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
3
 setFromParserOptions
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
6
 __sleep
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 mergeInternalMetaDataFrom
70.00% covered (warning)
70.00%
28 / 40
0.00% covered (danger)
0.00%
0 / 1
22.91
 mergeHtmlMetaDataFrom
97.67% covered (success)
97.67%
42 / 43
0.00% covered (danger)
0.00%
0 / 1
14
 mergeTrackingMetaDataFrom
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
1
 collectMetadata
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 1
930
 mergeMixedList
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 mergeList
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 mergeMap
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 mergeMapStrategy
85.71% covered (warning)
85.71%
18 / 21
0.00% covered (danger)
0.00%
0 / 1
12.42
 merge2D
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
6.03
 useEachMinValue
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 useEachTotalValue
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 useMaxValue
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 toJsonArray
98.15% covered (success)
98.15%
53 / 54
0.00% covered (danger)
0.00%
0 / 1
5
 newFromJsonArray
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 initFromJson
98.04% covered (success)
98.04%
50 / 51
0.00% covered (danger)
0.00%
0 / 1
5
 detectAndEncodeBinary
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
4
 detectAndDecodeBinary
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
5
 __wakeup
100.00% covered (success)
100.00%
70 / 70
100.00% covered (success)
100.00%
1 / 1
11
 __clone
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 getContentHolderText
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setContentHolderText
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __get
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 __set
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21namespace MediaWiki\Parser;
22
23use CacheTime;
24use InvalidArgumentException;
25use LogicException;
26use MediaWiki\Edit\ParsoidRenderID;
27use MediaWiki\Json\JsonDeserializable;
28use MediaWiki\Json\JsonDeserializableTrait;
29use MediaWiki\Json\JsonDeserializer;
30use MediaWiki\MainConfigNames;
31use MediaWiki\MediaWikiServices;
32use MediaWiki\Message\Converter;
33use MediaWiki\Output\OutputPage;
34use MediaWiki\Parser\Parsoid\PageBundleParserOutputConverter;
35use MediaWiki\Title\Title;
36use MediaWiki\Title\TitleValue;
37use ParserOptions;
38use UnexpectedValueException;
39use Wikimedia\Bcp47Code\Bcp47Code;
40use Wikimedia\Bcp47Code\Bcp47CodeValue;
41use Wikimedia\Message\MessageValue;
42use Wikimedia\Parsoid\Core\ContentMetadataCollector;
43use Wikimedia\Parsoid\Core\ContentMetadataCollectorCompat;
44use Wikimedia\Parsoid\Core\LinkTarget as ParsoidLinkTarget;
45use Wikimedia\Parsoid\Core\TOCData;
46use Wikimedia\Reflection\GhostFieldAccessTrait;
47
48/**
49 * ParserOutput is a rendering of a Content object or a message.
50 * Content objects and messages often contain wikitext, but not always.
51 *
52 * `ParserOutput` object combine the HTML rendering of Content objects
53 * or messages, available via `::getRawText()`, with various bits of
54 * metadata generated during rendering, which may include categories,
55 * links, page properties, and extension data, among others.
56 *
57 * `ParserOutput` objects corresponding to the content of page revisions
58 * are created by the `ParserOutputAccess` service, which
59 * automatically caches them via `ParserCache` where appropriate and
60 * produces new output via `ContentHandler` as needed.
61 *
62 * In addition, wikitext from system messages as well as odd bits of
63 * wikitext rendered to create special pages and other UX elements are
64 * rendered to `ParserOutput` objects.  In these cases the metadata
65 * from the `ParserOutput` is generally discarded and the
66 * `ParserOutput` is not cached.  These bits of wikitext are generally
67 * rendered with `ParserOptions::setInterfaceMessage(true)` when
68 * content is intended to be in the user interface language, but
69 * sometimes rendered to the content language and displayed in the
70 * content area instead.
71 *
72 * A `ParserOutput` object corresponding to a given revision may be a
73 * combination of the renderings of multiple "slots":
74 * the Multi-Content Revisions (MCR) work allows articles to be
75 * composed from multiple `Content` objects.  Each `Content` renders
76 * to a `ParserOutput`, and those `ParserOutput`s are merged by
77 * `RevisionRenderer::combineSlotOutput()` to create the final article
78 * output.
79 *
80 * Similarly, `OutputPage` maintains metadata overlapping
81 * with the metadata kept by `ParserOutput` (T301020) and may merge
82 * several `ParserOutput`s using `OutputPage::addParserOutput()` to
83 * create the final output page.  Parsoid parses certain transclusions
84 * in independent top-level contexts using
85 * `Parser::parseExtensionTagAsTopLevelDoc()` and these also result in
86 * `ParserOutput`s which are merged via
87 * `ParserOutput::collectMetadata()`.
88 *
89 * Future plans for incremental parsing and asynchronous rendering may
90 * result in several of these component `ParserOutput` objects being
91 * cached independently and then recombined asynchronously, so
92 * operations on `ParserOutput` objects should be compatible with that
93 * model (T300979).
94 *
95 * @ingroup Parser
96 */
97class ParserOutput extends CacheTime implements ContentMetadataCollector {
98    use GhostFieldAccessTrait;
99    use JsonDeserializableTrait;
100    // This is used to break cyclic dependencies and allow a measure
101    // of compatibility when new methods are added to ContentMetadataCollector
102    // by Parsoid.
103    use ContentMetadataCollectorCompat;
104
105    /**
106     * Feature flags to indicate to extensions that MediaWiki core supports and
107     * uses getText() stateless transforms.
108     *
109     * @since 1.31
110     */
111    public const SUPPORTS_STATELESS_TRANSFORMS = 1;
112
113    /**
114     * @since 1.31
115     */
116    public const SUPPORTS_UNWRAP_TRANSFORM = 1;
117
118    /**
119     * @internal
120     * @since 1.38
121     */
122    public const MW_MERGE_STRATEGY_KEY = '_mw-strategy';
123
124    /**
125     * Merge strategy to use for ParserOutput accumulators: "union"
126     * means that values are strings, stored as a set, and exposed as
127     * a PHP associative array mapping from values to `true`.
128     *
129     * This constant should be treated as @internal until we expose
130     * alternative merge strategies for external use.
131     * @internal
132     * @since 1.38
133     */
134    public const MW_MERGE_STRATEGY_UNION = 'union';
135
136    /**
137     * @var string|null The output text
138     */
139    private $mRawText = null;
140
141    /**
142     * @var string[] List of the full text of language links, in the order they appear.
143     */
144    private $mLanguageLinks;
145
146    /**
147     * @var array<string,string> Map of category names to sort keys
148     */
149    private $mCategories;
150
151    /**
152     * @var array<string,string> Page status indicators, usually displayed in top-right corner.
153     */
154    private $mIndicators = [];
155
156    /**
157     * @var string Title text of the chosen language variant, as HTML.
158     */
159    private $mTitleText;
160
161    /**
162     * @var array<int,array<string,int>> 2-D map of NS/DBK to ID for the links in the document.
163     *  ID=zero for broken.
164     */
165    private $mLinks = [];
166
167    /**
168     * @var array<string,int> Keys are DBKs for the links to special pages in the document.
169     * @since 1.35
170     */
171    private $mLinksSpecial = [];
172
173    /**
174     * @var array<int,array<string,int>> 2-D map of NS/DBK to ID for the template references.
175     *  ID=zero for broken.
176     */
177    private $mTemplates = [];
178
179    /**
180     * @var array<int,array<string,int>> 2-D map of NS/DBK to rev ID for the template references.
181     *  ID=zero for broken.
182     */
183    private $mTemplateIds = [];
184
185    /**
186     * @var array<string,int> DB keys of the images used, in the array key only
187     */
188    private $mImages = [];
189
190    /**
191     * @var array<string,array<string,string>> DB keys of the images used mapped to sha1 and MW timestamp.
192     */
193    private $mFileSearchOptions = [];
194
195    /**
196     * @var array<string,int> External link URLs, in the key only.
197     */
198    private $mExternalLinks = [];
199
200    /**
201     * @var array<string,array<string,int>> 2-D map of prefix/DBK (in keys only)
202     *  for the inline interwiki links in the document.
203     */
204    private $mInterwikiLinks = [];
205
206    /**
207     * @var bool Show a new section link?
208     */
209    private $mNewSection = false;
210
211    /**
212     * @var bool Hide the new section link?
213     */
214    private $mHideNewSection = false;
215
216    /**
217     * @var bool No gallery on category page? (__NOGALLERY__).
218     */
219    private $mNoGallery = false;
220
221    /**
222     * @var string[] Items to put in the <head> section
223     */
224    private $mHeadItems = [];
225
226    /**
227     * @var array<string,true> Modules to be loaded by ResourceLoader
228     */
229    private $mModuleSet = [];
230
231    /**
232     * @var array<string,true> Modules of which only the CSS will be loaded by ResourceLoader.
233     */
234    private $mModuleStyleSet = [];
235
236    /**
237     * @var array JavaScript config variable for mw.config combined with this page.
238     */
239    private $mJsConfigVars = [];
240
241    /**
242     * @var array<string,int> Warning text to be returned to the user.
243     *  Wikitext formatted, in the key only.
244     */
245    private $mWarnings = [];
246
247    /**
248     * @var array<string,array> *Unformatted* warning messages and
249     * arguments to be returned to the user.  This is for internal use
250     * when merging ParserOutputs and are not serialized/deserialized.
251     */
252    private $mWarningMsgs = [];
253
254    /**
255     * @var ?TOCData Table of contents data, or null if it hasn't been set.
256     */
257    private $mTOCData;
258
259    /**
260     * @var array Name/value pairs to be cached in the DB.
261     */
262    private $mProperties = [];
263
264    /**
265     * @var ?string Timestamp of the revision.
266     */
267    private $mTimestamp;
268
269    /**
270     * @var bool Whether OOUI should be enabled.
271     */
272    private $mEnableOOUI = false;
273
274    /**
275     * @var bool Whether the index policy has been set to 'index'.
276     */
277    private $mIndexSet = false;
278
279    /**
280     * @var bool Whether the index policy has been set to 'noindex'.
281     */
282    private $mNoIndexSet = false;
283
284    /**
285     * @var array extra data used by extensions.
286     */
287    private $mExtensionData = [];
288
289    /**
290     * @var array Parser limit report data.
291     */
292    private $mLimitReportData = [];
293
294    /** @var array Parser limit report data for JSON */
295    private $mLimitReportJSData = [];
296
297    /** @var string Debug message added by ParserCache */
298    private $mCacheMessage = '';
299
300    /**
301     * @var array Timestamps for getTimeSinceStart().
302     */
303    private $mParseStartTime = [];
304
305    /**
306     * @var array Durations for getTimeProfile().
307     */
308    private $mTimeProfile = [];
309
310    /**
311     * @var bool Whether to emit X-Frame-Options: DENY.
312     */
313    private $mPreventClickjacking = false;
314
315    /**
316     * @var string[] Extra script-src for CSP
317     */
318    private $mExtraScriptSrcs = [];
319
320    /**
321     * @var string[] Extra default-src for CSP [Everything but script and style]
322     */
323    private $mExtraDefaultSrcs = [];
324
325    /**
326     * @var string[] Extra style-src for CSP
327     */
328    private $mExtraStyleSrcs = [];
329
330    /**
331     * @var array<string,true> Generic flags.
332     */
333    private $mFlags = [];
334
335    /** @var string[] */
336    private const SPECULATIVE_FIELDS = [
337        'speculativePageIdUsed',
338        'mSpeculativeRevId',
339        'revisionTimestampUsed',
340    ];
341
342    /** @var int|null Assumed rev ID for {{REVISIONID}} if no revision is set */
343    private $mSpeculativeRevId;
344    /** @var int|null Assumed page ID for {{PAGEID}} if no revision is set */
345    private $speculativePageIdUsed;
346    /** @var string|null Assumed rev timestamp for {{REVISIONTIMESTAMP}} if no revision is set */
347    private $revisionTimestampUsed;
348
349    /** @var string|null SHA-1 base 36 hash of any self-transclusion */
350    private $revisionUsedSha1Base36;
351
352    /** string CSS classes to use for the wrapping div, stored in the array keys.
353     * If no class is given, no wrapper is added.
354     */
355    private $mWrapperDivClasses = [];
356
357    /** @var int Upper bound of expiry based on parse duration */
358    private $mMaxAdaptiveExpiry = INF;
359
360    // finalizeAdaptiveCacheExpiry() uses TTL = MAX( m * PARSE_TIME + b, MIN_AR_TTL)
361    // Current values imply that m=3933.333333 and b=-333.333333
362    // See https://www.nngroup.com/articles/website-response-times/
363    private const PARSE_FAST_SEC = 0.100; // perceived "fast" page parse
364    private const PARSE_SLOW_SEC = 1.0; // perceived "slow" page parse
365    private const FAST_AR_TTL = 60; // adaptive TTL for "fast" pages
366    private const SLOW_AR_TTL = 3600; // adaptive TTL for "slow" pages
367    private const MIN_AR_TTL = 15; // min adaptive TTL (for pool counter, and edit stashing)
368
369    /**
370     * @param string|null $text HTML. Use null to indicate that this ParserOutput contains only
371     *        meta-data, and the HTML output is undetermined, as opposed to empty. Passing null
372     *        here causes hasText() to return false. In 1.39 the default value changed from ''
373     *        to null.
374     * @param array $languageLinks
375     * @param array $categoryLinks
376     * @param bool $unused
377     * @param string $titletext
378     */
379    public function __construct( $text = null, $languageLinks = [], $categoryLinks = [],
380        $unused = false, $titletext = ''
381    ) {
382        $this->mRawText = $text;