Added template insertion mode stack

This commit is contained in:
Dustin Wilson 2018-08-22 17:01:55 -05:00
parent c414f3dbfa
commit ed3cf3add1
4 changed files with 20 additions and 7 deletions

View file

@ -9,7 +9,8 @@ class DOM {
// Instance used to pass around the implementation and the document. PHP's DOM
// cannot append a DOCTYPE to a DOMDocument, so the document must be created
// when the DOCTYPE is. This creates a problem where the Parser sometimes needs
// an implementation before the TreeBuilder is initiated.
// an implementation before the TreeBuilder is initiated. This instance is used
// to work around that problem.
public function __construct($document = null) {
if (is_null($document)) {
$this->implementation = new \DOMImplementation();

View file

@ -24,6 +24,8 @@ class Parser {
protected $parseError;
// The stack of open elements, uses Stack
protected $stack;
// Used to store the template insertion modes
protected $templateInsertionModes;
// Instance of the Tokenizer class used for creating tokens
protected $tokenizer;
// Instance of the TreeBuilder class used for building the document
@ -78,10 +80,14 @@ class Parser {
// Initialize the stack of open elements.
static::$instance->stack = new OpenElementsStack(static::$instance->fragmentCase, static::$instance->fragmentContext);
// Initialize the template insertion modes stack if necessary.
if (is_null(static::$instance->templateInsertionModes)) {
static::$instance->templateInsertionModes = new Stack();
}
// Initialize the tokenizer.
static::$instance->tokenizer = new Tokenizer(static::$instance->data, static::$instance->stack);
// Initialize the tree builder.
static::$instance->treeBuilder = new TreeBuilder(static::$instance->DOM, static::$instance->formElement, static::$instance->fragmentCase, static::$instance->fragmentContext, static::$instance->stack, static::$instance->tokenizer);
static::$instance->treeBuilder = new TreeBuilder(static::$instance->DOM, static::$instance->formElement, static::$instance->fragmentCase, static::$instance->fragmentContext, static::$instance->stack, static::$instance->templateInsertionModes, static::$instance->tokenizer);
// Initialize the parse error handler.
static::$instance->parseError = new ParseError(static::$instance->data);
@ -151,7 +157,10 @@ class Parser {
# If the context element is a template element, push "in template" onto the
# stack of template insertion modes so that it is the new current template
# insertion mode.
// DEVIATION: No scripting.
if ($context instanceof \DOMelement && $context->nodeName === 'template') {
static::$templateInsertionModes = new Stack();
static::$templateInsertionModes[] = TreeBuilder::IN_TEMPLATE_MODE;
}
# Reset the parser's insertion mode appropriately.
// DEVIATION: The insertion mode will be always 'in body', not 'before head' if

View file

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace dW\HTML5;
abstract class Stack implements \ArrayAccess {
class Stack implements \ArrayAccess {
protected $_storage = [];
protected $fragmentCase;
protected $fragmentContext;

View file

@ -36,6 +36,8 @@ class TreeBuilder {
protected $tokenizer;
// Used to check if the document is in quirks mode
protected $quirksMode;
// Used to store the template insertion modes
protected $templateInsertionModes;
// Instance used with the static token insertion methods.
@ -73,7 +75,7 @@ class TreeBuilder {
const QUIRKS_MODE_LIMITED = 2;
public function __construct(DOM $dom, $formElement, bool $fragmentCase = false, $fragmentContext = null, OpenElementsStack $stack, Tokenizer $tokenizer) {
public function __construct(DOM $dom, $formElement, bool $fragmentCase = false, $fragmentContext = null, OpenElementsStack $stack, Stack $templateInsertionModes, Tokenizer $tokenizer) {
// If the form element isn't an instance of DOMElement that has a node name of
// "form" or null then there's a problem.
if (!is_null($formElement) && !($formElement instanceof DOMElement && $formElement->nodeName === 'form')) {
@ -94,6 +96,7 @@ class TreeBuilder {
$this->fragmentCase = $fragmentCase;
$this->fragmentContext = $fragmentContext;
$this->stack = $stack;
$this->templateInsertionModes = $templateInsertionModes;
$this->tokenizer = $tokenizer;
// Initialize the list of active formatting elements.
@ -641,7 +644,7 @@ class TreeBuilder {
$this->insertionMode = self::IN_TEMPLATE_MODE;
# Push "in template" onto the stack of template insertion modes so that it is
# the new current template insertion mode.
// DEVIATION: No scripting.
$this->templateInsertionModes = self::IN_TEMPLATE_MODE;
}
# A start tag whose tag name is "head"
elseif ($token->name === 'head') {
@ -710,7 +713,7 @@ class TreeBuilder {
$this->activeFormattingElementsList->clearToTheLastMarker();
# 5. Pop the current template insertion mode off the stack of template insertion modes.
// DEVIATION: No scripting.
$this->templateInsertionModes->pop();
# 6. Reset the insertion mode appropriately.
$this->resetInsertionMode();