1<?php
2
3namespace MediaWiki\Tidy;
4
5/**
6 * @internal
7 */
8class RemexMungerData {
9	/**
10	 * The Element for the mw:p-wrap which is a child of the current node. If
11	 * this is set, inline insertions into this node will be diverted so that
12	 * they insert into the p-wrap.
13	 *
14	 * @var \Wikimedia\RemexHtml\TreeBuilder\Element|null
15	 */
16	public $childPElement;
17
18	/**
19	 * This tracks the mw:p-wrap node in the Serializer stack which is an
20	 * ancestor of this node. If there is no mw:p-wrap ancestor, it is null.
21	 *
22	 * @var \Wikimedia\RemexHtml\Serializer\SerializerNode|null
23	 */
24	public $ancestorPNode;
25
26	/**
27	 * The wrap base node is the body or blockquote node which is the parent
28	 * of active p-wrappers. This is set if there is an ancestor p-wrapper,
29	 * or if a p-wrapper was closed due to a block element being encountered
30	 * inside it.
31	 *
32	 * @var \Wikimedia\RemexHtml\Serializer\SerializerNode|null
33	 */
34	public $wrapBaseNode;
35
36	/**
37	 * Stack splitting (essentially our idea of AFE reconstruction) can clone
38	 * formatting elements which are split over multiple paragraphs.
39	 * TreeBuilder is not aware of the cloning, and continues to insert into
40	 * the original element. This is set to the newer clone if this node was
41	 * cloned, i.e. if there is an active diversion of the insertion location.
42	 *
43	 * @var \Wikimedia\RemexHtml\TreeBuilder\Element|null
44	 */
45	public $currentCloneElement;
46
47	/**
48	 * Is the node a p-wrapper, with name mw:p-wrap?
49	 *
50	 * @var bool
51	 */
52	public $isPWrapper = false;
53
54	/**
55	 * Is the node splittable, i.e. a formatting element or a node with a
56	 * formatting element ancestor which is under an active or deactivated
57	 * p-wrapper.
58	 *
59	 * @var bool
60	 */
61	public $isSplittable = false;
62
63	/**
64	 * This is true if the node is a body or blockquote, which activates
65	 * p-wrapping of child nodes.
66	 */
67	public $needsPWrapping = false;
68
69	/**
70	 * The number of child nodes, not counting whitespace-only text nodes or
71	 * comments.
72	 */
73	public $nonblankNodeCount = 0;
74
75	public function __set( $name, $value ) {
76		// @phan-suppress-previous-line PhanPluginNeverReturnMethod
77		throw new \Exception( "Cannot set property \"$name\"" );
78	}
79
80	/**
81	 * Get a text representation of the current state of the serializer, for
82	 * debugging.
83	 *
84	 * @return string
85	 */
86	public function dump() {
87		$parts = [];
88
89		if ( $this->childPElement ) {
90			$parts[] = 'childPElement=' . $this->childPElement->getDebugTag();
91		}
92		if ( $this->ancestorPNode ) {
93			$parts[] = "ancestorPNode=<{$this->ancestorPNode->name}>";
94		}
95		if ( $this->wrapBaseNode ) {
96			$parts[] = "wrapBaseNode=<{$this->wrapBaseNode->name}>";
97		}
98		if ( $this->currentCloneElement ) {
99			$parts[] = "currentCloneElement=" . $this->currentCloneElement->getDebugTag();
100		}
101		if ( $this->isPWrapper ) {
102			$parts[] = 'isPWrapper';
103		}
104		if ( $this->isSplittable ) {
105			$parts[] = 'isSplittable';
106		}
107		if ( $this->needsPWrapping ) {
108			$parts[] = 'needsPWrapping';
109		}
110		if ( $this->nonblankNodeCount ) {
111			$parts[] = "nonblankNodeCount={$this->nonblankNodeCount}";
112		}
113		$s = "RemexMungerData {\n";
114		foreach ( $parts as $part ) {
115			$s .= "  $part\n";
116		}
117		$s .= "}\n";
118		return $s;
119	}
120}
121