3 * Code for writing the HTML subset of XML.
4 * @author: Jeff Dairiki
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
9 * Todo: Add support for a JavaScript backend, a php2js compiler.
10 * HTML::div(array('onclick' => 'HTML::div(...)'))
12 if (!class_exists("XmlElement"))
13 require_once(dirname(__FILE__) . "/XmlElement.php");
14 if (class_exists("HtmlElement"))
20 //apd_set_session_trace(35);
22 class HtmlElement extends XmlElement
24 function __construct($tagname /* , $attr_or_content , ...*/)
26 $this->_init(func_get_args());
27 $this->_properties = HTML::getTagProperties($tagname);
33 $args = func_get_args();
35 assert(count($args) >= 1);
36 assert(is_string($args[0]));
37 $this->_tag = array_shift($args);
39 if ($args && is_array($args[0]))
40 $this->_attr = array_shift($args);
42 $this->_attr = array();
43 if ($args && $args[0] === false)
46 $this->setContent($args);
47 $this->_properties = HTML::getTagProperties($this->_tag);
52 * This is used by the static factory methods is class HTML.
54 function _init2($args)
57 if (is_array($args[0]))
58 $this->_attr = array_shift($args);
59 elseif ($args[0] === false)
63 if (count($args) == 1 && is_array($args[0]))
65 $this->_content = $args;
69 /** Add a "tooltip" to an element.
71 * @param $tooltip_text string The tooltip text.
73 function addTooltip($tooltip_text, $accesskey = null)
75 $this->setAttr('title', $tooltip_text);
76 if ($accesskey) $this->setAccesskey($accesskey);
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;");
87 function setAccesskey($key)
90 if (strlen($key) != 1) return;
91 $this->setAttr("accesskey", $key);
93 if (!empty($this->_attr['title'])) {
94 if (preg_match("/\[(alt-)?(.)\]$/", $this->_attr['title'], $m)) {
95 $this->_attr['title'] = preg_replace
97 "[" . $WikiTheme->tooltipAccessKeyPrefix() . "-\\2]",
98 $this->_attr['title']);
100 $this->_attr['title'] .=
101 " [" . $WikiTheme->tooltipAccessKeyPrefix() . "-$key]";
104 $this->_attr['title'] =
105 "[" . $WikiTheme->tooltipAccessKeyPrefix() . "-$key]";
111 if (($this->_properties & HTMLTAG_EMPTY) == 0)
112 return $this->startTag() . "</$this->_tag>";
114 return substr($this->startTag(), 0, -1) . " />";
117 function hasInlineContent()
119 return ($this->_properties & HTMLTAG_ACCEPTS_INLINE) != 0;
122 function isInlineElement()
124 return ($this->_properties & HTMLTAG_INLINE) != 0;
128 function HTML( /* $content, ... */)
130 return new XmlContent(func_get_args());
133 class HTML extends HtmlElement
135 public static function raw($html_text)
137 return new RawXml($html_text);
140 public static function getTagProperties($tag)
142 $props = &$GLOBALS['HTML_TagProperties'];
143 return isset($props[$tag]) ? $props[$tag] : 0;
146 public static function _setTagProperty($prop_flag, $tags)
148 $props = &$GLOBALS['HTML_TagProperties'];
149 if (is_string($tags))
150 $tags = preg_split('/\s+/', $tags);
151 foreach ($tags as $tag) {
154 if (isset($props[$tag]))
155 $props[$tag] |= $prop_flag;
157 $props[$tag] = $prop_flag;
161 // See admin/mkfuncs shell script to generate the following static methods
163 public static function link( /*...*/)
165 $el = new HtmlElement('link');
166 return $el->_init2(func_get_args());
169 public static function meta( /*...*/)
171 $el = new HtmlElement('meta');
172 return $el->_init2(func_get_args());
175 public static function style( /*...*/)
177 $el = new HtmlElement('style');
178 return $el->_init2(func_get_args());
181 public static function script( /*...*/)
183 $el = new HtmlElement('script');
184 return $el->_init2(func_get_args());
187 public static function noscript( /*...*/)
189 $el = new HtmlElement('noscript');
190 return $el->_init2(func_get_args());
193 /****************************************/
194 public static function a( /*...*/)
196 $el = new HtmlElement('a');
197 return $el->_init2(func_get_args());
200 public static function img( /*...*/)
202 $el = new HtmlElement('img');
203 return $el->_init2(func_get_args());
206 public static function br( /*...*/)
208 $el = new HtmlElement('br');
209 return $el->_init2(func_get_args());
212 public static function span( /*...*/)
214 $el = new HtmlElement('span');
215 return $el->_init2(func_get_args());
218 /****************************************/
219 public static function h1( /*...*/)
221 $el = new HtmlElement('h1');
222 return $el->_init2(func_get_args());
225 public static function h2( /*...*/)
227 $el = new HtmlElement('h2');
228 return $el->_init2(func_get_args());
231 public static function h3( /*...*/)
233 $el = new HtmlElement('h3');
234 return $el->_init2(func_get_args());
237 public static function h4( /*...*/)
239 $el = new HtmlElement('h4');
240 return $el->_init2(func_get_args());
243 public static function h5( /*...*/)
245 $el = new HtmlElement('h5');
246 return $el->_init2(func_get_args());
249 public static function h6( /*...*/)
251 $el = new HtmlElement('h6');
252 return $el->_init2(func_get_args());
255 /****************************************/
256 public static function hr( /*...*/)
258 $el = new HtmlElement('hr');
259 return $el->_init2(func_get_args());
262 public static function div( /*...*/)
264 $el = new HtmlElement('div');
265 return $el->_init2(func_get_args());
268 public static function p( /*...*/)
270 $el = new HtmlElement('p');
271 return $el->_init2(func_get_args());
274 public static function pre( /*...*/)
276 $el = new HtmlElement('pre');
277 return $el->_init2(func_get_args());
280 public static function blockquote( /*...*/)
282 $el = new HtmlElement('blockquote');
283 return $el->_init2(func_get_args());
286 /****************************************/
287 public static function em( /*...*/)
289 $el = new HtmlElement('em');
290 return $el->_init2(func_get_args());
293 public static function strong( /*...*/)
295 $el = new HtmlElement('strong');
296 return $el->_init2(func_get_args());
299 public static function small( /*...*/)
301 $el = new HtmlElement('small');
302 return $el->_init2(func_get_args());
305 /****************************************/
306 public static function tt( /*...*/)
308 $el = new HtmlElement('tt');
309 return $el->_init2(func_get_args());
312 public static function u( /*...*/)
314 $el = new HtmlElement('u');
315 return $el->_init2(func_get_args());
318 public static function sup( /*...*/)
320 $el = new HtmlElement('sup');
321 return $el->_init2(func_get_args());
324 public static function sub( /*...*/)
326 $el = new HtmlElement('sub');
327 return $el->_init2(func_get_args());
330 /****************************************/
331 public static function ul( /*...*/)
333 $el = new HtmlElement('ul');
334 return $el->_init2(func_get_args());
337 public static function ol( /*...*/)
339 $el = new HtmlElement('ol');
340 return $el->_init2(func_get_args());
343 public static function dl( /*...*/)
345 $el = new HtmlElement('dl');
346 return $el->_init2(func_get_args());
349 public static function li( /*...*/)
351 $el = new HtmlElement('li');
352 return $el->_init2(func_get_args());
355 public static function dt( /*...*/)
357 $el = new HtmlElement('dt');
358 return $el->_init2(func_get_args());
361 public static function dd( /*...*/)
363 $el = new HtmlElement('dd');
364 return $el->_init2(func_get_args());
367 /****************************************/
368 public static function table( /*...*/)
370 $el = new HtmlElement('table');
371 return $el->_init2(func_get_args());
374 public static function caption( /*...*/)
376 $el = new HtmlElement('caption');
377 return $el->_init2(func_get_args());
380 public static function thead( /*...*/)
382 $el = new HtmlElement('thead');
383 return $el->_init2(func_get_args());
386 public static function tbody( /*...*/)
388 $el = new HtmlElement('tbody');
389 return $el->_init2(func_get_args());
392 public static function tfoot( /*...*/)
394 $el = new HtmlElement('tfoot');
395 return $el->_init2(func_get_args());
398 public static function tr( /*...*/)
400 $el = new HtmlElement('tr');
401 return $el->_init2(func_get_args());
404 public static function td( /*...*/)
406 $el = new HtmlElement('td');
407 return $el->_init2(func_get_args());
410 public static function th( /*...*/)
412 $el = new HtmlElement('th');
413 return $el->_init2(func_get_args());
416 public static function colgroup( /*...*/)
418 $el = new HtmlElement('colgroup');
419 return $el->_init2(func_get_args());
422 public static function col( /*...*/)
424 $el = new HtmlElement('col');
425 return $el->_init2(func_get_args());
428 /****************************************/
429 public static function form( /*...*/)
431 $el = new HtmlElement('form');
432 return $el->_init2(func_get_args());
435 public static function input( /*...*/)
437 $el = new HtmlElement('input');
438 return $el->_init2(func_get_args());
441 public static function button( /*...*/)
443 $el = new HtmlElement('button');
444 return $el->_init2(func_get_args());
447 public static function option( /*...*/)
449 $el = new HtmlElement('option');
450 return $el->_init2(func_get_args());
453 public static function select( /*...*/)
455 $el = new HtmlElement('select');
456 return $el->_init2(func_get_args());
459 public static function textarea( /*...*/)
461 $el = new HtmlElement('textarea');
462 return $el->_init2(func_get_args());
465 public static function label( /*...*/)
467 $el = new HtmlElement('label');
468 return $el->_init2(func_get_args());
471 /****************************************/
472 public static function area( /*...*/)
474 $el = new HtmlElement('area');
475 return $el->_init2(func_get_args());
478 public static function map( /*...*/)
480 $el = new HtmlElement('map');
481 return $el->_init2(func_get_args());
484 public static function frame( /*...*/)
486 $el = new HtmlElement('frame');
487 return $el->_init2(func_get_args());
490 public static function frameset( /*...*/)
492 $el = new HtmlElement('frameset');
493 return $el->_init2(func_get_args());
496 public static function iframe( /*...*/)
498 $el = new HtmlElement('iframe');
499 return $el->_init2(func_get_args());
502 public static function nobody( /*...*/)
504 $el = new HtmlElement('nobody');
505 return $el->_init2(func_get_args());
508 public static function object( /*...*/)
510 $el = new HtmlElement('object');
511 return $el->_init2(func_get_args());
514 public static function embed( /*...*/)
516 $el = new HtmlElement('embed');
517 return $el->_init2(func_get_args());
520 public static function param( /*...*/)
522 $el = new HtmlElement('param');
523 return $el->_init2(func_get_args());
526 public static function fieldset( /*...*/)
528 $el = new HtmlElement('fieldset');
529 return $el->_init2(func_get_args());
532 public static function legend( /*...*/)
534 $el = new HtmlElement('legend');
535 return $el->_init2(func_get_args());
538 /****************************************/
539 public static function video( /*...*/)
541 $el = new HtmlElement('video');
542 return $el->_init2(func_get_args());
546 define('HTMLTAG_EMPTY', 1);
547 define('HTMLTAG_INLINE', 2);
548 define('HTMLTAG_ACCEPTS_INLINE', 4);
550 HTML::_setTagProperty(HTMLTAG_EMPTY,
551 'area base basefont br col embed frame hr img input isindex link meta param');
552 HTML::_setTagProperty(HTMLTAG_ACCEPTS_INLINE,
554 'b big i small tt ' // %fontstyle
555 . 's strike u ' // (deprecated)
556 . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
557 . 'a img object embed br script map q sub sup span bdo ' //%special
558 . 'button input label option select textarea label ' //%formctl
560 // %block elements which contain inline content
561 . 'address h1 h2 h3 h4 h5 h6 p pre '
562 // %block elements which contain either block or inline content
563 . 'div fieldset frameset'
565 // other with inline content
566 . 'caption dt label legend video '
567 // other with either inline or block
568 . 'dd del ins li td th colgroup');
570 HTML::_setTagProperty(HTMLTAG_INLINE,
572 'b big i small tt ' // %fontstyle
573 . 's strike u ' // (deprecated)
574 . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
575 . 'a img object br script map q sub sup span bdo ' //%special
576 . 'button input label option select textarea ' //%formctl
581 * Generate hidden form input fields.
583 * @param $query_args hash A hash mapping names to values for the hidden inputs.
584 * Values in the hash can themselves be hashes. The will result in hidden inputs
585 * which will reconstruct the nested structure in the resulting query args as
590 * $args = array('x' => '2',
591 * 'y' => array('a' => 'aval', 'b' => 'bval'));
592 * $inputs = HiddenInputs($args);
596 * <input type="hidden" name="x" value = "2" />
597 * <input type="hidden" name="y[a]" value = "aval" />
598 * <input type="hidden" name="y[b]" value = "bval" />
600 * @return object An XmlContent object containing the inputs.
602 function HiddenInputs($query_args, $pfx = false, $exclude = array())
606 foreach ($query_args as $key => $val) {
607 if (in_array($key, $exclude)) continue;
608 $name = $pfx ? $pfx . "[$key]" : $key;
610 $inputs->pushContent(HiddenInputs($val, $name));
612 $inputs->pushContent(HTML::input(array('type' => 'hidden',
619 /** Generate a <script> tag containing javascript.
621 * @param string $js The javascript.
622 * @param string $script_args (optional) hash of script tags options
623 * e.g. to provide another version or the defer attr
624 * @return HtmlElement A <script> element.
626 function JavaScript($js, $script_args = false)
628 $default_script_args = array( //'version' => 'JavaScript', // not xhtml conformant
629 'type' => 'text/javascript');
630 $script_args = $script_args ? array_merge($default_script_args, $script_args)
631 : $default_script_args;
633 return HTML(HTML::script($script_args), "\n");
635 // see http://devedge.netscape.com/viewsource/2003/xhtml-style-script/
636 return HTML(HTML::script($script_args,
637 new RawXml((ENABLE_XHTML_XML ? "\n//<![CDATA[" : "\n<!--//")
638 . "\n" . trim($js) . "\n"
639 . (ENABLE_XHTML_XML ? "//]]>\n" : "// -->"))), "\n");
642 /** Conditionally display content based of whether javascript is supported.
644 * This conditionally (on the client side) displays one of two alternate
645 * contents depending on whether the client supports javascript.
648 * The content you pass as arguments to this function must be block-level.
649 * (This is because the <noscript> tag is block-level.)
651 * @param mixed $if_content Content to display if the browser supports
654 * @param mixed $else_content Content to display if the browser does
655 * not support javascript.
659 function IfJavaScript($if_content = false, $else_content = false)
663 $xml = AsXML($if_content);
664 $js = sprintf('document.write("%s");',
665 addcslashes($xml, "\0..\37!@\\\177..\377"));
666 $html[] = JavaScript($js);
669 $html[] = HTML::noscript(false, $else_content);
678 // c-hanging-comment-ender-p: nil
679 // indent-tabs-mode: nil