3 * Code for writing the HTML subset of XML.
4 * @author: Jeff Dairiki
6 * Todo: Add support for a JavaScript backend, a php2js compiler.
7 * HTML::div(array('onclick' => 'HTML::div(...)'))
9 if (!class_exists("XmlElement"))
10 require_once(dirname(__FILE__) . "/XmlElement.php");
11 if (class_exists("HtmlElement"))
18 class HtmlElement extends XmlElement
23 function __construct($tagname /* , $attr_or_content , ...*/)
25 $this->_init(func_get_args());
26 $this->_properties = HTML::getTagProperties($tagname);
32 $args = func_get_args();
34 assert(count($args) >= 1);
35 assert(is_string($args[0]));
36 $this->_tag = array_shift($args);
38 if ($args && is_array($args[0]))
39 $this->_attr = array_shift($args);
41 $this->_attr = array();
42 if ($args && $args[0] === false)
45 $this->setContent($args);
46 $this->_properties = HTML::getTagProperties($this->_tag);
50 * This is used by the static factory methods is class HTML.
55 protected function _init2($args)
58 if (is_array($args[0]))
59 $this->_attr = array_shift($args);
60 elseif ($args[0] === false)
64 if (count($args) == 1 && is_array($args[0]))
66 $this->_content = $args;
70 /** Add a "tooltip" to an element.
72 * @param string $tooltip_text The tooltip text.
74 function addTooltip($tooltip_text)
76 $this->setAttr('title', $tooltip_text);
78 // FIXME: this should be initialized from title by an onLoad() function.
79 // (though, that may not be possible.)
80 $this->setAttr('onmouseover',
81 sprintf('window.status="%s"; return true;',
82 addslashes($tooltip_text)));
83 $this->setAttr('onmouseout', "window.status='';return true;");
88 if (($this->_properties & HTMLTAG_EMPTY) == 0)
89 return $this->startTag() . "</$this->_tag>";
91 return substr($this->startTag(), 0, -1) . " />";
94 function hasInlineContent()
96 return ($this->_properties & HTMLTAG_ACCEPTS_INLINE) != 0;
99 function isInlineElement()
101 return ($this->_properties & HTMLTAG_INLINE) != 0;
105 function HTML( /* $content, ... */)
107 return new XmlContent(func_get_args());
110 class HTML extends HtmlElement
112 public static function raw($html_text)
114 return new RawXml($html_text);
117 public static function getTagProperties($tag)
119 $props = &$GLOBALS['HTML_TagProperties'];
120 return isset($props[$tag]) ? $props[$tag] : 0;
123 public static function _setTagProperty($prop_flag, $tags)
125 $props = &$GLOBALS['HTML_TagProperties'];
126 if (is_string($tags))
127 $tags = preg_split('/\s+/', $tags);
128 foreach ($tags as $tag) {
131 if (isset($props[$tag]))
132 $props[$tag] |= $prop_flag;
134 $props[$tag] = $prop_flag;
138 // See admin/mkfuncs shell script to generate the following static methods
140 public static function link( /*...*/)
142 $el = new HtmlElement('link');
143 return $el->_init2(func_get_args());
146 public static function meta( /*...*/)
148 $el = new HtmlElement('meta');
149 return $el->_init2(func_get_args());
152 public static function style( /*...*/)
154 $el = new HtmlElement('style');
155 return $el->_init2(func_get_args());
158 public static function script( /*...*/)
160 $el = new HtmlElement('script');
161 return $el->_init2(func_get_args());
164 public static function noscript( /*...*/)
166 $el = new HtmlElement('noscript');
167 return $el->_init2(func_get_args());
170 /****************************************/
171 public static function a( /*...*/)
173 $el = new HtmlElement('a');
174 return $el->_init2(func_get_args());
177 public static function img( /*...*/)
179 $el = new HtmlElement('img');
180 return $el->_init2(func_get_args());
183 public static function br( /*...*/)
185 $el = new HtmlElement('br');
186 return $el->_init2(func_get_args());
189 public static function span( /*...*/)
191 $el = new HtmlElement('span');
192 return $el->_init2(func_get_args());
195 /****************************************/
196 public static function h1( /*...*/)
198 $el = new HtmlElement('h1');
199 return $el->_init2(func_get_args());
202 public static function h2( /*...*/)
204 $el = new HtmlElement('h2');
205 return $el->_init2(func_get_args());
208 public static function h3( /*...*/)
210 $el = new HtmlElement('h3');
211 return $el->_init2(func_get_args());
214 public static function h4( /*...*/)
216 $el = new HtmlElement('h4');
217 return $el->_init2(func_get_args());
220 public static function h5( /*...*/)
222 $el = new HtmlElement('h5');
223 return $el->_init2(func_get_args());
226 public static function h6( /*...*/)
228 $el = new HtmlElement('h6');
229 return $el->_init2(func_get_args());
232 /****************************************/
233 public static function hr( /*...*/)
235 $el = new HtmlElement('hr');
236 return $el->_init2(func_get_args());
239 public static function div( /*...*/)
241 $el = new HtmlElement('div');
242 return $el->_init2(func_get_args());
245 public static function p( /*...*/)
247 $el = new HtmlElement('p');
248 return $el->_init2(func_get_args());
251 public static function pre( /*...*/)
253 $el = new HtmlElement('pre');
254 return $el->_init2(func_get_args());
257 public static function blockquote( /*...*/)
259 $el = new HtmlElement('blockquote');
260 return $el->_init2(func_get_args());
263 /****************************************/
264 public static function em( /*...*/)
266 $el = new HtmlElement('em');
267 return $el->_init2(func_get_args());
270 public static function strong( /*...*/)
272 $el = new HtmlElement('strong');
273 return $el->_init2(func_get_args());
276 public static function small( /*...*/)
278 $el = new HtmlElement('small');
279 return $el->_init2(func_get_args());
282 public static function abbr( /*...*/)
284 $el = new HtmlElement('abbr');
285 return $el->_init2(func_get_args());
288 public static function acronym( /*...*/)
290 $el = new HtmlElement('acronym');
291 return $el->_init2(func_get_args());
294 public static function cite( /*...*/)
296 $el = new HtmlElement('cite');
297 return $el->_init2(func_get_args());
300 public static function code( /*...*/)
302 $el = new HtmlElement('code');
303 return $el->_init2(func_get_args());
306 public static function dfn( /*...*/)
308 $el = new HtmlElement('dfn');
309 return $el->_init2(func_get_args());
312 public static function kbd( /*...*/)
314 $el = new HtmlElement('kbd');
315 return $el->_init2(func_get_args());
318 public static function samp( /*...*/)
320 $el = new HtmlElement('samp');
321 return $el->_init2(func_get_args());
324 /****************************************/
325 public static function tt( /*...*/)
327 $el = new HtmlElement('tt');
328 return $el->_init2(func_get_args());
331 public static function u( /*...*/)
333 $el = new HtmlElement('u');
334 return $el->_init2(func_get_args());
337 public static function sup( /*...*/)
339 $el = new HtmlElement('sup');
340 return $el->_init2(func_get_args());
343 public static function sub( /*...*/)
345 $el = new HtmlElement('sub');
346 return $el->_init2(func_get_args());
349 /****************************************/
350 public static function ul( /*...*/)
352 $el = new HtmlElement('ul');
353 return $el->_init2(func_get_args());
356 public static function ol( /*...*/)
358 $el = new HtmlElement('ol');
359 return $el->_init2(func_get_args());
362 public static function dl( /*...*/)
364 $el = new HtmlElement('dl');
365 return $el->_init2(func_get_args());
368 public static function li( /*...*/)
370 $el = new HtmlElement('li');
371 return $el->_init2(func_get_args());
374 public static function dt( /*...*/)
376 $el = new HtmlElement('dt');
377 return $el->_init2(func_get_args());
380 public static function dd( /*...*/)
382 $el = new HtmlElement('dd');
383 return $el->_init2(func_get_args());
386 /****************************************/
387 public static function table( /*...*/)
389 $el = new HtmlElement('table');
390 return $el->_init2(func_get_args());
393 public static function caption( /*...*/)
395 $el = new HtmlElement('caption');
396 return $el->_init2(func_get_args());
399 public static function thead( /*...*/)
401 $el = new HtmlElement('thead');
402 return $el->_init2(func_get_args());
405 public static function tbody( /*...*/)
407 $el = new HtmlElement('tbody');
408 return $el->_init2(func_get_args());
411 public static function tfoot( /*...*/)
413 $el = new HtmlElement('tfoot');
414 return $el->_init2(func_get_args());
417 public static function tr( /*...*/)
419 $el = new HtmlElement('tr');
420 return $el->_init2(func_get_args());
423 public static function td( /*...*/)
425 $el = new HtmlElement('td');
426 return $el->_init2(func_get_args());
429 public static function th( /*...*/)
431 $el = new HtmlElement('th');
432 return $el->_init2(func_get_args());
435 public static function colgroup( /*...*/)
437 $el = new HtmlElement('colgroup');
438 return $el->_init2(func_get_args());
441 public static function col( /*...*/)
443 $el = new HtmlElement('col');
444 return $el->_init2(func_get_args());
447 /****************************************/
448 public static function form( /*...*/)
450 $el = new HtmlElement('form');
451 return $el->_init2(func_get_args());
454 public static function input( /*...*/)
456 $el = new HtmlElement('input');
457 return $el->_init2(func_get_args());
460 public static function button( /*...*/)
462 $el = new HtmlElement('button');
463 return $el->_init2(func_get_args());
466 public static function option( /*...*/)
468 $el = new HtmlElement('option');
469 return $el->_init2(func_get_args());
472 public static function select( /*...*/)
474 $el = new HtmlElement('select');
475 return $el->_init2(func_get_args());
478 public static function textarea( /*...*/)
480 $el = new HtmlElement('textarea');
481 return $el->_init2(func_get_args());
484 public static function label( /*...*/)
486 $el = new HtmlElement('label');
487 return $el->_init2(func_get_args());
490 /****************************************/
491 public static function area( /*...*/)
493 $el = new HtmlElement('area');
494 return $el->_init2(func_get_args());
497 public static function map( /*...*/)
499 $el = new HtmlElement('map');
500 return $el->_init2(func_get_args());
503 public static function iframe( /*...*/)
505 $el = new HtmlElement('iframe');
506 return $el->_init2(func_get_args());
509 public static function nobody( /*...*/)
511 $el = new HtmlElement('nobody');
512 return $el->_init2(func_get_args());
515 public static function object( /*...*/)
517 $el = new HtmlElement('object');
518 return $el->_init2(func_get_args());
521 public static function embed( /*...*/)
523 $el = new HtmlElement('embed');
524 return $el->_init2(func_get_args());
527 public static function param( /*...*/)
529 $el = new HtmlElement('param');
530 return $el->_init2(func_get_args());
533 public static function fieldset( /*...*/)
535 $el = new HtmlElement('fieldset');
536 return $el->_init2(func_get_args());
539 public static function legend( /*...*/)
541 $el = new HtmlElement('legend');
542 return $el->_init2(func_get_args());
545 /****************************************/
546 public static function video( /*...*/)
548 $el = new HtmlElement('video');
549 return $el->_init2(func_get_args());
553 define('HTMLTAG_EMPTY', 1);
554 define('HTMLTAG_INLINE', 2);
555 define('HTMLTAG_ACCEPTS_INLINE', 4);
557 HTML::_setTagProperty(HTMLTAG_EMPTY,
558 'area base basefont br col embed hr img input isindex link meta param');
559 HTML::_setTagProperty(HTMLTAG_ACCEPTS_INLINE,
561 'b big i small tt ' // %fontstyle
562 . 's strike u ' // (deprecated)
563 . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
564 . 'a img object embed br script map q sub sup span bdo ' //%special
565 . 'button input label option select textarea label ' //%formctl
567 // %block elements which contain inline content
568 . 'address h1 h2 h3 h4 h5 h6 p pre '
569 // %block elements which contain either block or inline content
572 // other with inline content
573 . 'caption dt label legend video '
574 // other with either inline or block
575 . 'dd del ins li td th colgroup');
577 HTML::_setTagProperty(HTMLTAG_INLINE,
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 br script map q sub sup span bdo ' //%special
583 . 'button input label option select textarea ' //%formctl
588 * Generate hidden form input fields.
590 * @param array $query_args A hash mapping names to values for the hidden inputs.
591 * Values in the hash can themselves be hashes. The will result in hidden inputs
592 * which will reconstruct the nested structure in the resulting query args as
597 * $args = array('x' => '2',
598 * 'y' => array('a' => 'aval', 'b' => 'bval'));
599 * $inputs = HiddenInputs($args);
603 * <input type="hidden" name="x" value = "2" />
604 * <input type="hidden" name="y[a]" value = "aval" />
605 * <input type="hidden" name="y[b]" value = "bval" />
608 * @param array $exclude
609 * @return object An XmlContent object containing the inputs.
611 function HiddenInputs($query_args, $pfx = false, $exclude = array())
615 foreach ($query_args as $key => $val) {
616 if (in_array($key, $exclude)) continue;
617 $name = $pfx ? $pfx . "[$key]" : $key;
619 $inputs->pushContent(HiddenInputs($val, $name));
621 $inputs->pushContent(HTML::input(array('type' => 'hidden',
628 /** Generate a <script> tag containing javascript.
630 * @param string $js The javascript.
631 * @param array $script_args (optional) hash of script tags options
632 * e.g. to provide another version or the defer attr
633 * @return HtmlElement A <script> element.
635 function JavaScript($js, $script_args = array())
637 $default_script_args = array('type' => 'text/javascript');
638 $script_args = $script_args ? array_merge($default_script_args, $script_args)
639 : $default_script_args;
641 return HTML(HTML::script($script_args), "\n");
643 return HTML(HTML::script($script_args,
644 new RawXml((ENABLE_XHTML_XML ? "\n//<![CDATA[" : "\n<!--//")
645 . "\n" . trim($js) . "\n"
646 . (ENABLE_XHTML_XML ? "//]]>\n" : "// -->"))), "\n");
649 /** Conditionally display content based of whether javascript is supported.
651 * This conditionally (on the client side) displays one of two alternate
652 * contents depending on whether the client supports javascript.
655 * The content you pass as arguments to this function must be block-level.
656 * (This is because the <noscript> tag is block-level.)
658 * @param mixed $if_content Content to display if the browser supports
661 * @param mixed $else_content Content to display if the browser does
662 * not support javascript.
666 function IfJavaScript($if_content = false, $else_content = false)
670 $xml = AsXML($if_content);
671 $js = sprintf('document.write("%s");',
672 addcslashes($xml, "\0..\37!@\\\177..\377"));
673 $html[] = JavaScript($js);
676 $html[] = HTML::noscript(false, $else_content);