]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/HtmlElement5.php
Reformat code
[SourceForge/phpwiki.git] / lib / HtmlElement5.php
1 <?php
2 /**
3  * Code for writing the HTML subset of XML.
4  * @author: Jeff Dairiki
5  *
6  * This code is now php5 compatible. --2004-04-19 23:51:43 rurban
7  * Specialized for php-5.3: added public static 2010-06-07 09:51:37 rurban
8  *
9  * Todo: Add support for a JavaScript backend, a php2js compiler.
10  * HTML::div(array('onclick' => 'HTML::div(...)'))
11  */
12 if (!class_exists("XmlElement"))
13     require_once(dirname(__FILE__) . "/XmlElement.php");
14 if (class_exists("HtmlElement"))
15     return;
16
17 /**
18  * An XML element.
19  */
20 //apd_set_session_trace(35);
21
22 class HtmlElement extends XmlElement
23 {
24     function __construct($tagname /* , $attr_or_content , ...*/)
25     {
26         $this->_init(func_get_args());
27         $this->_properties = HTML::getTagProperties($tagname);
28     }
29
30     function _init($args)
31     {
32         if (!is_array($args))
33             $args = func_get_args();
34
35         assert(count($args) >= 1);
36         assert(is_string($args[0]));
37         $this->_tag = array_shift($args);
38
39         if ($args && is_array($args[0]))
40             $this->_attr = array_shift($args);
41         else {
42             $this->_attr = array();
43             if ($args && $args[0] === false)
44                 array_shift($args);
45         }
46         $this->setContent($args);
47         $this->_properties = HTML::getTagProperties($this->_tag);
48     }
49
50     /**
51      * @access protected
52      * This is used by the static factory methods is class HTML.
53      */
54     function _init2($args)
55     {
56         if ($args) {
57             if (is_array($args[0]))
58                 $this->_attr = array_shift($args);
59             elseif ($args[0] === false)
60                 array_shift($args);
61         }
62
63         if (count($args) == 1 && is_array($args[0]))
64             $args = $args[0];
65         $this->_content = $args;
66         return $this;
67     }
68
69     /** Add a "tooltip" to an element.
70      *
71      * @param $tooltip_text string The tooltip text.
72      */
73     function addTooltip($tooltip_text, $accesskey = null)
74     {
75         $this->setAttr('title', $tooltip_text);
76         if ($accesskey) $this->setAccesskey($accesskey);
77
78         // FIXME: this should be initialized from title by an onLoad() function.
79         //        (though, that may not be possible.)
80         $qtooltip = str_replace("'", "\\'", $tooltip_text);
81         $this->setAttr('onmouseover',
82             sprintf('window.status="%s"; return true;',
83                 addslashes($tooltip_text)));
84         $this->setAttr('onmouseout', "window.status='';return true;");
85     }
86
87     function setAccesskey($key)
88     {
89         global $WikiTheme;
90         if (strlen($key) != 1) return;
91         $this->setAttr("accesskey", $key);
92
93         if (!empty($this->_attr['title'])) {
94             if (preg_match("/\[(alt-)?(.)\]$/", $this->_attr['title'], $m)) {
95                 $this->_attr['title'] = preg_replace
96                 ("/\[(alt-)?(.)\]$/",
97                     "[" . $WikiTheme->tooltipAccessKeyPrefix() . "-\\2]",
98                     $this->_attr['title']);
99             } else {
100                 $this->_attr['title'] .=
101                     " [" . $WikiTheme->tooltipAccessKeyPrefix() . "-$key]";
102             }
103         } else {
104             $this->_attr['title'] =
105                 "[" . $WikiTheme->tooltipAccessKeyPrefix() . "-$key]";
106         }
107     }
108
109     function emptyTag()
110     {
111         if (($this->_properties & HTMLTAG_EMPTY) == 0)
112             return $this->startTag() . "</$this->_tag>";
113
114         return substr($this->startTag(), 0, -1) . " />";
115     }
116
117     function hasInlineContent()
118     {
119         return ($this->_properties & HTMLTAG_ACCEPTS_INLINE) != 0;
120     }
121
122     function isInlineElement()
123     {
124         return ($this->_properties & HTMLTAG_INLINE) != 0;
125     }
126 }
127
128 ;
129
130 function HTML( /* $content, ... */)
131 {
132     return new XmlContent(func_get_args());
133 }
134
135 class HTML extends HtmlElement
136 {
137     public static function raw($html_text)
138     {
139         return new RawXml($html_text);
140     }
141
142     public static function getTagProperties($tag)
143     {
144         $props = &$GLOBALS['HTML_TagProperties'];
145         return isset($props[$tag]) ? $props[$tag] : 0;
146     }
147
148     public static function _setTagProperty($prop_flag, $tags)
149     {
150         $props = &$GLOBALS['HTML_TagProperties'];
151         if (is_string($tags))
152             $tags = preg_split('/\s+/', $tags);
153         foreach ($tags as $tag) {
154             $tag = trim($tag);
155             if ($tag)
156                 if (isset($props[$tag]))
157                     $props[$tag] |= $prop_flag;
158                 else
159                     $props[$tag] = $prop_flag;
160         }
161     }
162
163     // See admin/mkfuncs shell script to generate the following static methods
164
165     public static function link( /*...*/)
166     {
167         $el = new HtmlElement('link');
168         return $el->_init2(func_get_args());
169     }
170
171     public static function meta( /*...*/)
172     {
173         $el = new HtmlElement('meta');
174         return $el->_init2(func_get_args());
175     }
176
177     public static function style( /*...*/)
178     {
179         $el = new HtmlElement('style');
180         return $el->_init2(func_get_args());
181     }
182
183     public static function script( /*...*/)
184     {
185         $el = new HtmlElement('script');
186         return $el->_init2(func_get_args());
187     }
188
189     public static function noscript( /*...*/)
190     {
191         $el = new HtmlElement('noscript');
192         return $el->_init2(func_get_args());
193     }
194
195     /****************************************/
196     public static function a( /*...*/)
197     {
198         $el = new HtmlElement('a');
199         return $el->_init2(func_get_args());
200     }
201
202     public static function img( /*...*/)
203     {
204         $el = new HtmlElement('img');
205         return $el->_init2(func_get_args());
206     }
207
208     public static function br( /*...*/)
209     {
210         $el = new HtmlElement('br');
211         return $el->_init2(func_get_args());
212     }
213
214     public static function span( /*...*/)
215     {
216         $el = new HtmlElement('span');
217         return $el->_init2(func_get_args());
218     }
219
220     /****************************************/
221     public static function h1( /*...*/)
222     {
223         $el = new HtmlElement('h1');
224         return $el->_init2(func_get_args());
225     }
226
227     public static function h2( /*...*/)
228     {
229         $el = new HtmlElement('h2');
230         return $el->_init2(func_get_args());
231     }
232
233     public static function h3( /*...*/)
234     {
235         $el = new HtmlElement('h3');
236         return $el->_init2(func_get_args());
237     }
238
239     public static function h4( /*...*/)
240     {
241         $el = new HtmlElement('h4');
242         return $el->_init2(func_get_args());
243     }
244
245     public static function h5( /*...*/)
246     {
247         $el = new HtmlElement('h5');
248         return $el->_init2(func_get_args());
249     }
250
251     public static function h6( /*...*/)
252     {
253         $el = new HtmlElement('h6');
254         return $el->_init2(func_get_args());
255     }
256
257     /****************************************/
258     public static function hr( /*...*/)
259     {
260         $el = new HtmlElement('hr');
261         return $el->_init2(func_get_args());
262     }
263
264     public static function div( /*...*/)
265     {
266         $el = new HtmlElement('div');
267         return $el->_init2(func_get_args());
268     }
269
270     public static function p( /*...*/)
271     {
272         $el = new HtmlElement('p');
273         return $el->_init2(func_get_args());
274     }
275
276     public static function pre( /*...*/)
277     {
278         $el = new HtmlElement('pre');
279         return $el->_init2(func_get_args());
280     }
281
282     public static function blockquote( /*...*/)
283     {
284         $el = new HtmlElement('blockquote');
285         return $el->_init2(func_get_args());
286     }
287
288     /****************************************/
289     public static function em( /*...*/)
290     {
291         $el = new HtmlElement('em');
292         return $el->_init2(func_get_args());
293     }
294
295     public static function strong( /*...*/)
296     {
297         $el = new HtmlElement('strong');
298         return $el->_init2(func_get_args());
299     }
300
301     public static function small( /*...*/)
302     {
303         $el = new HtmlElement('small');
304         return $el->_init2(func_get_args());
305     }
306
307     /****************************************/
308     public static function tt( /*...*/)
309     {
310         $el = new HtmlElement('tt');
311         return $el->_init2(func_get_args());
312     }
313
314     public static function u( /*...*/)
315     {
316         $el = new HtmlElement('u');
317         return $el->_init2(func_get_args());
318     }
319
320     public static function sup( /*...*/)
321     {
322         $el = new HtmlElement('sup');
323         return $el->_init2(func_get_args());
324     }
325
326     public static function sub( /*...*/)
327     {
328         $el = new HtmlElement('sub');
329         return $el->_init2(func_get_args());
330     }
331
332     /****************************************/
333     public static function ul( /*...*/)
334     {
335         $el = new HtmlElement('ul');
336         return $el->_init2(func_get_args());
337     }
338
339     public static function ol( /*...*/)
340     {
341         $el = new HtmlElement('ol');
342         return $el->_init2(func_get_args());
343     }
344
345     public static function dl( /*...*/)
346     {
347         $el = new HtmlElement('dl');
348         return $el->_init2(func_get_args());
349     }
350
351     public static function li( /*...*/)
352     {
353         $el = new HtmlElement('li');
354         return $el->_init2(func_get_args());
355     }
356
357     public static function dt( /*...*/)
358     {
359         $el = new HtmlElement('dt');
360         return $el->_init2(func_get_args());
361     }
362
363     public static function dd( /*...*/)
364     {
365         $el = new HtmlElement('dd');
366         return $el->_init2(func_get_args());
367     }
368
369     /****************************************/
370     public static function table( /*...*/)
371     {
372         $el = new HtmlElement('table');
373         return $el->_init2(func_get_args());
374     }
375
376     public static function caption( /*...*/)
377     {
378         $el = new HtmlElement('caption');
379         return $el->_init2(func_get_args());
380     }
381
382     public static function thead( /*...*/)
383     {
384         $el = new HtmlElement('thead');
385         return $el->_init2(func_get_args());
386     }
387
388     public static function tbody( /*...*/)
389     {
390         $el = new HtmlElement('tbody');
391         return $el->_init2(func_get_args());
392     }
393
394     public static function tfoot( /*...*/)
395     {
396         $el = new HtmlElement('tfoot');
397         return $el->_init2(func_get_args());
398     }
399
400     public static function tr( /*...*/)
401     {
402         $el = new HtmlElement('tr');
403         return $el->_init2(func_get_args());
404     }
405
406     public static function td( /*...*/)
407     {
408         $el = new HtmlElement('td');
409         return $el->_init2(func_get_args());
410     }
411
412     public static function th( /*...*/)
413     {
414         $el = new HtmlElement('th');
415         return $el->_init2(func_get_args());
416     }
417
418     public static function colgroup( /*...*/)
419     {
420         $el = new HtmlElement('colgroup');
421         return $el->_init2(func_get_args());
422     }
423
424     public static function col( /*...*/)
425     {
426         $el = new HtmlElement('col');
427         return $el->_init2(func_get_args());
428     }
429
430     /****************************************/
431     public static function form( /*...*/)
432     {
433         $el = new HtmlElement('form');
434         return $el->_init2(func_get_args());
435     }
436
437     public static function input( /*...*/)
438     {
439         $el = new HtmlElement('input');
440         return $el->_init2(func_get_args());
441     }
442
443     public static function button( /*...*/)
444     {
445         $el = new HtmlElement('button');
446         return $el->_init2(func_get_args());
447     }
448
449     public static function option( /*...*/)
450     {
451         $el = new HtmlElement('option');
452         return $el->_init2(func_get_args());
453     }
454
455     public static function select( /*...*/)
456     {
457         $el = new HtmlElement('select');
458         return $el->_init2(func_get_args());
459     }
460
461     public static function textarea( /*...*/)
462     {
463         $el = new HtmlElement('textarea');
464         return $el->_init2(func_get_args());
465     }
466
467     public static function label( /*...*/)
468     {
469         $el = new HtmlElement('label');
470         return $el->_init2(func_get_args());
471     }
472
473     /****************************************/
474     public static function area( /*...*/)
475     {
476         $el = new HtmlElement('area');
477         return $el->_init2(func_get_args());
478     }
479
480     public static function map( /*...*/)
481     {
482         $el = new HtmlElement('map');
483         return $el->_init2(func_get_args());
484     }
485
486     public static function frame( /*...*/)
487     {
488         $el = new HtmlElement('frame');
489         return $el->_init2(func_get_args());
490     }
491
492     public static function frameset( /*...*/)
493     {
494         $el = new HtmlElement('frameset');
495         return $el->_init2(func_get_args());
496     }
497
498     public static function iframe( /*...*/)
499     {
500         $el = new HtmlElement('iframe');
501         return $el->_init2(func_get_args());
502     }
503
504     public static function nobody( /*...*/)
505     {
506         $el = new HtmlElement('nobody');
507         return $el->_init2(func_get_args());
508     }
509
510     public static function object( /*...*/)
511     {
512         $el = new HtmlElement('object');
513         return $el->_init2(func_get_args());
514     }
515
516     public static function embed( /*...*/)
517     {
518         $el = new HtmlElement('embed');
519         return $el->_init2(func_get_args());
520     }
521
522     public static function param( /*...*/)
523     {
524         $el = new HtmlElement('param');
525         return $el->_init2(func_get_args());
526     }
527
528     public static function fieldset( /*...*/)
529     {
530         $el = new HtmlElement('fieldset');
531         return $el->_init2(func_get_args());
532     }
533
534     public static function legend( /*...*/)
535     {
536         $el = new HtmlElement('legend');
537         return $el->_init2(func_get_args());
538     }
539
540     /****************************************/
541     public static function video( /*...*/)
542     {
543         $el = new HtmlElement('video');
544         return $el->_init2(func_get_args());
545     }
546 }
547
548 define('HTMLTAG_EMPTY', 1);
549 define('HTMLTAG_INLINE', 2);
550 define('HTMLTAG_ACCEPTS_INLINE', 4);
551
552 HTML::_setTagProperty(HTMLTAG_EMPTY,
553     'area base basefont br col embed frame hr img input isindex link meta param');
554 HTML::_setTagProperty(HTMLTAG_ACCEPTS_INLINE,
555     // %inline elements:
556     'b big i small tt ' // %fontstyle
557         . 's strike u ' // (deprecated)
558         . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
559         . 'a img object embed br script map q sub sup span bdo ' //%special
560         . 'button input label option select textarea label ' //%formctl
561
562         // %block elements which contain inline content
563         . 'address h1 h2 h3 h4 h5 h6 p pre '
564         // %block elements which contain either block or inline content
565         . 'div fieldset frameset'
566
567         // other with inline content
568         . 'caption dt label legend video '
569         // other with either inline or block
570         . 'dd del ins li td th colgroup');
571
572 HTML::_setTagProperty(HTMLTAG_INLINE,
573     // %inline elements:
574     'b big i small tt ' // %fontstyle
575         . 's strike u ' // (deprecated)
576         . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
577         . 'a img object br script map q sub sup span bdo ' //%special
578         . 'button input label option select textarea ' //%formctl
579         . 'nobody iframe'
580 );
581
582 /**
583  * Generate hidden form input fields.
584  *
585  * @param $query_args hash  A hash mapping names to values for the hidden inputs.
586  * Values in the hash can themselves be hashes.  The will result in hidden inputs
587  * which will reconstruct the nested structure in the resulting query args as
588  * processed by PHP.
589  *
590  * Example:
591  *
592  * $args = array('x' => '2',
593  *               'y' => array('a' => 'aval', 'b' => 'bval'));
594  * $inputs = HiddenInputs($args);
595  *
596  * Will result in:
597  *
598  *  <input type="hidden" name="x" value = "2" />
599  *  <input type="hidden" name="y[a]" value = "aval" />
600  *  <input type="hidden" name="y[b]" value = "bval" />
601  *
602  * @return object An XmlContent object containing the inputs.
603  */
604 function HiddenInputs($query_args, $pfx = false, $exclude = array())
605 {
606     $inputs = HTML();
607
608     foreach ($query_args as $key => $val) {
609         if (in_array($key, $exclude)) continue;
610         $name = $pfx ? $pfx . "[$key]" : $key;
611         if (is_array($val))
612             $inputs->pushContent(HiddenInputs($val, $name));
613         else
614             $inputs->pushContent(HTML::input(array('type' => 'hidden',
615                 'name' => $name,
616                 'value' => $val)));
617     }
618     return $inputs;
619 }
620
621 /** Generate a <script> tag containing javascript.
622  *
623  * @param string $js  The javascript.
624  * @param string $script_args  (optional) hash of script tags options
625  *                             e.g. to provide another version or the defer attr
626  * @return HtmlElement A <script> element.
627  */
628 function JavaScript($js, $script_args = false)
629 {
630     $default_script_args = array( //'version' => 'JavaScript', // not xhtml conformant
631         'type' => 'text/javascript');
632     $script_args = $script_args ? array_merge($default_script_args, $script_args)
633         : $default_script_args;
634     if (empty($js))
635         return HTML(HTML::script($script_args), "\n");
636     else
637         // see http://devedge.netscape.com/viewsource/2003/xhtml-style-script/
638         return HTML(HTML::script($script_args,
639             new RawXml((ENABLE_XHTML_XML ? "\n//<![CDATA[" : "\n<!--//")
640                 . "\n" . trim($js) . "\n"
641                 . (ENABLE_XHTML_XML ? "//]]>\n" : "// -->"))), "\n");
642 }
643
644 /** Conditionally display content based of whether javascript is supported.
645  *
646  * This conditionally (on the client side) displays one of two alternate
647  * contents depending on whether the client supports javascript.
648  *
649  * NOTE:
650  * The content you pass as arguments to this function must be block-level.
651  * (This is because the <noscript> tag is block-level.)
652  *
653  * @param mixed $if_content Content to display if the browser supports
654  * javascript.
655  *
656  * @param mixed $else_content Content to display if the browser does
657  * not support javascript.
658  *
659  * @return XmlContent
660  */
661 function IfJavaScript($if_content = false, $else_content = false)
662 {
663     $html = array();
664     if ($if_content) {
665         $xml = AsXML($if_content);
666         $js = sprintf('document.write("%s");',
667             addcslashes($xml, "\0..\37!@\\\177..\377"));
668         $html[] = JavaScript($js);
669     }
670     if ($else_content) {
671         $html[] = HTML::noscript(false, $else_content);
672     }
673     return HTML($html);
674 }
675
676 // Local Variables:
677 // mode: php
678 // tab-width: 8
679 // c-basic-offset: 4
680 // c-hanging-comment-ender-p: nil
681 // indent-tabs-mode: nil
682 // End: