9
9
use DOMText ;
10
10
use Exception ;
11
11
use Paneon \VueToTwig \Models \Replacements ;
12
+ use Paneon \VueToTwig \Utils \TwigBuilder ;
12
13
use Psr \Log \LoggerInterface ;
13
14
14
15
class Compiler
@@ -26,16 +27,37 @@ class Compiler
26
27
/** @var LoggerInterface */
27
28
protected $ logger ;
28
29
30
+ /** @var string[] */
31
+ protected $ banner ;
32
+ /**
33
+ * @var TwigBuilder
34
+ */
35
+ protected $ builder ;
36
+
29
37
public function __construct (DOMDocument $ document , LoggerInterface $ logger )
30
38
{
31
- $ this ->logger = $ logger ;
39
+ $ this ->builder = new TwigBuilder () ;
32
40
$ this ->document = $ document ;
41
+ $ this ->logger = $ logger ;
33
42
$ this ->lastCloseIf = null ;
34
43
$ this ->components = [];
44
+ $ this ->banner = [];
35
45
36
46
$ this ->logger ->debug ("\n--------- New Compiler Instance ---------- \n" );
37
47
}
38
48
49
+ /**
50
+ * @param string|string[] $strings
51
+ */
52
+ public function setBanner ($ strings ): void
53
+ {
54
+ if (!is_array ($ strings )) {
55
+ $ strings = [$ strings ];
56
+ }
57
+
58
+ $ this ->banner = $ strings ;
59
+ }
60
+
39
61
/**
40
62
* @throws Exception
41
63
*/
@@ -53,22 +75,30 @@ public function convert(): string
53
75
54
76
$ html = $ this ->replacePlaceholders ($ html );
55
77
78
+ if (!empty ($ this ->banner )) {
79
+ $ html = $ this ->addBanner ($ html );
80
+ }
81
+
56
82
return $ html ;
57
83
}
58
84
59
85
public function convertNode (DOMNode $ node ): DOMNode
60
86
{
61
- if ($ node ->nodeType === XML_TEXT_NODE ) {
62
- return $ node ;
63
- }
64
-
65
- if ($ node ->nodeType === XML_ELEMENT_NODE ) {
66
- //echo "\nElement node found";
67
- /** @var DOMElement $node */
68
- $ this ->replaceShowWithIf ($ node );
69
- $ this ->handleIf ($ node );
70
- } elseif ($ node ->nodeType === XML_HTML_DOCUMENT_NODE ) {
71
- $ this ->logger ->warning ("Document node found. " );
87
+ switch ($ node ->nodeType ) {
88
+ case XML_TEXT_NODE :
89
+ $ this ->logger ->debug ('Text node found ' , ['name ' => $ node ->nodeName ]);
90
+ // fall through to next case, because we don't need to handle either of these node-types
91
+ case XML_COMMENT_NODE :
92
+ $ this ->logger ->debug ('Comment node found ' , ['name ' => $ node ->nodeName ]);
93
+ return $ node ;
94
+ case XML_ELEMENT_NODE :
95
+ /** @var DOMElement $node */
96
+ $ this ->replaceShowWithIf ($ node );
97
+ $ this ->handleIf ($ node );
98
+ break ;
99
+ case XML_HTML_DOCUMENT_NODE :
100
+ $ this ->logger ->warning ("Document node found. " );
101
+ break ;
72
102
}
73
103
74
104
if (in_array ($ node ->nodeName , array_keys ($ this ->components ))) {
@@ -158,8 +188,8 @@ private function handleAttributeBinding(DOMElement $node)
158
188
$ this ->logger ->debug ('- setAttribute " ' .$ name .'" with value ' );
159
189
$ node ->setAttribute (
160
190
$ name ,
161
- Replacements::getSanitizedConstant ('DOUBLE_CURLY_OPEN ' ) .
162
- $ value .
191
+ Replacements::getSanitizedConstant ('DOUBLE_CURLY_OPEN ' ).
192
+ $ value .
163
193
Replacements::getSanitizedConstant ('DOUBLE_CURLY_CLOSE ' )
164
194
);
165
195
}
@@ -184,6 +214,21 @@ private function handleAttributeBinding(DOMElement $node)
184
214
}
185
215
$ node ->setAttribute ($ name , implode (' ' , $ classes ));
186
216
}
217
+ } /*
218
+ * <div :class="`abc ${someDynamicClass}`">
219
+ */
220
+ elseif (preg_match ('/^`(?P<content>.+)`$/ ' , $ value , $ matches )) {
221
+ $ templateStringContent = $ matches ['content ' ];
222
+
223
+ $ templateStringContent = preg_replace (
224
+ '/\$\{(.+)\}/ ' ,
225
+ '{{ $1 }} ' ,
226
+ $ templateStringContent
227
+ );
228
+
229
+ $ node ->setAttribute ($ name , $ templateStringContent );
230
+ } else {
231
+ $ this ->logger ->warning ('- No Handling for: ' .$ value );
187
232
}
188
233
189
234
$ this ->logger ->debug ('=> remove original ' .$ attribute ->name );
@@ -204,11 +249,11 @@ private function handleIf(DOMElement $node): void
204
249
$ condition = $ this ->sanitizeCondition ($ condition );
205
250
206
251
// Open with if
207
- $ openIf = $ this ->document ->createTextNode (' {% if ' . $ condition. ' %} ' );
252
+ $ openIf = $ this ->document ->createTextNode ($ this -> builder -> createIf ( $ condition) );
208
253
$ node ->parentNode ->insertBefore ($ openIf , $ node );
209
254
210
255
// Close with endif
211
- $ closeIf = $ this ->document ->createTextNode (' {% endif %} ' );
256
+ $ closeIf = $ this ->document ->createTextNode ($ this -> builder -> createEndIf () );
212
257
$ node ->parentNode ->insertBefore ($ closeIf , $ node ->nextSibling );
213
258
214
259
$ this ->lastCloseIf = $ closeIf ;
@@ -219,20 +264,20 @@ private function handleIf(DOMElement $node): void
219
264
$ condition = $ this ->sanitizeCondition ($ condition );
220
265
221
266
// Replace old endif with else
222
- $ this ->lastCloseIf ->textContent = ' {% elseif ' . $ condition. ' %} ' ;
267
+ $ this ->lastCloseIf ->textContent = $ this -> builder -> createElseIf ( $ condition) ;
223
268
224
269
// Close with new endif
225
- $ closeIf = $ this ->document ->createTextNode (' {% endif %} ' );
270
+ $ closeIf = $ this ->document ->createTextNode ($ this -> builder -> createEndIf () );
226
271
$ node ->parentNode ->insertBefore ($ closeIf , $ node ->nextSibling );
227
272
$ this ->lastCloseIf = $ closeIf ;
228
273
229
274
$ node ->removeAttribute ('v-else-if ' );
230
275
} elseif ($ node ->hasAttribute ('v-else ' )) {
231
276
// Replace old endif with else
232
- $ this ->lastCloseIf ->textContent = ' {% else %} ' ;
277
+ $ this ->lastCloseIf ->textContent = $ this -> builder -> createElse () ;
233
278
234
279
// Close with new endif
235
- $ closeIf = $ this ->document ->createTextNode (' {% endif %} ' );
280
+ $ closeIf = $ this ->document ->createTextNode ($ this -> builder -> createEndIf () );
236
281
$ node ->parentNode ->insertBefore ($ closeIf , $ node ->nextSibling );
237
282
$ this ->lastCloseIf = $ closeIf ;
238
283
@@ -263,7 +308,7 @@ private function handleFor(DOMElement $node)
263
308
}
264
309
265
310
// (1)
266
- $ forCommand = ' {% for ' . $ forLeft. ' in ' . $ listName. ' %} ' ;
311
+ $ forCommand = $ this -> builder -> createForItemInList ( $ forLeft, $ listName) ;
267
312
268
313
if (strpos ($ forLeft , ', ' )) {
269
314
$ forLeft = str_replace ('( ' , '' , $ forLeft );
@@ -276,19 +321,19 @@ private function handleFor(DOMElement $node)
276
321
$ forIndex = $ forLeftArray [2 ] ?? null ;
277
322
278
323
// (3)
279
- $ forCommand = ' {% for ' . $ forKey . ' , ' . $ forValue. ' in ' . $ listName . ' %} ' ;
324
+ $ forCommand = $ this -> builder -> createFor ( $ listName , $ forValue, $ forKey ) ;
280
325
281
326
if ($ forIndex ) {
282
327
// (4)
283
- $ forCommand .= ' {% set ' . $ forIndex. ' = loop.index0 %} ' ;
328
+ $ forCommand .= $ this -> builder -> createVariable ( $ forIndex, ' loop.index0 ' ) ;
284
329
}
285
330
}
286
331
287
332
$ startFor = $ this ->document ->createTextNode ($ forCommand );
288
333
$ node ->parentNode ->insertBefore ($ startFor , $ node );
289
334
290
335
// End For
291
- $ endFor = $ this ->document ->createTextNode (' {% endfor %} ' );
336
+ $ endFor = $ this ->document ->createTextNode ($ this -> builder -> createEndFor () );
292
337
$ node ->parentNode ->insertBefore ($ endFor , $ node ->nextSibling );
293
338
294
339
$ node ->removeAttribute ('v-for ' );
@@ -315,10 +360,11 @@ private function getRootNode(DOMElement $element): \DOMNode
315
360
$ tagNodes = 0 ;
316
361
$ firstTagNode = null ;
317
362
363
+ /** @var DOMNode $node */
318
364
foreach ($ nodes as $ node ) {
319
365
if ($ node ->nodeType === XML_TEXT_NODE ) {
320
366
continue ;
321
- } else if ( $ node ->nodeName === 'script ' || $ node -> nodeName === 'style ' ) {
367
+ } elseif ( in_array ( $ node ->nodeName , [ 'script ' , 'style ' ]) ) {
322
368
continue ;
323
369
} else {
324
370
$ tagNodes ++;
@@ -338,7 +384,7 @@ protected function sanitizeCondition(string $condition)
338
384
$ condition = str_replace ('&& ' , 'and ' , $ condition );
339
385
$ condition = str_replace ('|| ' , 'or ' , $ condition );
340
386
341
- foreach (Replacements::getConstants () as $ constant => $ value ) {
387
+ foreach (Replacements::getConstants () as $ constant => $ value ) {
342
388
$ condition = str_replace ($ value , Replacements::getSanitizedConstant ($ constant ), $ condition );
343
389
}
344
390
@@ -347,7 +393,7 @@ protected function sanitizeCondition(string $condition)
347
393
348
394
protected function replacePlaceholders (string $ string )
349
395
{
350
- foreach (Replacements::getConstants () as $ constant => $ value ) {
396
+ foreach (Replacements::getConstants () as $ constant => $ value ) {
351
397
$ string = str_replace (Replacements::getSanitizedConstant ($ constant ), $ value , $ string );
352
398
}
353
399
@@ -358,4 +404,28 @@ public function registerComponent(string $componentName, string $componentPath)
358
404
{
359
405
$ this ->components [strtolower ($ componentName )] = new Component ($ componentName , $ componentPath );
360
406
}
407
+
408
+ protected function addSingleLineBanner (string $ html )
409
+ {
410
+ return $ this ->builder ->createComment (implode ('' , $ this ->banner ))."\n" .$ html ;
411
+ }
412
+
413
+ protected function addBanner (string $ html )
414
+ {
415
+ if (count ($ this ->banner ) === 1 ) {
416
+ return $ this ->addSingleLineBanner ($ html );
417
+ }
418
+
419
+ $ bannerLines = ['{# ' ];
420
+
421
+ foreach ($ this ->banner as $ line ) {
422
+ $ bannerLines [] = ' # ' .$ line ;
423
+ }
424
+
425
+ $ bannerLines [] = ' #} ' ;
426
+
427
+ $ html = implode ("\n" , $ bannerLines )."\n" .$ html ;
428
+
429
+ return $ html ;
430
+ }
361
431
}
0 commit comments