]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/HtmlElement.php
rename genericQuery to genericSqlQuery
[SourceForge/phpwiki.git] / lib / HtmlElement.php
1 <?php rcs_id('$Id: HtmlElement.php,v 1.41 2004-08-05 17:31:50 rurban Exp $');
2 /**
3  * Code for writing the HTML subset of XML.
4  * @author: Jeff Dairiki
5  *
6  * This code is now php5 compatible. --2004-04-19 23:51:43 rurban
7  */
8 if (!class_exists("XmlElement"))
9     require_once(dirname(__FILE__)."/XmlElement.php");
10 if (class_exists("HtmlElement"))
11     return;
12
13 /**
14  * An XML element.
15  */
16 //apd_set_session_trace(35);
17
18 class HtmlElement extends XmlElement
19 {
20     function __construct ($tagname /* , $attr_or_content , ...*/) {
21         $this->_init(func_get_args());
22         $this->_properties = HTML::getTagProperties($tagname);
23     }
24
25     function _init ($args) {
26         if (!is_array($args))
27             $args = func_get_args();
28
29         assert(count($args) >= 1);
30         assert(is_string($args[0]));
31         $this->_tag = array_shift($args);
32         
33         if ($args && is_array($args[0]))
34             $this->_attr = array_shift($args);
35         else {
36             $this->_attr = array();
37             if ($args && $args[0] === false)
38                 array_shift($args);
39         }
40         $this->setContent($args);
41         $this->_properties = HTML::getTagProperties($this->_tag);
42     }
43
44     /**
45      * @access protected
46      * This is used by the static factory methods is class HTML.
47      */
48     function _init2 ($args) {
49         if ($args) {
50             if (is_array($args[0]))
51                 $this->_attr = array_shift($args);
52             elseif ($args[0] === false)
53                 array_shift($args);
54         }
55         
56         if (count($args) == 1 && is_array($args[0]))
57             $args = $args[0];
58         $this->_content = $args;
59         return $this;
60     }
61
62     /** Add a "tooltip" to an element.
63      *
64      * @param $tooltip_text string The tooltip text.
65      */
66     function addTooltip ($tooltip_text) {
67         $this->setAttr('title', $tooltip_text);
68
69         // FIXME: this should be initialized from title by an onLoad() function.
70         //        (though, that may not be possible.)
71         $qtooltip = str_replace("'", "\\'", $tooltip_text);
72         $this->setAttr('onmouseover',
73                        sprintf('window.status="%s"; return true;',
74                                addslashes($tooltip_text)));
75         $this->setAttr('onmouseout', "window.status='';return true;");
76     }
77
78     function emptyTag () {
79         if (($this->_properties & HTMLTAG_EMPTY) == 0)
80             return $this->startTag() . "</$this->_tag>";
81
82         return substr($this->startTag(), 0, -1) . " />";
83     }
84
85     function hasInlineContent () {
86         return ($this->_properties & HTMLTAG_ACCEPTS_INLINE) != 0;
87     }
88
89     function isInlineElement () {
90         return ($this->_properties & HTMLTAG_INLINE) != 0;
91     }
92 };
93
94 function HTML (/* $content, ... */) {
95     return new XmlContent(func_get_args());
96 }
97
98 class HTML extends HtmlElement {
99     function raw ($html_text) {
100         return new RawXML($html_text);
101     }
102     
103     function getTagProperties($tag) {
104         $props = &$GLOBALS['HTML_TagProperties'];
105         return isset($props[$tag]) ? $props[$tag] : 0;
106     }
107
108     function _setTagProperty($prop_flag, $tags) {
109         $props = &$GLOBALS['HTML_TagProperties'];
110         if (is_string($tags))
111             $tags = preg_split('/\s+/', $tags);
112         foreach ($tags as $tag) {
113             if (isset($props[$tag]))
114                 $props[$tag] |= $prop_flag;
115             else
116                 $props[$tag] = $prop_flag;
117         }
118     }
119
120     //
121     // Shell script to generate the following static methods:
122     //
123     // #!/bin/sh
124     // function mkfuncs () {
125     //     for tag in "$@"
126     //     do
127     //         echo "    function $tag (/*...*/) {"
128     //         echo "        \$el = new HtmlElement('$tag');"
129     //         echo "        return \$el->_init2(func_get_args());"
130     //         echo "    }"
131     //     done
132     // }
133     // d='
134     //     /****************************************/'
135     // mkfuncs link meta style script noscript
136     // echo "$d"
137     // mkfuncs a img br span
138     // echo "$d"
139     // mkfuncs h1 h2 h3 h4 h5 h6
140     // echo "$d"
141     // mkfuncs hr div p pre blockquote
142     // echo "$d"
143     // mkfuncs em strong small
144     // echo "$d"
145     // mkfuncs tt u sup sub
146     // echo "$d"
147     // mkfuncs ul ol dl li dt dd
148     // echo "$d"
149     // mkfuncs table caption thead tbody tfoot tr td th colgroup col
150     // echo "$d"
151     // mkfuncs form input option select textarea
152     // echo "$d"
153     // mkfuncs area map frame frameset iframe nobody
154
155     function link (/*...*/) {
156         $el = new HtmlElement('link');
157         return $el->_init2(func_get_args());
158     }
159     function meta (/*...*/) {
160         $el = new HtmlElement('meta');
161         return $el->_init2(func_get_args());
162     }
163     function style (/*...*/) {
164         $el = new HtmlElement('style');
165         return $el->_init2(func_get_args());
166     }
167     function script (/*...*/) {
168         $el = new HtmlElement('script');
169         return $el->_init2(func_get_args());
170     }
171     function noscript (/*...*/) {
172         $el = new HtmlElement('noscript');
173         return $el->_init2(func_get_args());
174     }
175
176     /****************************************/
177     function a (/*...*/) {
178         $el = new HtmlElement('a');
179         return $el->_init2(func_get_args());
180     }
181     function img (/*...*/) {
182         $el = new HtmlElement('img');
183         return $el->_init2(func_get_args());
184     }
185     function br (/*...*/) {
186         $el = new HtmlElement('br');
187         return $el->_init2(func_get_args());
188     }
189     function span (/*...*/) {
190         $el = new HtmlElement('span');
191         return $el->_init2(func_get_args());
192     }
193
194     /****************************************/
195     function h1 (/*...*/) {
196         $el = new HtmlElement('h1');
197         return $el->_init2(func_get_args());
198     }
199     function h2 (/*...*/) {
200         $el = new HtmlElement('h2');
201         return $el->_init2(func_get_args());
202     }
203     function h3 (/*...*/) {
204         $el = new HtmlElement('h3');
205         return $el->_init2(func_get_args());
206     }
207     function h4 (/*...*/) {
208         $el = new HtmlElement('h4');
209         return $el->_init2(func_get_args());
210     }
211     function h5 (/*...*/) {
212         $el = new HtmlElement('h5');
213         return $el->_init2(func_get_args());
214     }
215     function h6 (/*...*/) {
216         $el = new HtmlElement('h6');
217         return $el->_init2(func_get_args());
218     }
219
220     /****************************************/
221     function hr (/*...*/) {
222         $el = new HtmlElement('hr');
223         return $el->_init2(func_get_args());
224     }
225     function div (/*...*/) {
226         $el = new HtmlElement('div');
227         return $el->_init2(func_get_args());
228     }
229     function p (/*...*/) {
230         $el = new HtmlElement('p');
231         return $el->_init2(func_get_args());
232     }
233     function pre (/*...*/) {
234         $el = new HtmlElement('pre');
235         return $el->_init2(func_get_args());
236     }
237     function blockquote (/*...*/) {
238         $el = new HtmlElement('blockquote');
239         return $el->_init2(func_get_args());
240     }
241
242     /****************************************/
243     function em (/*...*/) {
244         $el = new HtmlElement('em');
245         return $el->_init2(func_get_args());
246     }
247     function strong (/*...*/) {
248         $el = new HtmlElement('strong');
249         return $el->_init2(func_get_args());
250     }
251     function small (/*...*/) {
252         $el = new HtmlElement('small');
253         return $el->_init2(func_get_args());
254     }
255
256     /****************************************/
257     function tt (/*...*/) {
258         $el = new HtmlElement('tt');
259         return $el->_init2(func_get_args());
260     }
261     function u (/*...*/) {
262         $el = new HtmlElement('u');
263         return $el->_init2(func_get_args());
264     }
265     function sup (/*...*/) {
266         $el = new HtmlElement('sup');
267         return $el->_init2(func_get_args());
268     }
269     function sub (/*...*/) {
270         $el = new HtmlElement('sub');
271         return $el->_init2(func_get_args());
272     }
273
274     /****************************************/
275     function ul (/*...*/) {
276         $el = new HtmlElement('ul');
277         return $el->_init2(func_get_args());
278     }
279     function ol (/*...*/) {
280         $el = new HtmlElement('ol');
281         return $el->_init2(func_get_args());
282     }
283     function dl (/*...*/) {
284         $el = new HtmlElement('dl');
285         return $el->_init2(func_get_args());
286     }
287     function li (/*...*/) {
288         $el = new HtmlElement('li');
289         return $el->_init2(func_get_args());
290     }
291     function dt (/*...*/) {
292         $el = new HtmlElement('dt');
293         return $el->_init2(func_get_args());
294     }
295     function dd (/*...*/) {
296         $el = new HtmlElement('dd');
297         return $el->_init2(func_get_args());
298     }
299
300     /****************************************/
301     function table (/*...*/) {
302         $el = new HtmlElement('table');
303         return $el->_init2(func_get_args());
304     }
305     function caption (/*...*/) {
306         $el = new HtmlElement('caption');
307         return $el->_init2(func_get_args());
308     }
309     function thead (/*...*/) {
310         $el = new HtmlElement('thead');
311         return $el->_init2(func_get_args());
312     }
313     function tbody (/*...*/) {
314         $el = new HtmlElement('tbody');
315         return $el->_init2(func_get_args());
316     }
317     function tfoot (/*...*/) {
318         $el = new HtmlElement('tfoot');
319         return $el->_init2(func_get_args());
320     }
321     function tr (/*...*/) {
322         $el = new HtmlElement('tr');
323         return $el->_init2(func_get_args());
324     }
325     function td (/*...*/) {
326         $el = new HtmlElement('td');
327         return $el->_init2(func_get_args());
328     }
329     function th (/*...*/) {
330         $el = new HtmlElement('th');
331         return $el->_init2(func_get_args());
332     }
333     function colgroup (/*...*/) {
334         $el = new HtmlElement('colgroup');
335         return $el->_init2(func_get_args());
336     }
337     function col (/*...*/) {
338         $el = new HtmlElement('col');
339         return $el->_init2(func_get_args());
340     }
341
342     /****************************************/
343     function form (/*...*/) {
344         $el = new HtmlElement('form');
345         return $el->_init2(func_get_args());
346     }
347     function input (/*...*/) {
348         $el = new HtmlElement('input');
349         return $el->_init2(func_get_args());
350     }
351     function button (/*...*/) {
352         $el = new HtmlElement('button');
353         return $el->_init2(func_get_args());
354     }
355     function option (/*...*/) {
356         $el = new HtmlElement('option');
357         return $el->_init2(func_get_args());
358     }
359     function select (/*...*/) {
360         $el = new HtmlElement('select');
361         return $el->_init2(func_get_args());
362     }
363     function textarea (/*...*/) {
364         $el = new HtmlElement('textarea');
365         return $el->_init2(func_get_args());
366     }
367
368     /****************************************/
369     function area (/*...*/) {
370         $el = new HtmlElement('area');
371         return $el->_init2(func_get_args());
372     }
373     function map (/*...*/) {
374         $el = new HtmlElement('map');
375         return $el->_init2(func_get_args());
376     }
377     function frame (/*...*/) {
378         $el = new HtmlElement('frame');
379         return $el->_init2(func_get_args());
380     }
381     function frameset (/*...*/) {
382         $el = new HtmlElement('frameset');
383         return $el->_init2(func_get_args());
384     }
385     function iframe (/*...*/) {
386         $el = new HtmlElement('iframe');
387         return $el->_init2(func_get_args());
388     }
389     function nobody (/*...*/) {
390         $el = new HtmlElement('nobody');
391         return $el->_init2(func_get_args());
392     }
393 }
394
395 define('HTMLTAG_EMPTY', 1);
396 define('HTMLTAG_INLINE', 2);
397 define('HTMLTAG_ACCEPTS_INLINE', 4);
398
399
400 HTML::_setTagProperty(HTMLTAG_EMPTY,
401                       'area base basefont br col frame hr img input isindex link meta param');
402 HTML::_setTagProperty(HTMLTAG_ACCEPTS_INLINE,
403                       // %inline elements:
404                       'b big i small tt ' // %fontstyle
405                       . 's strike u ' // (deprecated)
406                       . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
407                       . 'a img object br script map q sub sup span bdo '//%special
408                       . 'button input label option select textarea ' //%formctl
409
410                       // %block elements which contain inline content
411                       . 'address h1 h2 h3 h4 h5 h6 p pre '
412                       // %block elements which contain either block or inline content
413                       . 'div fieldset frameset'
414
415                       // other with inline content
416                       . 'caption dt label legend '
417                       // other with either inline or block
418                       . 'dd del ins li td th colgroup ');
419
420 HTML::_setTagProperty(HTMLTAG_INLINE,
421                       // %inline elements:
422                       'b big i small tt ' // %fontstyle
423                       . 's strike u ' // (deprecated)
424                       . 'abbr acronym cite code dfn em kbd samp strong var ' //%phrase
425                       . 'a img object br script map q sub sup span bdo '//%special
426                       . 'button input label option select textarea ' //%formctl
427                       . 'nobody iframe'
428                       );
429
430 /**
431  * Generate hidden form input fields.
432  *
433  * @param $query_args hash  A hash mapping names to values for the hidden inputs.
434  * Values in the hash can themselves be hashes.  The will result in hidden inputs
435  * which will reconstruct the nested structure in the resulting query args as
436  * processed by PHP.
437  *
438  * Example:
439  *
440  * $args = array('x' => '2',
441  *               'y' => array('a' => 'aval', 'b' => 'bval'));
442  * $inputs = HiddenInputs($args);
443  *
444  * Will result in:
445  *
446  *  <input type="hidden" name="x" value = "2" />
447  *  <input type="hidden" name="y[a]" value = "aval" />
448  *  <input type="hidden" name="y[b]" value = "bval" />
449  *
450  * @return object An XmlContent object containing the inputs.
451  */
452 function HiddenInputs ($query_args, $pfx = false, $exclude = array()) {
453     $inputs = HTML();
454
455     foreach ($query_args as $key => $val) {
456         if (in_array($key,$exclude)) continue;
457         $name = $pfx ? $pfx . "[$key]" : $key;
458         if (is_array($val))
459             $inputs->pushContent(HiddenInputs($val, $name));
460         else
461             $inputs->pushContent(HTML::input(array('type' => 'hidden',
462                                                    'name' => $name,
463                                                    'value' => $val)));
464     }
465     return $inputs;
466 }
467
468
469 /** Generate a <script> tag containing javascript.
470  *
471  * @param string $js  The javascript.
472  * @param string $script_args  (optional) hash of script tags options
473  *                             e.g. to provide another version or the defer attr
474  * @return HtmlElement A <script> element.
475  */
476 function JavaScript ($js, $script_args = false) {
477     $default_script_args = array(//'version' => 'JavaScript', // not xhtml conformant
478                                  'type' => 'text/javascript');
479     $script_args = $script_args ? array_merge($default_script_args,$script_args)
480                                 : $default_script_args;
481     if (empty($js))
482         return HTML::script($script_args);
483     else
484         // see http://devedge.netscape.com/viewsource/2003/xhtml-style-script/
485         return HTML::script($script_args,
486                             new RawXml((ENABLE_XHTML_XML ? "\n//<![CDATA[" : "\n<!--//")
487                                        . "\n".rtrim($js)."\n"
488                                        . (ENABLE_XHTML_XML ? "//]]>\n" : "// -->")));
489 }
490
491 /** Conditionally display content based of whether javascript is supported.
492  *
493  * This conditionally (on the client side) displays one of two alternate
494  * contents depending on whether the client supports javascript.
495  *
496  * NOTE:
497  * The content you pass as arguments to this function must be block-level.
498  * (This is because the <noscript> tag is block-level.)
499  *
500  * @param mixed $if_content Content to display if the browser supports
501  * javascript.
502  *
503  * @param mixed $else_content Content to display if the browser does
504  * not support javascript.
505  *
506  * @return XmlContent
507  */
508 function IfJavaScript($if_content = false, $else_content = false) {
509     $html = array();
510     if ($if_content) {
511         $xml = AsXML($if_content);
512         $js = sprintf('document.write("%s");',
513                       addcslashes($xml, "\0..\37!@\\\177..\377"));
514         $html[] = JavaScript($js);
515     }
516     if ($else_content) {
517         $html[] = HTML::noscript(false, $else_content);
518     }
519     return HTML($html);
520 }
521     
522 /**
523  $Log: not supported by cvs2svn $
524  Revision 1.40  2004/06/25 14:29:17  rurban
525  WikiGroup refactoring:
526    global group attached to user, code for not_current user.
527    improved helpers for special groups (avoid double invocations)
528  new experimental config option ENABLE_XHTML_XML (fails with IE, and document.write())
529  fixed a XHTML validation error on userprefs.tmpl
530
531  Revision 1.39  2004/05/17 13:36:49  rurban
532  Apply RFE #952323 "ExternalSearchPlugin improvement", but
533    with <button><img></button>
534
535  Revision 1.38  2004/05/12 10:49:54  rurban
536  require_once fix for those libs which are loaded before FileFinder and
537    its automatic include_path fix, and where require_once doesn't grok
538    dirname(__FILE__) != './lib'
539  upgrade fix with PearDB
540  navbar.tmpl: remove spaces for IE &nbsp; button alignment
541
542  Revision 1.37  2004/04/26 20:44:34  rurban
543  locking table specific for better databases
544
545  Revision 1.36  2004/04/19 21:51:41  rurban
546  php5 compatibility: it works!
547
548  Revision 1.35  2004/04/19 18:27:45  rurban
549  Prevent from some PHP5 warnings (ref args, no :: object init)
550    php5 runs now through, just one wrong XmlElement object init missing
551  Removed unneccesary UpgradeUser lines
552  Changed WikiLink to omit version if current (RecentChanges)
553
554  Revision 1.34  2004/03/24 19:39:02  rurban
555  php5 workaround code (plus some interim debugging code in XmlElement)
556    php5 doesn't work yet with the current XmlElement class constructors,
557    WikiUserNew does work better than php4.
558  rewrote WikiUserNew user upgrading to ease php5 update
559  fixed pref handling in WikiUserNew
560  added Email Notification
561  added simple Email verification
562  removed emailVerify userpref subclass: just a email property
563  changed pref binary storage layout: numarray => hash of non default values
564  print optimize message only if really done.
565  forced new cookie policy: delete pref cookies, use only WIKI_ID as plain string.
566    prefs should be stored in db or homepage, besides the current session.
567
568  Revision 1.33  2004/03/18 22:32:33  rurban
569  work to make it php5 compatible
570
571  Revision 1.32  2004/02/15 21:34:37  rurban
572  PageList enhanced and improved.
573  fixed new WikiAdmin... plugins
574  editpage, Theme with exp. htmlarea framework
575    (htmlarea yet committed, this is really questionable)
576  WikiUser... code with better session handling for prefs
577  enhanced UserPreferences (again)
578  RecentChanges for show_deleted: how should pages be deleted then?
579
580  Revision 1.31  2003/02/27 22:47:26  dairiki
581  New functions in HtmlElement:
582
583  JavaScript($js)
584     Helper for generating javascript.
585
586  IfJavaScript($if_content, $else_content)
587     Helper for generating
588        <script>document.write('...')</script><noscript>...</noscript>
589     constructs.
590
591  Revision 1.30  2003/02/17 06:02:25  dairiki
592  Remove functions HiddenGets() and HiddenPosts().
593
594  These functions were evil.  They didn't check the request method,
595  so they often resulted in GET args being converted to POST args,
596  etc...
597
598  One of these is still used in lib/plugin/WikiAdminSelect.php,
599  but, so far as I can tell, that code is both broken _and_ it
600  doesn't do anything.
601
602  Revision 1.29  2003/02/15 01:54:19  dairiki
603  Added HTML::meta() for <meta> tag.
604
605  Revision 1.28  2003/01/04 02:32:30  carstenklapp
606  Added 'col' and 'colgroup' table elements used by PluginManager.
607
608  */
609
610 // (c-file-style: "gnu")
611 // Local Variables:
612 // mode: php
613 // tab-width: 8
614 // c-basic-offset: 4
615 // c-hanging-comment-ender-p: nil
616 // indent-tabs-mode: nil
617 // End:
618 ?>