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