]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/HtmlElement5.php
No tabs
[SourceForge/phpwiki.git] / lib / HtmlElement5.php
1 <?php // $Id$
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         $this->_init(func_get_args());
26         $this->_properties = HTML::getTagProperties($tagname);
27     }
28
29     function _init ($args) {
30         if (!is_array($args))
31             $args = func_get_args();
32
33         assert(count($args) >= 1);
34         assert(is_string($args[0]));
35         $this->_tag = array_shift($args);
36
37         if ($args && is_array($args[0]))
38             $this->_attr = array_shift($args);
39         else {
40             $this->_attr = array();
41             if ($args && $args[0] === false)
42                 array_shift($args);
43         }
44         $this->setContent($args);
45         $this->_properties = HTML::getTagProperties($this->_tag);
46     }
47
48     /**
49      * @access protected
50      * This is used by the static factory methods is class HTML.
51      */
52     function _init2 ($args) {
53         if ($args) {
54             if (is_array($args[0]))
55                 $this->_attr = array_shift($args);
56             elseif ($args[0] === false)
57                 array_shift($args);
58         }
59
60         if (count($args) == 1 && is_array($args[0]))
61             $args = $args[0];
62         $this->_content = $args;
63         return $this;
64     }
65
66     /** Add a "tooltip" to an element.
67      *
68      * @param $tooltip_text string The tooltip text.
69      */
70     function addTooltip ($tooltip_text, $accesskey = null) {
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         $qtooltip = str_replace("'", "\\'", $tooltip_text);
77         $this->setAttr('onmouseover',
78                        sprintf('window.status="%s"; return true;',
79                                addslashes($tooltip_text)));
80         $this->setAttr('onmouseout', "window.status='';return true;");
81     }
82
83     function setAccesskey ($key) {
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         {
91         $this->_attr['title'] = preg_replace
92                     ("/\[(alt-)?(.)\]$/",
93                      "[".$WikiTheme->tooltipAccessKeyPrefix()."-\\2]",
94                      $this->_attr['title']);
95         } else  {
96         $this->_attr['title'] .=
97                     " [".$WikiTheme->tooltipAccessKeyPrefix()."-$key]";
98         }
99     } else {
100         $this->_attr['title'] =
101                 "[".$WikiTheme->tooltipAccessKeyPrefix()."-$key]";
102     }
103     }
104
105     function emptyTag () {
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         return ($this->_properties & HTMLTAG_ACCEPTS_INLINE) != 0;
114     }
115
116     function isInlineElement () {
117         return ($this->_properties & HTMLTAG_INLINE) != 0;
118     }
119 };
120
121 function HTML (/* $content, ... */) {
122     return new XmlContent(func_get_args());
123 }
124
125 class HTML extends HtmlElement {
126     public static function raw ($html_text) {
127         return new RawXml($html_text);
128     }
129
130     function getTagProperties($tag) {
131         $props = &$GLOBALS['HTML_TagProperties'];
132         return isset($props[$tag]) ? $props[$tag] : 0;
133     }
134
135     public static function _setTagProperty($prop_flag, $tags) {
136         $props = &$GLOBALS['HTML_TagProperties'];
137         if (is_string($tags))
138             $tags = preg_split('/\s+/', $tags);
139         foreach ($tags as $tag) {
140             $tag = trim($tag);
141             if ($tag)
142                 if (isset($props[$tag]))
143                     $props[$tag] |= $prop_flag;
144                 else
145                     $props[$tag] = $prop_flag;
146         }
147     }
148
149     // See admin/mkfuncs shell script to generate the following static methods
150
151     public static function link (/*...*/) {
152         $el = new HtmlElement('link');
153         return $el->_init2(func_get_args());
154     }
155     public static function meta (/*...*/) {
156         $el = new HtmlElement('meta');
157         return $el->_init2(func_get_args());
158     }
159     public static function style (/*...*/) {
160         $el = new HtmlElement('style');
161         return $el->_init2(func_get_args());
162     }
163     public static function script (/*...*/) {
164         $el = new HtmlElement('script');
165         return $el->_init2(func_get_args());
166     }
167     public static function noscript (/*...*/) {
168         $el = new HtmlElement('noscript');
169         return $el->_init2(func_get_args());
170     }
171
172     /****************************************/
173     public static function a (/*...*/) {
174         $el = new HtmlElement('a');
175         return $el->_init2(func_get_args());
176     }
177     public static function img (/*...*/) {
178         $el = new HtmlElement('img');
179         return $el->_init2(func_get_args());
180     }
181     public static function br (/*...*/) {
182         $el = new HtmlElement('br');
183         return $el->_init2(func_get_args());
184     }
185     public static function span (/*...*/) {
186         $el = new HtmlElement('span');
187         return $el->_init2(func_get_args());
188     }
189
190     /****************************************/
191     public static function h1 (/*...*/) {
192         $el = new HtmlElement('h1');
193         return $el->_init2(func_get_args());
194     }
195     public static function h2 (/*...*/) {
196         $el = new HtmlElement('h2');
197         return $el->_init2(func_get_args());
198     }
199     public static function h3 (/*...*/) {
200         $el = new HtmlElement('h3');
201         return $el->_init2(func_get_args());
202     }
203     public static function h4 (/*...*/) {
204         $el = new HtmlElement('h4');
205         return $el->_init2(func_get_args());
206     }
207     public static function h5 (/*...*/) {
208         $el = new HtmlElement('h5');
209         return $el->_init2(func_get_args());
210     }
211     public static function h6 (/*...*/) {
212         $el = new HtmlElement('h6');
213         return $el->_init2(func_get_args());
214     }
215
216     /****************************************/
217     public static function hr (/*...*/) {
218         $el = new HtmlElement('hr');
219         return $el->_init2(func_get_args());
220     }
221     public static function div (/*...*/) {
222         $el = new HtmlElement('div');
223         return $el->_init2(func_get_args());
224     }
225     public static function p (/*...*/) {
226         $el = new HtmlElement('p');
227         return $el->_init2(func_get_args());
228     }
229     public static function pre (/*...*/) {
230         $el = new HtmlElement('pre');
231         return $el->_init2(func_get_args());
232     }
233     public static function blockquote (/*...*/) {
234         $el = new HtmlElement('blockquote');
235         return $el->_init2(func_get_args());
236     }
237
238     /****************************************/
239     public static function em (/*...*/) {
240         $el = new HtmlElement('em');
241         return $el->_init2(func_get_args());
242     }
243     public static function strong (/*...*/) {
244         $el = new HtmlElement('strong');
245         return $el->_init2(func_get_args());
246     }
247     public static function small (/*...*/) {
248         $el = new HtmlElement('small');
249         return $el->_init2(func_get_args());
250     }
251
252     /****************************************/
253     public static function tt (/*...*/) {
254         $el = new HtmlElement('tt');
255         return $el->_init2(func_get_args());
256     }
257     public static function u (/*...*/) {
258         $el = new HtmlElement('u');
259         return $el->_init2(func_get_args());
260     }
261     public static function sup (/*...*/) {
262         $el = new HtmlElement('sup');
263         return $el->_init2(func_get_args());
264     }
265     public static function sub (/*...*/) {
266         $el = new HtmlElement('sub');
267         return $el->_init2(func_get_args());
268     }
269
270     /****************************************/
271     public static function ul (/*...*/) {
272         $el = new HtmlElement('ul');
273         return $el->_init2(func_get_args());
274     }
275     public static function ol (/*...*/) {
276         $el = new HtmlElement('ol');
277         return $el->_init2(func_get_args());
278     }
279     public static function dl (/*...*/) {
280         $el = new HtmlElement('dl');
281         return $el->_init2(func_get_args());
282     }
283     public static function li (/*...*/) {
284         $el = new HtmlElement('li');
285         return $el->_init2(func_get_args());
286     }
287     public static function dt (/*...*/) {
288         $el = new HtmlElement('dt');
289         return $el->_init2(func_get_args());
290     }
291     public static function dd (/*...*/) {
292         $el = new HtmlElement('dd');
293         return $el->_init2(func_get_args());
294     }
295
296     /****************************************/
297     public static function table (/*...*/) {
298         $el = new HtmlElement('table');
299         return $el->_init2(func_get_args());
300     }
301     public static function caption (/*...*/) {
302         $el = new HtmlElement('caption');
303         return $el->_init2(func_get_args());
304     }
305     public static function thead (/*...*/) {
306         $el = new HtmlElement('thead');
307         return $el->_init2(func_get_args());
308     }
309     public static function tbody (/*...*/) {
310         $el = new HtmlElement('tbody');
311         return $el->_init2(func_get_args());
312     }
313     public static function tfoot (/*...*/) {
314         $el = new HtmlElement('tfoot');
315         return $el->_init2(func_get_args());
316     }
317     public static function tr (/*...*/) {
318         $el = new HtmlElement('tr');
319         return $el->_init2(func_get_args());
320     }
321     public static function td (/*...*/) {
322         $el = new HtmlElement('td');
323         return $el->_init2(func_get_args());
324     }
325     public static function th (/*...*/) {
326         $el = new HtmlElement('th');
327         return $el->_init2(func_get_args());
328     }
329     public static function colgroup (/*...*/) {
330         $el = new HtmlElement('colgroup');
331         return $el->_init2(func_get_args());
332     }
333     public static function col (/*...*/) {
334         $el = new HtmlElement('col');
335         return $el->_init2(func_get_args());
336     }
337
338     /****************************************/
339     public static function form (/*...*/) {
340         $el = new HtmlElement('form');
341         return $el->_init2(func_get_args());
342     }
343     public static function input (/*...*/) {
344         $el = new HtmlElement('input');
345         return $el->_init2(func_get_args());
346     }
347     public static function button (/*...*/) {
348         $el = new HtmlElement('button');
349         return $el->_init2(func_get_args());
350     }
351     public static function option (/*...*/) {
352         $el = new HtmlElement('option');
353         return $el->_init2(func_get_args());
354     }
355     public static function select (/*...*/) {
356         $el = new HtmlElement('select');
357         return $el->_init2(func_get_args());
358     }
359     public static function textarea (/*...*/) {
360         $el = new HtmlElement('textarea');
361         return $el->_init2(func_get_args());
362     }
363     public static function label (/*...*/) {
364         $el = new HtmlElement('label');
365         return $el->_init2(func_get_args());
366     }
367
368     /****************************************/
369     public static function area (/*...*/) {
370         $el = new HtmlElement('area');
371         return $el->_init2(func_get_args());
372     }
373     public static function map (/*...*/) {
374         $el = new HtmlElement('map');
375         return $el->_init2(func_get_args());
376     }
377     public static function frame (/*...*/) {
378         $el = new HtmlElement('frame');
379         return $el->_init2(func_get_args());
380     }
381     public static function frameset (/*...*/) {
382         $el = new HtmlElement('frameset');
383         return $el->_init2(func_get_args());
384     }
385     public static function iframe (/*...*/) {
386         $el = new HtmlElement('iframe');
387         return $el->_init2(func_get_args());
388     }
389     public static function nobody (/*...*/) {
390         $el = new HtmlElement('nobody');
391         return $el->_init2(func_get_args());
392     }
393     public static function object (/*...*/) {
394         $el = new HtmlElement('object');
395         return $el->_init2(func_get_args());
396     }
397     public static function embed (/*...*/) {
398         $el = new HtmlElement('embed');
399         return $el->_init2(func_get_args());
400     }
401     public static function param (/*...*/) {
402         $el = new HtmlElement('param');
403         return $el->_init2(func_get_args());
404     }
405     public static function fieldset (/*...*/) {
406         $el = new HtmlElement('fieldset');
407         return $el->_init2(func_get_args());
408     }
409     public static function legend (/*...*/) {
410         $el = new HtmlElement('legend');
411         return $el->_init2(func_get_args());
412     }
413
414     /****************************************/
415     public static function video (/*...*/) {
416         $el = new HtmlElement('video');
417         return $el->_init2(func_get_args());
418     }
419 }
420
421 define('HTMLTAG_EMPTY', 1);
422 define('HTMLTAG_INLINE', 2);
423 define('HTMLTAG_ACCEPTS_INLINE', 4);
424
425
426 HTML::_setTagProperty(HTMLTAG_EMPTY,
427                       'area base basefont br col frame hr img input isindex link meta param');
428 HTML::_setTagProperty(HTMLTAG_ACCEPTS_INLINE,
429                       // %inline elements:
430                       'b big i small tt ' // %fontstyle
431                       . 's strike u ' // (deprecated)
432                       . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
433                       . 'a img object embed br script map q sub sup span bdo '//%special
434                       . 'button input label option select textarea label ' //%formctl
435
436                       // %block elements which contain inline content
437                       . 'address h1 h2 h3 h4 h5 h6 p pre '
438                       // %block elements which contain either block or inline content
439                       . 'div fieldset frameset'
440
441                       // other with inline content
442                       . 'caption dt label legend video '
443                       // other with either inline or block
444                       . 'dd del ins li td th colgroup');
445
446 HTML::_setTagProperty(HTMLTAG_INLINE,
447                       // %inline elements:
448                       'b big i small tt ' // %fontstyle
449                       . 's strike u ' // (deprecated)
450                       . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
451                       . 'a img object br script map q sub sup span bdo '//%special
452                       . 'button input label option select textarea ' //%formctl
453                       . 'nobody iframe'
454                       );
455
456 /**
457  * Generate hidden form input fields.
458  *
459  * @param $query_args hash  A hash mapping names to values for the hidden inputs.
460  * Values in the hash can themselves be hashes.  The will result in hidden inputs
461  * which will reconstruct the nested structure in the resulting query args as
462  * processed by PHP.
463  *
464  * Example:
465  *
466  * $args = array('x' => '2',
467  *               'y' => array('a' => 'aval', 'b' => 'bval'));
468  * $inputs = HiddenInputs($args);
469  *
470  * Will result in:
471  *
472  *  <input type="hidden" name="x" value = "2" />
473  *  <input type="hidden" name="y[a]" value = "aval" />
474  *  <input type="hidden" name="y[b]" value = "bval" />
475  *
476  * @return object An XmlContent object containing the inputs.
477  */
478 function HiddenInputs ($query_args, $pfx = false, $exclude = array()) {
479     $inputs = HTML();
480
481     foreach ($query_args as $key => $val) {
482         if (in_array($key, $exclude)) continue;
483         $name = $pfx ? $pfx . "[$key]" : $key;
484         if (is_array($val))
485             $inputs->pushContent(HiddenInputs($val, $name));
486         else
487             $inputs->pushContent(HTML::input(array('type' => 'hidden',
488                                                    'name' => $name,
489                                                    'value' => $val)));
490     }
491     return $inputs;
492 }
493
494
495 /** Generate a <script> tag containing javascript.
496  *
497  * @param string $js  The javascript.
498  * @param string $script_args  (optional) hash of script tags options
499  *                             e.g. to provide another version or the defer attr
500  * @return HtmlElement A <script> element.
501  */
502 function JavaScript ($js, $script_args = false) {
503     $default_script_args = array(//'version' => 'JavaScript', // not xhtml conformant
504                                  'type' => 'text/javascript');
505     $script_args = $script_args ? array_merge($default_script_args, $script_args)
506                                 : $default_script_args;
507     if (empty($js))
508         return HTML(HTML::script($script_args),"\n");
509     else
510         // see http://devedge.netscape.com/viewsource/2003/xhtml-style-script/
511         return HTML(HTML::script($script_args,
512                             new RawXml((ENABLE_XHTML_XML ? "\n//<![CDATA[" : "\n<!--//")
513                                        . "\n".trim($js)."\n"
514                                        . (ENABLE_XHTML_XML ? "//]]>\n" : "// -->"))),"\n");
515 }
516
517 /** Conditionally display content based of whether javascript is supported.
518  *
519  * This conditionally (on the client side) displays one of two alternate
520  * contents depending on whether the client supports javascript.
521  *
522  * NOTE:
523  * The content you pass as arguments to this function must be block-level.
524  * (This is because the <noscript> tag is block-level.)
525  *
526  * @param mixed $if_content Content to display if the browser supports
527  * javascript.
528  *
529  * @param mixed $else_content Content to display if the browser does
530  * not support javascript.
531  *
532  * @return XmlContent
533  */
534 function IfJavaScript($if_content = false, $else_content = false) {
535     $html = array();
536     if ($if_content) {
537         $xml = AsXML($if_content);
538         $js = sprintf('document.write("%s");',
539                       addcslashes($xml, "\0..\37!@\\\177..\377"));
540         $html[] = JavaScript($js);
541     }
542     if ($else_content) {
543         $html[] = HTML::noscript(false, $else_content);
544     }
545     return HTML($html);
546 }
547
548 // Local Variables:
549 // mode: php
550 // tab-width: 8
551 // c-basic-offset: 4
552 // c-hanging-comment-ender-p: nil
553 // indent-tabs-mode: nil
554 // End:
555 ?>