1 //
2 // Copyright (c) 2006, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 28 May 06 Andy Frank Creation
7 //
8
9 **
10 ** WebOutStream provides methods for generating XML and XHTML content.
11 **
12 class WebOutStream : OutStream
13 {
14
15 //////////////////////////////////////////////////////////////////////////
16 // Factory
17 //////////////////////////////////////////////////////////////////////////
18
19 **
20 ** Construct a WebOutStream that wraps the given OutStream.
21 **
22 new make(OutStream out)
23 : super(out)
24 {
25 }
26
27 //////////////////////////////////////////////////////////////////////////
28 // General Methods
29 //////////////////////////////////////////////////////////////////////////
30
31 **
32 ** Convenience for writeChars(obj.toStr).
33 **
34 WebOutStream w(Obj obj)
35 {
36 writeChars(obj.toStr)
37 return this
38 }
39
40 **
41 ** Convenience for writeChars(Str.spaces(numSpaces)).
42 **
43 WebOutStream tab(Int numSpaces := 2)
44 {
45 writeChars(Str.spaces(numSpaces))
46 return this
47 }
48
49 **
50 ** Convenience for writeChar('\n').
51 **
52 WebOutStream nl()
53 {
54 writeChar('\n')
55 return this
56 }
57
58 //////////////////////////////////////////////////////////////////////////
59 // Xml Methods
60 //////////////////////////////////////////////////////////////////////////
61
62 **
63 ** Write out a prolog statement using the streams
64 ** current charset encoding.
65 **
66 WebOutStream prolog()
67 {
68 writeChars("<?xml version='1.0' encoding='$charset'?>\n")
69 return this
70 }
71
72 **
73 ** Write a start tag. Use attrs to fully specify the attributes
74 ** manually. Use empty to optionally close this element without
75 ** using an end tag.
76 **
77 WebOutStream tag(Str elemName, Str attrs := null, Bool empty := false)
78 {
79 writeChar('<')
80 writeChars(elemName)
81 if (attrs != null) writeChar(' ').writeChars(attrs)
82 if (empty) writeChars(" /")
83 writeChar('>')
84 return this
85 }
86
87 **
88 ** Write an end tag.
89 **
90 WebOutStream tagEnd(Str elemName)
91 {
92 writeChars("</").writeChars(elemName).writeChar('>')
93 return this
94 }
95
96 //////////////////////////////////////////////////////////////////////////
97 // DOCTYPE
98 //////////////////////////////////////////////////////////////////////////
99
100 **
101 ** Write the XHTML Strict DOCTYPE.
102 **
103 WebOutStream docType()
104 {
105 writeChars("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n")
106 writeChars(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n")
107 return this
108 }
109
110 //////////////////////////////////////////////////////////////////////////
111 // html
112 //////////////////////////////////////////////////////////////////////////
113
114 **
115 ** Start a <html> tag.
116 **
117 WebOutStream html()
118 {
119 return tag("html", "xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'").nl
120 }
121
122 **
123 ** End a <html> tag.
124 **
125 WebOutStream htmlEnd()
126 {
127 return tagEnd("html").nl
128 }
129
130 //////////////////////////////////////////////////////////////////////////
131 // head
132 //////////////////////////////////////////////////////////////////////////
133
134 **
135 ** Start a <head> tag.
136 **
137 WebOutStream head()
138 {
139 return tag("head").nl
140 }
141
142 **
143 ** End a <head> tag.
144 **
145 WebOutStream headEnd()
146 {
147 return tagEnd("head").nl
148 }
149
150 **
151 ** Write a complete <title> tag.
152 **
153 WebOutStream title(Str title)
154 {
155 return tag("title").w(title).tagEnd("title").nl
156 }
157
158 **
159 ** Write a complete <link> tag for an external CSS stylesheet.
160 ** If this URI has already been included in this WebOutStream
161 ** instance, then this method does nothing.
162 **
163 WebOutStream css(Uri href)
164 {
165 if (cssUris == null) cssUris = Uri[,]
166 if (!cssUris.contains(href))
167 {
168 attrs := "rel='stylesheet' type='text/css' href='$href'"
169 tag("link", attrs, true).nl
170 cssUris.add(href)
171 }
172 return this
173 }
174
175 **
176 ** Write a complete <script> tag for an external JavaScript file.
177 ** If this URI has already been included in this WebOutStream
178 ** instance, then this method does nothing.
179 **
180 WebOutStream js(Uri href)
181 {
182 if (jsUris == null) jsUris = Uri[,]
183 if (!jsUris.contains(href))
184 {
185 tag("script", "type='text/javascript' src='$href'")
186 tagEnd("script").nl
187 jsUris.add(href)
188 }
189 return this
190 }
191
192 //////////////////////////////////////////////////////////////////////////
193 // body
194 //////////////////////////////////////////////////////////////////////////
195
196 **
197 ** Start a <body> tag.
198 **
199 WebOutStream body(Str attrs := null)
200 {
201 return tag("body", attrs).nl
202 }
203
204 **
205 ** End a <body> tag.
206 **
207 WebOutStream bodyEnd()
208 {
209 return tagEnd("body").nl
210 }
211
212 //////////////////////////////////////////////////////////////////////////
213 // h1, h2, h3, h4, h5, h6
214 //////////////////////////////////////////////////////////////////////////
215
216 **
217 ** Write a complete <h1> tag.
218 **
219 WebOutStream h1(Str content, Str attrs := null)
220 {
221 return tag("h1", attrs).w(content).tagEnd("h1").nl
222 }
223
224 **
225 ** Write a complete <h2> tag.
226 **
227 WebOutStream h2(Str content, Str attrs := null)
228 {
229 return tag("h2", attrs).w(content).tagEnd("h2").nl
230 }
231
232 **
233 ** Write a complete <h3> tag.
234 **
235 WebOutStream h3(Str content, Str attrs := null)
236 {
237 return tag("h3", attrs).w(content).tagEnd("h3").nl
238 }
239
240 **
241 ** Write a complete <h4> tag.
242 **
243 WebOutStream h4(Str content, Str attrs := null)
244 {
245 return tag("h4", attrs).w(content).tagEnd("h4").nl
246 }
247
248 **
249 ** Write a complete <h5> tag.
250 **
251 WebOutStream h5(Str content, Str attrs := null)
252 {
253 return tag("h5", attrs).w(content).tagEnd("h5").nl
254 }
255
256 **
257 ** Write a complete <h6> tag.
258 **
259 WebOutStream h6(Str content, Str attrs := null)
260 {
261 return tag("h6", attrs).w(content).tagEnd("h6").nl
262 }
263
264 //////////////////////////////////////////////////////////////////////////
265 // div
266 //////////////////////////////////////////////////////////////////////////
267
268 **
269 ** Start a <div> tag.
270 **
271 WebOutStream div(Str attrs := null)
272 {
273 return tag("div", attrs).nl
274 }
275
276 **
277 ** End a <div> tag.
278 **
279 WebOutStream divEnd()
280 {
281 return tagEnd("div").nl
282 }
283
284 //////////////////////////////////////////////////////////////////////////
285 // span
286 //////////////////////////////////////////////////////////////////////////
287
288 **
289 ** Start a <span> tag.
290 **
291 WebOutStream span(Str attrs := null)
292 {
293 return tag("span", attrs)
294 }
295
296 **
297 ** End a <span> tag.
298 **
299 WebOutStream spanEnd()
300 {
301 return tagEnd("span")
302 }
303
304 //////////////////////////////////////////////////////////////////////////
305 // p
306 //////////////////////////////////////////////////////////////////////////
307
308 **
309 ** Start a <p> tag.
310 **
311 WebOutStream p(Str attrs := null)
312 {
313 return tag("p", attrs).nl
314 }
315
316 **
317 ** End a <p> tag.
318 **
319 WebOutStream pEnd()
320 {
321 return tagEnd("p").nl
322 }
323
324 //////////////////////////////////////////////////////////////////////////
325 // pre
326 //////////////////////////////////////////////////////////////////////////
327
328 **
329 ** Start a <pre> tag.
330 **
331 WebOutStream pre(Str attrs := null)
332 {
333 return tag("pre", attrs)
334 }
335
336 **
337 ** End a <pre> tag.
338 **
339 WebOutStream preEnd()
340 {
341 return tagEnd("pre").nl
342 }
343
344 //////////////////////////////////////////////////////////////////////////
345 // code
346 //////////////////////////////////////////////////////////////////////////
347
348 **
349 ** Start a <code> tag.
350 **
351 WebOutStream code(Str attrs := null)
352 {
353 return tag("code", attrs)
354 }
355
356 **
357 ** End a <code> tag.
358 **
359 WebOutStream codeEnd()
360 {
361 return tagEnd("code")
362 }
363
364 //////////////////////////////////////////////////////////////////////////
365 // hr
366 //////////////////////////////////////////////////////////////////////////
367
368 **
369 ** Write out a complete <hr/> tag.
370 **
371 WebOutStream hr()
372 {
373 return tag("hr", null, true).nl
374 }
375
376 //////////////////////////////////////////////////////////////////////////
377 // br
378 //////////////////////////////////////////////////////////////////////////
379
380 **
381 ** Write out a complete <br/> tag.
382 **
383 WebOutStream br()
384 {
385 return tag("br", null, true)
386 }
387
388 //////////////////////////////////////////////////////////////////////////
389 // a
390 //////////////////////////////////////////////////////////////////////////
391
392 **
393 ** Start a <a> tag.
394 **
395 WebOutStream a(Uri href, Str attrs := null)
396 {
397 return tag("a href='$href'", attrs)
398 }
399
400 **
401 ** End a <a> tag.
402 **
403 WebOutStream aEnd()
404 {
405 return tagEnd("a")
406 }
407
408 //////////////////////////////////////////////////////////////////////////
409 // img
410 //////////////////////////////////////////////////////////////////////////
411
412 **
413 ** Write a complete <img> tag.
414 **
415 WebOutStream img(Uri src, Str attrs := null)
416 {
417 return tag("img src='$src'", attrs, true)
418 }
419
420 //////////////////////////////////////////////////////////////////////////
421 // table
422 //////////////////////////////////////////////////////////////////////////
423
424 **
425 ** Start a <table> tag.
426 **
427 WebOutStream table(Str attrs := null)
428 {
429 return tag("table", attrs).nl
430 }
431
432 **
433 ** End a <table> tag.
434 **
435 WebOutStream tableEnd()
436 {
437 return tagEnd("table").nl
438 }
439
440 //////////////////////////////////////////////////////////////////////////
441 // tr
442 //////////////////////////////////////////////////////////////////////////
443
444 **
445 ** Start a <tr> tag.
446 **
447 WebOutStream tr(Str attrs := null)
448 {
449 return tag("tr", attrs).nl
450 }
451
452 **
453 ** End a <tr> tag.
454 **
455 WebOutStream trEnd()
456 {
457 return tagEnd("tr").nl
458 }
459
460 //////////////////////////////////////////////////////////////////////////
461 // th
462 //////////////////////////////////////////////////////////////////////////
463
464 **
465 ** Start a <th> tag.
466 **
467 WebOutStream th(Str attrs := null)
468 {
469 return tag("th", attrs)
470 }
471
472 **
473 ** End a <th> tag.
474 **
475 WebOutStream thEnd()
476 {
477 return tagEnd("th").nl
478 }
479
480 //////////////////////////////////////////////////////////////////////////
481 // td
482 //////////////////////////////////////////////////////////////////////////
483
484 **
485 ** Start a <td> tag.
486 **
487 WebOutStream td(Str attrs := null)
488 {
489 return tag("td", attrs)
490 }
491
492 **
493 ** End a <td> tag.
494 **
495 WebOutStream tdEnd()
496 {
497 return tagEnd("td").nl
498 }
499
500 //////////////////////////////////////////////////////////////////////////
501 // ul/ol/li
502 //////////////////////////////////////////////////////////////////////////
503
504 **
505 ** Start a <ul> tag.
506 **
507 WebOutStream ul(Str attrs := null)
508 {
509 return tag("ul", attrs).nl
510 }
511
512 **
513 ** End a <ul> tag.
514 **
515 WebOutStream ulEnd()
516 {
517 return tagEnd("ul").nl
518 }
519
520 **
521 ** Start a <ol> tag.
522 **
523 WebOutStream ol(Str attrs := null)
524 {
525 return tag("ol", attrs).nl
526 }
527
528 **
529 ** End a <ol> tag.
530 **
531 WebOutStream olEnd()
532 {
533 return tagEnd("ol").nl
534 }
535
536 **
537 ** Start a <li> tag.
538 **
539 WebOutStream li(Str attrs := null)
540 {
541 return tag("li", attrs).nl
542 }
543
544 **
545 ** End a <li> tag.
546 **
547 WebOutStream liEnd()
548 {
549 return tagEnd("li").nl
550 }
551
552 //////////////////////////////////////////////////////////////////////////
553 // dl/dd/dt
554 //////////////////////////////////////////////////////////////////////////
555
556 **
557 ** Start a <dl> tag.
558 **
559 WebOutStream dl(Str attrs := null)
560 {
561 return tag("dl", attrs).nl
562 }
563
564 **
565 ** End a <dl> tag.
566 **
567 WebOutStream dlEnd()
568 {
569 return tagEnd("dl").nl
570 }
571
572 **
573 ** Start a <dt> tag.
574 **
575 WebOutStream dt(Str attrs := null)
576 {
577 return tag("dt", attrs).nl
578 }
579
580 **
581 ** End a <dt> tag.
582 **
583 WebOutStream dtEnd()
584 {
585 return tagEnd("dt").nl
586 }
587
588 **
589 ** Start a <dd> tag.
590 **
591 WebOutStream dd(Str attrs := null)
592 {
593 return tag("dd", attrs).nl
594 }
595
596 **
597 ** End a <dd> tag.
598 **
599 WebOutStream ddEnd()
600 {
601 return tagEnd("dd").nl
602 }
603
604 //////////////////////////////////////////////////////////////////////////
605 // form
606 //////////////////////////////////////////////////////////////////////////
607
608 **
609 ** Start a <form> tag.
610 **
611 WebOutStream form(Str attrs := null)
612 {
613 return tag("form", attrs).nl
614 }
615
616 **
617 ** End a <form> tag.
618 **
619 WebOutStream formEnd()
620 {
621 return tagEnd("form").nl
622 }
623
624 //////////////////////////////////////////////////////////////////////////
625 // input
626 //////////////////////////////////////////////////////////////////////////
627
628 **
629 ** Write a complete <input> tag.
630 **
631 WebOutStream input(Str attrs := null)
632 {
633 return tag("input", attrs, true)
634 }
635
636 **
637 ** Convenience for input("type='text'" + attrs).
638 **
639 WebOutStream textField(Str attrs := null)
640 {
641 return tag("input type='text'", attrs, true)
642 }
643
644 **
645 ** Convenience for input("type='button'" + attrs).
646 **
647 WebOutStream button(Str attrs := null)
648 {
649 return tag("input type='button'", attrs, true)
650 }
651
652 **
653 ** Convenience for input("type='submit'" + attrs).
654 **
655 WebOutStream submit(Str attrs := null)
656 {
657 return tag("input type='submit'", attrs, true)
658 }
659
660 //////////////////////////////////////////////////////////////////////////
661 // select
662 //////////////////////////////////////////////////////////////////////////
663
664 **
665 ** Start a <select> tag.
666 **
667 WebOutStream select(Str attrs := null)
668 {
669 return tag("select", attrs).nl
670 }
671
672 **
673 ** End a <select> tag.
674 **
675 WebOutStream selectEnd()
676 {
677 return tagEnd("select").nl
678 }
679
680 **
681 ** Start a <option> tag.
682 **
683 WebOutStream option(Str attrs := null)
684 {
685 return tag("option", attrs)
686 }
687
688 **
689 ** End a <option> tag.
690 **
691 WebOutStream optionEnd()
692 {
693 return tagEnd("option").nl
694 }
695
696 //////////////////////////////////////////////////////////////////////////
697 // Fields
698 //////////////////////////////////////////////////////////////////////////
699
700 private Uri[] cssUris // what CSS uris have been added
701 private Uri[] jsUris // what JavaScript uris have been added
702
703 }