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
8 if (!class_exists("XmlElement"))
9 require_once(dirname(__FILE__)."/XmlElement.php");
10 if (class_exists("HtmlElement"))
16 //apd_set_session_trace(35);
18 class HtmlElement extends XmlElement
20 function __construct ($tagname /* , $attr_or_content , ...*/) {
21 $this->_init(func_get_args());
22 $this->_properties = HTML::getTagProperties($tagname);
25 function _init ($args) {
27 $args = func_get_args();
29 assert(count($args) >= 1);
30 assert(is_string($args[0]));
31 $this->_tag = array_shift($args);
33 if ($args && is_array($args[0]))
34 $this->_attr = array_shift($args);
36 $this->_attr = array();
37 if ($args && $args[0] === false)
40 $this->setContent($args);
41 $this->_properties = HTML::getTagProperties($this->_tag);
46 * This is used by the static factory methods is class HTML.
48 function _init2 ($args) {
50 if (is_array($args[0]))
51 $this->_attr = array_shift($args);
52 elseif ($args[0] === false)
56 if (count($args) == 1 && is_array($args[0]))
58 $this->_content = $args;
62 /** Add a "tooltip" to an element.
64 * @param $tooltip_text string The tooltip text.
66 function addTooltip ($tooltip_text, $accesskey = null) {
67 $this->setAttr('title', $tooltip_text);
68 if ($accesskey) $this->setAccesskey($accesskey);
70 // FIXME: this should be initialized from title by an onLoad() function.
71 // (though, that may not be possible.)
72 $qtooltip = str_replace("'", "\\'", $tooltip_text);
73 $this->setAttr('onmouseover',
74 sprintf('window.status="%s"; return true;',
75 addslashes($tooltip_text)));
76 $this->setAttr('onmouseout', "window.status='';return true;");
79 function setAccesskey ($key) {
81 if (strlen($key) != 1) return;
82 $this->setAttr("accesskey", $key);
84 if (!empty($this->_attr['title'])) {
85 if (preg_match("/\[(alt-)?(.)\]$/", $this->_attr['title'], $m))
87 $this->_attr['title'] = preg_replace("/\[(alt-)?(.)\]$/", "[".$WikiTheme->tooltipAccessKeyPrefix()."-\\2]", $this->_attr['title']);
89 $this->_attr['title'] .= " [".$WikiTheme->tooltipAccessKeyPrefix()."-$key]";
92 $this->_attr['title'] = "[".$WikiTheme->tooltipAccessKeyPrefix()."-$key]";
96 function emptyTag () {
97 if (($this->_properties & HTMLTAG_EMPTY) == 0)
98 return $this->startTag() . "</$this->_tag>";
100 return substr($this->startTag(), 0, -1) . " />";
103 function hasInlineContent () {
104 return ($this->_properties & HTMLTAG_ACCEPTS_INLINE) != 0;
107 function isInlineElement () {
108 return ($this->_properties & HTMLTAG_INLINE) != 0;
112 function HTML (/* $content, ... */) {
113 return new XmlContent(func_get_args());
116 class HTML extends HtmlElement {
117 function raw ($html_text) {
118 return new RawXml($html_text);
121 function getTagProperties($tag) {
122 $props = &$GLOBALS['HTML_TagProperties'];
123 return isset($props[$tag]) ? $props[$tag] : 0;
126 function _setTagProperty($prop_flag, $tags) {
127 $props = &$GLOBALS['HTML_TagProperties'];
128 if (is_string($tags))
129 $tags = preg_split('/\s+/', $tags);
130 foreach ($tags as $tag) {
133 if (isset($props[$tag]))
134 $props[$tag] |= $prop_flag;
136 $props[$tag] = $prop_flag;
141 // Shell script to generate the following static methods:
144 // function mkfuncs () {
147 // echo " function $tag (/*...*/) {"
148 // echo " \$el = new HtmlElement('$tag');"
149 // echo " return \$el->_init2(func_get_args());"
154 // /****************************************/'
155 // mkfuncs link meta style script noscript
157 // mkfuncs a img br span
159 // mkfuncs h1 h2 h3 h4 h5 h6
161 // mkfuncs hr div p pre blockquote
163 // mkfuncs em strong small
165 // mkfuncs tt u sup sub
167 // mkfuncs ul ol dl li dt dd
169 // mkfuncs table caption thead tbody tfoot tr td th colgroup col
171 // mkfuncs form input option select textarea
173 // mkfuncs area map frame frameset iframe nobody
175 function link (/*...*/) {
176 $el = new HtmlElement('link');
177 return $el->_init2(func_get_args());
179 function meta (/*...*/) {
180 $el = new HtmlElement('meta');
181 return $el->_init2(func_get_args());
183 function style (/*...*/) {
184 $el = new HtmlElement('style');
185 return $el->_init2(func_get_args());
187 function script (/*...*/) {
188 $el = new HtmlElement('script');
189 return $el->_init2(func_get_args());
191 function noscript (/*...*/) {
192 $el = new HtmlElement('noscript');
193 return $el->_init2(func_get_args());
196 /****************************************/
197 function a (/*...*/) {
198 $el = new HtmlElement('a');
199 return $el->_init2(func_get_args());
201 function img (/*...*/) {
202 $el = new HtmlElement('img');
203 return $el->_init2(func_get_args());
205 function br (/*...*/) {
206 $el = new HtmlElement('br');
207 return $el->_init2(func_get_args());
209 function span (/*...*/) {
210 $el = new HtmlElement('span');
211 return $el->_init2(func_get_args());
214 /****************************************/
215 function h1 (/*...*/) {
216 $el = new HtmlElement('h1');
217 return $el->_init2(func_get_args());
219 function h2 (/*...*/) {
220 $el = new HtmlElement('h2');
221 return $el->_init2(func_get_args());
223 function h3 (/*...*/) {
224 $el = new HtmlElement('h3');
225 return $el->_init2(func_get_args());
227 function h4 (/*...*/) {
228 $el = new HtmlElement('h4');
229 return $el->_init2(func_get_args());
231 function h5 (/*...*/) {
232 $el = new HtmlElement('h5');
233 return $el->_init2(func_get_args());
235 function h6 (/*...*/) {
236 $el = new HtmlElement('h6');
237 return $el->_init2(func_get_args());
240 /****************************************/
241 function hr (/*...*/) {
242 $el = new HtmlElement('hr');
243 return $el->_init2(func_get_args());
245 function div (/*...*/) {
246 $el = new HtmlElement('div');
247 return $el->_init2(func_get_args());
249 function p (/*...*/) {
250 $el = new HtmlElement('p');
251 return $el->_init2(func_get_args());
253 function pre (/*...*/) {
254 $el = new HtmlElement('pre');
255 return $el->_init2(func_get_args());
257 function blockquote (/*...*/) {
258 $el = new HtmlElement('blockquote');
259 return $el->_init2(func_get_args());
262 /****************************************/
263 function em (/*...*/) {
264 $el = new HtmlElement('em');
265 return $el->_init2(func_get_args());
267 function strong (/*...*/) {
268 $el = new HtmlElement('strong');
269 return $el->_init2(func_get_args());
271 function small (/*...*/) {
272 $el = new HtmlElement('small');
273 return $el->_init2(func_get_args());
276 /****************************************/
277 function tt (/*...*/) {
278 $el = new HtmlElement('tt');
279 return $el->_init2(func_get_args());
281 function u (/*...*/) {
282 $el = new HtmlElement('u');
283 return $el->_init2(func_get_args());
285 function sup (/*...*/) {
286 $el = new HtmlElement('sup');
287 return $el->_init2(func_get_args());
289 function sub (/*...*/) {
290 $el = new HtmlElement('sub');
291 return $el->_init2(func_get_args());
294 /****************************************/
295 function ul (/*...*/) {
296 $el = new HtmlElement('ul');
297 return $el->_init2(func_get_args());
299 function ol (/*...*/) {
300 $el = new HtmlElement('ol');
301 return $el->_init2(func_get_args());
303 function dl (/*...*/) {
304 $el = new HtmlElement('dl');
305 return $el->_init2(func_get_args());
307 function li (/*...*/) {
308 $el = new HtmlElement('li');
309 return $el->_init2(func_get_args());
311 function dt (/*...*/) {
312 $el = new HtmlElement('dt');
313 return $el->_init2(func_get_args());
315 function dd (/*...*/) {
316 $el = new HtmlElement('dd');
317 return $el->_init2(func_get_args());
320 /****************************************/
321 function table (/*...*/) {
322 $el = new HtmlElement('table');
323 return $el->_init2(func_get_args());
325 function caption (/*...*/) {
326 $el = new HtmlElement('caption');
327 return $el->_init2(func_get_args());
329 function thead (/*...*/) {
330 $el = new HtmlElement('thead');
331 return $el->_init2(func_get_args());
333 function tbody (/*...*/) {
334 $el = new HtmlElement('tbody');
335 return $el->_init2(func_get_args());
337 function tfoot (/*...*/) {
338 $el = new HtmlElement('tfoot');
339 return $el->_init2(func_get_args());
341 function tr (/*...*/) {
342 $el = new HtmlElement('tr');
343 return $el->_init2(func_get_args());
345 function td (/*...*/) {
346 $el = new HtmlElement('td');
347 return $el->_init2(func_get_args());
349 function th (/*...*/) {
350 $el = new HtmlElement('th');
351 return $el->_init2(func_get_args());
353 function colgroup (/*...*/) {
354 $el = new HtmlElement('colgroup');
355 return $el->_init2(func_get_args());
357 function col (/*...*/) {
358 $el = new HtmlElement('col');
359 return $el->_init2(func_get_args());
362 /****************************************/
363 function form (/*...*/) {
364 $el = new HtmlElement('form');
365 return $el->_init2(func_get_args());
367 function input (/*...*/) {
368 $el = new HtmlElement('input');
369 return $el->_init2(func_get_args());
371 function button (/*...*/) {
372 $el = new HtmlElement('button');
373 return $el->_init2(func_get_args());
375 function option (/*...*/) {
376 $el = new HtmlElement('option');
377 return $el->_init2(func_get_args());
379 function select (/*...*/) {
380 $el = new HtmlElement('select');
381 return $el->_init2(func_get_args());
383 function textarea (/*...*/) {
384 $el = new HtmlElement('textarea');
385 return $el->_init2(func_get_args());
387 function label (/*...*/) {
388 $el = new HtmlElement('label');
389 return $el->_init2(func_get_args());
392 /****************************************/
393 function area (/*...*/) {
394 $el = new HtmlElement('area');
395 return $el->_init2(func_get_args());
397 function map (/*...*/) {
398 $el = new HtmlElement('map');
399 return $el->_init2(func_get_args());
401 function frame (/*...*/) {
402 $el = new HtmlElement('frame');
403 return $el->_init2(func_get_args());
405 function frameset (/*...*/) {
406 $el = new HtmlElement('frameset');
407 return $el->_init2(func_get_args());
409 function iframe (/*...*/) {
410 $el = new HtmlElement('iframe');
411 return $el->_init2(func_get_args());
413 function nobody (/*...*/) {
414 $el = new HtmlElement('nobody');
415 return $el->_init2(func_get_args());
417 function object (/*...*/) {
418 $el = new HtmlElement('object');
419 return $el->_init2(func_get_args());
421 function embed (/*...*/) {
422 $el = new HtmlElement('embed');
423 return $el->_init2(func_get_args());
425 function param (/*...*/) {
426 $el = new HtmlElement('param');
427 return $el->_init2(func_get_args());
429 function legend (/*...*/) {
430 $el = new HtmlElement('legend');
431 return $el->_init2(func_get_args());
435 define('HTMLTAG_EMPTY', 1);
436 define('HTMLTAG_INLINE', 2);
437 define('HTMLTAG_ACCEPTS_INLINE', 4);
440 HTML::_setTagProperty(HTMLTAG_EMPTY,
441 'area base basefont br col frame hr img input isindex link meta param');
442 HTML::_setTagProperty(HTMLTAG_ACCEPTS_INLINE,
444 'b big i small tt ' // %fontstyle
445 . 's strike u ' // (deprecated)
446 . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
447 . 'a img object embed br script map q sub sup span bdo '//%special
448 . 'button input label option select textarea label ' //%formctl
450 // %block elements which contain inline content
451 . 'address h1 h2 h3 h4 h5 h6 p pre '
452 // %block elements which contain either block or inline content
453 . 'div fieldset frameset'
455 // other with inline content
456 . 'caption dt label legend '
457 // other with either inline or block
458 . 'dd del ins li td th colgroup');
460 HTML::_setTagProperty(HTMLTAG_INLINE,
462 'b big i small tt ' // %fontstyle
463 . 's strike u ' // (deprecated)
464 . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
465 . 'a img object br script map q sub sup span bdo '//%special
466 . 'button input label option select textarea ' //%formctl
471 * Generate hidden form input fields.
473 * @param $query_args hash A hash mapping names to values for the hidden inputs.
474 * Values in the hash can themselves be hashes. The will result in hidden inputs
475 * which will reconstruct the nested structure in the resulting query args as
480 * $args = array('x' => '2',
481 * 'y' => array('a' => 'aval', 'b' => 'bval'));
482 * $inputs = HiddenInputs($args);
486 * <input type="hidden" name="x" value = "2" />
487 * <input type="hidden" name="y[a]" value = "aval" />
488 * <input type="hidden" name="y[b]" value = "bval" />
490 * @return object An XmlContent object containing the inputs.
492 function HiddenInputs ($query_args, $pfx = false, $exclude = array()) {
495 foreach ($query_args as $key => $val) {
496 if (in_array($key, $exclude)) continue;
497 $name = $pfx ? $pfx . "[$key]" : $key;
499 $inputs->pushContent(HiddenInputs($val, $name));
501 $inputs->pushContent(HTML::input(array('type' => 'hidden',
509 /** Generate a <script> tag containing javascript.
511 * @param string $js The javascript.
512 * @param string $script_args (optional) hash of script tags options
513 * e.g. to provide another version or the defer attr
514 * @return HtmlElement A <script> element.
516 function JavaScript ($js, $script_args = false) {
517 $default_script_args = array(//'version' => 'JavaScript', // not xhtml conformant
518 'type' => 'text/javascript');
519 $script_args = $script_args ? array_merge($default_script_args, $script_args)
520 : $default_script_args;
522 return HTML(HTML::script($script_args),"\n");
524 // see http://devedge.netscape.com/viewsource/2003/xhtml-style-script/
525 return HTML(HTML::script($script_args,
526 new RawXml((ENABLE_XHTML_XML ? "\n//<![CDATA[" : "\n<!--//")
527 . "\n".trim($js)."\n"
528 . (ENABLE_XHTML_XML ? "//]]>\n" : "// -->"))),"\n");
531 /** Conditionally display content based of whether javascript is supported.
533 * This conditionally (on the client side) displays one of two alternate
534 * contents depending on whether the client supports javascript.
537 * The content you pass as arguments to this function must be block-level.
538 * (This is because the <noscript> tag is block-level.)
540 * @param mixed $if_content Content to display if the browser supports
543 * @param mixed $else_content Content to display if the browser does
544 * not support javascript.
548 function IfJavaScript($if_content = false, $else_content = false) {
551 $xml = AsXML($if_content);
552 $js = sprintf('document.write("%s");',
553 addcslashes($xml, "\0..\37!@\\\177..\377"));
554 $html[] = JavaScript($js);
557 $html[] = HTML::noscript(false, $else_content);
562 // (c-file-style: "gnu")
567 // c-hanging-comment-ender-p: nil
568 // indent-tabs-mode: nil