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
20 function __construct($tagname /* , $attr_or_content , ...*/)
22 $this->_init(func_get_args());
23 $this->_properties = HTML::getTagProperties($tagname);
29 $args = func_get_args();
31 assert(count($args) >= 1);
32 assert(is_string($args[0]));
33 $this->_tag = array_shift($args);
35 if ($args && is_array($args[0]))
36 $this->_attr = array_shift($args);
38 $this->_attr = array();
39 if ($args && $args[0] === false)
42 $this->setContent($args);
43 $this->_properties = HTML::getTagProperties($this->_tag);
47 * This is used by the static factory methods is class HTML.
49 protected function _init2($args)
52 if (is_array($args[0]))
53 $this->_attr = array_shift($args);
54 elseif ($args[0] === false)
58 if (count($args) == 1 && is_array($args[0]))
60 $this->_content = $args;
64 /** Add a "tooltip" to an element.
66 * @param string $tooltip_text The tooltip text.
67 * @param string $accesskey.
69 function addTooltip($tooltip_text, $accesskey = '')
71 $this->setAttr('title', $tooltip_text);
72 if ($accesskey) $this->setAccesskey($accesskey);
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;");
82 function setAccesskey($key)
85 if (strlen($key) != 1) return;
86 $this->setAttr("accesskey", $key);
88 if (!empty($this->_attr['title'])) {
89 if (preg_match("/\[(alt-)?(.)\]$/", $this->_attr['title'], $m)) {
90 $this->_attr['title'] = preg_replace
92 "[" . $WikiTheme->tooltipAccessKeyPrefix() . "-\\2]",
93 $this->_attr['title']);
95 $this->_attr['title'] .=
96 " [" . $WikiTheme->tooltipAccessKeyPrefix() . "-$key]";
99 $this->_attr['title'] =
100 "[" . $WikiTheme->tooltipAccessKeyPrefix() . "-$key]";
106 if (($this->_properties & HTMLTAG_EMPTY) == 0)
107 return $this->startTag() . "</$this->_tag>";
109 return substr($this->startTag(), 0, -1) . " />";
112 function hasInlineContent()
114 return ($this->_properties & HTMLTAG_ACCEPTS_INLINE) != 0;
117 function isInlineElement()
119 return ($this->_properties & HTMLTAG_INLINE) != 0;
123 function HTML( /* $content, ... */)
125 return new XmlContent(func_get_args());
128 class HTML extends HtmlElement
130 public static function raw($html_text)
132 return new RawXml($html_text);
135 public static function getTagProperties($tag)
137 $props = &$GLOBALS['HTML_TagProperties'];
138 return isset($props[$tag]) ? $props[$tag] : 0;
141 public static function _setTagProperty($prop_flag, $tags)
143 $props = &$GLOBALS['HTML_TagProperties'];
144 if (is_string($tags))
145 $tags = preg_split('/\s+/', $tags);
146 foreach ($tags as $tag) {
149 if (isset($props[$tag]))
150 $props[$tag] |= $prop_flag;
152 $props[$tag] = $prop_flag;
156 // See admin/mkfuncs shell script to generate the following static methods
158 public static function link( /*...*/)
160 $el = new HtmlElement('link');
161 return $el->_init2(func_get_args());
164 public static function meta( /*...*/)
166 $el = new HtmlElement('meta');
167 return $el->_init2(func_get_args());
170 public static function style( /*...*/)
172 $el = new HtmlElement('style');
173 return $el->_init2(func_get_args());
176 public static function script( /*...*/)
178 $el = new HtmlElement('script');
179 return $el->_init2(func_get_args());
182 public static function noscript( /*...*/)
184 $el = new HtmlElement('noscript');
185 return $el->_init2(func_get_args());
188 /****************************************/
189 public static function a( /*...*/)
191 $el = new HtmlElement('a');
192 return $el->_init2(func_get_args());
195 public static function img( /*...*/)
197 $el = new HtmlElement('img');
198 return $el->_init2(func_get_args());
201 public static function br( /*...*/)
203 $el = new HtmlElement('br');
204 return $el->_init2(func_get_args());
207 public static function span( /*...*/)
209 $el = new HtmlElement('span');
210 return $el->_init2(func_get_args());
213 /****************************************/
214 public static function h1( /*...*/)
216 $el = new HtmlElement('h1');
217 return $el->_init2(func_get_args());
220 public static function h2( /*...*/)
222 $el = new HtmlElement('h2');
223 return $el->_init2(func_get_args());
226 public static function h3( /*...*/)
228 $el = new HtmlElement('h3');
229 return $el->_init2(func_get_args());
232 public static function h4( /*...*/)
234 $el = new HtmlElement('h4');
235 return $el->_init2(func_get_args());
238 public static function h5( /*...*/)
240 $el = new HtmlElement('h5');
241 return $el->_init2(func_get_args());
244 public static function h6( /*...*/)
246 $el = new HtmlElement('h6');
247 return $el->_init2(func_get_args());
250 /****************************************/
251 public static function hr( /*...*/)
253 $el = new HtmlElement('hr');
254 return $el->_init2(func_get_args());
257 public static function div( /*...*/)
259 $el = new HtmlElement('div');
260 return $el->_init2(func_get_args());
263 public static function p( /*...*/)
265 $el = new HtmlElement('p');
266 return $el->_init2(func_get_args());
269 public static function pre( /*...*/)
271 $el = new HtmlElement('pre');
272 return $el->_init2(func_get_args());
275 public static function blockquote( /*...*/)
277 $el = new HtmlElement('blockquote');
278 return $el->_init2(func_get_args());
281 /****************************************/
282 public static function em( /*...*/)
284 $el = new HtmlElement('em');
285 return $el->_init2(func_get_args());
288 public static function strong( /*...*/)
290 $el = new HtmlElement('strong');
291 return $el->_init2(func_get_args());
294 public static function small( /*...*/)
296 $el = new HtmlElement('small');
297 return $el->_init2(func_get_args());
300 public static function abbr( /*...*/)
302 $el = new HtmlElement('abbr');
303 return $el->_init2(func_get_args());
306 public static function acronym( /*...*/)
308 $el = new HtmlElement('acronym');
309 return $el->_init2(func_get_args());
312 public static function cite( /*...*/)
314 $el = new HtmlElement('cite');
315 return $el->_init2(func_get_args());
318 public static function code( /*...*/)
320 $el = new HtmlElement('code');
321 return $el->_init2(func_get_args());
324 public static function dfn( /*...*/)
326 $el = new HtmlElement('dfn');
327 return $el->_init2(func_get_args());
330 public static function kbd( /*...*/)
332 $el = new HtmlElement('kbd');
333 return $el->_init2(func_get_args());
336 public static function samp( /*...*/)
338 $el = new HtmlElement('samp');
339 return $el->_init2(func_get_args());
342 /****************************************/
343 public static function tt( /*...*/)
345 $el = new HtmlElement('tt');
346 return $el->_init2(func_get_args());
349 public static function u( /*...*/)
351 $el = new HtmlElement('u');
352 return $el->_init2(func_get_args());
355 public static function sup( /*...*/)
357 $el = new HtmlElement('sup');
358 return $el->_init2(func_get_args());
361 public static function sub( /*...*/)
363 $el = new HtmlElement('sub');
364 return $el->_init2(func_get_args());
367 /****************************************/
368 public static function ul( /*...*/)
370 $el = new HtmlElement('ul');
371 return $el->_init2(func_get_args());
374 public static function ol( /*...*/)
376 $el = new HtmlElement('ol');
377 return $el->_init2(func_get_args());
380 public static function dl( /*...*/)
382 $el = new HtmlElement('dl');
383 return $el->_init2(func_get_args());
386 public static function li( /*...*/)
388 $el = new HtmlElement('li');
389 return $el->_init2(func_get_args());
392 public static function dt( /*...*/)
394 $el = new HtmlElement('dt');
395 return $el->_init2(func_get_args());
398 public static function dd( /*...*/)
400 $el = new HtmlElement('dd');
401 return $el->_init2(func_get_args());
404 /****************************************/
405 public static function table( /*...*/)
407 $el = new HtmlElement('table');
408 return $el->_init2(func_get_args());
411 public static function caption( /*...*/)
413 $el = new HtmlElement('caption');
414 return $el->_init2(func_get_args());
417 public static function thead( /*...*/)
419 $el = new HtmlElement('thead');
420 return $el->_init2(func_get_args());
423 public static function tbody( /*...*/)
425 $el = new HtmlElement('tbody');
426 return $el->_init2(func_get_args());
429 public static function tfoot( /*...*/)
431 $el = new HtmlElement('tfoot');
432 return $el->_init2(func_get_args());
435 public static function tr( /*...*/)
437 $el = new HtmlElement('tr');
438 return $el->_init2(func_get_args());
441 public static function td( /*...*/)
443 $el = new HtmlElement('td');
444 return $el->_init2(func_get_args());
447 public static function th( /*...*/)
449 $el = new HtmlElement('th');
450 return $el->_init2(func_get_args());
453 public static function colgroup( /*...*/)
455 $el = new HtmlElement('colgroup');
456 return $el->_init2(func_get_args());
459 public static function col( /*...*/)
461 $el = new HtmlElement('col');
462 return $el->_init2(func_get_args());
465 /****************************************/
466 public static function form( /*...*/)
468 $el = new HtmlElement('form');
469 return $el->_init2(func_get_args());
472 public static function input( /*...*/)
474 $el = new HtmlElement('input');
475 return $el->_init2(func_get_args());
478 public static function button( /*...*/)
480 $el = new HtmlElement('button');
481 return $el->_init2(func_get_args());
484 public static function option( /*...*/)
486 $el = new HtmlElement('option');
487 return $el->_init2(func_get_args());
490 public static function select( /*...*/)
492 $el = new HtmlElement('select');
493 return $el->_init2(func_get_args());
496 public static function textarea( /*...*/)
498 $el = new HtmlElement('textarea');
499 return $el->_init2(func_get_args());
502 public static function label( /*...*/)
504 $el = new HtmlElement('label');
505 return $el->_init2(func_get_args());
508 /****************************************/
509 public static function area( /*...*/)
511 $el = new HtmlElement('area');
512 return $el->_init2(func_get_args());
515 public static function map( /*...*/)
517 $el = new HtmlElement('map');
518 return $el->_init2(func_get_args());
521 public static function iframe( /*...*/)
523 $el = new HtmlElement('iframe');
524 return $el->_init2(func_get_args());
527 public static function nobody( /*...*/)
529 $el = new HtmlElement('nobody');
530 return $el->_init2(func_get_args());
533 public static function object( /*...*/)
535 $el = new HtmlElement('object');
536 return $el->_init2(func_get_args());
539 public static function embed( /*...*/)
541 $el = new HtmlElement('embed');
542 return $el->_init2(func_get_args());
545 public static function param( /*...*/)
547 $el = new HtmlElement('param');
548 return $el->_init2(func_get_args());
551 public static function fieldset( /*...*/)
553 $el = new HtmlElement('fieldset');
554 return $el->_init2(func_get_args());
557 public static function legend( /*...*/)
559 $el = new HtmlElement('legend');
560 return $el->_init2(func_get_args());
563 /****************************************/
564 public static function video( /*...*/)
566 $el = new HtmlElement('video');
567 return $el->_init2(func_get_args());
571 define('HTMLTAG_EMPTY', 1);
572 define('HTMLTAG_INLINE', 2);
573 define('HTMLTAG_ACCEPTS_INLINE', 4);
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,
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
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
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');
595 HTML::_setTagProperty(HTMLTAG_INLINE,
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
606 * Generate hidden form input fields.
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
615 * $args = array('x' => '2',
616 * 'y' => array('a' => 'aval', 'b' => 'bval'));
617 * $inputs = HiddenInputs($args);
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" />
626 * @param array $exclude
627 * @return object An XmlContent object containing the inputs.
629 function HiddenInputs($query_args, $pfx = false, $exclude = array())
633 foreach ($query_args as $key => $val) {
634 if (in_array($key, $exclude)) continue;
635 $name = $pfx ? $pfx . "[$key]" : $key;
637 $inputs->pushContent(HiddenInputs($val, $name));
639 $inputs->pushContent(HTML::input(array('type' => 'hidden',
646 /** Generate a <script> tag containing javascript.
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.
653 function JavaScript($js, $script_args = array())
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;
660 return HTML(HTML::script($script_args), "\n");
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");
669 /** Conditionally display content based of whether javascript is supported.
671 * This conditionally (on the client side) displays one of two alternate
672 * contents depending on whether the client supports javascript.
675 * The content you pass as arguments to this function must be block-level.
676 * (This is because the <noscript> tag is block-level.)
678 * @param mixed $if_content Content to display if the browser supports
681 * @param mixed $else_content Content to display if the browser does
682 * not support javascript.
686 function IfJavaScript($if_content = false, $else_content = false)
690 $xml = AsXML($if_content);
691 $js = sprintf('document.write("%s");',
692 addcslashes($xml, "\0..\37!@\\\177..\377"));
693 $html[] = JavaScript($js);
696 $html[] = HTML::noscript(false, $else_content);
705 // c-hanging-comment-ender-p: nil
706 // indent-tabs-mode: nil