summaryrefslogtreecommitdiffstats
path: root/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef')
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS.php87
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/AlphaValue.php21
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Background.php87
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php133
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Border.php43
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Color.php78
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Composite.php38
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php28
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Filter.php54
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Font.php149
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/FontFamily.php197
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Ident.php24
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php40
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Length.php47
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/ListStyle.php78
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Multiple.php58
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Number.php69
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Percentage.php40
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/TextDecoration.php38
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/URI.php61
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/Clone.php28
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/Enum.php65
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Bool.php28
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Class.php34
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Color.php33
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/FrameTarget.php21
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/ID.php80
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Length.php41
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/LinkTypes.php53
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/MultiLength.php41
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Nmtokens.php52
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/Pixels.php48
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/Integer.php73
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/Lang.php73
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/Switch.php34
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/Text.php15
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/URI.php77
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email.php17
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Email/SimpleCheck.php21
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/URI/Host.php101
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv4.php39
-rw-r--r--3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/URI/IPv6.php99
42 files changed, 2443 insertions, 0 deletions
diff --git a/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS.php b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS.php
new file mode 100644
index 000000000..1e7b886ec
--- /dev/null
+++ b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS.php
@@ -0,0 +1,87 @@
+<?php
+
+/**
+ * Validates the HTML attribute style, otherwise known as CSS.
+ * @note We don't implement the whole CSS specification, so it might be
+ * difficult to reuse this component in the context of validating
+ * actual stylesheet declarations.
+ * @note If we were really serious about validating the CSS, we would
+ * tokenize the styles and then parse the tokens. Obviously, we
+ * are not doing that. Doing that could seriously harm performance,
+ * but would make these components a lot more viable for a CSS
+ * filtering solution.
+ */
+class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
+{
+
+ public function validate($css, $config, $context) {
+
+ $css = $this->parseCDATA($css);
+
+ $definition = $config->getCSSDefinition();
+
+ // we're going to break the spec and explode by semicolons.
+ // This is because semicolon rarely appears in escaped form
+ // Doing this is generally flaky but fast
+ // IT MIGHT APPEAR IN URIs, see HTMLPurifier_AttrDef_CSSURI
+ // for details
+
+ $declarations = explode(';', $css);
+ $propvalues = array();
+
+ /**
+ * Name of the current CSS property being validated.
+ */
+ $property = false;
+ $context->register('CurrentCSSProperty', $property);
+
+ foreach ($declarations as $declaration) {
+ if (!$declaration) continue;
+ if (!strpos($declaration, ':')) continue;
+ list($property, $value) = explode(':', $declaration, 2);
+ $property = trim($property);
+ $value = trim($value);
+ $ok = false;
+ do {
+ if (isset($definition->info[$property])) {
+ $ok = true;
+ break;
+ }
+ if (ctype_lower($property)) break;
+ $property = strtolower($property);
+ if (isset($definition->info[$property])) {
+ $ok = true;
+ break;
+ }
+ } while(0);
+ if (!$ok) continue;
+ // inefficient call, since the validator will do this again
+ if (strtolower(trim($value)) !== 'inherit') {
+ // inherit works for everything (but only on the base property)
+ $result = $definition->info[$property]->validate(
+ $value, $config, $context );
+ } else {
+ $result = 'inherit';
+ }
+ if ($result === false) continue;
+ $propvalues[$property] = $result;
+ }
+
+ $context->destroy('CurrentCSSProperty');
+
+ // procedure does not write the new CSS simultaneously, so it's
+ // slightly inefficient, but it's the only way of getting rid of
+ // duplicates. Perhaps config to optimize it, but not now.
+
+ $new_declarations = '';
+ foreach ($propvalues as $prop => $value) {
+ $new_declarations .= "$prop:$value;";
+ }
+
+ return $new_declarations ? $new_declarations : false;
+
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/AlphaValue.php b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/AlphaValue.php
new file mode 100644
index 000000000..93db63f2c
--- /dev/null
+++ b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/AlphaValue.php
@@ -0,0 +1,21 @@
+<?php
+
+class HTMLPurifier_AttrDef_CSS_AlphaValue extends HTMLPurifier_AttrDef_CSS_Number
+{
+
+ public function __construct() {
+ parent::__construct(false); // opacity is non-negative, but we will clamp it
+ }
+
+ public function validate($number, $config, $context) {
+ $result = parent::validate($number, $config, $context);
+ if ($result === false) return $result;
+ $float = (float) $result;
+ if ($float < 0.0) $result = '0';
+ if ($float > 1.0) $result = '1';
+ return $result;
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Background.php b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Background.php
new file mode 100644
index 000000000..dd2804038
--- /dev/null
+++ b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Background.php
@@ -0,0 +1,87 @@
+<?php
+
+/**
+ * Validates shorthand CSS property background.
+ * @warning Does not support url tokens that have internal spaces.
+ */
+class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
+{
+
+ /**
+ * Local copy of component validators.
+ * @note See HTMLPurifier_AttrDef_Font::$info for a similar impl.
+ */
+ protected $info;
+
+ public function __construct($config) {
+ $def = $config->getCSSDefinition();
+ $this->info['background-color'] = $def->info['background-color'];
+ $this->info['background-image'] = $def->info['background-image'];
+ $this->info['background-repeat'] = $def->info['background-repeat'];
+ $this->info['background-attachment'] = $def->info['background-attachment'];
+ $this->info['background-position'] = $def->info['background-position'];
+ }
+
+ public function validate($string, $config, $context) {
+
+ // regular pre-processing
+ $string = $this->parseCDATA($string);
+ if ($string === '') return false;
+
+ // munge rgb() decl if necessary
+ $string = $this->mungeRgb($string);
+
+ // assumes URI doesn't have spaces in it
+ $bits = explode(' ', $string); // bits to process
+
+ $caught = array();
+ $caught['color'] = false;
+ $caught['image'] = false;
+ $caught['repeat'] = false;
+ $caught['attachment'] = false;
+ $caught['position'] = false;
+
+ $i = 0; // number of catches
+ $none = false;
+
+ foreach ($bits as $bit) {
+ if ($bit === '') continue;
+ foreach ($caught as $key => $status) {
+ if ($key != 'position') {
+ if ($status !== false) continue;
+ $r = $this->info['background-' . $key]->validate($bit, $config, $context);
+ } else {
+ $r = $bit;
+ }
+ if ($r === false) continue;
+ if ($key == 'position') {
+ if ($caught[$key] === false) $caught[$key] = '';
+ $caught[$key] .= $r . ' ';
+ } else {
+ $caught[$key] = $r;
+ }
+ $i++;
+ break;
+ }
+ }
+
+ if (!$i) return false;
+ if ($caught['position'] !== false) {
+ $caught['position'] = $this->info['background-position']->
+ validate($caught['position'], $config, $context);
+ }
+
+ $ret = array();
+ foreach ($caught as $value) {
+ if ($value === false) continue;
+ $ret[] = $value;
+ }
+
+ if (empty($ret)) return false;
+ return implode(' ', $ret);
+
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php
new file mode 100644
index 000000000..6627218e1
--- /dev/null
+++ b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php
@@ -0,0 +1,133 @@
+<?php
+
+/* W3C says:
+ [ // adjective and number must be in correct order, even if
+ // you could switch them without introducing ambiguity.
+ // some browsers support that syntax
+ [
+ <percentage> | <length> | left | center | right
+ ]
+ [
+ <percentage> | <length> | top | center | bottom
+ ]?
+ ] |
+ [ // this signifies that the vertical and horizontal adjectives
+ // can be arbitrarily ordered, however, there can only be two,
+ // one of each, or none at all
+ [
+ left | center | right
+ ] ||
+ [
+ top | center | bottom
+ ]
+ ]
+ top, left = 0%
+ center, (none) = 50%
+ bottom, right = 100%
+*/
+
+/* QuirksMode says:
+ keyword + length/percentage must be ordered correctly, as per W3C
+
+ Internet Explorer and Opera, however, support arbitrary ordering. We
+ should fix it up.
+
+ Minor issue though, not strictly necessary.
+*/
+
+// control freaks may appreciate the ability to convert these to
+// percentages or something, but it's not necessary
+
+/**
+ * Validates the value of background-position.
+ */
+class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
+{
+
+ protected $length;
+ protected $percentage;
+
+ public function __construct() {
+ $this->length = new HTMLPurifier_AttrDef_CSS_Length();
+ $this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage();
+ }
+
+ public function validate($string, $config, $context) {
+ $string = $this->parseCDATA($string);
+ $bits = explode(' ', $string);
+
+ $keywords = array();
+ $keywords['h'] = false; // left, right
+ $keywords['v'] = false; // top, bottom
+ $keywords['ch'] = false; // center (first word)
+ $keywords['cv'] = false; // center (second word)
+ $measures = array();
+
+ $i = 0;
+
+ $lookup = array(
+ 'top' => 'v',
+ 'bottom' => 'v',
+ 'left' => 'h',
+ 'right' => 'h',
+ 'center' => 'c'
+ );
+
+ foreach ($bits as $bit) {
+ if ($bit === '') continue;
+
+ // test for keyword
+ $lbit = ctype_lower($bit) ? $bit : strtolower($bit);
+ if (isset($lookup[$lbit])) {
+ $status = $lookup[$lbit];
+ if ($status == 'c') {
+ if ($i == 0) {
+ $status = 'ch';
+ } else {
+ $status = 'cv';
+ }
+ }
+ $keywords[$status] = $lbit;
+ $i++;
+ }
+
+ // test for length
+ $r = $this->length->validate($bit, $config, $context);
+ if ($r !== false) {
+ $measures[] = $r;
+ $i++;
+ }
+
+ // test for percentage
+ $r = $this->percentage->validate($bit, $config, $context);
+ if ($r !== false) {
+ $measures[] = $r;
+ $i++;
+ }
+
+ }
+
+ if (!$i) return false; // no valid values were caught
+
+ $ret = array();
+
+ // first keyword
+ if ($keywords['h']) $ret[] = $keywords['h'];
+ elseif ($keywords['ch']) {
+ $ret[] = $keywords['ch'];
+ $keywords['cv'] = false; // prevent re-use: center = center center
+ }
+ elseif (count($measures)) $ret[] = array_shift($measures);
+
+ if ($keywords['v']) $ret[] = $keywords['v'];
+ elseif ($keywords['cv']) $ret[] = $keywords['cv'];
+ elseif (count($measures)) $ret[] = array_shift($measures);
+
+ if (empty($ret)) return false;
+ return implode(' ', $ret);
+
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Border.php b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Border.php
new file mode 100644
index 000000000..c3e279fc4
--- /dev/null
+++ b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Border.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * Validates the border property as defined by CSS.
+ */
+class HTMLPurifier_AttrDef_CSS_Border extends HTMLPurifier_AttrDef
+{
+
+ /**
+ * Local copy of properties this property is shorthand for.
+ */
+ protected $info = array();
+
+ public function __construct($config) {
+ $def = $config->getCSSDefinition();
+ $this->info['border-width'] = $def->info['border-width'];
+ $this->info['border-style'] = $def->info['border-style'];
+ $this->info['border-top-color'] = $def->info['border-top-color'];
+ }
+
+ public function validate($string, $config, $context) {
+ $string = $this->parseCDATA($string);
+ $string = $this->mungeRgb($string);
+ $bits = explode(' ', $string);
+ $done = array(); // segments we've finished
+ $ret = ''; // return value
+ foreach ($bits as $bit) {
+ foreach ($this->info as $propname => $validator) {
+ if (isset($done[$propname])) continue;
+ $r = $validator->validate($bit, $config, $context);
+ if ($r !== false) {
+ $ret .= $r . ' ';
+ $done[$propname] = true;
+ break;
+ }
+ }
+ }
+ return rtrim($ret);
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Color.php b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Color.php
new file mode 100644
index 000000000..ec999d652
--- /dev/null
+++ b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Color.php
@@ -0,0 +1,78 @@
+<?php
+
+/**
+ * Validates Color as defined by CSS.
+ */
+class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
+{
+
+ public function validate($color, $config, $context) {
+
+ static $colors = null;
+ if ($colors === null) $colors = $config->get('Core.ColorKeywords');
+
+ $color = trim($color);
+ if ($color === '') return false;
+
+ $lower = strtolower($color);
+ if (isset($colors[$lower])) return $colors[$lower];
+
+ if (strpos($color, 'rgb(') !== false) {
+ // rgb literal handling
+ $length = strlen($color);
+ if (strpos($color, ')') !== $length - 1) return false;
+ $triad = substr($color, 4, $length - 4 - 1);
+ $parts = explode(',', $triad);
+ if (count($parts) !== 3) return false;
+ $type = false; // to ensure that they're all the same type
+ $new_parts = array();
+ foreach ($parts as $part) {
+ $part = trim($part);
+ if ($part === '') return false;
+ $length = strlen($part);
+ if ($part[$length - 1] === '%') {
+ // handle percents
+ if (!$type) {
+ $type = 'percentage';
+ } elseif ($type !== 'percentage') {
+ return false;
+ }
+ $num = (float) substr($part, 0, $length - 1);
+ if ($num < 0) $num = 0;
+ if ($num > 100) $num = 100;
+ $new_parts[] = "$num%";
+ } else {
+ // handle integers
+ if (!$type) {
+ $type = 'integer';
+ } elseif ($type !== 'integer') {
+ return false;
+ }
+ $num = (int) $part;
+ if ($num < 0) $num = 0;
+ if ($num > 255) $num = 255;
+ $new_parts[] = (string) $num;
+ }
+ }
+ $new_triad = implode(',', $new_parts);
+ $color = "rgb($new_triad)";
+ } else {
+ // hexadecimal handling
+ if ($color[0] === '#') {
+ $hex = substr($color, 1);
+ } else {
+ $hex = $color;
+ $color = '#' . $color;
+ }
+ $length = strlen($hex);
+ if ($length !== 3 && $length !== 6) return false;
+ if (!ctype_xdigit($hex)) return false;
+ }
+
+ return $color;
+
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Composite.php b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Composite.php
new file mode 100644
index 000000000..9e9f071e2
--- /dev/null
+++ b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Composite.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * Allows multiple validators to attempt to validate attribute.
+ *
+ * Composite is just what it sounds like: a composite of many validators.
+ * This means that multiple HTMLPurifier_AttrDef objects will have a whack
+ * at the string. If one of them passes, that's what is returned. This is
+ * especially useful for CSS values, which often are a choice between
+ * an enumerated set of predefined values or a flexible data type.
+ */
+class HTMLPurifier_AttrDef_CSS_Composite extends HTMLPurifier_AttrDef
+{
+
+ /**
+ * List of HTMLPurifier_AttrDef objects that may process strings
+ * @todo Make protected
+ */
+ public $defs;
+
+ /**
+ * @param $defs List of HTMLPurifier_AttrDef objects
+ */
+ public function __construct($defs) {
+ $this->defs = $defs;
+ }
+
+ public function validate($string, $config, $context) {
+ foreach ($this->defs as $i => $def) {
+ $result = $this->defs[$i]->validate($string, $config, $context);
+ if ($result !== false) return $result;
+ }
+ return false;
+ }
+
+}
+
+// vim: et sw=4 sts=4
diff --git a/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php
new file mode 100644
index 000000000..52cac2ac8
--- /dev/null
+++ b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * Decorator which enables CSS properties to be disabled for specific elements.
+ */
+class HTMLPurifier_AttrDef_CSS_DenyElementDecorator extends HTMLPurifier_AttrDef
+{
+ public $def, $element;
+
+ /**
+ * @param $def Definition to wrap
+ * @param $element Element to deny
+ */
+ public function __construct($def, $element) {
+ $this->def = $def;
+ $this->element = $element;
+ }
+ /**
+ * Checks if CurrentToken is set and equal to $this->element
+ */
+ public function validate($string, $config, $context) {
+ $token = $context->get('CurrentToken', true);
+ if ($token && $token->name == $this->element) return false;
+ return $this->def->validate($string, $config, $context);
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Filter.php b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Filter.php
new file mode 100644
index 000000000..4a0fb3319
--- /dev/null
+++ b/3rdparty/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/Filter.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * Microsoft's proprietary filter: CSS property
+ * @note Currently supports the alpha filter. In the future, this will
+ * probably need an extensible framework
+ */
+class HTMLPurifier_AttrDef_CSS_Filter extends HTMLPurifier_AttrDef
+{
+
+ protected $intValidator;
+
+ public function __construct() {
+ $this->intValidator = new HTMLPurifier_AttrDef_Integer();
+ }
+
+ public function validate($value, $config, $context) {
+ $value = $this->parseCDATA($value);
+ if ($value === 'none') return $value;
+ // if we looped this we could support multiple filters
+ $function_length = strcspn($value, '(');
+ $function = trim(substr($value, 0, $function_length));
+ if ($function !== 'alpha' &&
+ $function !== 'Alpha' &&
+ $function !== 'progid:DXImageTransform.Microsoft.Alpha'
+ ) return false;
+ $cursor = $function_length + 1;
+ $parameters_length = strcspn($value, ')', $cursor);
+ $parameters = substr($value, $cursor, $parameters_length);
+ $params = explode(',', $parameters);
+ $ret_params = array();
+ $lookup = array();
+ foreach ($params as $param) {
+ list($key, $value) = explode('=', $param);
+ $key = trim($key);
+ $value = trim($value);
+ if (isset($lookup[$key])) continue;
+ if ($key !== 'opacity') continue;
+ $value = $this-&