Browse Source

Implement a in body

Adoption agency will be handled later
split-manual
J. King 3 years ago
parent
commit
baaa00e544
  1. 34
      lib/ActiveFormattingElementsList.php
  2. 9
      lib/OpenElementsStack.php
  3. 2
      lib/ParseError.php
  4. 25
      lib/TreeBuilder.php

34
lib/ActiveFormattingElementsList.php

@ -37,7 +37,7 @@ class ActiveFormattingElementsList extends Stack {
), new \Exception("Active formatting element value is invalid"));
if ($value instanceof ActiveFormattingElementsMarker) {
$this->_storage[$offset] = $value;
} elseif (($offset ?? $count) === $count) {
} elseif ($count && ($offset ?? $count) === $count) {
# When the steps below require the UA to push onto the list of active formatting
# elements an element element, the UA must perform the following steps:
// First find the position of the last marker, if any
@ -60,12 +60,12 @@ class ActiveFormattingElementsList extends Stack {
// Stop once there are three matches or the marker is reached
} while ($matches < 3 && (--$pos) > $lastMarker);
if ($matches === 3) {
array_splice($this->_storage, $pos, 1, []);
$this->offsetUnset($pos);
}
# Add element to the list of active formatting elements.
$this->_storage[] = $value;
} else {
$this->_storage[$offset] = $value;
$this->_storage[$offset ?? $count] = $value;
}
}
@ -178,6 +178,34 @@ class ActiveFormattingElementsList extends Stack {
}
}
}
public function findSame(Element $target): int {
foreach ($this as $k => $entry) {
if ($entry instanceof Element && $entry['element']->isSameNode($target)) {
return $k;
}
}
return -1;
}
public function findToMarker(string ...$name): int {
foreach ($this as $k => $entry) {
if ($entry instanceof ActiveFormattingElementsMarker) {
return -1;
}
if (in_array($entry['element']->nodeName, $name)) {
return $k;
}
}
return -1;
}
public function removeSame(Element $target): void {
$pos = $this->findSame($target);
if ($pos > -1) {
unset($this[$pos]);
}
}
}
class ActiveFormattingElementsMarker {}

9
lib/OpenElementsStack.php

@ -126,7 +126,7 @@ class OpenElementsStack extends Stack {
return -1;
}
public function findSame(\DOMElement $target): int {
public function findSame(Element $target): int {
foreach ($this as $k => $node) {
if ($node->isSameNode($target)) {
return $k;
@ -135,6 +135,13 @@ class OpenElementsStack extends Stack {
return -1;
}
public function removeSame(Element $target): void {
$pos = $this->findSame($target);
if ($pos > -1) {
unset($this[$pos]);
}
}
public function generateImpliedEndTags(string ...$exclude): void {
# When the steps below require the UA to generate implied end tags,
# then, while the current node is {elided list of element names},

2
lib/ParseError.php

@ -65,6 +65,7 @@ class ParseError {
const UNEXPECTED_START_TAG = 206;
const UNEXPECTED_END_TAG = 207; // html5lib also uses 'adoption-agency-1.2' and 'adoption-agency-1.3' for this
const NON_VOID_HTML_ELEMENT_START_TAG_WITH_TRAILING_SOLIDUS = 208;
const UNEXPECTED_START_TAG_IMPLIES_END_TAG = 209;
const MESSAGES = [
self::EXPECTED_DOCTYPE_BUT_GOT_START_TAG => 'Expected DOCTYPE but got start tag',
@ -75,6 +76,7 @@ class ParseError {
self::UNEXPECTED_START_TAG => 'Unexpected start tag',
self::UNEXPECTED_END_TAG => 'Unexpected end tag',
self::NON_VOID_HTML_ELEMENT_START_TAG_WITH_TRAILING_SOLIDUS => 'Trailing solidus in non-void HTML element start tag',
self::UNEXPECTED_START_TAG_IMPLIES_END_TAG => 'Unexpcted non-nesting start tag in nested context',
self::ENCODING_ERROR => 'Corrupt encoding near byte position %s',
self::UNEXPECTED_NULL_CHARACTER => 'Unexpected null character',

25
lib/TreeBuilder.php

@ -1354,17 +1354,28 @@ class TreeBuilder {
# 4. Set the frameset-ok flag to "not ok".
$this->framesetOk = false;
}
# A start tag whose tag name is "a"
elseif ($token->name === "a") {
# If the list of active formatting elements contains an a element 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;
$this->error(ParseError::UNEXPECTED_START_TAG);
# ... run the adoption agency algorithm for the token,
$this->adopt($token);
# ... then remove that element from the list of active formatting elements and the
# stack of open elements if the adoption agency algorithm didn't already remove it
# (it might not have if the element is not in table scope).
throw new NotImplementedException("NOT IMPLEMENTED");
if (($pos = $this->activeFormattingElementsList->findToMarker("a")) > -1) {
$this->error(ParseError::UNEXPECTED_START_TAG_IMPLIES_END_TAG);
$element = $this->activeFormattingElementsList[$pos]['element'];
# ... run the adoption agency algorithm for the token,
$this->adopt($token);
# ... then remove that element from the list of active formatting elements and the
# stack of open elements if the adoption agency algorithm didn't already remove it
# (it might not have if the element is not in table scope).
$this->activeFormattingElementsList->removeSame($element);
$this->Stack->removeSame($element);
}
# Reconstruct the active formatting elements, if any.
$this->activeFormattingElementsList->reconstruct();
# Insert an HTML element for the token.
$element = $this->insertStartTagToken($token);
# Push onto the list of active formatting elements that element.
$this->activeFormattingElementsList->insert($token, $element);
} else {
throw new NotImplementedException("NOT IMPLEMENTED");
}

Loading…
Cancel
Save