]> code.delx.au - gnu-emacs-elpa/blob - web-forms.rnc
Allow "minlength"
[gnu-emacs-elpa] / web-forms.rnc
1 datatypes w = "http://whattf.org/datatype-draft"
2
3 # #####################################################################
4 ## RELAX NG Schema for HTML 5: Web Forms 1.0 markup #
5 # #####################################################################
6
7 ## Shared attributes for form controls
8
9 common-form.attrs =
10 ( common-form.attrs.name?
11 & common-form.attrs.disabled?
12 )
13
14 common-form.attrs.name =
15 attribute name {
16 form.data.nonemptystring
17 }
18
19 common-form.attrs.disabled =
20 attribute disabled {
21 w:string "disabled" | w:string ""
22 }
23
24 shared-form.attrs.readonly =
25 attribute readonly {
26 w:string "readonly" | w:string ""
27 }
28
29 shared-form.attrs.maxlength =
30 attribute maxlength {
31 common.data.integer.non-negative
32 }
33
34 shared-form.attrs.minlength =
35 attribute minlength {
36 common.data.integer.non-negative
37 }
38
39 shared-form.attrs.size =
40 attribute size {
41 common.data.integer.positive
42 }
43
44 # REVISIT tabindex goes in common.attrs
45
46 ## Shared attributes for <input>
47
48 input.attrs.checked =
49 attribute checked {
50 w:string "checked" | w:string ""
51 }
52
53 ## Text Field: <input type='text'>
54
55 input.text.elem =
56 element input { input.text.attrs }
57 input.text.attrs =
58 ( common.attrs
59 & common-form.attrs
60 & input.text.attrs.type?
61 & shared-form.attrs.maxlength?
62 & shared-form.attrs.readonly?
63 & shared-form.attrs.size?
64 & input.text.attrs.value?
65 & ( common.attrs.aria.implicit.textbox
66 | common.attrs.aria.implicit.combobox
67 | common.attrs.aria.role.textbox
68 | common.attrs.aria.role.combobox
69 )?
70 )
71 input.text.attrs.type =
72 attribute type {
73 w:string "text"
74 }
75 input.text.attrs.value =
76 attribute value {
77 form.data.stringwithoutlinebreaks
78 }
79
80 input.elem = input.text.elem
81
82 ## Password Field: <input type='password'>
83
84 input.password.elem =
85 element input { input.password.attrs }
86 input.password.attrs =
87 ( common.attrs
88 & common-form.attrs
89 & input.password.attrs.type
90 & shared-form.attrs.maxlength?
91 & shared-form.attrs.readonly?
92 & shared-form.attrs.size?
93 & input.password.attrs.value?
94 & ( common.attrs.aria.implicit.textbox
95 | common.attrs.aria.role.textbox
96 )?
97 )
98 input.password.attrs.type =
99 attribute type {
100 w:string "password"
101 }
102 input.password.attrs.value =
103 attribute value {
104 form.data.stringwithoutlinebreaks
105 }
106
107 input.elem |= input.password.elem
108
109 ## Checkbox: <input type='checkbox'>
110
111 input.checkbox.elem =
112 element input { input.checkbox.attrs }
113 input.checkbox.attrs =
114 ( common.attrs
115 & common-form.attrs
116 & input.checkbox.attrs.type
117 & input.attrs.checked?
118 & input.checkbox.attrs.value?
119 & ( common.attrs.aria.implicit.checkbox
120 | common.attrs.aria.role.checkbox
121 | common.attrs.aria.role.menuitemcheckbox
122 | common.attrs.aria.role.switch
123 )?
124 )
125 input.checkbox.attrs.type =
126 attribute type {
127 w:string "checkbox"
128 }
129 input.checkbox.attrs.value =
130 attribute value {
131 string #REVISIT require non-empty value?
132 }
133
134 input.elem |= input.checkbox.elem
135
136 ## Radiobutton: <input type='radio'>
137
138 input.radio.elem =
139 element input { input.radio.attrs }
140 input.radio.attrs =
141 ( common.attrs
142 & common-form.attrs
143 & input.radio.attrs.type
144 & input.attrs.checked?
145 & input.radio.attrs.value?
146 & ( common.attrs.aria.implicit.radio
147 | common.attrs.aria.role.radio
148 | common.attrs.aria.role.menuitemradio
149 )?
150 )
151 input.radio.attrs.type =
152 attribute type {
153 w:string "radio"
154 }
155 input.radio.attrs.value =
156 attribute value {
157 string #REVISIT require non-empty value?
158 }
159
160 input.elem |= input.radio.elem
161
162 ## Scripting Hook Button: <input type='button'>
163
164 input.button.elem =
165 element input { input.button.attrs }
166 input.button.attrs =
167 ( common.attrs
168 & common-form.attrs
169 & input.button.attrs.type
170 & input.button.attrs.value?
171 & ( common.attrs.aria.implicit.button
172 | common.attrs.aria.role.button
173 | common.attrs.aria.role.link
174 | common.attrs.aria.role.menuitem
175 | common.attrs.aria.role.menuitemcheckbox
176 | common.attrs.aria.role.menuitemradio
177 | common.attrs.aria.role.radio
178 | common.attrs.aria.role.switch
179 )?
180 )
181 input.button.attrs.type =
182 attribute type {
183 w:string "button"
184 }
185 input.button.attrs.value =
186 attribute value {
187 string #REVISIT require non-empty value?
188 }
189
190 input.elem |= input.button.elem
191 #REVISIT should this be enabled by a scripting module only?
192
193 ## Submit Button: <input type='submit'>
194
195 input.submit.elem =
196 element input { input.submit.attrs }
197 input.submit.attrs =
198 ( common.attrs
199 & common-form.attrs
200 & input.submit.attrs.type
201 & input.submit.attrs.value?
202 & ( common.attrs.aria.implicit.button
203 | common.attrs.aria.role.button
204 )?
205 )
206 input.submit.attrs.type =
207 attribute type {
208 w:string "submit"
209 }
210 input.submit.attrs.value =
211 attribute value {
212 string #REVISIT require non-empty value?
213 }
214
215 input.elem |= input.submit.elem
216
217 ## Reset Button: <input type='reset'>
218
219 input.reset.elem =
220 element input { input.reset.attrs }
221 input.reset.attrs =
222 ( common.attrs
223 & common-form.attrs
224 & input.reset.attrs.type
225 & input.reset.attrs.value?
226 & ( common.attrs.aria.implicit.button
227 | common.attrs.aria.role.button
228 )?
229 )
230 input.reset.attrs.type =
231 attribute type {
232 w:string "reset"
233 }
234 input.reset.attrs.value =
235 attribute value {
236 string #REVISIT require non-empty value?
237 }
238
239 input.elem |= input.reset.elem
240 # REVISIT does reset make sense outside a form?
241
242 ## File Upload: <input type='file'>
243
244 input.file.elem =
245 element input { input.file.attrs }
246 input.file.attrs =
247 ( common.attrs
248 & common-form.attrs
249 & input.file.attrs.type
250 & input.file.attrs.accept?
251 & common.attrs.aria?
252 )
253 input.file.attrs.type =
254 attribute type {
255 w:string "file"
256 }
257 input.file.attrs.accept =
258 attribute accept {
259 form.data.mimetypelist
260 }
261
262 input.elem |= input.file.elem
263
264 ## Hidden String: <input type='hidden'>
265
266 input.hidden.elem =
267 element input { input.hidden.attrs }
268 input.hidden.attrs =
269 ( common.attrs
270 & common-form.attrs
271 & input.hidden.attrs.type
272 & input.hidden.attrs.value?
273 & common.attrs.aria?
274 )
275 input.hidden.attrs.type =
276 attribute type {
277 w:string "hidden"
278 }
279 input.hidden.attrs.value =
280 attribute value {
281 string
282 }
283
284 input.elem |= input.hidden.elem
285
286 ## Image Submit Button: <input type='image'>
287
288 input.image.elem =
289 element input { input.image.attrs }
290 input.image.attrs =
291 ( common.attrs
292 & common-form.attrs
293 & input.image.attrs.type
294 & input.image.attrs.alt
295 & input.image.attrs.src?
296 & ( common.attrs.aria.implicit.button
297 | common.attrs.aria.role.button
298 | common.attrs.aria.role.link
299 | common.attrs.aria.role.menuitem
300 | common.attrs.aria.role.menuitemcheckbox
301 | common.attrs.aria.role.menuitemradio
302 | common.attrs.aria.role.radio
303 | common.attrs.aria.role.switch
304 )?
305 )
306 input.image.attrs.type =
307 attribute type {
308 w:string "image"
309 }
310 input.image.attrs.alt =
311 attribute alt {
312 form.data.nonemptystring
313 }
314 input.image.attrs.src =
315 attribute src {
316 common.data.uri.non-empty
317 }
318
319 input.elem |= input.image.elem
320
321 common.elem.phrasing |= input.elem
322
323 ## Text Area: <textarea>
324
325 textarea.elem =
326 element textarea { textarea.inner & textarea.attrs }
327 textarea.attrs =
328 ( common.attrs
329 & common-form.attrs
330 & shared-form.attrs.readonly?
331 & textarea.attrs.rows-and-cols-wf1
332 & ( common.attrs.aria.implicit.textbox
333 | common.attrs.aria.role.textbox
334 )?
335 #FIXME onfocus, onblur, onselect,onchange
336 )
337 # This is ugly.
338 textarea.attrs.rows-and-cols-wf1 =
339 textarea.attrs.rows-and-cols-wf1.inner
340 textarea.attrs.rows-and-cols-wf1.inner =
341 ( textarea.attrs.cols
342 & textarea.attrs.rows
343 )
344 textarea.attrs.cols =
345 attribute cols {
346 common.data.integer.positive
347 }
348 textarea.attrs.rows =
349 attribute rows {
350 common.data.integer.positive
351 }
352 textarea.inner =
353 ( text )
354
355 common.elem.phrasing |= textarea.elem
356
357 # Due to limitations with interleave, handling single/multiple selection
358 # enforcement in RELAX NG seems to be possible but really awkward.
359 # Tried it. Leaving it to Schematron.
360
361 ## Select menu option: <option selected>
362
363 option.elem =
364 element option { option.inner & option.attrs }
365 option.attrs =
366 ( common.attrs
367 & common-form.attrs.disabled?
368 & option.attrs.selected?
369 & option.attrs.label?
370 & option.attrs.value?
371 & ( common.attrs.aria.implicit.option
372 | common.attrs.aria.role.option
373 )?
374 )
375 option.attrs.selected =
376 attribute selected {
377 w:string "selected" | w:string ""
378 }
379 option.attrs.label =
380 attribute label {
381 form.data.nonemptystring
382 }
383 option.attrs.value =
384 attribute value {
385 string
386 }
387 option.inner =
388 ( text )
389
390 ## Option Group: <optgroup>
391
392 optgroup.elem =
393 element optgroup { optgroup.inner & optgroup.attrs }
394 optgroup.attrs =
395 ( common.attrs
396 & optgroup.attrs.label
397 & common-form.attrs.disabled?
398 & ( common.attrs.aria.role.presentation
399 | common.attrs.aria.role.menuitem
400 )?
401 )
402 optgroup.attrs.label =
403 attribute label {
404 string
405 }
406 optgroup.inner =
407 ( option.elem*
408 & common.elem.script-supporting*
409 )
410
411 ## Selection Menu: <select>
412
413 select.elem =
414 element select { select.inner & select.attrs }
415 select.attrs =
416 ( common.attrs
417 & common-form.attrs
418 & select.attrs.size?
419 & select.attrs.multiple?
420 # FIXME onfocus, onblur, onchange
421 & ( common.attrs.aria.implicit.listbox
422 | common.attrs.aria.role.listbox # aria-multiselectable depends on "multiple" value; check in assertions
423 )?
424 )
425 select.attrs.size =
426 attribute size {
427 common.data.integer.positive
428 }
429 select.attrs.multiple =
430 attribute multiple {
431 w:string "multiple" | w:string ""
432 }
433 select.inner =
434 ( optgroup.elem*
435 & option.elem*
436 & common.elem.script-supporting*
437 )
438
439 common.elem.phrasing |= select.elem
440
441 ## Shared Definitions for Complex Button
442
443 button.attrs.value =
444 attribute value {
445 string
446 }
447 button.inner =
448 ( common.inner.phrasing )
449
450 ## Complex Submit Button: <button type='submit'>
451
452 button.submit.elem =
453 element button { button.inner & button.submit.attrs }
454 button.submit.attrs =
455 ( common.attrs
456 & common-form.attrs
457 & button.submit.attrs.type?
458 & button.attrs.value?
459 & ( common.attrs.aria.implicit.button
460 | common.attrs.aria.role.button
461 | common.attrs.aria.role.checkbox
462 | common.attrs.aria.role.link
463 | common.attrs.aria.role.menuitem
464 | common.attrs.aria.role.menuitemcheckbox
465 | common.attrs.aria.role.menuitemradio
466 | common.attrs.aria.role.radio
467 )?
468 )
469 button.submit.attrs.type =
470 attribute type {
471 w:string "submit"
472 }
473
474 button.elem = button.submit.elem
475
476 ## Complex Reset Button: <button type='reset'>
477
478 button.reset.elem =
479 element button { button.inner & button.reset.attrs }
480 button.reset.attrs =
481 ( common.attrs
482 & common-form.attrs
483 & button.reset.attrs.type
484 & button.attrs.value? #REVISIT I guess this still affects the DOM
485 & ( common.attrs.aria.implicit.button
486 | common.attrs.aria.role.button
487 | common.attrs.aria.role.checkbox
488 | common.attrs.aria.role.link
489 | common.attrs.aria.role.menuitem
490 | common.attrs.aria.role.menuitemcheckbox
491 | common.attrs.aria.role.menuitemradio
492 | common.attrs.aria.role.radio
493 | common.attrs.aria.role.switch
494 )?
495 )
496 button.reset.attrs.type =
497 attribute type {
498 w:string "reset"
499 }
500
501 button.elem |= button.reset.elem
502
503 ## Complex Push Button: <button type='button'>
504
505 button.button.elem =
506 element button { button.inner & button.button.attrs }
507 button.button.attrs =
508 ( common.attrs
509 & common-form.attrs
510 & button.button.attrs.type
511 & button.attrs.value? #REVISIT I guess this still affects the DOM
512 & ( common.attrs.aria.implicit.button
513 | common.attrs.aria.role.button
514 | common.attrs.aria.role.checkbox
515 | common.attrs.aria.role.link
516 | common.attrs.aria.role.menuitem
517 | common.attrs.aria.role.menuitemcheckbox
518 | common.attrs.aria.role.menuitemradio
519 | common.attrs.aria.role.radio
520 | common.attrs.aria.role.switch
521 )?
522 )
523 button.button.attrs.type =
524 attribute type {
525 w:string "button"
526 }
527
528 button.elem |= button.button.elem
529
530 common.elem.phrasing |= button.elem
531
532 ## Form: <form>
533
534 form.elem =
535 element form { form.inner & form.attrs }
536 form.attrs =
537 ( common.attrs
538 & form.attrs.action? #REVISIT Should this be required anyway?
539 & form.attrs.method?
540 & form.attrs.enctype?
541 & common-form.attrs.name?
542 & form.attrs.accept-charset?
543 & ( common.attrs.aria.implicit.form
544 | common.attrs.aria.landmark.form
545 | common.attrs.aria.role.search
546 | common.attrs.aria.role.presentation
547 )?
548 )
549 form.attrs.action =
550 attribute action {
551 common.data.uri.non-empty
552 }
553 form.attrs.method =
554 attribute method {
555 form.attrs.method.data
556 }
557 form.attrs.method.data =
558 ( w:string "get" | w:string "post" )
559 form.attrs.enctype =
560 attribute enctype {
561 form.attrs.enctype.data
562 }
563 form.attrs.enctype.data =
564 ( w:string "application/x-www-form-urlencoded"
565 | w:string "multipart/form-data"
566 )
567 form.attrs.accept-charset =
568 attribute accept-charset {
569 form.data.charsetlist
570 }
571 form.inner =
572 ( common.inner.flow )
573
574 common.elem.flow |= form.elem
575
576 ## Fieldset: <fieldset>
577
578 fieldset.elem =
579 element fieldset { fieldset.inner & fieldset.attrs }
580 fieldset.attrs =
581 ( common.attrs
582 & ( common.attrs.aria.implicit.group
583 | common.attrs.aria
584 )?
585 )
586 fieldset.inner =
587 ( legend.elem? #REVISIT should this be required?
588 , common.inner.flow
589 )
590
591 common.elem.flow |= fieldset.elem
592
593 ## Label: <label>
594
595 label.elem =
596 element label { label.inner & label.attrs }
597 label.attrs =
598 ( common.attrs
599 & label.attrs.for?
600 & ( common.attrs.aria.role.presentation
601 | common.attrs.aria.role.menuitem
602 )?
603 )
604 label.attrs.for =
605 attribute for {
606 common.data.idref
607 }
608 label.inner =
609 ( common.inner.phrasing ) #REVISIT making obvious guess
610
611 common.elem.phrasing |= label.elem
612