X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/mediawiki.git/blobdiff_plain/19e297c21b10b1b8a3acad5e73fc71dcb35db44a..6932310fd58ebef145fa01eb76edf7150284d8ea:/vendor/wikimedia/remex-html/RemexHtml/TreeBuilder/CachingStack.php diff --git a/vendor/wikimedia/remex-html/RemexHtml/TreeBuilder/CachingStack.php b/vendor/wikimedia/remex-html/RemexHtml/TreeBuilder/CachingStack.php new file mode 100644 index 00000000..74112e16 --- /dev/null +++ b/vendor/wikimedia/remex-html/RemexHtml/TreeBuilder/CachingStack.php @@ -0,0 +1,420 @@ + true, + 'mo' => true, + 'mn' => true, + 'ms' => true, + 'mtext' => true, + 'annotation-xml' => true + ]; + + private static $svgBreakers = [ + 'foreignObject' => true, + 'desc' => true, + 'title' => true + ]; + + /** + * If you compile every predicate of the form "an X element in Y scope" in + * the HTML 5 spec, you discover that every element name X corresponds to + * at most one such scope Y. This is useful because it means when we see + * a new element, we need to add it to at most one scope cache. + * + * This is a list of such statements in the spec, and the scope they relate + * to. All formatting elements are included as SCOPE_DEFAULT since the AAA + * involves pulling an item out of the AFE list and checking if it is in + * scope. + */ + static private $predicateMap = [ + 'a' => self::SCOPE_DEFAULT, + 'address' => self::SCOPE_DEFAULT, + 'applet' => self::SCOPE_DEFAULT, + 'article' => self::SCOPE_DEFAULT, + 'aside' => self::SCOPE_DEFAULT, + 'b' => self::SCOPE_DEFAULT, + 'big' => self::SCOPE_DEFAULT, + 'blockquote' => self::SCOPE_DEFAULT, + 'body' => self::SCOPE_DEFAULT, + 'button' => self::SCOPE_DEFAULT, + 'caption' => self::SCOPE_TABLE, + 'center' => self::SCOPE_DEFAULT, + 'code' => self::SCOPE_DEFAULT, + 'dd' => self::SCOPE_DEFAULT, + 'details' => self::SCOPE_DEFAULT, + 'dialog' => self::SCOPE_DEFAULT, + 'dir' => self::SCOPE_DEFAULT, + 'div' => self::SCOPE_DEFAULT, + 'dl' => self::SCOPE_DEFAULT, + 'dt' => self::SCOPE_DEFAULT, + 'em' => self::SCOPE_DEFAULT, + 'fieldset' => self::SCOPE_DEFAULT, + 'figcaption' => self::SCOPE_DEFAULT, + 'figure' => self::SCOPE_DEFAULT, + 'font' => self::SCOPE_DEFAULT, + 'footer' => self::SCOPE_DEFAULT, + 'form' => self::SCOPE_DEFAULT, + 'h1' => self::SCOPE_DEFAULT, + 'h2' => self::SCOPE_DEFAULT, + 'h3' => self::SCOPE_DEFAULT, + 'h4' => self::SCOPE_DEFAULT, + 'h5' => self::SCOPE_DEFAULT, + 'h6' => self::SCOPE_DEFAULT, + 'header' => self::SCOPE_DEFAULT, + 'hgroup' => self::SCOPE_DEFAULT, + 'i' => self::SCOPE_DEFAULT, + 'li' => self::SCOPE_LIST, + 'listing' => self::SCOPE_DEFAULT, + 'main' => self::SCOPE_DEFAULT, + 'marquee' => self::SCOPE_DEFAULT, + 'menu' => self::SCOPE_DEFAULT, + 'nav' => self::SCOPE_DEFAULT, + 'nobr' => self::SCOPE_DEFAULT, + 'object' => self::SCOPE_DEFAULT, + 'ol' => self::SCOPE_DEFAULT, + 'p' => self::SCOPE_BUTTON, + 'pre' => self::SCOPE_DEFAULT, + 'ruby' => self::SCOPE_DEFAULT, + 's' => self::SCOPE_DEFAULT, + 'section' => self::SCOPE_DEFAULT, + 'select' => self::SCOPE_SELECT, + 'small' => self::SCOPE_DEFAULT, + 'strike' => self::SCOPE_DEFAULT, + 'strong' => self::SCOPE_DEFAULT, + 'summary' => self::SCOPE_DEFAULT, + 'table' => self::SCOPE_TABLE, + 'tbody' => self::SCOPE_TABLE, + 'td' => self::SCOPE_TABLE, + 'tfoot' => self::SCOPE_TABLE, + 'th' => self::SCOPE_TABLE, + 'thead' => self::SCOPE_TABLE, + 'tr' => self::SCOPE_TABLE, + 'tt' => self::SCOPE_DEFAULT, + 'u' => self::SCOPE_DEFAULT, + 'ul' => self::SCOPE_DEFAULT, + ]; + + /** + * The stack of open elements + */ + private $elements = []; + + /** + * A cache of the elements which are currently in a given scope. + * The first key is the scope ID, the second key is the element name, and the + * value is the first Element in a singly-linked list of Element objects, + * linked by $element->nextScope. + * + * @todo Benchmark time and memory compared to an array stack instead of an + * SLL. The SLL here is maybe not quite so well justified as some other + * SLLs in RemexHtml. + * + * @var Element[int][string] + */ + private $scopes = [ + self::SCOPE_DEFAULT => [], + self::SCOPE_LIST => [], + self::SCOPE_BUTTON => [], + self::SCOPE_TABLE => [], + self::SCOPE_SELECT => [] + ]; + + /** + * This is the part of the scope cache which stores scope lists for objects + * which are not currently in scope. The first key is the scope ID, the + * second key is the stack index, the third key is the element name. + * + * @var Element[int][int][string] + */ + private $scopeStacks = [ + self::SCOPE_DEFAULT => [], + self::SCOPE_LIST => [], + self::SCOPE_BUTTON => [], + self::SCOPE_TABLE => [], + self::SCOPE_SELECT => [] + ]; + + /** + * The number of