1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* (c) Steve Nebes <[email protected]>. |
4
|
|
|
* |
5
|
|
|
* For the full copyright and license information, please view the LICENSE |
6
|
|
|
* file that was distributed with this source code. |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
declare(strict_types=1); |
10
|
|
|
|
11
|
|
|
namespace SN\HtmlSanitizer\Extension; |
12
|
|
|
|
13
|
|
|
use SN\HtmlSanitizer\NodeVisitor\NodeVisitorInterface; |
14
|
|
|
use SN\HtmlSanitizer\NodeVisitor\TagNodeVisitor; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* HTML5 Extension. |
18
|
|
|
*/ |
19
|
|
|
class HTML5Extension implements ExtensionInterface |
20
|
|
|
{ |
21
|
|
|
/** |
22
|
|
|
* @return string |
23
|
|
|
*/ |
24
|
6 |
|
public function getName(): string |
25
|
|
|
{ |
26
|
6 |
|
return 'html5'; |
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @param array $config |
31
|
|
|
* |
32
|
|
|
* @return NodeVisitorInterface[] |
33
|
|
|
*/ |
34
|
5 |
|
public function createNodeVisitors(array $config = []): array |
35
|
|
|
{ |
36
|
|
|
return [ |
37
|
|
|
// Main root |
38
|
5 |
|
'html' => new TagNodeVisitor('html', $config['tags']['html'] ?? []), |
39
|
|
|
|
40
|
|
|
// Document metadata |
41
|
5 |
|
'base' => new TagNodeVisitor('base', $config['tags']['base'] ?? ['childless' => true]), |
42
|
5 |
|
'head' => new TagNodeVisitor('head', $config['tags']['head'] ?? []), |
43
|
5 |
|
'link' => new TagNodeVisitor('link', $config['tags']['link'] ?? ['childless' => true]), |
44
|
5 |
|
'meta' => new TagNodeVisitor('meta', $config['tags']['meta'] ?? ['childless' => true]), |
45
|
5 |
|
'style' => new TagNodeVisitor('style', $config['tags']['style'] ?? []), |
46
|
5 |
|
'title' => new TagNodeVisitor('title', $config['tags']['title'] ?? []), |
47
|
|
|
|
48
|
|
|
// Sectioning root |
49
|
5 |
|
'body' => new TagNodeVisitor('body', $config['tags']['body'] ?? []), |
50
|
|
|
|
51
|
|
|
// Content sectioning |
52
|
5 |
|
'address' => new TagNodeVisitor('address', $config['tags']['address'] ?? []), |
53
|
5 |
|
'article' => new TagNodeVisitor('article', $config['tags']['article'] ?? []), |
54
|
5 |
|
'aside' => new TagNodeVisitor('aside', $config['tags']['aside'] ?? []), |
55
|
5 |
|
'footer' => new TagNodeVisitor('footer', $config['tags']['footer'] ?? []), |
56
|
5 |
|
'header' => new TagNodeVisitor('header', $config['tags']['header'] ?? []), |
57
|
5 |
|
'h1' => new TagNodeVisitor('h1', $config['tags']['h1'] ?? []), |
58
|
5 |
|
'h2' => new TagNodeVisitor('h2', $config['tags']['h2'] ?? []), |
59
|
5 |
|
'h3' => new TagNodeVisitor('h3', $config['tags']['h3'] ?? []), |
60
|
5 |
|
'h4' => new TagNodeVisitor('h4', $config['tags']['h4'] ?? []), |
61
|
5 |
|
'h5' => new TagNodeVisitor('h5', $config['tags']['h5'] ?? []), |
62
|
5 |
|
'h6' => new TagNodeVisitor('h6', $config['tags']['h6'] ?? []), |
63
|
5 |
|
'hgroup' => new TagNodeVisitor('hgroup', $config['tags']['hgroup'] ?? []), |
64
|
5 |
|
'main' => new TagNodeVisitor('main', $config['tags']['main'] ?? []), |
65
|
5 |
|
'nav' => new TagNodeVisitor('nav', $config['tags']['nav'] ?? []), |
66
|
5 |
|
'section' => new TagNodeVisitor('section', $config['tags']['section'] ?? []), |
67
|
|
|
|
68
|
|
|
// Text content |
69
|
5 |
|
'blockquote' => new TagNodeVisitor('blockquote', $config['tags']['blockquote'] ?? []), |
70
|
5 |
|
'dd' => new TagNodeVisitor('dd', $config['tags']['dd'] ?? []), |
71
|
5 |
|
'dir' => new TagNodeVisitor('dir', $config['tags']['dir'] ?? []), |
72
|
5 |
|
'div' => new TagNodeVisitor('div', $config['tags']['div'] ?? []), |
73
|
5 |
|
'dl' => new TagNodeVisitor('dl', $config['tags']['dl'] ?? []), |
74
|
5 |
|
'dt' => new TagNodeVisitor('dt', $config['tags']['dt'] ?? []), |
75
|
5 |
|
'figcaption' => new TagNodeVisitor('figcaption', $config['tags']['figcaption'] ?? []), |
76
|
5 |
|
'figure' => new TagNodeVisitor('figure', $config['tags']['figure'] ?? []), |
77
|
5 |
|
'hr' => new TagNodeVisitor('hr', $config['tags']['hr'] ?? ['childless' => true]), |
78
|
5 |
|
'li' => new TagNodeVisitor('li', $config['tags']['li'] ?? []), |
79
|
5 |
|
'ol' => new TagNodeVisitor('ol', $config['tags']['ol'] ?? []), |
80
|
5 |
|
'p' => new TagNodeVisitor('p', $config['tags']['p'] ?? []), |
81
|
5 |
|
'pre' => new TagNodeVisitor('pre', $config['tags']['pre'] ?? []), |
82
|
5 |
|
'ul' => new TagNodeVisitor('ul', $config['tags']['ul'] ?? []), |
83
|
|
|
|
84
|
|
|
// Inline text semantics |
85
|
5 |
|
'a' => new TagNodeVisitor('a', $config['tags']['a'] ?? []), |
86
|
5 |
|
'abbr' => new TagNodeVisitor('abbr', $config['tags']['abbr'] ?? []), |
87
|
5 |
|
'b' => new TagNodeVisitor('b', $config['tags']['b'] ?? []), |
88
|
5 |
|
'bdi' => new TagNodeVisitor('bdi', $config['tags']['bdi'] ?? []), |
89
|
5 |
|
'bdo' => new TagNodeVisitor('bdo', $config['tags']['bdo'] ?? []), |
90
|
5 |
|
'br' => new TagNodeVisitor('br', $config['tags']['br'] ?? ['childless' => true]), |
91
|
5 |
|
'cite' => new TagNodeVisitor('cite', $config['tags']['cite'] ?? []), |
92
|
5 |
|
'code' => new TagNodeVisitor('code', $config['tags']['code'] ?? []), |
93
|
5 |
|
'data' => new TagNodeVisitor('data', $config['tags']['data'] ?? []), |
94
|
5 |
|
'dfn' => new TagNodeVisitor('dfn', $config['tags']['dfn'] ?? []), |
95
|
5 |
|
'em' => new TagNodeVisitor('em', $config['tags']['em'] ?? []), |
96
|
5 |
|
'i' => new TagNodeVisitor('i', $config['tags']['i'] ?? []), |
97
|
5 |
|
'kbd' => new TagNodeVisitor('kbd', $config['tags']['kbd'] ?? []), |
98
|
5 |
|
'mark' => new TagNodeVisitor('mark', $config['tags']['mark'] ?? []), |
99
|
5 |
|
'q' => new TagNodeVisitor('q', $config['tags']['q'] ?? []), |
100
|
5 |
|
'rb' => new TagNodeVisitor('rb', $config['tags']['rb'] ?? []), |
101
|
5 |
|
'rp' => new TagNodeVisitor('rp', $config['tags']['rp'] ?? []), |
102
|
5 |
|
'rt' => new TagNodeVisitor('rt', $config['tags']['rt'] ?? []), |
103
|
5 |
|
'rtc' => new TagNodeVisitor('rtc', $config['tags']['rtc'] ?? []), |
104
|
5 |
|
'ruby' => new TagNodeVisitor('ruby', $config['tags']['ruby'] ?? []), |
105
|
5 |
|
's' => new TagNodeVisitor('s', $config['tags']['s'] ?? []), |
106
|
5 |
|
'samp' => new TagNodeVisitor('samp', $config['tags']['samp'] ?? []), |
107
|
5 |
|
'small' => new TagNodeVisitor('small', $config['tags']['small'] ?? []), |
108
|
5 |
|
'span' => new TagNodeVisitor('span', $config['tags']['span'] ?? []), |
109
|
5 |
|
'strong' => new TagNodeVisitor('strong', $config['tags']['strong'] ?? []), |
110
|
5 |
|
'sub' => new TagNodeVisitor('sub', $config['tags']['sub'] ?? []), |
111
|
5 |
|
'sup' => new TagNodeVisitor('sup', $config['tags']['sup'] ?? []), |
112
|
5 |
|
'time' => new TagNodeVisitor('time', $config['tags']['time'] ?? []), |
113
|
5 |
|
'tt' => new TagNodeVisitor('tt', $config['tags']['tt'] ?? []), |
114
|
5 |
|
'u' => new TagNodeVisitor('u', $config['tags']['u'] ?? []), |
115
|
5 |
|
'var' => new TagNodeVisitor('var', $config['tags']['var'] ?? []), |
116
|
5 |
|
'wbr' => new TagNodeVisitor('wbr', $config['tags']['wbr'] ?? ['childless' => true]), |
117
|
|
|
|
118
|
|
|
// Image and multimedia |
119
|
5 |
|
'area' => new TagNodeVisitor('area', $config['tags']['area'] ?? ['childless' => true]), |
120
|
5 |
|
'audio' => new TagNodeVisitor('audio', $config['tags']['audio'] ?? []), |
121
|
5 |
|
'img' => new TagNodeVisitor('img', $config['tags']['img'] ?? ['childless' => true]), |
122
|
5 |
|
'map' => new TagNodeVisitor('map', $config['tags']['map'] ?? []), |
123
|
5 |
|
'track' => new TagNodeVisitor('track', $config['tags']['track'] ?? ['childless' => true]), |
124
|
5 |
|
'video' => new TagNodeVisitor('video', $config['tags']['video'] ?? []), |
125
|
|
|
|
126
|
|
|
// Embedded content |
127
|
5 |
|
'applet' => new TagNodeVisitor('applet', $config['tags']['applet'] ?? []), |
128
|
5 |
|
'embed' => new TagNodeVisitor('embed', $config['tags']['embed'] ?? []), |
129
|
5 |
|
'iframe' => new TagNodeVisitor('iframe', $config['tags']['iframe'] ?? []), |
130
|
5 |
|
'noembed' => new TagNodeVisitor('noembed', $config['tags']['noembed'] ?? []), |
131
|
5 |
|
'object' => new TagNodeVisitor('object', $config['tags']['object'] ?? []), |
132
|
5 |
|
'param' => new TagNodeVisitor('param', $config['tags']['param'] ?? ['childless' => true]), |
133
|
5 |
|
'picture' => new TagNodeVisitor('picture', $config['tags']['picture'] ?? []), |
134
|
5 |
|
'source' => new TagNodeVisitor('source', $config['tags']['source'] ?? []), |
135
|
|
|
|
136
|
|
|
// Scripting |
137
|
5 |
|
'canvas' => new TagNodeVisitor('canvas', $config['tags']['canvas'] ?? []), |
138
|
5 |
|
'noscript' => new TagNodeVisitor('noscript', $config['tags']['noscript'] ?? []), |
139
|
5 |
|
'script' => new TagNodeVisitor('script', $config['tags']['script'] ?? []), |
140
|
|
|
|
141
|
|
|
// Demarcating edits |
142
|
5 |
|
'del' => new TagNodeVisitor('del', $config['tags']['del'] ?? []), |
143
|
5 |
|
'ins' => new TagNodeVisitor('ins', $config['tags']['ins'] ?? []), |
144
|
|
|
|
145
|
|
|
// Table content |
146
|
5 |
|
'caption' => new TagNodeVisitor('caption', $config['tags']['caption'] ?? []), |
147
|
5 |
|
'col' => new TagNodeVisitor('col', $config['tags']['col'] ?? ['childless' => true]), |
148
|
5 |
|
'colgroup' => new TagNodeVisitor('colgroup', $config['tags']['colgroup'] ?? []), |
149
|
5 |
|
'table' => new TagNodeVisitor('table', $config['tags']['table'] ?? []), |
150
|
5 |
|
'tbody' => new TagNodeVisitor('tbody', $config['tags']['tbody'] ?? []), |
151
|
5 |
|
'td' => new TagNodeVisitor('td', $config['tags']['td'] ?? []), |
152
|
5 |
|
'tfoot' => new TagNodeVisitor('tfoot', $config['tags']['tfoot'] ?? []), |
153
|
5 |
|
'th' => new TagNodeVisitor('th', $config['tags']['th'] ?? []), |
154
|
5 |
|
'thead' => new TagNodeVisitor('thead', $config['tags']['thead'] ?? []), |
155
|
5 |
|
'tr' => new TagNodeVisitor('tr', $config['tags']['tr'] ?? []), |
156
|
|
|
|
157
|
|
|
// Forms |
158
|
5 |
|
'button' => new TagNodeVisitor('button', $config['tags']['button'] ?? []), |
159
|
5 |
|
'datalist' => new TagNodeVisitor('datalist', $config['tags']['datalist'] ?? []), |
160
|
5 |
|
'fieldset' => new TagNodeVisitor('fieldset', $config['tags']['fieldset'] ?? []), |
161
|
5 |
|
'form' => new TagNodeVisitor('form', $config['tags']['form'] ?? []), |
162
|
5 |
|
'input' => new TagNodeVisitor('input', $config['tags']['input'] ?? ['childless' => true]), |
163
|
5 |
|
'label' => new TagNodeVisitor('label', $config['tags']['label'] ?? []), |
164
|
5 |
|
'legend' => new TagNodeVisitor('legend', $config['tags']['legend'] ?? []), |
165
|
5 |
|
'meter' => new TagNodeVisitor('meter', $config['tags']['meter'] ?? []), |
166
|
5 |
|
'optgroup' => new TagNodeVisitor('optgroup', $config['tags']['optgroup'] ?? []), |
167
|
5 |
|
'option' => new TagNodeVisitor('option', $config['tags']['option'] ?? []), |
168
|
5 |
|
'output' => new TagNodeVisitor('output', $config['tags']['output'] ?? []), |
169
|
5 |
|
'progress' => new TagNodeVisitor('progress', $config['tags']['progress'] ?? []), |
170
|
5 |
|
'select' => new TagNodeVisitor('select', $config['tags']['select'] ?? []), |
171
|
5 |
|
'textarea' => new TagNodeVisitor('textarea', $config['tags']['textarea'] ?? []), |
172
|
|
|
|
173
|
|
|
// Interactive elements |
174
|
5 |
|
'details' => new TagNodeVisitor('details', $config['tags']['details'] ?? []), |
175
|
5 |
|
'dialog' => new TagNodeVisitor('dialog', $config['tags']['dialog'] ?? []), |
176
|
5 |
|
'menu' => new TagNodeVisitor('menu', $config['tags']['menu'] ?? []), |
177
|
5 |
|
'menuitem' => new TagNodeVisitor('menuitem', $config['tags']['menuitem'] ?? []), |
178
|
5 |
|
'summary' => new TagNodeVisitor('summary', $config['tags']['summary'] ?? []), |
179
|
|
|
|
180
|
|
|
// Web Components |
181
|
5 |
|
'content' => new TagNodeVisitor('content', $config['tags']['content'] ?? []), |
182
|
5 |
|
'element' => new TagNodeVisitor('element', $config['tags']['element'] ?? []), |
183
|
5 |
|
'shadow' => new TagNodeVisitor('shadow', $config['tags']['shadow'] ?? []), |
184
|
5 |
|
'slot' => new TagNodeVisitor('slot', $config['tags']['slot'] ?? []), |
185
|
5 |
|
'template' => new TagNodeVisitor('template', $config['tags']['template'] ?? []), |
186
|
|
|
]; |
187
|
|
|
} |
188
|
|
|
} |
189
|
|
|
|