Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@0
|
3 * Provide general element functions.
|
Chris@0
|
4 */
|
Chris@17
|
5
|
Chris@0
|
6 namespace Masterminds\HTML5;
|
Chris@0
|
7
|
Chris@0
|
8 /**
|
Chris@0
|
9 * This class provides general information about HTML5 elements,
|
Chris@0
|
10 * including syntactic and semantic issues.
|
Chris@0
|
11 * Parsers and serializers can
|
Chris@0
|
12 * use this class as a reference point for information about the rules
|
Chris@0
|
13 * of various HTML5 elements.
|
Chris@0
|
14 *
|
Chris@0
|
15 * @todo consider using a bitmask table lookup. There is enough overlap in
|
Chris@0
|
16 * naming that this could significantly shrink the size and maybe make it
|
Chris@0
|
17 * faster. See the Go teams implementation at https://code.google.com/p/go/source/browse/html/atom.
|
Chris@0
|
18 */
|
Chris@0
|
19 class Elements
|
Chris@0
|
20 {
|
Chris@0
|
21 /**
|
Chris@0
|
22 * Indicates an element is described in the specification.
|
Chris@0
|
23 */
|
Chris@0
|
24 const KNOWN_ELEMENT = 1;
|
Chris@0
|
25
|
Chris@0
|
26 // From section 8.1.2: "script", "style"
|
Chris@0
|
27 // From 8.2.5.4.7 ("in body" insertion mode): "noembed"
|
Chris@0
|
28 // From 8.4 "style", "xmp", "iframe", "noembed", "noframes"
|
Chris@0
|
29 /**
|
Chris@0
|
30 * Indicates the contained text should be processed as raw text.
|
Chris@0
|
31 */
|
Chris@0
|
32 const TEXT_RAW = 2;
|
Chris@0
|
33
|
Chris@0
|
34 // From section 8.1.2: "textarea", "title"
|
Chris@0
|
35 /**
|
Chris@0
|
36 * Indicates the contained text should be processed as RCDATA.
|
Chris@0
|
37 */
|
Chris@0
|
38 const TEXT_RCDATA = 4;
|
Chris@0
|
39
|
Chris@0
|
40 /**
|
Chris@0
|
41 * Indicates the tag cannot have content.
|
Chris@0
|
42 */
|
Chris@0
|
43 const VOID_TAG = 8;
|
Chris@0
|
44
|
Chris@0
|
45 // "address", "article", "aside", "blockquote", "center", "details", "dialog", "dir", "div", "dl",
|
Chris@0
|
46 // "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "menu",
|
Chris@0
|
47 // "nav", "ol", "p", "section", "summary", "ul"
|
Chris@0
|
48 // "h1", "h2", "h3", "h4", "h5", "h6"
|
Chris@0
|
49 // "pre", "listing"
|
Chris@0
|
50 // "form"
|
Chris@0
|
51 // "plaintext"
|
Chris@0
|
52 /**
|
Chris@0
|
53 * Indicates that if a previous event is for a P tag, that element
|
Chris@0
|
54 * should be considered closed.
|
Chris@0
|
55 */
|
Chris@0
|
56 const AUTOCLOSE_P = 16;
|
Chris@0
|
57
|
Chris@0
|
58 /**
|
Chris@0
|
59 * Indicates that the text inside is plaintext (pre).
|
Chris@0
|
60 */
|
Chris@0
|
61 const TEXT_PLAINTEXT = 32;
|
Chris@0
|
62
|
Chris@0
|
63 // See https://developer.mozilla.org/en-US/docs/HTML/Block-level_elements
|
Chris@0
|
64 /**
|
Chris@0
|
65 * Indicates that the tag is a block.
|
Chris@0
|
66 */
|
Chris@0
|
67 const BLOCK_TAG = 64;
|
Chris@0
|
68
|
Chris@0
|
69 /**
|
Chris@0
|
70 * Indicates that the tag allows only inline elements as child nodes.
|
Chris@0
|
71 */
|
Chris@0
|
72 const BLOCK_ONLY_INLINE = 128;
|
Chris@0
|
73
|
Chris@0
|
74 /**
|
Chris@0
|
75 * The HTML5 elements as defined in http://dev.w3.org/html5/markup/elements.html.
|
Chris@0
|
76 *
|
Chris@0
|
77 * @var array
|
Chris@0
|
78 */
|
Chris@0
|
79 public static $html5 = array(
|
Chris@17
|
80 'a' => 1,
|
Chris@17
|
81 'abbr' => 1,
|
Chris@17
|
82 'address' => 65, // NORMAL | BLOCK_TAG
|
Chris@17
|
83 'area' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
84 'article' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
85 'aside' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
86 'audio' => 1, // NORMAL
|
Chris@17
|
87 'b' => 1,
|
Chris@17
|
88 'base' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
89 'bdi' => 1,
|
Chris@17
|
90 'bdo' => 1,
|
Chris@17
|
91 'blockquote' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
92 'body' => 1,
|
Chris@17
|
93 'br' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
94 'button' => 1,
|
Chris@17
|
95 'canvas' => 65, // NORMAL | BLOCK_TAG
|
Chris@17
|
96 'caption' => 1,
|
Chris@17
|
97 'cite' => 1,
|
Chris@17
|
98 'code' => 1,
|
Chris@17
|
99 'col' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
100 'colgroup' => 1,
|
Chris@17
|
101 'command' => 9, // NORMAL | VOID_TAG
|
Chris@0
|
102 // "data" => 1, // This is highly experimental and only part of the whatwg spec (not w3c). See https://developer.mozilla.org/en-US/docs/HTML/Element/data
|
Chris@17
|
103 'datalist' => 1,
|
Chris@17
|
104 'dd' => 65, // NORMAL | BLOCK_TAG
|
Chris@17
|
105 'del' => 1,
|
Chris@17
|
106 'details' => 17, // NORMAL | AUTOCLOSE_P,
|
Chris@17
|
107 'dfn' => 1,
|
Chris@17
|
108 'dialog' => 17, // NORMAL | AUTOCLOSE_P,
|
Chris@17
|
109 'div' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
110 'dl' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
111 'dt' => 1,
|
Chris@17
|
112 'em' => 1,
|
Chris@17
|
113 'embed' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
114 'fieldset' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
115 'figcaption' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
116 'figure' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
117 'footer' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
118 'form' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
119 'h1' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
120 'h2' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
121 'h3' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
122 'h4' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
123 'h5' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
124 'h6' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
125 'head' => 1,
|
Chris@17
|
126 'header' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
127 'hgroup' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
128 'hr' => 73, // NORMAL | VOID_TAG
|
Chris@17
|
129 'html' => 1,
|
Chris@17
|
130 'i' => 1,
|
Chris@17
|
131 'iframe' => 3, // NORMAL | TEXT_RAW
|
Chris@17
|
132 'img' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
133 'input' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
134 'kbd' => 1,
|
Chris@17
|
135 'ins' => 1,
|
Chris@17
|
136 'keygen' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
137 'label' => 1,
|
Chris@17
|
138 'legend' => 1,
|
Chris@17
|
139 'li' => 1,
|
Chris@17
|
140 'link' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
141 'map' => 1,
|
Chris@17
|
142 'mark' => 1,
|
Chris@17
|
143 'menu' => 17, // NORMAL | AUTOCLOSE_P,
|
Chris@17
|
144 'meta' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
145 'meter' => 1,
|
Chris@17
|
146 'nav' => 17, // NORMAL | AUTOCLOSE_P,
|
Chris@17
|
147 'noscript' => 65, // NORMAL | BLOCK_TAG
|
Chris@17
|
148 'object' => 1,
|
Chris@17
|
149 'ol' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
150 'optgroup' => 1,
|
Chris@17
|
151 'option' => 1,
|
Chris@17
|
152 'output' => 65, // NORMAL | BLOCK_TAG
|
Chris@17
|
153 'p' => 209, // NORMAL | AUTOCLOSE_P | BLOCK_TAG | BLOCK_ONLY_INLINE
|
Chris@17
|
154 'param' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
155 'pre' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
156 'progress' => 1,
|
Chris@17
|
157 'q' => 1,
|
Chris@17
|
158 'rp' => 1,
|
Chris@17
|
159 'rt' => 1,
|
Chris@17
|
160 'ruby' => 1,
|
Chris@17
|
161 's' => 1,
|
Chris@17
|
162 'samp' => 1,
|
Chris@17
|
163 'script' => 3, // NORMAL | TEXT_RAW
|
Chris@17
|
164 'section' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
165 'select' => 1,
|
Chris@17
|
166 'small' => 1,
|
Chris@17
|
167 'source' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
168 'span' => 1,
|
Chris@17
|
169 'strong' => 1,
|
Chris@17
|
170 'style' => 3, // NORMAL | TEXT_RAW
|
Chris@17
|
171 'sub' => 1,
|
Chris@17
|
172 'summary' => 17, // NORMAL | AUTOCLOSE_P,
|
Chris@17
|
173 'sup' => 1,
|
Chris@17
|
174 'table' => 65, // NORMAL | BLOCK_TAG
|
Chris@17
|
175 'tbody' => 1,
|
Chris@17
|
176 'td' => 1,
|
Chris@17
|
177 'textarea' => 5, // NORMAL | TEXT_RCDATA
|
Chris@17
|
178 'tfoot' => 65, // NORMAL | BLOCK_TAG
|
Chris@17
|
179 'th' => 1,
|
Chris@17
|
180 'thead' => 1,
|
Chris@17
|
181 'time' => 1,
|
Chris@17
|
182 'title' => 5, // NORMAL | TEXT_RCDATA
|
Chris@17
|
183 'tr' => 1,
|
Chris@17
|
184 'track' => 9, // NORMAL | VOID_TAG
|
Chris@17
|
185 'u' => 1,
|
Chris@17
|
186 'ul' => 81, // NORMAL | AUTOCLOSE_P | BLOCK_TAG
|
Chris@17
|
187 'var' => 1,
|
Chris@17
|
188 'video' => 65, // NORMAL | BLOCK_TAG
|
Chris@17
|
189 'wbr' => 9, // NORMAL | VOID_TAG
|
Chris@0
|
190
|
Chris@0
|
191 // Legacy?
|
Chris@0
|
192 'basefont' => 8, // VOID_TAG
|
Chris@0
|
193 'bgsound' => 8, // VOID_TAG
|
Chris@0
|
194 'noframes' => 2, // RAW_TEXT
|
Chris@0
|
195 'frame' => 9, // NORMAL | VOID_TAG
|
Chris@0
|
196 'frameset' => 1,
|
Chris@0
|
197 'center' => 16,
|
Chris@0
|
198 'dir' => 16,
|
Chris@0
|
199 'listing' => 16, // AUTOCLOSE_P
|
Chris@0
|
200 'plaintext' => 48, // AUTOCLOSE_P | TEXT_PLAINTEXT
|
Chris@0
|
201 'applet' => 0,
|
Chris@0
|
202 'marquee' => 0,
|
Chris@0
|
203 'isindex' => 8, // VOID_TAG
|
Chris@0
|
204 'xmp' => 20, // AUTOCLOSE_P | VOID_TAG | RAW_TEXT
|
Chris@17
|
205 'noembed' => 2, // RAW_TEXT
|
Chris@0
|
206 );
|
Chris@0
|
207
|
Chris@0
|
208 /**
|
Chris@0
|
209 * The MathML elements.
|
Chris@0
|
210 * See http://www.w3.org/wiki/MathML/Elements.
|
Chris@0
|
211 *
|
Chris@0
|
212 * In our case we are only concerned with presentation MathML and not content
|
Chris@0
|
213 * MathML. There is a nice list of this subset at https://developer.mozilla.org/en-US/docs/MathML/Element.
|
Chris@0
|
214 *
|
Chris@0
|
215 * @var array
|
Chris@0
|
216 */
|
Chris@0
|
217 public static $mathml = array(
|
Chris@17
|
218 'maction' => 1,
|
Chris@17
|
219 'maligngroup' => 1,
|
Chris@17
|
220 'malignmark' => 1,
|
Chris@17
|
221 'math' => 1,
|
Chris@17
|
222 'menclose' => 1,
|
Chris@17
|
223 'merror' => 1,
|
Chris@17
|
224 'mfenced' => 1,
|
Chris@17
|
225 'mfrac' => 1,
|
Chris@17
|
226 'mglyph' => 1,
|
Chris@17
|
227 'mi' => 1,
|
Chris@17
|
228 'mlabeledtr' => 1,
|
Chris@17
|
229 'mlongdiv' => 1,
|
Chris@17
|
230 'mmultiscripts' => 1,
|
Chris@17
|
231 'mn' => 1,
|
Chris@17
|
232 'mo' => 1,
|
Chris@17
|
233 'mover' => 1,
|
Chris@17
|
234 'mpadded' => 1,
|
Chris@17
|
235 'mphantom' => 1,
|
Chris@17
|
236 'mroot' => 1,
|
Chris@17
|
237 'mrow' => 1,
|
Chris@17
|
238 'ms' => 1,
|
Chris@17
|
239 'mscarries' => 1,
|
Chris@17
|
240 'mscarry' => 1,
|
Chris@17
|
241 'msgroup' => 1,
|
Chris@17
|
242 'msline' => 1,
|
Chris@17
|
243 'mspace' => 1,
|
Chris@17
|
244 'msqrt' => 1,
|
Chris@17
|
245 'msrow' => 1,
|
Chris@17
|
246 'mstack' => 1,
|
Chris@17
|
247 'mstyle' => 1,
|
Chris@17
|
248 'msub' => 1,
|
Chris@17
|
249 'msup' => 1,
|
Chris@17
|
250 'msubsup' => 1,
|
Chris@17
|
251 'mtable' => 1,
|
Chris@17
|
252 'mtd' => 1,
|
Chris@17
|
253 'mtext' => 1,
|
Chris@17
|
254 'mtr' => 1,
|
Chris@17
|
255 'munder' => 1,
|
Chris@17
|
256 'munderover' => 1,
|
Chris@0
|
257 );
|
Chris@0
|
258
|
Chris@0
|
259 /**
|
Chris@0
|
260 * The svg elements.
|
Chris@0
|
261 *
|
Chris@0
|
262 * The Mozilla documentation has a good list at https://developer.mozilla.org/en-US/docs/SVG/Element.
|
Chris@0
|
263 * The w3c list appears to be lacking in some areas like filter effect elements.
|
Chris@0
|
264 * That list can be found at http://www.w3.org/wiki/SVG/Elements.
|
Chris@0
|
265 *
|
Chris@0
|
266 * Note, FireFox appears to do a better job rendering filter effects than chrome.
|
Chris@0
|
267 * While they are in the spec I'm not sure how widely implemented they are.
|
Chris@0
|
268 *
|
Chris@0
|
269 * @var array
|
Chris@0
|
270 */
|
Chris@0
|
271 public static $svg = array(
|
Chris@17
|
272 'a' => 1,
|
Chris@17
|
273 'altGlyph' => 1,
|
Chris@17
|
274 'altGlyphDef' => 1,
|
Chris@17
|
275 'altGlyphItem' => 1,
|
Chris@17
|
276 'animate' => 1,
|
Chris@17
|
277 'animateColor' => 1,
|
Chris@17
|
278 'animateMotion' => 1,
|
Chris@17
|
279 'animateTransform' => 1,
|
Chris@17
|
280 'circle' => 1,
|
Chris@17
|
281 'clipPath' => 1,
|
Chris@17
|
282 'color-profile' => 1,
|
Chris@17
|
283 'cursor' => 1,
|
Chris@17
|
284 'defs' => 1,
|
Chris@17
|
285 'desc' => 1,
|
Chris@17
|
286 'ellipse' => 1,
|
Chris@17
|
287 'feBlend' => 1,
|
Chris@17
|
288 'feColorMatrix' => 1,
|
Chris@17
|
289 'feComponentTransfer' => 1,
|
Chris@17
|
290 'feComposite' => 1,
|
Chris@17
|
291 'feConvolveMatrix' => 1,
|
Chris@17
|
292 'feDiffuseLighting' => 1,
|
Chris@17
|
293 'feDisplacementMap' => 1,
|
Chris@17
|
294 'feDistantLight' => 1,
|
Chris@17
|
295 'feFlood' => 1,
|
Chris@17
|
296 'feFuncA' => 1,
|
Chris@17
|
297 'feFuncB' => 1,
|
Chris@17
|
298 'feFuncG' => 1,
|
Chris@17
|
299 'feFuncR' => 1,
|
Chris@17
|
300 'feGaussianBlur' => 1,
|
Chris@17
|
301 'feImage' => 1,
|
Chris@17
|
302 'feMerge' => 1,
|
Chris@17
|
303 'feMergeNode' => 1,
|
Chris@17
|
304 'feMorphology' => 1,
|
Chris@17
|
305 'feOffset' => 1,
|
Chris@17
|
306 'fePointLight' => 1,
|
Chris@17
|
307 'feSpecularLighting' => 1,
|
Chris@17
|
308 'feSpotLight' => 1,
|
Chris@17
|
309 'feTile' => 1,
|
Chris@17
|
310 'feTurbulence' => 1,
|
Chris@17
|
311 'filter' => 1,
|
Chris@17
|
312 'font' => 1,
|
Chris@17
|
313 'font-face' => 1,
|
Chris@17
|
314 'font-face-format' => 1,
|
Chris@17
|
315 'font-face-name' => 1,
|
Chris@17
|
316 'font-face-src' => 1,
|
Chris@17
|
317 'font-face-uri' => 1,
|
Chris@17
|
318 'foreignObject' => 1,
|
Chris@17
|
319 'g' => 1,
|
Chris@17
|
320 'glyph' => 1,
|
Chris@17
|
321 'glyphRef' => 1,
|
Chris@17
|
322 'hkern' => 1,
|
Chris@17
|
323 'image' => 1,
|
Chris@17
|
324 'line' => 1,
|
Chris@17
|
325 'linearGradient' => 1,
|
Chris@17
|
326 'marker' => 1,
|
Chris@17
|
327 'mask' => 1,
|
Chris@17
|
328 'metadata' => 1,
|
Chris@17
|
329 'missing-glyph' => 1,
|
Chris@17
|
330 'mpath' => 1,
|
Chris@17
|
331 'path' => 1,
|
Chris@17
|
332 'pattern' => 1,
|
Chris@17
|
333 'polygon' => 1,
|
Chris@17
|
334 'polyline' => 1,
|
Chris@17
|
335 'radialGradient' => 1,
|
Chris@17
|
336 'rect' => 1,
|
Chris@17
|
337 'script' => 3, // NORMAL | RAW_TEXT
|
Chris@17
|
338 'set' => 1,
|
Chris@17
|
339 'stop' => 1,
|
Chris@17
|
340 'style' => 3, // NORMAL | RAW_TEXT
|
Chris@17
|
341 'svg' => 1,
|
Chris@17
|
342 'switch' => 1,
|
Chris@17
|
343 'symbol' => 1,
|
Chris@17
|
344 'text' => 1,
|
Chris@17
|
345 'textPath' => 1,
|
Chris@17
|
346 'title' => 1,
|
Chris@17
|
347 'tref' => 1,
|
Chris@17
|
348 'tspan' => 1,
|
Chris@17
|
349 'use' => 1,
|
Chris@17
|
350 'view' => 1,
|
Chris@17
|
351 'vkern' => 1,
|
Chris@0
|
352 );
|
Chris@0
|
353
|
Chris@0
|
354 /**
|
Chris@17
|
355 * Some attributes in SVG are case sensitive.
|
Chris@0
|
356 *
|
Chris@0
|
357 * This map contains key/value pairs with the key as the lowercase attribute
|
Chris@0
|
358 * name and the value with the correct casing.
|
Chris@0
|
359 */
|
Chris@0
|
360 public static $svgCaseSensitiveAttributeMap = array(
|
Chris@0
|
361 'attributename' => 'attributeName',
|
Chris@0
|
362 'attributetype' => 'attributeType',
|
Chris@0
|
363 'basefrequency' => 'baseFrequency',
|
Chris@0
|
364 'baseprofile' => 'baseProfile',
|
Chris@0
|
365 'calcmode' => 'calcMode',
|
Chris@0
|
366 'clippathunits' => 'clipPathUnits',
|
Chris@0
|
367 'contentscripttype' => 'contentScriptType',
|
Chris@0
|
368 'contentstyletype' => 'contentStyleType',
|
Chris@0
|
369 'diffuseconstant' => 'diffuseConstant',
|
Chris@0
|
370 'edgemode' => 'edgeMode',
|
Chris@0
|
371 'externalresourcesrequired' => 'externalResourcesRequired',
|
Chris@0
|
372 'filterres' => 'filterRes',
|
Chris@0
|
373 'filterunits' => 'filterUnits',
|
Chris@0
|
374 'glyphref' => 'glyphRef',
|
Chris@0
|
375 'gradienttransform' => 'gradientTransform',
|
Chris@0
|
376 'gradientunits' => 'gradientUnits',
|
Chris@0
|
377 'kernelmatrix' => 'kernelMatrix',
|
Chris@0
|
378 'kernelunitlength' => 'kernelUnitLength',
|
Chris@0
|
379 'keypoints' => 'keyPoints',
|
Chris@0
|
380 'keysplines' => 'keySplines',
|
Chris@0
|
381 'keytimes' => 'keyTimes',
|
Chris@0
|
382 'lengthadjust' => 'lengthAdjust',
|
Chris@0
|
383 'limitingconeangle' => 'limitingConeAngle',
|
Chris@0
|
384 'markerheight' => 'markerHeight',
|
Chris@0
|
385 'markerunits' => 'markerUnits',
|
Chris@0
|
386 'markerwidth' => 'markerWidth',
|
Chris@0
|
387 'maskcontentunits' => 'maskContentUnits',
|
Chris@0
|
388 'maskunits' => 'maskUnits',
|
Chris@0
|
389 'numoctaves' => 'numOctaves',
|
Chris@0
|
390 'pathlength' => 'pathLength',
|
Chris@0
|
391 'patterncontentunits' => 'patternContentUnits',
|
Chris@0
|
392 'patterntransform' => 'patternTransform',
|
Chris@0
|
393 'patternunits' => 'patternUnits',
|
Chris@0
|
394 'pointsatx' => 'pointsAtX',
|
Chris@0
|
395 'pointsaty' => 'pointsAtY',
|
Chris@0
|
396 'pointsatz' => 'pointsAtZ',
|
Chris@0
|
397 'preservealpha' => 'preserveAlpha',
|
Chris@0
|
398 'preserveaspectratio' => 'preserveAspectRatio',
|
Chris@0
|
399 'primitiveunits' => 'primitiveUnits',
|
Chris@0
|
400 'refx' => 'refX',
|
Chris@0
|
401 'refy' => 'refY',
|
Chris@0
|
402 'repeatcount' => 'repeatCount',
|
Chris@0
|
403 'repeatdur' => 'repeatDur',
|
Chris@0
|
404 'requiredextensions' => 'requiredExtensions',
|
Chris@0
|
405 'requiredfeatures' => 'requiredFeatures',
|
Chris@0
|
406 'specularconstant' => 'specularConstant',
|
Chris@0
|
407 'specularexponent' => 'specularExponent',
|
Chris@0
|
408 'spreadmethod' => 'spreadMethod',
|
Chris@0
|
409 'startoffset' => 'startOffset',
|
Chris@0
|
410 'stddeviation' => 'stdDeviation',
|
Chris@0
|
411 'stitchtiles' => 'stitchTiles',
|
Chris@0
|
412 'surfacescale' => 'surfaceScale',
|
Chris@0
|
413 'systemlanguage' => 'systemLanguage',
|
Chris@0
|
414 'tablevalues' => 'tableValues',
|
Chris@0
|
415 'targetx' => 'targetX',
|
Chris@0
|
416 'targety' => 'targetY',
|
Chris@0
|
417 'textlength' => 'textLength',
|
Chris@0
|
418 'viewbox' => 'viewBox',
|
Chris@0
|
419 'viewtarget' => 'viewTarget',
|
Chris@0
|
420 'xchannelselector' => 'xChannelSelector',
|
Chris@0
|
421 'ychannelselector' => 'yChannelSelector',
|
Chris@17
|
422 'zoomandpan' => 'zoomAndPan',
|
Chris@0
|
423 );
|
Chris@0
|
424
|
Chris@0
|
425 /**
|
Chris@17
|
426 * Some SVG elements are case sensitive.
|
Chris@0
|
427 * This map contains these.
|
Chris@0
|
428 *
|
Chris@0
|
429 * The map contains key/value store of the name is lowercase as the keys and
|
Chris@0
|
430 * the correct casing as the value.
|
Chris@0
|
431 */
|
Chris@0
|
432 public static $svgCaseSensitiveElementMap = array(
|
Chris@0
|
433 'altglyph' => 'altGlyph',
|
Chris@0
|
434 'altglyphdef' => 'altGlyphDef',
|
Chris@0
|
435 'altglyphitem' => 'altGlyphItem',
|
Chris@0
|
436 'animatecolor' => 'animateColor',
|
Chris@0
|
437 'animatemotion' => 'animateMotion',
|
Chris@0
|
438 'animatetransform' => 'animateTransform',
|
Chris@0
|
439 'clippath' => 'clipPath',
|
Chris@0
|
440 'feblend' => 'feBlend',
|
Chris@0
|
441 'fecolormatrix' => 'feColorMatrix',
|
Chris@0
|
442 'fecomponenttransfer' => 'feComponentTransfer',
|
Chris@0
|
443 'fecomposite' => 'feComposite',
|
Chris@0
|
444 'feconvolvematrix' => 'feConvolveMatrix',
|
Chris@0
|
445 'fediffuselighting' => 'feDiffuseLighting',
|
Chris@0
|
446 'fedisplacementmap' => 'feDisplacementMap',
|
Chris@0
|
447 'fedistantlight' => 'feDistantLight',
|
Chris@0
|
448 'feflood' => 'feFlood',
|
Chris@0
|
449 'fefunca' => 'feFuncA',
|
Chris@0
|
450 'fefuncb' => 'feFuncB',
|
Chris@0
|
451 'fefuncg' => 'feFuncG',
|
Chris@0
|
452 'fefuncr' => 'feFuncR',
|
Chris@0
|
453 'fegaussianblur' => 'feGaussianBlur',
|
Chris@0
|
454 'feimage' => 'feImage',
|
Chris@0
|
455 'femerge' => 'feMerge',
|
Chris@0
|
456 'femergenode' => 'feMergeNode',
|
Chris@0
|
457 'femorphology' => 'feMorphology',
|
Chris@0
|
458 'feoffset' => 'feOffset',
|
Chris@0
|
459 'fepointlight' => 'fePointLight',
|
Chris@0
|
460 'fespecularlighting' => 'feSpecularLighting',
|
Chris@0
|
461 'fespotlight' => 'feSpotLight',
|
Chris@0
|
462 'fetile' => 'feTile',
|
Chris@0
|
463 'feturbulence' => 'feTurbulence',
|
Chris@0
|
464 'foreignobject' => 'foreignObject',
|
Chris@0
|
465 'glyphref' => 'glyphRef',
|
Chris@0
|
466 'lineargradient' => 'linearGradient',
|
Chris@0
|
467 'radialgradient' => 'radialGradient',
|
Chris@17
|
468 'textpath' => 'textPath',
|
Chris@0
|
469 );
|
Chris@0
|
470
|
Chris@0
|
471 /**
|
Chris@0
|
472 * Check whether the given element meets the given criterion.
|
Chris@0
|
473 *
|
Chris@0
|
474 * Example:
|
Chris@0
|
475 *
|
Chris@0
|
476 * Elements::isA('script', Elements::TEXT_RAW); // Returns true.
|
Chris@0
|
477 *
|
Chris@0
|
478 * Elements::isA('script', Elements::TEXT_RCDATA); // Returns false.
|
Chris@0
|
479 *
|
Chris@17
|
480 * @param string $name The element name.
|
Chris@17
|
481 * @param int $mask One of the constants on this class.
|
Chris@17
|
482 *
|
Chris@17
|
483 * @return bool true if the element matches the mask, false otherwise.
|
Chris@0
|
484 */
|
Chris@0
|
485 public static function isA($name, $mask)
|
Chris@0
|
486 {
|
Chris@17
|
487 return (static::element($name) & $mask) === $mask;
|
Chris@0
|
488 }
|
Chris@0
|
489
|
Chris@0
|
490 /**
|
Chris@0
|
491 * Test if an element is a valid html5 element.
|
Chris@0
|
492 *
|
Chris@17
|
493 * @param string $name The name of the element.
|
Chris@0
|
494 *
|
Chris@17
|
495 * @return bool true if a html5 element and false otherwise.
|
Chris@0
|
496 */
|
Chris@0
|
497 public static function isHtml5Element($name)
|
Chris@0
|
498 {
|
Chris@17
|
499 // html5 element names are case insensitive. Forcing lowercase for the check.
|
Chris@0
|
500 // Do we need this check or will all data passed here already be lowercase?
|
Chris@0
|
501 return isset(static::$html5[strtolower($name)]);
|
Chris@0
|
502 }
|
Chris@0
|
503
|
Chris@0
|
504 /**
|
Chris@0
|
505 * Test if an element name is a valid MathML presentation element.
|
Chris@0
|
506 *
|
Chris@17
|
507 * @param string $name The name of the element.
|
Chris@0
|
508 *
|
Chris@17
|
509 * @return bool true if a MathML name and false otherwise.
|
Chris@0
|
510 */
|
Chris@0
|
511 public static function isMathMLElement($name)
|
Chris@0
|
512 {
|
Chris@17
|
513 // MathML is case-sensitive unlike html5 elements.
|
Chris@0
|
514 return isset(static::$mathml[$name]);
|
Chris@0
|
515 }
|
Chris@0
|
516
|
Chris@0
|
517 /**
|
Chris@0
|
518 * Test if an element is a valid SVG element.
|
Chris@0
|
519 *
|
Chris@17
|
520 * @param string $name The name of the element.
|
Chris@0
|
521 *
|
Chris@17
|
522 * @return bool true if a SVG element and false otherise.
|
Chris@0
|
523 */
|
Chris@0
|
524 public static function isSvgElement($name)
|
Chris@0
|
525 {
|
Chris@17
|
526 // SVG is case-sensitive unlike html5 elements.
|
Chris@0
|
527 return isset(static::$svg[$name]);
|
Chris@0
|
528 }
|
Chris@0
|
529
|
Chris@0
|
530 /**
|
Chris@0
|
531 * Is an element name valid in an html5 document.
|
Chris@0
|
532 * This includes html5 elements along with other allowed embedded content
|
Chris@0
|
533 * such as svg and mathml.
|
Chris@0
|
534 *
|
Chris@17
|
535 * @param string $name The name of the element.
|
Chris@0
|
536 *
|
Chris@17
|
537 * @return bool true if valid and false otherwise.
|
Chris@0
|
538 */
|
Chris@0
|
539 public static function isElement($name)
|
Chris@0
|
540 {
|
Chris@0
|
541 return static::isHtml5Element($name) || static::isMathMLElement($name) || static::isSvgElement($name);
|
Chris@0
|
542 }
|
Chris@0
|
543
|
Chris@0
|
544 /**
|
Chris@0
|
545 * Get the element mask for the given element name.
|
Chris@0
|
546 *
|
Chris@17
|
547 * @param string $name The name of the element.
|
Chris@0
|
548 *
|
Chris@17
|
549 * @return int the element mask.
|
Chris@0
|
550 */
|
Chris@0
|
551 public static function element($name)
|
Chris@0
|
552 {
|
Chris@0
|
553 if (isset(static::$html5[$name])) {
|
Chris@0
|
554 return static::$html5[$name];
|
Chris@0
|
555 }
|
Chris@0
|
556 if (isset(static::$svg[$name])) {
|
Chris@0
|
557 return static::$svg[$name];
|
Chris@0
|
558 }
|
Chris@0
|
559 if (isset(static::$mathml[$name])) {
|
Chris@0
|
560 return static::$mathml[$name];
|
Chris@0
|
561 }
|
Chris@0
|
562
|
Chris@17
|
563 return 0;
|
Chris@0
|
564 }
|
Chris@0
|
565
|
Chris@0
|
566 /**
|
Chris@0
|
567 * Normalize a SVG element name to its proper case and form.
|
Chris@0
|
568 *
|
Chris@17
|
569 * @param string $name The name of the element.
|
Chris@0
|
570 *
|
Chris@17
|
571 * @return string the normalized form of the element name.
|
Chris@0
|
572 */
|
Chris@0
|
573 public static function normalizeSvgElement($name)
|
Chris@0
|
574 {
|
Chris@0
|
575 $name = strtolower($name);
|
Chris@0
|
576 if (isset(static::$svgCaseSensitiveElementMap[$name])) {
|
Chris@0
|
577 $name = static::$svgCaseSensitiveElementMap[$name];
|
Chris@0
|
578 }
|
Chris@0
|
579
|
Chris@0
|
580 return $name;
|
Chris@0
|
581 }
|
Chris@0
|
582
|
Chris@0
|
583 /**
|
Chris@0
|
584 * Normalize a SVG attribute name to its proper case and form.
|
Chris@0
|
585 *
|
Chris@17
|
586 * @param string $name The name of the attribute.
|
Chris@0
|
587 *
|
Chris@0
|
588 * @return string The normalized form of the attribute name.
|
Chris@0
|
589 */
|
Chris@0
|
590 public static function normalizeSvgAttribute($name)
|
Chris@0
|
591 {
|
Chris@0
|
592 $name = strtolower($name);
|
Chris@0
|
593 if (isset(static::$svgCaseSensitiveAttributeMap[$name])) {
|
Chris@0
|
594 $name = static::$svgCaseSensitiveAttributeMap[$name];
|
Chris@0
|
595 }
|
Chris@0
|
596
|
Chris@0
|
597 return $name;
|
Chris@0
|
598 }
|
Chris@0
|
599
|
Chris@0
|
600 /**
|
Chris@0
|
601 * Normalize a MathML attribute name to its proper case and form.
|
Chris@0
|
602 * Note, all MathML element names are lowercase.
|
Chris@0
|
603 *
|
Chris@17
|
604 * @param string $name The name of the attribute.
|
Chris@0
|
605 *
|
Chris@0
|
606 * @return string The normalized form of the attribute name.
|
Chris@0
|
607 */
|
Chris@0
|
608 public static function normalizeMathMlAttribute($name)
|
Chris@0
|
609 {
|
Chris@0
|
610 $name = strtolower($name);
|
Chris@0
|
611
|
Chris@0
|
612 // Only one attribute has a mixed case form for MathML.
|
Chris@17
|
613 if ('definitionurl' === $name) {
|
Chris@0
|
614 $name = 'definitionURL';
|
Chris@0
|
615 }
|
Chris@0
|
616
|
Chris@0
|
617 return $name;
|
Chris@0
|
618 }
|
Chris@0
|
619 }
|