00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 @require_once('config.inc.php');
00013 require_once('util.inc.php');
00014
00015 $single_tags = array('br', 'hr', 'img', 'input', 'link', 'meta', 'param');
00016
00017 if (!isset($html)) {
00018 html_flush();
00019 }
00020
00021
00022
00023
00024
00025
00026
00027 function _array_sort_by_prio(&$a)
00028 {
00029
00030
00031 usort($a, '_cmp_prio');
00032 }
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 function _cmp_prio($a, $b)
00043 {
00044 if ($a['prio'] == $b['prio']) {
00045 return 0;
00046 }
00047 return ($a['prio'] < $b['prio']) ? -1 : 1;
00048 }
00049
00050
00051
00052
00053
00054
00055
00056 function &body()
00057 {
00058 global $html;
00059 return $html['body'];
00060 }
00061
00062
00063
00064
00065
00066
00067
00068 function body_append($c)
00069 {
00070 global $html;
00071 elem_append($html['body'], $c);
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081 function elem($tag)
00082 {
00083 return array('tag'=>$tag);
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093 function elem_add_class(&$elem, $c)
00094 {
00095 if (!@is_array($elem['class'])) {
00096 $elem['class'] = array();
00097 }
00098 $elem['class'][] = $c;
00099 $elem['class'] = array_unique($elem['class']);
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 function elem_append(&$elem, $c)
00111 {
00112 if (!isset($elem['val'])) {
00113 if (is_array($c)) {
00114 $elem['val'] = array($c);
00115 } else {
00116 $elem['val'] = $c;
00117 }
00118 } elseif (is_array($c) && is_array($elem['val'])) {
00119 $elem['val'][] = $c;
00120 } elseif (is_array($c) && is_string($elem['val'])) {
00121 $elem['val'] = array($elem['val'], $c);
00122 } elseif (is_string($c) && is_array($elem['val'])) {
00123 $elem['val'][] = $c;
00124 } elseif (is_string($c) && is_string($elem['val'])) {
00125 $elem['val'] .= $c;
00126 }
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 function elem_attr(&$elem)
00138 {
00139 if (func_num_args() == 2) {
00140 if (isset($elem[func_get_arg(1)])) {
00141 return $elem[func_get_arg(1)];
00142 } else {
00143 return NULL;
00144 }
00145 } elseif (2 < func_num_args()) {
00146 $elem[func_get_arg(1)] = func_get_arg(2);
00147 }
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157 function elem_classes($elem)
00158 {
00159 if (@is_array($elem['class'])) {
00160 return $elem['class'];
00161 } else {
00162 return array();
00163 }
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 function elem_css(&$elem)
00175 {
00176 if (func_num_args() == 2) {
00177 if (@is_array($elem['style']) && isset($elem['style'][func_get_arg(1)])) {
00178 return $elem['style'][func_get_arg(1)];
00179 } else {
00180 return NULL;
00181 }
00182 } elseif (2 < func_num_args()) {
00183 if (!@is_array($elem['style'])) {
00184 $elem['style'] = array();
00185 }
00186 if (func_get_arg(2) === '') {
00187
00188 unset($elem['style'][func_get_arg(1)]);
00189 } else {
00190 $elem['style'][func_get_arg(1)] = func_get_arg(2);
00191 }
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202 function elem_finalize($elem)
00203 {
00204 global $single_tags;
00205
00206 $ret = '<'.$elem['tag'];
00207 if (isset($elem['id'])) {
00208 $ret .= ' id="'.htmlspecialchars($elem['id'], ENT_COMPAT, 'UTF-8').'"';
00209 unset($elem['id']);
00210 }
00211 if (@is_array($elem['class'])) {
00212 $ret .= ' class="'.htmlspecialchars(implode(' ', $elem['class']), ENT_COMPAT, 'UTF-8').'"';
00213 unset($elem['class']);
00214 }
00215 foreach ($elem as $key=>$val) {
00216 if ($key == 'tag' || $key == 'id' || $key == 'class' || $key == 'val' || $key == 'body_inline') {
00217 continue;
00218 } elseif ($key == 'style') {
00219 $ret .= ' style="';
00220 ksort($val);
00221 foreach ($val as $k=>$v) {
00222 $ret .= htmlspecialchars($k, ENT_COMPAT, 'UTF-8').': '.htmlspecialchars($v, ENT_COMPAT, 'UTF-8').'; ';
00223 }
00224
00225 $ret = substr($ret, 0, -1);
00226 $ret .= '"';
00227 } else {
00228 $ret .= ' '.htmlspecialchars($key, ENT_NOQUOTES, 'UTF-8').'="'.htmlspecialchars($val, ENT_COMPAT, 'UTF-8').'"';
00229 }
00230 }
00231 $ret .= '>';
00232
00233
00234 $block_tags = array('blockquote', 'body', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'li', 'ol', 'p', 'pre', 'script', 'ul');
00235 if (in_array($elem['tag'], $block_tags)) {
00236 $block_tag = true;
00237 $ret .= nl();
00238 } else {
00239 $block_tag = false;
00240 }
00241
00242
00243 if (in_array(strtolower($elem['tag']), $single_tags)) {
00244 return $ret;
00245 }
00246
00247
00248 $content = '';
00249 if (@is_string($elem['val'])) {
00250 $content = $elem['val'];
00251 } elseif (@is_array($elem['val']) && isset($elem['val']['tag'])) {
00252
00253 $content = elem_finalize($elem['val']);
00254 } elseif (@is_array($elem['val'])) {
00255 foreach ($elem['val'] as $v) {
00256 if (is_string($v)) {
00257 $content .= $v;
00258 } elseif (is_array($v) && isset($v['tag'])) {
00259
00260 if (in_array($v['tag'], $block_tags) && 0 < strlen($content) && substr($content, -1) != "\n") {
00261 $content .= nl();
00262 }
00263
00264 $content .= elem_finalize($v);
00265 }
00266 }
00267 }
00268
00269 if ($block_tag && 0 < strlen($content)) {
00270
00271 if (substr($content, -1) == "\n") {
00272 $content = substr($content, 0, -1);
00273 }
00274 $content = str_replace("\n", "\n\t", $content);
00275 $ret .= tab().$content.nl();
00276 } elseif (0 < strlen($content)) {
00277 $ret .= $content;
00278 }
00279
00280 $ret .= '</'.$elem['tag'].'>';
00281
00282 if ($block_tag) {
00283 $ret .= nl();
00284 }
00285
00286 return $ret;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 function elem_has_class($elem, $c)
00298 {
00299 if (@in_array($c, $elem['class'])) {
00300 return true;
00301 } else {
00302 return false;
00303 }
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313 function elem_remove_attr(&$elem, $a)
00314 {
00315 unset($elem[$a]);
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325 function elem_remove_class(&$elem, $c)
00326 {
00327 if (@is_array($elem['class'])) {
00328 if (($k = array_search($c, $elem['class'])) !== false) {
00329 array_splice($elem['class'], $k, 1);
00330 }
00331 }
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 function elem_tag($elem)
00343 {
00344 if (isset($elem['tag'])) {
00345 return strtolower($elem['tag']);
00346 } else {
00347 return '';
00348 }
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 function elem_val(&$elem)
00360 {
00361 if (func_num_args() == 1) {
00362 if (@is_string($elem['val'])) {
00363 return $elem['val'];
00364 } else {
00365 return '';
00366 }
00367 } elseif (1 < func_num_args()) {
00368 $elem['val'] = func_get_arg(1);
00369 }
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 function html_add_alternate($type, $url, $title)
00381 {
00382 global $html;
00383 if (!@is_array($html['header']['alternate'])) {
00384 $html['header']['alternate'] = array();
00385 }
00386 $html['header']['alternate'][] = array('type'=>$type, 'url'=>$url, 'title'=>$title);
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 function html_add_css($url, $prio = 5, $media = '')
00398 {
00399 global $html;
00400 if (!@is_array($html['header']['css'])) {
00401 $html['header']['css'] = array();
00402 }
00403 $html['header']['css'][] = array('url'=>$url, 'prio'=>$prio, 'media'=>$media);
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413 function html_add_css_inline($rule, $prio = 5)
00414 {
00415 global $html;
00416 if (!@is_array($html['header']['css_inline'])) {
00417 $html['header']['css_inline'] = array();
00418 }
00419 $html['header']['css_inline'][] = array('rule'=>$rule, 'prio'=>$prio);
00420 }
00421
00422
00423
00424
00425
00426
00427
00428 function html_add_head_inline($def, $prio = 5)
00429 {
00430 global $html;
00431 if (!@is_array($html['header']['head_inline'])) {
00432 $html['header']['head_inline'] = array();
00433 }
00434 $html['header']['head_inline'][] = array('def'=>$def, 'prio'=>$prio);
00435 }
00436
00437
00438
00439
00440
00441
00442
00443 function html_add_body_inline($def, $prio = 5)
00444 {
00445 global $html;
00446 if (!@is_array($html['body']['body_inline'])) {
00447 $html['body']['body_inline'] = array();
00448 }
00449 $html['body']['body_inline'][] = array('def'=>$def, 'prio'=>$prio);
00450 }
00451
00452
00453
00454
00455
00456
00457
00458 function html_add_js($url, $prio = 5)
00459 {
00460 global $html;
00461 if (!@is_array($html['header']['js'])) {
00462 $html['header']['js'] = array();
00463 }
00464 $html['header']['js'][] = array('url'=>$url, 'prio'=>$prio);
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 function html_add_js_inline($code, $prio = 5, $reason = '')
00476 {
00477 global $html;
00478 if (!@is_array($html['header']['js_inline'])) {
00479 $html['header']['js_inline'] = array();
00480 }
00481 $html['header']['js_inline'][] = array('code'=>$code, 'prio'=>$prio, 'reason'=>$reason);
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491 function html_add_js_var($key, $val)
00492 {
00493 global $html;
00494 if (!@is_array($html['header']['js_var'])) {
00495 $html['header']['js_var'] = array();
00496 }
00497 $html['header']['js_var'][$key] = $val;
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507 function html_css($prop)
00508 {
00509 global $html;
00510 if (func_num_args() == 1) {
00511 if (@is_array($html['header']['style']) && isset($html['header']['style'][$prop])) {
00512 return $html['header']['style'][$prop];
00513 } else {
00514 return NULL;
00515 }
00516 } elseif (1 < func_num_args()) {
00517 if (!@is_array($html['header']['style'])) {
00518 $html['header']['style'] = array();
00519 }
00520 if (func_get_arg(1) === '') {
00521
00522 unset($html['header']['style'][$prop]);
00523 } else {
00524 $html['header']['style'][$prop] = func_get_arg(1);
00525 }
00526 }
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536 function html_disable_caching($reason = '')
00537 {
00538 global $html;
00539 if ($html['cache']) {
00540 log_msg('info', 'html: disabled caching for this request because of '.quot($reason));
00541 $html['cache'] = false;
00542 }
00543 }
00544
00545
00546
00547
00548
00549
00550
00551 function html_favicon()
00552 {
00553 global $html;
00554 if (func_num_args() == 0) {
00555 if (@is_string($html['header']['favicon'])) {
00556 return $html['header']['favicon'];
00557 } else {
00558 return '';
00559 }
00560 } elseif (0 < func_num_args()) {
00561 $html['header']['favicon'] = func_get_arg(0);
00562 }
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 function html_finalize(&$cache = false)
00574 {
00575 global $html;
00576
00577 $ret = '<!DOCTYPE html>'.nl();
00578 $ret .= '<html';
00579 if (@is_array($html['header']['style'])) {
00580 $ret .= ' style="';
00581 ksort($html['header']['style']);
00582 foreach ($html['header']['style'] as $key=>$val) {
00583 $ret .= htmlspecialchars($key, ENT_COMPAT, 'UTF-8').': '.htmlspecialchars($val, ENT_COMPAT, 'UTF-8').'; ';
00584 }
00585
00586 $ret = substr($ret, 0, -1);
00587 $ret .= '"';
00588 }
00589 $ret .= '>'.nl();
00590 $ret .= '<head>'.nl();
00591 $ret .= '<title>'.htmlspecialchars($html['header']['title'], ENT_NOQUOTES, 'UTF-8').'</title>'.nl();
00592 $ret .= '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'.nl();
00593 if (@is_array($html['header']['alternate'])) {
00594 foreach ($html['header']['alternate'] as $e) {
00595 $ret .= '<link rel="alternate" type="'.htmlspecialchars($e['type'], ENT_COMPAT, 'UTF-8').'" href="'.htmlspecialchars($e['url'], ENT_COMPAT, 'UTF-8').'" title="'.htmlspecialchars($e['title'], ENT_COMPAT, 'UTF-8').'">'.nl();
00596 }
00597 }
00598 if (!empty($html['header']['favicon'])) {
00599 $ret .= '<link rel="shortcut icon" href="'.htmlspecialchars($html['header']['favicon'], ENT_COMPAT, 'UTF-8').'">'.nl();
00600 }
00601 if (@is_array($html['header']['css'])) {
00602 _array_sort_by_prio($html['header']['css']);
00603
00604
00605 foreach ($html['header']['css'] as $e) {
00606 $ret .= '<link rel="stylesheet" type="text/css" href="'.htmlspecialchars($e['url'], ENT_COMPAT, 'UTF-8').'"';
00607 if (!empty($e['media'])) {
00608 $ret .= ' media="'.htmlspecialchars($e['media'], ENT_COMPAT, 'UTF-8').'"';
00609 }
00610 $ret .= '>'.nl();
00611 }
00612 }
00613 if (@is_array($html['header']['css_inline'])) {
00614 _array_sort_by_prio($html['header']['css_inline']);
00615 if (0 < count($html['header']['css_inline'])) {
00616 $ret .= '<style type="text/css">'.nl();
00617 }
00618 foreach ($html['header']['css_inline'] as $c) {
00619 $rule = $c['rule'];
00620
00621 if (substr($rule, -1) == "\n") {
00622 $rule = substr($rule, 0, -1);
00623 }
00624
00625 $rule = str_replace("\n", "\n\t", $rule);
00626 $ret .= tab().$rule.nl();
00627 }
00628 if (0 < count($html['header']['css_inline'])) {
00629 $ret .= '</style>'.nl();
00630 }
00631 }
00632 if (@is_array($html['header']['js'])) {
00633 _array_sort_by_prio($html['header']['js']);
00634 array_unique_element($html['header']['js'], 'url');
00635 foreach ($html['header']['js'] as $e) {
00636 $ret .= '<script type="text/javascript" src="'.htmlspecialchars($e['url'], ENT_COMPAT, 'UTF-8').'"></script>'.nl();
00637 }
00638 }
00639 if (@is_array($html['header']['js_var'])) {
00640 $ret .= array_to_js($html['header']['js_var']);
00641 }
00642 if (@is_array($html['header']['js_inline'])) {
00643 _array_sort_by_prio($html['header']['js_inline']);
00644 foreach ($html['header']['js_inline'] as $c) {
00645 if (!empty($c['reason'])) {
00646 $ret .= '<!-- '.$c['reason'].' -->'.nl();
00647 $ret .= '<script type="text/javascript">'.nl();
00648
00649 if (substr($c['code'], -1) == "\n") {
00650 $c['code'] = substr($c['code'], 0, -1);
00651 }
00652
00653 $c = str_replace("\n", "\n\t", $c);
00654 $ret .= tab().$c['code'].nl();
00655 $ret .= '</script>'.nl();
00656 }
00657 }
00658 }
00659 if (@is_array($html['header']['head_inline'])) {
00660 _array_sort_by_prio($html['header']['head_inline']);
00661 if (0 < count($html['header']['head_inline'])) {
00662 $ret .= '<!-- user HEAD definitions -->'.nl();
00663 }
00664 foreach ($html['header']['head_inline'] as $c) {
00665 $def = $c['def'];
00666
00667 if (substr($def, -1) == "\n") {
00668 $def = substr($def, 0, -1);
00669 }
00670
00671 $ret .= $def.nl();
00672 }
00673 }
00674 $ret .= '</head>'.nl();
00675
00676 if (@is_array($html['body']['body_inline'])) {
00677 _array_sort_by_prio($html['body']['body_inline']);
00678 if (0 < count($html['body']['body_inline'])) {
00679 $user_body = '<!-- user BODY definitions -->'.nl();
00680 }
00681 foreach ($html['body']['body_inline'] as $c) {
00682 $def = $c['def'];
00683
00684 if (substr($def, -1) == "\n") {
00685 $def = substr($def, 0, -1);
00686 }
00687 $rule = str_replace("\n", "\n\t", $def);
00688 $user_body .= $def.nl();
00689 }
00690 body_append($user_body);
00691 }
00692 $ret .= elem_finalize($html['body']);
00693 $ret .= '</html>';
00694
00695
00696 if ($cache) {
00697 if (!$html['cache']) {
00698 $cache = false;
00699 }
00700 }
00701
00702 return $ret;
00703 }
00704
00705
00706
00707
00708
00709 function html_flush()
00710 {
00711 global $html;
00712 $html = array();
00713 $html['header'] = array('title'=>'');
00714 $html['body'] = array('tag'=>'body');
00715 $html['cache'] = true;
00716 }
00717
00718
00719
00720
00721
00722
00723
00724 function html_title()
00725 {
00726 global $html;
00727 if (func_num_args() == 0) {
00728 return $html['header']['title'];
00729 } elseif (0 < func_num_args()) {
00730 $html['header']['title'] = func_get_arg(0);
00731 }
00732 }