‪TYPO3CMS  9.5
RteHtmlParserTest.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types = 1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
20 
24 class ‪RteHtmlParserTest extends UnitTestCase
25 {
29  protected ‪$resetSingletonInstances = true;
30 
31  protected ‪$procOptions = ['overruleMode' => 'default'];
32 
37  {
38  return [
39  'Single hr' => [
40  '<hr />',
41  '<hr />',
42  ],
43  'Non-xhtml single hr' => [
44  '<hr/>',
45  '<hr />',
46  ],
47  'Double hr' => [
48  '<hr /><hr />',
49  '<hr />' . CRLF . '<hr />',
50  ],
51  'Linebreak followed by hr' => [
52  CRLF . '<hr />',
53  '<hr />',
54  ],
55  'White space followed by hr' => [
56  ' <hr />',
57  ' ' . CRLF . '<hr />',
58  ],
59  'White space followed linebreak and hr' => [
60  ' ' . CRLF . '<hr />',
61  ' ' . CRLF . '<hr />',
62  ],
63  'br followed by hr' => [
64  '<br /><hr />',
65  '<br />' . CRLF . '<hr />',
66  ],
67  'br followed by linebreak and hr' => [
68  '<br />' . CRLF . '<hr />',
69  '<br />' . CRLF . '<hr />',
70  ],
71  'Preserved div followed by hr' => [
72  '<div>Some text</div><hr />',
73  '<div>Some text</div>' . CRLF . '<hr />',
74  ],
75  'Preserved div followed by linebreak and hr' => [
76  '<div>Some text</div>' . CRLF . '<hr />',
77  '<div>Some text</div>' . CRLF . '<hr />',
78  ],
79  'h1 followed by linebreak and hr' => [
80  '<h1>Some text</h1>' . CRLF . '<hr />',
81  '<h1>Some text</h1>' . CRLF . '<hr />',
82  ],
83  'Paragraph followed by linebreak and hr' => [
84  '<p>Some text</p>' . CRLF . '<hr />',
85  '<p>Some text</p>' . CRLF . '<hr />',
86  ],
87  'Some text without HTML tags' => [
88  'Some text',
89  'Some text',
90  ],
91  'Some text followed by hr' => [
92  'Some text<hr />',
93  'Some text' . CRLF . '<hr />',
94  ],
95  'Some text followed by linebreak and hr' => [
96  'Some text' . CRLF . '<hr />',
97  'Some text' . CRLF . '<hr />',
98  ],
99  ];
100  }
101 
106  public function ‪hrTagCorrectlyTransformedOnWayToDataBase($content, $expectedResult)
107  {
108  // @todo Explicitly disabled HTML Sanitizer (since it is based on HTML5)
109  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.backend.htmlSanitizeRte'] = false;
110  $subject = new ‪RteHtmlParser();
111  $thisConfig = ['proc.' => ‪$this->procOptions];
112  $this->assertEquals($expectedResult, $subject->RTE_transform($content, [], 'db', $thisConfig));
113  }
114 
119  {
120  return [
121  'Single hr' => [
122  '<hr />',
123  '<hr />',
124  ],
125  'Non-xhtml single hr' => [
126  '<hr/>',
127  '<hr />',
128  ],
129  'Double hr' => [
130  '<hr /><hr />',
131  '<hr />' . CRLF . '<hr />',
132  ],
133  'Linebreak followed by hr' => [
134  CRLF . '<hr />',
135  '<hr />',
136  ],
137  'White space followed by hr' => [
138  ' <hr />',
139  '<p>&nbsp;</p>' . CRLF . '<hr />',
140  ],
141  'White space followed by linebreak and hr' => [
142  ' ' . CRLF . '<hr />',
143  '<p>&nbsp;</p>' . CRLF . '<hr />',
144  ],
145  'br followed by hr' => [
146  '<br /><hr />',
147  '<p><br /></p>' . CRLF . '<hr />',
148  ],
149  'br followed by linebreak and hr' => [
150  '<br />' . CRLF . '<hr />',
151  '<p><br /></p>' . CRLF . '<hr />',
152  ],
153  'Preserved div followed by hr' => [
154  '<div>Some text</div>' . '<hr />',
155  '<div><p>Some text</p></div>' . CRLF . '<hr />',
156  ],
157  'Preserved div followed by linebreak and hr' => [
158  '<div>Some text</div>' . CRLF . '<hr />',
159  '<div><p>Some text</p></div>' . CRLF . '<hr />',
160  ],
161  'h1 followed by linebreak and hr' => [
162  '<h1>Some text</h1>' . CRLF . '<hr />',
163  '<h1>Some text</h1>' . CRLF . '<hr />',
164  ],
165  'Paragraph followed by linebreak and hr' => [
166  '<p>Some text</p>' . CRLF . '<hr />',
167  '<p>Some text</p>' . CRLF . '<hr />',
168  ],
169  'Some text followed by hr' => [
170  'Some text<hr />',
171  '<p>Some text</p>' . CRLF . '<hr />',
172  ],
173  'Some text followed by linebreak and hr' => [
174  'Some text' . CRLF . '<hr />',
175  '<p>Some text</p>' . CRLF . '<hr />',
176  ],
177  ];
178  }
179 
184  public function ‪hrTagCorrectlyTransformedOnWayToDatabaseAndBackToRte($content, $expectedResult)
185  {
186  // @todo Explicitly disabled HTML Sanitizer (since it is based on HTML5)
187  ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.backend.htmlSanitizeRte'] = false;
188  $subject = new RteHtmlParser();
189  $thisConfig = ['proc.' => ‪$this->procOptions];
190  $this->assertEquals($expectedResult, $subject->RTE_transform($subject->RTE_transform($content, [], 'db', $thisConfig), [], 'rte', $thisConfig));
191  }
192 
197  {
198  return [
199  'Empty string' => [
200  '',
201  '',
202  ],
203  'Linebreak' => [
204  CRLF,
205  '',
206  ],
207  'Double linebreak' => [
208  CRLF . CRLF,
209  '',
210  ],
211  'Empty paragraph' => [
212  '<p></p>',
213  CRLF,
214  ],
215  'Double empty paragraph' => [
216  '<p></p><p></p>',
217  CRLF . CRLF,
218  ],
219  'Spacing paragraph' => [
220  '<p>&nbsp;</p>',
221  CRLF,
222  ],
223  'Double spacing paragraph' => [
224  '<p>&nbsp;</p>' . '<p>&nbsp;</p>',
225  CRLF . CRLF,
226  ],
227  'Plain text' => [
228  'plain text',
229  'plain text',
230  ],
231  'Plain text followed by linebreak' => [
232  'plain text' . CRLF,
233  'plain text ',
234  ],
235  'Paragraph' => [
236  '<p>paragraph</p>',
237  '<p>paragraph</p>',
238  ],
239  'Paragraph followed by paragraph' => [
240  '<p>paragraph1</p>' . '<p>paragraph2</p>',
241  '<p>paragraph1</p>' . CRLF . '<p>paragraph2</p>',
242  ],
243  'Paragraph followed by paragraph, linebreak-separated' => [
244  '<p>paragraph1</p>' . CRLF . '<p>paragraph2</p>',
245  '<p>paragraph1</p>' . CRLF . '<p>paragraph2</p>',
246  ],
247  'Double spacing paragraph with text' => [
248  '<p>&nbsp;</p><p>&nbsp;</p><p>paragraph1</p>',
249  CRLF . CRLF . '<p>paragraph1</p>',
250  ],
251  'Paragraph followed by linebreak' => [
252  '<p>paragraph</p>' . CRLF,
253  '<p>paragraph</p>',
254  ],
255  'Paragraph followed by spacing paragraph' => [
256  '<p>paragraph</p>' . '<p>&nbsp;</p>',
257  '<p>paragraph</p>' . CRLF . CRLF,
258  ],
259  'Paragraph followed by spacing paragraph, linebreak-separated' => [
260  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>',
261  '<p>paragraph</p>' . CRLF . CRLF,
262  ],
263  'Paragraph followed by double spacing paragraph' => [
264  '<p>paragraph</p>' . '<p>&nbsp;</p>' . '<p>&nbsp;</p>',
265  '<p>paragraph</p>' . CRLF . CRLF . CRLF,
266  ],
267  'Paragraph followed by double spacing paragraph, linebreak-separated' => [
268  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>',
269  '<p>paragraph</p>' . CRLF . CRLF . CRLF,
270  ],
271  'Paragraph followed by spacing paragraph and by paragraph' => [
272  '<p>paragraph1</p>' . '<p>&nbsp;</p>' . '<p>paragraph2</p>',
273  '<p>paragraph1</p>' . CRLF . CRLF . '<p>paragraph2</p>',
274  ],
275  'Paragraph followed by spacing paragraph and by paragraph, linebreak-separated' => [
276  '<p>paragraph1</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>paragraph2</p>',
277  '<p>paragraph1</p>' . CRLF . CRLF . '<p>paragraph2</p>',
278  ],
279  'Paragraph followed by double spacing paragraph and by paragraph' => [
280  '<p>paragraph1</p>' . '<p>&nbsp;</p>' . '<p>&nbsp;</p>' . '<p>paragraph2</p>',
281  '<p>paragraph1</p>' . CRLF . CRLF . CRLF . '<p>paragraph2</p>',
282  ],
283  'Paragraph followed by double spacing paragraph and by paragraph, linebreak-separated' => [
284  '<p>paragraph1</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>paragraph2</p>',
285  '<p>paragraph1</p>' . CRLF . CRLF . CRLF . '<p>paragraph2</p>',
286  ],
287  'Paragraph followed by block' => [
288  '<p>paragraph</p>' . '<h1>block</h1>',
289  '<p>paragraph</p>' . CRLF . '<h1>block</h1>',
290  ],
291  'Paragraph followed by block, linebreak-separated' => [
292  '<p>paragraph</p>' . CRLF . '<h1>block</h1>',
293  '<p>paragraph</p>' . CRLF . '<h1>block</h1>',
294  ],
295  'Paragraph followed by spacing paragraph and block' => [
296  '<p>paragraph</p>' . '<p>&nbsp;</p>' . '<h1>block</h1>',
297  '<p>paragraph</p>' . CRLF . CRLF . '<h1>block</h1>',
298  ],
299  'Paragraph followed by spacing paragraph and block, linebreak-separated' => [
300  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block</h1>',
301  '<p>paragraph</p>' . CRLF . CRLF . '<h1>block</h1>',
302  ],
303  'Paragraph followed by double spacing paragraph and block' => [
304  '<p>paragraph</p>' . '<p>&nbsp;</p>' . '<p>&nbsp;</p>' . '<h1>block</h1>',
305  '<p>paragraph</p>' . CRLF . CRLF . CRLF . '<h1>block</h1>',
306  ],
307  'Paragraph followed by double spacing paragraph and block, linebreak-separated' => [
308  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block</h1>',
309  '<p>paragraph</p>' . CRLF . CRLF . CRLF . '<h1>block</h1>',
310  ],
311  'Block followed by block' => [
312  '<h1>block1</h1>' . '<h1>block2</h1>',
313  '<h1>block1</h1>' . CRLF . '<h1>block2</h1>',
314  ],
315  'Block followed by block, linebreak-separated' => [
316  '<h1>block1</h1>' . CRLF . '<h1>block2</h1>',
317  '<h1>block1</h1>' . CRLF . '<h1>block2</h1>',
318  ],
319  'Block followed by empty paragraph and block' => [
320  '<h1>block1</h1>' . '<p></p>' . '<h1>block2</h1>',
321  '<h1>block1</h1>' . CRLF . CRLF . '<h1>block2</h1>',
322  ],
323  'Block followed by empty paragraph aand block, linebreak-separated' => [
324  '<h1>block1</h1>' . CRLF . '<p></p>' . CRLF . '<h1>block2</h1>',
325  '<h1>block1</h1>' . CRLF . CRLF . '<h1>block2</h1>',
326  ],
327  'Block followed by spacing paragraph' => [
328  '<h1>block1</h1>' . '<p>&nbsp;</p>',
329  '<h1>block1</h1>' . CRLF . CRLF,
330  ],
331  'Block followed by spacing paragraph, linebreak-separated' => [
332  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>',
333  '<h1>block1</h1>' . CRLF . CRLF,
334  ],
335  'Block followed by spacing paragraph and block' => [
336  '<h1>block1</h1>' . '<p>&nbsp;</p>' . '<h1>block2</h1>',
337  '<h1>block1</h1>' . CRLF . CRLF . '<h1>block2</h1>',
338  ],
339  'Block followed by spacing paragraph and block, linebreak-separated' => [
340  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
341  '<h1>block1</h1>' . CRLF . CRLF . '<h1>block2</h1>',
342  ],
343  'Block followed by double spacing paragraph and by block' => [
344  '<h1>block1</h1>' . '<p>&nbsp;</p>' . '<p>&nbsp;</p>' . '<h1>block2</h1>',
345  '<h1>block1</h1>' . CRLF . CRLF . CRLF . '<h1>block2</h1>',
346  ],
347  'Block followed by double spacing paragraph and by block, linebreak-separated' => [
348  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
349  '<h1>block1</h1>' . CRLF . CRLF . CRLF . '<h1>block2</h1>',
350  ],
351  'Block followed by paragraph and block' => [
352  '<h1>block1</h1>' . '<p>paragraph</p>' . '<h1>block2</h1>',
353  '<h1>block1</h1>' . CRLF . '<p>paragraph</p>' . CRLF . '<h1>block2</h1>',
354  ],
355  'Block followed by paragraph and block, linebreak-separated' => [
356  '<h1>block1</h1>' . CRLF . '<p>paragraph</p>' . CRLF . '<h1>block2</h1>',
357  '<h1>block1</h1>' . CRLF . '<p>paragraph</p>' . CRLF . '<h1>block2</h1>',
358  ],
359  'Block followed by paragraph, spacing paragraph and block' => [
360  '<h1>block1</h1>' . '<p>paragraph</p>' . '<p>&nbsp;</p>' . '<h1>block2</h1>',
361  '<h1>block1</h1>' . CRLF . '<p>paragraph</p>' . CRLF . CRLF . '<h1>block2</h1>',
362  ],
363  'Block followed by paragraph, spacing paragraph and block, linebreak-separated' => [
364  '<h1>block1</h1>' . CRLF . '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
365  '<h1>block1</h1>' . CRLF . '<p>paragraph</p>' . CRLF . CRLF . '<h1>block2</h1>',
366  ],
367  ];
368  }
369 
374  public function ‪paragraphCorrectlyTransformedOnWayToDatabase($content, $expectedResult)
375  {
376  $subject = new RteHtmlParser();
377  $thisConfig = ['proc.' => ‪$this->procOptions];
378  $this->assertEquals($expectedResult, $subject->RTE_transform($content, [], 'db', $thisConfig));
379  }
380 
385  {
386  return [
387  'Empty string' => [
388  '',
389  '',
390  ],
391  'Single linebreak' => [
392  CRLF,
393  '<p>&nbsp;</p>',
394  ],
395  'Double linebreak' => [
396  CRLF . CRLF,
397  '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>',
398  ],
399  'Triple linebreak' => [
400  CRLF . CRLF . CRLF,
401  '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>',
402  ],
403  'Paragraph' => [
404  'paragraph',
405  '<p>paragraph</p>',
406  ],
407  'Paragraph followed by single linebreak' => [
408  'paragraph' . CRLF,
409  '<p>paragraph</p>',
410  ],
411  'Paragraph followed by double linebreak' => [
412  'paragraph' . CRLF . CRLF,
413  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>',
414  ],
415  'Paragraph followed by triple linebreak' => [
416  'paragraph' . CRLF . CRLF . CRLF,
417  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>',
418  ],
419  'Paragraph followed by paragraph' => [
420  'paragraph1' . CRLF . 'paragraph2',
421  '<p>paragraph1</p>' . CRLF . '<p>paragraph2</p>',
422  ],
423  'Paragraph followed by double linebreak and paragraph' => [
424  'paragraph1' . CRLF . CRLF . 'paragraph2',
425  '<p>paragraph1</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>paragraph2</p>',
426  ],
427  'Paragraph followed by triple linebreak and paragraph' => [
428  'paragraph1' . CRLF . CRLF . CRLF . 'paragraph2',
429  '<p>paragraph1</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>paragraph2</p>',
430  ],
431  'Paragraph followed by block' => [
432  'paragraph' . '<h1>block</h1>',
433  '<p>paragraph</p>' . CRLF . '<h1>block</h1>',
434  ],
435  'Paragraph followed by linebreak and block' => [
436  'paragraph' . CRLF . '<h1>block</h1>',
437  '<p>paragraph</p>' . CRLF . '<h1>block</h1>',
438  ],
439  'Paragraph followed by double linebreak and block' => [
440  'paragraph' . CRLF . CRLF . '<h1>block</h1>',
441  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block</h1>',
442  ],
443  'Paragraph followed by triple linebreak and block' => [
444  'paragraph' . CRLF . CRLF . CRLF . '<h1>block</h1>',
445  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block</h1>',
446  ],
447  'Block followed by block' => [
448  '<h1>block1</h1>' . '<h1>block2</h1>',
449  '<h1>block1</h1>' . CRLF . '<h1>block2</h1>',
450  ],
451  'Block followed by single linebreak and block' => [
452  '<h1>block1</h1>' . CRLF . '<h1>block2</h1>',
453  '<h1>block1</h1>' . CRLF . '<h1>block2</h1>',
454  ],
455  'Block followed by double linebreak and block' => [
456  '<h1>block1</h1>' . CRLF . CRLF . '<h1>block2</h1>',
457  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
458  ],
459  'Block followed by triple linebreak and block' => [
460  '<h1>block1</h1>' . CRLF . CRLF . CRLF . '<h1>block2</h1>',
461  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
462  ],
463  'Block followed by paragraph and block' => [
464  '<h1>block1</h1>' . CRLF . 'paragraph' . CRLF . '<h1>block2</h1>',
465  '<h1>block1</h1>' . CRLF . '<p>paragraph</p>' . CRLF . '<h1>block2</h1>',
466  ],
467  ];
468  }
469 
474  public function ‪lineBreakCorrectlyTransformedOnWayToRTE($content, $expectedResult)
475  {
476  $subject = new RteHtmlParser();
477  $thisConfig = ['proc.' => ‪$this->procOptions];
478  $this->assertEquals($expectedResult, $subject->RTE_transform($content, [], 'rte', $thisConfig));
479  }
480 
485  {
486  return [
487  'Empty string' => [
488  '',
489  '',
490  ],
491  'Empty paragraph' => [
492  '<p></p>',
493  '<p>&nbsp;</p>',
494  ],
495  'Double empty paragraph' => [
496  '<p></p><p></p>',
497  '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>',
498  ],
499  'Triple empty paragraph' => [
500  '<p></p><p></p><p></p>',
501  '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>',
502  ],
503  'Plain text' => [
504  'plain text',
505  '<p>plain text</p>',
506  ],
507  'Plain text followed by linebreak' => [
508  'plain text' . CRLF,
509  '<p>plain text </p>',
510  ],
511  'Plain text followed by paragraph' => [
512  'plain text' . '<p>paragraph</p>',
513  '<p>plain text</p>' . CRLF . '<p>paragraph</p>',
514  ],
515  'Spacing paragraph' => [
516  '<p>&nbsp;</p>',
517  '<p>&nbsp;</p>',
518  ],
519  'Double spacing paragraph' => [
520  '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>',
521  '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>',
522  ],
523  'Paragraph' => [
524  '<p>paragraph</p>',
525  '<p>paragraph</p>',
526  ],
527  'Paragraph followed by linebreak' => [
528  '<p>paragraph</p>' . CRLF,
529  '<p>paragraph</p>',
530  ],
531  'Paragraph followed by spacing paragraph' => [
532  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>',
533  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>',
534  ],
535  'Paragraph followed by double spacing paragraph' => [
536  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>',
537  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>',
538  ],
539  'Paragraph followed by paragraph' => [
540  '<p>paragraph1</p>' . '<p>paragraph2</p>',
541  '<p>paragraph1</p>' . CRLF . '<p>paragraph2</p>',
542  ],
543  'Paragraph followed by paragraph, linebreak-separated' => [
544  '<p>paragraph1</p>' . CRLF . '<p>paragraph2</p>',
545  '<p>paragraph1</p>' . CRLF . '<p>paragraph2</p>',
546  ],
547  'Paragraph followed by spacing paragraph and by paragraph' => [
548  '<p>paragraph1</p>' . '<p>&nbsp;</p>' . '<p>paragraph2</p>',
549  '<p>paragraph1</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>paragraph2</p>',
550  ],
551  'Paragraph followed by spacing paragraph and by paragraph, linebreak-separated' => [
552  '<p>paragraph1</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>paragraph2</p>',
553  '<p>paragraph1</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>paragraph2</p>',
554  ],
555  'Paragraph followed by double spacing paragraph and by paragraph' => [
556  '<p>paragraph1</p>' . '<p>&nbsp;</p>' . '<p>&nbsp;</p>' . '<p>paragraph2</p>',
557  '<p>paragraph1</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>paragraph2</p>',
558  ],
559  'Paragraph followed by double spacing paragraph and by paragraph, linebreak-separated' => [
560  '<p>paragraph1</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>paragraph2</p>',
561  '<p>paragraph1</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>paragraph2</p>',
562  ],
563  'Paragraph followed by block' => [
564  '<p>paragraph</p>' . '<h1>block</h1>',
565  '<p>paragraph</p>' . CRLF . '<h1>block</h1>',
566  ],
567  'Paragraph followed by block, linebreak-separated' => [
568  '<p>paragraph</p>' . CRLF . '<h1>block</h1>',
569  '<p>paragraph</p>' . CRLF . '<h1>block</h1>',
570  ],
571  'Paragraph followed by spacing paragraph and by block' => [
572  '<p>paragraph</p>' . '<p>&nbsp;</p>' . '<h1>block</h1>',
573  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block</h1>',
574  ],
575  'Paragraph followed by spacing paragraph and by block, linebreak-separated' => [
576  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block</h1>',
577  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block</h1>',
578  ],
579  'Paragraph followed by double spacing paragraph and by block' => [
580  '<p>paragraph</p>' . '<p>&nbsp;</p>' . '<p>&nbsp;</p>' . '<h1>block</h1>',
581  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block</h1>',
582  ],
583  'Paragraph followed by double spacing paragraph and by block, linebreak-separated' => [
584  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block</h1>',
585  '<p>paragraph</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block</h1>',
586  ],
587  'Block followed by block' => [
588  '<h1>block1</h1>' . '<h1>block2</h1>',
589  '<h1>block1</h1>' . CRLF . '<h1>block2</h1>',
590  ],
591  'Block followed by block, linebreak-separated' => [
592  '<h1>block1</h1>' . CRLF . '<h1>block2</h1>',
593  '<h1>block1</h1>' . CRLF . '<h1>block2</h1>',
594  ],
595  'Block followed by empty paragraph and by block' => [
596  '<h1>block1</h1>' . '<p></p>' . '<h1>block2</h1>',
597  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
598  ],
599  'Block followed by empty paragraph and by block, linebreak-separated' => [
600  '<h1>block1</h1>' . CRLF . '<p></p>' . CRLF . '<h1>block2</h1>',
601  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
602  ],
603  'Block followed by spacing paragraph and by block' => [
604  '<h1>block1</h1>' . '<p>&nbsp;</p>' . '<h1>block2</h1>',
605  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
606  ],
607  'Block followed by spacing paragraph and by block, linebreak-separated' => [
608  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
609  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
610  ],
611  'Block followed by double spacing paragraph and by block' => [
612  '<h1>block1</h1>' . '<p>&nbsp;</p>' . '<p>&nbsp;</p>' . '<h1>block2</h1>',
613  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
614  ],
615  'Block followed by double spacing paragraph and by block, linebreak-separated' => [
616  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
617  '<h1>block1</h1>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<p>&nbsp;</p>' . CRLF . '<h1>block2</h1>',
618  ],
619  ];
620  }
621 
626  public function ‪paragraphCorrectlyTransformedOnWayToDatabaseAndBackToRte($content, $expectedResult)
627  {
628  $subject = new RteHtmlParser();
629  $thisConfig = ['proc.' => ‪$this->procOptions];
630  $this->assertEquals($expectedResult, $subject->RTE_transform($subject->RTE_transform($content, [], 'db', $thisConfig), [], 'rte', $thisConfig));
631  }
632 
637  {
638  return [
639  [
640  '<p><a name="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>',
641  '<p><a name="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>'
642  ],
643  [
644  '<p><a id="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>',
645  '<p><a id="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>'
646  ],
647  [
648  '<p><a name="some_anchor" id="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>',
649  '<p><a name="some_anchor" id="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>'
650  ],
651  [
652  '<p><a id="some_anchor">Some text inside the anchor</a></p>',
653  '<p><a id="some_anchor">Some text inside the anchor</a></p>'
654  ]
655  ];
656  }
657 
664  public function ‪anchorCorrectlyTransformedOnWayToDatabase($content, $expectedResult)
665  {
666  $subject = new RteHtmlParser();
667  $thisConfig = ['proc.' => ‪$this->procOptions];
668  self::assertEquals($expectedResult, $subject->RTE_transform($content, [], 'db', $thisConfig));
669  }
670 
675  {
676  return [
677  [
678  '<p><a name="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>',
679  '<p><a name="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>'
680  ],
681  [
682  '<p><a id="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>',
683  '<p><a id="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>'
684  ],
685  [
686  '<p><a name="some_anchor" id="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>',
687  '<p><a name="some_anchor" id="some_anchor"></a></p>' . CRLF . '<h3>Some headline here</h3>'
688  ],
689  [
690  '<p><a id="some_anchor">Some text inside the anchor</a></p>',
691  '<p><a id="some_anchor">Some text inside the anchor</a></p>'
692  ]
693  ];
694  }
695 
702  public function ‪anchorCorrectlyTransformedOnWayToDatabaseAndBackToRTE($content, $expectedResult)
703  {
704  $subject = new RteHtmlParser();
705  $thisConfig = ['proc.' => ‪$this->procOptions];
706  self::assertEquals($expectedResult, $subject->RTE_transform($subject->RTE_transform($content, [], 'db', $thisConfig), [], 'rte', $thisConfig));
707  }
708 }
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\$procOptions
‪$procOptions
Definition: RteHtmlParserTest.php:30
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\paragraphCorrectlyTransformedOnWayToDatabaseProvider
‪static paragraphCorrectlyTransformedOnWayToDatabaseProvider()
Definition: RteHtmlParserTest.php:195
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\paragraphCorrectlyTransformedOnWayToDatabase
‪paragraphCorrectlyTransformedOnWayToDatabase($content, $expectedResult)
Definition: RteHtmlParserTest.php:373
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\lineBreakCorrectlyTransformedOnWayToRTE
‪lineBreakCorrectlyTransformedOnWayToRTE($content, $expectedResult)
Definition: RteHtmlParserTest.php:473
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\anchorCorrectlyTransformedOnWayToDatabaseAndBackToRTE
‪anchorCorrectlyTransformedOnWayToDatabaseAndBackToRTE($content, $expectedResult)
Definition: RteHtmlParserTest.php:701
‪TYPO3\CMS\Core\Tests\Unit\Html
Definition: HtmlParserTest.php:4
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\anchorCorrectlyTransformedOnWayToDatabaseAndBackToRTEProvider
‪static anchorCorrectlyTransformedOnWayToDatabaseAndBackToRTEProvider()
Definition: RteHtmlParserTest.php:673
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\anchorCorrectlyTransformedOnWayToDatabaseProvider
‪static anchorCorrectlyTransformedOnWayToDatabaseProvider()
Definition: RteHtmlParserTest.php:635
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\lineBreakCorrectlyTransformedOnWayToRteProvider
‪static lineBreakCorrectlyTransformedOnWayToRteProvider()
Definition: RteHtmlParserTest.php:383
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\paragraphCorrectlyTransformedOnWayToDatabaseAndBackToRte
‪paragraphCorrectlyTransformedOnWayToDatabaseAndBackToRte($content, $expectedResult)
Definition: RteHtmlParserTest.php:625
‪TYPO3\CMS\Core\Html\RteHtmlParser
Definition: RteHtmlParser.php:40
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\hrTagCorrectlyTransformedOnWayToDatabaseAndBackToRteProvider
‪static hrTagCorrectlyTransformedOnWayToDatabaseAndBackToRteProvider()
Definition: RteHtmlParserTest.php:117
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest
Definition: RteHtmlParserTest.php:25
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\paragraphCorrectlyTransformedOnWayToDatabaseAndBackToRteProvider
‪static paragraphCorrectlyTransformedOnWayToDatabaseAndBackToRteProvider()
Definition: RteHtmlParserTest.php:483
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\hrTagCorrectlyTransformedOnWayToDataBaseDataProvider
‪static hrTagCorrectlyTransformedOnWayToDataBaseDataProvider()
Definition: RteHtmlParserTest.php:35
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\$resetSingletonInstances
‪bool $resetSingletonInstances
Definition: RteHtmlParserTest.php:28
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\hrTagCorrectlyTransformedOnWayToDatabaseAndBackToRte
‪hrTagCorrectlyTransformedOnWayToDatabaseAndBackToRte($content, $expectedResult)
Definition: RteHtmlParserTest.php:183
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\anchorCorrectlyTransformedOnWayToDatabase
‪anchorCorrectlyTransformedOnWayToDatabase($content, $expectedResult)
Definition: RteHtmlParserTest.php:663
‪TYPO3\CMS\Core\Tests\Unit\Html\RteHtmlParserTest\hrTagCorrectlyTransformedOnWayToDataBase
‪hrTagCorrectlyTransformedOnWayToDataBase($content, $expectedResult)
Definition: RteHtmlParserTest.php:105