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 * php-5.3 uses now HtmlElement5.php with public static
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;
130 function HTML( /* $content, ... */)
132 return new XmlContent(func_get_args());
135 class HTML extends HtmlElement
137 function raw($html_text)
139 return new RawXml($html_text);
142 function getTagProperties($tag)
144 $props = &$GLOBALS['HTML_TagProperties'];
145 return isset($props[$tag]) ? $props[$tag] : 0;
148 function _setTagProperty($prop_flag, $tags)
150 $props = &$GLOBALS['HTML_TagProperties'];
151 if (is_string($tags))
152 $tags = preg_split('/\s+/', $tags);
153 foreach ($tags as $tag) {
156 if (isset($props[$tag]))
157 $props[$tag] |= $prop_flag;
159 $props[$tag] = $prop_flag;
163 // See admin/mkfuncs shell script to generate the following static methods
165 function link( /*...*/)
167 $el = new HtmlElement('link');
168 return $el->_init2(func_get_args());
171 function meta( /*...*/)
173 $el = new HtmlElement('meta');
174 return $el->_init2(func_get_args());
177 function style( /*...*/)
179 $el = new HtmlElement('style');
180 return $el->_init2(func_get_args());
183 function script( /*...*/)
185 $el = new HtmlElement('script');
186 return $el->_init2(func_get_args());
189 function noscript( /*...*/)
191 $el = new HtmlElement('noscript');
192 return $el->_init2(func_get_args());
195 /****************************************/
198 $el = new HtmlElement('a');
199 return $el->_init2(func_get_args());
202 function img( /*...*/)
204 $el = new HtmlElement('img');
205 return $el->_init2(func_get_args());
208 function br( /*...*/)
210 $el = new HtmlElement('br');
211 return $el->_init2(func_get_args());
214 function span( /*...*/)
216 $el = new HtmlElement('span');
217 return $el->_init2(func_get_args());
220 /****************************************/
221 function h1( /*...*/)
223 $el = new HtmlElement('h1');
224 return $el->_init2(func_get_args());
227 function h2( /*...*/)
229 $el = new HtmlElement('h2');
230 return $el->_init2(func_get_args());
233 function h3( /*...*/)
235 $el = new HtmlElement('h3');
236 return $el->_init2(func_get_args());
239 function h4( /*...*/)
241 $el = new HtmlElement('h4');
242 return $el->_init2(func_get_args());
245 function h5( /*...*/)
247 $el = new HtmlElement('h5');
248 return $el->_init2(func_get_args());
251 function h6( /*...*/)
253 $el = new HtmlElement('h6');
254 return $el->_init2(func_get_args());
257 /****************************************/
258 function hr( /*...*/)
260 $el = new HtmlElement('hr');
261 return $el->_init2(func_get_args());
264 function div( /*...*/)
266 $el = new HtmlElement('div');
267 return $el->_init2(func_get_args());
272 $el = new HtmlElement('p');
273 return $el->_init2(func_get_args());
276 function pre( /*...*/)
278 $el = new HtmlElement('pre');
279 return $el->_init2(func_get_args());
282 function blockquote( /*...*/)
284 $el = new HtmlElement('blockquote');
285 return $el->_init2(func_get_args());
288 /****************************************/
289 function em( /*...*/)
291 $el = new HtmlElement('em');
292 return $el->_init2(func_get_args());
295 function strong( /*...*/)
297 $el = new HtmlElement('strong');
298 return $el->_init2(func_get_args());
301 function small( /*...*/)
303 $el = new HtmlElement('small');
304 return $el->_init2(func_get_args());
307 /****************************************/
308 function tt( /*...*/)
310 $el = new HtmlElement('tt');
311 return $el->_init2(func_get_args());
316 $el = new HtmlElement('u');
317 return $el->_init2(func_get_args());
320 function sup( /*...*/)
322 $el = new HtmlElement('sup');
323 return $el->_init2(func_get_args());
326 function sub( /*...*/)
328 $el = new HtmlElement('sub');
329 return $el->_init2(func_get_args());
332 /****************************************/
333 function ul( /*...*/)
335 $el = new HtmlElement('ul');
336 return $el->_init2(func_get_args());
339 function ol( /*...*/)
341 $el = new HtmlElement('ol');
342 return $el->_init2(func_get_args());
345 function dl( /*...*/)
347 $el = new HtmlElement('dl');
348 return $el->_init2(func_get_args());
351 function li( /*...*/)
353 $el = new HtmlElement('li');
354 return $el->_init2(func_get_args());
357 function dt( /*...*/)
359 $el = new HtmlElement('dt');
360 return $el->_init2(func_get_args());
363 function dd( /*...*/)
365 $el = new HtmlElement('dd');
366 return $el->_init2(func_get_args());
369 /****************************************/
370 function table( /*...*/)
372 $el = new HtmlElement('table');
373 return $el->_init2(func_get_args());
376 function caption( /*...*/)
378 $el = new HtmlElement('caption');
379 return $el->_init2(func_get_args());
382 function thead( /*...*/)
384 $el = new HtmlElement('thead');
385 return $el->_init2(func_get_args());
388 function tbody( /*...*/)
390 $el = new HtmlElement('tbody');
391 return $el->_init2(func_get_args());
394 function tfoot( /*...*/)
396 $el = new HtmlElement('tfoot');
397 return $el->_init2(func_get_args());
400 function tr( /*...*/)
402 $el = new HtmlElement('tr');
403 return $el->_init2(func_get_args());
406 function td( /*...*/)
408 $el = new HtmlElement('td');
409 return $el->_init2(func_get_args());
412 function th( /*...*/)
414 $el = new HtmlElement('th');
415 return $el->_init2(func_get_args());
418 function colgroup( /*...*/)
420 $el = new HtmlElement('colgroup');
421 return $el->_init2(func_get_args());
424 function col( /*...*/)
426 $el = new HtmlElement('col');
427 return $el->_init2(func_get_args());
430 /****************************************/
431 function form( /*...*/)
433 $el = new HtmlElement('form');
434 return $el->_init2(func_get_args());
437 function input( /*...*/)
439 $el = new HtmlElement('input');
440 return $el->_init2(func_get_args());
443 function button( /*...*/)
445 $el = new HtmlElement('button');
446 return $el->_init2(func_get_args());
449 function option( /*...*/)
451 $el = new HtmlElement('option');
452 return $el->_init2(func_get_args());
455 function select( /*...*/)
457 $el = new HtmlElement('select');
458 return $el->_init2(func_get_args());
461 function textarea( /*...*/)
463 $el = new HtmlElement('textarea');
464 return $el->_init2(func_get_args());
467 function label( /*...*/)
469 $el = new HtmlElement('label');
470 return $el->_init2(func_get_args());
473 /****************************************/
474 function area( /*...*/)
476 $el = new HtmlElement('area');
477 return $el->_init2(func_get_args());
480 function map( /*...*/)
482 $el = new HtmlElement('map');
483 return $el->_init2(func_get_args());
486 function frame( /*...*/)
488 $el = new HtmlElement('frame');
489 return $el->_init2(func_get_args());
492 function frameset( /*...*/)
494 $el = new HtmlElement('frameset');
495 return $el->_init2(func_get_args());
498 function iframe( /*...*/)
500 $el = new HtmlElement('iframe');
501 return $el->_init2(func_get_args());
504 function nobody( /*...*/)
506 $el = new HtmlElement('nobody');
507 return $el->_init2(func_get_args());
510 function object( /*...*/)
512 $el = new HtmlElement('object');
513 return $el->_init2(func_get_args());
516 function embed( /*...*/)
518 $el = new HtmlElement('embed');
519 return $el->_init2(func_get_args());
522 function param( /*...*/)
524 $el = new HtmlElement('param');
525 return $el->_init2(func_get_args());
528 function fieldset( /*...*/)
530 $el = new HtmlElement('fieldset');
531 return $el->_init2(func_get_args());
534 function legend( /*...*/)
536 $el = new HtmlElement('legend');
537 return $el->_init2(func_get_args());
540 /****************************************/
541 function video( /*...*/)
543 $el = new HtmlElement('video');
544 return $el->_init2(func_get_args());
548 define('HTMLTAG_EMPTY', 1);
549 define('HTMLTAG_INLINE', 2);
550 define('HTMLTAG_ACCEPTS_INLINE', 4);
552 HTML::_setTagProperty(HTMLTAG_EMPTY,
553 'area base basefont br col frame hr img input isindex link meta param');
554 HTML::_setTagProperty(HTMLTAG_ACCEPTS_INLINE,
556 'b big i small tt ' // %fontstyle
557 . 's strike u ' // (deprecated)
558 . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
559 . 'a img object embed br script map q sub sup span bdo ' //%special
560 . 'button input label option select textarea label ' //%formctl
562 // %block elements which contain inline content
563 . 'address h1 h2 h3 h4 h5 h6 p pre '
564 // %block elements which contain either block or inline content
565 . 'div fieldset frameset'
567 // other with inline content
568 . 'caption dt label legend video '
569 // other with either inline or block
570 . 'dd del ins li td th colgroup');
572 HTML::_setTagProperty(HTMLTAG_INLINE,
574 'b big i small tt ' // %fontstyle
575 . 's strike u ' // (deprecated)
576 . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
577 . 'a img object br script map q sub sup span bdo ' //%special
578 . 'button input label option select textarea ' //%formctl
583 * Generate hidden form input fields.
585 * @param $query_args hash A hash mapping names to values for the hidden inputs.
586 * Values in the hash can themselves be hashes. The will result in hidden inputs
587 * which will reconstruct the nested structure in the resulting query args as
592 * $args = array('x' => '2',
593 * 'y' => array('a' => 'aval', 'b' => 'bval'));
594 * $inputs = HiddenInputs($args);
598 * <input type="hidden" name="x" value = "2" />
599 * <input type="hidden" name="y[a]" value = "aval" />
600 * <input type="hidden" name="y[b]" value = "bval" />
602 * @return object An XmlContent object containing the inputs.
604 function HiddenInputs($query_args, $pfx = false, $exclude = array())
608 foreach ($query_args as $key => $val) {
609 if (in_array($key, $exclude)) continue;
610 $name = $pfx ? $pfx . "[$key]" : $key;
612 $inputs->pushContent(HiddenInputs($val, $name));
614 $inputs->pushContent(HTML::input(array('type' => 'hidden',
621 /** Generate a <script> tag containing javascript.
623 * @param string $js The javascript.
624 * @param string $script_args (optional) hash of script tags options
625 * e.g. to provide another version or the defer attr
626 * @return HtmlElement A <script> element.
628 function JavaScript($js, $script_args = false)
630 $default_script_args = array( //'version' => 'JavaScript', // not xhtml conformant
631 'type' => 'text/javascript');
632 $script_args = $script_args ? array_merge($default_script_args, $script_args)
633 : $default_script_args;
635 return HTML(HTML::script($script_args), "\n");
637 // see http://devedge.netscape.com/viewsource/2003/xhtml-style-script/
638 return HTML(HTML::script($script_args,
639 new RawXml((ENABLE_XHTML_XML ? "\n//<![CDATA[" : "\n<!--//")
640 . "\n" . trim($js) . "\n"
641 . (ENABLE_XHTML_XML ? "//]]>\n" : "// -->"))), "\n");
644 /** Conditionally display content based of whether javascript is supported.
646 * This conditionally (on the client side) displays one of two alternate
647 * contents depending on whether the client supports javascript.
650 * The content you pass as arguments to this function must be block-level.
651 * (This is because the <noscript> tag is block-level.)
653 * @param mixed $if_content Content to display if the browser supports
656 * @param mixed $else_content Content to display if the browser does
657 * not support javascript.
661 function IfJavaScript($if_content = false, $else_content = false)
665 $xml = AsXML($if_content);
666 $js = sprintf('document.write("%s");',
667 addcslashes($xml, "\0..\37!@\\\177..\377"));
668 $html[] = JavaScript($js);
671 $html[] = HTML::noscript(false, $else_content);
680 // c-hanging-comment-ender-p: nil
681 // indent-tabs-mode: nil