diff options
author | Nathan Gass | 2012-03-22 18:23:53 +0000 |
---|---|---|
committer | Nathan Gass | 2012-03-22 18:23:53 +0000 |
commit | 338cda9000356404cf2865d61787607acf67fe98 (patch) | |
tree | 3924b3e2e12a5d5ea3b40890477d5e070498543c /devel-utf8/it_html.class | |
parent | e0a89b408041d25b18090bfc3d596627ea930507 (diff) | |
download | itools-338cda9000356404cf2865d61787607acf67fe98.tar.gz itools-338cda9000356404cf2865d61787607acf67fe98.tar.bz2 itools-338cda9000356404cf2865d61787607acf67fe98.zip |
last remains of wrong branch itools/live/devel-utf8 removed
Diffstat (limited to 'devel-utf8/it_html.class')
-rw-r--r-- | devel-utf8/it_html.class | 582 |
1 files changed, 0 insertions, 582 deletions
diff --git a/devel-utf8/it_html.class b/devel-utf8/it_html.class deleted file mode 100644 index 92aa9ba..0000000 --- a/devel-utf8/it_html.class +++ /dev/null @@ -1,582 +0,0 @@ -<?php -/* -** $Id$ -** -** Copyright (C) 1995-2007 by the ITools Authors. -** This file is part of ITools - the Internet Tools Library -** -** ITools is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 3 of the License, or -** (at your option) any later version. -** -** ITools is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see <http://www.gnu.org/licenses/>. -** -** UltraHTML 3000 tool layer. Create functions for html tags. -** -** new it_html; -** echo html(head('title' => 'hello'), body(h1('hello'), p('Hello world!'))); -**/ - -class it_html -{ - -/** - * Create a HTML object and global functions for all methods (exlcluding - * methods starting with '_') in this class plus the default tags (see below). - * - * @param $p Configuration settings. Can be set/overridden in constructor, configure(), html() or head(). - * See source code for a list of supported values - */ -function it_html($p = array()) -{ - # Default configuration of html class - $this->p = $p + array( - 'charset' => 'iso-8859-1', - 'doctype' => null, # Custom doctype (will usually be calculated from htmltype) - 'head' => '', # Code to put into head() section - 'htmltype' => 'xhtml', # 'html' (=old-style), 'xhtml' or 'xhtml-mobile' - 'lang' => 'de', # Language code to use in <html lang="..."> tag - 'ie_png_fix' => false, # To enable, supply URL of a transparent gif (like /images/0.gif) - 'moretags' => '', # Comma-separated list of tag-functions to generate additionally to 'tags' - 'name' => 'it_html', # Name of global variable $this is assigned to (string), XXX Copy and paste in configure() to keep PHP4 compatibility - 'nonewlinetags' => 'a,b,em,img,input,label,span,noscript', # tags that do not like newlines after them - 'notexported' => 'configure,sanitize',# Those methods are not exported - 'prettyprint' => false, # Should output be prettily indented? - 'show_boot_dom' => false, # If true, append invisible <div id="it_boot_dom"> at the end of body - 'show_content_type' => true, # If true, add <meta http-equiv="Content-Type" ...> header - 'show_favicon' => true, # If true, add <link> tag to /favicon.ico if it exists - 'favicon' => '', # If set, add favicon <link> tag to this url - 'staticallycallable' => 'Q,U,select', # Those methods are statically callable (have same arguments as global stubs) but are a bit slower - 'tags' => 'a,b,br,button,div,em,fieldset,form,h1,h2,h3,h4,h5,h6,hr,input,label,legend,li,meta,noscript,p,span,style,table,tbody,td,textarea,tfoot,th,thead,tr,ul', - 'title' => '', # HTML title (default: no title added) - 'use_it_state' => false, # If true, generate code needed by state.js (aka 'history iframe') - ); - - # We know these doctypes. If you need something else, supply 'doctype' in p - $this->doctypes = array( - 'html' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">', - 'xhtml' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', - 'xhtml-mobile' => '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">' - ); - - $this->hasnonewline = array_flip(explode(',', $this->p['nonewlinetags'])); - $notexported = array_flip(explode(',', "dummy," . $this->p['notexported'])); # dummy keeps values > 0 - - # Create global functions for _tags - foreach (array_merge(explode(',', $this->p['tags']), explode(',', $this->p['moretags'])) as $func) - { - if (!function_exists($func) && $func) - $code[$func] = "function $func() { \$args = func_get_args(); return \$GLOBALS['{$this->p['name']}']->_tag('$func', \$args); }"; - } - - # Create global functions for it_html methods - foreach (get_class_methods(get_class($this)) as $func) - { - if (!preg_match('/^_/', $func) && !is_a($this, $func) && $func && !function_exists($func) && !$notexported[$func]) - $code[$func] = "function $func() { \$args = func_get_args(); return \$GLOBALS['{$this->p['name']}']->$func(\$args); }"; - } - - # Create global functions for methods that are statically callable (have same arguments as global stubs) - foreach (explode(',', $this->p['staticallycallable']) as $func) - { - if ($func && !function_exists($func)) - $code[$func] = "function $func() { \$args = func_get_args(); return call_user_func_array(array(&\$GLOBALS['{$this->p['name']}'], '$func'), \$args); }"; - } - - eval(join('', (array)$code)); - - # Since name is given as param, it is our duty to store it, not our caller's. - $GLOBALS[$this->p['name']] =& $this; -} - - -/** - * Modify configuration of it_html, e.g. htmltype after it was instantiated. - * @param $p Configuration settings. Can be set/overridden in constructor, configure(), html() or head(). - * See constructor for a list of supported values - */ -function configure($p) -{ - $p += array('name' => "it_html"); # XXX Copy and paste from constructor to keep PHP4 compatibility - $GLOBALS[$p['name']]->p = $p + (array)$GLOBALS[$p['name']]->p; - $GLOBALS[$p['name']]->hasnonewline = array_flip(explode(',', $GLOBALS[$p['name']]->p['nonewlinetags'])); -} - -/** - * Return doctype and entire HTML page. - * Example application code to render page: - * echo html(head(...), body(...)); - * - * @param any number of text args or array of key => value pairs - * Defaults for key => value parameters are inherited from the it_html constructor and should be set there. - * The parameters are $p['lang'], $p['htmltype'] and $p['doctype'] - */ -function html($args) -{ - list($data, $p) = $this->_parse_args($args); - $p += $this->p; - - $html = ($p['doctype'] ? $p['doctype'] : $this->doctypes[$p['htmltype']]) . "\n" . - '<html ' . ($p['htmltype'] == "xhtml" ? 'xmlns="http://www.w3.org/1999/xhtml" ' : '') . ($p['htmltype'] == "xhtml-mobile" ? 'xml:lang' : 'lang') . "=\"{$p['lang']}\">\n" . $data . ($p['omit_endhtml'] ? '' : "</html>\n"); - - return EDC('upd') ? it::replace(array('<!DOCTYPE.*<head>' => ''), $html, array('singleline' => true)) : $html; -} - - -/** - * Return HTML header on first call or empty string on subsequent calls - * - * @param args... any number of assoc arrays and strings. strings will be content of <head> - * @param $p['content-type'] content type (default: "text/html; charset=iso-8859-1") - * @param $p['cssinline'] stylesheet to be put in header - * @param $p['description'] data for <meta name="description"> tag - * @param $p['keywords'] data for <meta name="keywords"> tag - * @param $p['stylesheets'] array mediatype => url of styleshests - * @param $p['title'] content of <title>, will be html encoded - */ -function head($args = array()) -{ - if (!$this->head_sent++) - { - list($data, $p) = $this->_parse_args($args); - - $p += $this->p; - $this->p = ($p += array('content-type' => "text/html; charset={$p['charset']}")); - - $header = $p['show_content_type'] ? meta(array('http-equiv' => "Content-Type", 'content' => $p['content-type'])) : ""; - - # Enable latest IE mode - if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) - $header .= meta(array('http-equiv' => "X-UA-Compatible", 'content' => "IE=9")); - - foreach(array('description', 'keywords') as $name) - if (!empty($p[$name])) - $header .= meta(array('name' => $name, 'content' => $p[$name])); - - # Add favicon - if ($p['favicon']) - $header .= tag('link', array('rel' => "shortcut icon", 'href' => $p['favicon'])); - elseif ($p['show_favicon'] && @file_exists($_SERVER['DOCUMENT_ROOT'] . '/favicon.ico')) - $header .= tag('link', array('rel' => "shortcut icon", 'href' => "/favicon.ico")); - - foreach((array)$p['stylesheets'] as $type => $url) - $header .= tag('link', array('rel' => "stylesheet", 'type' => "text/css", 'href' => $url) + (is_int($type) ? array() : array('media' => $type))); - - if (!empty($p['cssinline'])) - $header .= tag('style', array('type' => "text/css", "\n" . preg_replace(array('/\s*\/\*[^\*]+\*\//Um', '/\s*\{\s*/', '/;\s+/'), array('', '{', ';'), $p['cssinline']))); - - $header .= $p['head'] . ($p['title'] ? tag('title', strip_tags(Q(strip_tags($p['title'])))) : ""); # remove coloring by .texts and .q debug param - - if($this->p['htmltype'] == "xhtml-mobile" && strpos($_SERVER['HTTP_USER_AGENT'], 'W3C_Validator')) - header("Content-Type: application/xhtml+xml; charset={$this->p['charset']}"); # for validation - else if (!headers_sent()) # prevent warnings when ED() in use - header("Content-Type: " . $p['content-type']); - - $js = isset($p['jsenv']) ? "var env = " . itjs::serialize($p['jsenv']) . ";\n" : ''; - if ($GLOBALS['it_html']->p['charset'] == "iso-8859-1") - $js = it_html::latinize($js); - - $js .= $this->_itjs($p['jsinline'], 'inline'); - - if ($p['js']) - { - $checksum = itjs::checksum(itjs::filenames($p['js'])); - $js .= $this->_itjs("boot.js", "inline"); - $js .= "function it_boot_start(){ " . trim($p['jsboot']) . " }\n"; - $js .= "it_boot('/itjs/" . U($p['js'], array('s' => $checksum)) . "');\n"; - } - - if ($js) - $data .= $this->js(array($js)); - - return tag('head', $header, $data); - } -} - - -/** - * Return HTML head (if not already sent) and body with it_state and it_boot magic code - */ -function body($args) -{ - if ($this->p['use_it_state']) - array_unshift($args, tag('iframe', array('id' => "it_state", 'src' => "/itjs/state.html", 'width' => 1, 'height' => 1, 'frameborder' => 0))); - - if (EDC('what')) - { - $debugvars = array_merge($GLOBALS['ULTRADEBUGVARS'], array('srclines' => 1, 'texts' => 1)); - ksort($debugvars); - foreach ($debugvars as $var => $dummy) - { - if (EDC($var)) - $toggled_host = preg_replace("/$var\./", "", $_SERVER['HTTP_HOST']); - else - $toggled_host = preg_replace("/\.([^.]*)\.([^.]*)\.([^.]*)$/", ".$var.\$1.\$2.\$3", $_SERVER['HTTP_HOST']); - $debug_links[] = a(array('href' => U('http://' . $toggled_host . $_SERVER['REQUEST_URI']), 'style' => 'font-weight:' . (EDC($var) ? 'bold' : 'normal') . ';'), $var); - } - $args[] = div(array('style' => 'font-family:monospace;'), "Debugvars: " . join(" ", $debug_links)); - } - - if ($this->p['show_boot_dom']) - $args[] = div(array('id' => "it_boot_dom", 'style' => "visibility:hidden")); - - return $this->head() . $this->_tag('body', $args); -} - - -/** - * INTERNAL: Parse an arg array (mixed key=>value pairs and strings) and return it - * as array(0 => all numerical args concatenated, 1 => array(key=>value pairs) - */ -function _parse_args($args) -{ - $p = array(); - foreach ($args as $arg) - { - if (is_array($arg)) - { - foreach ($arg as $key => $value) - { - if (is_int($key)) - $data .= it_taintcheck($value); - else - $p[$key] = $value; - } - } - else - $data .= it_taintcheck($arg); - } - - return array($data, $p); -} - - -/** - * function div($args...) - * Return a <div>...</div> element - * Any strings in the argument list will be content of the <div> - * Any associative arrays among the arguments will create attributes for <div>. - * Attributes with values false or null will be omitted completely. - * Attributes with value true can be used for boolean attributes like 'checked' - * Attribute values will be html encoded, content values won't so you may need to use Q(). - * @see _tag() - */ #:} - -/** - * INTERNAL: Create html tag from name and args array (the arguments of the parent function) - */ -function _tag($name, $args) -{ - list($data, $attr) = $this->_parse_args($args); - - $newline = isset($this->hasnonewline[$name]) ? "" : "\n"; - - # Ultra XML PrettyPrinter 3000 [\] by SCA - if ($this->p['prettyprint'] && $newline && (substr($data, -1, 1) == "\n") && (strpos($data, '<textarea') === false && strpos($data, '<pre') === false) && ($data != strip_tags($data))) - $data = str_replace("\n", "\n ", "\n" . trim($data)) . "\n"; - - # debugging aid: add backtrace - if (($levels = intval($GLOBALS['debug_srclines'])) && !it::match('^(head|meta|title|script|style|link)', $name)) - $attr = array('title' => it_debug::backtrace(array('levels' => max(3, $levels), 'skipfiles' => "_html\\.class"))) + $attr; - - $result .= "<$name"; - - # add attributes. If $value === true, use key only (<td nowrap> instead of <td nowrap=""> for old html, <td nowrap="nowrap"> for xhtml style) - foreach($attr as $key => $value) - { - if (($value === null) || ($value === false)) # null or false: omit whole tag - ; - else if (isset($value) && $value !== true) # normal case: value - { - if (preg_match('/[<>&"\x00-\x08\x0a-\x0c\x0e-\x1f\x80-\x9f]/', $value)) # WARNING: copy/pasted from Q() - $result .= " $key=\"" . str_replace("\n", " ", htmlspecialchars($GLOBALS['it_html']->p['charset'] == "iso-8859-1" ? it_html::latinize($value) : $value, ENT_COMPAT, $GLOBALS['it_html']->p['charset'])) . '"'; - else - $result .= " $key=\"$value\""; - } - else # true: tag without value - $result .= ($this->p['htmltype'] == 'html') ? " $key" : " $key=\"$key\""; - } - - # Apply a kind of magic... this needs further investigation - if (isset($data) || preg_match('/^(a|div|iframe|pre|script|span|tbody|td|tfoot|thead|textarea)$/i', $name)) - $result .= ">$data</$name>$newline"; - elseif ($this->p['htmltype'] == 'html') - $result .= ">$newline"; - else - $result .= " />$newline"; - - return $result; -} - - -/** - * Return a <tag> containing optional data. - * @param $name tag name ('style', etc.) - * @param ... any number optional data or array of key => value arguments - * @return string containing XML/HTML tag - */ -function tag($args) -{ - $name = array_shift($args); - return $this->_tag($name, $args); -} - -/** - * Special img() function patches png transparency for IE 5.5-6 if ie_png_fix is set - * @param ... any number optional data or array of key => value arguments - * @return <img ... /> - */ -function img($args) -{ - if ($this->p['ie_png_fix'] && preg_match('/MSIE [56]/', $_SERVER['HTTP_USER_AGENT'])) - { - foreach($args as $id => $arg) - if (preg_match('/\.png(\?.*)?$/', $arg['src'])) - { - $args[$id]['style'] = "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='{$arg['src']}',sizingMethod='crop');" . $arg['style']; - $args[$id]['src'] = $this->p['ie_png_fix']; - } - } - - foreach ($args as $arg) - $havealt += isset($arg['alt']); - - if (!$havealt) - it::error('img() needs alt'); - - return $this->_tag("img", $args); -} - - -/** - * Create a dropdown menu object. Warning: encodes html code within options! - * @param $tags key => value pairs of <select> tag - * @param $options array (value => text) of available options or - * string key:val{,key:val} where key will be rawurldecoded so it may contain %2C as comma - * supports optgroups as array (value => optgroup => array(value => text)) - * @param $selected optional currently selected value, or comma-separated list or array for multi-select - * Note: use tag('select') and tag('option') if you want do roll your own - */ -function select($tags, $options, $selected = null) -{ - # Transmogrify key:val{,key:val} to array(key => val) - if (!is_array($options)) - { - $opts = explode(',', $options); - $options = array(); - - foreach($opts as $opt) - { - list($key, $value) = explode(':', $opt); - $options[rawurldecode($key)] = $value; - } - } - - $selected = ($tags['multiple'] && is_string($selected)) ? explode(',', $selected) : (array)$selected; - - $html = ""; - foreach($options as $value => $option) - { - if (is_array($option)) - { - $grouphtml = ""; - foreach($option as $optval => $opt) - $grouphtml .= $this->_tag("option", array(array('value' => $optval, 'selected' => in_array((string)$optval, $selected)), self::_strip_tags(Q(self::_strip_tags($opt))))); - $html .= $this->_tag("optgroup", array(array('label' => $value, $grouphtml))); - } - else - $html .= $this->_tag("option", array(array('value' => $value, 'selected' => in_array((string)$value, $selected), 'disabled' => $option === ""), (trim($option) === "") ? " " : self::_strip_tags(Q(self::_strip_tags($option))))); # self::_strip_tags removes .q debug param coloring - } - - return $this->_tag("select", array($tags, $html)); -} - -# internal: strip spans added by debug params -function _strip_tags($html) -{ - return preg_replace('!</?(span|a)\b[^>]*>!', '', $html); -} - -/** - * Return HTML with all evil things stripped. Allowed are a coupld of simple - * tags like div, p, i, b, br without attributes, a with absolute href, - * img with absolute src url. Also ensures that tags are balanced. - * @param $html HTML string to be sanitized - * @return Sanitized HTML - */ -function sanitize($html) -{ - $result = ""; - $html = it::replace(array('[\0\s]+' => " "), $html); # \s also matches \r and \n - $urlpattern = 'https?://[^">]+'; - $charset = $GLOBALS['it_html']->p['charset'] ? $GLOBALS['it_html']->p['charset'] : 'iso-8859-1'; - - if ($tag = it::match("(.*)<(div|p|i|b)\b[^>]*>(.*?)</\\2>(.*)", $html)) - { - # Simple tags with content, no attributes kept - list($head, $tagname, $content, $tail) = $tag; - $tagname = strtolower($tagname); - $result .= it_html::sanitize($head) . "<$tagname>" . it_html::sanitize($content) . "</$tagname>" . it_html::sanitize($tail); - } - else if ($tag = it::match('(.*)<a\b[^>]+?href="(' . $urlpattern . ')"[^>]*?>(.*?)</a>(.*)', $html)) - { - # Link tags, keeps only href attribute - list($head, $href, $content, $tail) = $tag; - $result .= it_html::sanitize($head) . '<a href="' . it_html::Q(it_html::U(html_entity_decode($href, ENT_COMPAT, $charset))) . '">' . it_html::sanitize($content) . "</a>" . it_html::sanitize($tail); - } - else if ($tag = it::match('(.*)<img\b[^>]+?src="(' . $urlpattern . ')"[^>]*?>(.*)', $html)) - { - # Image tags, keeps only src attribute - list($head, $src, $tail) = $tag; - $result .= it_html::sanitize($head) . '<img src="' . it_html::Q(it_html::U(html_entity_decode($src, ENT_COMPAT, $charset))) . '" alt="" />' . it_html::sanitize($tail); - } - else if ($tag = it::match("(.*)<(br|/tr)\b[^>]*>(.*)", $html)) - { - # brs and table rows are converted so simple line breaks - list($head, $tagname, $tail) = $tag; - $result .= it_html::sanitize($head) . "<br />" . it_html::sanitize($tail); - } - else - $result = it::replace(array('&(#\d+;)' => '&$1'), it_html::Q(html_entity_decode(strip_tags($html), ENT_COMPAT, $charset))); - - return $GLOBALS['debug_q'] ? "<span style='background:#8FF'>$result</span>" : $result; -} - -/** - * Decode all entities, ensure latin-1 encoding - */ -function entity_decode($string) -{ - $string = preg_replace('/&#(8217|65533);/', "'", html_entity_decode($string)); - $string = preg_replace_callback('/�*([0-9a-f]+);/i', function($m) { return hexdec($m[1]) <= 255 ? chr(hexdec($m[1])) : " "; }, $string); - $string = preg_replace_callback('/�*([0-9]+);/', function($m) { return $m[1] <= 255 ? chr($m[1]) : " "; }, $string); - - return $string; -} - -/** - * Replace or remove all illegal characters from a latin-1 string - */ -function latinize($string) -{ - return preg_replace('/[\x00-\x08\x0b-\x0c\x0e-\x1f\x80-\x9f]/', ' ', strtr($string, array("\x80" => "EUR", "\x82" => "'", "\x84" => "\"", "\x85" => "...", "\x8a" => "S", "\x8c" => "OE", "\x8e" => "Z", "\x91" => "'", "\x92" => "'", "\x93" => "\"", "\x94" => "\"", "\x96" => "-", "\x97" => "-", "\x9a" => "s", "\x9e" => "z"))); -} - -/** - * Shortcut: return htmlspecialchars($string) and encode forbidden characters 80-9f if latin1 is output - * @param $string String to encode with htmlspecialchars() - * @return htmlspecialchars($string) - */ -function Q($string) -{ - if (preg_match('/[<>&"\x00-\x08\x0a-\x0c\x0e-\x1f\x80-\x9f]/', $string)) # WARNING: copy/pasted to _tag() - $string = htmlspecialchars($GLOBALS['it_html']->p['charset'] == "iso-8859-1" ? it_html::latinize($string) : $string, ENT_COMPAT, $GLOBALS['it_html']->p['charset']); - - return $GLOBALS['debug_q'] && $string ? "<span style='background:#8FF'>$string</span>" : $string; -} - - -/** - * Build a complete url from base-url and params - * @param ... scalar args and numeric indices build base-url, rest as params - */ -function U(/* ... */) -{ - $args = func_get_args(); - list($base, $params) = it_html::_parse_args($args); - - if (!isset($base)) - $base = preg_replace('/\?.*/', '', $_SERVER['REQUEST_URI']); - - $base = preg_replace(array('|\0|', '/\\\\/'), array('', '/'), $base); # kill null chars, turn \ to / - - if (!($u = @parse_url($base))) - list($u['path'], $u['query']) = explode("?", $base, 2); - - $u['host'] = preg_match('/[^-_.0-9a-z]/i', $u['host']) && function_exists('idn_to_ascii') && ($idnahost = idn_to_ascii($GLOBALS['it_html']->p['charset'] == "iso-8859-1" ? utf8_encode($u['host']) : $u['host'])) ? $idnahost : $u['host']; # Punycode hostname to include into webpage - $u['host'] = preg_replace_callback('/[^-_.0-9a-z\x80-\xff]/i', function($m) { return rawurlencode($m[0]); }, $u['host']); # Encode garbage chars in host - - # handle scheme, user (urlencoded), password, host - $hostpart = - ($u['user'] ? preg_replace_callback('|[^-a-z0-9_.+!*(),:?@&=/~$%#]|i', function($m) { return urlencode($m[0]); }, $u['user'] . ($u['pass'] ? ":" . $u['pass'] : "") . "@") : "") . - ($u['host'] ? $u['host'] : "") . - ($u['port'] ? ":" . intval($u['port']) : ""); - - $schemepart = $hostpart ? ($u['scheme'] ? $u['scheme'] . ":" : "") . "//$hostpart" : ""; - - $path = $u['path'] . ($u['query'] ? "?" . $u['query'] : "") . ($u['fragment'] ? "#" . $u['fragment'] : ""); - - # hack: encode % if not followed by two hex digits - $parts = preg_split('/%([^%]{0,2})/', $path, -1, PREG_SPLIT_DELIM_CAPTURE); - for ($i = 1; $i < count($parts); $i+=2) - $parts[$i] = (preg_match('/[0-9a-f][0-9a-f]/i', $parts[$i]) ? "%" : "%25") . $parts[$i]; - $path = join("", $parts); - - $path = preg_replace_callback('|[^-a-z0-9_.+!*(),:?@&=/~$%#]|i', function($m) { return urlencode($m[0]); }, $path); - $path = preg_replace('|^([a-z0-9_]+:)?//[^/]*$|', '$0/', $path); # Add slash if absolute url without a path, e.g. http://gna.ch - $queryparams = it_url::params($params); - $separator = strpos($path, "?") === false ? "?" : "&"; - - return $schemepart . $path . ($queryparams ? "$separator$queryparams" : ""); -} - - -/** - * Insert a javascript script - * @param ... any number optional data or array of key => value arguments - * @return <script type="text/javascript"...>...</script> - */ -function js($args) -{ - if (($this->p['htmltype'] != 'html') && $args[0] && ((array)$args[0] === array_values((array)$args[0]))) - { - array_unshift($args, "<!--//--><![CDATA[//><!--\n"); - $args[] = "\n//--><!]]>"; - } - - array_unshift($args, array('type' => 'text/javascript')); - return $this->_tag('script', $args); -} - - -/** - * Include javascript code or generate HTML to include it - */ -function _itjs($files, $mode) -{ - $result = ""; - - if ($files) - { - $filenames = itjs::filenames($files); - - if ($mode == "files") - { - foreach ($filenames as $file) - $result .= tag('script', array('type' => "text/javascript", 'src' => "/itjs/" . basename($file) . "?v=" . itjs::checksum($file))); - } - else if ($mode == "inline") - { - $jsfile = ""; - - foreach ($filenames as $file) - $jsfile .= @file_get_contents($file); - - $result .= itjs::strip($jsfile); - } - else - $result .= tag('script', array('type' => "text/javascript", 'src' => "/itjs/$files?v=" . itjs::checksum($filenames))); - } - - return $result; -} - -} -?> |