Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 122 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
ParserHook | |
0.00% |
0 / 122 |
|
0.00% |
0 / 5 |
812 | |
0.00% |
0 / 1 |
getParserTestConfigFileName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
sourceToDom | |
0.00% |
0 / 49 |
|
0.00% |
0 / 1 |
240 | |||
processAttributeEmbeddedDom | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
domToWikitext | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
72 | |||
getConfig | |
0.00% |
0 / 49 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | declare( strict_types = 1 ); |
3 | |
4 | namespace Wikimedia\Parsoid\ParserTests; |
5 | |
6 | use Error; |
7 | use Wikimedia\Parsoid\DOM\DocumentFragment; |
8 | use Wikimedia\Parsoid\DOM\Element; |
9 | use Wikimedia\Parsoid\Ext\ExtensionModule; |
10 | use Wikimedia\Parsoid\Ext\ExtensionTagHandler; |
11 | use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI; |
12 | use Wikimedia\Parsoid\Utils\DOMCompat; |
13 | use Wikimedia\Parsoid\Utils\DOMDataUtils; |
14 | use Wikimedia\Parsoid\Utils\WTUtils; |
15 | |
16 | /** |
17 | * See tests/parser/ParserTestParserHook.php in core. |
18 | */ |
19 | class ParserHook extends ExtensionTagHandler implements ExtensionModule { |
20 | |
21 | /** |
22 | * Ensure that both integrated and standalone test runners have the |
23 | * magic word definitions used by these test hooks. |
24 | * @see SiteConfig::getCustomSiteConfigFileName() |
25 | * @see ParserTestRunner::staticSetup() (in core) |
26 | */ |
27 | public static function getParserTestConfigFileName(): string { |
28 | return ParserTestPFragmentHandlers::getParserTestConfigFileName(); |
29 | } |
30 | |
31 | /** @inheritDoc */ |
32 | public function sourceToDom( |
33 | ParsoidExtensionAPI $extApi, string $content, array $args |
34 | ): DocumentFragment { |
35 | $extName = $extApi->extTag->getName(); |
36 | if ( $extApi->extTag->isSelfClosed() ) { |
37 | $content = null; |
38 | } |
39 | switch ( $extName ) { |
40 | case 'tag': |
41 | case 'tåg': |
42 | return $extApi->htmlToDom( |
43 | "<pre>\n" . |
44 | var_export( $content, true ) . "\n" . |
45 | var_export( $extApi->extArgsToArray( $args ), true ) . "\n" . |
46 | "</pre>" |
47 | ); |
48 | |
49 | case 'statictag': |
50 | // FIXME: Choose a better DOM representation that doesn't mess with |
51 | // newline constraints. |
52 | return $extApi->htmlToDom( '<span />' ); |
53 | |
54 | case 'asidetag': |
55 | // T278565 |
56 | return $extApi->htmlToDom( '<aside>Some aside content</aside>' ); |
57 | |
58 | case 'pwraptest': |
59 | return $extApi->htmlToDom( '<!--CMT--><style>p{}</style>' ); |
60 | |
61 | case 'divtag': |
62 | case 'spantag': |
63 | // "Transparent" tag which wraps wikitext in a <span> or <div>; |
64 | // useful in testing various parsoid wrapping scenarios |
65 | // (we used to use <ref> for this) |
66 | // |
67 | // NOTE: When using <spantag>, p-wrapping and indent-pre |
68 | // transforms are disabled. |
69 | $argArray = $extApi->extArgsToArray( $args ); |
70 | $isDiv = ( $extName === 'divtag' ); |
71 | $isRaw = $argArray['raw'] ?? false; |
72 | $tag = $isDiv ? 'div' : 'span'; |
73 | if ( $isRaw ) { |
74 | return $extApi->htmlToDom( "<$tag>$content</$tag>" ); |
75 | } |
76 | return $extApi->extTagToDOM( $args, $content, [ |
77 | 'wrapperTag' => $tag, |
78 | 'parseOpts' => [ |
79 | 'extTag' => $extName, |
80 | 'context' => $isDiv ? 'block' : 'inline', |
81 | ], |
82 | ] ); |
83 | |
84 | case 'embedtag': |
85 | $dataMw = $extApi->extTag->getDefaultDataMw(); |
86 | $domFragment = $extApi->extTagToDOM( $args, $content, [ |
87 | 'parseOpts' => [ |
88 | 'extTag' => $extName, |
89 | 'context' => 'inline', |
90 | ], |
91 | ] ); |
92 | $dataMw->body->extsrc = null; // clear wt representation |
93 | $dataMw->body->setHtml( $extApi, $domFragment ); |
94 | $span = $domFragment->ownerDocument->createElement( 'span' ); |
95 | DOMDataUtils::setDataMw( $span, $dataMw ); |
96 | DOMCompat::replaceChildren( $domFragment, $span ); |
97 | return $domFragment; |
98 | |
99 | case 'sealtag': |
100 | return $extApi->htmlToDom( '<span />' ); |
101 | |
102 | default: |
103 | throw new Error( "Unexpected tag name: $extName in ParserHook" ); |
104 | } |
105 | } |
106 | |
107 | /** @inheritDoc */ |
108 | public function processAttributeEmbeddedDom( |
109 | ParsoidExtensionAPI $extApi, Element $elt, callable $proc |
110 | ): void { |
111 | $dataMw = DOMDataUtils::getDataMw( $elt ); |
112 | if ( isset( $dataMw->body->html ) ) { |
113 | $dom = $dataMw->body->getHtml( $extApi ); |
114 | $ret = $proc( $dom ); |
115 | if ( $ret ) { |
116 | $dataMw->body->setHtml( $extApi, $dom ); |
117 | } |
118 | } |
119 | } |
120 | |
121 | /** @inheritDoc */ |
122 | public function domToWikitext( |
123 | ParsoidExtensionAPI $extApi, Element $node, bool $wrapperUnmodified |
124 | ) { |
125 | $dataMw = DOMDataUtils::getDataMw( $node ); |
126 | $extName = WTUtils::getExtTagName( $node ) ?? $dataMw->name; |
127 | if ( !in_array( $extName, [ 'spantag', 'divtag', 'embedtag' ], true ) ) { |
128 | return false; // use default serialization |
129 | } |
130 | if ( in_array( $extName, [ 'spantag', 'divtag' ], true ) ) { |
131 | if ( $dataMw->getExtAttrib( 'raw' ) ?? false ) { |
132 | return false; // use default serialization in 'raw' mode |
133 | } |
134 | } |
135 | $html2wtOpts = [ |
136 | 'extName' => $extName, |
137 | // FIXME: One-off PHP parser state leak. This needs a better solution. |
138 | 'inPHPBlock' => true |
139 | ]; |
140 | if ( $wrapperUnmodified && isset( $dataMw->body->extsrc ) ) { |
141 | $src = $dataMw->body->extsrc; |
142 | } elseif ( $extName === 'embedtag' && isset( $dataMw->body->html ) ) { |
143 | // First look for the extension's content in data-mw.body.html |
144 | $src = $extApi->htmlToWikitext( $html2wtOpts, $dataMw->body->html ); |
145 | } else { |
146 | $src = $extApi->htmlToWikitext( $html2wtOpts, DOMCompat::getInnerHTML( $node ) ); |
147 | } |
148 | return "<$extName>" . $src . "</$extName>"; |
149 | } |
150 | |
151 | /** @inheritDoc */ |
152 | public function getConfig(): array { |
153 | return [ |
154 | 'name' => 'ParserHook', |
155 | 'tags' => [ |
156 | [ 'name' => 'tag', 'handler' => self::class ], |
157 | [ 'name' => 'tåg', 'handler' => self::class ], |
158 | [ 'name' => 'statictag', 'handler' => self::class ], |
159 | [ 'name' => 'asidetag', 'handler' => self::class ], |
160 | [ 'name' => 'pwraptest', 'handler' => self::class ], |
161 | [ |
162 | 'name' => 'divtag', |
163 | 'handler' => self::class, |
164 | 'options' => [ |
165 | 'outputHasCoreMwDomSpecMarkup' => true, |
166 | ], |
167 | ], |
168 | [ |
169 | 'name' => 'spantag', |
170 | 'handler' => self::class, |
171 | 'options' => [ |
172 | 'outputHasCoreMwDomSpecMarkup' => true, |
173 | ], |
174 | ], |
175 | [ |
176 | 'name' => 'embedtag', |
177 | 'handler' => self::class, |
178 | 'options' => [ |
179 | 'wt2html' => [ |
180 | 'embedsDomInAttributes' => true, |
181 | 'customizesDataMw' => true, |
182 | ], |
183 | 'outputHasCoreMwDomSpecMarkup' => true, |
184 | ], |
185 | ], |
186 | [ |
187 | 'name' => 'sealtag', |
188 | 'handler' => self::class, |
189 | 'options' => [ |
190 | 'wt2html' => [ |
191 | 'unpackOutput' => false, |
192 | ], |
193 | ], |
194 | ], |
195 | ], |
196 | 'domProcessors' => [ |
197 | ParserHookProcessor::class |
198 | ], |
199 | 'fragmentHandlers' => |
200 | ParserTestPFragmentHandlers::getPFragmentHandlersConfig(), |
201 | ]; |
202 | } |
203 | |
204 | } |