PAR1
PAR1...
- // ----
- }
- }
- return null;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/DisplayLinkURI.php b/library/vendor/HTMLPurifier/HTMLPurifier/Injector/DisplayLinkURI.php
deleted file mode 100644
index c19b1bc27..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/DisplayLinkURI.php
+++ /dev/null
@@ -1,40 +0,0 @@
-start->attr['href'])) {
- $url = $token->start->attr['href'];
- unset($token->start->attr['href']);
- $token = array($token, new HTMLPurifier_Token_Text(" ($url)"));
- } else {
- // nothing to display
- }
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/Linkify.php b/library/vendor/HTMLPurifier/HTMLPurifier/Injector/Linkify.php
deleted file mode 100644
index 069708c25..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/Linkify.php
+++ /dev/null
@@ -1,59 +0,0 @@
- array('href'));
-
- /**
- * @param HTMLPurifier_Token $token
- */
- public function handleText(&$token)
- {
- if (!$this->allowsElement('a')) {
- return;
- }
-
- if (strpos($token->data, '://') === false) {
- // our really quick heuristic failed, abort
- // this may not work so well if we want to match things like
- // "google.com", but then again, most people don't
- return;
- }
-
- // there is/are URL(s). Let's split the string:
- // Note: this regex is extremely permissive
- $bits = preg_split('#((?:https?|ftp)://[^\s\'",<>()]+)#Su', $token->data, -1, PREG_SPLIT_DELIM_CAPTURE);
-
-
- $token = array();
-
- // $i = index
- // $c = count
- // $l = is link
- for ($i = 0, $c = count($bits), $l = false; $i < $c; $i++, $l = !$l) {
- if (!$l) {
- if ($bits[$i] === '') {
- continue;
- }
- $token[] = new HTMLPurifier_Token_Text($bits[$i]);
- } else {
- $token[] = new HTMLPurifier_Token_Start('a', array('href' => $bits[$i]));
- $token[] = new HTMLPurifier_Token_Text($bits[$i]);
- $token[] = new HTMLPurifier_Token_End('a');
- }
- }
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/PurifierLinkify.php b/library/vendor/HTMLPurifier/HTMLPurifier/Injector/PurifierLinkify.php
deleted file mode 100644
index cb9046f33..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/PurifierLinkify.php
+++ /dev/null
@@ -1,71 +0,0 @@
- array('href'));
-
- /**
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return string
- */
- public function prepare($config, $context)
- {
- $this->docURL = $config->get('AutoFormat.PurifierLinkify.DocURL');
- return parent::prepare($config, $context);
- }
-
- /**
- * @param HTMLPurifier_Token $token
- */
- public function handleText(&$token)
- {
- if (!$this->allowsElement('a')) {
- return;
- }
- if (strpos($token->data, '%') === false) {
- return;
- }
-
- $bits = preg_split('#%([a-z0-9]+\.[a-z0-9]+)#Si', $token->data, -1, PREG_SPLIT_DELIM_CAPTURE);
- $token = array();
-
- // $i = index
- // $c = count
- // $l = is link
- for ($i = 0, $c = count($bits), $l = false; $i < $c; $i++, $l = !$l) {
- if (!$l) {
- if ($bits[$i] === '') {
- continue;
- }
- $token[] = new HTMLPurifier_Token_Text($bits[$i]);
- } else {
- $token[] = new HTMLPurifier_Token_Start(
- 'a',
- array('href' => str_replace('%s', $bits[$i], $this->docURL))
- );
- $token[] = new HTMLPurifier_Token_Text('%' . $bits[$i]);
- $token[] = new HTMLPurifier_Token_End('a');
- }
- }
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/RemoveEmpty.php b/library/vendor/HTMLPurifier/HTMLPurifier/Injector/RemoveEmpty.php
deleted file mode 100644
index 01353ff1d..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/RemoveEmpty.php
+++ /dev/null
@@ -1,106 +0,0 @@
-config = $config;
- $this->context = $context;
- $this->removeNbsp = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp');
- $this->removeNbspExceptions = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions');
- $this->exclude = $config->get('AutoFormat.RemoveEmpty.Predicate');
- $this->attrValidator = new HTMLPurifier_AttrValidator();
- }
-
- /**
- * @param HTMLPurifier_Token $token
- */
- public function handleElement(&$token)
- {
- if (!$token instanceof HTMLPurifier_Token_Start) {
- return;
- }
- $next = false;
- $deleted = 1; // the current tag
- for ($i = count($this->inputZipper->back) - 1; $i >= 0; $i--, $deleted++) {
- $next = $this->inputZipper->back[$i];
- if ($next instanceof HTMLPurifier_Token_Text) {
- if ($next->is_whitespace) {
- continue;
- }
- if ($this->removeNbsp && !isset($this->removeNbspExceptions[$token->name])) {
- $plain = str_replace("\xC2\xA0", "", $next->data);
- $isWsOrNbsp = $plain === '' || ctype_space($plain);
- if ($isWsOrNbsp) {
- continue;
- }
- }
- }
- break;
- }
- if (!$next || ($next instanceof HTMLPurifier_Token_End && $next->name == $token->name)) {
- $this->attrValidator->validateToken($token, $this->config, $this->context);
- $token->armor['ValidateAttributes'] = true;
- if (isset($this->exclude[$token->name])) {
- $r = true;
- foreach ($this->exclude[$token->name] as $elem) {
- if (!isset($token->attr[$elem])) $r = false;
- }
- if ($r) return;
- }
- if (isset($token->attr['id']) || isset($token->attr['name'])) {
- return;
- }
- $token = $deleted + 1;
- for ($b = 0, $c = count($this->inputZipper->front); $b < $c; $b++) {
- $prev = $this->inputZipper->front[$b];
- if ($prev instanceof HTMLPurifier_Token_Text && $prev->is_whitespace) {
- continue;
- }
- break;
- }
- // This is safe because we removed the token that triggered this.
- $this->rewindOffset($b+$deleted);
- return;
- }
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php b/library/vendor/HTMLPurifier/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php
deleted file mode 100644
index 9ee7aa84d..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php
+++ /dev/null
@@ -1,84 +0,0 @@
-attrValidator = new HTMLPurifier_AttrValidator();
- $this->config = $config;
- $this->context = $context;
- return parent::prepare($config, $context);
- }
-
- /**
- * @param HTMLPurifier_Token $token
- */
- public function handleElement(&$token)
- {
- if ($token->name !== 'span' || !$token instanceof HTMLPurifier_Token_Start) {
- return;
- }
-
- // We need to validate the attributes now since this doesn't normally
- // happen until after MakeWellFormed. If all the attributes are removed
- // the span needs to be removed too.
- $this->attrValidator->validateToken($token, $this->config, $this->context);
- $token->armor['ValidateAttributes'] = true;
-
- if (!empty($token->attr)) {
- return;
- }
-
- $nesting = 0;
- while ($this->forwardUntilEndToken($i, $current, $nesting)) {
- }
-
- if ($current instanceof HTMLPurifier_Token_End && $current->name === 'span') {
- // Mark closing span tag for deletion
- $current->markForDeletion = true;
- // Delete open span tag
- $token = false;
- }
- }
-
- /**
- * @param HTMLPurifier_Token $token
- */
- public function handleEnd(&$token)
- {
- if ($token->markForDeletion) {
- $token = false;
- }
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/SafeObject.php b/library/vendor/HTMLPurifier/HTMLPurifier/Injector/SafeObject.php
deleted file mode 100644
index 3d17e07af..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Injector/SafeObject.php
+++ /dev/null
@@ -1,121 +0,0 @@
- 'never',
- 'allowNetworking' => 'internal',
- );
-
- /**
- * @type array
- */
- protected $allowedParam = array(
- 'wmode' => true,
- 'movie' => true,
- 'flashvars' => true,
- 'src' => true,
- 'allowFullScreen' => true, // if omitted, assume to be 'false'
- );
-
- /**
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return void
- */
- public function prepare($config, $context)
- {
- parent::prepare($config, $context);
- }
-
- /**
- * @param HTMLPurifier_Token $token
- */
- public function handleElement(&$token)
- {
- if ($token->name == 'object') {
- $this->objectStack[] = $token;
- $this->paramStack[] = array();
- $new = array($token);
- foreach ($this->addParam as $name => $value) {
- $new[] = new HTMLPurifier_Token_Empty('param', array('name' => $name, 'value' => $value));
- }
- $token = $new;
- } elseif ($token->name == 'param') {
- $nest = count($this->currentNesting) - 1;
- if ($nest >= 0 && $this->currentNesting[$nest]->name === 'object') {
- $i = count($this->objectStack) - 1;
- if (!isset($token->attr['name'])) {
- $token = false;
- return;
- }
- $n = $token->attr['name'];
- // We need this fix because YouTube doesn't supply a data
- // attribute, which we need if a type is specified. This is
- // *very* Flash specific.
- if (!isset($this->objectStack[$i]->attr['data']) &&
- ($token->attr['name'] == 'movie' || $token->attr['name'] == 'src')
- ) {
- $this->objectStack[$i]->attr['data'] = $token->attr['value'];
- }
- // Check if the parameter is the correct value but has not
- // already been added
- if (!isset($this->paramStack[$i][$n]) &&
- isset($this->addParam[$n]) &&
- $token->attr['name'] === $this->addParam[$n]) {
- // keep token, and add to param stack
- $this->paramStack[$i][$n] = true;
- } elseif (isset($this->allowedParam[$n])) {
- // keep token, don't do anything to it
- // (could possibly check for duplicates here)
- } else {
- $token = false;
- }
- } else {
- // not directly inside an object, DENY!
- $token = false;
- }
- }
- }
-
- public function handleEnd(&$token)
- {
- // This is the WRONG way of handling the object and param stacks;
- // we should be inserting them directly on the relevant object tokens
- // so that the global stack handling handles it.
- if ($token->name == 'object') {
- array_pop($this->objectStack);
- array_pop($this->paramStack);
- }
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Language.php b/library/vendor/HTMLPurifier/HTMLPurifier/Language.php
deleted file mode 100644
index 65277dd43..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Language.php
+++ /dev/null
@@ -1,204 +0,0 @@
-config = $config;
- $this->context = $context;
- }
-
- /**
- * Loads language object with necessary info from factory cache
- * @note This is a lazy loader
- */
- public function load()
- {
- if ($this->_loaded) {
- return;
- }
- $factory = HTMLPurifier_LanguageFactory::instance();
- $factory->loadLanguage($this->code);
- foreach ($factory->keys as $key) {
- $this->$key = $factory->cache[$this->code][$key];
- }
- $this->_loaded = true;
- }
-
- /**
- * Retrieves a localised message.
- * @param string $key string identifier of message
- * @return string localised message
- */
- public function getMessage($key)
- {
- if (!$this->_loaded) {
- $this->load();
- }
- if (!isset($this->messages[$key])) {
- return "[$key]";
- }
- return $this->messages[$key];
- }
-
- /**
- * Retrieves a localised error name.
- * @param int $int error number, corresponding to PHP's error reporting
- * @return string localised message
- */
- public function getErrorName($int)
- {
- if (!$this->_loaded) {
- $this->load();
- }
- if (!isset($this->errorNames[$int])) {
- return "[Error: $int]";
- }
- return $this->errorNames[$int];
- }
-
- /**
- * Converts an array list into a string readable representation
- * @param array $array
- * @return string
- */
- public function listify($array)
- {
- $sep = $this->getMessage('Item separator');
- $sep_last = $this->getMessage('Item separator last');
- $ret = '';
- for ($i = 0, $c = count($array); $i < $c; $i++) {
- if ($i == 0) {
- } elseif ($i + 1 < $c) {
- $ret .= $sep;
- } else {
- $ret .= $sep_last;
- }
- $ret .= $array[$i];
- }
- return $ret;
- }
-
- /**
- * Formats a localised message with passed parameters
- * @param string $key string identifier of message
- * @param array $args Parameters to substitute in
- * @return string localised message
- * @todo Implement conditionals? Right now, some messages make
- * reference to line numbers, but those aren't always available
- */
- public function formatMessage($key, $args = array())
- {
- if (!$this->_loaded) {
- $this->load();
- }
- if (!isset($this->messages[$key])) {
- return "[$key]";
- }
- $raw = $this->messages[$key];
- $subst = array();
- $generator = false;
- foreach ($args as $i => $value) {
- if (is_object($value)) {
- if ($value instanceof HTMLPurifier_Token) {
- // factor this out some time
- if (!$generator) {
- $generator = $this->context->get('Generator');
- }
- if (isset($value->name)) {
- $subst['$'.$i.'.Name'] = $value->name;
- }
- if (isset($value->data)) {
- $subst['$'.$i.'.Data'] = $value->data;
- }
- $subst['$'.$i.'.Compact'] =
- $subst['$'.$i.'.Serialized'] = $generator->generateFromToken($value);
- // a more complex algorithm for compact representation
- // could be introduced for all types of tokens. This
- // may need to be factored out into a dedicated class
- if (!empty($value->attr)) {
- $stripped_token = clone $value;
- $stripped_token->attr = array();
- $subst['$'.$i.'.Compact'] = $generator->generateFromToken($stripped_token);
- }
- $subst['$'.$i.'.Line'] = $value->line ? $value->line : 'unknown';
- }
- continue;
- } elseif (is_array($value)) {
- $keys = array_keys($value);
- if (array_keys($keys) === $keys) {
- // list
- $subst['$'.$i] = $this->listify($value);
- } else {
- // associative array
- // no $i implementation yet, sorry
- $subst['$'.$i.'.Keys'] = $this->listify($keys);
- $subst['$'.$i.'.Values'] = $this->listify(array_values($value));
- }
- continue;
- }
- $subst['$' . $i] = $value;
- }
- return strtr($raw, $subst);
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Language/classes/en-x-test.php b/library/vendor/HTMLPurifier/HTMLPurifier/Language/classes/en-x-test.php
deleted file mode 100644
index 8828f5cde..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Language/classes/en-x-test.php
+++ /dev/null
@@ -1,9 +0,0 @@
- 'HTML Purifier X'
-);
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Language/messages/en-x-testmini.php b/library/vendor/HTMLPurifier/HTMLPurifier/Language/messages/en-x-testmini.php
deleted file mode 100644
index 806c83fbf..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Language/messages/en-x-testmini.php
+++ /dev/null
@@ -1,12 +0,0 @@
- 'HTML Purifier XNone'
-);
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Language/messages/en.php b/library/vendor/HTMLPurifier/HTMLPurifier/Language/messages/en.php
deleted file mode 100644
index c7f197e1e..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Language/messages/en.php
+++ /dev/null
@@ -1,55 +0,0 @@
- 'HTML Purifier',
-// for unit testing purposes
- 'LanguageFactoryTest: Pizza' => 'Pizza',
- 'LanguageTest: List' => '$1',
- 'LanguageTest: Hash' => '$1.Keys; $1.Values',
- 'Item separator' => ', ',
- 'Item separator last' => ' and ', // non-Harvard style
-
- 'ErrorCollector: No errors' => 'No errors detected. However, because error reporting is still incomplete, there may have been errors that the error collector was not notified of; please inspect the output HTML carefully.',
- 'ErrorCollector: At line' => ' at line $line',
- 'ErrorCollector: Incidental errors' => 'Incidental errors',
- 'Lexer: Unclosed comment' => 'Unclosed comment',
- 'Lexer: Unescaped lt' => 'Unescaped less-than sign (<) should be <',
- 'Lexer: Missing gt' => 'Missing greater-than sign (>), previous less-than sign (<) should be escaped',
- 'Lexer: Missing attribute key' => 'Attribute declaration has no key',
- 'Lexer: Missing end quote' => 'Attribute declaration has no end quote',
- 'Lexer: Extracted body' => 'Removed document metadata tags',
- 'Strategy_RemoveForeignElements: Tag transform' => '<$1> element transformed into $CurrentToken.Serialized',
- 'Strategy_RemoveForeignElements: Missing required attribute' => '$CurrentToken.Compact element missing required attribute $1',
- 'Strategy_RemoveForeignElements: Foreign element to text' => 'Unrecognized $CurrentToken.Serialized tag converted to text',
- 'Strategy_RemoveForeignElements: Foreign element removed' => 'Unrecognized $CurrentToken.Serialized tag removed',
- 'Strategy_RemoveForeignElements: Comment removed' => 'Comment containing "$CurrentToken.Data" removed',
- 'Strategy_RemoveForeignElements: Foreign meta element removed' => 'Unrecognized $CurrentToken.Serialized meta tag and all descendants removed',
- 'Strategy_RemoveForeignElements: Token removed to end' => 'Tags and text starting from $1 element where removed to end',
- 'Strategy_RemoveForeignElements: Trailing hyphen in comment removed' => 'Trailing hyphen(s) in comment removed',
- 'Strategy_RemoveForeignElements: Hyphens in comment collapsed' => 'Double hyphens in comments are not allowed, and were collapsed into single hyphens',
- 'Strategy_MakeWellFormed: Unnecessary end tag removed' => 'Unnecessary $CurrentToken.Serialized tag removed',
- 'Strategy_MakeWellFormed: Unnecessary end tag to text' => 'Unnecessary $CurrentToken.Serialized tag converted to text',
- 'Strategy_MakeWellFormed: Tag auto closed' => '$1.Compact started on line $1.Line auto-closed by $CurrentToken.Compact',
- 'Strategy_MakeWellFormed: Tag carryover' => '$1.Compact started on line $1.Line auto-continued into $CurrentToken.Compact',
- 'Strategy_MakeWellFormed: Stray end tag removed' => 'Stray $CurrentToken.Serialized tag removed',
- 'Strategy_MakeWellFormed: Stray end tag to text' => 'Stray $CurrentToken.Serialized tag converted to text',
- 'Strategy_MakeWellFormed: Tag closed by element end' => '$1.Compact tag started on line $1.Line closed by end of $CurrentToken.Serialized',
- 'Strategy_MakeWellFormed: Tag closed by document end' => '$1.Compact tag started on line $1.Line closed by end of document',
- 'Strategy_FixNesting: Node removed' => '$CurrentToken.Compact node removed',
- 'Strategy_FixNesting: Node excluded' => '$CurrentToken.Compact node removed due to descendant exclusion by ancestor element',
- 'Strategy_FixNesting: Node reorganized' => 'Contents of $CurrentToken.Compact node reorganized to enforce its content model',
- 'Strategy_FixNesting: Node contents removed' => 'Contents of $CurrentToken.Compact node removed',
- 'AttrValidator: Attributes transformed' => 'Attributes on $CurrentToken.Compact transformed from $1.Keys to $2.Keys',
- 'AttrValidator: Attribute removed' => '$CurrentAttr.Name attribute on $CurrentToken.Compact removed',
-);
-
-$errorNames = array(
- E_ERROR => 'Error',
- E_WARNING => 'Warning',
- E_NOTICE => 'Notice'
-);
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/LanguageFactory.php b/library/vendor/HTMLPurifier/HTMLPurifier/LanguageFactory.php
deleted file mode 100644
index 4e35272d8..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/LanguageFactory.php
+++ /dev/null
@@ -1,209 +0,0 @@
-cache[$language_code][$key] = $value
- * @type array
- */
- public $cache;
-
- /**
- * Valid keys in the HTMLPurifier_Language object. Designates which
- * variables to slurp out of a message file.
- * @type array
- */
- public $keys = array('fallback', 'messages', 'errorNames');
-
- /**
- * Instance to validate language codes.
- * @type HTMLPurifier_AttrDef_Lang
- *
- */
- protected $validator;
-
- /**
- * Cached copy of dirname(__FILE__), directory of current file without
- * trailing slash.
- * @type string
- */
- protected $dir;
-
- /**
- * Keys whose contents are a hash map and can be merged.
- * @type array
- */
- protected $mergeable_keys_map = array('messages' => true, 'errorNames' => true);
-
- /**
- * Keys whose contents are a list and can be merged.
- * @value array lookup
- */
- protected $mergeable_keys_list = array();
-
- /**
- * Retrieve sole instance of the factory.
- * @param HTMLPurifier_LanguageFactory $prototype Optional prototype to overload sole instance with,
- * or bool true to reset to default factory.
- * @return HTMLPurifier_LanguageFactory
- */
- public static function instance($prototype = null)
- {
- static $instance = null;
- if ($prototype !== null) {
- $instance = $prototype;
- } elseif ($instance === null || $prototype == true) {
- $instance = new HTMLPurifier_LanguageFactory();
- $instance->setup();
- }
- return $instance;
- }
-
- /**
- * Sets up the singleton, much like a constructor
- * @note Prevents people from getting this outside of the singleton
- */
- public function setup()
- {
- $this->validator = new HTMLPurifier_AttrDef_Lang();
- $this->dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier';
- }
-
- /**
- * Creates a language object, handles class fallbacks
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @param bool|string $code Code to override configuration with. Private parameter.
- * @return HTMLPurifier_Language
- */
- public function create($config, $context, $code = false)
- {
- // validate language code
- if ($code === false) {
- $code = $this->validator->validate(
- $config->get('Core.Language'),
- $config,
- $context
- );
- } else {
- $code = $this->validator->validate($code, $config, $context);
- }
- if ($code === false) {
- $code = 'en'; // malformed code becomes English
- }
-
- $pcode = str_replace('-', '_', $code); // make valid PHP classname
- static $depth = 0; // recursion protection
-
- if ($code == 'en') {
- $lang = new HTMLPurifier_Language($config, $context);
- } else {
- $class = 'HTMLPurifier_Language_' . $pcode;
- $file = $this->dir . '/Language/classes/' . $code . '.php';
- if (file_exists($file) || class_exists($class, false)) {
- $lang = new $class($config, $context);
- } else {
- // Go fallback
- $raw_fallback = $this->getFallbackFor($code);
- $fallback = $raw_fallback ? $raw_fallback : 'en';
- $depth++;
- $lang = $this->create($config, $context, $fallback);
- if (!$raw_fallback) {
- $lang->error = true;
- }
- $depth--;
- }
- }
- $lang->code = $code;
- return $lang;
- }
-
- /**
- * Returns the fallback language for language
- * @note Loads the original language into cache
- * @param string $code language code
- * @return string|bool
- */
- public function getFallbackFor($code)
- {
- $this->loadLanguage($code);
- return $this->cache[$code]['fallback'];
- }
-
- /**
- * Loads language into the cache, handles message file and fallbacks
- * @param string $code language code
- */
- public function loadLanguage($code)
- {
- static $languages_seen = array(); // recursion guard
-
- // abort if we've already loaded it
- if (isset($this->cache[$code])) {
- return;
- }
-
- // generate filename
- $filename = $this->dir . '/Language/messages/' . $code . '.php';
-
- // default fallback : may be overwritten by the ensuing include
- $fallback = ($code != 'en') ? 'en' : false;
-
- // load primary localisation
- if (!file_exists($filename)) {
- // skip the include: will rely solely on fallback
- $filename = $this->dir . '/Language/messages/en.php';
- $cache = array();
- } else {
- include $filename;
- $cache = compact($this->keys);
- }
-
- // load fallback localisation
- if (!empty($fallback)) {
-
- // infinite recursion guard
- if (isset($languages_seen[$code])) {
- trigger_error(
- 'Circular fallback reference in language ' .
- $code,
- E_USER_ERROR
- );
- $fallback = 'en';
- }
- $language_seen[$code] = true;
-
- // load the fallback recursively
- $this->loadLanguage($fallback);
- $fallback_cache = $this->cache[$fallback];
-
- // merge fallback with current language
- foreach ($this->keys as $key) {
- if (isset($cache[$key]) && isset($fallback_cache[$key])) {
- if (isset($this->mergeable_keys_map[$key])) {
- $cache[$key] = $cache[$key] + $fallback_cache[$key];
- } elseif (isset($this->mergeable_keys_list[$key])) {
- $cache[$key] = array_merge($fallback_cache[$key], $cache[$key]);
- }
- } else {
- $cache[$key] = $fallback_cache[$key];
- }
- }
- }
-
- // save to cache for later retrieval
- $this->cache[$code] = $cache;
- return;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Length.php b/library/vendor/HTMLPurifier/HTMLPurifier/Length.php
deleted file mode 100644
index bbfbe6624..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Length.php
+++ /dev/null
@@ -1,160 +0,0 @@
- true, 'ex' => true, 'px' => true, 'in' => true,
- 'cm' => true, 'mm' => true, 'pt' => true, 'pc' => true
- );
-
- /**
- * @param string $n Magnitude
- * @param bool|string $u Unit
- */
- public function __construct($n = '0', $u = false)
- {
- $this->n = (string) $n;
- $this->unit = $u !== false ? (string) $u : false;
- }
-
- /**
- * @param string $s Unit string, like '2em' or '3.4in'
- * @return HTMLPurifier_Length
- * @warning Does not perform validation.
- */
- public static function make($s)
- {
- if ($s instanceof HTMLPurifier_Length) {
- return $s;
- }
- $n_length = strspn($s, '1234567890.+-');
- $n = substr($s, 0, $n_length);
- $unit = substr($s, $n_length);
- if ($unit === '') {
- $unit = false;
- }
- return new HTMLPurifier_Length($n, $unit);
- }
-
- /**
- * Validates the number and unit.
- * @return bool
- */
- protected function validate()
- {
- // Special case:
- if ($this->n === '+0' || $this->n === '-0') {
- $this->n = '0';
- }
- if ($this->n === '0' && $this->unit === false) {
- return true;
- }
- if (!ctype_lower($this->unit)) {
- $this->unit = strtolower($this->unit);
- }
- if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) {
- return false;
- }
- // Hack:
- $def = new HTMLPurifier_AttrDef_CSS_Number();
- $result = $def->validate($this->n, false, false);
- if ($result === false) {
- return false;
- }
- $this->n = $result;
- return true;
- }
-
- /**
- * Returns string representation of number.
- * @return string
- */
- public function toString()
- {
- if (!$this->isValid()) {
- return false;
- }
- return $this->n . $this->unit;
- }
-
- /**
- * Retrieves string numeric magnitude.
- * @return string
- */
- public function getN()
- {
- return $this->n;
- }
-
- /**
- * Retrieves string unit.
- * @return string
- */
- public function getUnit()
- {
- return $this->unit;
- }
-
- /**
- * Returns true if this length unit is valid.
- * @return bool
- */
- public function isValid()
- {
- if ($this->isValid === null) {
- $this->isValid = $this->validate();
- }
- return $this->isValid;
- }
-
- /**
- * Compares two lengths, and returns 1 if greater, -1 if less and 0 if equal.
- * @param HTMLPurifier_Length $l
- * @return int
- * @warning If both values are too large or small, this calculation will
- * not work properly
- */
- public function compareTo($l)
- {
- if ($l === false) {
- return false;
- }
- if ($l->unit !== $this->unit) {
- $converter = new HTMLPurifier_UnitConverter();
- $l = $converter->convert($l, $this->unit);
- if ($l === false) {
- return false;
- }
- }
- return $this->n - $l->n;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Lexer.php b/library/vendor/HTMLPurifier/HTMLPurifier/Lexer.php
deleted file mode 100644
index 43732621d..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Lexer.php
+++ /dev/null
@@ -1,357 +0,0 @@
-get('Core.LexerImpl');
- }
-
- $needs_tracking =
- $config->get('Core.MaintainLineNumbers') ||
- $config->get('Core.CollectErrors');
-
- $inst = null;
- if (is_object($lexer)) {
- $inst = $lexer;
- } else {
- if (is_null($lexer)) {
- do {
- // auto-detection algorithm
- if ($needs_tracking) {
- $lexer = 'DirectLex';
- break;
- }
-
- if (class_exists('DOMDocument') &&
- method_exists('DOMDocument', 'loadHTML') &&
- !extension_loaded('domxml')
- ) {
- // check for DOM support, because while it's part of the
- // core, it can be disabled compile time. Also, the PECL
- // domxml extension overrides the default DOM, and is evil
- // and nasty and we shan't bother to support it
- $lexer = 'DOMLex';
- } else {
- $lexer = 'DirectLex';
- }
- } while (0);
- } // do..while so we can break
-
- // instantiate recognized string names
- switch ($lexer) {
- case 'DOMLex':
- $inst = new HTMLPurifier_Lexer_DOMLex();
- break;
- case 'DirectLex':
- $inst = new HTMLPurifier_Lexer_DirectLex();
- break;
- case 'PH5P':
- $inst = new HTMLPurifier_Lexer_PH5P();
- break;
- default:
- throw new HTMLPurifier_Exception(
- "Cannot instantiate unrecognized Lexer type " .
- htmlspecialchars($lexer)
- );
- }
- }
-
- if (!$inst) {
- throw new HTMLPurifier_Exception('No lexer was instantiated');
- }
-
- // once PHP DOM implements native line numbers, or we
- // hack out something using XSLT, remove this stipulation
- if ($needs_tracking && !$inst->tracksLineNumbers) {
- throw new HTMLPurifier_Exception(
- 'Cannot use lexer that does not support line numbers with ' .
- 'Core.MaintainLineNumbers or Core.CollectErrors (use DirectLex instead)'
- );
- }
-
- return $inst;
-
- }
-
- // -- CONVENIENCE MEMBERS ---------------------------------------------
-
- public function __construct()
- {
- $this->_entity_parser = new HTMLPurifier_EntityParser();
- }
-
- /**
- * Most common entity to raw value conversion table for special entities.
- * @type array
- */
- protected $_special_entity2str =
- array(
- '"' => '"',
- '&' => '&',
- '<' => '<',
- '>' => '>',
- ''' => "'",
- ''' => "'",
- ''' => "'"
- );
-
- /**
- * Parses special entities into the proper characters.
- *
- * This string will translate escaped versions of the special characters
- * into the correct ones.
- *
- * @warning
- * You should be able to treat the output of this function as
- * completely parsed, but that's only because all other entities should
- * have been handled previously in substituteNonSpecialEntities()
- *
- * @param string $string String character data to be parsed.
- * @return string Parsed character data.
- */
- public function parseData($string)
- {
- // following functions require at least one character
- if ($string === '') {
- return '';
- }
-
- // subtracts amps that cannot possibly be escaped
- $num_amp = substr_count($string, '&') - substr_count($string, '& ') -
- ($string[strlen($string) - 1] === '&' ? 1 : 0);
-
- if (!$num_amp) {
- return $string;
- } // abort if no entities
- $num_esc_amp = substr_count($string, '&');
- $string = strtr($string, $this->_special_entity2str);
-
- // code duplication for sake of optimization, see above
- $num_amp_2 = substr_count($string, '&') - substr_count($string, '& ') -
- ($string[strlen($string) - 1] === '&' ? 1 : 0);
-
- if ($num_amp_2 <= $num_esc_amp) {
- return $string;
- }
-
- // hmm... now we have some uncommon entities. Use the callback.
- $string = $this->_entity_parser->substituteSpecialEntities($string);
- return $string;
- }
-
- /**
- * Lexes an HTML string into tokens.
- * @param $string String HTML.
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return HTMLPurifier_Token[] array representation of HTML.
- */
- public function tokenizeHTML($string, $config, $context)
- {
- trigger_error('Call to abstract class', E_USER_ERROR);
- }
-
- /**
- * Translates CDATA sections into regular sections (through escaping).
- * @param string $string HTML string to process.
- * @return string HTML with CDATA sections escaped.
- */
- protected static function escapeCDATA($string)
- {
- return preg_replace_callback(
- '//s',
- array('HTMLPurifier_Lexer', 'CDATACallback'),
- $string
- );
- }
-
- /**
- * Special CDATA case that is especially convoluted for )#si',
- array($this, 'scriptCallback'),
- $html
- );
- }
-
- $html = $this->normalize($html, $config, $context);
-
- $cursor = 0; // our location in the text
- $inside_tag = false; // whether or not we're parsing the inside of a tag
- $array = array(); // result array
-
- // This is also treated to mean maintain *column* numbers too
- $maintain_line_numbers = $config->get('Core.MaintainLineNumbers');
-
- if ($maintain_line_numbers === null) {
- // automatically determine line numbering by checking
- // if error collection is on
- $maintain_line_numbers = $config->get('Core.CollectErrors');
- }
-
- if ($maintain_line_numbers) {
- $current_line = 1;
- $current_col = 0;
- $length = strlen($html);
- } else {
- $current_line = false;
- $current_col = false;
- $length = false;
- }
- $context->register('CurrentLine', $current_line);
- $context->register('CurrentCol', $current_col);
- $nl = "\n";
- // how often to manually recalculate. This will ALWAYS be right,
- // but it's pretty wasteful. Set to 0 to turn off
- $synchronize_interval = $config->get('Core.DirectLexLineNumberSyncInterval');
-
- $e = false;
- if ($config->get('Core.CollectErrors')) {
- $e =& $context->get('ErrorCollector');
- }
-
- // for testing synchronization
- $loops = 0;
-
- while (++$loops) {
- // $cursor is either at the start of a token, or inside of
- // a tag (i.e. there was a < immediately before it), as indicated
- // by $inside_tag
-
- if ($maintain_line_numbers) {
- // $rcursor, however, is always at the start of a token.
- $rcursor = $cursor - (int)$inside_tag;
-
- // Column number is cheap, so we calculate it every round.
- // We're interested at the *end* of the newline string, so
- // we need to add strlen($nl) == 1 to $nl_pos before subtracting it
- // from our "rcursor" position.
- $nl_pos = strrpos($html, $nl, $rcursor - $length);
- $current_col = $rcursor - (is_bool($nl_pos) ? 0 : $nl_pos + 1);
-
- // recalculate lines
- if ($synchronize_interval && // synchronization is on
- $cursor > 0 && // cursor is further than zero
- $loops % $synchronize_interval === 0) { // time to synchronize!
- $current_line = 1 + $this->substrCount($html, $nl, 0, $cursor);
- }
- }
-
- $position_next_lt = strpos($html, '<', $cursor);
- $position_next_gt = strpos($html, '>', $cursor);
-
- // triggers on "asdf" but not "asdf "
- // special case to set up context
- if ($position_next_lt === $cursor) {
- $inside_tag = true;
- $cursor++;
- }
-
- if (!$inside_tag && $position_next_lt !== false) {
- // We are not inside tag and there still is another tag to parse
- $token = new
- HTMLPurifier_Token_Text(
- $this->parseData(
- substr(
- $html,
- $cursor,
- $position_next_lt - $cursor
- )
- )
- );
- if ($maintain_line_numbers) {
- $token->rawPosition($current_line, $current_col);
- $current_line += $this->substrCount($html, $nl, $cursor, $position_next_lt - $cursor);
- }
- $array[] = $token;
- $cursor = $position_next_lt + 1;
- $inside_tag = true;
- continue;
- } elseif (!$inside_tag) {
- // We are not inside tag but there are no more tags
- // If we're already at the end, break
- if ($cursor === strlen($html)) {
- break;
- }
- // Create Text of rest of string
- $token = new
- HTMLPurifier_Token_Text(
- $this->parseData(
- substr(
- $html,
- $cursor
- )
- )
- );
- if ($maintain_line_numbers) {
- $token->rawPosition($current_line, $current_col);
- }
- $array[] = $token;
- break;
- } elseif ($inside_tag && $position_next_gt !== false) {
- // We are in tag and it is well formed
- // Grab the internals of the tag
- $strlen_segment = $position_next_gt - $cursor;
-
- if ($strlen_segment < 1) {
- // there's nothing to process!
- $token = new HTMLPurifier_Token_Text('<');
- $cursor++;
- continue;
- }
-
- $segment = substr($html, $cursor, $strlen_segment);
-
- if ($segment === false) {
- // somehow, we attempted to access beyond the end of
- // the string, defense-in-depth, reported by Nate Abele
- break;
- }
-
- // Check if it's a comment
- if (substr($segment, 0, 3) === '!--') {
- // re-determine segment length, looking for -->
- $position_comment_end = strpos($html, '-->', $cursor);
- if ($position_comment_end === false) {
- // uh oh, we have a comment that extends to
- // infinity. Can't be helped: set comment
- // end position to end of string
- if ($e) {
- $e->send(E_WARNING, 'Lexer: Unclosed comment');
- }
- $position_comment_end = strlen($html);
- $end = true;
- } else {
- $end = false;
- }
- $strlen_segment = $position_comment_end - $cursor;
- $segment = substr($html, $cursor, $strlen_segment);
- $token = new
- HTMLPurifier_Token_Comment(
- substr(
- $segment,
- 3,
- $strlen_segment - 3
- )
- );
- if ($maintain_line_numbers) {
- $token->rawPosition($current_line, $current_col);
- $current_line += $this->substrCount($html, $nl, $cursor, $strlen_segment);
- }
- $array[] = $token;
- $cursor = $end ? $position_comment_end : $position_comment_end + 3;
- $inside_tag = false;
- continue;
- }
-
- // Check if it's an end tag
- $is_end_tag = (strpos($segment, '/') === 0);
- if ($is_end_tag) {
- $type = substr($segment, 1);
- $token = new HTMLPurifier_Token_End($type);
- if ($maintain_line_numbers) {
- $token->rawPosition($current_line, $current_col);
- $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
- }
- $array[] = $token;
- $inside_tag = false;
- $cursor = $position_next_gt + 1;
- continue;
- }
-
- // Check leading character is alnum, if not, we may
- // have accidently grabbed an emoticon. Translate into
- // text and go our merry way
- if (!ctype_alpha($segment[0])) {
- // XML: $segment[0] !== '_' && $segment[0] !== ':'
- if ($e) {
- $e->send(E_NOTICE, 'Lexer: Unescaped lt');
- }
- $token = new HTMLPurifier_Token_Text('<');
- if ($maintain_line_numbers) {
- $token->rawPosition($current_line, $current_col);
- $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
- }
- $array[] = $token;
- $inside_tag = false;
- continue;
- }
-
- // Check if it is explicitly self closing, if so, remove
- // trailing slash. Remember, we could have a tag like
, so
- // any later token processing scripts must convert improperly
- // classified EmptyTags from StartTags.
- $is_self_closing = (strrpos($segment, '/') === $strlen_segment - 1);
- if ($is_self_closing) {
- $strlen_segment--;
- $segment = substr($segment, 0, $strlen_segment);
- }
-
- // Check if there are any attributes
- $position_first_space = strcspn($segment, $this->_whitespace);
-
- if ($position_first_space >= $strlen_segment) {
- if ($is_self_closing) {
- $token = new HTMLPurifier_Token_Empty($segment);
- } else {
- $token = new HTMLPurifier_Token_Start($segment);
- }
- if ($maintain_line_numbers) {
- $token->rawPosition($current_line, $current_col);
- $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
- }
- $array[] = $token;
- $inside_tag = false;
- $cursor = $position_next_gt + 1;
- continue;
- }
-
- // Grab out all the data
- $type = substr($segment, 0, $position_first_space);
- $attribute_string =
- trim(
- substr(
- $segment,
- $position_first_space
- )
- );
- if ($attribute_string) {
- $attr = $this->parseAttributeString(
- $attribute_string,
- $config,
- $context
- );
- } else {
- $attr = array();
- }
-
- if ($is_self_closing) {
- $token = new HTMLPurifier_Token_Empty($type, $attr);
- } else {
- $token = new HTMLPurifier_Token_Start($type, $attr);
- }
- if ($maintain_line_numbers) {
- $token->rawPosition($current_line, $current_col);
- $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
- }
- $array[] = $token;
- $cursor = $position_next_gt + 1;
- $inside_tag = false;
- continue;
- } else {
- // inside tag, but there's no ending > sign
- if ($e) {
- $e->send(E_WARNING, 'Lexer: Missing gt');
- }
- $token = new
- HTMLPurifier_Token_Text(
- '<' .
- $this->parseData(
- substr($html, $cursor)
- )
- );
- if ($maintain_line_numbers) {
- $token->rawPosition($current_line, $current_col);
- }
- // no cursor scroll? Hmm...
- $array[] = $token;
- break;
- }
- break;
- }
-
- $context->destroy('CurrentLine');
- $context->destroy('CurrentCol');
- return $array;
- }
-
- /**
- * PHP 5.0.x compatible substr_count that implements offset and length
- * @param string $haystack
- * @param string $needle
- * @param int $offset
- * @param int $length
- * @return int
- */
- protected function substrCount($haystack, $needle, $offset, $length)
- {
- static $oldVersion;
- if ($oldVersion === null) {
- $oldVersion = version_compare(PHP_VERSION, '5.1', '<');
- }
- if ($oldVersion) {
- $haystack = substr($haystack, $offset, $length);
- return substr_count($haystack, $needle);
- } else {
- return substr_count($haystack, $needle, $offset, $length);
- }
- }
-
- /**
- * Takes the inside of an HTML tag and makes an assoc array of attributes.
- *
- * @param string $string Inside of tag excluding name.
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return array Assoc array of attributes.
- */
- public function parseAttributeString($string, $config, $context)
- {
- $string = (string)$string; // quick typecast
-
- if ($string == '') {
- return array();
- } // no attributes
-
- $e = false;
- if ($config->get('Core.CollectErrors')) {
- $e =& $context->get('ErrorCollector');
- }
-
- // let's see if we can abort as quickly as possible
- // one equal sign, no spaces => one attribute
- $num_equal = substr_count($string, '=');
- $has_space = strpos($string, ' ');
- if ($num_equal === 0 && !$has_space) {
- // bool attribute
- return array($string => $string);
- } elseif ($num_equal === 1 && !$has_space) {
- // only one attribute
- list($key, $quoted_value) = explode('=', $string);
- $quoted_value = trim($quoted_value);
- if (!$key) {
- if ($e) {
- $e->send(E_ERROR, 'Lexer: Missing attribute key');
- }
- return array();
- }
- if (!$quoted_value) {
- return array($key => '');
- }
- $first_char = @$quoted_value[0];
- $last_char = @$quoted_value[strlen($quoted_value) - 1];
-
- $same_quote = ($first_char == $last_char);
- $open_quote = ($first_char == '"' || $first_char == "'");
-
- if ($same_quote && $open_quote) {
- // well behaved
- $value = substr($quoted_value, 1, strlen($quoted_value) - 2);
- } else {
- // not well behaved
- if ($open_quote) {
- if ($e) {
- $e->send(E_ERROR, 'Lexer: Missing end quote');
- }
- $value = substr($quoted_value, 1);
- } else {
- $value = $quoted_value;
- }
- }
- if ($value === false) {
- $value = '';
- }
- return array($key => $this->parseData($value));
- }
-
- // setup loop environment
- $array = array(); // return assoc array of attributes
- $cursor = 0; // current position in string (moves forward)
- $size = strlen($string); // size of the string (stays the same)
-
- // if we have unquoted attributes, the parser expects a terminating
- // space, so let's guarantee that there's always a terminating space.
- $string .= ' ';
-
- $old_cursor = -1;
- while ($cursor < $size) {
- if ($old_cursor >= $cursor) {
- throw new Exception("Infinite loop detected");
- }
- $old_cursor = $cursor;
-
- $cursor += ($value = strspn($string, $this->_whitespace, $cursor));
- // grab the key
-
- $key_begin = $cursor; //we're currently at the start of the key
-
- // scroll past all characters that are the key (not whitespace or =)
- $cursor += strcspn($string, $this->_whitespace . '=', $cursor);
-
- $key_end = $cursor; // now at the end of the key
-
- $key = substr($string, $key_begin, $key_end - $key_begin);
-
- if (!$key) {
- if ($e) {
- $e->send(E_ERROR, 'Lexer: Missing attribute key');
- }
- $cursor += 1 + strcspn($string, $this->_whitespace, $cursor + 1); // prevent infinite loop
- continue; // empty key
- }
-
- // scroll past all whitespace
- $cursor += strspn($string, $this->_whitespace, $cursor);
-
- if ($cursor >= $size) {
- $array[$key] = $key;
- break;
- }
-
- // if the next character is an equal sign, we've got a regular
- // pair, otherwise, it's a bool attribute
- $first_char = @$string[$cursor];
-
- if ($first_char == '=') {
- // key="value"
-
- $cursor++;
- $cursor += strspn($string, $this->_whitespace, $cursor);
-
- if ($cursor === false) {
- $array[$key] = '';
- break;
- }
-
- // we might be in front of a quote right now
-
- $char = @$string[$cursor];
-
- if ($char == '"' || $char == "'") {
- // it's quoted, end bound is $char
- $cursor++;
- $value_begin = $cursor;
- $cursor = strpos($string, $char, $cursor);
- $value_end = $cursor;
- } else {
- // it's not quoted, end bound is whitespace
- $value_begin = $cursor;
- $cursor += strcspn($string, $this->_whitespace, $cursor);
- $value_end = $cursor;
- }
-
- // we reached a premature end
- if ($cursor === false) {
- $cursor = $size;
- $value_end = $cursor;
- }
-
- $value = substr($string, $value_begin, $value_end - $value_begin);
- if ($value === false) {
- $value = '';
- }
- $array[$key] = $this->parseData($value);
- $cursor++;
- } else {
- // boolattr
- if ($key !== '') {
- $array[$key] = $key;
- } else {
- // purely theoretical
- if ($e) {
- $e->send(E_ERROR, 'Lexer: Missing attribute key');
- }
- }
- }
- }
- return $array;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Lexer/PH5P.php b/library/vendor/HTMLPurifier/HTMLPurifier/Lexer/PH5P.php
deleted file mode 100644
index ff4fa218f..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Lexer/PH5P.php
+++ /dev/null
@@ -1,4787 +0,0 @@
-normalize($html, $config, $context);
- $new_html = $this->wrapHTML($new_html, $config, $context);
- try {
- $parser = new HTML5($new_html);
- $doc = $parser->save();
- } catch (DOMException $e) {
- // Uh oh, it failed. Punt to DirectLex.
- $lexer = new HTMLPurifier_Lexer_DirectLex();
- $context->register('PH5PError', $e); // save the error, so we can detect it
- return $lexer->tokenizeHTML($html, $config, $context); // use original HTML
- }
- $tokens = array();
- $this->tokenizeDOM(
- $doc->getElementsByTagName('html')->item(0)-> //
- getElementsByTagName('body')->item(0) //
- ,
- $tokens
- );
- return $tokens;
- }
-}
-
-/*
-
-Copyright 2007 Jeroen van der Meer
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-*/
-
-class HTML5
-{
- private $data;
- private $char;
- private $EOF;
- private $state;
- private $tree;
- private $token;
- private $content_model;
- private $escape = false;
- private $entities = array(
- 'AElig;',
- 'AElig',
- 'AMP;',
- 'AMP',
- 'Aacute;',
- 'Aacute',
- 'Acirc;',
- 'Acirc',
- 'Agrave;',
- 'Agrave',
- 'Alpha;',
- 'Aring;',
- 'Aring',
- 'Atilde;',
- 'Atilde',
- 'Auml;',
- 'Auml',
- 'Beta;',
- 'COPY;',
- 'COPY',
- 'Ccedil;',
- 'Ccedil',
- 'Chi;',
- 'Dagger;',
- 'Delta;',
- 'ETH;',
- 'ETH',
- 'Eacute;',
- 'Eacute',
- 'Ecirc;',
- 'Ecirc',
- 'Egrave;',
- 'Egrave',
- 'Epsilon;',
- 'Eta;',
- 'Euml;',
- 'Euml',
- 'GT;',
- 'GT',
- 'Gamma;',
- 'Iacute;',
- 'Iacute',
- 'Icirc;',
- 'Icirc',
- 'Igrave;',
- 'Igrave',
- 'Iota;',
- 'Iuml;',
- 'Iuml',
- 'Kappa;',
- 'LT;',
- 'LT',
- 'Lambda;',
- 'Mu;',
- 'Ntilde;',
- 'Ntilde',
- 'Nu;',
- 'OElig;',
- 'Oacute;',
- 'Oacute',
- 'Ocirc;',
- 'Ocirc',
- 'Ograve;',
- 'Ograve',
- 'Omega;',
- 'Omicron;',
- 'Oslash;',
- 'Oslash',
- 'Otilde;',
- 'Otilde',
- 'Ouml;',
- 'Ouml',
- 'Phi;',
- 'Pi;',
- 'Prime;',
- 'Psi;',
- 'QUOT;',
- 'QUOT',
- 'REG;',
- 'REG',
- 'Rho;',
- 'Scaron;',
- 'Sigma;',
- 'THORN;',
- 'THORN',
- 'TRADE;',
- 'Tau;',
- 'Theta;',
- 'Uacute;',
- 'Uacute',
- 'Ucirc;',
- 'Ucirc',
- 'Ugrave;',
- 'Ugrave',
- 'Upsilon;',
- 'Uuml;',
- 'Uuml',
- 'Xi;',
- 'Yacute;',
- 'Yacute',
- 'Yuml;',
- 'Zeta;',
- 'aacute;',
- 'aacute',
- 'acirc;',
- 'acirc',
- 'acute;',
- 'acute',
- 'aelig;',
- 'aelig',
- 'agrave;',
- 'agrave',
- 'alefsym;',
- 'alpha;',
- 'amp;',
- 'amp',
- 'and;',
- 'ang;',
- 'apos;',
- 'aring;',
- 'aring',
- 'asymp;',
- 'atilde;',
- 'atilde',
- 'auml;',
- 'auml',
- 'bdquo;',
- 'beta;',
- 'brvbar;',
- 'brvbar',
- 'bull;',
- 'cap;',
- 'ccedil;',
- 'ccedil',
- 'cedil;',
- 'cedil',
- 'cent;',
- 'cent',
- 'chi;',
- 'circ;',
- 'clubs;',
- 'cong;',
- 'copy;',
- 'copy',
- 'crarr;',
- 'cup;',
- 'curren;',
- 'curren',
- 'dArr;',
- 'dagger;',
- 'darr;',
- 'deg;',
- 'deg',
- 'delta;',
- 'diams;',
- 'divide;',
- 'divide',
- 'eacute;',
- 'eacute',
- 'ecirc;',
- 'ecirc',
- 'egrave;',
- 'egrave',
- 'empty;',
- 'emsp;',
- 'ensp;',
- 'epsilon;',
- 'equiv;',
- 'eta;',
- 'eth;',
- 'eth',
- 'euml;',
- 'euml',
- 'euro;',
- 'exist;',
- 'fnof;',
- 'forall;',
- 'frac12;',
- 'frac12',
- 'frac14;',
- 'frac14',
- 'frac34;',
- 'frac34',
- 'frasl;',
- 'gamma;',
- 'ge;',
- 'gt;',
- 'gt',
- 'hArr;',
- 'harr;',
- 'hearts;',
- 'hellip;',
- 'iacute;',
- 'iacute',
- 'icirc;',
- 'icirc',
- 'iexcl;',
- 'iexcl',
- 'igrave;',
- 'igrave',
- 'image;',
- 'infin;',
- 'int;',
- 'iota;',
- 'iquest;',
- 'iquest',
- 'isin;',
- 'iuml;',
- 'iuml',
- 'kappa;',
- 'lArr;',
- 'lambda;',
- 'lang;',
- 'laquo;',
- 'laquo',
- 'larr;',
- 'lceil;',
- 'ldquo;',
- 'le;',
- 'lfloor;',
- 'lowast;',
- 'loz;',
- 'lrm;',
- 'lsaquo;',
- 'lsquo;',
- 'lt;',
- 'lt',
- 'macr;',
- 'macr',
- 'mdash;',
- 'micro;',
- 'micro',
- 'middot;',
- 'middot',
- 'minus;',
- 'mu;',
- 'nabla;',
- 'nbsp;',
- 'nbsp',
- 'ndash;',
- 'ne;',
- 'ni;',
- 'not;',
- 'not',
- 'notin;',
- 'nsub;',
- 'ntilde;',
- 'ntilde',
- 'nu;',
- 'oacute;',
- 'oacute',
- 'ocirc;',
- 'ocirc',
- 'oelig;',
- 'ograve;',
- 'ograve',
- 'oline;',
- 'omega;',
- 'omicron;',
- 'oplus;',
- 'or;',
- 'ordf;',
- 'ordf',
- 'ordm;',
- 'ordm',
- 'oslash;',
- 'oslash',
- 'otilde;',
- 'otilde',
- 'otimes;',
- 'ouml;',
- 'ouml',
- 'para;',
- 'para',
- 'part;',
- 'permil;',
- 'perp;',
- 'phi;',
- 'pi;',
- 'piv;',
- 'plusmn;',
- 'plusmn',
- 'pound;',
- 'pound',
- 'prime;',
- 'prod;',
- 'prop;',
- 'psi;',
- 'quot;',
- 'quot',
- 'rArr;',
- 'radic;',
- 'rang;',
- 'raquo;',
- 'raquo',
- 'rarr;',
- 'rceil;',
- 'rdquo;',
- 'real;',
- 'reg;',
- 'reg',
- 'rfloor;',
- 'rho;',
- 'rlm;',
- 'rsaquo;',
- 'rsquo;',
- 'sbquo;',
- 'scaron;',
- 'sdot;',
- 'sect;',
- 'sect',
- 'shy;',
- 'shy',
- 'sigma;',
- 'sigmaf;',
- 'sim;',
- 'spades;',
- 'sub;',
- 'sube;',
- 'sum;',
- 'sup1;',
- 'sup1',
- 'sup2;',
- 'sup2',
- 'sup3;',
- 'sup3',
- 'sup;',
- 'supe;',
- 'szlig;',
- 'szlig',
- 'tau;',
- 'there4;',
- 'theta;',
- 'thetasym;',
- 'thinsp;',
- 'thorn;',
- 'thorn',
- 'tilde;',
- 'times;',
- 'times',
- 'trade;',
- 'uArr;',
- 'uacute;',
- 'uacute',
- 'uarr;',
- 'ucirc;',
- 'ucirc',
- 'ugrave;',
- 'ugrave',
- 'uml;',
- 'uml',
- 'upsih;',
- 'upsilon;',
- 'uuml;',
- 'uuml',
- 'weierp;',
- 'xi;',
- 'yacute;',
- 'yacute',
- 'yen;',
- 'yen',
- 'yuml;',
- 'yuml',
- 'zeta;',
- 'zwj;',
- 'zwnj;'
- );
-
- const PCDATA = 0;
- const RCDATA = 1;
- const CDATA = 2;
- const PLAINTEXT = 3;
-
- const DOCTYPE = 0;
- const STARTTAG = 1;
- const ENDTAG = 2;
- const COMMENT = 3;
- const CHARACTR = 4;
- const EOF = 5;
-
- public function __construct($data)
- {
- $this->data = $data;
- $this->char = -1;
- $this->EOF = strlen($data);
- $this->tree = new HTML5TreeConstructer;
- $this->content_model = self::PCDATA;
-
- $this->state = 'data';
-
- while ($this->state !== null) {
- $this->{$this->state . 'State'}();
- }
- }
-
- public function save()
- {
- return $this->tree->save();
- }
-
- private function char()
- {
- return ($this->char < $this->EOF)
- ? $this->data[$this->char]
- : false;
- }
-
- private function character($s, $l = 0)
- {
- if ($s + $l < $this->EOF) {
- if ($l === 0) {
- return $this->data[$s];
- } else {
- return substr($this->data, $s, $l);
- }
- }
- }
-
- private function characters($char_class, $start)
- {
- return preg_replace('#^([' . $char_class . ']+).*#s', '\\1', substr($this->data, $start));
- }
-
- private function dataState()
- {
- // Consume the next input character
- $this->char++;
- $char = $this->char();
-
- if ($char === '&' && ($this->content_model === self::PCDATA || $this->content_model === self::RCDATA)) {
- /* U+0026 AMPERSAND (&)
- When the content model flag is set to one of the PCDATA or RCDATA
- states: switch to the entity data state. Otherwise: treat it as per
- the "anything else" entry below. */
- $this->state = 'entityData';
-
- } elseif ($char === '-') {
- /* If the content model flag is set to either the RCDATA state or
- the CDATA state, and the escape flag is false, and there are at
- least three characters before this one in the input stream, and the
- last four characters in the input stream, including this one, are
- U+003C LESS-THAN SIGN, U+0021 EXCLAMATION MARK, U+002D HYPHEN-MINUS,
- and U+002D HYPHEN-MINUS (""),
- set the escape flag to false. */
- if (($this->content_model === self::RCDATA ||
- $this->content_model === self::CDATA) && $this->escape === true &&
- $this->character($this->char, 3) === '-->'
- ) {
- $this->escape = false;
- }
-
- /* In any case, emit the input character as a character token.
- Stay in the data state. */
- $this->emitToken(
- array(
- 'type' => self::CHARACTR,
- 'data' => $char
- )
- );
-
- } elseif ($this->char === $this->EOF) {
- /* EOF
- Emit an end-of-file token. */
- $this->EOF();
-
- } elseif ($this->content_model === self::PLAINTEXT) {
- /* When the content model flag is set to the PLAINTEXT state
- THIS DIFFERS GREATLY FROM THE SPEC: Get the remaining characters of
- the text and emit it as a character token. */
- $this->emitToken(
- array(
- 'type' => self::CHARACTR,
- 'data' => substr($this->data, $this->char)
- )
- );
-
- $this->EOF();
-
- } else {
- /* Anything else
- THIS DIFFERS GREATLY FROM THE SPEC: Get as many character that
- otherwise would also be treated as a character token and emit it
- as a single character token. Stay in the data state. */
- $len = strcspn($this->data, '<&', $this->char);
- $char = substr($this->data, $this->char, $len);
- $this->char += $len - 1;
-
- $this->emitToken(
- array(
- 'type' => self::CHARACTR,
- 'data' => $char
- )
- );
-
- $this->state = 'data';
- }
- }
-
- private function entityDataState()
- {
- // Attempt to consume an entity.
- $entity = $this->entity();
-
- // If nothing is returned, emit a U+0026 AMPERSAND character token.
- // Otherwise, emit the character token that was returned.
- $char = (!$entity) ? '&' : $entity;
- $this->emitToken(
- array(
- 'type' => self::CHARACTR,
- 'data' => $char
- )
- );
-
- // Finally, switch to the data state.
- $this->state = 'data';
- }
-
- private function tagOpenState()
- {
- switch ($this->content_model) {
- case self::RCDATA:
- case self::CDATA:
- /* If the next input character is a U+002F SOLIDUS (/) character,
- consume it and switch to the close tag open state. If the next
- input character is not a U+002F SOLIDUS (/) character, emit a
- U+003C LESS-THAN SIGN character token and switch to the data
- state to process the next input character. */
- if ($this->character($this->char + 1) === '/') {
- $this->char++;
- $this->state = 'closeTagOpen';
-
- } else {
- $this->emitToken(
- array(
- 'type' => self::CHARACTR,
- 'data' => '<'
- )
- );
-
- $this->state = 'data';
- }
- break;
-
- case self::PCDATA:
- // If the content model flag is set to the PCDATA state
- // Consume the next input character:
- $this->char++;
- $char = $this->char();
-
- if ($char === '!') {
- /* U+0021 EXCLAMATION MARK (!)
- Switch to the markup declaration open state. */
- $this->state = 'markupDeclarationOpen';
-
- } elseif ($char === '/') {
- /* U+002F SOLIDUS (/)
- Switch to the close tag open state. */
- $this->state = 'closeTagOpen';
-
- } elseif (preg_match('/^[A-Za-z]$/', $char)) {
- /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z
- Create a new start tag token, set its tag name to the lowercase
- version of the input character (add 0x0020 to the character's code
- point), then switch to the tag name state. (Don't emit the token
- yet; further details will be filled in before it is emitted.) */
- $this->token = array(
- 'name' => strtolower($char),
- 'type' => self::STARTTAG,
- 'attr' => array()
- );
-
- $this->state = 'tagName';
-
- } elseif ($char === '>') {
- /* U+003E GREATER-THAN SIGN (>)
- Parse error. Emit a U+003C LESS-THAN SIGN character token and a
- U+003E GREATER-THAN SIGN character token. Switch to the data state. */
- $this->emitToken(
- array(
- 'type' => self::CHARACTR,
- 'data' => '<>'
- )
- );
-
- $this->state = 'data';
-
- } elseif ($char === '?') {
- /* U+003F QUESTION MARK (?)
- Parse error. Switch to the bogus comment state. */
- $this->state = 'bogusComment';
-
- } else {
- /* Anything else
- Parse error. Emit a U+003C LESS-THAN SIGN character token and
- reconsume the current input character in the data state. */
- $this->emitToken(
- array(
- 'type' => self::CHARACTR,
- 'data' => '<'
- )
- );
-
- $this->char--;
- $this->state = 'data';
- }
- break;
- }
- }
-
- private function closeTagOpenState()
- {
- $next_node = strtolower($this->characters('A-Za-z', $this->char + 1));
- $the_same = count($this->tree->stack) > 0 && $next_node === end($this->tree->stack)->nodeName;
-
- if (($this->content_model === self::RCDATA || $this->content_model === self::CDATA) &&
- (!$the_same || ($the_same && (!preg_match(
- '/[\t\n\x0b\x0c >\/]/',
- $this->character($this->char + 1 + strlen($next_node))
- ) || $this->EOF === $this->char)))
- ) {
- /* If the content model flag is set to the RCDATA or CDATA states then
- examine the next few characters. If they do not match the tag name of
- the last start tag token emitted (case insensitively), or if they do but
- they are not immediately followed by one of the following characters:
- * U+0009 CHARACTER TABULATION
- * U+000A LINE FEED (LF)
- * U+000B LINE TABULATION
- * U+000C FORM FEED (FF)
- * U+0020 SPACE
- * U+003E GREATER-THAN SIGN (>)
- * U+002F SOLIDUS (/)
- * EOF
- ...then there is a parse error. Emit a U+003C LESS-THAN SIGN character
- token, a U+002F SOLIDUS character token, and switch to the data state
- to process the next input character. */
- $this->emitToken(
- array(
- 'type' => self::CHARACTR,
- 'data' => ''
- )
- );
-
- $this->state = 'data';
-
- } else {
- /* Otherwise, if the content model flag is set to the PCDATA state,
- or if the next few characters do match that tag name, consume the
- next input character: */
- $this->char++;
- $char = $this->char();
-
- if (preg_match('/^[A-Za-z]$/', $char)) {
- /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z
- Create a new end tag token, set its tag name to the lowercase version
- of the input character (add 0x0020 to the character's code point), then
- switch to the tag name state. (Don't emit the token yet; further details
- will be filled in before it is emitted.) */
- $this->token = array(
- 'name' => strtolower($char),
- 'type' => self::ENDTAG
- );
-
- $this->state = 'tagName';
-
- } elseif ($char === '>') {
- /* U+003E GREATER-THAN SIGN (>)
- Parse error. Switch to the data state. */
- $this->state = 'data';
-
- } elseif ($this->char === $this->EOF) {
- /* EOF
- Parse error. Emit a U+003C LESS-THAN SIGN character token and a U+002F
- SOLIDUS character token. Reconsume the EOF character in the data state. */
- $this->emitToken(
- array(
- 'type' => self::CHARACTR,
- 'data' => ''
- )
- );
-
- $this->char--;
- $this->state = 'data';
-
- } else {
- /* Parse error. Switch to the bogus comment state. */
- $this->state = 'bogusComment';
- }
- }
- }
-
- private function tagNameState()
- {
- // Consume the next input character:
- $this->char++;
- $char = $this->character($this->char);
-
- if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) {
- /* U+0009 CHARACTER TABULATION
- U+000A LINE FEED (LF)
- U+000B LINE TABULATION
- U+000C FORM FEED (FF)
- U+0020 SPACE
- Switch to the before attribute name state. */
- $this->state = 'beforeAttributeName';
-
- } elseif ($char === '>') {
- /* U+003E GREATER-THAN SIGN (>)
- Emit the current tag token. Switch to the data state. */
- $this->emitToken($this->token);
- $this->state = 'data';
-
- } elseif ($this->char === $this->EOF) {
- /* EOF
- Parse error. Emit the current tag token. Reconsume the EOF
- character in the data state. */
- $this->emitToken($this->token);
-
- $this->char--;
- $this->state = 'data';
-
- } elseif ($char === '/') {
- /* U+002F SOLIDUS (/)
- Parse error unless this is a permitted slash. Switch to the before
- attribute name state. */
- $this->state = 'beforeAttributeName';
-
- } else {
- /* Anything else
- Append the current input character to the current tag token's tag name.
- Stay in the tag name state. */
- $this->token['name'] .= strtolower($char);
- $this->state = 'tagName';
- }
- }
-
- private function beforeAttributeNameState()
- {
- // Consume the next input character:
- $this->char++;
- $char = $this->character($this->char);
-
- if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) {
- /* U+0009 CHARACTER TABULATION
- U+000A LINE FEED (LF)
- U+000B LINE TABULATION
- U+000C FORM FEED (FF)
- U+0020 SPACE
- Stay in the before attribute name state. */
- $this->state = 'beforeAttributeName';
-
- } elseif ($char === '>') {
- /* U+003E GREATER-THAN SIGN (>)
- Emit the current tag token. Switch to the data state. */
- $this->emitToken($this->token);
- $this->state = 'data';
-
- } elseif ($char === '/') {
- /* U+002F SOLIDUS (/)
- Parse error unless this is a permitted slash. Stay in the before
- attribute name state. */
- $this->state = 'beforeAttributeName';
-
- } elseif ($this->char === $this->EOF) {
- /* EOF
- Parse error. Emit the current tag token. Reconsume the EOF
- character in the data state. */
- $this->emitToken($this->token);
-
- $this->char--;
- $this->state = 'data';
-
- } else {
- /* Anything else
- Start a new attribute in the current tag token. Set that attribute's
- name to the current input character, and its value to the empty string.
- Switch to the attribute name state. */
- $this->token['attr'][] = array(
- 'name' => strtolower($char),
- 'value' => null
- );
-
- $this->state = 'attributeName';
- }
- }
-
- private function attributeNameState()
- {
- // Consume the next input character:
- $this->char++;
- $char = $this->character($this->char);
-
- if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) {
- /* U+0009 CHARACTER TABULATION
- U+000A LINE FEED (LF)
- U+000B LINE TABULATION
- U+000C FORM FEED (FF)
- U+0020 SPACE
- Stay in the before attribute name state. */
- $this->state = 'afterAttributeName';
-
- } elseif ($char === '=') {
- /* U+003D EQUALS SIGN (=)
- Switch to the before attribute value state. */
- $this->state = 'beforeAttributeValue';
-
- } elseif ($char === '>') {
- /* U+003E GREATER-THAN SIGN (>)
- Emit the current tag token. Switch to the data state. */
- $this->emitToken($this->token);
- $this->state = 'data';
-
- } elseif ($char === '/' && $this->character($this->char + 1) !== '>') {
- /* U+002F SOLIDUS (/)
- Parse error unless this is a permitted slash. Switch to the before
- attribute name state. */
- $this->state = 'beforeAttributeName';
-
- } elseif ($this->char === $this->EOF) {
- /* EOF
- Parse error. Emit the current tag token. Reconsume the EOF
- character in the data state. */
- $this->emitToken($this->token);
-
- $this->char--;
- $this->state = 'data';
-
- } else {
- /* Anything else
- Append the current input character to the current attribute's name.
- Stay in the attribute name state. */
- $last = count($this->token['attr']) - 1;
- $this->token['attr'][$last]['name'] .= strtolower($char);
-
- $this->state = 'attributeName';
- }
- }
-
- private function afterAttributeNameState()
- {
- // Consume the next input character:
- $this->char++;
- $char = $this->character($this->char);
-
- if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) {
- /* U+0009 CHARACTER TABULATION
- U+000A LINE FEED (LF)
- U+000B LINE TABULATION
- U+000C FORM FEED (FF)
- U+0020 SPACE
- Stay in the after attribute name state. */
- $this->state = 'afterAttributeName';
-
- } elseif ($char === '=') {
- /* U+003D EQUALS SIGN (=)
- Switch to the before attribute value state. */
- $this->state = 'beforeAttributeValue';
-
- } elseif ($char === '>') {
- /* U+003E GREATER-THAN SIGN (>)
- Emit the current tag token. Switch to the data state. */
- $this->emitToken($this->token);
- $this->state = 'data';
-
- } elseif ($char === '/' && $this->character($this->char + 1) !== '>') {
- /* U+002F SOLIDUS (/)
- Parse error unless this is a permitted slash. Switch to the
- before attribute name state. */
- $this->state = 'beforeAttributeName';
-
- } elseif ($this->char === $this->EOF) {
- /* EOF
- Parse error. Emit the current tag token. Reconsume the EOF
- character in the data state. */
- $this->emitToken($this->token);
-
- $this->char--;
- $this->state = 'data';
-
- } else {
- /* Anything else
- Start a new attribute in the current tag token. Set that attribute's
- name to the current input character, and its value to the empty string.
- Switch to the attribute name state. */
- $this->token['attr'][] = array(
- 'name' => strtolower($char),
- 'value' => null
- );
-
- $this->state = 'attributeName';
- }
- }
-
- private function beforeAttributeValueState()
- {
- // Consume the next input character:
- $this->char++;
- $char = $this->character($this->char);
-
- if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) {
- /* U+0009 CHARACTER TABULATION
- U+000A LINE FEED (LF)
- U+000B LINE TABULATION
- U+000C FORM FEED (FF)
- U+0020 SPACE
- Stay in the before attribute value state. */
- $this->state = 'beforeAttributeValue';
-
- } elseif ($char === '"') {
- /* U+0022 QUOTATION MARK (")
- Switch to the attribute value (double-quoted) state. */
- $this->state = 'attributeValueDoubleQuoted';
-
- } elseif ($char === '&') {
- /* U+0026 AMPERSAND (&)
- Switch to the attribute value (unquoted) state and reconsume
- this input character. */
- $this->char--;
- $this->state = 'attributeValueUnquoted';
-
- } elseif ($char === '\'') {
- /* U+0027 APOSTROPHE (')
- Switch to the attribute value (single-quoted) state. */
- $this->state = 'attributeValueSingleQuoted';
-
- } elseif ($char === '>') {
- /* U+003E GREATER-THAN SIGN (>)
- Emit the current tag token. Switch to the data state. */
- $this->emitToken($this->token);
- $this->state = 'data';
-
- } else {
- /* Anything else
- Append the current input character to the current attribute's value.
- Switch to the attribute value (unquoted) state. */
- $last = count($this->token['attr']) - 1;
- $this->token['attr'][$last]['value'] .= $char;
-
- $this->state = 'attributeValueUnquoted';
- }
- }
-
- private function attributeValueDoubleQuotedState()
- {
- // Consume the next input character:
- $this->char++;
- $char = $this->character($this->char);
-
- if ($char === '"') {
- /* U+0022 QUOTATION MARK (")
- Switch to the before attribute name state. */
- $this->state = 'beforeAttributeName';
-
- } elseif ($char === '&') {
- /* U+0026 AMPERSAND (&)
- Switch to the entity in attribute value state. */
- $this->entityInAttributeValueState('double');
-
- } elseif ($this->char === $this->EOF) {
- /* EOF
- Parse error. Emit the current tag token. Reconsume the character
- in the data state. */
- $this->emitToken($this->token);
-
- $this->char--;
- $this->state = 'data';
-
- } else {
- /* Anything else
- Append the current input character to the current attribute's value.
- Stay in the attribute value (double-quoted) state. */
- $last = count($this->token['attr']) - 1;
- $this->token['attr'][$last]['value'] .= $char;
-
- $this->state = 'attributeValueDoubleQuoted';
- }
- }
-
- private function attributeValueSingleQuotedState()
- {
- // Consume the next input character:
- $this->char++;
- $char = $this->character($this->char);
-
- if ($char === '\'') {
- /* U+0022 QUOTATION MARK (')
- Switch to the before attribute name state. */
- $this->state = 'beforeAttributeName';
-
- } elseif ($char === '&') {
- /* U+0026 AMPERSAND (&)
- Switch to the entity in attribute value state. */
- $this->entityInAttributeValueState('single');
-
- } elseif ($this->char === $this->EOF) {
- /* EOF
- Parse error. Emit the current tag token. Reconsume the character
- in the data state. */
- $this->emitToken($this->token);
-
- $this->char--;
- $this->state = 'data';
-
- } else {
- /* Anything else
- Append the current input character to the current attribute's value.
- Stay in the attribute value (single-quoted) state. */
- $last = count($this->token['attr']) - 1;
- $this->token['attr'][$last]['value'] .= $char;
-
- $this->state = 'attributeValueSingleQuoted';
- }
- }
-
- private function attributeValueUnquotedState()
- {
- // Consume the next input character:
- $this->char++;
- $char = $this->character($this->char);
-
- if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) {
- /* U+0009 CHARACTER TABULATION
- U+000A LINE FEED (LF)
- U+000B LINE TABULATION
- U+000C FORM FEED (FF)
- U+0020 SPACE
- Switch to the before attribute name state. */
- $this->state = 'beforeAttributeName';
-
- } elseif ($char === '&') {
- /* U+0026 AMPERSAND (&)
- Switch to the entity in attribute value state. */
- $this->entityInAttributeValueState();
-
- } elseif ($char === '>') {
- /* U+003E GREATER-THAN SIGN (>)
- Emit the current tag token. Switch to the data state. */
- $this->emitToken($this->token);
- $this->state = 'data';
-
- } else {
- /* Anything else
- Append the current input character to the current attribute's value.
- Stay in the attribute value (unquoted) state. */
- $last = count($this->token['attr']) - 1;
- $this->token['attr'][$last]['value'] .= $char;
-
- $this->state = 'attributeValueUnquoted';
- }
- }
-
- private function entityInAttributeValueState()
- {
- // Attempt to consume an entity.
- $entity = $this->entity();
-
- // If nothing is returned, append a U+0026 AMPERSAND character to the
- // current attribute's value. Otherwise, emit the character token that
- // was returned.
- $char = (!$entity)
- ? '&'
- : $entity;
-
- $last = count($this->token['attr']) - 1;
- $this->token['attr'][$last]['value'] .= $char;
- }
-
- private function bogusCommentState()
- {
- /* Consume every character up to the first U+003E GREATER-THAN SIGN
- character (>) or the end of the file (EOF), whichever comes first. Emit
- a comment token whose data is the concatenation of all the characters
- starting from and including the character that caused the state machine
- to switch into the bogus comment state, up to and including the last
- consumed character before the U+003E character, if any, or up to the
- end of the file otherwise. (If the comment was started by the end of
- the file (EOF), the token is empty.) */
- $data = $this->characters('^>', $this->char);
- $this->emitToken(
- array(
- 'data' => $data,
- 'type' => self::COMMENT
- )
- );
-
- $this->char += strlen($data);
-
- /* Switch to the data state. */
- $this->state = 'data';
-
- /* If the end of the file was reached, reconsume the EOF character. */
- if ($this->char === $this->EOF) {
- $this->char = $this->EOF - 1;
- }
- }
-
- private function markupDeclarationOpenState()
- {
- /* If the next two characters are both U+002D HYPHEN-MINUS (-)
- characters, consume those two characters, create a comment token whose
- data is the empty string, and switch to the comment state. */
- if ($this->character($this->char + 1, 2) === '--') {
- $this->char += 2;
- $this->state = 'comment';
- $this->token = array(
- 'data' => null,
- 'type' => self::COMMENT
- );
-
- /* Otherwise if the next seven chacacters are a case-insensitive match
- for the word "DOCTYPE", then consume those characters and switch to the
- DOCTYPE state. */
- } elseif (strtolower($this->character($this->char + 1, 7)) === 'doctype') {
- $this->char += 7;
- $this->state = 'doctype';
-
- /* Otherwise, is is a parse error. Switch to the bogus comment state.
- The next character that is consumed, if any, is the first character
- that will be in the comment. */
- } else {
- $this->char++;
- $this->state = 'bogusComment';
- }
- }
-
- private function commentState()
- {
- /* Consume the next input character: */
- $this->char++;
- $char = $this->char();
-
- /* U+002D HYPHEN-MINUS (-) */
- if ($char === '-') {
- /* Switch to the comment dash state */
- $this->state = 'commentDash';
-
- /* EOF */
- } elseif ($this->char === $this->EOF) {
- /* Parse error. Emit the comment token. Reconsume the EOF character
- in the data state. */
- $this->emitToken($this->token);
- $this->char--;
- $this->state = 'data';
-
- /* Anything else */
- } else {
- /* Append the input character to the comment token's data. Stay in
- the comment state. */
- $this->token['data'] .= $char;
- }
- }
-
- private function commentDashState()
- {
- /* Consume the next input character: */
- $this->char++;
- $char = $this->char();
-
- /* U+002D HYPHEN-MINUS (-) */
- if ($char === '-') {
- /* Switch to the comment end state */
- $this->state = 'commentEnd';
-
- /* EOF */
- } elseif ($this->char === $this->EOF) {
- /* Parse error. Emit the comment token. Reconsume the EOF character
- in the data state. */
- $this->emitToken($this->token);
- $this->char--;
- $this->state = 'data';
-
- /* Anything else */
- } else {
- /* Append a U+002D HYPHEN-MINUS (-) character and the input
- character to the comment token's data. Switch to the comment state. */
- $this->token['data'] .= '-' . $char;
- $this->state = 'comment';
- }
- }
-
- private function commentEndState()
- {
- /* Consume the next input character: */
- $this->char++;
- $char = $this->char();
-
- if ($char === '>') {
- $this->emitToken($this->token);
- $this->state = 'data';
-
- } elseif ($char === '-') {
- $this->token['data'] .= '-';
-
- } elseif ($this->char === $this->EOF) {
- $this->emitToken($this->token);
- $this->char--;
- $this->state = 'data';
-
- } else {
- $this->token['data'] .= '--' . $char;
- $this->state = 'comment';
- }
- }
-
- private function doctypeState()
- {
- /* Consume the next input character: */
- $this->char++;
- $char = $this->char();
-
- if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) {
- $this->state = 'beforeDoctypeName';
-
- } else {
- $this->char--;
- $this->state = 'beforeDoctypeName';
- }
- }
-
- private function beforeDoctypeNameState()
- {
- /* Consume the next input character: */
- $this->char++;
- $char = $this->char();
-
- if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) {
- // Stay in the before DOCTYPE name state.
-
- } elseif (preg_match('/^[a-z]$/', $char)) {
- $this->token = array(
- 'name' => strtoupper($char),
- 'type' => self::DOCTYPE,
- 'error' => true
- );
-
- $this->state = 'doctypeName';
-
- } elseif ($char === '>') {
- $this->emitToken(
- array(
- 'name' => null,
- 'type' => self::DOCTYPE,
- 'error' => true
- )
- );
-
- $this->state = 'data';
-
- } elseif ($this->char === $this->EOF) {
- $this->emitToken(
- array(
- 'name' => null,
- 'type' => self::DOCTYPE,
- 'error' => true
- )
- );
-
- $this->char--;
- $this->state = 'data';
-
- } else {
- $this->token = array(
- 'name' => $char,
- 'type' => self::DOCTYPE,
- 'error' => true
- );
-
- $this->state = 'doctypeName';
- }
- }
-
- private function doctypeNameState()
- {
- /* Consume the next input character: */
- $this->char++;
- $char = $this->char();
-
- if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) {
- $this->state = 'AfterDoctypeName';
-
- } elseif ($char === '>') {
- $this->emitToken($this->token);
- $this->state = 'data';
-
- } elseif (preg_match('/^[a-z]$/', $char)) {
- $this->token['name'] .= strtoupper($char);
-
- } elseif ($this->char === $this->EOF) {
- $this->emitToken($this->token);
- $this->char--;
- $this->state = 'data';
-
- } else {
- $this->token['name'] .= $char;
- }
-
- $this->token['error'] = ($this->token['name'] === 'HTML')
- ? false
- : true;
- }
-
- private function afterDoctypeNameState()
- {
- /* Consume the next input character: */
- $this->char++;
- $char = $this->char();
-
- if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) {
- // Stay in the DOCTYPE name state.
-
- } elseif ($char === '>') {
- $this->emitToken($this->token);
- $this->state = 'data';
-
- } elseif ($this->char === $this->EOF) {
- $this->emitToken($this->token);
- $this->char--;
- $this->state = 'data';
-
- } else {
- $this->token['error'] = true;
- $this->state = 'bogusDoctype';
- }
- }
-
- private function bogusDoctypeState()
- {
- /* Consume the next input character: */
- $this->char++;
- $char = $this->char();
-
- if ($char === '>') {
- $this->emitToken($this->token);
- $this->state = 'data';
-
- } elseif ($this->char === $this->EOF) {
- $this->emitToken($this->token);
- $this->char--;
- $this->state = 'data';
-
- } else {
- // Stay in the bogus DOCTYPE state.
- }
- }
-
- private function entity()
- {
- $start = $this->char;
-
- // This section defines how to consume an entity. This definition is
- // used when parsing entities in text and in attributes.
-
- // The behaviour depends on the identity of the next character (the
- // one immediately after the U+0026 AMPERSAND character):
-
- switch ($this->character($this->char + 1)) {
- // U+0023 NUMBER SIGN (#)
- case '#':
-
- // The behaviour further depends on the character after the
- // U+0023 NUMBER SIGN:
- switch ($this->character($this->char + 1)) {
- // U+0078 LATIN SMALL LETTER X
- // U+0058 LATIN CAPITAL LETTER X
- case 'x':
- case 'X':
- // Follow the steps below, but using the range of
- // characters U+0030 DIGIT ZERO through to U+0039 DIGIT
- // NINE, U+0061 LATIN SMALL LETTER A through to U+0066
- // LATIN SMALL LETTER F, and U+0041 LATIN CAPITAL LETTER
- // A, through to U+0046 LATIN CAPITAL LETTER F (in other
- // words, 0-9, A-F, a-f).
- $char = 1;
- $char_class = '0-9A-Fa-f';
- break;
-
- // Anything else
- default:
- // Follow the steps below, but using the range of
- // characters U+0030 DIGIT ZERO through to U+0039 DIGIT
- // NINE (i.e. just 0-9).
- $char = 0;
- $char_class = '0-9';
- break;
- }
-
- // Consume as many characters as match the range of characters
- // given above.
- $this->char++;
- $e_name = $this->characters($char_class, $this->char + $char + 1);
- $entity = $this->character($start, $this->char);
- $cond = strlen($e_name) > 0;
-
- // The rest of the parsing happens bellow.
- break;
-
- // Anything else
- default:
- // Consume the maximum number of characters possible, with the
- // consumed characters case-sensitively matching one of the
- // identifiers in the first column of the entities table.
- $e_name = $this->characters('0-9A-Za-z;', $this->char + 1);
- $len = strlen($e_name);
-
- for ($c = 1; $c <= $len; $c++) {
- $id = substr($e_name, 0, $c);
- $this->char++;
-
- if (in_array($id, $this->entities)) {
- if ($e_name[$c - 1] !== ';') {
- if ($c < $len && $e_name[$c] == ';') {
- $this->char++; // consume extra semicolon
- }
- }
- $entity = $id;
- break;
- }
- }
-
- $cond = isset($entity);
- // The rest of the parsing happens bellow.
- break;
- }
-
- if (!$cond) {
- // If no match can be made, then this is a parse error. No
- // characters are consumed, and nothing is returned.
- $this->char = $start;
- return false;
- }
-
- // Return a character token for the character corresponding to the
- // entity name (as given by the second column of the entities table).
- return html_entity_decode('&' . $entity . ';', ENT_QUOTES, 'UTF-8');
- }
-
- private function emitToken($token)
- {
- $emit = $this->tree->emitToken($token);
-
- if (is_int($emit)) {
- $this->content_model = $emit;
-
- } elseif ($token['type'] === self::ENDTAG) {
- $this->content_model = self::PCDATA;
- }
- }
-
- private function EOF()
- {
- $this->state = null;
- $this->tree->emitToken(
- array(
- 'type' => self::EOF
- )
- );
- }
-}
-
-class HTML5TreeConstructer
-{
- public $stack = array();
-
- private $phase;
- private $mode;
- private $dom;
- private $foster_parent = null;
- private $a_formatting = array();
-
- private $head_pointer = null;
- private $form_pointer = null;
-
- private $scoping = array('button', 'caption', 'html', 'marquee', 'object', 'table', 'td', 'th');
- private $formatting = array(
- 'a',
- 'b',
- 'big',
- 'em',
- 'font',
- 'i',
- 'nobr',
- 's',
- 'small',
- 'strike',
- 'strong',
- 'tt',
- 'u'
- );
- private $special = array(
- 'address',
- 'area',
- 'base',
- 'basefont',
- 'bgsound',
- 'blockquote',
- 'body',
- 'br',
- 'center',
- 'col',
- 'colgroup',
- 'dd',
- 'dir',
- 'div',
- 'dl',
- 'dt',
- 'embed',
- 'fieldset',
- 'form',
- 'frame',
- 'frameset',
- 'h1',
- 'h2',
- 'h3',
- 'h4',
- 'h5',
- 'h6',
- 'head',
- 'hr',
- 'iframe',
- 'image',
- 'img',
- 'input',
- 'isindex',
- 'li',
- 'link',
- 'listing',
- 'menu',
- 'meta',
- 'noembed',
- 'noframes',
- 'noscript',
- 'ol',
- 'optgroup',
- 'option',
- 'p',
- 'param',
- 'plaintext',
- 'pre',
- 'script',
- 'select',
- 'spacer',
- 'style',
- 'tbody',
- 'textarea',
- 'tfoot',
- 'thead',
- 'title',
- 'tr',
- 'ul',
- 'wbr'
- );
-
- // The different phases.
- const INIT_PHASE = 0;
- const ROOT_PHASE = 1;
- const MAIN_PHASE = 2;
- const END_PHASE = 3;
-
- // The different insertion modes for the main phase.
- const BEFOR_HEAD = 0;
- const IN_HEAD = 1;
- const AFTER_HEAD = 2;
- const IN_BODY = 3;
- const IN_TABLE = 4;
- const IN_CAPTION = 5;
- const IN_CGROUP = 6;
- const IN_TBODY = 7;
- const IN_ROW = 8;
- const IN_CELL = 9;
- const IN_SELECT = 10;
- const AFTER_BODY = 11;
- const IN_FRAME = 12;
- const AFTR_FRAME = 13;
-
- // The different types of elements.
- const SPECIAL = 0;
- const SCOPING = 1;
- const FORMATTING = 2;
- const PHRASING = 3;
-
- const MARKER = 0;
-
- public function __construct()
- {
- $this->phase = self::INIT_PHASE;
- $this->mode = self::BEFOR_HEAD;
- $this->dom = new DOMDocument;
-
- $this->dom->encoding = 'UTF-8';
- $this->dom->preserveWhiteSpace = true;
- $this->dom->substituteEntities = true;
- $this->dom->strictErrorChecking = false;
- }
-
- // Process tag tokens
- public function emitToken($token)
- {
- switch ($this->phase) {
- case self::INIT_PHASE:
- return $this->initPhase($token);
- break;
- case self::ROOT_PHASE:
- return $this->rootElementPhase($token);
- break;
- case self::MAIN_PHASE:
- return $this->mainPhase($token);
- break;
- case self::END_PHASE :
- return $this->trailingEndPhase($token);
- break;
- }
- }
-
- private function initPhase($token)
- {
- /* Initially, the tree construction stage must handle each token
- emitted from the tokenisation stage as follows: */
-
- /* A DOCTYPE token that is marked as being in error
- A comment token
- A start tag token
- An end tag token
- A character token that is not one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE
- An end-of-file token */
- if ((isset($token['error']) && $token['error']) ||
- $token['type'] === HTML5::COMMENT ||
- $token['type'] === HTML5::STARTTAG ||
- $token['type'] === HTML5::ENDTAG ||
- $token['type'] === HTML5::EOF ||
- ($token['type'] === HTML5::CHARACTR && isset($token['data']) &&
- !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']))
- ) {
- /* This specification does not define how to handle this case. In
- particular, user agents may ignore the entirety of this specification
- altogether for such documents, and instead invoke special parse modes
- with a greater emphasis on backwards compatibility. */
-
- $this->phase = self::ROOT_PHASE;
- return $this->rootElementPhase($token);
-
- /* A DOCTYPE token marked as being correct */
- } elseif (isset($token['error']) && !$token['error']) {
- /* Append a DocumentType node to the Document node, with the name
- attribute set to the name given in the DOCTYPE token (which will be
- "HTML"), and the other attributes specific to DocumentType objects
- set to null, empty lists, or the empty string as appropriate. */
- $doctype = new DOMDocumentType(null, null, 'HTML');
-
- /* Then, switch to the root element phase of the tree construction
- stage. */
- $this->phase = self::ROOT_PHASE;
-
- /* A character token that is one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE */
- } elseif (isset($token['data']) && preg_match(
- '/^[\t\n\x0b\x0c ]+$/',
- $token['data']
- )
- ) {
- /* Append that character to the Document node. */
- $text = $this->dom->createTextNode($token['data']);
- $this->dom->appendChild($text);
- }
- }
-
- private function rootElementPhase($token)
- {
- /* After the initial phase, as each token is emitted from the tokenisation
- stage, it must be processed as described in this section. */
-
- /* A DOCTYPE token */
- if ($token['type'] === HTML5::DOCTYPE) {
- // Parse error. Ignore the token.
-
- /* A comment token */
- } elseif ($token['type'] === HTML5::COMMENT) {
- /* Append a Comment node to the Document object with the data
- attribute set to the data given in the comment token. */
- $comment = $this->dom->createComment($token['data']);
- $this->dom->appendChild($comment);
-
- /* A character token that is one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE */
- } elseif ($token['type'] === HTML5::CHARACTR &&
- preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
- ) {
- /* Append that character to the Document node. */
- $text = $this->dom->createTextNode($token['data']);
- $this->dom->appendChild($text);
-
- /* A character token that is not one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED
- (FF), or U+0020 SPACE
- A start tag token
- An end tag token
- An end-of-file token */
- } elseif (($token['type'] === HTML5::CHARACTR &&
- !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) ||
- $token['type'] === HTML5::STARTTAG ||
- $token['type'] === HTML5::ENDTAG ||
- $token['type'] === HTML5::EOF
- ) {
- /* Create an HTMLElement node with the tag name html, in the HTML
- namespace. Append it to the Document object. Switch to the main
- phase and reprocess the current token. */
- $html = $this->dom->createElement('html');
- $this->dom->appendChild($html);
- $this->stack[] = $html;
-
- $this->phase = self::MAIN_PHASE;
- return $this->mainPhase($token);
- }
- }
-
- private function mainPhase($token)
- {
- /* Tokens in the main phase must be handled as follows: */
-
- /* A DOCTYPE token */
- if ($token['type'] === HTML5::DOCTYPE) {
- // Parse error. Ignore the token.
-
- /* A start tag token with the tag name "html" */
- } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'html') {
- /* If this start tag token was not the first start tag token, then
- it is a parse error. */
-
- /* For each attribute on the token, check to see if the attribute
- is already present on the top element of the stack of open elements.
- If it is not, add the attribute and its corresponding value to that
- element. */
- foreach ($token['attr'] as $attr) {
- if (!$this->stack[0]->hasAttribute($attr['name'])) {
- $this->stack[0]->setAttribute($attr['name'], $attr['value']);
- }
- }
-
- /* An end-of-file token */
- } elseif ($token['type'] === HTML5::EOF) {
- /* Generate implied end tags. */
- $this->generateImpliedEndTags();
-
- /* Anything else. */
- } else {
- /* Depends on the insertion mode: */
- switch ($this->mode) {
- case self::BEFOR_HEAD:
- return $this->beforeHead($token);
- break;
- case self::IN_HEAD:
- return $this->inHead($token);
- break;
- case self::AFTER_HEAD:
- return $this->afterHead($token);
- break;
- case self::IN_BODY:
- return $this->inBody($token);
- break;
- case self::IN_TABLE:
- return $this->inTable($token);
- break;
- case self::IN_CAPTION:
- return $this->inCaption($token);
- break;
- case self::IN_CGROUP:
- return $this->inColumnGroup($token);
- break;
- case self::IN_TBODY:
- return $this->inTableBody($token);
- break;
- case self::IN_ROW:
- return $this->inRow($token);
- break;
- case self::IN_CELL:
- return $this->inCell($token);
- break;
- case self::IN_SELECT:
- return $this->inSelect($token);
- break;
- case self::AFTER_BODY:
- return $this->afterBody($token);
- break;
- case self::IN_FRAME:
- return $this->inFrameset($token);
- break;
- case self::AFTR_FRAME:
- return $this->afterFrameset($token);
- break;
- case self::END_PHASE:
- return $this->trailingEndPhase($token);
- break;
- }
- }
- }
-
- private function beforeHead($token)
- {
- /* Handle the token as follows: */
-
- /* A character token that is one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE */
- if ($token['type'] === HTML5::CHARACTR &&
- preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
- ) {
- /* Append the character to the current node. */
- $this->insertText($token['data']);
-
- /* A comment token */
- } elseif ($token['type'] === HTML5::COMMENT) {
- /* Append a Comment node to the current node with the data attribute
- set to the data given in the comment token. */
- $this->insertComment($token['data']);
-
- /* A start tag token with the tag name "head" */
- } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') {
- /* Create an element for the token, append the new element to the
- current node and push it onto the stack of open elements. */
- $element = $this->insertElement($token);
-
- /* Set the head element pointer to this new element node. */
- $this->head_pointer = $element;
-
- /* Change the insertion mode to "in head". */
- $this->mode = self::IN_HEAD;
-
- /* A start tag token whose tag name is one of: "base", "link", "meta",
- "script", "style", "title". Or an end tag with the tag name "html".
- Or a character token that is not one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE. Or any other start tag token */
- } elseif ($token['type'] === HTML5::STARTTAG ||
- ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') ||
- ($token['type'] === HTML5::CHARACTR && !preg_match(
- '/^[\t\n\x0b\x0c ]$/',
- $token['data']
- ))
- ) {
- /* Act as if a start tag token with the tag name "head" and no
- attributes had been seen, then reprocess the current token. */
- $this->beforeHead(
- array(
- 'name' => 'head',
- 'type' => HTML5::STARTTAG,
- 'attr' => array()
- )
- );
-
- return $this->inHead($token);
-
- /* Any other end tag */
- } elseif ($token['type'] === HTML5::ENDTAG) {
- /* Parse error. Ignore the token. */
- }
- }
-
- private function inHead($token)
- {
- /* Handle the token as follows: */
-
- /* A character token that is one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE.
-
- THIS DIFFERS FROM THE SPEC: If the current node is either a title, style
- or script element, append the character to the current node regardless
- of its content. */
- if (($token['type'] === HTML5::CHARACTR &&
- preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || (
- $token['type'] === HTML5::CHARACTR && in_array(
- end($this->stack)->nodeName,
- array('title', 'style', 'script')
- ))
- ) {
- /* Append the character to the current node. */
- $this->insertText($token['data']);
-
- /* A comment token */
- } elseif ($token['type'] === HTML5::COMMENT) {
- /* Append a Comment node to the current node with the data attribute
- set to the data given in the comment token. */
- $this->insertComment($token['data']);
-
- } elseif ($token['type'] === HTML5::ENDTAG &&
- in_array($token['name'], array('title', 'style', 'script'))
- ) {
- array_pop($this->stack);
- return HTML5::PCDATA;
-
- /* A start tag with the tag name "title" */
- } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'title') {
- /* Create an element for the token and append the new element to the
- node pointed to by the head element pointer, or, if that is null
- (innerHTML case), to the current node. */
- if ($this->head_pointer !== null) {
- $element = $this->insertElement($token, false);
- $this->head_pointer->appendChild($element);
-
- } else {
- $element = $this->insertElement($token);
- }
-
- /* Switch the tokeniser's content model flag to the RCDATA state. */
- return HTML5::RCDATA;
-
- /* A start tag with the tag name "style" */
- } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'style') {
- /* Create an element for the token and append the new element to the
- node pointed to by the head element pointer, or, if that is null
- (innerHTML case), to the current node. */
- if ($this->head_pointer !== null) {
- $element = $this->insertElement($token, false);
- $this->head_pointer->appendChild($element);
-
- } else {
- $this->insertElement($token);
- }
-
- /* Switch the tokeniser's content model flag to the CDATA state. */
- return HTML5::CDATA;
-
- /* A start tag with the tag name "script" */
- } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'script') {
- /* Create an element for the token. */
- $element = $this->insertElement($token, false);
- $this->head_pointer->appendChild($element);
-
- /* Switch the tokeniser's content model flag to the CDATA state. */
- return HTML5::CDATA;
-
- /* A start tag with the tag name "base", "link", or "meta" */
- } elseif ($token['type'] === HTML5::STARTTAG && in_array(
- $token['name'],
- array('base', 'link', 'meta')
- )
- ) {
- /* Create an element for the token and append the new element to the
- node pointed to by the head element pointer, or, if that is null
- (innerHTML case), to the current node. */
- if ($this->head_pointer !== null) {
- $element = $this->insertElement($token, false);
- $this->head_pointer->appendChild($element);
- array_pop($this->stack);
-
- } else {
- $this->insertElement($token);
- }
-
- /* An end tag with the tag name "head" */
- } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'head') {
- /* If the current node is a head element, pop the current node off
- the stack of open elements. */
- if ($this->head_pointer->isSameNode(end($this->stack))) {
- array_pop($this->stack);
-
- /* Otherwise, this is a parse error. */
- } else {
- // k
- }
-
- /* Change the insertion mode to "after head". */
- $this->mode = self::AFTER_HEAD;
-
- /* A start tag with the tag name "head" or an end tag except "html". */
- } elseif (($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') ||
- ($token['type'] === HTML5::ENDTAG && $token['name'] !== 'html')
- ) {
- // Parse error. Ignore the token.
-
- /* Anything else */
- } else {
- /* If the current node is a head element, act as if an end tag
- token with the tag name "head" had been seen. */
- if ($this->head_pointer->isSameNode(end($this->stack))) {
- $this->inHead(
- array(
- 'name' => 'head',
- 'type' => HTML5::ENDTAG
- )
- );
-
- /* Otherwise, change the insertion mode to "after head". */
- } else {
- $this->mode = self::AFTER_HEAD;
- }
-
- /* Then, reprocess the current token. */
- return $this->afterHead($token);
- }
- }
-
- private function afterHead($token)
- {
- /* Handle the token as follows: */
-
- /* A character token that is one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE */
- if ($token['type'] === HTML5::CHARACTR &&
- preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
- ) {
- /* Append the character to the current node. */
- $this->insertText($token['data']);
-
- /* A comment token */
- } elseif ($token['type'] === HTML5::COMMENT) {
- /* Append a Comment node to the current node with the data attribute
- set to the data given in the comment token. */
- $this->insertComment($token['data']);
-
- /* A start tag token with the tag name "body" */
- } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'body') {
- /* Insert a body element for the token. */
- $this->insertElement($token);
-
- /* Change the insertion mode to "in body". */
- $this->mode = self::IN_BODY;
-
- /* A start tag token with the tag name "frameset" */
- } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'frameset') {
- /* Insert a frameset element for the token. */
- $this->insertElement($token);
-
- /* Change the insertion mode to "in frameset". */
- $this->mode = self::IN_FRAME;
-
- /* A start tag token whose tag name is one of: "base", "link", "meta",
- "script", "style", "title" */
- } elseif ($token['type'] === HTML5::STARTTAG && in_array(
- $token['name'],
- array('base', 'link', 'meta', 'script', 'style', 'title')
- )
- ) {
- /* Parse error. Switch the insertion mode back to "in head" and
- reprocess the token. */
- $this->mode = self::IN_HEAD;
- return $this->inHead($token);
-
- /* Anything else */
- } else {
- /* Act as if a start tag token with the tag name "body" and no
- attributes had been seen, and then reprocess the current token. */
- $this->afterHead(
- array(
- 'name' => 'body',
- 'type' => HTML5::STARTTAG,
- 'attr' => array()
- )
- );
-
- return $this->inBody($token);
- }
- }
-
- private function inBody($token)
- {
- /* Handle the token as follows: */
-
- switch ($token['type']) {
- /* A character token */
- case HTML5::CHARACTR:
- /* Reconstruct the active formatting elements, if any. */
- $this->reconstructActiveFormattingElements();
-
- /* Append the token's character to the current node. */
- $this->insertText($token['data']);
- break;
-
- /* A comment token */
- case HTML5::COMMENT:
- /* Append a Comment node to the current node with the data
- attribute set to the data given in the comment token. */
- $this->insertComment($token['data']);
- break;
-
- case HTML5::STARTTAG:
- switch ($token['name']) {
- /* A start tag token whose tag name is one of: "script",
- "style" */
- case 'script':
- case 'style':
- /* Process the token as if the insertion mode had been "in
- head". */
- return $this->inHead($token);
- break;
-
- /* A start tag token whose tag name is one of: "base", "link",
- "meta", "title" */
- case 'base':
- case 'link':
- case 'meta':
- case 'title':
- /* Parse error. Process the token as if the insertion mode
- had been "in head". */
- return $this->inHead($token);
- break;
-
- /* A start tag token with the tag name "body" */
- case 'body':
- /* Parse error. If the second element on the stack of open
- elements is not a body element, or, if the stack of open
- elements has only one node on it, then ignore the token.
- (innerHTML case) */
- if (count($this->stack) === 1 || $this->stack[1]->nodeName !== 'body') {
- // Ignore
-
- /* Otherwise, for each attribute on the token, check to see
- if the attribute is already present on the body element (the
- second element) on the stack of open elements. If it is not,
- add the attribute and its corresponding value to that
- element. */
- } else {
- foreach ($token['attr'] as $attr) {
- if (!$this->stack[1]->hasAttribute($attr['name'])) {
- $this->stack[1]->setAttribute($attr['name'], $attr['value']);
- }
- }
- }
- break;
-
- /* A start tag whose tag name is one of: "address",
- "blockquote", "center", "dir", "div", "dl", "fieldset",
- "listing", "menu", "ol", "p", "ul" */
- case 'address':
- case 'blockquote':
- case 'center':
- case 'dir':
- case 'div':
- case 'dl':
- case 'fieldset':
- case 'listing':
- case 'menu':
- case 'ol':
- case 'p':
- case 'ul':
- /* If the stack of open elements has a p element in scope,
- then act as if an end tag with the tag name p had been
- seen. */
- if ($this->elementInScope('p')) {
- $this->emitToken(
- array(
- 'name' => 'p',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
- break;
-
- /* A start tag whose tag name is "form" */
- case 'form':
- /* If the form element pointer is not null, ignore the
- token with a parse error. */
- if ($this->form_pointer !== null) {
- // Ignore.
-
- /* Otherwise: */
- } else {
- /* If the stack of open elements has a p element in
- scope, then act as if an end tag with the tag name p
- had been seen. */
- if ($this->elementInScope('p')) {
- $this->emitToken(
- array(
- 'name' => 'p',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- /* Insert an HTML element for the token, and set the
- form element pointer to point to the element created. */
- $element = $this->insertElement($token);
- $this->form_pointer = $element;
- }
- break;
-
- /* A start tag whose tag name is "li", "dd" or "dt" */
- case 'li':
- case 'dd':
- case 'dt':
- /* If the stack of open elements has a p element in scope,
- then act as if an end tag with the tag name p had been
- seen. */
- if ($this->elementInScope('p')) {
- $this->emitToken(
- array(
- 'name' => 'p',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- $stack_length = count($this->stack) - 1;
-
- for ($n = $stack_length; 0 <= $n; $n--) {
- /* 1. Initialise node to be the current node (the
- bottommost node of the stack). */
- $stop = false;
- $node = $this->stack[$n];
- $cat = $this->getElementCategory($node->tagName);
-
- /* 2. If node is an li, dd or dt element, then pop all
- the nodes from the current node up to node, including
- node, then stop this algorithm. */
- if ($token['name'] === $node->tagName || ($token['name'] !== 'li'
- && ($node->tagName === 'dd' || $node->tagName === 'dt'))
- ) {
- for ($x = $stack_length; $x >= $n; $x--) {
- array_pop($this->stack);
- }
-
- break;
- }
-
- /* 3. If node is not in the formatting category, and is
- not in the phrasing category, and is not an address or
- div element, then stop this algorithm. */
- if ($cat !== self::FORMATTING && $cat !== self::PHRASING &&
- $node->tagName !== 'address' && $node->tagName !== 'div'
- ) {
- break;
- }
- }
-
- /* Finally, insert an HTML element with the same tag
- name as the token's. */
- $this->insertElement($token);
- break;
-
- /* A start tag token whose tag name is "plaintext" */
- case 'plaintext':
- /* If the stack of open elements has a p element in scope,
- then act as if an end tag with the tag name p had been
- seen. */
- if ($this->elementInScope('p')) {
- $this->emitToken(
- array(
- 'name' => 'p',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
-
- return HTML5::PLAINTEXT;
- break;
-
- /* A start tag whose tag name is one of: "h1", "h2", "h3", "h4",
- "h5", "h6" */
- case 'h1':
- case 'h2':
- case 'h3':
- case 'h4':
- case 'h5':
- case 'h6':
- /* If the stack of open elements has a p element in scope,
- then act as if an end tag with the tag name p had been seen. */
- if ($this->elementInScope('p')) {
- $this->emitToken(
- array(
- 'name' => 'p',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- /* If the stack of open elements has in scope an element whose
- tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then
- this is a parse error; pop elements from the stack until an
- element with one of those tag names has been popped from the
- stack. */
- while ($this->elementInScope(array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) {
- array_pop($this->stack);
- }
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
- break;
-
- /* A start tag whose tag name is "a" */
- case 'a':
- /* If the list of active formatting elements contains
- an element whose tag name is "a" between the end of the
- list and the last marker on the list (or the start of
- the list if there is no marker on the list), then this
- is a parse error; act as if an end tag with the tag name
- "a" had been seen, then remove that element from the list
- of active formatting elements and the stack of open
- elements if the end tag didn't already remove it (it
- might not have if the element is not in table scope). */
- $leng = count($this->a_formatting);
-
- for ($n = $leng - 1; $n >= 0; $n--) {
- if ($this->a_formatting[$n] === self::MARKER) {
- break;
-
- } elseif ($this->a_formatting[$n]->nodeName === 'a') {
- $this->emitToken(
- array(
- 'name' => 'a',
- 'type' => HTML5::ENDTAG
- )
- );
- break;
- }
- }
-
- /* Reconstruct the active formatting elements, if any. */
- $this->reconstructActiveFormattingElements();
-
- /* Insert an HTML element for the token. */
- $el = $this->insertElement($token);
-
- /* Add that element to the list of active formatting
- elements. */
- $this->a_formatting[] = $el;
- break;
-
- /* A start tag whose tag name is one of: "b", "big", "em", "font",
- "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */
- case 'b':
- case 'big':
- case 'em':
- case 'font':
- case 'i':
- case 'nobr':
- case 's':
- case 'small':
- case 'strike':
- case 'strong':
- case 'tt':
- case 'u':
- /* Reconstruct the active formatting elements, if any. */
- $this->reconstructActiveFormattingElements();
-
- /* Insert an HTML element for the token. */
- $el = $this->insertElement($token);
-
- /* Add that element to the list of active formatting
- elements. */
- $this->a_formatting[] = $el;
- break;
-
- /* A start tag token whose tag name is "button" */
- case 'button':
- /* If the stack of open elements has a button element in scope,
- then this is a parse error; act as if an end tag with the tag
- name "button" had been seen, then reprocess the token. (We don't
- do that. Unnecessary.) */
- if ($this->elementInScope('button')) {
- $this->inBody(
- array(
- 'name' => 'button',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- /* Reconstruct the active formatting elements, if any. */
- $this->reconstructActiveFormattingElements();
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
-
- /* Insert a marker at the end of the list of active
- formatting elements. */
- $this->a_formatting[] = self::MARKER;
- break;
-
- /* A start tag token whose tag name is one of: "marquee", "object" */
- case 'marquee':
- case 'object':
- /* Reconstruct the active formatting elements, if any. */
- $this->reconstructActiveFormattingElements();
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
-
- /* Insert a marker at the end of the list of active
- formatting elements. */
- $this->a_formatting[] = self::MARKER;
- break;
-
- /* A start tag token whose tag name is "xmp" */
- case 'xmp':
- /* Reconstruct the active formatting elements, if any. */
- $this->reconstructActiveFormattingElements();
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
-
- /* Switch the content model flag to the CDATA state. */
- return HTML5::CDATA;
- break;
-
- /* A start tag whose tag name is "table" */
- case 'table':
- /* If the stack of open elements has a p element in scope,
- then act as if an end tag with the tag name p had been seen. */
- if ($this->elementInScope('p')) {
- $this->emitToken(
- array(
- 'name' => 'p',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
-
- /* Change the insertion mode to "in table". */
- $this->mode = self::IN_TABLE;
- break;
-
- /* A start tag whose tag name is one of: "area", "basefont",
- "bgsound", "br", "embed", "img", "param", "spacer", "wbr" */
- case 'area':
- case 'basefont':
- case 'bgsound':
- case 'br':
- case 'embed':
- case 'img':
- case 'param':
- case 'spacer':
- case 'wbr':
- /* Reconstruct the active formatting elements, if any. */
- $this->reconstructActiveFormattingElements();
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
-
- /* Immediately pop the current node off the stack of open elements. */
- array_pop($this->stack);
- break;
-
- /* A start tag whose tag name is "hr" */
- case 'hr':
- /* If the stack of open elements has a p element in scope,
- then act as if an end tag with the tag name p had been seen. */
- if ($this->elementInScope('p')) {
- $this->emitToken(
- array(
- 'name' => 'p',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
-
- /* Immediately pop the current node off the stack of open elements. */
- array_pop($this->stack);
- break;
-
- /* A start tag whose tag name is "image" */
- case 'image':
- /* Parse error. Change the token's tag name to "img" and
- reprocess it. (Don't ask.) */
- $token['name'] = 'img';
- return $this->inBody($token);
- break;
-
- /* A start tag whose tag name is "input" */
- case 'input':
- /* Reconstruct the active formatting elements, if any. */
- $this->reconstructActiveFormattingElements();
-
- /* Insert an input element for the token. */
- $element = $this->insertElement($token, false);
-
- /* If the form element pointer is not null, then associate the
- input element with the form element pointed to by the form
- element pointer. */
- $this->form_pointer !== null
- ? $this->form_pointer->appendChild($element)
- : end($this->stack)->appendChild($element);
-
- /* Pop that input element off the stack of open elements. */
- array_pop($this->stack);
- break;
-
- /* A start tag whose tag name is "isindex" */
- case 'isindex':
- /* Parse error. */
- // w/e
-
- /* If the form element pointer is not null,
- then ignore the token. */
- if ($this->form_pointer === null) {
- /* Act as if a start tag token with the tag name "form" had
- been seen. */
- $this->inBody(
- array(
- 'name' => 'body',
- 'type' => HTML5::STARTTAG,
- 'attr' => array()
- )
- );
-
- /* Act as if a start tag token with the tag name "hr" had
- been seen. */
- $this->inBody(
- array(
- 'name' => 'hr',
- 'type' => HTML5::STARTTAG,
- 'attr' => array()
- )
- );
-
- /* Act as if a start tag token with the tag name "p" had
- been seen. */
- $this->inBody(
- array(
- 'name' => 'p',
- 'type' => HTML5::STARTTAG,
- 'attr' => array()
- )
- );
-
- /* Act as if a start tag token with the tag name "label"
- had been seen. */
- $this->inBody(
- array(
- 'name' => 'label',
- 'type' => HTML5::STARTTAG,
- 'attr' => array()
- )
- );
-
- /* Act as if a stream of character tokens had been seen. */
- $this->insertText(
- 'This is a searchable index. ' .
- 'Insert your search keywords here: '
- );
-
- /* Act as if a start tag token with the tag name "input"
- had been seen, with all the attributes from the "isindex"
- token, except with the "name" attribute set to the value
- "isindex" (ignoring any explicit "name" attribute). */
- $attr = $token['attr'];
- $attr[] = array('name' => 'name', 'value' => 'isindex');
-
- $this->inBody(
- array(
- 'name' => 'input',
- 'type' => HTML5::STARTTAG,
- 'attr' => $attr
- )
- );
-
- /* Act as if a stream of character tokens had been seen
- (see below for what they should say). */
- $this->insertText(
- 'This is a searchable index. ' .
- 'Insert your search keywords here: '
- );
-
- /* Act as if an end tag token with the tag name "label"
- had been seen. */
- $this->inBody(
- array(
- 'name' => 'label',
- 'type' => HTML5::ENDTAG
- )
- );
-
- /* Act as if an end tag token with the tag name "p" had
- been seen. */
- $this->inBody(
- array(
- 'name' => 'p',
- 'type' => HTML5::ENDTAG
- )
- );
-
- /* Act as if a start tag token with the tag name "hr" had
- been seen. */
- $this->inBody(
- array(
- 'name' => 'hr',
- 'type' => HTML5::ENDTAG
- )
- );
-
- /* Act as if an end tag token with the tag name "form" had
- been seen. */
- $this->inBody(
- array(
- 'name' => 'form',
- 'type' => HTML5::ENDTAG
- )
- );
- }
- break;
-
- /* A start tag whose tag name is "textarea" */
- case 'textarea':
- $this->insertElement($token);
-
- /* Switch the tokeniser's content model flag to the
- RCDATA state. */
- return HTML5::RCDATA;
- break;
-
- /* A start tag whose tag name is one of: "iframe", "noembed",
- "noframes" */
- case 'iframe':
- case 'noembed':
- case 'noframes':
- $this->insertElement($token);
-
- /* Switch the tokeniser's content model flag to the CDATA state. */
- return HTML5::CDATA;
- break;
-
- /* A start tag whose tag name is "select" */
- case 'select':
- /* Reconstruct the active formatting elements, if any. */
- $this->reconstructActiveFormattingElements();
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
-
- /* Change the insertion mode to "in select". */
- $this->mode = self::IN_SELECT;
- break;
-
- /* A start or end tag whose tag name is one of: "caption", "col",
- "colgroup", "frame", "frameset", "head", "option", "optgroup",
- "tbody", "td", "tfoot", "th", "thead", "tr". */
- case 'caption':
- case 'col':
- case 'colgroup':
- case 'frame':
- case 'frameset':
- case 'head':
- case 'option':
- case 'optgroup':
- case 'tbody':
- case 'td':
- case 'tfoot':
- case 'th':
- case 'thead':
- case 'tr':
- // Parse error. Ignore the token.
- break;
-
- /* A start or end tag whose tag name is one of: "event-source",
- "section", "nav", "article", "aside", "header", "footer",
- "datagrid", "command" */
- case 'event-source':
- case 'section':
- case 'nav':
- case 'article':
- case 'aside':
- case 'header':
- case 'footer':
- case 'datagrid':
- case 'command':
- // Work in progress!
- break;
-
- /* A start tag token not covered by the previous entries */
- default:
- /* Reconstruct the active formatting elements, if any. */
- $this->reconstructActiveFormattingElements();
-
- $this->insertElement($token, true, true);
- break;
- }
- break;
-
- case HTML5::ENDTAG:
- switch ($token['name']) {
- /* An end tag with the tag name "body" */
- case 'body':
- /* If the second element in the stack of open elements is
- not a body element, this is a parse error. Ignore the token.
- (innerHTML case) */
- if (count($this->stack) < 2 || $this->stack[1]->nodeName !== 'body') {
- // Ignore.
-
- /* If the current node is not the body element, then this
- is a parse error. */
- } elseif (end($this->stack)->nodeName !== 'body') {
- // Parse error.
- }
-
- /* Change the insertion mode to "after body". */
- $this->mode = self::AFTER_BODY;
- break;
-
- /* An end tag with the tag name "html" */
- case 'html':
- /* Act as if an end tag with tag name "body" had been seen,
- then, if that token wasn't ignored, reprocess the current
- token. */
- $this->inBody(
- array(
- 'name' => 'body',
- 'type' => HTML5::ENDTAG
- )
- );
-
- return $this->afterBody($token);
- break;
-
- /* An end tag whose tag name is one of: "address", "blockquote",
- "center", "dir", "div", "dl", "fieldset", "listing", "menu",
- "ol", "pre", "ul" */
- case 'address':
- case 'blockquote':
- case 'center':
- case 'dir':
- case 'div':
- case 'dl':
- case 'fieldset':
- case 'listing':
- case 'menu':
- case 'ol':
- case 'pre':
- case 'ul':
- /* If the stack of open elements has an element in scope
- with the same tag name as that of the token, then generate
- implied end tags. */
- if ($this->elementInScope($token['name'])) {
- $this->generateImpliedEndTags();
-
- /* Now, if the current node is not an element with
- the same tag name as that of the token, then this
- is a parse error. */
- // w/e
-
- /* If the stack of open elements has an element in
- scope with the same tag name as that of the token,
- then pop elements from this stack until an element
- with that tag name has been popped from the stack. */
- for ($n = count($this->stack) - 1; $n >= 0; $n--) {
- if ($this->stack[$n]->nodeName === $token['name']) {
- $n = -1;
- }
-
- array_pop($this->stack);
- }
- }
- break;
-
- /* An end tag whose tag name is "form" */
- case 'form':
- /* If the stack of open elements has an element in scope
- with the same tag name as that of the token, then generate
- implied end tags. */
- if ($this->elementInScope($token['name'])) {
- $this->generateImpliedEndTags();
-
- }
-
- if (end($this->stack)->nodeName !== $token['name']) {
- /* Now, if the current node is not an element with the
- same tag name as that of the token, then this is a parse
- error. */
- // w/e
-
- } else {
- /* Otherwise, if the current node is an element with
- the same tag name as that of the token pop that element
- from the stack. */
- array_pop($this->stack);
- }
-
- /* In any case, set the form element pointer to null. */
- $this->form_pointer = null;
- break;
-
- /* An end tag whose tag name is "p" */
- case 'p':
- /* If the stack of open elements has a p element in scope,
- then generate implied end tags, except for p elements. */
- if ($this->elementInScope('p')) {
- $this->generateImpliedEndTags(array('p'));
-
- /* If the current node is not a p element, then this is
- a parse error. */
- // k
-
- /* If the stack of open elements has a p element in
- scope, then pop elements from this stack until the stack
- no longer has a p element in scope. */
- for ($n = count($this->stack) - 1; $n >= 0; $n--) {
- if ($this->elementInScope('p')) {
- array_pop($this->stack);
-
- } else {
- break;
- }
- }
- }
- break;
-
- /* An end tag whose tag name is "dd", "dt", or "li" */
- case 'dd':
- case 'dt':
- case 'li':
- /* If the stack of open elements has an element in scope
- whose tag name matches the tag name of the token, then
- generate implied end tags, except for elements with the
- same tag name as the token. */
- if ($this->elementInScope($token['name'])) {
- $this->generateImpliedEndTags(array($token['name']));
-
- /* If the current node is not an element with the same
- tag name as the token, then this is a parse error. */
- // w/e
-
- /* If the stack of open elements has an element in scope
- whose tag name matches the tag name of the token, then
- pop elements from this stack until an element with that
- tag name has been popped from the stack. */
- for ($n = count($this->stack) - 1; $n >= 0; $n--) {
- if ($this->stack[$n]->nodeName === $token['name']) {
- $n = -1;
- }
-
- array_pop($this->stack);
- }
- }
- break;
-
- /* An end tag whose tag name is one of: "h1", "h2", "h3", "h4",
- "h5", "h6" */
- case 'h1':
- case 'h2':
- case 'h3':
- case 'h4':
- case 'h5':
- case 'h6':
- $elements = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6');
-
- /* If the stack of open elements has in scope an element whose
- tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then
- generate implied end tags. */
- if ($this->elementInScope($elements)) {
- $this->generateImpliedEndTags();
-
- /* Now, if the current node is not an element with the same
- tag name as that of the token, then this is a parse error. */
- // w/e
-
- /* If the stack of open elements has in scope an element
- whose tag name is one of "h1", "h2", "h3", "h4", "h5", or
- "h6", then pop elements from the stack until an element
- with one of those tag names has been popped from the stack. */
- while ($this->elementInScope($elements)) {
- array_pop($this->stack);
- }
- }
- break;
-
- /* An end tag whose tag name is one of: "a", "b", "big", "em",
- "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */
- case 'a':
- case 'b':
- case 'big':
- case 'em':
- case 'font':
- case 'i':
- case 'nobr':
- case 's':
- case 'small':
- case 'strike':
- case 'strong':
- case 'tt':
- case 'u':
- /* 1. Let the formatting element be the last element in
- the list of active formatting elements that:
- * is between the end of the list and the last scope
- marker in the list, if any, or the start of the list
- otherwise, and
- * has the same tag name as the token.
- */
- while (true) {
- for ($a = count($this->a_formatting) - 1; $a >= 0; $a--) {
- if ($this->a_formatting[$a] === self::MARKER) {
- break;
-
- } elseif ($this->a_formatting[$a]->tagName === $token['name']) {
- $formatting_element = $this->a_formatting[$a];
- $in_stack = in_array($formatting_element, $this->stack, true);
- $fe_af_pos = $a;
- break;
- }
- }
-
- /* If there is no such node, or, if that node is
- also in the stack of open elements but the element
- is not in scope, then this is a parse error. Abort
- these steps. The token is ignored. */
- if (!isset($formatting_element) || ($in_stack &&
- !$this->elementInScope($token['name']))
- ) {
- break;
-
- /* Otherwise, if there is such a node, but that node
- is not in the stack of open elements, then this is a
- parse error; remove the element from the list, and
- abort these steps. */
- } elseif (isset($formatting_element) && !$in_stack) {
- unset($this->a_formatting[$fe_af_pos]);
- $this->a_formatting = array_merge($this->a_formatting);
- break;
- }
-
- /* 2. Let the furthest block be the topmost node in the
- stack of open elements that is lower in the stack
- than the formatting element, and is not an element in
- the phrasing or formatting categories. There might
- not be one. */
- $fe_s_pos = array_search($formatting_element, $this->stack, true);
- $length = count($this->stack);
-
- for ($s = $fe_s_pos + 1; $s < $length; $s++) {
- $category = $this->getElementCategory($this->stack[$s]->nodeName);
-
- if ($category !== self::PHRASING && $category !== self::FORMATTING) {
- $furthest_block = $this->stack[$s];
- }
- }
-
- /* 3. If there is no furthest block, then the UA must
- skip the subsequent steps and instead just pop all
- the nodes from the bottom of the stack of open
- elements, from the current node up to the formatting
- element, and remove the formatting element from the
- list of active formatting elements. */
- if (!isset($furthest_block)) {
- for ($n = $length - 1; $n >= $fe_s_pos; $n--) {
- array_pop($this->stack);
- }
-
- unset($this->a_formatting[$fe_af_pos]);
- $this->a_formatting = array_merge($this->a_formatting);
- break;
- }
-
- /* 4. Let the common ancestor be the element
- immediately above the formatting element in the stack
- of open elements. */
- $common_ancestor = $this->stack[$fe_s_pos - 1];
-
- /* 5. If the furthest block has a parent node, then
- remove the furthest block from its parent node. */
- if ($furthest_block->parentNode !== null) {
- $furthest_block->parentNode->removeChild($furthest_block);
- }
-
- /* 6. Let a bookmark note the position of the
- formatting element in the list of active formatting
- elements relative to the elements on either side
- of it in the list. */
- $bookmark = $fe_af_pos;
-
- /* 7. Let node and last node be the furthest block.
- Follow these steps: */
- $node = $furthest_block;
- $last_node = $furthest_block;
-
- while (true) {
- for ($n = array_search($node, $this->stack, true) - 1; $n >= 0; $n--) {
- /* 7.1 Let node be the element immediately
- prior to node in the stack of open elements. */
- $node = $this->stack[$n];
-
- /* 7.2 If node is not in the list of active
- formatting elements, then remove node from
- the stack of open elements and then go back
- to step 1. */
- if (!in_array($node, $this->a_formatting, true)) {
- unset($this->stack[$n]);
- $this->stack = array_merge($this->stack);
-
- } else {
- break;
- }
- }
-
- /* 7.3 Otherwise, if node is the formatting
- element, then go to the next step in the overall
- algorithm. */
- if ($node === $formatting_element) {
- break;
-
- /* 7.4 Otherwise, if last node is the furthest
- block, then move the aforementioned bookmark to
- be immediately after the node in the list of
- active formatting elements. */
- } elseif ($last_node === $furthest_block) {
- $bookmark = array_search($node, $this->a_formatting, true) + 1;
- }
-
- /* 7.5 If node has any children, perform a
- shallow clone of node, replace the entry for
- node in the list of active formatting elements
- with an entry for the clone, replace the entry
- for node in the stack of open elements with an
- entry for the clone, and let node be the clone. */
- if ($node->hasChildNodes()) {
- $clone = $node->cloneNode();
- $s_pos = array_search($node, $this->stack, true);
- $a_pos = array_search($node, $this->a_formatting, true);
-
- $this->stack[$s_pos] = $clone;
- $this->a_formatting[$a_pos] = $clone;
- $node = $clone;
- }
-
- /* 7.6 Insert last node into node, first removing
- it from its previous parent node if any. */
- if ($last_node->parentNode !== null) {
- $last_node->parentNode->removeChild($last_node);
- }
-
- $node->appendChild($last_node);
-
- /* 7.7 Let last node be node. */
- $last_node = $node;
- }
-
- /* 8. Insert whatever last node ended up being in
- the previous step into the common ancestor node,
- first removing it from its previous parent node if
- any. */
- if ($last_node->parentNode !== null) {
- $last_node->parentNode->removeChild($last_node);
- }
-
- $common_ancestor->appendChild($last_node);
-
- /* 9. Perform a shallow clone of the formatting
- element. */
- $clone = $formatting_element->cloneNode();
-
- /* 10. Take all of the child nodes of the furthest
- block and append them to the clone created in the
- last step. */
- while ($furthest_block->hasChildNodes()) {
- $child = $furthest_block->firstChild;
- $furthest_block->removeChild($child);
- $clone->appendChild($child);
- }
-
- /* 11. Append that clone to the furthest block. */
- $furthest_block->appendChild($clone);
-
- /* 12. Remove the formatting element from the list
- of active formatting elements, and insert the clone
- into the list of active formatting elements at the
- position of the aforementioned bookmark. */
- $fe_af_pos = array_search($formatting_element, $this->a_formatting, true);
- unset($this->a_formatting[$fe_af_pos]);
- $this->a_formatting = array_merge($this->a_formatting);
-
- $af_part1 = array_slice($this->a_formatting, 0, $bookmark - 1);
- $af_part2 = array_slice($this->a_formatting, $bookmark, count($this->a_formatting));
- $this->a_formatting = array_merge($af_part1, array($clone), $af_part2);
-
- /* 13. Remove the formatting element from the stack
- of open elements, and insert the clone into the stack
- of open elements immediately after (i.e. in a more
- deeply nested position than) the position of the
- furthest block in that stack. */
- $fe_s_pos = array_search($formatting_element, $this->stack, true);
- $fb_s_pos = array_search($furthest_block, $this->stack, true);
- unset($this->stack[$fe_s_pos]);
-
- $s_part1 = array_slice($this->stack, 0, $fb_s_pos);
- $s_part2 = array_slice($this->stack, $fb_s_pos + 1, count($this->stack));
- $this->stack = array_merge($s_part1, array($clone), $s_part2);
-
- /* 14. Jump back to step 1 in this series of steps. */
- unset($formatting_element, $fe_af_pos, $fe_s_pos, $furthest_block);
- }
- break;
-
- /* An end tag token whose tag name is one of: "button",
- "marquee", "object" */
- case 'button':
- case 'marquee':
- case 'object':
- /* If the stack of open elements has an element in scope whose
- tag name matches the tag name of the token, then generate implied
- tags. */
- if ($this->elementInScope($token['name'])) {
- $this->generateImpliedEndTags();
-
- /* Now, if the current node is not an element with the same
- tag name as the token, then this is a parse error. */
- // k
-
- /* Now, if the stack of open elements has an element in scope
- whose tag name matches the tag name of the token, then pop
- elements from the stack until that element has been popped from
- the stack, and clear the list of active formatting elements up
- to the last marker. */
- for ($n = count($this->stack) - 1; $n >= 0; $n--) {
- if ($this->stack[$n]->nodeName === $token['name']) {
- $n = -1;
- }
-
- array_pop($this->stack);
- }
-
- $marker = end(array_keys($this->a_formatting, self::MARKER, true));
-
- for ($n = count($this->a_formatting) - 1; $n > $marker; $n--) {
- array_pop($this->a_formatting);
- }
- }
- break;
-
- /* Or an end tag whose tag name is one of: "area", "basefont",
- "bgsound", "br", "embed", "hr", "iframe", "image", "img",
- "input", "isindex", "noembed", "noframes", "param", "select",
- "spacer", "table", "textarea", "wbr" */
- case 'area':
- case 'basefont':
- case 'bgsound':
- case 'br':
- case 'embed':
- case 'hr':
- case 'iframe':
- case 'image':
- case 'img':
- case 'input':
- case 'isindex':
- case 'noembed':
- case 'noframes':
- case 'param':
- case 'select':
- case 'spacer':
- case 'table':
- case 'textarea':
- case 'wbr':
- // Parse error. Ignore the token.
- break;
-
- /* An end tag token not covered by the previous entries */
- default:
- for ($n = count($this->stack) - 1; $n >= 0; $n--) {
- /* Initialise node to be the current node (the bottommost
- node of the stack). */
- $node = end($this->stack);
-
- /* If node has the same tag name as the end tag token,
- then: */
- if ($token['name'] === $node->nodeName) {
- /* Generate implied end tags. */
- $this->generateImpliedEndTags();
-
- /* If the tag name of the end tag token does not
- match the tag name of the current node, this is a
- parse error. */
- // k
-
- /* Pop all the nodes from the current node up to
- node, including node, then stop this algorithm. */
- for ($x = count($this->stack) - $n; $x >= $n; $x--) {
- array_pop($this->stack);
- }
-
- } else {
- $category = $this->getElementCategory($node);
-
- if ($category !== self::SPECIAL && $category !== self::SCOPING) {
- /* Otherwise, if node is in neither the formatting
- category nor the phrasing category, then this is a
- parse error. Stop this algorithm. The end tag token
- is ignored. */
- return false;
- }
- }
- }
- break;
- }
- break;
- }
- }
-
- private function inTable($token)
- {
- $clear = array('html', 'table');
-
- /* A character token that is one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE */
- if ($token['type'] === HTML5::CHARACTR &&
- preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
- ) {
- /* Append the character to the current node. */
- $text = $this->dom->createTextNode($token['data']);
- end($this->stack)->appendChild($text);
-
- /* A comment token */
- } elseif ($token['type'] === HTML5::COMMENT) {
- /* Append a Comment node to the current node with the data
- attribute set to the data given in the comment token. */
- $comment = $this->dom->createComment($token['data']);
- end($this->stack)->appendChild($comment);
-
- /* A start tag whose tag name is "caption" */
- } elseif ($token['type'] === HTML5::STARTTAG &&
- $token['name'] === 'caption'
- ) {
- /* Clear the stack back to a table context. */
- $this->clearStackToTableContext($clear);
-
- /* Insert a marker at the end of the list of active
- formatting elements. */
- $this->a_formatting[] = self::MARKER;
-
- /* Insert an HTML element for the token, then switch the
- insertion mode to "in caption". */
- $this->insertElement($token);
- $this->mode = self::IN_CAPTION;
-
- /* A start tag whose tag name is "colgroup" */
- } elseif ($token['type'] === HTML5::STARTTAG &&
- $token['name'] === 'colgroup'
- ) {
- /* Clear the stack back to a table context. */
- $this->clearStackToTableContext($clear);
-
- /* Insert an HTML element for the token, then switch the
- insertion mode to "in column group". */
- $this->insertElement($token);
- $this->mode = self::IN_CGROUP;
-
- /* A start tag whose tag name is "col" */
- } elseif ($token['type'] === HTML5::STARTTAG &&
- $token['name'] === 'col'
- ) {
- $this->inTable(
- array(
- 'name' => 'colgroup',
- 'type' => HTML5::STARTTAG,
- 'attr' => array()
- )
- );
-
- $this->inColumnGroup($token);
-
- /* A start tag whose tag name is one of: "tbody", "tfoot", "thead" */
- } elseif ($token['type'] === HTML5::STARTTAG && in_array(
- $token['name'],
- array('tbody', 'tfoot', 'thead')
- )
- ) {
- /* Clear the stack back to a table context. */
- $this->clearStackToTableContext($clear);
-
- /* Insert an HTML element for the token, then switch the insertion
- mode to "in table body". */
- $this->insertElement($token);
- $this->mode = self::IN_TBODY;
-
- /* A start tag whose tag name is one of: "td", "th", "tr" */
- } elseif ($token['type'] === HTML5::STARTTAG &&
- in_array($token['name'], array('td', 'th', 'tr'))
- ) {
- /* Act as if a start tag token with the tag name "tbody" had been
- seen, then reprocess the current token. */
- $this->inTable(
- array(
- 'name' => 'tbody',
- 'type' => HTML5::STARTTAG,
- 'attr' => array()
- )
- );
-
- return $this->inTableBody($token);
-
- /* A start tag whose tag name is "table" */
- } elseif ($token['type'] === HTML5::STARTTAG &&
- $token['name'] === 'table'
- ) {
- /* Parse error. Act as if an end tag token with the tag name "table"
- had been seen, then, if that token wasn't ignored, reprocess the
- current token. */
- $this->inTable(
- array(
- 'name' => 'table',
- 'type' => HTML5::ENDTAG
- )
- );
-
- return $this->mainPhase($token);
-
- /* An end tag whose tag name is "table" */
- } elseif ($token['type'] === HTML5::ENDTAG &&
- $token['name'] === 'table'
- ) {
- /* If the stack of open elements does not have an element in table
- scope with the same tag name as the token, this is a parse error.
- Ignore the token. (innerHTML case) */
- if (!$this->elementInScope($token['name'], true)) {
- return false;
-
- /* Otherwise: */
- } else {
- /* Generate implied end tags. */
- $this->generateImpliedEndTags();
-
- /* Now, if the current node is not a table element, then this
- is a parse error. */
- // w/e
-
- /* Pop elements from this stack until a table element has been
- popped from the stack. */
- while (true) {
- $current = end($this->stack)->nodeName;
- array_pop($this->stack);
-
- if ($current === 'table') {
- break;
- }
- }
-
- /* Reset the insertion mode appropriately. */
- $this->resetInsertionMode();
- }
-
- /* An end tag whose tag name is one of: "body", "caption", "col",
- "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */
- } elseif ($token['type'] === HTML5::ENDTAG && in_array(
- $token['name'],
- array(
- 'body',
- 'caption',
- 'col',
- 'colgroup',
- 'html',
- 'tbody',
- 'td',
- 'tfoot',
- 'th',
- 'thead',
- 'tr'
- )
- )
- ) {
- // Parse error. Ignore the token.
-
- /* Anything else */
- } else {
- /* Parse error. Process the token as if the insertion mode was "in
- body", with the following exception: */
-
- /* If the current node is a table, tbody, tfoot, thead, or tr
- element, then, whenever a node would be inserted into the current
- node, it must instead be inserted into the foster parent element. */
- if (in_array(
- end($this->stack)->nodeName,
- array('table', 'tbody', 'tfoot', 'thead', 'tr')
- )
- ) {
- /* The foster parent element is the parent element of the last
- table element in the stack of open elements, if there is a
- table element and it has such a parent element. If there is no
- table element in the stack of open elements (innerHTML case),
- then the foster parent element is the first element in the
- stack of open elements (the html element). Otherwise, if there
- is a table element in the stack of open elements, but the last
- table element in the stack of open elements has no parent, or
- its parent node is not an element, then the foster parent
- element is the element before the last table element in the
- stack of open elements. */
- for ($n = count($this->stack) - 1; $n >= 0; $n--) {
- if ($this->stack[$n]->nodeName === 'table') {
- $table = $this->stack[$n];
- break;
- }
- }
-
- if (isset($table) && $table->parentNode !== null) {
- $this->foster_parent = $table->parentNode;
-
- } elseif (!isset($table)) {
- $this->foster_parent = $this->stack[0];
-
- } elseif (isset($table) && ($table->parentNode === null ||
- $table->parentNode->nodeType !== XML_ELEMENT_NODE)
- ) {
- $this->foster_parent = $this->stack[$n - 1];
- }
- }
-
- $this->inBody($token);
- }
- }
-
- private function inCaption($token)
- {
- /* An end tag whose tag name is "caption" */
- if ($token['type'] === HTML5::ENDTAG && $token['name'] === 'caption') {
- /* If the stack of open elements does not have an element in table
- scope with the same tag name as the token, this is a parse error.
- Ignore the token. (innerHTML case) */
- if (!$this->elementInScope($token['name'], true)) {
- // Ignore
-
- /* Otherwise: */
- } else {
- /* Generate implied end tags. */
- $this->generateImpliedEndTags();
-
- /* Now, if the current node is not a caption element, then this
- is a parse error. */
- // w/e
-
- /* Pop elements from this stack until a caption element has
- been popped from the stack. */
- while (true) {
- $node = end($this->stack)->nodeName;
- array_pop($this->stack);
-
- if ($node === 'caption') {
- break;
- }
- }
-
- /* Clear the list of active formatting elements up to the last
- marker. */
- $this->clearTheActiveFormattingElementsUpToTheLastMarker();
-
- /* Switch the insertion mode to "in table". */
- $this->mode = self::IN_TABLE;
- }
-
- /* A start tag whose tag name is one of: "caption", "col", "colgroup",
- "tbody", "td", "tfoot", "th", "thead", "tr", or an end tag whose tag
- name is "table" */
- } elseif (($token['type'] === HTML5::STARTTAG && in_array(
- $token['name'],
- array(
- 'caption',
- 'col',
- 'colgroup',
- 'tbody',
- 'td',
- 'tfoot',
- 'th',
- 'thead',
- 'tr'
- )
- )) || ($token['type'] === HTML5::ENDTAG &&
- $token['name'] === 'table')
- ) {
- /* Parse error. Act as if an end tag with the tag name "caption"
- had been seen, then, if that token wasn't ignored, reprocess the
- current token. */
- $this->inCaption(
- array(
- 'name' => 'caption',
- 'type' => HTML5::ENDTAG
- )
- );
-
- return $this->inTable($token);
-
- /* An end tag whose tag name is one of: "body", "col", "colgroup",
- "html", "tbody", "td", "tfoot", "th", "thead", "tr" */
- } elseif ($token['type'] === HTML5::ENDTAG && in_array(
- $token['name'],
- array(
- 'body',
- 'col',
- 'colgroup',
- 'html',
- 'tbody',
- 'tfoot',
- 'th',
- 'thead',
- 'tr'
- )
- )
- ) {
- // Parse error. Ignore the token.
-
- /* Anything else */
- } else {
- /* Process the token as if the insertion mode was "in body". */
- $this->inBody($token);
- }
- }
-
- private function inColumnGroup($token)
- {
- /* A character token that is one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE */
- if ($token['type'] === HTML5::CHARACTR &&
- preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
- ) {
- /* Append the character to the current node. */
- $text = $this->dom->createTextNode($token['data']);
- end($this->stack)->appendChild($text);
-
- /* A comment token */
- } elseif ($token['type'] === HTML5::COMMENT) {
- /* Append a Comment node to the current node with the data
- attribute set to the data given in the comment token. */
- $comment = $this->dom->createComment($token['data']);
- end($this->stack)->appendChild($comment);
-
- /* A start tag whose tag name is "col" */
- } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'col') {
- /* Insert a col element for the token. Immediately pop the current
- node off the stack of open elements. */
- $this->insertElement($token);
- array_pop($this->stack);
-
- /* An end tag whose tag name is "colgroup" */
- } elseif ($token['type'] === HTML5::ENDTAG &&
- $token['name'] === 'colgroup'
- ) {
- /* If the current node is the root html element, then this is a
- parse error, ignore the token. (innerHTML case) */
- if (end($this->stack)->nodeName === 'html') {
- // Ignore
-
- /* Otherwise, pop the current node (which will be a colgroup
- element) from the stack of open elements. Switch the insertion
- mode to "in table". */
- } else {
- array_pop($this->stack);
- $this->mode = self::IN_TABLE;
- }
-
- /* An end tag whose tag name is "col" */
- } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'col') {
- /* Parse error. Ignore the token. */
-
- /* Anything else */
- } else {
- /* Act as if an end tag with the tag name "colgroup" had been seen,
- and then, if that token wasn't ignored, reprocess the current token. */
- $this->inColumnGroup(
- array(
- 'name' => 'colgroup',
- 'type' => HTML5::ENDTAG
- )
- );
-
- return $this->inTable($token);
- }
- }
-
- private function inTableBody($token)
- {
- $clear = array('tbody', 'tfoot', 'thead', 'html');
-
- /* A start tag whose tag name is "tr" */
- if ($token['type'] === HTML5::STARTTAG && $token['name'] === 'tr') {
- /* Clear the stack back to a table body context. */
- $this->clearStackToTableContext($clear);
-
- /* Insert a tr element for the token, then switch the insertion
- mode to "in row". */
- $this->insertElement($token);
- $this->mode = self::IN_ROW;
-
- /* A start tag whose tag name is one of: "th", "td" */
- } elseif ($token['type'] === HTML5::STARTTAG &&
- ($token['name'] === 'th' || $token['name'] === 'td')
- ) {
- /* Parse error. Act as if a start tag with the tag name "tr" had
- been seen, then reprocess the current token. */
- $this->inTableBody(
- array(
- 'name' => 'tr',
- 'type' => HTML5::STARTTAG,
- 'attr' => array()
- )
- );
-
- return $this->inRow($token);
-
- /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */
- } elseif ($token['type'] === HTML5::ENDTAG &&
- in_array($token['name'], array('tbody', 'tfoot', 'thead'))
- ) {
- /* If the stack of open elements does not have an element in table
- scope with the same tag name as the token, this is a parse error.
- Ignore the token. */
- if (!$this->elementInScope($token['name'], true)) {
- // Ignore
-
- /* Otherwise: */
- } else {
- /* Clear the stack back to a table body context. */
- $this->clearStackToTableContext($clear);
-
- /* Pop the current node from the stack of open elements. Switch
- the insertion mode to "in table". */
- array_pop($this->stack);
- $this->mode = self::IN_TABLE;
- }
-
- /* A start tag whose tag name is one of: "caption", "col", "colgroup",
- "tbody", "tfoot", "thead", or an end tag whose tag name is "table" */
- } elseif (($token['type'] === HTML5::STARTTAG && in_array(
- $token['name'],
- array('caption', 'col', 'colgroup', 'tbody', 'tfoor', 'thead')
- )) ||
- ($token['type'] === HTML5::STARTTAG && $token['name'] === 'table')
- ) {
- /* If the stack of open elements does not have a tbody, thead, or
- tfoot element in table scope, this is a parse error. Ignore the
- token. (innerHTML case) */
- if (!$this->elementInScope(array('tbody', 'thead', 'tfoot'), true)) {
- // Ignore.
-
- /* Otherwise: */
- } else {
- /* Clear the stack back to a table body context. */
- $this->clearStackToTableContext($clear);
-
- /* Act as if an end tag with the same tag name as the current
- node ("tbody", "tfoot", or "thead") had been seen, then
- reprocess the current token. */
- $this->inTableBody(
- array(
- 'name' => end($this->stack)->nodeName,
- 'type' => HTML5::ENDTAG
- )
- );
-
- return $this->mainPhase($token);
- }
-
- /* An end tag whose tag name is one of: "body", "caption", "col",
- "colgroup", "html", "td", "th", "tr" */
- } elseif ($token['type'] === HTML5::ENDTAG && in_array(
- $token['name'],
- array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr')
- )
- ) {
- /* Parse error. Ignore the token. */
-
- /* Anything else */
- } else {
- /* Process the token as if the insertion mode was "in table". */
- $this->inTable($token);
- }
- }
-
- private function inRow($token)
- {
- $clear = array('tr', 'html');
-
- /* A start tag whose tag name is one of: "th", "td" */
- if ($token['type'] === HTML5::STARTTAG &&
- ($token['name'] === 'th' || $token['name'] === 'td')
- ) {
- /* Clear the stack back to a table row context. */
- $this->clearStackToTableContext($clear);
-
- /* Insert an HTML element for the token, then switch the insertion
- mode to "in cell". */
- $this->insertElement($token);
- $this->mode = self::IN_CELL;
-
- /* Insert a marker at the end of the list of active formatting
- elements. */
- $this->a_formatting[] = self::MARKER;
-
- /* An end tag whose tag name is "tr" */
- } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'tr') {
- /* If the stack of open elements does not have an element in table
- scope with the same tag name as the token, this is a parse error.
- Ignore the token. (innerHTML case) */
- if (!$this->elementInScope($token['name'], true)) {
- // Ignore.
-
- /* Otherwise: */
- } else {
- /* Clear the stack back to a table row context. */
- $this->clearStackToTableContext($clear);
-
- /* Pop the current node (which will be a tr element) from the
- stack of open elements. Switch the insertion mode to "in table
- body". */
- array_pop($this->stack);
- $this->mode = self::IN_TBODY;
- }
-
- /* A start tag whose tag name is one of: "caption", "col", "colgroup",
- "tbody", "tfoot", "thead", "tr" or an end tag whose tag name is "table" */
- } elseif ($token['type'] === HTML5::STARTTAG && in_array(
- $token['name'],
- array('caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead', 'tr')
- )
- ) {
- /* Act as if an end tag with the tag name "tr" had been seen, then,
- if that token wasn't ignored, reprocess the current token. */
- $this->inRow(
- array(
- 'name' => 'tr',
- 'type' => HTML5::ENDTAG
- )
- );
-
- return $this->inCell($token);
-
- /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */
- } elseif ($token['type'] === HTML5::ENDTAG &&
- in_array($token['name'], array('tbody', 'tfoot', 'thead'))
- ) {
- /* If the stack of open elements does not have an element in table
- scope with the same tag name as the token, this is a parse error.
- Ignore the token. */
- if (!$this->elementInScope($token['name'], true)) {
- // Ignore.
-
- /* Otherwise: */
- } else {
- /* Otherwise, act as if an end tag with the tag name "tr" had
- been seen, then reprocess the current token. */
- $this->inRow(
- array(
- 'name' => 'tr',
- 'type' => HTML5::ENDTAG
- )
- );
-
- return $this->inCell($token);
- }
-
- /* An end tag whose tag name is one of: "body", "caption", "col",
- "colgroup", "html", "td", "th" */
- } elseif ($token['type'] === HTML5::ENDTAG && in_array(
- $token['name'],
- array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr')
- )
- ) {
- /* Parse error. Ignore the token. */
-
- /* Anything else */
- } else {
- /* Process the token as if the insertion mode was "in table". */
- $this->inTable($token);
- }
- }
-
- private function inCell($token)
- {
- /* An end tag whose tag name is one of: "td", "th" */
- if ($token['type'] === HTML5::ENDTAG &&
- ($token['name'] === 'td' || $token['name'] === 'th')
- ) {
- /* If the stack of open elements does not have an element in table
- scope with the same tag name as that of the token, then this is a
- parse error and the token must be ignored. */
- if (!$this->elementInScope($token['name'], true)) {
- // Ignore.
-
- /* Otherwise: */
- } else {
- /* Generate implied end tags, except for elements with the same
- tag name as the token. */
- $this->generateImpliedEndTags(array($token['name']));
-
- /* Now, if the current node is not an element with the same tag
- name as the token, then this is a parse error. */
- // k
-
- /* Pop elements from this stack until an element with the same
- tag name as the token has been popped from the stack. */
- while (true) {
- $node = end($this->stack)->nodeName;
- array_pop($this->stack);
-
- if ($node === $token['name']) {
- break;
- }
- }
-
- /* Clear the list of active formatting elements up to the last
- marker. */
- $this->clearTheActiveFormattingElementsUpToTheLastMarker();
-
- /* Switch the insertion mode to "in row". (The current node
- will be a tr element at this point.) */
- $this->mode = self::IN_ROW;
- }
-
- /* A start tag whose tag name is one of: "caption", "col", "colgroup",
- "tbody", "td", "tfoot", "th", "thead", "tr" */
- } elseif ($token['type'] === HTML5::STARTTAG && in_array(
- $token['name'],
- array(
- 'caption',
- 'col',
- 'colgroup',
- 'tbody',
- 'td',
- 'tfoot',
- 'th',
- 'thead',
- 'tr'
- )
- )
- ) {
- /* If the stack of open elements does not have a td or th element
- in table scope, then this is a parse error; ignore the token.
- (innerHTML case) */
- if (!$this->elementInScope(array('td', 'th'), true)) {
- // Ignore.
-
- /* Otherwise, close the cell (see below) and reprocess the current
- token. */
- } else {
- $this->closeCell();
- return $this->inRow($token);
- }
-
- /* A start tag whose tag name is one of: "caption", "col", "colgroup",
- "tbody", "td", "tfoot", "th", "thead", "tr" */
- } elseif ($token['type'] === HTML5::STARTTAG && in_array(
- $token['name'],
- array(
- 'caption',
- 'col',
- 'colgroup',
- 'tbody',
- 'td',
- 'tfoot',
- 'th',
- 'thead',
- 'tr'
- )
- )
- ) {
- /* If the stack of open elements does not have a td or th element
- in table scope, then this is a parse error; ignore the token.
- (innerHTML case) */
- if (!$this->elementInScope(array('td', 'th'), true)) {
- // Ignore.
-
- /* Otherwise, close the cell (see below) and reprocess the current
- token. */
- } else {
- $this->closeCell();
- return $this->inRow($token);
- }
-
- /* An end tag whose tag name is one of: "body", "caption", "col",
- "colgroup", "html" */
- } elseif ($token['type'] === HTML5::ENDTAG && in_array(
- $token['name'],
- array('body', 'caption', 'col', 'colgroup', 'html')
- )
- ) {
- /* Parse error. Ignore the token. */
-
- /* An end tag whose tag name is one of: "table", "tbody", "tfoot",
- "thead", "tr" */
- } elseif ($token['type'] === HTML5::ENDTAG && in_array(
- $token['name'],
- array('table', 'tbody', 'tfoot', 'thead', 'tr')
- )
- ) {
- /* If the stack of open elements does not have an element in table
- scope with the same tag name as that of the token (which can only
- happen for "tbody", "tfoot" and "thead", or, in the innerHTML case),
- then this is a parse error and the token must be ignored. */
- if (!$this->elementInScope($token['name'], true)) {
- // Ignore.
-
- /* Otherwise, close the cell (see below) and reprocess the current
- token. */
- } else {
- $this->closeCell();
- return $this->inRow($token);
- }
-
- /* Anything else */
- } else {
- /* Process the token as if the insertion mode was "in body". */
- $this->inBody($token);
- }
- }
-
- private function inSelect($token)
- {
- /* Handle the token as follows: */
-
- /* A character token */
- if ($token['type'] === HTML5::CHARACTR) {
- /* Append the token's character to the current node. */
- $this->insertText($token['data']);
-
- /* A comment token */
- } elseif ($token['type'] === HTML5::COMMENT) {
- /* Append a Comment node to the current node with the data
- attribute set to the data given in the comment token. */
- $this->insertComment($token['data']);
-
- /* A start tag token whose tag name is "option" */
- } elseif ($token['type'] === HTML5::STARTTAG &&
- $token['name'] === 'option'
- ) {
- /* If the current node is an option element, act as if an end tag
- with the tag name "option" had been seen. */
- if (end($this->stack)->nodeName === 'option') {
- $this->inSelect(
- array(
- 'name' => 'option',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
-
- /* A start tag token whose tag name is "optgroup" */
- } elseif ($token['type'] === HTML5::STARTTAG &&
- $token['name'] === 'optgroup'
- ) {
- /* If the current node is an option element, act as if an end tag
- with the tag name "option" had been seen. */
- if (end($this->stack)->nodeName === 'option') {
- $this->inSelect(
- array(
- 'name' => 'option',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- /* If the current node is an optgroup element, act as if an end tag
- with the tag name "optgroup" had been seen. */
- if (end($this->stack)->nodeName === 'optgroup') {
- $this->inSelect(
- array(
- 'name' => 'optgroup',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
-
- /* An end tag token whose tag name is "optgroup" */
- } elseif ($token['type'] === HTML5::ENDTAG &&
- $token['name'] === 'optgroup'
- ) {
- /* First, if the current node is an option element, and the node
- immediately before it in the stack of open elements is an optgroup
- element, then act as if an end tag with the tag name "option" had
- been seen. */
- $elements_in_stack = count($this->stack);
-
- if ($this->stack[$elements_in_stack - 1]->nodeName === 'option' &&
- $this->stack[$elements_in_stack - 2]->nodeName === 'optgroup'
- ) {
- $this->inSelect(
- array(
- 'name' => 'option',
- 'type' => HTML5::ENDTAG
- )
- );
- }
-
- /* If the current node is an optgroup element, then pop that node
- from the stack of open elements. Otherwise, this is a parse error,
- ignore the token. */
- if ($this->stack[$elements_in_stack - 1] === 'optgroup') {
- array_pop($this->stack);
- }
-
- /* An end tag token whose tag name is "option" */
- } elseif ($token['type'] === HTML5::ENDTAG &&
- $token['name'] === 'option'
- ) {
- /* If the current node is an option element, then pop that node
- from the stack of open elements. Otherwise, this is a parse error,
- ignore the token. */
- if (end($this->stack)->nodeName === 'option') {
- array_pop($this->stack);
- }
-
- /* An end tag whose tag name is "select" */
- } elseif ($token['type'] === HTML5::ENDTAG &&
- $token['name'] === 'select'
- ) {
- /* If the stack of open elements does not have an element in table
- scope with the same tag name as the token, this is a parse error.
- Ignore the token. (innerHTML case) */
- if (!$this->elementInScope($token['name'], true)) {
- // w/e
-
- /* Otherwise: */
- } else {
- /* Pop elements from the stack of open elements until a select
- element has been popped from the stack. */
- while (true) {
- $current = end($this->stack)->nodeName;
- array_pop($this->stack);
-
- if ($current === 'select') {
- break;
- }
- }
-
- /* Reset the insertion mode appropriately. */
- $this->resetInsertionMode();
- }
-
- /* A start tag whose tag name is "select" */
- } elseif ($token['name'] === 'select' &&
- $token['type'] === HTML5::STARTTAG
- ) {
- /* Parse error. Act as if the token had been an end tag with the
- tag name "select" instead. */
- $this->inSelect(
- array(
- 'name' => 'select',
- 'type' => HTML5::ENDTAG
- )
- );
-
- /* An end tag whose tag name is one of: "caption", "table", "tbody",
- "tfoot", "thead", "tr", "td", "th" */
- } elseif (in_array(
- $token['name'],
- array(
- 'caption',
- 'table',
- 'tbody',
- 'tfoot',
- 'thead',
- 'tr',
- 'td',
- 'th'
- )
- ) && $token['type'] === HTML5::ENDTAG
- ) {
- /* Parse error. */
- // w/e
-
- /* If the stack of open elements has an element in table scope with
- the same tag name as that of the token, then act as if an end tag
- with the tag name "select" had been seen, and reprocess the token.
- Otherwise, ignore the token. */
- if ($this->elementInScope($token['name'], true)) {
- $this->inSelect(
- array(
- 'name' => 'select',
- 'type' => HTML5::ENDTAG
- )
- );
-
- $this->mainPhase($token);
- }
-
- /* Anything else */
- } else {
- /* Parse error. Ignore the token. */
- }
- }
-
- private function afterBody($token)
- {
- /* Handle the token as follows: */
-
- /* A character token that is one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE */
- if ($token['type'] === HTML5::CHARACTR &&
- preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
- ) {
- /* Process the token as it would be processed if the insertion mode
- was "in body". */
- $this->inBody($token);
-
- /* A comment token */
- } elseif ($token['type'] === HTML5::COMMENT) {
- /* Append a Comment node to the first element in the stack of open
- elements (the html element), with the data attribute set to the
- data given in the comment token. */
- $comment = $this->dom->createComment($token['data']);
- $this->stack[0]->appendChild($comment);
-
- /* An end tag with the tag name "html" */
- } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') {
- /* If the parser was originally created in order to handle the
- setting of an element's innerHTML attribute, this is a parse error;
- ignore the token. (The element will be an html element in this
- case.) (innerHTML case) */
-
- /* Otherwise, switch to the trailing end phase. */
- $this->phase = self::END_PHASE;
-
- /* Anything else */
- } else {
- /* Parse error. Set the insertion mode to "in body" and reprocess
- the token. */
- $this->mode = self::IN_BODY;
- return $this->inBody($token);
- }
- }
-
- private function inFrameset($token)
- {
- /* Handle the token as follows: */
-
- /* A character token that is one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */
- if ($token['type'] === HTML5::CHARACTR &&
- preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
- ) {
- /* Append the character to the current node. */
- $this->insertText($token['data']);
-
- /* A comment token */
- } elseif ($token['type'] === HTML5::COMMENT) {
- /* Append a Comment node to the current node with the data
- attribute set to the data given in the comment token. */
- $this->insertComment($token['data']);
-
- /* A start tag with the tag name "frameset" */
- } elseif ($token['name'] === 'frameset' &&
- $token['type'] === HTML5::STARTTAG
- ) {
- $this->insertElement($token);
-
- /* An end tag with the tag name "frameset" */
- } elseif ($token['name'] === 'frameset' &&
- $token['type'] === HTML5::ENDTAG
- ) {
- /* If the current node is the root html element, then this is a
- parse error; ignore the token. (innerHTML case) */
- if (end($this->stack)->nodeName === 'html') {
- // Ignore
-
- } else {
- /* Otherwise, pop the current node from the stack of open
- elements. */
- array_pop($this->stack);
-
- /* If the parser was not originally created in order to handle
- the setting of an element's innerHTML attribute (innerHTML case),
- and the current node is no longer a frameset element, then change
- the insertion mode to "after frameset". */
- $this->mode = self::AFTR_FRAME;
- }
-
- /* A start tag with the tag name "frame" */
- } elseif ($token['name'] === 'frame' &&
- $token['type'] === HTML5::STARTTAG
- ) {
- /* Insert an HTML element for the token. */
- $this->insertElement($token);
-
- /* Immediately pop the current node off the stack of open elements. */
- array_pop($this->stack);
-
- /* A start tag with the tag name "noframes" */
- } elseif ($token['name'] === 'noframes' &&
- $token['type'] === HTML5::STARTTAG
- ) {
- /* Process the token as if the insertion mode had been "in body". */
- $this->inBody($token);
-
- /* Anything else */
- } else {
- /* Parse error. Ignore the token. */
- }
- }
-
- private function afterFrameset($token)
- {
- /* Handle the token as follows: */
-
- /* A character token that is one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */
- if ($token['type'] === HTML5::CHARACTR &&
- preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
- ) {
- /* Append the character to the current node. */
- $this->insertText($token['data']);
-
- /* A comment token */
- } elseif ($token['type'] === HTML5::COMMENT) {
- /* Append a Comment node to the current node with the data
- attribute set to the data given in the comment token. */
- $this->insertComment($token['data']);
-
- /* An end tag with the tag name "html" */
- } elseif ($token['name'] === 'html' &&
- $token['type'] === HTML5::ENDTAG
- ) {
- /* Switch to the trailing end phase. */
- $this->phase = self::END_PHASE;
-
- /* A start tag with the tag name "noframes" */
- } elseif ($token['name'] === 'noframes' &&
- $token['type'] === HTML5::STARTTAG
- ) {
- /* Process the token as if the insertion mode had been "in body". */
- $this->inBody($token);
-
- /* Anything else */
- } else {
- /* Parse error. Ignore the token. */
- }
- }
-
- private function trailingEndPhase($token)
- {
- /* After the main phase, as each token is emitted from the tokenisation
- stage, it must be processed as described in this section. */
-
- /* A DOCTYPE token */
- if ($token['type'] === HTML5::DOCTYPE) {
- // Parse error. Ignore the token.
-
- /* A comment token */
- } elseif ($token['type'] === HTML5::COMMENT) {
- /* Append a Comment node to the Document object with the data
- attribute set to the data given in the comment token. */
- $comment = $this->dom->createComment($token['data']);
- $this->dom->appendChild($comment);
-
- /* A character token that is one of one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE */
- } elseif ($token['type'] === HTML5::CHARACTR &&
- preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
- ) {
- /* Process the token as it would be processed in the main phase. */
- $this->mainPhase($token);
-
- /* A character token that is not one of U+0009 CHARACTER TABULATION,
- U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
- or U+0020 SPACE. Or a start tag token. Or an end tag token. */
- } elseif (($token['type'] === HTML5::CHARACTR &&
- preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) ||
- $token['type'] === HTML5::STARTTAG || $token['type'] === HTML5::ENDTAG
- ) {
- /* Parse error. Switch back to the main phase and reprocess the
- token. */
- $this->phase = self::MAIN_PHASE;
- return $this->mainPhase($token);
-
- /* An end-of-file token */
- } elseif ($token['type'] === HTML5::EOF) {
- /* OMG DONE!! */
- }
- }
-
- private function insertElement($token, $append = true, $check = false)
- {
- // Proprietary workaround for libxml2's limitations with tag names
- if ($check) {
- // Slightly modified HTML5 tag-name modification,
- // removing anything that's not an ASCII letter, digit, or hyphen
- $token['name'] = preg_replace('/[^a-z0-9-]/i', '', $token['name']);
- // Remove leading hyphens and numbers
- $token['name'] = ltrim($token['name'], '-0..9');
- // In theory, this should ever be needed, but just in case
- if ($token['name'] === '') {
- $token['name'] = 'span';
- } // arbitrary generic choice
- }
-
- $el = $this->dom->createElement($token['name']);
-
- foreach ($token['attr'] as $attr) {
- if (!$el->hasAttribute($attr['name'])) {
- $el->setAttribute($attr['name'], $attr['value']);
- }
- }
-
- $this->appendToRealParent($el);
- $this->stack[] = $el;
-
- return $el;
- }
-
- private function insertText($data)
- {
- $text = $this->dom->createTextNode($data);
- $this->appendToRealParent($text);
- }
-
- private function insertComment($data)
- {
- $comment = $this->dom->createComment($data);
- $this->appendToRealParent($comment);
- }
-
- private function appendToRealParent($node)
- {
- if ($this->foster_parent === null) {
- end($this->stack)->appendChild($node);
-
- } elseif ($this->foster_parent !== null) {
- /* If the foster parent element is the parent element of the
- last table element in the stack of open elements, then the new
- node must be inserted immediately before the last table element
- in the stack of open elements in the foster parent element;
- otherwise, the new node must be appended to the foster parent
- element. */
- for ($n = count($this->stack) - 1; $n >= 0; $n--) {
- if ($this->stack[$n]->nodeName === 'table' &&
- $this->stack[$n]->parentNode !== null
- ) {
- $table = $this->stack[$n];
- break;
- }
- }
-
- if (isset($table) && $this->foster_parent->isSameNode($table->parentNode)) {
- $this->foster_parent->insertBefore($node, $table);
- } else {
- $this->foster_parent->appendChild($node);
- }
-
- $this->foster_parent = null;
- }
- }
-
- private function elementInScope($el, $table = false)
- {
- if (is_array($el)) {
- foreach ($el as $element) {
- if ($this->elementInScope($element, $table)) {
- return true;
- }
- }
-
- return false;
- }
-
- $leng = count($this->stack);
-
- for ($n = 0; $n < $leng; $n++) {
- /* 1. Initialise node to be the current node (the bottommost node of
- the stack). */
- $node = $this->stack[$leng - 1 - $n];
-
- if ($node->tagName === $el) {
- /* 2. If node is the target node, terminate in a match state. */
- return true;
-
- } elseif ($node->tagName === 'table') {
- /* 3. Otherwise, if node is a table element, terminate in a failure
- state. */
- return false;
-
- } elseif ($table === true && in_array(
- $node->tagName,
- array(
- 'caption',
- 'td',
- 'th',
- 'button',
- 'marquee',
- 'object'
- )
- )
- ) {
- /* 4. Otherwise, if the algorithm is the "has an element in scope"
- variant (rather than the "has an element in table scope" variant),
- and node is one of the following, terminate in a failure state. */
- return false;
-
- } elseif ($node === $node->ownerDocument->documentElement) {
- /* 5. Otherwise, if node is an html element (root element), terminate
- in a failure state. (This can only happen if the node is the topmost
- node of the stack of open elements, and prevents the next step from
- being invoked if there are no more elements in the stack.) */
- return false;
- }
-
- /* Otherwise, set node to the previous entry in the stack of open
- elements and return to step 2. (This will never fail, since the loop
- will always terminate in the previous step if the top of the stack
- is reached.) */
- }
- }
-
- private function reconstructActiveFormattingElements()
- {
- /* 1. If there are no entries in the list of active formatting elements,
- then there is nothing to reconstruct; stop this algorithm. */
- $formatting_elements = count($this->a_formatting);
-
- if ($formatting_elements === 0) {
- return false;
- }
-
- /* 3. Let entry be the last (most recently added) element in the list
- of active formatting elements. */
- $entry = end($this->a_formatting);
-
- /* 2. If the last (most recently added) entry in the list of active
- formatting elements is a marker, or if it is an element that is in the
- stack of open elements, then there is nothing to reconstruct; stop this
- algorithm. */
- if ($entry === self::MARKER || in_array($entry, $this->stack, true)) {
- return false;
- }
-
- for ($a = $formatting_elements - 1; $a >= 0; true) {
- /* 4. If there are no entries before entry in the list of active
- formatting elements, then jump to step 8. */
- if ($a === 0) {
- $step_seven = false;
- break;
- }
-
- /* 5. Let entry be the entry one earlier than entry in the list of
- active formatting elements. */
- $a--;
- $entry = $this->a_formatting[$a];
-
- /* 6. If entry is neither a marker nor an element that is also in
- thetack of open elements, go to step 4. */
- if ($entry === self::MARKER || in_array($entry, $this->stack, true)) {
- break;
- }
- }
-
- while (true) {
- /* 7. Let entry be the element one later than entry in the list of
- active formatting elements. */
- if (isset($step_seven) && $step_seven === true) {
- $a++;
- $entry = $this->a_formatting[$a];
- }
-
- /* 8. Perform a shallow clone of the element entry to obtain clone. */
- $clone = $entry->cloneNode();
-
- /* 9. Append clone to the current node and push it onto the stack
- of open elements so that it is the new current node. */
- end($this->stack)->appendChild($clone);
- $this->stack[] = $clone;
-
- /* 10. Replace the entry for entry in the list with an entry for
- clone. */
- $this->a_formatting[$a] = $clone;
-
- /* 11. If the entry for clone in the list of active formatting
- elements is not the last entry in the list, return to step 7. */
- if (end($this->a_formatting) !== $clone) {
- $step_seven = true;
- } else {
- break;
- }
- }
- }
-
- private function clearTheActiveFormattingElementsUpToTheLastMarker()
- {
- /* When the steps below require the UA to clear the list of active
- formatting elements up to the last marker, the UA must perform the
- following steps: */
-
- while (true) {
- /* 1. Let entry be the last (most recently added) entry in the list
- of active formatting elements. */
- $entry = end($this->a_formatting);
-
- /* 2. Remove entry from the list of active formatting elements. */
- array_pop($this->a_formatting);
-
- /* 3. If entry was a marker, then stop the algorithm at this point.
- The list has been cleared up to the last marker. */
- if ($entry === self::MARKER) {
- break;
- }
- }
- }
-
- private function generateImpliedEndTags($exclude = array())
- {
- /* When the steps below require the UA to generate implied end tags,
- then, if the current node is a dd element, a dt element, an li element,
- a p element, a td element, a th element, or a tr element, the UA must
- act as if an end tag with the respective tag name had been seen and
- then generate implied end tags again. */
- $node = end($this->stack);
- $elements = array_diff(array('dd', 'dt', 'li', 'p', 'td', 'th', 'tr'), $exclude);
-
- while (in_array(end($this->stack)->nodeName, $elements)) {
- array_pop($this->stack);
- }
- }
-
- private function getElementCategory($node)
- {
- $name = $node->tagName;
- if (in_array($name, $this->special)) {
- return self::SPECIAL;
- } elseif (in_array($name, $this->scoping)) {
- return self::SCOPING;
- } elseif (in_array($name, $this->formatting)) {
- return self::FORMATTING;
- } else {
- return self::PHRASING;
- }
- }
-
- private function clearStackToTableContext($elements)
- {
- /* When the steps above require the UA to clear the stack back to a
- table context, it means that the UA must, while the current node is not
- a table element or an html element, pop elements from the stack of open
- elements. If this causes any elements to be popped from the stack, then
- this is a parse error. */
- while (true) {
- $node = end($this->stack)->nodeName;
-
- if (in_array($node, $elements)) {
- break;
- } else {
- array_pop($this->stack);
- }
- }
- }
-
- private function resetInsertionMode()
- {
- /* 1. Let last be false. */
- $last = false;
- $leng = count($this->stack);
-
- for ($n = $leng - 1; $n >= 0; $n--) {
- /* 2. Let node be the last node in the stack of open elements. */
- $node = $this->stack[$n];
-
- /* 3. If node is the first node in the stack of open elements, then
- set last to true. If the element whose innerHTML attribute is being
- set is neither a td element nor a th element, then set node to the
- element whose innerHTML attribute is being set. (innerHTML case) */
- if ($this->stack[0]->isSameNode($node)) {
- $last = true;
- }
-
- /* 4. If node is a select element, then switch the insertion mode to
- "in select" and abort these steps. (innerHTML case) */
- if ($node->nodeName === 'select') {
- $this->mode = self::IN_SELECT;
- break;
-
- /* 5. If node is a td or th element, then switch the insertion mode
- to "in cell" and abort these steps. */
- } elseif ($node->nodeName === 'td' || $node->nodeName === 'th') {
- $this->mode = self::IN_CELL;
- break;
-
- /* 6. If node is a tr element, then switch the insertion mode to
- "in row" and abort these steps. */
- } elseif ($node->nodeName === 'tr') {
- $this->mode = self::IN_ROW;
- break;
-
- /* 7. If node is a tbody, thead, or tfoot element, then switch the
- insertion mode to "in table body" and abort these steps. */
- } elseif (in_array($node->nodeName, array('tbody', 'thead', 'tfoot'))) {
- $this->mode = self::IN_TBODY;
- break;
-
- /* 8. If node is a caption element, then switch the insertion mode
- to "in caption" and abort these steps. */
- } elseif ($node->nodeName === 'caption') {
- $this->mode = self::IN_CAPTION;
- break;
-
- /* 9. If node is a colgroup element, then switch the insertion mode
- to "in column group" and abort these steps. (innerHTML case) */
- } elseif ($node->nodeName === 'colgroup') {
- $this->mode = self::IN_CGROUP;
- break;
-
- /* 10. If node is a table element, then switch the insertion mode
- to "in table" and abort these steps. */
- } elseif ($node->nodeName === 'table') {
- $this->mode = self::IN_TABLE;
- break;
-
- /* 11. If node is a head element, then switch the insertion mode
- to "in body" ("in body"! not "in head"!) and abort these steps.
- (innerHTML case) */
- } elseif ($node->nodeName === 'head') {
- $this->mode = self::IN_BODY;
- break;
-
- /* 12. If node is a body element, then switch the insertion mode to
- "in body" and abort these steps. */
- } elseif ($node->nodeName === 'body') {
- $this->mode = self::IN_BODY;
- break;
-
- /* 13. If node is a frameset element, then switch the insertion
- mode to "in frameset" and abort these steps. (innerHTML case) */
- } elseif ($node->nodeName === 'frameset') {
- $this->mode = self::IN_FRAME;
- break;
-
- /* 14. If node is an html element, then: if the head element
- pointer is null, switch the insertion mode to "before head",
- otherwise, switch the insertion mode to "after head". In either
- case, abort these steps. (innerHTML case) */
- } elseif ($node->nodeName === 'html') {
- $this->mode = ($this->head_pointer === null)
- ? self::BEFOR_HEAD
- : self::AFTER_HEAD;
-
- break;
-
- /* 15. If last is true, then set the insertion mode to "in body"
- and abort these steps. (innerHTML case) */
- } elseif ($last) {
- $this->mode = self::IN_BODY;
- break;
- }
- }
- }
-
- private function closeCell()
- {
- /* If the stack of open elements has a td or th element in table scope,
- then act as if an end tag token with that tag name had been seen. */
- foreach (array('td', 'th') as $cell) {
- if ($this->elementInScope($cell, true)) {
- $this->inCell(
- array(
- 'name' => $cell,
- 'type' => HTML5::ENDTAG
- )
- );
-
- break;
- }
- }
- }
-
- public function save()
- {
- return $this->dom;
- }
-}
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Node.php b/library/vendor/HTMLPurifier/HTMLPurifier/Node.php
deleted file mode 100644
index 3995fec9f..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Node.php
+++ /dev/null
@@ -1,49 +0,0 @@
-data = $data;
- $this->line = $line;
- $this->col = $col;
- }
-
- public function toTokenPair() {
- return array(new HTMLPurifier_Token_Comment($this->data, $this->line, $this->col), null);
- }
-}
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Node/Element.php b/library/vendor/HTMLPurifier/HTMLPurifier/Node/Element.php
deleted file mode 100644
index 6cbf56dad..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Node/Element.php
+++ /dev/null
@@ -1,59 +0,0 @@
- form or the form, i.e.
- * is it a pair of start/end tokens or an empty token.
- * @bool
- */
- public $empty = false;
-
- public $endCol = null, $endLine = null, $endArmor = array();
-
- public function __construct($name, $attr = array(), $line = null, $col = null, $armor = array()) {
- $this->name = $name;
- $this->attr = $attr;
- $this->line = $line;
- $this->col = $col;
- $this->armor = $armor;
- }
-
- public function toTokenPair() {
- // XXX inefficiency here, normalization is not necessary
- if ($this->empty) {
- return array(new HTMLPurifier_Token_Empty($this->name, $this->attr, $this->line, $this->col, $this->armor), null);
- } else {
- $start = new HTMLPurifier_Token_Start($this->name, $this->attr, $this->line, $this->col, $this->armor);
- $end = new HTMLPurifier_Token_End($this->name, array(), $this->endLine, $this->endCol, $this->endArmor);
- //$end->start = $start;
- return array($start, $end);
- }
- }
-}
-
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Node/Text.php b/library/vendor/HTMLPurifier/HTMLPurifier/Node/Text.php
deleted file mode 100644
index aec916647..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Node/Text.php
+++ /dev/null
@@ -1,54 +0,0 @@
-data = $data;
- $this->is_whitespace = $is_whitespace;
- $this->line = $line;
- $this->col = $col;
- }
-
- public function toTokenPair() {
- return array(new HTMLPurifier_Token_Text($this->data, $this->line, $this->col), null);
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/PercentEncoder.php b/library/vendor/HTMLPurifier/HTMLPurifier/PercentEncoder.php
deleted file mode 100644
index 18c8bbb00..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/PercentEncoder.php
+++ /dev/null
@@ -1,111 +0,0 @@
-preserve[$i] = true;
- }
- for ($i = 65; $i <= 90; $i++) { // upper-case
- $this->preserve[$i] = true;
- }
- for ($i = 97; $i <= 122; $i++) { // lower-case
- $this->preserve[$i] = true;
- }
- $this->preserve[45] = true; // Dash -
- $this->preserve[46] = true; // Period .
- $this->preserve[95] = true; // Underscore _
- $this->preserve[126]= true; // Tilde ~
-
- // extra letters not to escape
- if ($preserve !== false) {
- for ($i = 0, $c = strlen($preserve); $i < $c; $i++) {
- $this->preserve[ord($preserve[$i])] = true;
- }
- }
- }
-
- /**
- * Our replacement for urlencode, it encodes all non-reserved characters,
- * as well as any extra characters that were instructed to be preserved.
- * @note
- * Assumes that the string has already been normalized, making any
- * and all percent escape sequences valid. Percents will not be
- * re-escaped, regardless of their status in $preserve
- * @param string $string String to be encoded
- * @return string Encoded string.
- */
- public function encode($string)
- {
- $ret = '';
- for ($i = 0, $c = strlen($string); $i < $c; $i++) {
- if ($string[$i] !== '%' && !isset($this->preserve[$int = ord($string[$i])])) {
- $ret .= '%' . sprintf('%02X', $int);
- } else {
- $ret .= $string[$i];
- }
- }
- return $ret;
- }
-
- /**
- * Fix up percent-encoding by decoding unreserved characters and normalizing.
- * @warning This function is affected by $preserve, even though the
- * usual desired behavior is for this not to preserve those
- * characters. Be careful when reusing instances of PercentEncoder!
- * @param string $string String to normalize
- * @return string
- */
- public function normalize($string)
- {
- if ($string == '') {
- return '';
- }
- $parts = explode('%', $string);
- $ret = array_shift($parts);
- foreach ($parts as $part) {
- $length = strlen($part);
- if ($length < 2) {
- $ret .= '%25' . $part;
- continue;
- }
- $encoding = substr($part, 0, 2);
- $text = substr($part, 2);
- if (!ctype_xdigit($encoding)) {
- $ret .= '%25' . $part;
- continue;
- }
- $int = hexdec($encoding);
- if (isset($this->preserve[$int])) {
- $ret .= chr($int) . $text;
- continue;
- }
- $encoding = strtoupper($encoding);
- $ret .= '%' . $encoding . $text;
- }
- return $ret;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Printer.php b/library/vendor/HTMLPurifier/HTMLPurifier/Printer.php
deleted file mode 100644
index 549e4cea1..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Printer.php
+++ /dev/null
@@ -1,218 +0,0 @@
-getAll();
- $context = new HTMLPurifier_Context();
- $this->generator = new HTMLPurifier_Generator($config, $context);
- }
-
- /**
- * Main function that renders object or aspect of that object
- * @note Parameters vary depending on printer
- */
- // function render() {}
-
- /**
- * Returns a start tag
- * @param string $tag Tag name
- * @param array $attr Attribute array
- * @return string
- */
- protected function start($tag, $attr = array())
- {
- return $this->generator->generateFromToken(
- new HTMLPurifier_Token_Start($tag, $attr ? $attr : array())
- );
- }
-
- /**
- * Returns an end tag
- * @param string $tag Tag name
- * @return string
- */
- protected function end($tag)
- {
- return $this->generator->generateFromToken(
- new HTMLPurifier_Token_End($tag)
- );
- }
-
- /**
- * Prints a complete element with content inside
- * @param string $tag Tag name
- * @param string $contents Element contents
- * @param array $attr Tag attributes
- * @param bool $escape whether or not to escape contents
- * @return string
- */
- protected function element($tag, $contents, $attr = array(), $escape = true)
- {
- return $this->start($tag, $attr) .
- ($escape ? $this->escape($contents) : $contents) .
- $this->end($tag);
- }
-
- /**
- * @param string $tag
- * @param array $attr
- * @return string
- */
- protected function elementEmpty($tag, $attr = array())
- {
- return $this->generator->generateFromToken(
- new HTMLPurifier_Token_Empty($tag, $attr)
- );
- }
-
- /**
- * @param string $text
- * @return string
- */
- protected function text($text)
- {
- return $this->generator->generateFromToken(
- new HTMLPurifier_Token_Text($text)
- );
- }
-
- /**
- * Prints a simple key/value row in a table.
- * @param string $name Key
- * @param mixed $value Value
- * @return string
- */
- protected function row($name, $value)
- {
- if (is_bool($value)) {
- $value = $value ? 'On' : 'Off';
- }
- return
- $this->start('tr') . "\n" .
- $this->element('th', $name) . "\n" .
- $this->element('td', $value) . "\n" .
- $this->end('tr');
- }
-
- /**
- * Escapes a string for HTML output.
- * @param string $string String to escape
- * @return string
- */
- protected function escape($string)
- {
- $string = HTMLPurifier_Encoder::cleanUTF8($string);
- $string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8');
- return $string;
- }
-
- /**
- * Takes a list of strings and turns them into a single list
- * @param string[] $array List of strings
- * @param bool $polite Bool whether or not to add an end before the last
- * @return string
- */
- protected function listify($array, $polite = false)
- {
- if (empty($array)) {
- return 'None';
- }
- $ret = '';
- $i = count($array);
- foreach ($array as $value) {
- $i--;
- $ret .= $value;
- if ($i > 0 && !($polite && $i == 1)) {
- $ret .= ', ';
- }
- if ($polite && $i == 1) {
- $ret .= 'and ';
- }
- }
- return $ret;
- }
-
- /**
- * Retrieves the class of an object without prefixes, as well as metadata
- * @param object $obj Object to determine class of
- * @param string $sec_prefix Further prefix to remove
- * @return string
- */
- protected function getClass($obj, $sec_prefix = '')
- {
- static $five = null;
- if ($five === null) {
- $five = version_compare(PHP_VERSION, '5', '>=');
- }
- $prefix = 'HTMLPurifier_' . $sec_prefix;
- if (!$five) {
- $prefix = strtolower($prefix);
- }
- $class = str_replace($prefix, '', get_class($obj));
- $lclass = strtolower($class);
- $class .= '(';
- switch ($lclass) {
- case 'enum':
- $values = array();
- foreach ($obj->valid_values as $value => $bool) {
- $values[] = $value;
- }
- $class .= implode(', ', $values);
- break;
- case 'css_composite':
- $values = array();
- foreach ($obj->defs as $def) {
- $values[] = $this->getClass($def, $sec_prefix);
- }
- $class .= implode(', ', $values);
- break;
- case 'css_multiple':
- $class .= $this->getClass($obj->single, $sec_prefix) . ', ';
- $class .= $obj->max;
- break;
- case 'css_denyelementdecorator':
- $class .= $this->getClass($obj->def, $sec_prefix) . ', ';
- $class .= $obj->element;
- break;
- case 'css_importantdecorator':
- $class .= $this->getClass($obj->def, $sec_prefix);
- if ($obj->allow) {
- $class .= ', !important';
- }
- break;
- }
- $class .= ')';
- return $class;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Printer/CSSDefinition.php b/library/vendor/HTMLPurifier/HTMLPurifier/Printer/CSSDefinition.php
deleted file mode 100644
index 29505fe12..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Printer/CSSDefinition.php
+++ /dev/null
@@ -1,44 +0,0 @@
-def = $config->getCSSDefinition();
- $ret = '';
-
- $ret .= $this->start('div', array('class' => 'HTMLPurifier_Printer'));
- $ret .= $this->start('table');
-
- $ret .= $this->element('caption', 'Properties ($info)');
-
- $ret .= $this->start('thead');
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Property', array('class' => 'heavy'));
- $ret .= $this->element('th', 'Definition', array('class' => 'heavy', 'style' => 'width:auto;'));
- $ret .= $this->end('tr');
- $ret .= $this->end('thead');
-
- ksort($this->def->info);
- foreach ($this->def->info as $property => $obj) {
- $name = $this->getClass($obj, 'AttrDef_');
- $ret .= $this->row($property, $name);
- }
-
- $ret .= $this->end('table');
- $ret .= $this->end('div');
-
- return $ret;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.php b/library/vendor/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.php
deleted file mode 100644
index 36100ce73..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.php
+++ /dev/null
@@ -1,447 +0,0 @@
-docURL = $doc_url;
- $this->name = $name;
- $this->compress = $compress;
- // initialize sub-printers
- $this->fields[0] = new HTMLPurifier_Printer_ConfigForm_default();
- $this->fields[HTMLPurifier_VarParser::BOOL] = new HTMLPurifier_Printer_ConfigForm_bool();
- }
-
- /**
- * Sets default column and row size for textareas in sub-printers
- * @param $cols Integer columns of textarea, null to use default
- * @param $rows Integer rows of textarea, null to use default
- */
- public function setTextareaDimensions($cols = null, $rows = null)
- {
- if ($cols) {
- $this->fields['default']->cols = $cols;
- }
- if ($rows) {
- $this->fields['default']->rows = $rows;
- }
- }
-
- /**
- * Retrieves styling, in case it is not accessible by webserver
- */
- public static function getCSS()
- {
- return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.css');
- }
-
- /**
- * Retrieves JavaScript, in case it is not accessible by webserver
- */
- public static function getJavaScript()
- {
- return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.js');
- }
-
- /**
- * Returns HTML output for a configuration form
- * @param HTMLPurifier_Config|array $config Configuration object of current form state, or an array
- * where [0] has an HTML namespace and [1] is being rendered.
- * @param array|bool $allowed Optional namespace(s) and directives to restrict form to.
- * @param bool $render_controls
- * @return string
- */
- public function render($config, $allowed = true, $render_controls = true)
- {
- if (is_array($config) && isset($config[0])) {
- $gen_config = $config[0];
- $config = $config[1];
- } else {
- $gen_config = $config;
- }
-
- $this->config = $config;
- $this->genConfig = $gen_config;
- $this->prepareGenerator($gen_config);
-
- $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $config->def);
- $all = array();
- foreach ($allowed as $key) {
- list($ns, $directive) = $key;
- $all[$ns][$directive] = $config->get($ns . '.' . $directive);
- }
-
- $ret = '';
- $ret .= $this->start('table', array('class' => 'hp-config'));
- $ret .= $this->start('thead');
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Directive', array('class' => 'hp-directive'));
- $ret .= $this->element('th', 'Value', array('class' => 'hp-value'));
- $ret .= $this->end('tr');
- $ret .= $this->end('thead');
- foreach ($all as $ns => $directives) {
- $ret .= $this->renderNamespace($ns, $directives);
- }
- if ($render_controls) {
- $ret .= $this->start('tbody');
- $ret .= $this->start('tr');
- $ret .= $this->start('td', array('colspan' => 2, 'class' => 'controls'));
- $ret .= $this->elementEmpty('input', array('type' => 'submit', 'value' => 'Submit'));
- $ret .= '[Reset]';
- $ret .= $this->end('td');
- $ret .= $this->end('tr');
- $ret .= $this->end('tbody');
- }
- $ret .= $this->end('table');
- return $ret;
- }
-
- /**
- * Renders a single namespace
- * @param $ns String namespace name
- * @param array $directives array of directives to values
- * @return string
- */
- protected function renderNamespace($ns, $directives)
- {
- $ret = '';
- $ret .= $this->start('tbody', array('class' => 'namespace'));
- $ret .= $this->start('tr');
- $ret .= $this->element('th', $ns, array('colspan' => 2));
- $ret .= $this->end('tr');
- $ret .= $this->end('tbody');
- $ret .= $this->start('tbody');
- foreach ($directives as $directive => $value) {
- $ret .= $this->start('tr');
- $ret .= $this->start('th');
- if ($this->docURL) {
- $url = str_replace('%s', urlencode("$ns.$directive"), $this->docURL);
- $ret .= $this->start('a', array('href' => $url));
- }
- $attr = array('for' => "{$this->name}:$ns.$directive");
-
- // crop directive name if it's too long
- if (!$this->compress || (strlen($directive) < $this->compress)) {
- $directive_disp = $directive;
- } else {
- $directive_disp = substr($directive, 0, $this->compress - 2) . '...';
- $attr['title'] = $directive;
- }
-
- $ret .= $this->element(
- 'label',
- $directive_disp,
- // component printers must create an element with this id
- $attr
- );
- if ($this->docURL) {
- $ret .= $this->end('a');
- }
- $ret .= $this->end('th');
-
- $ret .= $this->start('td');
- $def = $this->config->def->info["$ns.$directive"];
- if (is_int($def)) {
- $allow_null = $def < 0;
- $type = abs($def);
- } else {
- $type = $def->type;
- $allow_null = isset($def->allow_null);
- }
- if (!isset($this->fields[$type])) {
- $type = 0;
- } // default
- $type_obj = $this->fields[$type];
- if ($allow_null) {
- $type_obj = new HTMLPurifier_Printer_ConfigForm_NullDecorator($type_obj);
- }
- $ret .= $type_obj->render($ns, $directive, $value, $this->name, array($this->genConfig, $this->config));
- $ret .= $this->end('td');
- $ret .= $this->end('tr');
- }
- $ret .= $this->end('tbody');
- return $ret;
- }
-
-}
-
-/**
- * Printer decorator for directives that accept null
- */
-class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer
-{
- /**
- * Printer being decorated
- * @type HTMLPurifier_Printer
- */
- protected $obj;
-
- /**
- * @param HTMLPurifier_Printer $obj Printer to decorate
- */
- public function __construct($obj)
- {
- parent::__construct();
- $this->obj = $obj;
- }
-
- /**
- * @param string $ns
- * @param string $directive
- * @param string $value
- * @param string $name
- * @param HTMLPurifier_Config|array $config
- * @return string
- */
- public function render($ns, $directive, $value, $name, $config)
- {
- if (is_array($config) && isset($config[0])) {
- $gen_config = $config[0];
- $config = $config[1];
- } else {
- $gen_config = $config;
- }
- $this->prepareGenerator($gen_config);
-
- $ret = '';
- $ret .= $this->start('label', array('for' => "$name:Null_$ns.$directive"));
- $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose'));
- $ret .= $this->text(' Null/Disabled');
- $ret .= $this->end('label');
- $attr = array(
- 'type' => 'checkbox',
- 'value' => '1',
- 'class' => 'null-toggle',
- 'name' => "$name" . "[Null_$ns.$directive]",
- 'id' => "$name:Null_$ns.$directive",
- 'onclick' => "toggleWriteability('$name:$ns.$directive',checked)" // INLINE JAVASCRIPT!!!!
- );
- if ($this->obj instanceof HTMLPurifier_Printer_ConfigForm_bool) {
- // modify inline javascript slightly
- $attr['onclick'] =
- "toggleWriteability('$name:Yes_$ns.$directive',checked);" .
- "toggleWriteability('$name:No_$ns.$directive',checked)";
- }
- if ($value === null) {
- $attr['checked'] = 'checked';
- }
- $ret .= $this->elementEmpty('input', $attr);
- $ret .= $this->text(' or ');
- $ret .= $this->elementEmpty('br');
- $ret .= $this->obj->render($ns, $directive, $value, $name, array($gen_config, $config));
- return $ret;
- }
-}
-
-/**
- * Swiss-army knife configuration form field printer
- */
-class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer
-{
- /**
- * @type int
- */
- public $cols = 18;
-
- /**
- * @type int
- */
- public $rows = 5;
-
- /**
- * @param string $ns
- * @param string $directive
- * @param string $value
- * @param string $name
- * @param HTMLPurifier_Config|array $config
- * @return string
- */
- public function render($ns, $directive, $value, $name, $config)
- {
- if (is_array($config) && isset($config[0])) {
- $gen_config = $config[0];
- $config = $config[1];
- } else {
- $gen_config = $config;
- }
- $this->prepareGenerator($gen_config);
- // this should probably be split up a little
- $ret = '';
- $def = $config->def->info["$ns.$directive"];
- if (is_int($def)) {
- $type = abs($def);
- } else {
- $type = $def->type;
- }
- if (is_array($value)) {
- switch ($type) {
- case HTMLPurifier_VarParser::LOOKUP:
- $array = $value;
- $value = array();
- foreach ($array as $val => $b) {
- $value[] = $val;
- }
- //TODO does this need a break?
- case HTMLPurifier_VarParser::ALIST:
- $value = implode(PHP_EOL, $value);
- break;
- case HTMLPurifier_VarParser::HASH:
- $nvalue = '';
- foreach ($value as $i => $v) {
- $nvalue .= "$i:$v" . PHP_EOL;
- }
- $value = $nvalue;
- break;
- default:
- $value = '';
- }
- }
- if ($type === HTMLPurifier_VarParser::MIXED) {
- return 'Not supported';
- $value = serialize($value);
- }
- $attr = array(
- 'name' => "$name" . "[$ns.$directive]",
- 'id' => "$name:$ns.$directive"
- );
- if ($value === null) {
- $attr['disabled'] = 'disabled';
- }
- if (isset($def->allowed)) {
- $ret .= $this->start('select', $attr);
- foreach ($def->allowed as $val => $b) {
- $attr = array();
- if ($value == $val) {
- $attr['selected'] = 'selected';
- }
- $ret .= $this->element('option', $val, $attr);
- }
- $ret .= $this->end('select');
- } elseif ($type === HTMLPurifier_VarParser::TEXT ||
- $type === HTMLPurifier_VarParser::ITEXT ||
- $type === HTMLPurifier_VarParser::ALIST ||
- $type === HTMLPurifier_VarParser::HASH ||
- $type === HTMLPurifier_VarParser::LOOKUP) {
- $attr['cols'] = $this->cols;
- $attr['rows'] = $this->rows;
- $ret .= $this->start('textarea', $attr);
- $ret .= $this->text($value);
- $ret .= $this->end('textarea');
- } else {
- $attr['value'] = $value;
- $attr['type'] = 'text';
- $ret .= $this->elementEmpty('input', $attr);
- }
- return $ret;
- }
-}
-
-/**
- * Bool form field printer
- */
-class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer
-{
- /**
- * @param string $ns
- * @param string $directive
- * @param string $value
- * @param string $name
- * @param HTMLPurifier_Config|array $config
- * @return string
- */
- public function render($ns, $directive, $value, $name, $config)
- {
- if (is_array($config) && isset($config[0])) {
- $gen_config = $config[0];
- $config = $config[1];
- } else {
- $gen_config = $config;
- }
- $this->prepareGenerator($gen_config);
- $ret = '';
- $ret .= $this->start('div', array('id' => "$name:$ns.$directive"));
-
- $ret .= $this->start('label', array('for' => "$name:Yes_$ns.$directive"));
- $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose'));
- $ret .= $this->text(' Yes');
- $ret .= $this->end('label');
-
- $attr = array(
- 'type' => 'radio',
- 'name' => "$name" . "[$ns.$directive]",
- 'id' => "$name:Yes_$ns.$directive",
- 'value' => '1'
- );
- if ($value === true) {
- $attr['checked'] = 'checked';
- }
- if ($value === null) {
- $attr['disabled'] = 'disabled';
- }
- $ret .= $this->elementEmpty('input', $attr);
-
- $ret .= $this->start('label', array('for' => "$name:No_$ns.$directive"));
- $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose'));
- $ret .= $this->text(' No');
- $ret .= $this->end('label');
-
- $attr = array(
- 'type' => 'radio',
- 'name' => "$name" . "[$ns.$directive]",
- 'id' => "$name:No_$ns.$directive",
- 'value' => '0'
- );
- if ($value === false) {
- $attr['checked'] = 'checked';
- }
- if ($value === null) {
- $attr['disabled'] = 'disabled';
- }
- $ret .= $this->elementEmpty('input', $attr);
-
- $ret .= $this->end('div');
-
- return $ret;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Printer/HTMLDefinition.php b/library/vendor/HTMLPurifier/HTMLPurifier/Printer/HTMLDefinition.php
deleted file mode 100644
index 5f2f2f8a7..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Printer/HTMLDefinition.php
+++ /dev/null
@@ -1,324 +0,0 @@
-config =& $config;
-
- $this->def = $config->getHTMLDefinition();
-
- $ret .= $this->start('div', array('class' => 'HTMLPurifier_Printer'));
-
- $ret .= $this->renderDoctype();
- $ret .= $this->renderEnvironment();
- $ret .= $this->renderContentSets();
- $ret .= $this->renderInfo();
-
- $ret .= $this->end('div');
-
- return $ret;
- }
-
- /**
- * Renders the Doctype table
- * @return string
- */
- protected function renderDoctype()
- {
- $doctype = $this->def->doctype;
- $ret = '';
- $ret .= $this->start('table');
- $ret .= $this->element('caption', 'Doctype');
- $ret .= $this->row('Name', $doctype->name);
- $ret .= $this->row('XML', $doctype->xml ? 'Yes' : 'No');
- $ret .= $this->row('Default Modules', implode($doctype->modules, ', '));
- $ret .= $this->row('Default Tidy Modules', implode($doctype->tidyModules, ', '));
- $ret .= $this->end('table');
- return $ret;
- }
-
-
- /**
- * Renders environment table, which is miscellaneous info
- * @return string
- */
- protected function renderEnvironment()
- {
- $def = $this->def;
-
- $ret = '';
-
- $ret .= $this->start('table');
- $ret .= $this->element('caption', 'Environment');
-
- $ret .= $this->row('Parent of fragment', $def->info_parent);
- $ret .= $this->renderChildren($def->info_parent_def->child);
- $ret .= $this->row('Block wrap name', $def->info_block_wrapper);
-
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Global attributes');
- $ret .= $this->element('td', $this->listifyAttr($def->info_global_attr), null, 0);
- $ret .= $this->end('tr');
-
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Tag transforms');
- $list = array();
- foreach ($def->info_tag_transform as $old => $new) {
- $new = $this->getClass($new, 'TagTransform_');
- $list[] = "<$old> with $new";
- }
- $ret .= $this->element('td', $this->listify($list));
- $ret .= $this->end('tr');
-
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Pre-AttrTransform');
- $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_pre));
- $ret .= $this->end('tr');
-
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Post-AttrTransform');
- $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_post));
- $ret .= $this->end('tr');
-
- $ret .= $this->end('table');
- return $ret;
- }
-
- /**
- * Renders the Content Sets table
- * @return string
- */
- protected function renderContentSets()
- {
- $ret = '';
- $ret .= $this->start('table');
- $ret .= $this->element('caption', 'Content Sets');
- foreach ($this->def->info_content_sets as $name => $lookup) {
- $ret .= $this->heavyHeader($name);
- $ret .= $this->start('tr');
- $ret .= $this->element('td', $this->listifyTagLookup($lookup));
- $ret .= $this->end('tr');
- }
- $ret .= $this->end('table');
- return $ret;
- }
-
- /**
- * Renders the Elements ($info) table
- * @return string
- */
- protected function renderInfo()
- {
- $ret = '';
- $ret .= $this->start('table');
- $ret .= $this->element('caption', 'Elements ($info)');
- ksort($this->def->info);
- $ret .= $this->heavyHeader('Allowed tags', 2);
- $ret .= $this->start('tr');
- $ret .= $this->element('td', $this->listifyTagLookup($this->def->info), array('colspan' => 2));
- $ret .= $this->end('tr');
- foreach ($this->def->info as $name => $def) {
- $ret .= $this->start('tr');
- $ret .= $this->element('th', "<$name>", array('class' => 'heavy', 'colspan' => 2));
- $ret .= $this->end('tr');
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Inline content');
- $ret .= $this->element('td', $def->descendants_are_inline ? 'Yes' : 'No');
- $ret .= $this->end('tr');
- if (!empty($def->excludes)) {
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Excludes');
- $ret .= $this->element('td', $this->listifyTagLookup($def->excludes));
- $ret .= $this->end('tr');
- }
- if (!empty($def->attr_transform_pre)) {
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Pre-AttrTransform');
- $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_pre));
- $ret .= $this->end('tr');
- }
- if (!empty($def->attr_transform_post)) {
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Post-AttrTransform');
- $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_post));
- $ret .= $this->end('tr');
- }
- if (!empty($def->auto_close)) {
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Auto closed by');
- $ret .= $this->element('td', $this->listifyTagLookup($def->auto_close));
- $ret .= $this->end('tr');
- }
- $ret .= $this->start('tr');
- $ret .= $this->element('th', 'Allowed attributes');
- $ret .= $this->element('td', $this->listifyAttr($def->attr), array(), 0);
- $ret .= $this->end('tr');
-
- if (!empty($def->required_attr)) {
- $ret .= $this->row('Required attributes', $this->listify($def->required_attr));
- }
-
- $ret .= $this->renderChildren($def->child);
- }
- $ret .= $this->end('table');
- return $ret;
- }
-
- /**
- * Renders a row describing the allowed children of an element
- * @param HTMLPurifier_ChildDef $def HTMLPurifier_ChildDef of pertinent element
- * @return string
- */
- protected function renderChildren($def)
- {
- $context = new HTMLPurifier_Context();
- $ret = '';
- $ret .= $this->start('tr');
- $elements = array();
- $attr = array();
- if (isset($def->elements)) {
- if ($def->type == 'strictblockquote') {
- $def->validateChildren(array(), $this->config, $context);
- }
- $elements = $def->elements;
- }
- if ($def->type == 'chameleon') {
- $attr['rowspan'] = 2;
- } elseif ($def->type == 'empty') {
- $elements = array();
- } elseif ($def->type == 'table') {
- $elements = array_flip(
- array(
- 'col',
- 'caption',
- 'colgroup',
- 'thead',
- 'tfoot',
- 'tbody',
- 'tr'
- )
- );
- }
- $ret .= $this->element('th', 'Allowed children', $attr);
-
- if ($def->type == 'chameleon') {
-
- $ret .= $this->element(
- 'td',
- 'Block: ' .
- $this->escape($this->listifyTagLookup($def->block->elements)),
- null,
- 0
- );
- $ret .= $this->end('tr');
- $ret .= $this->start('tr');
- $ret .= $this->element(
- 'td',
- 'Inline: ' .
- $this->escape($this->listifyTagLookup($def->inline->elements)),
- null,
- 0
- );
-
- } elseif ($def->type == 'custom') {
-
- $ret .= $this->element(
- 'td',
- '' . ucfirst($def->type) . ': ' .
- $def->dtd_regex
- );
-
- } else {
- $ret .= $this->element(
- 'td',
- '' . ucfirst($def->type) . ': ' .
- $this->escape($this->listifyTagLookup($elements)),
- null,
- 0
- );
- }
- $ret .= $this->end('tr');
- return $ret;
- }
-
- /**
- * Listifies a tag lookup table.
- * @param array $array Tag lookup array in form of array('tagname' => true)
- * @return string
- */
- protected function listifyTagLookup($array)
- {
- ksort($array);
- $list = array();
- foreach ($array as $name => $discard) {
- if ($name !== '#PCDATA' && !isset($this->def->info[$name])) {
- continue;
- }
- $list[] = $name;
- }
- return $this->listify($list);
- }
-
- /**
- * Listifies a list of objects by retrieving class names and internal state
- * @param array $array List of objects
- * @return string
- * @todo Also add information about internal state
- */
- protected function listifyObjectList($array)
- {
- ksort($array);
- $list = array();
- foreach ($array as $obj) {
- $list[] = $this->getClass($obj, 'AttrTransform_');
- }
- return $this->listify($list);
- }
-
- /**
- * Listifies a hash of attributes to AttrDef classes
- * @param array $array Array hash in form of array('attrname' => HTMLPurifier_AttrDef)
- * @return string
- */
- protected function listifyAttr($array)
- {
- ksort($array);
- $list = array();
- foreach ($array as $name => $obj) {
- if ($obj === false) {
- continue;
- }
- $list[] = "$name = " . $this->getClass($obj, 'AttrDef_') . '';
- }
- return $this->listify($list);
- }
-
- /**
- * Creates a heavy header row
- * @param string $text
- * @param int $num
- * @return string
- */
- protected function heavyHeader($text, $num = 1)
- {
- $ret = '';
- $ret .= $this->start('tr');
- $ret .= $this->element('th', $text, array('colspan' => $num, 'class' => 'heavy'));
- $ret .= $this->end('tr');
- return $ret;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/PropertyList.php b/library/vendor/HTMLPurifier/HTMLPurifier/PropertyList.php
deleted file mode 100644
index 189348fd9..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/PropertyList.php
+++ /dev/null
@@ -1,122 +0,0 @@
-parent = $parent;
- }
-
- /**
- * Recursively retrieves the value for a key
- * @param string $name
- * @throws HTMLPurifier_Exception
- */
- public function get($name)
- {
- if ($this->has($name)) {
- return $this->data[$name];
- }
- // possible performance bottleneck, convert to iterative if necessary
- if ($this->parent) {
- return $this->parent->get($name);
- }
- throw new HTMLPurifier_Exception("Key '$name' not found");
- }
-
- /**
- * Sets the value of a key, for this plist
- * @param string $name
- * @param mixed $value
- */
- public function set($name, $value)
- {
- $this->data[$name] = $value;
- }
-
- /**
- * Returns true if a given key exists
- * @param string $name
- * @return bool
- */
- public function has($name)
- {
- return array_key_exists($name, $this->data);
- }
-
- /**
- * Resets a value to the value of it's parent, usually the default. If
- * no value is specified, the entire plist is reset.
- * @param string $name
- */
- public function reset($name = null)
- {
- if ($name == null) {
- $this->data = array();
- } else {
- unset($this->data[$name]);
- }
- }
-
- /**
- * Squashes this property list and all of its property lists into a single
- * array, and returns the array. This value is cached by default.
- * @param bool $force If true, ignores the cache and regenerates the array.
- * @return array
- */
- public function squash($force = false)
- {
- if ($this->cache !== null && !$force) {
- return $this->cache;
- }
- if ($this->parent) {
- return $this->cache = array_merge($this->parent->squash($force), $this->data);
- } else {
- return $this->cache = $this->data;
- }
- }
-
- /**
- * Returns the parent plist.
- * @return HTMLPurifier_PropertyList
- */
- public function getParent()
- {
- return $this->parent;
- }
-
- /**
- * Sets the parent plist.
- * @param HTMLPurifier_PropertyList $plist Parent plist
- */
- public function setParent($plist)
- {
- $this->parent = $plist;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/PropertyListIterator.php b/library/vendor/HTMLPurifier/HTMLPurifier/PropertyListIterator.php
deleted file mode 100644
index 15b330ea3..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/PropertyListIterator.php
+++ /dev/null
@@ -1,42 +0,0 @@
-l = strlen($filter);
- $this->filter = $filter;
- }
-
- /**
- * @return bool
- */
- public function accept()
- {
- $key = $this->getInnerIterator()->key();
- if (strncmp($key, $this->filter, $this->l) !== 0) {
- return false;
- }
- return true;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Queue.php b/library/vendor/HTMLPurifier/HTMLPurifier/Queue.php
deleted file mode 100644
index f58db9042..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Queue.php
+++ /dev/null
@@ -1,56 +0,0 @@
-input = $input;
- $this->output = array();
- }
-
- /**
- * Shifts an element off the front of the queue.
- */
- public function shift() {
- if (empty($this->output)) {
- $this->output = array_reverse($this->input);
- $this->input = array();
- }
- if (empty($this->output)) {
- return NULL;
- }
- return array_pop($this->output);
- }
-
- /**
- * Pushes an element onto the front of the queue.
- */
- public function push($x) {
- array_push($this->input, $x);
- }
-
- /**
- * Checks if it's empty.
- */
- public function isEmpty() {
- return empty($this->input) && empty($this->output);
- }
-}
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy.php b/library/vendor/HTMLPurifier/HTMLPurifier/Strategy.php
deleted file mode 100644
index e1ff3b72d..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy.php
+++ /dev/null
@@ -1,26 +0,0 @@
-strategies as $strategy) {
- $tokens = $strategy->execute($tokens, $config, $context);
- }
- return $tokens;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/Core.php b/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/Core.php
deleted file mode 100644
index 4414c17d6..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/Core.php
+++ /dev/null
@@ -1,17 +0,0 @@
-strategies[] = new HTMLPurifier_Strategy_RemoveForeignElements();
- $this->strategies[] = new HTMLPurifier_Strategy_MakeWellFormed();
- $this->strategies[] = new HTMLPurifier_Strategy_FixNesting();
- $this->strategies[] = new HTMLPurifier_Strategy_ValidateAttributes();
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/FixNesting.php b/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/FixNesting.php
deleted file mode 100644
index 6fa673db9..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/FixNesting.php
+++ /dev/null
@@ -1,181 +0,0 @@
-getHTMLDefinition();
-
- $excludes_enabled = !$config->get('Core.DisableExcludes');
-
- // setup the context variable 'IsInline', for chameleon processing
- // is 'false' when we are not inline, 'true' when it must always
- // be inline, and an integer when it is inline for a certain
- // branch of the document tree
- $is_inline = $definition->info_parent_def->descendants_are_inline;
- $context->register('IsInline', $is_inline);
-
- // setup error collector
- $e =& $context->get('ErrorCollector', true);
-
- //####################################################################//
- // Loop initialization
-
- // stack that contains all elements that are excluded
- // it is organized by parent elements, similar to $stack,
- // but it is only populated when an element with exclusions is
- // processed, i.e. there won't be empty exclusions.
- $exclude_stack = array($definition->info_parent_def->excludes);
-
- // variable that contains the start token while we are processing
- // nodes. This enables error reporting to do its job
- $node = $top_node;
- // dummy token
- list($token, $d) = $node->toTokenPair();
- $context->register('CurrentNode', $node);
- $context->register('CurrentToken', $token);
-
- //####################################################################//
- // Loop
-
- // We need to implement a post-order traversal iteratively, to
- // avoid running into stack space limits. This is pretty tricky
- // to reason about, so we just manually stack-ify the recursive
- // variant:
- //
- // function f($node) {
- // foreach ($node->children as $child) {
- // f($child);
- // }
- // validate($node);
- // }
- //
- // Thus, we will represent a stack frame as array($node,
- // $is_inline, stack of children)
- // e.g. array_reverse($node->children) - already processed
- // children.
-
- $parent_def = $definition->info_parent_def;
- $stack = array(
- array($top_node,
- $parent_def->descendants_are_inline,
- $parent_def->excludes, // exclusions
- 0)
- );
-
- while (!empty($stack)) {
- list($node, $is_inline, $excludes, $ix) = array_pop($stack);
- // recursive call
- $go = false;
- $def = empty($stack) ? $definition->info_parent_def : $definition->info[$node->name];
- while (isset($node->children[$ix])) {
- $child = $node->children[$ix++];
- if ($child instanceof HTMLPurifier_Node_Element) {
- $go = true;
- $stack[] = array($node, $is_inline, $excludes, $ix);
- $stack[] = array($child,
- // ToDo: I don't think it matters if it's def or
- // child_def, but double check this...
- $is_inline || $def->descendants_are_inline,
- empty($def->excludes) ? $excludes
- : array_merge($excludes, $def->excludes),
- 0);
- break;
- }
- };
- if ($go) continue;
- list($token, $d) = $node->toTokenPair();
- // base case
- if ($excludes_enabled && isset($excludes[$node->name])) {
- $node->dead = true;
- if ($e) $e->send(E_ERROR, 'Strategy_FixNesting: Node excluded');
- } else {
- // XXX I suppose it would be slightly more efficient to
- // avoid the allocation here and have children
- // strategies handle it
- $children = array();
- foreach ($node->children as $child) {
- if (!$child->dead) $children[] = $child;
- }
- $result = $def->child->validateChildren($children, $config, $context);
- if ($result === true) {
- // nop
- $node->children = $children;
- } elseif ($result === false) {
- $node->dead = true;
- if ($e) $e->send(E_ERROR, 'Strategy_FixNesting: Node removed');
- } else {
- $node->children = $result;
- if ($e) {
- // XXX This will miss mutations of internal nodes. Perhaps defer to the child validators
- if (empty($result) && !empty($children)) {
- $e->send(E_ERROR, 'Strategy_FixNesting: Node contents removed');
- } else if ($result != $children) {
- $e->send(E_WARNING, 'Strategy_FixNesting: Node reorganized');
- }
- }
- }
- }
- }
-
- //####################################################################//
- // Post-processing
-
- // remove context variables
- $context->destroy('IsInline');
- $context->destroy('CurrentNode');
- $context->destroy('CurrentToken');
-
- //####################################################################//
- // Return
-
- return HTMLPurifier_Arborize::flatten($node, $config, $context);
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/MakeWellFormed.php b/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/MakeWellFormed.php
deleted file mode 100644
index e389e0011..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/MakeWellFormed.php
+++ /dev/null
@@ -1,600 +0,0 @@
-getHTMLDefinition();
-
- // local variables
- $generator = new HTMLPurifier_Generator($config, $context);
- $escape_invalid_tags = $config->get('Core.EscapeInvalidTags');
- // used for autoclose early abortion
- $global_parent_allowed_elements = $definition->info_parent_def->child->getAllowedElements($config);
- $e = $context->get('ErrorCollector', true);
- $i = false; // injector index
- list($zipper, $token) = HTMLPurifier_Zipper::fromArray($tokens);
- if ($token === NULL) {
- return array();
- }
- $reprocess = false; // whether or not to reprocess the same token
- $stack = array();
-
- // member variables
- $this->stack =& $stack;
- $this->tokens =& $tokens;
- $this->token =& $token;
- $this->zipper =& $zipper;
- $this->config = $config;
- $this->context = $context;
-
- // context variables
- $context->register('CurrentNesting', $stack);
- $context->register('InputZipper', $zipper);
- $context->register('CurrentToken', $token);
-
- // -- begin INJECTOR --
-
- $this->injectors = array();
-
- $injectors = $config->getBatch('AutoFormat');
- $def_injectors = $definition->info_injector;
- $custom_injectors = $injectors['Custom'];
- unset($injectors['Custom']); // special case
- foreach ($injectors as $injector => $b) {
- // XXX: Fix with a legitimate lookup table of enabled filters
- if (strpos($injector, '.') !== false) {
- continue;
- }
- $injector = "HTMLPurifier_Injector_$injector";
- if (!$b) {
- continue;
- }
- $this->injectors[] = new $injector;
- }
- foreach ($def_injectors as $injector) {
- // assumed to be objects
- $this->injectors[] = $injector;
- }
- foreach ($custom_injectors as $injector) {
- if (!$injector) {
- continue;
- }
- if (is_string($injector)) {
- $injector = "HTMLPurifier_Injector_$injector";
- $injector = new $injector;
- }
- $this->injectors[] = $injector;
- }
-
- // give the injectors references to the definition and context
- // variables for performance reasons
- foreach ($this->injectors as $ix => $injector) {
- $error = $injector->prepare($config, $context);
- if (!$error) {
- continue;
- }
- array_splice($this->injectors, $ix, 1); // rm the injector
- trigger_error("Cannot enable {$injector->name} injector because $error is not allowed", E_USER_WARNING);
- }
-
- // -- end INJECTOR --
-
- // a note on reprocessing:
- // In order to reduce code duplication, whenever some code needs
- // to make HTML changes in order to make things "correct", the
- // new HTML gets sent through the purifier, regardless of its
- // status. This means that if we add a start token, because it
- // was totally necessary, we don't have to update nesting; we just
- // punt ($reprocess = true; continue;) and it does that for us.
-
- // isset is in loop because $tokens size changes during loop exec
- for (;;
- // only increment if we don't need to reprocess
- $reprocess ? $reprocess = false : $token = $zipper->next($token)) {
-
- // check for a rewind
- if (is_int($i)) {
- // possibility: disable rewinding if the current token has a
- // rewind set on it already. This would offer protection from
- // infinite loop, but might hinder some advanced rewinding.
- $rewind_offset = $this->injectors[$i]->getRewindOffset();
- if (is_int($rewind_offset)) {
- for ($j = 0; $j < $rewind_offset; $j++) {
- if (empty($zipper->front)) break;
- $token = $zipper->prev($token);
- // indicate that other injectors should not process this token,
- // but we need to reprocess it
- unset($token->skip[$i]);
- $token->rewind = $i;
- if ($token instanceof HTMLPurifier_Token_Start) {
- array_pop($this->stack);
- } elseif ($token instanceof HTMLPurifier_Token_End) {
- $this->stack[] = $token->start;
- }
- }
- }
- $i = false;
- }
-
- // handle case of document end
- if ($token === NULL) {
- // kill processing if stack is empty
- if (empty($this->stack)) {
- break;
- }
-
- // peek
- $top_nesting = array_pop($this->stack);
- $this->stack[] = $top_nesting;
-
- // send error [TagClosedSuppress]
- if ($e && !isset($top_nesting->armor['MakeWellFormed_TagClosedError'])) {
- $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by document end', $top_nesting);
- }
-
- // append, don't splice, since this is the end
- $token = new HTMLPurifier_Token_End($top_nesting->name);
-
- // punt!
- $reprocess = true;
- continue;
- }
-
- //echo '
'; printZipper($zipper, $token);//printTokens($this->stack);
- //flush();
-
- // quick-check: if it's not a tag, no need to process
- if (empty($token->is_tag)) {
- if ($token instanceof HTMLPurifier_Token_Text) {
- foreach ($this->injectors as $i => $injector) {
- if (isset($token->skip[$i])) {
- continue;
- }
- if ($token->rewind !== null && $token->rewind !== $i) {
- continue;
- }
- // XXX fuckup
- $r = $token;
- $injector->handleText($r);
- $token = $this->processToken($r, $i);
- $reprocess = true;
- break;
- }
- }
- // another possibility is a comment
- continue;
- }
-
- if (isset($definition->info[$token->name])) {
- $type = $definition->info[$token->name]->child->type;
- } else {
- $type = false; // Type is unknown, treat accordingly
- }
-
- // quick tag checks: anything that's *not* an end tag
- $ok = false;
- if ($type === 'empty' && $token instanceof HTMLPurifier_Token_Start) {
- // claims to be a start tag but is empty
- $token = new HTMLPurifier_Token_Empty(
- $token->name,
- $token->attr,
- $token->line,
- $token->col,
- $token->armor
- );
- $ok = true;
- } elseif ($type && $type !== 'empty' && $token instanceof HTMLPurifier_Token_Empty) {
- // claims to be empty but really is a start tag
- // NB: this assignment is required
- $old_token = $token;
- $token = new HTMLPurifier_Token_End($token->name);
- $token = $this->insertBefore(
- new HTMLPurifier_Token_Start($old_token->name, $old_token->attr, $old_token->line, $old_token->col, $old_token->armor)
- );
- // punt (since we had to modify the input stream in a non-trivial way)
- $reprocess = true;
- continue;
- } elseif ($token instanceof HTMLPurifier_Token_Empty) {
- // real empty token
- $ok = true;
- } elseif ($token instanceof HTMLPurifier_Token_Start) {
- // start tag
-
- // ...unless they also have to close their parent
- if (!empty($this->stack)) {
-
- // Performance note: you might think that it's rather
- // inefficient, recalculating the autoclose information
- // for every tag that a token closes (since when we
- // do an autoclose, we push a new token into the
- // stream and then /process/ that, before
- // re-processing this token.) But this is
- // necessary, because an injector can make an
- // arbitrary transformations to the autoclosing
- // tokens we introduce, so things may have changed
- // in the meantime. Also, doing the inefficient thing is
- // "easy" to reason about (for certain perverse definitions
- // of "easy")
-
- $parent = array_pop($this->stack);
- $this->stack[] = $parent;
-
- $parent_def = null;
- $parent_elements = null;
- $autoclose = false;
- if (isset($definition->info[$parent->name])) {
- $parent_def = $definition->info[$parent->name];
- $parent_elements = $parent_def->child->getAllowedElements($config);
- $autoclose = !isset($parent_elements[$token->name]);
- }
-
- if ($autoclose && $definition->info[$token->name]->wrap) {
- // Check if an element can be wrapped by another
- // element to make it valid in a context (for
- // example, needs a - in between)
- $wrapname = $definition->info[$token->name]->wrap;
- $wrapdef = $definition->info[$wrapname];
- $elements = $wrapdef->child->getAllowedElements($config);
- if (isset($elements[$token->name]) && isset($parent_elements[$wrapname])) {
- $newtoken = new HTMLPurifier_Token_Start($wrapname);
- $token = $this->insertBefore($newtoken);
- $reprocess = true;
- continue;
- }
- }
-
- $carryover = false;
- if ($autoclose && $parent_def->formatting) {
- $carryover = true;
- }
-
- if ($autoclose) {
- // check if this autoclose is doomed to fail
- // (this rechecks $parent, which his harmless)
- $autoclose_ok = isset($global_parent_allowed_elements[$token->name]);
- if (!$autoclose_ok) {
- foreach ($this->stack as $ancestor) {
- $elements = $definition->info[$ancestor->name]->child->getAllowedElements($config);
- if (isset($elements[$token->name])) {
- $autoclose_ok = true;
- break;
- }
- if ($definition->info[$token->name]->wrap) {
- $wrapname = $definition->info[$token->name]->wrap;
- $wrapdef = $definition->info[$wrapname];
- $wrap_elements = $wrapdef->child->getAllowedElements($config);
- if (isset($wrap_elements[$token->name]) && isset($elements[$wrapname])) {
- $autoclose_ok = true;
- break;
- }
- }
- }
- }
- if ($autoclose_ok) {
- // errors need to be updated
- $new_token = new HTMLPurifier_Token_End($parent->name);
- $new_token->start = $parent;
- // [TagClosedSuppress]
- if ($e && !isset($parent->armor['MakeWellFormed_TagClosedError'])) {
- if (!$carryover) {
- $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag auto closed', $parent);
- } else {
- $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag carryover', $parent);
- }
- }
- if ($carryover) {
- $element = clone $parent;
- // [TagClosedAuto]
- $element->armor['MakeWellFormed_TagClosedError'] = true;
- $element->carryover = true;
- $token = $this->processToken(array($new_token, $token, $element));
- } else {
- $token = $this->insertBefore($new_token);
- }
- } else {
- $token = $this->remove();
- }
- $reprocess = true;
- continue;
- }
-
- }
- $ok = true;
- }
-
- if ($ok) {
- foreach ($this->injectors as $i => $injector) {
- if (isset($token->skip[$i])) {
- continue;
- }
- if ($token->rewind !== null && $token->rewind !== $i) {
- continue;
- }
- $r = $token;
- $injector->handleElement($r);
- $token = $this->processToken($r, $i);
- $reprocess = true;
- break;
- }
- if (!$reprocess) {
- // ah, nothing interesting happened; do normal processing
- if ($token instanceof HTMLPurifier_Token_Start) {
- $this->stack[] = $token;
- } elseif ($token instanceof HTMLPurifier_Token_End) {
- throw new HTMLPurifier_Exception(
- 'Improper handling of end tag in start code; possible error in MakeWellFormed'
- );
- }
- }
- continue;
- }
-
- // sanity check: we should be dealing with a closing tag
- if (!$token instanceof HTMLPurifier_Token_End) {
- throw new HTMLPurifier_Exception('Unaccounted for tag token in input stream, bug in HTML Purifier');
- }
-
- // make sure that we have something open
- if (empty($this->stack)) {
- if ($escape_invalid_tags) {
- if ($e) {
- $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag to text');
- }
- $token = new HTMLPurifier_Token_Text($generator->generateFromToken($token));
- } else {
- if ($e) {
- $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag removed');
- }
- $token = $this->remove();
- }
- $reprocess = true;
- continue;
- }
-
- // first, check for the simplest case: everything closes neatly.
- // Eventually, everything passes through here; if there are problems
- // we modify the input stream accordingly and then punt, so that
- // the tokens get processed again.
- $current_parent = array_pop($this->stack);
- if ($current_parent->name == $token->name) {
- $token->start = $current_parent;
- foreach ($this->injectors as $i => $injector) {
- if (isset($token->skip[$i])) {
- continue;
- }
- if ($token->rewind !== null && $token->rewind !== $i) {
- continue;
- }
- $r = $token;
- $injector->handleEnd($r);
- $token = $this->processToken($r, $i);
- $this->stack[] = $current_parent;
- $reprocess = true;
- break;
- }
- continue;
- }
-
- // okay, so we're trying to close the wrong tag
-
- // undo the pop previous pop
- $this->stack[] = $current_parent;
-
- // scroll back the entire nest, trying to find our tag.
- // (feature could be to specify how far you'd like to go)
- $size = count($this->stack);
- // -2 because -1 is the last element, but we already checked that
- $skipped_tags = false;
- for ($j = $size - 2; $j >= 0; $j--) {
- if ($this->stack[$j]->name == $token->name) {
- $skipped_tags = array_slice($this->stack, $j);
- break;
- }
- }
-
- // we didn't find the tag, so remove
- if ($skipped_tags === false) {
- if ($escape_invalid_tags) {
- if ($e) {
- $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag to text');
- }
- $token = new HTMLPurifier_Token_Text($generator->generateFromToken($token));
- } else {
- if ($e) {
- $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag removed');
- }
- $token = $this->remove();
- }
- $reprocess = true;
- continue;
- }
-
- // do errors, in REVERSE $j order: a,b,c with
- $c = count($skipped_tags);
- if ($e) {
- for ($j = $c - 1; $j > 0; $j--) {
- // notice we exclude $j == 0, i.e. the current ending tag, from
- // the errors... [TagClosedSuppress]
- if (!isset($skipped_tags[$j]->armor['MakeWellFormed_TagClosedError'])) {
- $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by element end', $skipped_tags[$j]);
- }
- }
- }
-
- // insert tags, in FORWARD $j order: c,b,a with
- $replace = array($token);
- for ($j = 1; $j < $c; $j++) {
- // ...as well as from the insertions
- $new_token = new HTMLPurifier_Token_End($skipped_tags[$j]->name);
- $new_token->start = $skipped_tags[$j];
- array_unshift($replace, $new_token);
- if (isset($definition->info[$new_token->name]) && $definition->info[$new_token->name]->formatting) {
- // [TagClosedAuto]
- $element = clone $skipped_tags[$j];
- $element->carryover = true;
- $element->armor['MakeWellFormed_TagClosedError'] = true;
- $replace[] = $element;
- }
- }
- $token = $this->processToken($replace);
- $reprocess = true;
- continue;
- }
-
- $context->destroy('CurrentToken');
- $context->destroy('CurrentNesting');
- $context->destroy('InputZipper');
-
- unset($this->injectors, $this->stack, $this->tokens);
- return $zipper->toArray($token);
- }
-
- /**
- * Processes arbitrary token values for complicated substitution patterns.
- * In general:
- *
- * If $token is an array, it is a list of tokens to substitute for the
- * current token. These tokens then get individually processed. If there
- * is a leading integer in the list, that integer determines how many
- * tokens from the stream should be removed.
- *
- * If $token is a regular token, it is swapped with the current token.
- *
- * If $token is false, the current token is deleted.
- *
- * If $token is an integer, that number of tokens (with the first token
- * being the current one) will be deleted.
- *
- * @param HTMLPurifier_Token|array|int|bool $token Token substitution value
- * @param HTMLPurifier_Injector|int $injector Injector that performed the substitution; default is if
- * this is not an injector related operation.
- * @throws HTMLPurifier_Exception
- */
- protected function processToken($token, $injector = -1)
- {
- // normalize forms of token
- if (is_object($token)) {
- $token = array(1, $token);
- }
- if (is_int($token)) {
- $token = array($token);
- }
- if ($token === false) {
- $token = array(1);
- }
- if (!is_array($token)) {
- throw new HTMLPurifier_Exception('Invalid token type from injector');
- }
- if (!is_int($token[0])) {
- array_unshift($token, 1);
- }
- if ($token[0] === 0) {
- throw new HTMLPurifier_Exception('Deleting zero tokens is not valid');
- }
-
- // $token is now an array with the following form:
- // array(number nodes to delete, new node 1, new node 2, ...)
-
- $delete = array_shift($token);
- list($old, $r) = $this->zipper->splice($this->token, $delete, $token);
-
- if ($injector > -1) {
- // determine appropriate skips
- $oldskip = isset($old[0]) ? $old[0]->skip : array();
- foreach ($token as $object) {
- $object->skip = $oldskip;
- $object->skip[$injector] = true;
- }
- }
-
- return $r;
-
- }
-
- /**
- * Inserts a token before the current token. Cursor now points to
- * this token. You must reprocess after this.
- * @param HTMLPurifier_Token $token
- */
- private function insertBefore($token)
- {
- // NB not $this->zipper->insertBefore(), due to positioning
- // differences
- $splice = $this->zipper->splice($this->token, 0, array($token));
-
- return $splice[1];
- }
-
- /**
- * Removes current token. Cursor now points to new token occupying previously
- * occupied space. You must reprocess after this.
- */
- private function remove()
- {
- return $this->zipper->delete();
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/RemoveForeignElements.php b/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/RemoveForeignElements.php
deleted file mode 100644
index 1a8149ecc..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/RemoveForeignElements.php
+++ /dev/null
@@ -1,207 +0,0 @@
-getHTMLDefinition();
- $generator = new HTMLPurifier_Generator($config, $context);
- $result = array();
-
- $escape_invalid_tags = $config->get('Core.EscapeInvalidTags');
- $remove_invalid_img = $config->get('Core.RemoveInvalidImg');
-
- // currently only used to determine if comments should be kept
- $trusted = $config->get('HTML.Trusted');
- $comment_lookup = $config->get('HTML.AllowedComments');
- $comment_regexp = $config->get('HTML.AllowedCommentsRegexp');
- $check_comments = $comment_lookup !== array() || $comment_regexp !== null;
-
- $remove_script_contents = $config->get('Core.RemoveScriptContents');
- $hidden_elements = $config->get('Core.HiddenElements');
-
- // remove script contents compatibility
- if ($remove_script_contents === true) {
- $hidden_elements['script'] = true;
- } elseif ($remove_script_contents === false && isset($hidden_elements['script'])) {
- unset($hidden_elements['script']);
- }
-
- $attr_validator = new HTMLPurifier_AttrValidator();
-
- // removes tokens until it reaches a closing tag with its value
- $remove_until = false;
-
- // converts comments into text tokens when this is equal to a tag name
- $textify_comments = false;
-
- $token = false;
- $context->register('CurrentToken', $token);
-
- $e = false;
- if ($config->get('Core.CollectErrors')) {
- $e =& $context->get('ErrorCollector');
- }
-
- foreach ($tokens as $token) {
- if ($remove_until) {
- if (empty($token->is_tag) || $token->name !== $remove_until) {
- continue;
- }
- }
- if (!empty($token->is_tag)) {
- // DEFINITION CALL
-
- // before any processing, try to transform the element
- if (isset($definition->info_tag_transform[$token->name])) {
- $original_name = $token->name;
- // there is a transformation for this tag
- // DEFINITION CALL
- $token = $definition->
- info_tag_transform[$token->name]->transform($token, $config, $context);
- if ($e) {
- $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Tag transform', $original_name);
- }
- }
-
- if (isset($definition->info[$token->name])) {
- // mostly everything's good, but
- // we need to make sure required attributes are in order
- if (($token instanceof HTMLPurifier_Token_Start || $token instanceof HTMLPurifier_Token_Empty) &&
- $definition->info[$token->name]->required_attr &&
- ($token->name != 'img' || $remove_invalid_img) // ensure config option still works
- ) {
- $attr_validator->validateToken($token, $config, $context);
- $ok = true;
- foreach ($definition->info[$token->name]->required_attr as $name) {
- if (!isset($token->attr[$name])) {
- $ok = false;
- break;
- }
- }
- if (!$ok) {
- if ($e) {
- $e->send(
- E_ERROR,
- 'Strategy_RemoveForeignElements: Missing required attribute',
- $name
- );
- }
- continue;
- }
- $token->armor['ValidateAttributes'] = true;
- }
-
- if (isset($hidden_elements[$token->name]) && $token instanceof HTMLPurifier_Token_Start) {
- $textify_comments = $token->name;
- } elseif ($token->name === $textify_comments && $token instanceof HTMLPurifier_Token_End) {
- $textify_comments = false;
- }
-
- } elseif ($escape_invalid_tags) {
- // invalid tag, generate HTML representation and insert in
- if ($e) {
- $e->send(E_WARNING, 'Strategy_RemoveForeignElements: Foreign element to text');
- }
- $token = new HTMLPurifier_Token_Text(
- $generator->generateFromToken($token)
- );
- } else {
- // check if we need to destroy all of the tag's children
- // CAN BE GENERICIZED
- if (isset($hidden_elements[$token->name])) {
- if ($token instanceof HTMLPurifier_Token_Start) {
- $remove_until = $token->name;
- } elseif ($token instanceof HTMLPurifier_Token_Empty) {
- // do nothing: we're still looking
- } else {
- $remove_until = false;
- }
- if ($e) {
- $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign meta element removed');
- }
- } else {
- if ($e) {
- $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign element removed');
- }
- }
- continue;
- }
- } elseif ($token instanceof HTMLPurifier_Token_Comment) {
- // textify comments in script tags when they are allowed
- if ($textify_comments !== false) {
- $data = $token->data;
- $token = new HTMLPurifier_Token_Text($data);
- } elseif ($trusted || $check_comments) {
- // always cleanup comments
- $trailing_hyphen = false;
- if ($e) {
- // perform check whether or not there's a trailing hyphen
- if (substr($token->data, -1) == '-') {
- $trailing_hyphen = true;
- }
- }
- $token->data = rtrim($token->data, '-');
- $found_double_hyphen = false;
- while (strpos($token->data, '--') !== false) {
- $found_double_hyphen = true;
- $token->data = str_replace('--', '-', $token->data);
- }
- if ($trusted || !empty($comment_lookup[trim($token->data)]) ||
- ($comment_regexp !== null && preg_match($comment_regexp, trim($token->data)))) {
- // OK good
- if ($e) {
- if ($trailing_hyphen) {
- $e->send(
- E_NOTICE,
- 'Strategy_RemoveForeignElements: Trailing hyphen in comment removed'
- );
- }
- if ($found_double_hyphen) {
- $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Hyphens in comment collapsed');
- }
- }
- } else {
- if ($e) {
- $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed');
- }
- continue;
- }
- } else {
- // strip comments
- if ($e) {
- $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed');
- }
- continue;
- }
- } elseif ($token instanceof HTMLPurifier_Token_Text) {
- } else {
- continue;
- }
- $result[] = $token;
- }
- if ($remove_until && $e) {
- // we removed tokens until the end, throw error
- $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Token removed to end', $remove_until);
- }
- $context->destroy('CurrentToken');
- return $result;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/ValidateAttributes.php b/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/ValidateAttributes.php
deleted file mode 100644
index fbb3d27c8..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Strategy/ValidateAttributes.php
+++ /dev/null
@@ -1,45 +0,0 @@
-register('CurrentToken', $token);
-
- foreach ($tokens as $key => $token) {
-
- // only process tokens that have attributes,
- // namely start and empty tags
- if (!$token instanceof HTMLPurifier_Token_Start && !$token instanceof HTMLPurifier_Token_Empty) {
- continue;
- }
-
- // skip tokens that are armored
- if (!empty($token->armor['ValidateAttributes'])) {
- continue;
- }
-
- // note that we have no facilities here for removing tokens
- $validator->validateToken($token, $config, $context);
- }
- $context->destroy('CurrentToken');
- return $tokens;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/StringHash.php b/library/vendor/HTMLPurifier/HTMLPurifier/StringHash.php
deleted file mode 100644
index c07370197..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/StringHash.php
+++ /dev/null
@@ -1,47 +0,0 @@
-accessed[$index] = true;
- return parent::offsetGet($index);
- }
-
- /**
- * Returns a lookup array of all array indexes that have been accessed.
- * @return array in form array($index => true).
- */
- public function getAccessed()
- {
- return $this->accessed;
- }
-
- /**
- * Resets the access array.
- */
- public function resetAccessed()
- {
- $this->accessed = array();
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/StringHashParser.php b/library/vendor/HTMLPurifier/HTMLPurifier/StringHashParser.php
deleted file mode 100644
index 7c73f8083..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/StringHashParser.php
+++ /dev/null
@@ -1,136 +0,0 @@
- 'DefaultKeyValue',
- * 'KEY' => 'Value',
- * 'KEY2' => 'Value2',
- * 'MULTILINE-KEY' => "Multiline\nvalue.\n",
- * )
- *
- * We use this as an easy to use file-format for configuration schema
- * files, but the class itself is usage agnostic.
- *
- * You can use ---- to forcibly terminate parsing of a single string-hash;
- * this marker is used in multi string-hashes to delimit boundaries.
- */
-class HTMLPurifier_StringHashParser
-{
-
- /**
- * @type string
- */
- public $default = 'ID';
-
- /**
- * Parses a file that contains a single string-hash.
- * @param string $file
- * @return array
- */
- public function parseFile($file)
- {
- if (!file_exists($file)) {
- return false;
- }
- $fh = fopen($file, 'r');
- if (!$fh) {
- return false;
- }
- $ret = $this->parseHandle($fh);
- fclose($fh);
- return $ret;
- }
-
- /**
- * Parses a file that contains multiple string-hashes delimited by '----'
- * @param string $file
- * @return array
- */
- public function parseMultiFile($file)
- {
- if (!file_exists($file)) {
- return false;
- }
- $ret = array();
- $fh = fopen($file, 'r');
- if (!$fh) {
- return false;
- }
- while (!feof($fh)) {
- $ret[] = $this->parseHandle($fh);
- }
- fclose($fh);
- return $ret;
- }
-
- /**
- * Internal parser that acepts a file handle.
- * @note While it's possible to simulate in-memory parsing by using
- * custom stream wrappers, if such a use-case arises we should
- * factor out the file handle into its own class.
- * @param resource $fh File handle with pointer at start of valid string-hash
- * block.
- * @return array
- */
- protected function parseHandle($fh)
- {
- $state = false;
- $single = false;
- $ret = array();
- do {
- $line = fgets($fh);
- if ($line === false) {
- break;
- }
- $line = rtrim($line, "\n\r");
- if (!$state && $line === '') {
- continue;
- }
- if ($line === '----') {
- break;
- }
- if (strncmp('--#', $line, 3) === 0) {
- // Comment
- continue;
- } elseif (strncmp('--', $line, 2) === 0) {
- // Multiline declaration
- $state = trim($line, '- ');
- if (!isset($ret[$state])) {
- $ret[$state] = '';
- }
- continue;
- } elseif (!$state) {
- $single = true;
- if (strpos($line, ':') !== false) {
- // Single-line declaration
- list($state, $line) = explode(':', $line, 2);
- $line = trim($line);
- } else {
- // Use default declaration
- $state = $this->default;
- }
- }
- if ($single) {
- $ret[$state] = $line;
- $single = false;
- $state = false;
- } else {
- $ret[$state] .= "$line\n";
- }
- } while (!feof($fh));
- return $ret;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/TagTransform.php b/library/vendor/HTMLPurifier/HTMLPurifier/TagTransform.php
deleted file mode 100644
index 7b8d83343..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/TagTransform.php
+++ /dev/null
@@ -1,37 +0,0 @@
- 'xx-small',
- '1' => 'xx-small',
- '2' => 'small',
- '3' => 'medium',
- '4' => 'large',
- '5' => 'x-large',
- '6' => 'xx-large',
- '7' => '300%',
- '-1' => 'smaller',
- '-2' => '60%',
- '+1' => 'larger',
- '+2' => '150%',
- '+3' => '200%',
- '+4' => '300%'
- );
-
- /**
- * @param HTMLPurifier_Token_Tag $tag
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return HTMLPurifier_Token_End|string
- */
- public function transform($tag, $config, $context)
- {
- if ($tag instanceof HTMLPurifier_Token_End) {
- $new_tag = clone $tag;
- $new_tag->name = $this->transform_to;
- return $new_tag;
- }
-
- $attr = $tag->attr;
- $prepend_style = '';
-
- // handle color transform
- if (isset($attr['color'])) {
- $prepend_style .= 'color:' . $attr['color'] . ';';
- unset($attr['color']);
- }
-
- // handle face transform
- if (isset($attr['face'])) {
- $prepend_style .= 'font-family:' . $attr['face'] . ';';
- unset($attr['face']);
- }
-
- // handle size transform
- if (isset($attr['size'])) {
- // normalize large numbers
- if ($attr['size'] !== '') {
- if ($attr['size']{0} == '+' || $attr['size']{0} == '-') {
- $size = (int)$attr['size'];
- if ($size < -2) {
- $attr['size'] = '-2';
- }
- if ($size > 4) {
- $attr['size'] = '+4';
- }
- } else {
- $size = (int)$attr['size'];
- if ($size > 7) {
- $attr['size'] = '7';
- }
- }
- }
- if (isset($this->_size_lookup[$attr['size']])) {
- $prepend_style .= 'font-size:' .
- $this->_size_lookup[$attr['size']] . ';';
- }
- unset($attr['size']);
- }
-
- if ($prepend_style) {
- $attr['style'] = isset($attr['style']) ?
- $prepend_style . $attr['style'] :
- $prepend_style;
- }
-
- $new_tag = clone $tag;
- $new_tag->name = $this->transform_to;
- $new_tag->attr = $attr;
-
- return $new_tag;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/TagTransform/Simple.php b/library/vendor/HTMLPurifier/HTMLPurifier/TagTransform/Simple.php
deleted file mode 100644
index 71bf10b91..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/TagTransform/Simple.php
+++ /dev/null
@@ -1,44 +0,0 @@
-transform_to = $transform_to;
- $this->style = $style;
- }
-
- /**
- * @param HTMLPurifier_Token_Tag $tag
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return string
- */
- public function transform($tag, $config, $context)
- {
- $new_tag = clone $tag;
- $new_tag->name = $this->transform_to;
- if (!is_null($this->style) &&
- ($new_tag instanceof HTMLPurifier_Token_Start || $new_tag instanceof HTMLPurifier_Token_Empty)
- ) {
- $this->prependCSS($new_tag->attr, $this->style);
- }
- return $new_tag;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Token.php b/library/vendor/HTMLPurifier/HTMLPurifier/Token.php
deleted file mode 100644
index 85b85e072..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Token.php
+++ /dev/null
@@ -1,100 +0,0 @@
-line = $l;
- $this->col = $c;
- }
-
- /**
- * Convenience function for DirectLex settings line/col position.
- * @param int $l
- * @param int $c
- */
- public function rawPosition($l, $c)
- {
- if ($c === -1) {
- $l++;
- }
- $this->line = $l;
- $this->col = $c;
- }
-
- /**
- * Converts a token into its corresponding node.
- */
- abstract public function toNode();
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Token/Comment.php b/library/vendor/HTMLPurifier/HTMLPurifier/Token/Comment.php
deleted file mode 100644
index 23453c705..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Token/Comment.php
+++ /dev/null
@@ -1,38 +0,0 @@
-data = $data;
- $this->line = $line;
- $this->col = $col;
- }
-
- public function toNode() {
- return new HTMLPurifier_Node_Comment($this->data, $this->line, $this->col);
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Token/Empty.php b/library/vendor/HTMLPurifier/HTMLPurifier/Token/Empty.php
deleted file mode 100644
index 78a95f555..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Token/Empty.php
+++ /dev/null
@@ -1,15 +0,0 @@
-empty = true;
- return $n;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Token/End.php b/library/vendor/HTMLPurifier/HTMLPurifier/Token/End.php
deleted file mode 100644
index 59b38fdc5..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Token/End.php
+++ /dev/null
@@ -1,24 +0,0 @@
-toNode not supported!");
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Token/Start.php b/library/vendor/HTMLPurifier/HTMLPurifier/Token/Start.php
deleted file mode 100644
index 019f317ad..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Token/Start.php
+++ /dev/null
@@ -1,10 +0,0 @@
-!empty($obj->is_tag)
- * without having to use a function call
is_a().
- * @type bool
- */
- public $is_tag = true;
-
- /**
- * The lower-case name of the tag, like 'a', 'b' or 'blockquote'.
- *
- * @note Strictly speaking, XML tags are case sensitive, so we shouldn't
- * be lower-casing them, but these tokens cater to HTML tags, which are
- * insensitive.
- * @type string
- */
- public $name;
-
- /**
- * Associative array of the tag's attributes.
- * @type array
- */
- public $attr = array();
-
- /**
- * Non-overloaded constructor, which lower-cases passed tag name.
- *
- * @param string $name String name.
- * @param array $attr Associative array of attributes.
- * @param int $line
- * @param int $col
- * @param array $armor
- */
- public function __construct($name, $attr = array(), $line = null, $col = null, $armor = array())
- {
- $this->name = ctype_lower($name) ? $name : strtolower($name);
- foreach ($attr as $key => $value) {
- // normalization only necessary when key is not lowercase
- if (!ctype_lower($key)) {
- $new_key = strtolower($key);
- if (!isset($attr[$new_key])) {
- $attr[$new_key] = $attr[$key];
- }
- if ($new_key !== $key) {
- unset($attr[$key]);
- }
- }
- }
- $this->attr = $attr;
- $this->line = $line;
- $this->col = $col;
- $this->armor = $armor;
- }
-
- public function toNode() {
- return new HTMLPurifier_Node_Element($this->name, $this->attr, $this->line, $this->col, $this->armor);
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/Token/Text.php b/library/vendor/HTMLPurifier/HTMLPurifier/Token/Text.php
deleted file mode 100644
index f26a1c211..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/Token/Text.php
+++ /dev/null
@@ -1,53 +0,0 @@
-data = $data;
- $this->is_whitespace = ctype_space($data);
- $this->line = $line;
- $this->col = $col;
- }
-
- public function toNode() {
- return new HTMLPurifier_Node_Text($this->data, $this->is_whitespace, $this->line, $this->col);
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/TokenFactory.php b/library/vendor/HTMLPurifier/HTMLPurifier/TokenFactory.php
deleted file mode 100644
index dea2446b9..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/TokenFactory.php
+++ /dev/null
@@ -1,118 +0,0 @@
-p_start = new HTMLPurifier_Token_Start('', array());
- $this->p_end = new HTMLPurifier_Token_End('');
- $this->p_empty = new HTMLPurifier_Token_Empty('', array());
- $this->p_text = new HTMLPurifier_Token_Text('');
- $this->p_comment = new HTMLPurifier_Token_Comment('');
- }
-
- /**
- * Creates a HTMLPurifier_Token_Start.
- * @param string $name Tag name
- * @param array $attr Associative array of attributes
- * @return HTMLPurifier_Token_Start Generated HTMLPurifier_Token_Start
- */
- public function createStart($name, $attr = array())
- {
- $p = clone $this->p_start;
- $p->__construct($name, $attr);
- return $p;
- }
-
- /**
- * Creates a HTMLPurifier_Token_End.
- * @param string $name Tag name
- * @return HTMLPurifier_Token_End Generated HTMLPurifier_Token_End
- */
- public function createEnd($name)
- {
- $p = clone $this->p_end;
- $p->__construct($name);
- return $p;
- }
-
- /**
- * Creates a HTMLPurifier_Token_Empty.
- * @param string $name Tag name
- * @param array $attr Associative array of attributes
- * @return HTMLPurifier_Token_Empty Generated HTMLPurifier_Token_Empty
- */
- public function createEmpty($name, $attr = array())
- {
- $p = clone $this->p_empty;
- $p->__construct($name, $attr);
- return $p;
- }
-
- /**
- * Creates a HTMLPurifier_Token_Text.
- * @param string $data Data of text token
- * @return HTMLPurifier_Token_Text Generated HTMLPurifier_Token_Text
- */
- public function createText($data)
- {
- $p = clone $this->p_text;
- $p->__construct($data);
- return $p;
- }
-
- /**
- * Creates a HTMLPurifier_Token_Comment.
- * @param string $data Data of comment token
- * @return HTMLPurifier_Token_Comment Generated HTMLPurifier_Token_Comment
- */
- public function createComment($data)
- {
- $p = clone $this->p_comment;
- $p->__construct($data);
- return $p;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URI.php b/library/vendor/HTMLPurifier/HTMLPurifier/URI.php
deleted file mode 100644
index a5e7ae298..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URI.php
+++ /dev/null
@@ -1,314 +0,0 @@
-scheme = is_null($scheme) || ctype_lower($scheme) ? $scheme : strtolower($scheme);
- $this->userinfo = $userinfo;
- $this->host = $host;
- $this->port = is_null($port) ? $port : (int)$port;
- $this->path = $path;
- $this->query = $query;
- $this->fragment = $fragment;
- }
-
- /**
- * Retrieves a scheme object corresponding to the URI's scheme/default
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return HTMLPurifier_URIScheme Scheme object appropriate for validating this URI
- */
- public function getSchemeObj($config, $context)
- {
- $registry = HTMLPurifier_URISchemeRegistry::instance();
- if ($this->scheme !== null) {
- $scheme_obj = $registry->getScheme($this->scheme, $config, $context);
- if (!$scheme_obj) {
- return false;
- } // invalid scheme, clean it out
- } else {
- // no scheme: retrieve the default one
- $def = $config->getDefinition('URI');
- $scheme_obj = $def->getDefaultScheme($config, $context);
- if (!$scheme_obj) {
- // something funky happened to the default scheme object
- trigger_error(
- 'Default scheme object "' . $def->defaultScheme . '" was not readable',
- E_USER_WARNING
- );
- return false;
- }
- }
- return $scheme_obj;
- }
-
- /**
- * Generic validation method applicable for all schemes. May modify
- * this URI in order to get it into a compliant form.
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return bool True if validation/filtering succeeds, false if failure
- */
- public function validate($config, $context)
- {
- // ABNF definitions from RFC 3986
- $chars_sub_delims = '!$&\'()*+,;=';
- $chars_gen_delims = ':/?#[]@';
- $chars_pchar = $chars_sub_delims . ':@';
-
- // validate host
- if (!is_null($this->host)) {
- $host_def = new HTMLPurifier_AttrDef_URI_Host();
- $this->host = $host_def->validate($this->host, $config, $context);
- if ($this->host === false) {
- $this->host = null;
- }
- }
-
- // validate scheme
- // NOTE: It's not appropriate to check whether or not this
- // scheme is in our registry, since a URIFilter may convert a
- // URI that we don't allow into one we do. So instead, we just
- // check if the scheme can be dropped because there is no host
- // and it is our default scheme.
- if (!is_null($this->scheme) && is_null($this->host) || $this->host === '') {
- // support for relative paths is pretty abysmal when the
- // scheme is present, so axe it when possible
- $def = $config->getDefinition('URI');
- if ($def->defaultScheme === $this->scheme) {
- $this->scheme = null;
- }
- }
-
- // validate username
- if (!is_null($this->userinfo)) {
- $encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . ':');
- $this->userinfo = $encoder->encode($this->userinfo);
- }
-
- // validate port
- if (!is_null($this->port)) {
- if ($this->port < 1 || $this->port > 65535) {
- $this->port = null;
- }
- }
-
- // validate path
- $segments_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/');
- if (!is_null($this->host)) { // this catches $this->host === ''
- // path-abempty (hier and relative)
- // http://www.example.com/my/path
- // //www.example.com/my/path (looks odd, but works, and
- // recognized by most browsers)
- // (this set is valid or invalid on a scheme by scheme
- // basis, so we'll deal with it later)
- // file:///my/path
- // ///my/path
- $this->path = $segments_encoder->encode($this->path);
- } elseif ($this->path !== '') {
- if ($this->path[0] === '/') {
- // path-absolute (hier and relative)
- // http:/my/path
- // /my/path
- if (strlen($this->path) >= 2 && $this->path[1] === '/') {
- // This could happen if both the host gets stripped
- // out
- // http://my/path
- // //my/path
- $this->path = '';
- } else {
- $this->path = $segments_encoder->encode($this->path);
- }
- } elseif (!is_null($this->scheme)) {
- // path-rootless (hier)
- // http:my/path
- // Short circuit evaluation means we don't need to check nz
- $this->path = $segments_encoder->encode($this->path);
- } else {
- // path-noscheme (relative)
- // my/path
- // (once again, not checking nz)
- $segment_nc_encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . '@');
- $c = strpos($this->path, '/');
- if ($c !== false) {
- $this->path =
- $segment_nc_encoder->encode(substr($this->path, 0, $c)) .
- $segments_encoder->encode(substr($this->path, $c));
- } else {
- $this->path = $segment_nc_encoder->encode($this->path);
- }
- }
- } else {
- // path-empty (hier and relative)
- $this->path = ''; // just to be safe
- }
-
- // qf = query and fragment
- $qf_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/?');
-
- if (!is_null($this->query)) {
- $this->query = $qf_encoder->encode($this->query);
- }
-
- if (!is_null($this->fragment)) {
- $this->fragment = $qf_encoder->encode($this->fragment);
- }
- return true;
- }
-
- /**
- * Convert URI back to string
- * @return string URI appropriate for output
- */
- public function toString()
- {
- // reconstruct authority
- $authority = null;
- // there is a rendering difference between a null authority
- // (http:foo-bar) and an empty string authority
- // (http:///foo-bar).
- if (!is_null($this->host)) {
- $authority = '';
- if (!is_null($this->userinfo)) {
- $authority .= $this->userinfo . '@';
- }
- $authority .= $this->host;
- if (!is_null($this->port)) {
- $authority .= ':' . $this->port;
- }
- }
-
- // Reconstruct the result
- // One might wonder about parsing quirks from browsers after
- // this reconstruction. Unfortunately, parsing behavior depends
- // on what *scheme* was employed (file:///foo is handled *very*
- // differently than http:///foo), so unfortunately we have to
- // defer to the schemes to do the right thing.
- $result = '';
- if (!is_null($this->scheme)) {
- $result .= $this->scheme . ':';
- }
- if (!is_null($authority)) {
- $result .= '//' . $authority;
- }
- $result .= $this->path;
- if (!is_null($this->query)) {
- $result .= '?' . $this->query;
- }
- if (!is_null($this->fragment)) {
- $result .= '#' . $this->fragment;
- }
-
- return $result;
- }
-
- /**
- * Returns true if this URL might be considered a 'local' URL given
- * the current context. This is true when the host is null, or
- * when it matches the host supplied to the configuration.
- *
- * Note that this does not do any scheme checking, so it is mostly
- * only appropriate for metadata that doesn't care about protocol
- * security. isBenign is probably what you actually want.
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return bool
- */
- public function isLocal($config, $context)
- {
- if ($this->host === null) {
- return true;
- }
- $uri_def = $config->getDefinition('URI');
- if ($uri_def->host === $this->host) {
- return true;
- }
- return false;
- }
-
- /**
- * Returns true if this URL should be considered a 'benign' URL,
- * that is:
- *
- * - It is a local URL (isLocal), and
- * - It has a equal or better level of security
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return bool
- */
- public function isBenign($config, $context)
- {
- if (!$this->isLocal($config, $context)) {
- return false;
- }
-
- $scheme_obj = $this->getSchemeObj($config, $context);
- if (!$scheme_obj) {
- return false;
- } // conservative approach
-
- $current_scheme_obj = $config->getDefinition('URI')->getDefaultScheme($config, $context);
- if ($current_scheme_obj->secure) {
- if (!$scheme_obj->secure) {
- return false;
- }
- }
- return true;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIDefinition.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIDefinition.php
deleted file mode 100644
index e0bd8bcca..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIDefinition.php
+++ /dev/null
@@ -1,112 +0,0 @@
-registerFilter(new HTMLPurifier_URIFilter_DisableExternal());
- $this->registerFilter(new HTMLPurifier_URIFilter_DisableExternalResources());
- $this->registerFilter(new HTMLPurifier_URIFilter_DisableResources());
- $this->registerFilter(new HTMLPurifier_URIFilter_HostBlacklist());
- $this->registerFilter(new HTMLPurifier_URIFilter_SafeIframe());
- $this->registerFilter(new HTMLPurifier_URIFilter_MakeAbsolute());
- $this->registerFilter(new HTMLPurifier_URIFilter_Munge());
- }
-
- public function registerFilter($filter)
- {
- $this->registeredFilters[$filter->name] = $filter;
- }
-
- public function addFilter($filter, $config)
- {
- $r = $filter->prepare($config);
- if ($r === false) return; // null is ok, for backwards compat
- if ($filter->post) {
- $this->postFilters[$filter->name] = $filter;
- } else {
- $this->filters[$filter->name] = $filter;
- }
- }
-
- protected function doSetup($config)
- {
- $this->setupMemberVariables($config);
- $this->setupFilters($config);
- }
-
- protected function setupFilters($config)
- {
- foreach ($this->registeredFilters as $name => $filter) {
- if ($filter->always_load) {
- $this->addFilter($filter, $config);
- } else {
- $conf = $config->get('URI.' . $name);
- if ($conf !== false && $conf !== null) {
- $this->addFilter($filter, $config);
- }
- }
- }
- unset($this->registeredFilters);
- }
-
- protected function setupMemberVariables($config)
- {
- $this->host = $config->get('URI.Host');
- $base_uri = $config->get('URI.Base');
- if (!is_null($base_uri)) {
- $parser = new HTMLPurifier_URIParser();
- $this->base = $parser->parse($base_uri);
- $this->defaultScheme = $this->base->scheme;
- if (is_null($this->host)) $this->host = $this->base->host;
- }
- if (is_null($this->defaultScheme)) $this->defaultScheme = $config->get('URI.DefaultScheme');
- }
-
- public function getDefaultScheme($config, $context)
- {
- return HTMLPurifier_URISchemeRegistry::instance()->getScheme($this->defaultScheme, $config, $context);
- }
-
- public function filter(&$uri, $config, $context)
- {
- foreach ($this->filters as $name => $f) {
- $result = $f->filter($uri, $config, $context);
- if (!$result) return false;
- }
- return true;
- }
-
- public function postFilter(&$uri, $config, $context)
- {
- foreach ($this->postFilters as $name => $f) {
- $result = $f->filter($uri, $config, $context);
- if (!$result) return false;
- }
- return true;
- }
-
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter.php
deleted file mode 100644
index 09724e9f4..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter.php
+++ /dev/null
@@ -1,74 +0,0 @@
-getDefinition('URI')->host;
- if ($our_host !== null) {
- $this->ourHostParts = array_reverse(explode('.', $our_host));
- }
- }
-
- /**
- * @param HTMLPurifier_URI $uri Reference
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return bool
- */
- public function filter(&$uri, $config, $context)
- {
- if (is_null($uri->host)) {
- return true;
- }
- if ($this->ourHostParts === false) {
- return false;
- }
- $host_parts = array_reverse(explode('.', $uri->host));
- foreach ($this->ourHostParts as $i => $x) {
- if (!isset($host_parts[$i])) {
- return false;
- }
- if ($host_parts[$i] != $this->ourHostParts[$i]) {
- return false;
- }
- }
- return true;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/DisableExternalResources.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/DisableExternalResources.php
deleted file mode 100644
index c6562169e..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/DisableExternalResources.php
+++ /dev/null
@@ -1,25 +0,0 @@
-get('EmbeddedURI', true)) {
- return true;
- }
- return parent::filter($uri, $config, $context);
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/DisableResources.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/DisableResources.php
deleted file mode 100644
index d5c412c44..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/DisableResources.php
+++ /dev/null
@@ -1,22 +0,0 @@
-get('EmbeddedURI', true);
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/HostBlacklist.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/HostBlacklist.php
deleted file mode 100644
index a6645c17e..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/HostBlacklist.php
+++ /dev/null
@@ -1,46 +0,0 @@
-blacklist = $config->get('URI.HostBlacklist');
- return true;
- }
-
- /**
- * @param HTMLPurifier_URI $uri
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return bool
- */
- public function filter(&$uri, $config, $context)
- {
- foreach ($this->blacklist as $blacklisted_host_fragment) {
- if (strpos($uri->host, $blacklisted_host_fragment) !== false) {
- return false;
- }
- }
- return true;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/MakeAbsolute.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/MakeAbsolute.php
deleted file mode 100644
index c507bbff8..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/MakeAbsolute.php
+++ /dev/null
@@ -1,158 +0,0 @@
-getDefinition('URI');
- $this->base = $def->base;
- if (is_null($this->base)) {
- trigger_error(
- 'URI.MakeAbsolute is being ignored due to lack of ' .
- 'value for URI.Base configuration',
- E_USER_WARNING
- );
- return false;
- }
- $this->base->fragment = null; // fragment is invalid for base URI
- $stack = explode('/', $this->base->path);
- array_pop($stack); // discard last segment
- $stack = $this->_collapseStack($stack); // do pre-parsing
- $this->basePathStack = $stack;
- return true;
- }
-
- /**
- * @param HTMLPurifier_URI $uri
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return bool
- */
- public function filter(&$uri, $config, $context)
- {
- if (is_null($this->base)) {
- return true;
- } // abort early
- if ($uri->path === '' && is_null($uri->scheme) &&
- is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment)) {
- // reference to current document
- $uri = clone $this->base;
- return true;
- }
- if (!is_null($uri->scheme)) {
- // absolute URI already: don't change
- if (!is_null($uri->host)) {
- return true;
- }
- $scheme_obj = $uri->getSchemeObj($config, $context);
- if (!$scheme_obj) {
- // scheme not recognized
- return false;
- }
- if (!$scheme_obj->hierarchical) {
- // non-hierarchal URI with explicit scheme, don't change
- return true;
- }
- // special case: had a scheme but always is hierarchical and had no authority
- }
- if (!is_null($uri->host)) {
- // network path, don't bother
- return true;
- }
- if ($uri->path === '') {
- $uri->path = $this->base->path;
- } elseif ($uri->path[0] !== '/') {
- // relative path, needs more complicated processing
- $stack = explode('/', $uri->path);
- $new_stack = array_merge($this->basePathStack, $stack);
- if ($new_stack[0] !== '' && !is_null($this->base->host)) {
- array_unshift($new_stack, '');
- }
- $new_stack = $this->_collapseStack($new_stack);
- $uri->path = implode('/', $new_stack);
- } else {
- // absolute path, but still we should collapse
- $uri->path = implode('/', $this->_collapseStack(explode('/', $uri->path)));
- }
- // re-combine
- $uri->scheme = $this->base->scheme;
- if (is_null($uri->userinfo)) {
- $uri->userinfo = $this->base->userinfo;
- }
- if (is_null($uri->host)) {
- $uri->host = $this->base->host;
- }
- if (is_null($uri->port)) {
- $uri->port = $this->base->port;
- }
- return true;
- }
-
- /**
- * Resolve dots and double-dots in a path stack
- * @param array $stack
- * @return array
- */
- private function _collapseStack($stack)
- {
- $result = array();
- $is_folder = false;
- for ($i = 0; isset($stack[$i]); $i++) {
- $is_folder = false;
- // absorb an internally duplicated slash
- if ($stack[$i] == '' && $i && isset($stack[$i + 1])) {
- continue;
- }
- if ($stack[$i] == '..') {
- if (!empty($result)) {
- $segment = array_pop($result);
- if ($segment === '' && empty($result)) {
- // error case: attempted to back out too far:
- // restore the leading slash
- $result[] = '';
- } elseif ($segment === '..') {
- $result[] = '..'; // cannot remove .. with ..
- }
- } else {
- // relative path, preserve the double-dots
- $result[] = '..';
- }
- $is_folder = true;
- continue;
- }
- if ($stack[$i] == '.') {
- // silently absorb
- $is_folder = true;
- continue;
- }
- $result[] = $stack[$i];
- }
- if ($is_folder) {
- $result[] = '';
- }
- return $result;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/Munge.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/Munge.php
deleted file mode 100644
index 6e03315a1..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/Munge.php
+++ /dev/null
@@ -1,115 +0,0 @@
-target = $config->get('URI.' . $this->name);
- $this->parser = new HTMLPurifier_URIParser();
- $this->doEmbed = $config->get('URI.MungeResources');
- $this->secretKey = $config->get('URI.MungeSecretKey');
- if ($this->secretKey && !function_exists('hash_hmac')) {
- throw new Exception("Cannot use %URI.MungeSecretKey without hash_hmac support.");
- }
- return true;
- }
-
- /**
- * @param HTMLPurifier_URI $uri
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return bool
- */
- public function filter(&$uri, $config, $context)
- {
- if ($context->get('EmbeddedURI', true) && !$this->doEmbed) {
- return true;
- }
-
- $scheme_obj = $uri->getSchemeObj($config, $context);
- if (!$scheme_obj) {
- return true;
- } // ignore unknown schemes, maybe another postfilter did it
- if (!$scheme_obj->browsable) {
- return true;
- } // ignore non-browseable schemes, since we can't munge those in a reasonable way
- if ($uri->isBenign($config, $context)) {
- return true;
- } // don't redirect if a benign URL
-
- $this->makeReplace($uri, $config, $context);
- $this->replace = array_map('rawurlencode', $this->replace);
-
- $new_uri = strtr($this->target, $this->replace);
- $new_uri = $this->parser->parse($new_uri);
- // don't redirect if the target host is the same as the
- // starting host
- if ($uri->host === $new_uri->host) {
- return true;
- }
- $uri = $new_uri; // overwrite
- return true;
- }
-
- /**
- * @param HTMLPurifier_URI $uri
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- */
- protected function makeReplace($uri, $config, $context)
- {
- $string = $uri->toString();
- // always available
- $this->replace['%s'] = $string;
- $this->replace['%r'] = $context->get('EmbeddedURI', true);
- $token = $context->get('CurrentToken', true);
- $this->replace['%n'] = $token ? $token->name : null;
- $this->replace['%m'] = $context->get('CurrentAttr', true);
- $this->replace['%p'] = $context->get('CurrentCSSProperty', true);
- // not always available
- if ($this->secretKey) {
- $this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey);
- }
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/SafeIframe.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/SafeIframe.php
deleted file mode 100644
index f609c47a3..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIFilter/SafeIframe.php
+++ /dev/null
@@ -1,68 +0,0 @@
-regexp = $config->get('URI.SafeIframeRegexp');
- return true;
- }
-
- /**
- * @param HTMLPurifier_URI $uri
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return bool
- */
- public function filter(&$uri, $config, $context)
- {
- // check if filter not applicable
- if (!$config->get('HTML.SafeIframe')) {
- return true;
- }
- // check if the filter should actually trigger
- if (!$context->get('EmbeddedURI', true)) {
- return true;
- }
- $token = $context->get('CurrentToken', true);
- if (!($token && $token->name == 'iframe')) {
- return true;
- }
- // check if we actually have some whitelists enabled
- if ($this->regexp === null) {
- return false;
- }
- // actually check the whitelists
- return preg_match($this->regexp, $uri->toString());
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIParser.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIParser.php
deleted file mode 100644
index 0e7381a07..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIParser.php
+++ /dev/null
@@ -1,71 +0,0 @@
-percentEncoder = new HTMLPurifier_PercentEncoder();
- }
-
- /**
- * Parses a URI.
- * @param $uri string URI to parse
- * @return HTMLPurifier_URI representation of URI. This representation has
- * not been validated yet and may not conform to RFC.
- */
- public function parse($uri)
- {
- $uri = $this->percentEncoder->normalize($uri);
-
- // Regexp is as per Appendix B.
- // Note that ["<>] are an addition to the RFC's recommended
- // characters, because they represent external delimeters.
- $r_URI = '!'.
- '(([a-zA-Z0-9\.\+\-]+):)?'. // 2. Scheme
- '(//([^/?#"<>]*))?'. // 4. Authority
- '([^?#"<>]*)'. // 5. Path
- '(\?([^#"<>]*))?'. // 7. Query
- '(#([^"<>]*))?'. // 8. Fragment
- '!';
-
- $matches = array();
- $result = preg_match($r_URI, $uri, $matches);
-
- if (!$result) return false; // *really* invalid URI
-
- // seperate out parts
- $scheme = !empty($matches[1]) ? $matches[2] : null;
- $authority = !empty($matches[3]) ? $matches[4] : null;
- $path = $matches[5]; // always present, can be empty
- $query = !empty($matches[6]) ? $matches[7] : null;
- $fragment = !empty($matches[8]) ? $matches[9] : null;
-
- // further parse authority
- if ($authority !== null) {
- $r_authority = "/^((.+?)@)?(\[[^\]]+\]|[^:]*)(:(\d*))?/";
- $matches = array();
- preg_match($r_authority, $authority, $matches);
- $userinfo = !empty($matches[1]) ? $matches[2] : null;
- $host = !empty($matches[3]) ? $matches[3] : '';
- $port = !empty($matches[4]) ? (int) $matches[5] : null;
- } else {
- $port = $host = $userinfo = null;
- }
-
- return new HTMLPurifier_URI(
- $scheme, $userinfo, $host, $port, $path, $query, $fragment);
- }
-
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme.php
deleted file mode 100644
index fe9e82cf2..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme.php
+++ /dev/null
@@ -1,102 +0,0 @@
-, resolves edge cases
- * with making relative URIs absolute
- * @type bool
- */
- public $hierarchical = false;
-
- /**
- * Whether or not the URI may omit a hostname when the scheme is
- * explicitly specified, ala file:///path/to/file. As of writing,
- * 'file' is the only scheme that browsers support his properly.
- * @type bool
- */
- public $may_omit_host = false;
-
- /**
- * Validates the components of a URI for a specific scheme.
- * @param HTMLPurifier_URI $uri Reference to a HTMLPurifier_URI object
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return bool success or failure
- */
- abstract public function doValidate(&$uri, $config, $context);
-
- /**
- * Public interface for validating components of a URI. Performs a
- * bunch of default actions. Don't overload this method.
- * @param HTMLPurifier_URI $uri Reference to a HTMLPurifier_URI object
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return bool success or failure
- */
- public function validate(&$uri, $config, $context)
- {
- if ($this->default_port == $uri->port) {
- $uri->port = null;
- }
- // kludge: browsers do funny things when the scheme but not the
- // authority is set
- if (!$this->may_omit_host &&
- // if the scheme is present, a missing host is always in error
- (!is_null($uri->scheme) && ($uri->host === '' || is_null($uri->host))) ||
- // if the scheme is not present, a *blank* host is in error,
- // since this translates into '///path' which most browsers
- // interpret as being 'http://path'.
- (is_null($uri->scheme) && $uri->host === '')
- ) {
- do {
- if (is_null($uri->scheme)) {
- if (substr($uri->path, 0, 2) != '//') {
- $uri->host = null;
- break;
- }
- // URI is '////path', so we cannot nullify the
- // host to preserve semantics. Try expanding the
- // hostname instead (fall through)
- }
- // first see if we can manually insert a hostname
- $host = $config->get('URI.Host');
- if (!is_null($host)) {
- $uri->host = $host;
- } else {
- // we can't do anything sensible, reject the URL.
- return false;
- }
- } while (false);
- }
- return $this->doValidate($uri, $config, $context);
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/data.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/data.php
deleted file mode 100644
index 6ebca4984..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/data.php
+++ /dev/null
@@ -1,127 +0,0 @@
- true,
- 'image/gif' => true,
- 'image/png' => true,
- );
- // this is actually irrelevant since we only write out the path
- // component
- /**
- * @type bool
- */
- public $may_omit_host = true;
-
- /**
- * @param HTMLPurifier_URI $uri
- * @param HTMLPurifier_Config $config
- * @param HTMLPurifier_Context $context
- * @return bool
- */
- public function doValidate(&$uri, $config, $context)
- {
- $result = explode(',', $uri->path, 2);
- $is_base64 = false;
- $charset = null;
- $content_type = null;
- if (count($result) == 2) {
- list($metadata, $data) = $result;
- // do some legwork on the metadata
- $metas = explode(';', $metadata);
- while (!empty($metas)) {
- $cur = array_shift($metas);
- if ($cur == 'base64') {
- $is_base64 = true;
- break;
- }
- if (substr($cur, 0, 8) == 'charset=') {
- // doesn't match if there are arbitrary spaces, but
- // whatever dude
- if ($charset !== null) {
- continue;
- } // garbage
- $charset = substr($cur, 8); // not used
- } else {
- if ($content_type !== null) {
- continue;
- } // garbage
- $content_type = $cur;
- }
- }
- } else {
- $data = $result[0];
- }
- if ($content_type !== null && empty($this->allowed_types[$content_type])) {
- return false;
- }
- if ($charset !== null) {
- // error; we don't allow plaintext stuff
- $charset = null;
- }
- $data = rawurldecode($data);
- if ($is_base64) {
- $raw_data = base64_decode($data);
- } else {
- $raw_data = $data;
- }
- // XXX probably want to refactor this into a general mechanism
- // for filtering arbitrary content types
- $file = tempnam("/tmp", "");
- file_put_contents($file, $raw_data);
- if (function_exists('exif_imagetype')) {
- $image_code = exif_imagetype($file);
- unlink($file);
- } elseif (function_exists('getimagesize')) {
- set_error_handler(array($this, 'muteErrorHandler'));
- $info = getimagesize($file);
- restore_error_handler();
- unlink($file);
- if ($info == false) {
- return false;
- }
- $image_code = $info[2];
- } else {
- trigger_error("could not find exif_imagetype or getimagesize functions", E_USER_ERROR);
- }
- $real_content_type = image_type_to_mime_type($image_code);
- if ($real_content_type != $content_type) {
- // we're nice guys; if the content type is something else we
- // support, change it over
- if (empty($this->allowed_types[$real_content_type])) {
- return false;
- }
- $content_type = $real_content_type;
- }
- // ok, it's kosher, rewrite what we need
- $uri->userinfo = null;
- $uri->host = null;
- $uri->port = null;
- $uri->fragment = null;
- $uri->query = null;
- $uri->path = "$content_type;base64," . base64_encode($raw_data);
- return true;
- }
-
- /**
- * @param int $errno
- * @param string $errstr
- */
- public function muteErrorHandler($errno, $errstr)
- {
- }
-}
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/file.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/file.php
deleted file mode 100644
index 215be4ba8..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/file.php
+++ /dev/null
@@ -1,44 +0,0 @@
-userinfo = null;
- // file:// makes no provisions for accessing the resource
- $uri->port = null;
- // While it seems to work on Firefox, the querystring has
- // no possible effect and is thus stripped.
- $uri->query = null;
- return true;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/ftp.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/ftp.php
deleted file mode 100644
index 1eb43ee5c..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/ftp.php
+++ /dev/null
@@ -1,58 +0,0 @@
-query = null;
-
- // typecode check
- $semicolon_pos = strrpos($uri->path, ';'); // reverse
- if ($semicolon_pos !== false) {
- $type = substr($uri->path, $semicolon_pos + 1); // no semicolon
- $uri->path = substr($uri->path, 0, $semicolon_pos);
- $type_ret = '';
- if (strpos($type, '=') !== false) {
- // figure out whether or not the declaration is correct
- list($key, $typecode) = explode('=', $type, 2);
- if ($key !== 'type') {
- // invalid key, tack it back on encoded
- $uri->path .= '%3B' . $type;
- } elseif ($typecode === 'a' || $typecode === 'i' || $typecode === 'd') {
- $type_ret = ";type=$typecode";
- }
- } else {
- $uri->path .= '%3B' . $type;
- }
- $uri->path = str_replace(';', '%3B', $uri->path);
- $uri->path .= $type_ret;
- }
- return true;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/http.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/http.php
deleted file mode 100644
index ce69ec438..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/http.php
+++ /dev/null
@@ -1,36 +0,0 @@
-userinfo = null;
- return true;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/https.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/https.php
deleted file mode 100644
index 0e96882db..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/https.php
+++ /dev/null
@@ -1,18 +0,0 @@
-userinfo = null;
- $uri->host = null;
- $uri->port = null;
- // we need to validate path against RFC 2368's addr-spec
- return true;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/news.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/news.php
deleted file mode 100644
index 7490927d6..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/news.php
+++ /dev/null
@@ -1,35 +0,0 @@
-userinfo = null;
- $uri->host = null;
- $uri->port = null;
- $uri->query = null;
- // typecode check needed on path
- return true;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/nntp.php b/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/nntp.php
deleted file mode 100644
index f211d715e..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URIScheme/nntp.php
+++ /dev/null
@@ -1,32 +0,0 @@
-userinfo = null;
- $uri->query = null;
- return true;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/URISchemeRegistry.php b/library/vendor/HTMLPurifier/HTMLPurifier/URISchemeRegistry.php
deleted file mode 100644
index 4ac8a0b76..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/URISchemeRegistry.php
+++ /dev/null
@@ -1,81 +0,0 @@
-get('URI.AllowedSchemes');
- if (!$config->get('URI.OverrideAllowedSchemes') &&
- !isset($allowed_schemes[$scheme])
- ) {
- return;
- }
-
- if (isset($this->schemes[$scheme])) {
- return $this->schemes[$scheme];
- }
- if (!isset($allowed_schemes[$scheme])) {
- return;
- }
-
- $class = 'HTMLPurifier_URIScheme_' . $scheme;
- if (!class_exists($class)) {
- return;
- }
- $this->schemes[$scheme] = new $class();
- return $this->schemes[$scheme];
- }
-
- /**
- * Registers a custom scheme to the cache, bypassing reflection.
- * @param string $scheme Scheme name
- * @param HTMLPurifier_URIScheme $scheme_obj
- */
- public function register($scheme, $scheme_obj)
- {
- $this->schemes[$scheme] = $scheme_obj;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/UnitConverter.php b/library/vendor/HTMLPurifier/HTMLPurifier/UnitConverter.php
deleted file mode 100644
index 166f3bf30..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/UnitConverter.php
+++ /dev/null
@@ -1,307 +0,0 @@
- array(
- 'px' => 3, // This is as per CSS 2.1 and Firefox. Your mileage may vary
- 'pt' => 4,
- 'pc' => 48,
- 'in' => 288,
- self::METRIC => array('pt', '0.352777778', 'mm'),
- ),
- self::METRIC => array(
- 'mm' => 1,
- 'cm' => 10,
- self::ENGLISH => array('mm', '2.83464567', 'pt'),
- ),
- );
-
- /**
- * Minimum bcmath precision for output.
- * @type int
- */
- protected $outputPrecision;
-
- /**
- * Bcmath precision for internal calculations.
- * @type int
- */
- protected $internalPrecision;
-
- /**
- * Whether or not BCMath is available.
- * @type bool
- */
- private $bcmath;
-
- public function __construct($output_precision = 4, $internal_precision = 10, $force_no_bcmath = false)
- {
- $this->outputPrecision = $output_precision;
- $this->internalPrecision = $internal_precision;
- $this->bcmath = !$force_no_bcmath && function_exists('bcmul');
- }
-
- /**
- * Converts a length object of one unit into another unit.
- * @param HTMLPurifier_Length $length
- * Instance of HTMLPurifier_Length to convert. You must validate()
- * it before passing it here!
- * @param string $to_unit
- * Unit to convert to.
- * @return HTMLPurifier_Length|bool
- * @note
- * About precision: This conversion function pays very special
- * attention to the incoming precision of values and attempts
- * to maintain a number of significant figure. Results are
- * fairly accurate up to nine digits. Some caveats:
- * - If a number is zero-padded as a result of this significant
- * figure tracking, the zeroes will be eliminated.
- * - If a number contains less than four sigfigs ($outputPrecision)
- * and this causes some decimals to be excluded, those
- * decimals will be added on.
- */
- public function convert($length, $to_unit)
- {
- if (!$length->isValid()) {
- return false;
- }
-
- $n = $length->getN();
- $unit = $length->getUnit();
-
- if ($n === '0' || $unit === false) {
- return new HTMLPurifier_Length('0', false);
- }
-
- $state = $dest_state = false;
- foreach (self::$units as $k => $x) {
- if (isset($x[$unit])) {
- $state = $k;
- }
- if (isset($x[$to_unit])) {
- $dest_state = $k;
- }
- }
- if (!$state || !$dest_state) {
- return false;
- }
-
- // Some calculations about the initial precision of the number;
- // this will be useful when we need to do final rounding.
- $sigfigs = $this->getSigFigs($n);
- if ($sigfigs < $this->outputPrecision) {
- $sigfigs = $this->outputPrecision;
- }
-
- // BCMath's internal precision deals only with decimals. Use
- // our default if the initial number has no decimals, or increase
- // it by how ever many decimals, thus, the number of guard digits
- // will always be greater than or equal to internalPrecision.
- $log = (int)floor(log(abs($n), 10));
- $cp = ($log < 0) ? $this->internalPrecision - $log : $this->internalPrecision; // internal precision
-
- for ($i = 0; $i < 2; $i++) {
-
- // Determine what unit IN THIS SYSTEM we need to convert to
- if ($dest_state === $state) {
- // Simple conversion
- $dest_unit = $to_unit;
- } else {
- // Convert to the smallest unit, pending a system shift
- $dest_unit = self::$units[$state][$dest_state][0];
- }
-
- // Do the conversion if necessary
- if ($dest_unit !== $unit) {
- $factor = $this->div(self::$units[$state][$unit], self::$units[$state][$dest_unit], $cp);
- $n = $this->mul($n, $factor, $cp);
- $unit = $dest_unit;
- }
-
- // Output was zero, so bail out early. Shouldn't ever happen.
- if ($n === '') {
- $n = '0';
- $unit = $to_unit;
- break;
- }
-
- // It was a simple conversion, so bail out
- if ($dest_state === $state) {
- break;
- }
-
- if ($i !== 0) {
- // Conversion failed! Apparently, the system we forwarded
- // to didn't have this unit. This should never happen!
- return false;
- }
-
- // Pre-condition: $i == 0
-
- // Perform conversion to next system of units
- $n = $this->mul($n, self::$units[$state][$dest_state][1], $cp);
- $unit = self::$units[$state][$dest_state][2];
- $state = $dest_state;
-
- // One more loop around to convert the unit in the new system.
-
- }
-
- // Post-condition: $unit == $to_unit
- if ($unit !== $to_unit) {
- return false;
- }
-
- // Useful for debugging:
- //echo "
n";
- //echo "$n\nsigfigs = $sigfigs\nnew_log = $new_log\nlog = $log\nrp = $rp\n
\n";
-
- $n = $this->round($n, $sigfigs);
- if (strpos($n, '.') !== false) {
- $n = rtrim($n, '0');
- }
- $n = rtrim($n, '.');
-
- return new HTMLPurifier_Length($n, $unit);
- }
-
- /**
- * Returns the number of significant figures in a string number.
- * @param string $n Decimal number
- * @return int number of sigfigs
- */
- public function getSigFigs($n)
- {
- $n = ltrim($n, '0+-');
- $dp = strpos($n, '.'); // decimal position
- if ($dp === false) {
- $sigfigs = strlen(rtrim($n, '0'));
- } else {
- $sigfigs = strlen(ltrim($n, '0.')); // eliminate extra decimal character
- if ($dp !== 0) {
- $sigfigs--;
- }
- }
- return $sigfigs;
- }
-
- /**
- * Adds two numbers, using arbitrary precision when available.
- * @param string $s1
- * @param string $s2
- * @param int $scale
- * @return string
- */
- private function add($s1, $s2, $scale)
- {
- if ($this->bcmath) {
- return bcadd($s1, $s2, $scale);
- } else {
- return $this->scale((float)$s1 + (float)$s2, $scale);
- }
- }
-
- /**
- * Multiples two numbers, using arbitrary precision when available.
- * @param string $s1
- * @param string $s2
- * @param int $scale
- * @return string
- */
- private function mul($s1, $s2, $scale)
- {
- if ($this->bcmath) {
- return bcmul($s1, $s2, $scale);
- } else {
- return $this->scale((float)$s1 * (float)$s2, $scale);
- }
- }
-
- /**
- * Divides two numbers, using arbitrary precision when available.
- * @param string $s1
- * @param string $s2
- * @param int $scale
- * @return string
- */
- private function div($s1, $s2, $scale)
- {
- if ($this->bcmath) {
- return bcdiv($s1, $s2, $scale);
- } else {
- return $this->scale((float)$s1 / (float)$s2, $scale);
- }
- }
-
- /**
- * Rounds a number according to the number of sigfigs it should have,
- * using arbitrary precision when available.
- * @param float $n
- * @param int $sigfigs
- * @return string
- */
- private function round($n, $sigfigs)
- {
- $new_log = (int)floor(log(abs($n), 10)); // Number of digits left of decimal - 1
- $rp = $sigfigs - $new_log - 1; // Number of decimal places needed
- $neg = $n < 0 ? '-' : ''; // Negative sign
- if ($this->bcmath) {
- if ($rp >= 0) {
- $n = bcadd($n, $neg . '0.' . str_repeat('0', $rp) . '5', $rp + 1);
- $n = bcdiv($n, '1', $rp);
- } else {
- // This algorithm partially depends on the standardized
- // form of numbers that comes out of bcmath.
- $n = bcadd($n, $neg . '5' . str_repeat('0', $new_log - $sigfigs), 0);
- $n = substr($n, 0, $sigfigs + strlen($neg)) . str_repeat('0', $new_log - $sigfigs + 1);
- }
- return $n;
- } else {
- return $this->scale(round($n, $sigfigs - $new_log - 1), $rp + 1);
- }
- }
-
- /**
- * Scales a float to $scale digits right of decimal point, like BCMath.
- * @param float $r
- * @param int $scale
- * @return string
- */
- private function scale($r, $scale)
- {
- if ($scale < 0) {
- // The f sprintf type doesn't support negative numbers, so we
- // need to cludge things manually. First get the string.
- $r = sprintf('%.0f', (float)$r);
- // Due to floating point precision loss, $r will more than likely
- // look something like 4652999999999.9234. We grab one more digit
- // than we need to precise from $r and then use that to round
- // appropriately.
- $precise = (string)round(substr($r, 0, strlen($r) + $scale), -1);
- // Now we return it, truncating the zero that was rounded off.
- return substr($precise, 0, -1) . str_repeat('0', -$scale + 1);
- }
- return sprintf('%.' . $scale . 'f', (float)$r);
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/VarParser.php b/library/vendor/HTMLPurifier/HTMLPurifier/VarParser.php
deleted file mode 100644
index 50cba6910..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/VarParser.php
+++ /dev/null
@@ -1,198 +0,0 @@
- self::STRING,
- 'istring' => self::ISTRING,
- 'text' => self::TEXT,
- 'itext' => self::ITEXT,
- 'int' => self::INT,
- 'float' => self::FLOAT,
- 'bool' => self::BOOL,
- 'lookup' => self::LOOKUP,
- 'list' => self::ALIST,
- 'hash' => self::HASH,
- 'mixed' => self::MIXED
- );
-
- /**
- * Lookup table of types that are string, and can have aliases or
- * allowed value lists.
- */
- public static $stringTypes = array(
- self::STRING => true,
- self::ISTRING => true,
- self::TEXT => true,
- self::ITEXT => true,
- );
-
- /**
- * Validate a variable according to type.
- * It may return NULL as a valid type if $allow_null is true.
- *
- * @param mixed $var Variable to validate
- * @param int $type Type of variable, see HTMLPurifier_VarParser->types
- * @param bool $allow_null Whether or not to permit null as a value
- * @return string Validated and type-coerced variable
- * @throws HTMLPurifier_VarParserException
- */
- final public function parse($var, $type, $allow_null = false)
- {
- if (is_string($type)) {
- if (!isset(HTMLPurifier_VarParser::$types[$type])) {
- throw new HTMLPurifier_VarParserException("Invalid type '$type'");
- } else {
- $type = HTMLPurifier_VarParser::$types[$type];
- }
- }
- $var = $this->parseImplementation($var, $type, $allow_null);
- if ($allow_null && $var === null) {
- return null;
- }
- // These are basic checks, to make sure nothing horribly wrong
- // happened in our implementations.
- switch ($type) {
- case (self::STRING):
- case (self::ISTRING):
- case (self::TEXT):
- case (self::ITEXT):
- if (!is_string($var)) {
- break;
- }
- if ($type == self::ISTRING || $type == self::ITEXT) {
- $var = strtolower($var);
- }
- return $var;
- case (self::INT):
- if (!is_int($var)) {
- break;
- }
- return $var;
- case (self::FLOAT):
- if (!is_float($var)) {
- break;
- }
- return $var;
- case (self::BOOL):
- if (!is_bool($var)) {
- break;
- }
- return $var;
- case (self::LOOKUP):
- case (self::ALIST):
- case (self::HASH):
- if (!is_array($var)) {
- break;
- }
- if ($type === self::LOOKUP) {
- foreach ($var as $k) {
- if ($k !== true) {
- $this->error('Lookup table contains value other than true');
- }
- }
- } elseif ($type === self::ALIST) {
- $keys = array_keys($var);
- if (array_keys($keys) !== $keys) {
- $this->error('Indices for list are not uniform');
- }
- }
- return $var;
- case (self::MIXED):
- return $var;
- default:
- $this->errorInconsistent(get_class($this), $type);
- }
- $this->errorGeneric($var, $type);
- }
-
- /**
- * Actually implements the parsing. Base implementation does not
- * do anything to $var. Subclasses should overload this!
- * @param mixed $var
- * @param int $type
- * @param bool $allow_null
- * @return string
- */
- protected function parseImplementation($var, $type, $allow_null)
- {
- return $var;
- }
-
- /**
- * Throws an exception.
- * @throws HTMLPurifier_VarParserException
- */
- protected function error($msg)
- {
- throw new HTMLPurifier_VarParserException($msg);
- }
-
- /**
- * Throws an inconsistency exception.
- * @note This should not ever be called. It would be called if we
- * extend the allowed values of HTMLPurifier_VarParser without
- * updating subclasses.
- * @param string $class
- * @param int $type
- * @throws HTMLPurifier_Exception
- */
- protected function errorInconsistent($class, $type)
- {
- throw new HTMLPurifier_Exception(
- "Inconsistency in $class: " . HTMLPurifier_VarParser::getTypeName($type) .
- " not implemented"
- );
- }
-
- /**
- * Generic error for if a type didn't work.
- * @param mixed $var
- * @param int $type
- */
- protected function errorGeneric($var, $type)
- {
- $vtype = gettype($var);
- $this->error("Expected type " . HTMLPurifier_VarParser::getTypeName($type) . ", got $vtype");
- }
-
- /**
- * @param int $type
- * @return string
- */
- public static function getTypeName($type)
- {
- static $lookup;
- if (!$lookup) {
- // Lazy load the alternative lookup table
- $lookup = array_flip(HTMLPurifier_VarParser::$types);
- }
- if (!isset($lookup[$type])) {
- return 'unknown';
- }
- return $lookup[$type];
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/VarParser/Flexible.php b/library/vendor/HTMLPurifier/HTMLPurifier/VarParser/Flexible.php
deleted file mode 100644
index b15016c5b..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/VarParser/Flexible.php
+++ /dev/null
@@ -1,130 +0,0 @@
- $j) {
- $var[$i] = trim($j);
- }
- if ($type === self::HASH) {
- // key:value,key2:value2
- $nvar = array();
- foreach ($var as $keypair) {
- $c = explode(':', $keypair, 2);
- if (!isset($c[1])) {
- continue;
- }
- $nvar[trim($c[0])] = trim($c[1]);
- }
- $var = $nvar;
- }
- }
- if (!is_array($var)) {
- break;
- }
- $keys = array_keys($var);
- if ($keys === array_keys($keys)) {
- if ($type == self::ALIST) {
- return $var;
- } elseif ($type == self::LOOKUP) {
- $new = array();
- foreach ($var as $key) {
- $new[$key] = true;
- }
- return $new;
- } else {
- break;
- }
- }
- if ($type === self::ALIST) {
- trigger_error("Array list did not have consecutive integer indexes", E_USER_WARNING);
- return array_values($var);
- }
- if ($type === self::LOOKUP) {
- foreach ($var as $key => $value) {
- if ($value !== true) {
- trigger_error(
- "Lookup array has non-true value at key '$key'; " .
- "maybe your input array was not indexed numerically",
- E_USER_WARNING
- );
- }
- $var[$key] = true;
- }
- }
- return $var;
- default:
- $this->errorInconsistent(__CLASS__, $type);
- }
- $this->errorGeneric($var, $type);
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/VarParser/Native.php b/library/vendor/HTMLPurifier/HTMLPurifier/VarParser/Native.php
deleted file mode 100644
index f11c318ef..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/VarParser/Native.php
+++ /dev/null
@@ -1,38 +0,0 @@
-evalExpression($var);
- }
-
- /**
- * @param string $expr
- * @return mixed
- * @throws HTMLPurifier_VarParserException
- */
- protected function evalExpression($expr)
- {
- $var = null;
- $result = eval("\$var = $expr;");
- if ($result === false) {
- throw new HTMLPurifier_VarParserException("Fatal error in evaluated code");
- }
- return $var;
- }
-}
-
-// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLPurifier/VarParserException.php b/library/vendor/HTMLPurifier/HTMLPurifier/VarParserException.php
deleted file mode 100644
index 5df341495..000000000
--- a/library/vendor/HTMLPurifier/HTMLPurifier/VarParserException.php
+++ /dev/null
@@ -1,11 +0,0 @@
-front = $front;
- $this->back = $back;
- }
-
- /**
- * Creates a zipper from an array, with a hole in the
- * 0-index position.
- * @param Array to zipper-ify.
- * @return Tuple of zipper and element of first position.
- */
- static public function fromArray($array) {
- $z = new self(array(), array_reverse($array));
- $t = $z->delete(); // delete the "dummy hole"
- return array($z, $t);
- }
-
- /**
- * Convert zipper back into a normal array, optionally filling in
- * the hole with a value. (Usually you should supply a $t, unless you
- * are at the end of the array.)
- */
- public function toArray($t = NULL) {
- $a = $this->front;
- if ($t !== NULL) $a[] = $t;
- for ($i = count($this->back)-1; $i >= 0; $i--) {
- $a[] = $this->back[$i];
- }
- return $a;
- }
-
- /**
- * Move hole to the next element.
- * @param $t Element to fill hole with
- * @return Original contents of new hole.
- */
- public function next($t) {
- if ($t !== NULL) array_push($this->front, $t);
- return empty($this->back) ? NULL : array_pop($this->back);
- }
-
- /**
- * Iterated hole advancement.
- * @param $t Element to fill hole with
- * @param $i How many forward to advance hole
- * @return Original contents of new hole, i away
- */
- public function advance($t, $n) {
- for ($i = 0; $i < $n; $i++) {
- $t = $this->next($t);
- }
- return $t;
- }
-
- /**
- * Move hole to the previous element
- * @param $t Element to fill hole with
- * @return Original contents of new hole.
- */
- public function prev($t) {
- if ($t !== NULL) array_push($this->back, $t);
- return empty($this->front) ? NULL : array_pop($this->front);
- }
-
- /**
- * Delete contents of current hole, shifting hole to
- * next element.
- * @return Original contents of new hole.
- */
- public function delete() {
- return empty($this->back) ? NULL : array_pop($this->back);
- }
-
- /**
- * Returns true if we are at the end of the list.
- * @return bool
- */
- public function done() {
- return empty($this->back);
- }
-
- /**
- * Insert element before hole.
- * @param Element to insert
- */
- public function insertBefore($t) {
- if ($t !== NULL) array_push($this->front, $t);
- }
-
- /**
- * Insert element after hole.
- * @param Element to insert
- */
- public function insertAfter($t) {
- if ($t !== NULL) array_push($this->back, $t);
- }
-
- /**
- * Splice in multiple elements at hole. Functional specification
- * in terms of array_splice:
- *
- * $arr1 = $arr;
- * $old1 = array_splice($arr1, $i, $delete, $replacement);
- *
- * list($z, $t) = HTMLPurifier_Zipper::fromArray($arr);
- * $t = $z->advance($t, $i);
- * list($old2, $t) = $z->splice($t, $delete, $replacement);
- * $arr2 = $z->toArray($t);
- *
- * assert($old1 === $old2);
- * assert($arr1 === $arr2);
- *
- * NB: the absolute index location after this operation is
- * *unchanged!*
- *
- * @param Current contents of hole.
- */
- public function splice($t, $delete, $replacement) {
- // delete
- $old = array();
- $r = $t;
- for ($i = $delete; $i > 0; $i--) {
- $old[] = $r;
- $r = $this->delete();
- }
- // insert
- for ($i = count($replacement)-1; $i >= 0; $i--) {
- $this->insertAfter($r);
- $r = $replacement[$i];
- }
- return array($old, $r);
- }
-}
diff --git a/library/vendor/HTMLPurifier/SOURCE b/library/vendor/HTMLPurifier/SOURCE
index 1d8335915..44e19b159 100644
--- a/library/vendor/HTMLPurifier/SOURCE
+++ b/library/vendor/HTMLPurifier/SOURCE
@@ -1,5 +1,7 @@
curl https://codeload.github.com/ezyang/htmlpurifier/tar.gz/v4.7.0 -o htmlpurifier-4.7.0.tar.gz
tar xzf htmlpurifier-4.7.0.tar.gz --strip-components 1 htmlpurifier-4.7.0/LICENSE
-tar xzf htmlpurifier-4.7.0.tar.gz --strip-components 2 htmlpurifier-4.7.0/library/*.php
+tar xzf htmlpurifier-4.7.0.tar.gz --strip-components 1 htmlpurifier-4.7.0/VERSION
+tar xzf htmlpurifier-4.7.0.tar.gz -C ../ --strip-components 2 htmlpurifier-4.7.0/library/HTMLPurifier.php
+tar xzf htmlpurifier-4.7.0.tar.gz -C ../ --strip-components 2 htmlpurifier-4.7.0/library/HTMLPurifier.autoload.php
tar xzf htmlpurifier-4.7.0.tar.gz --strip-components 3 htmlpurifier-4.7.0/library/HTMLPurifier/*
rm htmlpurifier-4.7.0.tar.gz
diff --git a/library/vendor/HTMLPurifier/VERSION b/library/vendor/HTMLPurifier/VERSION
new file mode 100644
index 000000000..1163055e2
--- /dev/null
+++ b/library/vendor/HTMLPurifier/VERSION
@@ -0,0 +1 @@
+4.7.0
\ No newline at end of file