ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
HTML5TreeConstructer Class Reference
+ Collaboration diagram for HTML5TreeConstructer:

Public Member Functions

 __construct ()
 
 emitToken ($token)
 
 save ()
 
 __construct ()
 
 emitToken ($token)
 
 save ()
 

Data Fields

 $stack = array()
 
const INIT_PHASE = 0
 
const ROOT_PHASE = 1
 
const MAIN_PHASE = 2
 
const END_PHASE = 3
 
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
 
const SPECIAL = 0
 
const SCOPING = 1
 
const FORMATTING = 2
 
const PHRASING = 3
 
const MARKER = 0
 

Private Member Functions

 initPhase ($token)
 
 rootElementPhase ($token)
 
 mainPhase ($token)
 
 beforeHead ($token)
 
 inHead ($token)
 
 afterHead ($token)
 
 inBody ($token)
 
 inTable ($token)
 
 inCaption ($token)
 
 inColumnGroup ($token)
 
 inTableBody ($token)
 
 inRow ($token)
 
 inCell ($token)
 
 inSelect ($token)
 
 afterBody ($token)
 
 inFrameset ($token)
 
 afterFrameset ($token)
 
 trailingEndPhase ($token)
 
 insertElement ($token, $append=true, $check=false)
 
 insertText ($data)
 
 insertComment ($data)
 
 appendToRealParent ($node)
 
 elementInScope ($el, $table=false)
 
 reconstructActiveFormattingElements ()
 
 clearTheActiveFormattingElementsUpToTheLastMarker ()
 
 generateImpliedEndTags ($exclude=array())
 
 getElementCategory ($node)
 
 clearStackToTableContext ($elements)
 
 resetInsertionMode ()
 
 closeCell ()
 
 initPhase ($token)
 
 rootElementPhase ($token)
 
 mainPhase ($token)
 
 beforeHead ($token)
 
 inHead ($token)
 
 afterHead ($token)
 
 inBody ($token)
 
 inTable ($token)
 
 inCaption ($token)
 
 inColumnGroup ($token)
 
 inTableBody ($token)
 
 inRow ($token)
 
 inCell ($token)
 
 inSelect ($token)
 
 afterBody ($token)
 
 inFrameset ($token)
 
 afterFrameset ($token)
 
 trailingEndPhase ($token)
 
 insertElement ($token, $append=true)
 
 insertText ($data)
 
 insertComment ($data)
 
 appendToRealParent ($node)
 
 elementInScope ($el, $table=false)
 
 reconstructActiveFormattingElements ()
 
 clearTheActiveFormattingElementsUpToTheLastMarker ()
 
 generateImpliedEndTags (array $exclude=array())
 
 getElementCategory ($name)
 
 clearStackToTableContext ($elements)
 
 resetInsertionMode ()
 
 closeCell ()
 

Private Attributes

 $phase
 
 $mode
 
 $dom
 
 $foster_parent = null
 
 $a_formatting = array()
 
 $head_pointer = null
 
 $form_pointer = null
 
 $scoping = array('button', 'caption', 'html', 'marquee', 'object', 'table', 'td', 'th')
 
 $formatting
 
 $special
 

Detailed Description

Definition at line 1576 of file PH5P.php.

Constructor & Destructor Documentation

◆ __construct() [1/2]

HTML5TreeConstructer::__construct ( )

Definition at line 1699 of file PH5P.php.

1700  {
1701  $this->phase = self::INIT_PHASE;
1702  $this->mode = self::BEFOR_HEAD;
1703  $this->dom = new DOMDocument;
1704 
1705  $this->dom->encoding = 'UTF-8';
1706  $this->dom->preserveWhiteSpace = true;
1707  $this->dom->substituteEntities = true;
1708  $this->dom->strictErrorChecking = false;
1709  }

◆ __construct() [2/2]

HTML5TreeConstructer::__construct ( )

Definition at line 1195 of file PH5P.php.

1196  {
1197  $this->phase = self::INIT_PHASE;
1198  $this->mode = self::BEFOR_HEAD;
1199  $this->dom = new DOMDocument;
1200 
1201  $this->dom->encoding = 'UTF-8';
1202  $this->dom->preserveWhiteSpace = true;
1203  $this->dom->substituteEntities = true;
1204  $this->dom->strictErrorChecking = false;
1205  }

Member Function Documentation

◆ afterBody() [1/2]

HTML5TreeConstructer::afterBody (   $token)
private

Definition at line 3340 of file PH5P.php.

References $comment, HTML5\$token, HTML5\CHARACTR, HTML5\COMMENT, and HTML5\ENDTAG.

3341  {
3342  /* Handle the token as follows: */
3343 
3344  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
3345  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
3346  or U+0020 SPACE */
3347  if($token['type'] === HTML5::CHARACTR &&
3348  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) {
3349  /* Process the token as it would be processed if the insertion mode
3350  was "in body". */
3351  $this->inBody($token);
3352 
3353  /* A comment token */
3354  } elseif($token['type'] === HTML5::COMMENT) {
3355  /* Append a Comment node to the first element in the stack of open
3356  elements (the html element), with the data attribute set to the
3357  data given in the comment token. */
3358  $comment = $this->dom->createComment($token['data']);
3359  $this->stack[0]->appendChild($comment);
3360 
3361  /* An end tag with the tag name "html" */
3362  } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') {
3363  /* If the parser was originally created in order to handle the
3364  setting of an element's innerHTML attribute, this is a parse error;
3365  ignore the token. (The element will be an html element in this
3366  case.) (innerHTML case) */
3367 
3368  /* Otherwise, switch to the trailing end phase. */
3369  $this->phase = self::END_PHASE;
3370 
3371  /* Anything else */
3372  } else {
3373  /* Parse error. Set the insertion mode to "in body" and reprocess
3374  the token. */
3375  $this->mode = self::IN_BODY;
3376  return $this->inBody($token);
3377  }
3378  }
const COMMENT
Definition: PH5P.php:457
$comment
Definition: buildRTE.php:83
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456

◆ afterBody() [2/2]

HTML5TreeConstructer::afterBody (   $token)
private

Definition at line 4201 of file PH5P.php.

References $comment, HTML5\CHARACTR, HTML5\COMMENT, and HTML5\ENDTAG.

4202  {
4203  /* Handle the token as follows: */
4204 
4205  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
4206  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
4207  or U+0020 SPACE */
4208  if ($token['type'] === HTML5::CHARACTR &&
4209  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
4210  ) {
4211  /* Process the token as it would be processed if the insertion mode
4212  was "in body". */
4213  $this->inBody($token);
4214 
4215  /* A comment token */
4216  } elseif ($token['type'] === HTML5::COMMENT) {
4217  /* Append a Comment node to the first element in the stack of open
4218  elements (the html element), with the data attribute set to the
4219  data given in the comment token. */
4220  $comment = $this->dom->createComment($token['data']);
4221  $this->stack[0]->appendChild($comment);
4222 
4223  /* An end tag with the tag name "html" */
4224  } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') {
4225  /* If the parser was originally created in order to handle the
4226  setting of an element's innerHTML attribute, this is a parse error;
4227  ignore the token. (The element will be an html element in this
4228  case.) (innerHTML case) */
4229 
4230  /* Otherwise, switch to the trailing end phase. */
4231  $this->phase = self::END_PHASE;
4232 
4233  /* Anything else */
4234  } else {
4235  /* Parse error. Set the insertion mode to "in body" and reprocess
4236  the token. */
4237  $this->mode = self::IN_BODY;
4238  return $this->inBody($token);
4239  }
4240  }
const COMMENT
Definition: PH5P.php:457
$comment
Definition: buildRTE.php:83
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456

◆ afterFrameset() [1/2]

HTML5TreeConstructer::afterFrameset (   $token)
private

Definition at line 3444 of file PH5P.php.

References HTML5\$token, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

3445  {
3446  /* Handle the token as follows: */
3447 
3448  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
3449  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
3450  U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */
3451  if($token['type'] === HTML5::CHARACTR &&
3452  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) {
3453  /* Append the character to the current node. */
3454  $this->insertText($token['data']);
3455 
3456  /* A comment token */
3457  } elseif($token['type'] === HTML5::COMMENT) {
3458  /* Append a Comment node to the current node with the data
3459  attribute set to the data given in the comment token. */
3460  $this->insertComment($token['data']);
3461 
3462  /* An end tag with the tag name "html" */
3463  } elseif($token['name'] === 'html' &&
3464  $token['type'] === HTML5::ENDTAG) {
3465  /* Switch to the trailing end phase. */
3466  $this->phase = self::END_PHASE;
3467 
3468  /* A start tag with the tag name "noframes" */
3469  } elseif($token['name'] === 'noframes' &&
3470  $token['type'] === HTML5::STARTTAG) {
3471  /* Process the token as if the insertion mode had been "in body". */
3472  $this->inBody($token);
3473 
3474  /* Anything else */
3475  } else {
3476  /* Parse error. Ignore the token. */
3477  }
3478  }
const COMMENT
Definition: PH5P.php:457
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ afterFrameset() [2/2]

HTML5TreeConstructer::afterFrameset (   $token)
private

Definition at line 4311 of file PH5P.php.

References HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

4312  {
4313  /* Handle the token as follows: */
4314 
4315  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
4316  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
4317  U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */
4318  if ($token['type'] === HTML5::CHARACTR &&
4319  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
4320  ) {
4321  /* Append the character to the current node. */
4322  $this->insertText($token['data']);
4323 
4324  /* A comment token */
4325  } elseif ($token['type'] === HTML5::COMMENT) {
4326  /* Append a Comment node to the current node with the data
4327  attribute set to the data given in the comment token. */
4328  $this->insertComment($token['data']);
4329 
4330  /* An end tag with the tag name "html" */
4331  } elseif ($token['name'] === 'html' &&
4332  $token['type'] === HTML5::ENDTAG
4333  ) {
4334  /* Switch to the trailing end phase. */
4335  $this->phase = self::END_PHASE;
4336 
4337  /* A start tag with the tag name "noframes" */
4338  } elseif ($token['name'] === 'noframes' &&
4339  $token['type'] === HTML5::STARTTAG
4340  ) {
4341  /* Process the token as if the insertion mode had been "in body". */
4342  $this->inBody($token);
4343 
4344  /* Anything else */
4345  } else {
4346  /* Parse error. Ignore the token. */
4347  }
4348  }
const COMMENT
Definition: PH5P.php:457
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ afterHead() [1/2]

HTML5TreeConstructer::afterHead (   $token)
private

Definition at line 1548 of file PH5P.php.

References HTML5\$token, array, HTML5\CHARACTR, HTML5\COMMENT, and HTML5\STARTTAG.

1549  {
1550  /* Handle the token as follows: */
1551 
1552  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
1553  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1554  or U+0020 SPACE */
1555  if($token['type'] === HTML5::CHARACTR &&
1556  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) {
1557  /* Append the character to the current node. */
1558  $this->insertText($token['data']);
1559 
1560  /* A comment token */
1561  } elseif($token['type'] === HTML5::COMMENT) {
1562  /* Append a Comment node to the current node with the data attribute
1563  set to the data given in the comment token. */
1564  $this->insertComment($token['data']);
1565 
1566  /* A start tag token with the tag name "body" */
1567  } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'body') {
1568  /* Insert a body element for the token. */
1569  $this->insertElement($token);
1570 
1571  /* Change the insertion mode to "in body". */
1572  $this->mode = self::IN_BODY;
1573 
1574  /* A start tag token with the tag name "frameset" */
1575  } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'frameset') {
1576  /* Insert a frameset element for the token. */
1577  $this->insertElement($token);
1578 
1579  /* Change the insertion mode to "in frameset". */
1580  $this->mode = self::IN_FRAME;
1581 
1582  /* A start tag token whose tag name is one of: "base", "link", "meta",
1583  "script", "style", "title" */
1584  } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'],
1585  array('base', 'link', 'meta', 'script', 'style', 'title'))) {
1586  /* Parse error. Switch the insertion mode back to "in head" and
1587  reprocess the token. */
1588  $this->mode = self::IN_HEAD;
1589  return $this->inHead($token);
1590 
1591  /* Anything else */
1592  } else {
1593  /* Act as if a start tag token with the tag name "body" and no
1594  attributes had been seen, and then reprocess the current token. */
1595  $this->afterHead(array(
1596  'name' => 'body',
1597  'type' => HTML5::STARTTAG,
1598  'attr' => array()
1599  ));
1600 
1601  return $this->inBody($token);
1602  }
1603  }
const COMMENT
Definition: PH5P.php:457
afterHead($token)
Definition: PH5P.php:2112
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const STARTTAG
Definition: PH5P.php:455

◆ afterHead() [2/2]

HTML5TreeConstructer::afterHead (   $token)
private

Definition at line 2112 of file PH5P.php.

References array, HTML5\CHARACTR, HTML5\COMMENT, and HTML5\STARTTAG.

2113  {
2114  /* Handle the token as follows: */
2115 
2116  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
2117  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
2118  or U+0020 SPACE */
2119  if ($token['type'] === HTML5::CHARACTR &&
2120  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
2121  ) {
2122  /* Append the character to the current node. */
2123  $this->insertText($token['data']);
2124 
2125  /* A comment token */
2126  } elseif ($token['type'] === HTML5::COMMENT) {
2127  /* Append a Comment node to the current node with the data attribute
2128  set to the data given in the comment token. */
2129  $this->insertComment($token['data']);
2130 
2131  /* A start tag token with the tag name "body" */
2132  } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'body') {
2133  /* Insert a body element for the token. */
2134  $this->insertElement($token);
2135 
2136  /* Change the insertion mode to "in body". */
2137  $this->mode = self::IN_BODY;
2138 
2139  /* A start tag token with the tag name "frameset" */
2140  } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'frameset') {
2141  /* Insert a frameset element for the token. */
2142  $this->insertElement($token);
2143 
2144  /* Change the insertion mode to "in frameset". */
2145  $this->mode = self::IN_FRAME;
2146 
2147  /* A start tag token whose tag name is one of: "base", "link", "meta",
2148  "script", "style", "title" */
2149  } elseif ($token['type'] === HTML5::STARTTAG && in_array(
2150  $token['name'],
2151  array('base', 'link', 'meta', 'script', 'style', 'title')
2152  )
2153  ) {
2154  /* Parse error. Switch the insertion mode back to "in head" and
2155  reprocess the token. */
2156  $this->mode = self::IN_HEAD;
2157  return $this->inHead($token);
2158 
2159  /* Anything else */
2160  } else {
2161  /* Act as if a start tag token with the tag name "body" and no
2162  attributes had been seen, and then reprocess the current token. */
2163  $this->afterHead(
2164  array(
2165  'name' => 'body',
2166  'type' => HTML5::STARTTAG,
2167  'attr' => array()
2168  )
2169  );
2170 
2171  return $this->inBody($token);
2172  }
2173  }
const COMMENT
Definition: PH5P.php:457
afterHead($token)
Definition: PH5P.php:2112
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const STARTTAG
Definition: PH5P.php:455

◆ appendToRealParent() [1/2]

HTML5TreeConstructer::appendToRealParent (   $node)
private

Definition at line 3549 of file PH5P.php.

References $n.

3550  {
3551  if($this->foster_parent === null) {
3552  end($this->stack)->appendChild($node);
3553 
3554  } elseif($this->foster_parent !== null) {
3555  /* If the foster parent element is the parent element of the
3556  last table element in the stack of open elements, then the new
3557  node must be inserted immediately before the last table element
3558  in the stack of open elements in the foster parent element;
3559  otherwise, the new node must be appended to the foster parent
3560  element. */
3561  for($n = count($this->stack) - 1; $n >= 0; $n--) {
3562  if($this->stack[$n]->nodeName === 'table' &&
3563  $this->stack[$n]->parentNode !== null) {
3564  $table = $this->stack[$n];
3565  break;
3566  }
3567  }
3568 
3569  if(isset($table) && $this->foster_parent->isSameNode($table->parentNode))
3570  $this->foster_parent->insertBefore($node, $table);
3571  else
3572  $this->foster_parent->appendChild($node);
3573 
3574  $this->foster_parent = null;
3575  }
3576  }
$n
Definition: RandomTest.php:80

◆ appendToRealParent() [2/2]

HTML5TreeConstructer::appendToRealParent (   $node)
private

Definition at line 4434 of file PH5P.php.

References $n.

4435  {
4436  if ($this->foster_parent === null) {
4437  end($this->stack)->appendChild($node);
4438 
4439  } elseif ($this->foster_parent !== null) {
4440  /* If the foster parent element is the parent element of the
4441  last table element in the stack of open elements, then the new
4442  node must be inserted immediately before the last table element
4443  in the stack of open elements in the foster parent element;
4444  otherwise, the new node must be appended to the foster parent
4445  element. */
4446  for ($n = count($this->stack) - 1; $n >= 0; $n--) {
4447  if ($this->stack[$n]->nodeName === 'table' &&
4448  $this->stack[$n]->parentNode !== null
4449  ) {
4450  $table = $this->stack[$n];
4451  break;
4452  }
4453  }
4454 
4455  if (isset($table) && $this->foster_parent->isSameNode($table->parentNode)) {
4456  $this->foster_parent->insertBefore($node, $table);
4457  } else {
4458  $this->foster_parent->appendChild($node);
4459  }
4460 
4461  $this->foster_parent = null;
4462  }
4463  }
$n
Definition: RandomTest.php:80

◆ beforeHead() [1/2]

HTML5TreeConstructer::beforeHead (   $token)
private

Definition at line 1368 of file PH5P.php.

References HTML5\$token, array, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

1369  {
1370  /* Handle the token as follows: */
1371 
1372  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
1373  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1374  or U+0020 SPACE */
1375  if($token['type'] === HTML5::CHARACTR &&
1376  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) {
1377  /* Append the character to the current node. */
1378  $this->insertText($token['data']);
1379 
1380  /* A comment token */
1381  } elseif($token['type'] === HTML5::COMMENT) {
1382  /* Append a Comment node to the current node with the data attribute
1383  set to the data given in the comment token. */
1384  $this->insertComment($token['data']);
1385 
1386  /* A start tag token with the tag name "head" */
1387  } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') {
1388  /* Create an element for the token, append the new element to the
1389  current node and push it onto the stack of open elements. */
1390  $element = $this->insertElement($token);
1391 
1392  /* Set the head element pointer to this new element node. */
1393  $this->head_pointer = $element;
1394 
1395  /* Change the insertion mode to "in head". */
1396  $this->mode = self::IN_HEAD;
1397 
1398  /* A start tag token whose tag name is one of: "base", "link", "meta",
1399  "script", "style", "title". Or an end tag with the tag name "html".
1400  Or a character token that is not one of U+0009 CHARACTER TABULATION,
1401  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1402  or U+0020 SPACE. Or any other start tag token */
1403  } elseif($token['type'] === HTML5::STARTTAG ||
1404  ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') ||
1405  ($token['type'] === HTML5::CHARACTR && !preg_match('/^[\t\n\x0b\x0c ]$/',
1406  $token['data']))) {
1407  /* Act as if a start tag token with the tag name "head" and no
1408  attributes had been seen, then reprocess the current token. */
1409  $this->beforeHead(array(
1410  'name' => 'head',
1411  'type' => HTML5::STARTTAG,
1412  'attr' => array()
1413  ));
1414 
1415  return $this->inHead($token);
1416 
1417  /* Any other end tag */
1418  } elseif($token['type'] === HTML5::ENDTAG) {
1419  /* Parse error. Ignore the token. */
1420  }
1421  }
const COMMENT
Definition: PH5P.php:457
beforeHead($token)
Definition: PH5P.php:1916
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ beforeHead() [2/2]

HTML5TreeConstructer::beforeHead (   $token)
private

Definition at line 1916 of file PH5P.php.

References array, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

1917  {
1918  /* Handle the token as follows: */
1919 
1920  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
1921  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1922  or U+0020 SPACE */
1923  if ($token['type'] === HTML5::CHARACTR &&
1924  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
1925  ) {
1926  /* Append the character to the current node. */
1927  $this->insertText($token['data']);
1928 
1929  /* A comment token */
1930  } elseif ($token['type'] === HTML5::COMMENT) {
1931  /* Append a Comment node to the current node with the data attribute
1932  set to the data given in the comment token. */
1933  $this->insertComment($token['data']);
1934 
1935  /* A start tag token with the tag name "head" */
1936  } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') {
1937  /* Create an element for the token, append the new element to the
1938  current node and push it onto the stack of open elements. */
1939  $element = $this->insertElement($token);
1940 
1941  /* Set the head element pointer to this new element node. */
1942  $this->head_pointer = $element;
1943 
1944  /* Change the insertion mode to "in head". */
1945  $this->mode = self::IN_HEAD;
1946 
1947  /* A start tag token whose tag name is one of: "base", "link", "meta",
1948  "script", "style", "title". Or an end tag with the tag name "html".
1949  Or a character token that is not one of U+0009 CHARACTER TABULATION,
1950  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1951  or U+0020 SPACE. Or any other start tag token */
1952  } elseif ($token['type'] === HTML5::STARTTAG ||
1953  ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') ||
1954  ($token['type'] === HTML5::CHARACTR && !preg_match(
1955  '/^[\t\n\x0b\x0c ]$/',
1956  $token['data']
1957  ))
1958  ) {
1959  /* Act as if a start tag token with the tag name "head" and no
1960  attributes had been seen, then reprocess the current token. */
1961  $this->beforeHead(
1962  array(
1963  'name' => 'head',
1964  'type' => HTML5::STARTTAG,
1965  'attr' => array()
1966  )
1967  );
1968 
1969  return $this->inHead($token);
1970 
1971  /* Any other end tag */
1972  } elseif ($token['type'] === HTML5::ENDTAG) {
1973  /* Parse error. Ignore the token. */
1974  }
1975  }
const COMMENT
Definition: PH5P.php:457
beforeHead($token)
Definition: PH5P.php:1916
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ clearStackToTableContext() [1/2]

HTML5TreeConstructer::clearStackToTableContext (   $elements)
private

Definition at line 3752 of file PH5P.php.

3753  {
3754  /* When the steps above require the UA to clear the stack back to a
3755  table context, it means that the UA must, while the current node is not
3756  a table element or an html element, pop elements from the stack of open
3757  elements. If this causes any elements to be popped from the stack, then
3758  this is a parse error. */
3759  while(true) {
3760  $node = end($this->stack)->nodeName;
3761 
3762  if(in_array($node, $elements)) {
3763  break;
3764  } else {
3765  array_pop($this->stack);
3766  }
3767  }
3768  }

◆ clearStackToTableContext() [2/2]

HTML5TreeConstructer::clearStackToTableContext (   $elements)
private

Definition at line 4648 of file PH5P.php.

4649  {
4650  /* When the steps above require the UA to clear the stack back to a
4651  table context, it means that the UA must, while the current node is not
4652  a table element or an html element, pop elements from the stack of open
4653  elements. If this causes any elements to be popped from the stack, then
4654  this is a parse error. */
4655  while (true) {
4656  $node = end($this->stack)->nodeName;
4657 
4658  if (in_array($node, $elements)) {
4659  break;
4660  } else {
4661  array_pop($this->stack);
4662  }
4663  }
4664  }

◆ clearTheActiveFormattingElementsUpToTheLastMarker() [1/2]

HTML5TreeConstructer::clearTheActiveFormattingElementsUpToTheLastMarker ( )
private

Definition at line 3700 of file PH5P.php.

3701  {
3702  /* When the steps below require the UA to clear the list of active
3703  formatting elements up to the last marker, the UA must perform the
3704  following steps: */
3705 
3706  while(true) {
3707  /* 1. Let entry be the last (most recently added) entry in the list
3708  of active formatting elements. */
3709  $entry = end($this->a_formatting);
3710 
3711  /* 2. Remove entry from the list of active formatting elements. */
3712  array_pop($this->a_formatting);
3713 
3714  /* 3. If entry was a marker, then stop the algorithm at this point.
3715  The list has been cleared up to the last marker. */
3716  if($entry === self::MARKER) {
3717  break;
3718  }
3719  }
3720  }

◆ clearTheActiveFormattingElementsUpToTheLastMarker() [2/2]

HTML5TreeConstructer::clearTheActiveFormattingElementsUpToTheLastMarker ( )
private

Definition at line 4597 of file PH5P.php.

4598  {
4599  /* When the steps below require the UA to clear the list of active
4600  formatting elements up to the last marker, the UA must perform the
4601  following steps: */
4602 
4603  while (true) {
4604  /* 1. Let entry be the last (most recently added) entry in the list
4605  of active formatting elements. */
4606  $entry = end($this->a_formatting);
4607 
4608  /* 2. Remove entry from the list of active formatting elements. */
4609  array_pop($this->a_formatting);
4610 
4611  /* 3. If entry was a marker, then stop the algorithm at this point.
4612  The list has been cleared up to the last marker. */
4613  if ($entry === self::MARKER) {
4614  break;
4615  }
4616  }
4617  }

◆ closeCell() [1/2]

HTML5TreeConstructer::closeCell ( )
private

Definition at line 3869 of file PH5P.php.

References array, and HTML5\ENDTAG.

3870  {
3871  /* If the stack of open elements has a td or th element in table scope,
3872  then act as if an end tag token with that tag name had been seen. */
3873  foreach(array('td', 'th') as $cell) {
3874  if($this->elementInScope($cell, true)) {
3875  $this->inCell(array(
3876  'name' => $cell,
3877  'type' => HTML5::ENDTAG
3878  ));
3879 
3880  break;
3881  }
3882  }
3883  }
elementInScope($el, $table=false)
Definition: PH5P.php:4465
Create styles array
The data for the language used.
const ENDTAG
Definition: PH5P.php:456

◆ closeCell() [2/2]

HTML5TreeConstructer::closeCell ( )
private

Definition at line 4765 of file PH5P.php.

References array, and HTML5\ENDTAG.

4766  {
4767  /* If the stack of open elements has a td or th element in table scope,
4768  then act as if an end tag token with that tag name had been seen. */
4769  foreach (array('td', 'th') as $cell) {
4770  if ($this->elementInScope($cell, true)) {
4771  $this->inCell(
4772  array(
4773  'name' => $cell,
4774  'type' => HTML5::ENDTAG
4775  )
4776  );
4777 
4778  break;
4779  }
4780  }
4781  }
elementInScope($el, $table=false)
Definition: PH5P.php:4465
Create styles array
The data for the language used.
const ENDTAG
Definition: PH5P.php:456

◆ elementInScope() [1/2]

HTML5TreeConstructer::elementInScope (   $el,
  $table = false 
)
private

Definition at line 3578 of file PH5P.php.

References $n, and array.

3579  {
3580  if(is_array($el)) {
3581  foreach($el as $element) {
3582  if($this->elementInScope($element, $table)) {
3583  return true;
3584  }
3585  }
3586 
3587  return false;
3588  }
3589 
3590  $leng = count($this->stack);
3591 
3592  for($n = 0; $n < $leng; $n++) {
3593  /* 1. Initialise node to be the current node (the bottommost node of
3594  the stack). */
3595  $node = $this->stack[$leng - 1 - $n];
3596 
3597  if($node->tagName === $el) {
3598  /* 2. If node is the target node, terminate in a match state. */
3599  return true;
3600 
3601  } elseif($node->tagName === 'table') {
3602  /* 3. Otherwise, if node is a table element, terminate in a failure
3603  state. */
3604  return false;
3605 
3606  } elseif($table === true && in_array($node->tagName, array('caption', 'td',
3607  'th', 'button', 'marquee', 'object'))) {
3608  /* 4. Otherwise, if the algorithm is the "has an element in scope"
3609  variant (rather than the "has an element in table scope" variant),
3610  and node is one of the following, terminate in a failure state. */
3611  return false;
3612 
3613  } elseif($node === $node->ownerDocument->documentElement) {
3614  /* 5. Otherwise, if node is an html element (root element), terminate
3615  in a failure state. (This can only happen if the node is the topmost
3616  node of the stack of open elements, and prevents the next step from
3617  being invoked if there are no more elements in the stack.) */
3618  return false;
3619  }
3620 
3621  /* Otherwise, set node to the previous entry in the stack of open
3622  elements and return to step 2. (This will never fail, since the loop
3623  will always terminate in the previous step if the top of the stack
3624  is reached.) */
3625  }
3626  }
elementInScope($el, $table=false)
Definition: PH5P.php:4465
$n
Definition: RandomTest.php:80
Create styles array
The data for the language used.

◆ elementInScope() [2/2]

HTML5TreeConstructer::elementInScope (   $el,
  $table = false 
)
private

Definition at line 4465 of file PH5P.php.

References $n, and array.

4466  {
4467  if (is_array($el)) {
4468  foreach ($el as $element) {
4469  if ($this->elementInScope($element, $table)) {
4470  return true;
4471  }
4472  }
4473 
4474  return false;
4475  }
4476 
4477  $leng = count($this->stack);
4478 
4479  for ($n = 0; $n < $leng; $n++) {
4480  /* 1. Initialise node to be the current node (the bottommost node of
4481  the stack). */
4482  $node = $this->stack[$leng - 1 - $n];
4483 
4484  if ($node->tagName === $el) {
4485  /* 2. If node is the target node, terminate in a match state. */
4486  return true;
4487 
4488  } elseif ($node->tagName === 'table') {
4489  /* 3. Otherwise, if node is a table element, terminate in a failure
4490  state. */
4491  return false;
4492 
4493  } elseif ($table === true && in_array(
4494  $node->tagName,
4495  array(
4496  'caption',
4497  'td',
4498  'th',
4499  'button',
4500  'marquee',
4501  'object'
4502  )
4503  )
4504  ) {
4505  /* 4. Otherwise, if the algorithm is the "has an element in scope"
4506  variant (rather than the "has an element in table scope" variant),
4507  and node is one of the following, terminate in a failure state. */
4508  return false;
4509 
4510  } elseif ($node === $node->ownerDocument->documentElement) {
4511  /* 5. Otherwise, if node is an html element (root element), terminate
4512  in a failure state. (This can only happen if the node is the topmost
4513  node of the stack of open elements, and prevents the next step from
4514  being invoked if there are no more elements in the stack.) */
4515  return false;
4516  }
4517 
4518  /* Otherwise, set node to the previous entry in the stack of open
4519  elements and return to step 2. (This will never fail, since the loop
4520  will always terminate in the previous step if the top of the stack
4521  is reached.) */
4522  }
4523  }
elementInScope($el, $table=false)
Definition: PH5P.php:4465
$n
Definition: RandomTest.php:80
Create styles array
The data for the language used.

◆ emitToken() [1/2]

HTML5TreeConstructer::emitToken (   $token)

Definition at line 1208 of file PH5P.php.

References HTML5\$token.

1209  {
1210  switch($this->phase) {
1211  case self::INIT_PHASE: return $this->initPhase($token); break;
1212  case self::ROOT_PHASE: return $this->rootElementPhase($token); break;
1213  case self::MAIN_PHASE: return $this->mainPhase($token); break;
1214  case self::END_PHASE : return $this->trailingEndPhase($token); break;
1215  }
1216  }
rootElementPhase($token)
Definition: PH5P.php:1785
initPhase($token)
Definition: PH5P.php:1730
trailingEndPhase($token)
Definition: PH5P.php:4350
mainPhase($token)
Definition: PH5P.php:1835

◆ emitToken() [2/2]

HTML5TreeConstructer::emitToken (   $token)

Definition at line 1712 of file PH5P.php.

1713  {
1714  switch ($this->phase) {
1715  case self::INIT_PHASE:
1716  return $this->initPhase($token);
1717  break;
1718  case self::ROOT_PHASE:
1719  return $this->rootElementPhase($token);
1720  break;
1721  case self::MAIN_PHASE:
1722  return $this->mainPhase($token);
1723  break;
1724  case self::END_PHASE :
1725  return $this->trailingEndPhase($token);
1726  break;
1727  }
1728  }
rootElementPhase($token)
Definition: PH5P.php:1785
initPhase($token)
Definition: PH5P.php:1730
trailingEndPhase($token)
Definition: PH5P.php:4350
mainPhase($token)
Definition: PH5P.php:1835

◆ generateImpliedEndTags() [1/2]

HTML5TreeConstructer::generateImpliedEndTags ( array  $exclude = array())
private

Definition at line 3722 of file PH5P.php.

References $exclude, and array.

3723  {
3724  /* When the steps below require the UA to generate implied end tags,
3725  then, if the current node is a dd element, a dt element, an li element,
3726  a p element, a td element, a th element, or a tr element, the UA must
3727  act as if an end tag with the respective tag name had been seen and
3728  then generate implied end tags again. */
3729  $node = end($this->stack);
3730  $elements = array_diff(array('dd', 'dt', 'li', 'p', 'td', 'th', 'tr'), $exclude);
3731 
3732  while(in_array(end($this->stack)->nodeName, $elements)) {
3733  array_pop($this->stack);
3734  }
3735  }
if(! $in) $exclude
Create styles array
The data for the language used.

◆ generateImpliedEndTags() [2/2]

HTML5TreeConstructer::generateImpliedEndTags (   $exclude = array())
private

Definition at line 4619 of file PH5P.php.

References $exclude, and array.

4620  {
4621  /* When the steps below require the UA to generate implied end tags,
4622  then, if the current node is a dd element, a dt element, an li element,
4623  a p element, a td element, a th element, or a tr element, the UA must
4624  act as if an end tag with the respective tag name had been seen and
4625  then generate implied end tags again. */
4626  $node = end($this->stack);
4627  $elements = array_diff(array('dd', 'dt', 'li', 'p', 'td', 'th', 'tr'), $exclude);
4628 
4629  while (in_array(end($this->stack)->nodeName, $elements)) {
4630  array_pop($this->stack);
4631  }
4632  }
if(! $in) $exclude
Create styles array
The data for the language used.

◆ getElementCategory() [1/2]

HTML5TreeConstructer::getElementCategory (   $name)
private

Definition at line 3737 of file PH5P.php.

References formatting.

3738  {
3739  if(in_array($name, $this->special))
3740  return self::SPECIAL;
3741 
3742  elseif(in_array($name, $this->scoping))
3743  return self::SCOPING;
3744 
3745  elseif(in_array($name, $this->formatting))
3746  return self::FORMATTING;
3747 
3748  else
3749  return self::PHRASING;
3750  }
Add conditional formatting

◆ getElementCategory() [2/2]

HTML5TreeConstructer::getElementCategory (   $node)
private

Definition at line 4634 of file PH5P.php.

References formatting.

4635  {
4636  $name = $node->tagName;
4637  if (in_array($name, $this->special)) {
4638  return self::SPECIAL;
4639  } elseif (in_array($name, $this->scoping)) {
4640  return self::SCOPING;
4641  } elseif (in_array($name, $this->formatting)) {
4642  return self::FORMATTING;
4643  } else {
4644  return self::PHRASING;
4645  }
4646  }
Add conditional formatting

◆ inBody() [1/2]

HTML5TreeConstructer::inBody (   $token)
private

Definition at line 1605 of file PH5P.php.

References $n, HTML5\$token, $x, array, HTML5\CDATA, HTML5\CHARACTR, HTML5\COMMENT, HTML5\emitToken(), HTML5\ENDTAG, HTML5\PLAINTEXT, HTML5\RCDATA, and HTML5\STARTTAG.

1606  {
1607  /* Handle the token as follows: */
1608 
1609  switch($token['type']) {
1610  /* A character token */
1611  case HTML5::CHARACTR:
1612  /* Reconstruct the active formatting elements, if any. */
1614 
1615  /* Append the token's character to the current node. */
1616  $this->insertText($token['data']);
1617  break;
1618 
1619  /* A comment token */
1620  case HTML5::COMMENT:
1621  /* Append a Comment node to the current node with the data
1622  attribute set to the data given in the comment token. */
1623  $this->insertComment($token['data']);
1624  break;
1625 
1626  case HTML5::STARTTAG:
1627  switch($token['name']) {
1628  /* A start tag token whose tag name is one of: "script",
1629  "style" */
1630  case 'script': case 'style':
1631  /* Process the token as if the insertion mode had been "in
1632  head". */
1633  return $this->inHead($token);
1634  break;
1635 
1636  /* A start tag token whose tag name is one of: "base", "link",
1637  "meta", "title" */
1638  case 'base': case 'link': case 'meta': case 'title':
1639  /* Parse error. Process the token as if the insertion mode
1640  had been "in head". */
1641  return $this->inHead($token);
1642  break;
1643 
1644  /* A start tag token with the tag name "body" */
1645  case 'body':
1646  /* Parse error. If the second element on the stack of open
1647  elements is not a body element, or, if the stack of open
1648  elements has only one node on it, then ignore the token.
1649  (innerHTML case) */
1650  if(count($this->stack) === 1 || $this->stack[1]->nodeName !== 'body') {
1651  // Ignore
1652 
1653  /* Otherwise, for each attribute on the token, check to see
1654  if the attribute is already present on the body element (the
1655  second element) on the stack of open elements. If it is not,
1656  add the attribute and its corresponding value to that
1657  element. */
1658  } else {
1659  foreach($token['attr'] as $attr) {
1660  if(!$this->stack[1]->hasAttribute($attr['name'])) {
1661  $this->stack[1]->setAttribute($attr['name'], $attr['value']);
1662  }
1663  }
1664  }
1665  break;
1666 
1667  /* A start tag whose tag name is one of: "address",
1668  "blockquote", "center", "dir", "div", "dl", "fieldset",
1669  "listing", "menu", "ol", "p", "ul" */
1670  case 'address': case 'blockquote': case 'center': case 'dir':
1671  case 'div': case 'dl': case 'fieldset': case 'listing':
1672  case 'menu': case 'ol': case 'p': case 'ul':
1673  /* If the stack of open elements has a p element in scope,
1674  then act as if an end tag with the tag name p had been
1675  seen. */
1676  if($this->elementInScope('p')) {
1677  $this->emitToken(array(
1678  'name' => 'p',
1679  'type' => HTML5::ENDTAG
1680  ));
1681  }
1682 
1683  /* Insert an HTML element for the token. */
1684  $this->insertElement($token);
1685  break;
1686 
1687  /* A start tag whose tag name is "form" */
1688  case 'form':
1689  /* If the form element pointer is not null, ignore the
1690  token with a parse error. */
1691  if($this->form_pointer !== null) {
1692  // Ignore.
1693 
1694  /* Otherwise: */
1695  } else {
1696  /* If the stack of open elements has a p element in
1697  scope, then act as if an end tag with the tag name p
1698  had been seen. */
1699  if($this->elementInScope('p')) {
1700  $this->emitToken(array(
1701  'name' => 'p',
1702  'type' => HTML5::ENDTAG
1703  ));
1704  }
1705 
1706  /* Insert an HTML element for the token, and set the
1707  form element pointer to point to the element created. */
1708  $element = $this->insertElement($token);
1709  $this->form_pointer = $element;
1710  }
1711  break;
1712 
1713  /* A start tag whose tag name is "li", "dd" or "dt" */
1714  case 'li': case 'dd': case 'dt':
1715  /* If the stack of open elements has a p element in scope,
1716  then act as if an end tag with the tag name p had been
1717  seen. */
1718  if($this->elementInScope('p')) {
1719  $this->emitToken(array(
1720  'name' => 'p',
1721  'type' => HTML5::ENDTAG
1722  ));
1723  }
1724 
1725  $stack_length = count($this->stack) - 1;
1726 
1727  for($n = $stack_length; 0 <= $n; $n--) {
1728  /* 1. Initialise node to be the current node (the
1729  bottommost node of the stack). */
1730  $stop = false;
1731  $node = $this->stack[$n];
1732  $cat = $this->getElementCategory($node->tagName);
1733 
1734  /* 2. If node is an li, dd or dt element, then pop all
1735  the nodes from the current node up to node, including
1736  node, then stop this algorithm. */
1737  if($token['name'] === $node->tagName || ($token['name'] !== 'li'
1738  && ($node->tagName === 'dd' || $node->tagName === 'dt'))) {
1739  for($x = $stack_length; $x >= $n ; $x--) {
1740  array_pop($this->stack);
1741  }
1742 
1743  break;
1744  }
1745 
1746  /* 3. If node is not in the formatting category, and is
1747  not in the phrasing category, and is not an address or
1748  div element, then stop this algorithm. */
1749  if($cat !== self::FORMATTING && $cat !== self::PHRASING &&
1750  $node->tagName !== 'address' && $node->tagName !== 'div') {
1751  break;
1752  }
1753  }
1754 
1755  /* Finally, insert an HTML element with the same tag
1756  name as the token's. */
1757  $this->insertElement($token);
1758  break;
1759 
1760  /* A start tag token whose tag name is "plaintext" */
1761  case 'plaintext':
1762  /* If the stack of open elements has a p element in scope,
1763  then act as if an end tag with the tag name p had been
1764  seen. */
1765  if($this->elementInScope('p')) {
1766  $this->emitToken(array(
1767  'name' => 'p',
1768  'type' => HTML5::ENDTAG
1769  ));
1770  }
1771 
1772  /* Insert an HTML element for the token. */
1773  $this->insertElement($token);
1774 
1775  return HTML5::PLAINTEXT;
1776  break;
1777 
1778  /* A start tag whose tag name is one of: "h1", "h2", "h3", "h4",
1779  "h5", "h6" */
1780  case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6':
1781  /* If the stack of open elements has a p element in scope,
1782  then act as if an end tag with the tag name p had been seen. */
1783  if($this->elementInScope('p')) {
1784  $this->emitToken(array(
1785  'name' => 'p',
1786  'type' => HTML5::ENDTAG
1787  ));
1788  }
1789 
1790  /* If the stack of open elements has in scope an element whose
1791  tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then
1792  this is a parse error; pop elements from the stack until an
1793  element with one of those tag names has been popped from the
1794  stack. */
1795  while($this->elementInScope(array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) {
1796  array_pop($this->stack);
1797  }
1798 
1799  /* Insert an HTML element for the token. */
1800  $this->insertElement($token);
1801  break;
1802 
1803  /* A start tag whose tag name is "a" */
1804  case 'a':
1805  /* If the list of active formatting elements contains
1806  an element whose tag name is "a" between the end of the
1807  list and the last marker on the list (or the start of
1808  the list if there is no marker on the list), then this
1809  is a parse error; act as if an end tag with the tag name
1810  "a" had been seen, then remove that element from the list
1811  of active formatting elements and the stack of open
1812  elements if the end tag didn't already remove it (it
1813  might not have if the element is not in table scope). */
1814  $leng = count($this->a_formatting);
1815 
1816  for($n = $leng - 1; $n >= 0; $n--) {
1817  if($this->a_formatting[$n] === self::MARKER) {
1818  break;
1819 
1820  } elseif($this->a_formatting[$n]->nodeName === 'a') {
1821  $this->emitToken(array(
1822  'name' => 'a',
1823  'type' => HTML5::ENDTAG
1824  ));
1825  break;
1826  }
1827  }
1828 
1829  /* Reconstruct the active formatting elements, if any. */
1831 
1832  /* Insert an HTML element for the token. */
1833  $el = $this->insertElement($token);
1834 
1835  /* Add that element to the list of active formatting
1836  elements. */
1837  $this->a_formatting[] = $el;
1838  break;
1839 
1840  /* A start tag whose tag name is one of: "b", "big", "em", "font",
1841  "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */
1842  case 'b': case 'big': case 'em': case 'font': case 'i':
1843  case 'nobr': case 's': case 'small': case 'strike':
1844  case 'strong': case 'tt': case 'u':
1845  /* Reconstruct the active formatting elements, if any. */
1847 
1848  /* Insert an HTML element for the token. */
1849  $el = $this->insertElement($token);
1850 
1851  /* Add that element to the list of active formatting
1852  elements. */
1853  $this->a_formatting[] = $el;
1854  break;
1855 
1856  /* A start tag token whose tag name is "button" */
1857  case 'button':
1858  /* If the stack of open elements has a button element in scope,
1859  then this is a parse error; act as if an end tag with the tag
1860  name "button" had been seen, then reprocess the token. (We don't
1861  do that. Unnecessary.) */
1862  if($this->elementInScope('button')) {
1863  $this->inBody(array(
1864  'name' => 'button',
1865  'type' => HTML5::ENDTAG
1866  ));
1867  }
1868 
1869  /* Reconstruct the active formatting elements, if any. */
1871 
1872  /* Insert an HTML element for the token. */
1873  $this->insertElement($token);
1874 
1875  /* Insert a marker at the end of the list of active
1876  formatting elements. */
1877  $this->a_formatting[] = self::MARKER;
1878  break;
1879 
1880  /* A start tag token whose tag name is one of: "marquee", "object" */
1881  case 'marquee': case 'object':
1882  /* Reconstruct the active formatting elements, if any. */
1884 
1885  /* Insert an HTML element for the token. */
1886  $this->insertElement($token);
1887 
1888  /* Insert a marker at the end of the list of active
1889  formatting elements. */
1890  $this->a_formatting[] = self::MARKER;
1891  break;
1892 
1893  /* A start tag token whose tag name is "xmp" */
1894  case 'xmp':
1895  /* Reconstruct the active formatting elements, if any. */
1897 
1898  /* Insert an HTML element for the token. */
1899  $this->insertElement($token);
1900 
1901  /* Switch the content model flag to the CDATA state. */
1902  return HTML5::CDATA;
1903  break;
1904 
1905  /* A start tag whose tag name is "table" */
1906  case 'table':
1907  /* If the stack of open elements has a p element in scope,
1908  then act as if an end tag with the tag name p had been seen. */
1909  if($this->elementInScope('p')) {
1910  $this->emitToken(array(
1911  'name' => 'p',
1912  'type' => HTML5::ENDTAG
1913  ));
1914  }
1915 
1916  /* Insert an HTML element for the token. */
1917  $this->insertElement($token);
1918 
1919  /* Change the insertion mode to "in table". */
1920  $this->mode = self::IN_TABLE;
1921  break;
1922 
1923  /* A start tag whose tag name is one of: "area", "basefont",
1924  "bgsound", "br", "embed", "img", "param", "spacer", "wbr" */
1925  case 'area': case 'basefont': case 'bgsound': case 'br':
1926  case 'embed': case 'img': case 'param': case 'spacer':
1927  case 'wbr':
1928  /* Reconstruct the active formatting elements, if any. */
1930 
1931  /* Insert an HTML element for the token. */
1932  $this->insertElement($token);
1933 
1934  /* Immediately pop the current node off the stack of open elements. */
1935  array_pop($this->stack);
1936  break;
1937 
1938  /* A start tag whose tag name is "hr" */
1939  case 'hr':
1940  /* If the stack of open elements has a p element in scope,
1941  then act as if an end tag with the tag name p had been seen. */
1942  if($this->elementInScope('p')) {
1943  $this->emitToken(array(
1944  'name' => 'p',
1945  'type' => HTML5::ENDTAG
1946  ));
1947  }
1948 
1949  /* Insert an HTML element for the token. */
1950  $this->insertElement($token);
1951 
1952  /* Immediately pop the current node off the stack of open elements. */
1953  array_pop($this->stack);
1954  break;
1955 
1956  /* A start tag whose tag name is "image" */
1957  case 'image':
1958  /* Parse error. Change the token's tag name to "img" and
1959  reprocess it. (Don't ask.) */
1960  $token['name'] = 'img';
1961  return $this->inBody($token);
1962  break;
1963 
1964  /* A start tag whose tag name is "input" */
1965  case 'input':
1966  /* Reconstruct the active formatting elements, if any. */
1968 
1969  /* Insert an input element for the token. */
1970  $element = $this->insertElement($token, false);
1971 
1972  /* If the form element pointer is not null, then associate the
1973  input element with the form element pointed to by the form
1974  element pointer. */
1975  $this->form_pointer !== null
1976  ? $this->form_pointer->appendChild($element)
1977  : end($this->stack)->appendChild($element);
1978 
1979  /* Pop that input element off the stack of open elements. */
1980  array_pop($this->stack);
1981  break;
1982 
1983  /* A start tag whose tag name is "isindex" */
1984  case 'isindex':
1985  /* Parse error. */
1986  // w/e
1987 
1988  /* If the form element pointer is not null,
1989  then ignore the token. */
1990  if($this->form_pointer === null) {
1991  /* Act as if a start tag token with the tag name "form" had
1992  been seen. */
1993  $this->inBody(array(
1994  'name' => 'body',
1995  'type' => HTML5::STARTTAG,
1996  'attr' => array()
1997  ));
1998 
1999  /* Act as if a start tag token with the tag name "hr" had
2000  been seen. */
2001  $this->inBody(array(
2002  'name' => 'hr',
2003  'type' => HTML5::STARTTAG,
2004  'attr' => array()
2005  ));
2006 
2007  /* Act as if a start tag token with the tag name "p" had
2008  been seen. */
2009  $this->inBody(array(
2010  'name' => 'p',
2011  'type' => HTML5::STARTTAG,
2012  'attr' => array()
2013  ));
2014 
2015  /* Act as if a start tag token with the tag name "label"
2016  had been seen. */
2017  $this->inBody(array(
2018  'name' => 'label',
2019  'type' => HTML5::STARTTAG,
2020  'attr' => array()
2021  ));
2022 
2023  /* Act as if a stream of character tokens had been seen. */
2024  $this->insertText('This is a searchable index. '.
2025  'Insert your search keywords here: ');
2026 
2027  /* Act as if a start tag token with the tag name "input"
2028  had been seen, with all the attributes from the "isindex"
2029  token, except with the "name" attribute set to the value
2030  "isindex" (ignoring any explicit "name" attribute). */
2031  $attr = $token['attr'];
2032  $attr[] = array('name' => 'name', 'value' => 'isindex');
2033 
2034  $this->inBody(array(
2035  'name' => 'input',
2036  'type' => HTML5::STARTTAG,
2037  'attr' => $attr
2038  ));
2039 
2040  /* Act as if a stream of character tokens had been seen
2041  (see below for what they should say). */
2042  $this->insertText('This is a searchable index. '.
2043  'Insert your search keywords here: ');
2044 
2045  /* Act as if an end tag token with the tag name "label"
2046  had been seen. */
2047  $this->inBody(array(
2048  'name' => 'label',
2049  'type' => HTML5::ENDTAG
2050  ));
2051 
2052  /* Act as if an end tag token with the tag name "p" had
2053  been seen. */
2054  $this->inBody(array(
2055  'name' => 'p',
2056  'type' => HTML5::ENDTAG
2057  ));
2058 
2059  /* Act as if a start tag token with the tag name "hr" had
2060  been seen. */
2061  $this->inBody(array(
2062  'name' => 'hr',
2063  'type' => HTML5::ENDTAG
2064  ));
2065 
2066  /* Act as if an end tag token with the tag name "form" had
2067  been seen. */
2068  $this->inBody(array(
2069  'name' => 'form',
2070  'type' => HTML5::ENDTAG
2071  ));
2072  }
2073  break;
2074 
2075  /* A start tag whose tag name is "textarea" */
2076  case 'textarea':
2077  $this->insertElement($token);
2078 
2079  /* Switch the tokeniser's content model flag to the
2080  RCDATA state. */
2081  return HTML5::RCDATA;
2082  break;
2083 
2084  /* A start tag whose tag name is one of: "iframe", "noembed",
2085  "noframes" */
2086  case 'iframe': case 'noembed': case 'noframes':
2087  $this->insertElement($token);
2088 
2089  /* Switch the tokeniser's content model flag to the CDATA state. */
2090  return HTML5::CDATA;
2091  break;
2092 
2093  /* A start tag whose tag name is "select" */
2094  case 'select':
2095  /* Reconstruct the active formatting elements, if any. */
2097 
2098  /* Insert an HTML element for the token. */
2099  $this->insertElement($token);
2100 
2101  /* Change the insertion mode to "in select". */
2102  $this->mode = self::IN_SELECT;
2103  break;
2104 
2105  /* A start or end tag whose tag name is one of: "caption", "col",
2106  "colgroup", "frame", "frameset", "head", "option", "optgroup",
2107  "tbody", "td", "tfoot", "th", "thead", "tr". */
2108  case 'caption': case 'col': case 'colgroup': case 'frame':
2109  case 'frameset': case 'head': case 'option': case 'optgroup':
2110  case 'tbody': case 'td': case 'tfoot': case 'th': case 'thead':
2111  case 'tr':
2112  // Parse error. Ignore the token.
2113  break;
2114 
2115  /* A start or end tag whose tag name is one of: "event-source",
2116  "section", "nav", "article", "aside", "header", "footer",
2117  "datagrid", "command" */
2118  case 'event-source': case 'section': case 'nav': case 'article':
2119  case 'aside': case 'header': case 'footer': case 'datagrid':
2120  case 'command':
2121  // Work in progress!
2122  break;
2123 
2124  /* A start tag token not covered by the previous entries */
2125  default:
2126  /* Reconstruct the active formatting elements, if any. */
2128 
2129  $this->insertElement($token);
2130  break;
2131  }
2132  break;
2133 
2134  case HTML5::ENDTAG:
2135  switch($token['name']) {
2136  /* An end tag with the tag name "body" */
2137  case 'body':
2138  /* If the second element in the stack of open elements is
2139  not a body element, this is a parse error. Ignore the token.
2140  (innerHTML case) */
2141  if(count($this->stack) < 2 || $this->stack[1]->nodeName !== 'body') {
2142  // Ignore.
2143 
2144  /* If the current node is not the body element, then this
2145  is a parse error. */
2146  } elseif(end($this->stack)->nodeName !== 'body') {
2147  // Parse error.
2148  }
2149 
2150  /* Change the insertion mode to "after body". */
2151  $this->mode = self::AFTER_BODY;
2152  break;
2153 
2154  /* An end tag with the tag name "html" */
2155  case 'html':
2156  /* Act as if an end tag with tag name "body" had been seen,
2157  then, if that token wasn't ignored, reprocess the current
2158  token. */
2159  $this->inBody(array(
2160  'name' => 'body',
2161  'type' => HTML5::ENDTAG
2162  ));
2163 
2164  return $this->afterBody($token);
2165  break;
2166 
2167  /* An end tag whose tag name is one of: "address", "blockquote",
2168  "center", "dir", "div", "dl", "fieldset", "listing", "menu",
2169  "ol", "pre", "ul" */
2170  case 'address': case 'blockquote': case 'center': case 'dir':
2171  case 'div': case 'dl': case 'fieldset': case 'listing':
2172  case 'menu': case 'ol': case 'pre': case 'ul':
2173  /* If the stack of open elements has an element in scope
2174  with the same tag name as that of the token, then generate
2175  implied end tags. */
2176  if($this->elementInScope($token['name'])) {
2177  $this->generateImpliedEndTags();
2178 
2179  /* Now, if the current node is not an element with
2180  the same tag name as that of the token, then this
2181  is a parse error. */
2182  // w/e
2183 
2184  /* If the stack of open elements has an element in
2185  scope with the same tag name as that of the token,
2186  then pop elements from this stack until an element
2187  with that tag name has been popped from the stack. */
2188  for($n = count($this->stack) - 1; $n >= 0; $n--) {
2189  if($this->stack[$n]->nodeName === $token['name']) {
2190  $n = -1;
2191  }
2192 
2193  array_pop($this->stack);
2194  }
2195  }
2196  break;
2197 
2198  /* An end tag whose tag name is "form" */
2199  case 'form':
2200  /* If the stack of open elements has an element in scope
2201  with the same tag name as that of the token, then generate
2202  implied end tags. */
2203  if($this->elementInScope($token['name'])) {
2204  $this->generateImpliedEndTags();
2205 
2206  }
2207 
2208  if(end($this->stack)->nodeName !== $token['name']) {
2209  /* Now, if the current node is not an element with the
2210  same tag name as that of the token, then this is a parse
2211  error. */
2212  // w/e
2213 
2214  } else {
2215  /* Otherwise, if the current node is an element with
2216  the same tag name as that of the token pop that element
2217  from the stack. */
2218  array_pop($this->stack);
2219  }
2220 
2221  /* In any case, set the form element pointer to null. */
2222  $this->form_pointer = null;
2223  break;
2224 
2225  /* An end tag whose tag name is "p" */
2226  case 'p':
2227  /* If the stack of open elements has a p element in scope,
2228  then generate implied end tags, except for p elements. */
2229  if($this->elementInScope('p')) {
2230  $this->generateImpliedEndTags(array('p'));
2231 
2232  /* If the current node is not a p element, then this is
2233  a parse error. */
2234  // k
2235 
2236  /* If the stack of open elements has a p element in
2237  scope, then pop elements from this stack until the stack
2238  no longer has a p element in scope. */
2239  for($n = count($this->stack) - 1; $n >= 0; $n--) {
2240  if($this->elementInScope('p')) {
2241  array_pop($this->stack);
2242 
2243  } else {
2244  break;
2245  }
2246  }
2247  }
2248  break;
2249 
2250  /* An end tag whose tag name is "dd", "dt", or "li" */
2251  case 'dd': case 'dt': case 'li':
2252  /* If the stack of open elements has an element in scope
2253  whose tag name matches the tag name of the token, then
2254  generate implied end tags, except for elements with the
2255  same tag name as the token. */
2256  if($this->elementInScope($token['name'])) {
2257  $this->generateImpliedEndTags(array($token['name']));
2258 
2259  /* If the current node is not an element with the same
2260  tag name as the token, then this is a parse error. */
2261  // w/e
2262 
2263  /* If the stack of open elements has an element in scope
2264  whose tag name matches the tag name of the token, then
2265  pop elements from this stack until an element with that
2266  tag name has been popped from the stack. */
2267  for($n = count($this->stack) - 1; $n >= 0; $n--) {
2268  if($this->stack[$n]->nodeName === $token['name']) {
2269  $n = -1;
2270  }
2271 
2272  array_pop($this->stack);
2273  }
2274  }
2275  break;
2276 
2277  /* An end tag whose tag name is one of: "h1", "h2", "h3", "h4",
2278  "h5", "h6" */
2279  case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6':
2280  $elements = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6');
2281 
2282  /* If the stack of open elements has in scope an element whose
2283  tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then
2284  generate implied end tags. */
2285  if($this->elementInScope($elements)) {
2286  $this->generateImpliedEndTags();
2287 
2288  /* Now, if the current node is not an element with the same
2289  tag name as that of the token, then this is a parse error. */
2290  // w/e
2291 
2292  /* If the stack of open elements has in scope an element
2293  whose tag name is one of "h1", "h2", "h3", "h4", "h5", or
2294  "h6", then pop elements from the stack until an element
2295  with one of those tag names has been popped from the stack. */
2296  while($this->elementInScope($elements)) {
2297  array_pop($this->stack);
2298  }
2299  }
2300  break;
2301 
2302  /* An end tag whose tag name is one of: "a", "b", "big", "em",
2303  "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */
2304  case 'a': case 'b': case 'big': case 'em': case 'font':
2305  case 'i': case 'nobr': case 's': case 'small': case 'strike':
2306  case 'strong': case 'tt': case 'u':
2307  /* 1. Let the formatting element be the last element in
2308  the list of active formatting elements that:
2309  * is between the end of the list and the last scope
2310  marker in the list, if any, or the start of the list
2311  otherwise, and
2312  * has the same tag name as the token.
2313  */
2314  while(true) {
2315  for($a = count($this->a_formatting) - 1; $a >= 0; $a--) {
2316  if($this->a_formatting[$a] === self::MARKER) {
2317  break;
2318 
2319  } elseif($this->a_formatting[$a]->tagName === $token['name']) {
2320  $formatting_element = $this->a_formatting[$a];
2321  $in_stack = in_array($formatting_element, $this->stack, true);
2322  $fe_af_pos = $a;
2323  break;
2324  }
2325  }
2326 
2327  /* If there is no such node, or, if that node is
2328  also in the stack of open elements but the element
2329  is not in scope, then this is a parse error. Abort
2330  these steps. The token is ignored. */
2331  if(!isset($formatting_element) || ($in_stack &&
2332  !$this->elementInScope($token['name']))) {
2333  break;
2334 
2335  /* Otherwise, if there is such a node, but that node
2336  is not in the stack of open elements, then this is a
2337  parse error; remove the element from the list, and
2338  abort these steps. */
2339  } elseif(isset($formatting_element) && !$in_stack) {
2340  unset($this->a_formatting[$fe_af_pos]);
2341  $this->a_formatting = array_merge($this->a_formatting);
2342  break;
2343  }
2344 
2345  /* 2. Let the furthest block be the topmost node in the
2346  stack of open elements that is lower in the stack
2347  than the formatting element, and is not an element in
2348  the phrasing or formatting categories. There might
2349  not be one. */
2350  $fe_s_pos = array_search($formatting_element, $this->stack, true);
2351  $length = count($this->stack);
2352 
2353  for($s = $fe_s_pos + 1; $s < $length; $s++) {
2354  $category = $this->getElementCategory($this->stack[$s]->nodeName);
2355 
2356  if($category !== self::PHRASING && $category !== self::FORMATTING) {
2357  $furthest_block = $this->stack[$s];
2358  }
2359  }
2360 
2361  /* 3. If there is no furthest block, then the UA must
2362  skip the subsequent steps and instead just pop all
2363  the nodes from the bottom of the stack of open
2364  elements, from the current node up to the formatting
2365  element, and remove the formatting element from the
2366  list of active formatting elements. */
2367  if(!isset($furthest_block)) {
2368  for($n = $length - 1; $n >= $fe_s_pos; $n--) {
2369  array_pop($this->stack);
2370  }
2371 
2372  unset($this->a_formatting[$fe_af_pos]);
2373  $this->a_formatting = array_merge($this->a_formatting);
2374  break;
2375  }
2376 
2377  /* 4. Let the common ancestor be the element
2378  immediately above the formatting element in the stack
2379  of open elements. */
2380  $common_ancestor = $this->stack[$fe_s_pos - 1];
2381 
2382  /* 5. If the furthest block has a parent node, then
2383  remove the furthest block from its parent node. */
2384  if($furthest_block->parentNode !== null) {
2385  $furthest_block->parentNode->removeChild($furthest_block);
2386  }
2387 
2388  /* 6. Let a bookmark note the position of the
2389  formatting element in the list of active formatting
2390  elements relative to the elements on either side
2391  of it in the list. */
2392  $bookmark = $fe_af_pos;
2393 
2394  /* 7. Let node and last node be the furthest block.
2395  Follow these steps: */
2396  $node = $furthest_block;
2397  $last_node = $furthest_block;
2398 
2399  while(true) {
2400  for($n = array_search($node, $this->stack, true) - 1; $n >= 0; $n--) {
2401  /* 7.1 Let node be the element immediately
2402  prior to node in the stack of open elements. */
2403  $node = $this->stack[$n];
2404 
2405  /* 7.2 If node is not in the list of active
2406  formatting elements, then remove node from
2407  the stack of open elements and then go back
2408  to step 1. */
2409  if(!in_array($node, $this->a_formatting, true)) {
2410  unset($this->stack[$n]);
2411  $this->stack = array_merge($this->stack);
2412 
2413  } else {
2414  break;
2415  }
2416  }
2417 
2418  /* 7.3 Otherwise, if node is the formatting
2419  element, then go to the next step in the overall
2420  algorithm. */
2421  if($node === $formatting_element) {
2422  break;
2423 
2424  /* 7.4 Otherwise, if last node is the furthest
2425  block, then move the aforementioned bookmark to
2426  be immediately after the node in the list of
2427  active formatting elements. */
2428  } elseif($last_node === $furthest_block) {
2429  $bookmark = array_search($node, $this->a_formatting, true) + 1;
2430  }
2431 
2432  /* 7.5 If node has any children, perform a
2433  shallow clone of node, replace the entry for
2434  node in the list of active formatting elements
2435  with an entry for the clone, replace the entry
2436  for node in the stack of open elements with an
2437  entry for the clone, and let node be the clone. */
2438  if($node->hasChildNodes()) {
2439  $clone = $node->cloneNode();
2440  $s_pos = array_search($node, $this->stack, true);
2441  $a_pos = array_search($node, $this->a_formatting, true);
2442 
2443  $this->stack[$s_pos] = $clone;
2444  $this->a_formatting[$a_pos] = $clone;
2445  $node = $clone;
2446  }
2447 
2448  /* 7.6 Insert last node into node, first removing
2449  it from its previous parent node if any. */
2450  if($last_node->parentNode !== null) {
2451  $last_node->parentNode->removeChild($last_node);
2452  }
2453 
2454  $node->appendChild($last_node);
2455 
2456  /* 7.7 Let last node be node. */
2457  $last_node = $node;
2458  }
2459 
2460  /* 8. Insert whatever last node ended up being in
2461  the previous step into the common ancestor node,
2462  first removing it from its previous parent node if
2463  any. */
2464  if($last_node->parentNode !== null) {
2465  $last_node->parentNode->removeChild($last_node);
2466  }
2467 
2468  $common_ancestor->appendChild($last_node);
2469 
2470  /* 9. Perform a shallow clone of the formatting
2471  element. */
2472  $clone = $formatting_element->cloneNode();
2473 
2474  /* 10. Take all of the child nodes of the furthest
2475  block and append them to the clone created in the
2476  last step. */
2477  while($furthest_block->hasChildNodes()) {
2478  $child = $furthest_block->firstChild;
2479  $furthest_block->removeChild($child);
2480  $clone->appendChild($child);
2481  }
2482 
2483  /* 11. Append that clone to the furthest block. */
2484  $furthest_block->appendChild($clone);
2485 
2486  /* 12. Remove the formatting element from the list
2487  of active formatting elements, and insert the clone
2488  into the list of active formatting elements at the
2489  position of the aforementioned bookmark. */
2490  $fe_af_pos = array_search($formatting_element, $this->a_formatting, true);
2491  unset($this->a_formatting[$fe_af_pos]);
2492  $this->a_formatting = array_merge($this->a_formatting);
2493 
2494  $af_part1 = array_slice($this->a_formatting, 0, $bookmark - 1);
2495  $af_part2 = array_slice($this->a_formatting, $bookmark, count($this->a_formatting));
2496  $this->a_formatting = array_merge($af_part1, array($clone), $af_part2);
2497 
2498  /* 13. Remove the formatting element from the stack
2499  of open elements, and insert the clone into the stack
2500  of open elements immediately after (i.e. in a more
2501  deeply nested position than) the position of the
2502  furthest block in that stack. */
2503  $fe_s_pos = array_search($formatting_element, $this->stack, true);
2504  $fb_s_pos = array_search($furthest_block, $this->stack, true);
2505  unset($this->stack[$fe_s_pos]);
2506 
2507  $s_part1 = array_slice($this->stack, 0, $fb_s_pos);
2508  $s_part2 = array_slice($this->stack, $fb_s_pos + 1, count($this->stack));
2509  $this->stack = array_merge($s_part1, array($clone), $s_part2);
2510 
2511  /* 14. Jump back to step 1 in this series of steps. */
2512  unset($formatting_element, $fe_af_pos, $fe_s_pos, $furthest_block);
2513  }
2514  break;
2515 
2516  /* An end tag token whose tag name is one of: "button",
2517  "marquee", "object" */
2518  case 'button': case 'marquee': case 'object':
2519  /* If the stack of open elements has an element in scope whose
2520  tag name matches the tag name of the token, then generate implied
2521  tags. */
2522  if($this->elementInScope($token['name'])) {
2523  $this->generateImpliedEndTags();
2524 
2525  /* Now, if the current node is not an element with the same
2526  tag name as the token, then this is a parse error. */
2527  // k
2528 
2529  /* Now, if the stack of open elements has an element in scope
2530  whose tag name matches the tag name of the token, then pop
2531  elements from the stack until that element has been popped from
2532  the stack, and clear the list of active formatting elements up
2533  to the last marker. */
2534  for($n = count($this->stack) - 1; $n >= 0; $n--) {
2535  if($this->stack[$n]->nodeName === $token['name']) {
2536  $n = -1;
2537  }
2538 
2539  array_pop($this->stack);
2540  }
2541 
2542  $marker = end(array_keys($this->a_formatting, self::MARKER, true));
2543 
2544  for($n = count($this->a_formatting) - 1; $n > $marker; $n--) {
2545  array_pop($this->a_formatting);
2546  }
2547  }
2548  break;
2549 
2550  /* Or an end tag whose tag name is one of: "area", "basefont",
2551  "bgsound", "br", "embed", "hr", "iframe", "image", "img",
2552  "input", "isindex", "noembed", "noframes", "param", "select",
2553  "spacer", "table", "textarea", "wbr" */
2554  case 'area': case 'basefont': case 'bgsound': case 'br':
2555  case 'embed': case 'hr': case 'iframe': case 'image':
2556  case 'img': case 'input': case 'isindex': case 'noembed':
2557  case 'noframes': case 'param': case 'select': case 'spacer':
2558  case 'table': case 'textarea': case 'wbr':
2559  // Parse error. Ignore the token.
2560  break;
2561 
2562  /* An end tag token not covered by the previous entries */
2563  default:
2564  for($n = count($this->stack) - 1; $n >= 0; $n--) {
2565  /* Initialise node to be the current node (the bottommost
2566  node of the stack). */
2567  $node = end($this->stack);
2568 
2569  /* If node has the same tag name as the end tag token,
2570  then: */
2571  if($token['name'] === $node->nodeName) {
2572  /* Generate implied end tags. */
2573  $this->generateImpliedEndTags();
2574 
2575  /* If the tag name of the end tag token does not
2576  match the tag name of the current node, this is a
2577  parse error. */
2578  // k
2579 
2580  /* Pop all the nodes from the current node up to
2581  node, including node, then stop this algorithm. */
2582  for($x = count($this->stack) - $n; $x >= $n; $x--) {
2583  array_pop($this->stack);
2584  }
2585 
2586  } else {
2587  $category = $this->getElementCategory($node);
2588 
2589  if($category !== self::SPECIAL && $category !== self::SCOPING) {
2590  /* Otherwise, if node is in neither the formatting
2591  category nor the phrasing category, then this is a
2592  parse error. Stop this algorithm. The end tag token
2593  is ignored. */
2594  return false;
2595  }
2596  }
2597  }
2598  break;
2599  }
2600  break;
2601  }
2602  }
emitToken($token)
Definition: PH5P.php:1712
const RCDATA
Definition: PH5P.php:450
getElementCategory($node)
Definition: PH5P.php:4634
const COMMENT
Definition: PH5P.php:457
$x
Definition: example_009.php:98
afterBody($token)
Definition: PH5P.php:4201
const CDATA
Definition: PH5P.php:451
const PLAINTEXT
Definition: PH5P.php:452
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4619
elementInScope($el, $table=false)
Definition: PH5P.php:4465
$n
Definition: RandomTest.php:80
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
reconstructActiveFormattingElements()
Definition: PH5P.php:4525
+ Here is the call graph for this function:

◆ inBody() [2/2]

HTML5TreeConstructer::inBody (   $token)
private

Definition at line 2175 of file PH5P.php.

References $n, $x, array, HTML5\CDATA, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, HTML5\PLAINTEXT, HTML5\RCDATA, and HTML5\STARTTAG.

2176  {
2177  /* Handle the token as follows: */
2178 
2179  switch ($token['type']) {
2180  /* A character token */
2181  case HTML5::CHARACTR:
2182  /* Reconstruct the active formatting elements, if any. */
2184 
2185  /* Append the token's character to the current node. */
2186  $this->insertText($token['data']);
2187  break;
2188 
2189  /* A comment token */
2190  case HTML5::COMMENT:
2191  /* Append a Comment node to the current node with the data
2192  attribute set to the data given in the comment token. */
2193  $this->insertComment($token['data']);
2194  break;
2195 
2196  case HTML5::STARTTAG:
2197  switch ($token['name']) {
2198  /* A start tag token whose tag name is one of: "script",
2199  "style" */
2200  case 'script':
2201  case 'style':
2202  /* Process the token as if the insertion mode had been "in
2203  head". */
2204  return $this->inHead($token);
2205  break;
2206 
2207  /* A start tag token whose tag name is one of: "base", "link",
2208  "meta", "title" */
2209  case 'base':
2210  case 'link':
2211  case 'meta':
2212  case 'title':
2213  /* Parse error. Process the token as if the insertion mode
2214  had been "in head". */
2215  return $this->inHead($token);
2216  break;
2217 
2218  /* A start tag token with the tag name "body" */
2219  case 'body':
2220  /* Parse error. If the second element on the stack of open
2221  elements is not a body element, or, if the stack of open
2222  elements has only one node on it, then ignore the token.
2223  (innerHTML case) */
2224  if (count($this->stack) === 1 || $this->stack[1]->nodeName !== 'body') {
2225  // Ignore
2226 
2227  /* Otherwise, for each attribute on the token, check to see
2228  if the attribute is already present on the body element (the
2229  second element) on the stack of open elements. If it is not,
2230  add the attribute and its corresponding value to that
2231  element. */
2232  } else {
2233  foreach ($token['attr'] as $attr) {
2234  if (!$this->stack[1]->hasAttribute($attr['name'])) {
2235  $this->stack[1]->setAttribute($attr['name'], $attr['value']);
2236  }
2237  }
2238  }
2239  break;
2240 
2241  /* A start tag whose tag name is one of: "address",
2242  "blockquote", "center", "dir", "div", "dl", "fieldset",
2243  "listing", "menu", "ol", "p", "ul" */
2244  case 'address':
2245  case 'blockquote':
2246  case 'center':
2247  case 'dir':
2248  case 'div':
2249  case 'dl':
2250  case 'fieldset':
2251  case 'listing':
2252  case 'menu':
2253  case 'ol':
2254  case 'p':
2255  case 'ul':
2256  /* If the stack of open elements has a p element in scope,
2257  then act as if an end tag with the tag name p had been
2258  seen. */
2259  if ($this->elementInScope('p')) {
2260  $this->emitToken(
2261  array(
2262  'name' => 'p',
2263  'type' => HTML5::ENDTAG
2264  )
2265  );
2266  }
2267 
2268  /* Insert an HTML element for the token. */
2269  $this->insertElement($token);
2270  break;
2271 
2272  /* A start tag whose tag name is "form" */
2273  case 'form':
2274  /* If the form element pointer is not null, ignore the
2275  token with a parse error. */
2276  if ($this->form_pointer !== null) {
2277  // Ignore.
2278 
2279  /* Otherwise: */
2280  } else {
2281  /* If the stack of open elements has a p element in
2282  scope, then act as if an end tag with the tag name p
2283  had been seen. */
2284  if ($this->elementInScope('p')) {
2285  $this->emitToken(
2286  array(
2287  'name' => 'p',
2288  'type' => HTML5::ENDTAG
2289  )
2290  );
2291  }
2292 
2293  /* Insert an HTML element for the token, and set the
2294  form element pointer to point to the element created. */
2295  $element = $this->insertElement($token);
2296  $this->form_pointer = $element;
2297  }
2298  break;
2299 
2300  /* A start tag whose tag name is "li", "dd" or "dt" */
2301  case 'li':
2302  case 'dd':
2303  case 'dt':
2304  /* If the stack of open elements has a p element in scope,
2305  then act as if an end tag with the tag name p had been
2306  seen. */
2307  if ($this->elementInScope('p')) {
2308  $this->emitToken(
2309  array(
2310  'name' => 'p',
2311  'type' => HTML5::ENDTAG
2312  )
2313  );
2314  }
2315 
2316  $stack_length = count($this->stack) - 1;
2317 
2318  for ($n = $stack_length; 0 <= $n; $n--) {
2319  /* 1. Initialise node to be the current node (the
2320  bottommost node of the stack). */
2321  $stop = false;
2322  $node = $this->stack[$n];
2323  $cat = $this->getElementCategory($node->tagName);
2324 
2325  /* 2. If node is an li, dd or dt element, then pop all
2326  the nodes from the current node up to node, including
2327  node, then stop this algorithm. */
2328  if ($token['name'] === $node->tagName || ($token['name'] !== 'li'
2329  && ($node->tagName === 'dd' || $node->tagName === 'dt'))
2330  ) {
2331  for ($x = $stack_length; $x >= $n; $x--) {
2332  array_pop($this->stack);
2333  }
2334 
2335  break;
2336  }
2337 
2338  /* 3. If node is not in the formatting category, and is
2339  not in the phrasing category, and is not an address or
2340  div element, then stop this algorithm. */
2341  if ($cat !== self::FORMATTING && $cat !== self::PHRASING &&
2342  $node->tagName !== 'address' && $node->tagName !== 'div'
2343  ) {
2344  break;
2345  }
2346  }
2347 
2348  /* Finally, insert an HTML element with the same tag
2349  name as the token's. */
2350  $this->insertElement($token);
2351  break;
2352 
2353  /* A start tag token whose tag name is "plaintext" */
2354  case 'plaintext':
2355  /* If the stack of open elements has a p element in scope,
2356  then act as if an end tag with the tag name p had been
2357  seen. */
2358  if ($this->elementInScope('p')) {
2359  $this->emitToken(
2360  array(
2361  'name' => 'p',
2362  'type' => HTML5::ENDTAG
2363  )
2364  );
2365  }
2366 
2367  /* Insert an HTML element for the token. */
2368  $this->insertElement($token);
2369 
2370  return HTML5::PLAINTEXT;
2371  break;
2372 
2373  /* A start tag whose tag name is one of: "h1", "h2", "h3", "h4",
2374  "h5", "h6" */
2375  case 'h1':
2376  case 'h2':
2377  case 'h3':
2378  case 'h4':
2379  case 'h5':
2380  case 'h6':
2381  /* If the stack of open elements has a p element in scope,
2382  then act as if an end tag with the tag name p had been seen. */
2383  if ($this->elementInScope('p')) {
2384  $this->emitToken(
2385  array(
2386  'name' => 'p',
2387  'type' => HTML5::ENDTAG
2388  )
2389  );
2390  }
2391 
2392  /* If the stack of open elements has in scope an element whose
2393  tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then
2394  this is a parse error; pop elements from the stack until an
2395  element with one of those tag names has been popped from the
2396  stack. */
2397  while ($this->elementInScope(array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) {
2398  array_pop($this->stack);
2399  }
2400 
2401  /* Insert an HTML element for the token. */
2402  $this->insertElement($token);
2403  break;
2404 
2405  /* A start tag whose tag name is "a" */
2406  case 'a':
2407  /* If the list of active formatting elements contains
2408  an element whose tag name is "a" between the end of the
2409  list and the last marker on the list (or the start of
2410  the list if there is no marker on the list), then this
2411  is a parse error; act as if an end tag with the tag name
2412  "a" had been seen, then remove that element from the list
2413  of active formatting elements and the stack of open
2414  elements if the end tag didn't already remove it (it
2415  might not have if the element is not in table scope). */
2416  $leng = count($this->a_formatting);
2417 
2418  for ($n = $leng - 1; $n >= 0; $n--) {
2419  if ($this->a_formatting[$n] === self::MARKER) {
2420  break;
2421 
2422  } elseif ($this->a_formatting[$n]->nodeName === 'a') {
2423  $this->emitToken(
2424  array(
2425  'name' => 'a',
2426  'type' => HTML5::ENDTAG
2427  )
2428  );
2429  break;
2430  }
2431  }
2432 
2433  /* Reconstruct the active formatting elements, if any. */
2435 
2436  /* Insert an HTML element for the token. */
2437  $el = $this->insertElement($token);
2438 
2439  /* Add that element to the list of active formatting
2440  elements. */
2441  $this->a_formatting[] = $el;
2442  break;
2443 
2444  /* A start tag whose tag name is one of: "b", "big", "em", "font",
2445  "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */
2446  case 'b':
2447  case 'big':
2448  case 'em':
2449  case 'font':
2450  case 'i':
2451  case 'nobr':
2452  case 's':
2453  case 'small':
2454  case 'strike':
2455  case 'strong':
2456  case 'tt':
2457  case 'u':
2458  /* Reconstruct the active formatting elements, if any. */
2460 
2461  /* Insert an HTML element for the token. */
2462  $el = $this->insertElement($token);
2463 
2464  /* Add that element to the list of active formatting
2465  elements. */
2466  $this->a_formatting[] = $el;
2467  break;
2468 
2469  /* A start tag token whose tag name is "button" */
2470  case 'button':
2471  /* If the stack of open elements has a button element in scope,
2472  then this is a parse error; act as if an end tag with the tag
2473  name "button" had been seen, then reprocess the token. (We don't
2474  do that. Unnecessary.) */
2475  if ($this->elementInScope('button')) {
2476  $this->inBody(
2477  array(
2478  'name' => 'button',
2479  'type' => HTML5::ENDTAG
2480  )
2481  );
2482  }
2483 
2484  /* Reconstruct the active formatting elements, if any. */
2486 
2487  /* Insert an HTML element for the token. */
2488  $this->insertElement($token);
2489 
2490  /* Insert a marker at the end of the list of active
2491  formatting elements. */
2492  $this->a_formatting[] = self::MARKER;
2493  break;
2494 
2495  /* A start tag token whose tag name is one of: "marquee", "object" */
2496  case 'marquee':
2497  case 'object':
2498  /* Reconstruct the active formatting elements, if any. */
2500 
2501  /* Insert an HTML element for the token. */
2502  $this->insertElement($token);
2503 
2504  /* Insert a marker at the end of the list of active
2505  formatting elements. */
2506  $this->a_formatting[] = self::MARKER;
2507  break;
2508 
2509  /* A start tag token whose tag name is "xmp" */
2510  case 'xmp':
2511  /* Reconstruct the active formatting elements, if any. */
2513 
2514  /* Insert an HTML element for the token. */
2515  $this->insertElement($token);
2516 
2517  /* Switch the content model flag to the CDATA state. */
2518  return HTML5::CDATA;
2519  break;
2520 
2521  /* A start tag whose tag name is "table" */
2522  case 'table':
2523  /* If the stack of open elements has a p element in scope,
2524  then act as if an end tag with the tag name p had been seen. */
2525  if ($this->elementInScope('p')) {
2526  $this->emitToken(
2527  array(
2528  'name' => 'p',
2529  'type' => HTML5::ENDTAG
2530  )
2531  );
2532  }
2533 
2534  /* Insert an HTML element for the token. */
2535  $this->insertElement($token);
2536 
2537  /* Change the insertion mode to "in table". */
2538  $this->mode = self::IN_TABLE;
2539  break;
2540 
2541  /* A start tag whose tag name is one of: "area", "basefont",
2542  "bgsound", "br", "embed", "img", "param", "spacer", "wbr" */
2543  case 'area':
2544  case 'basefont':
2545  case 'bgsound':
2546  case 'br':
2547  case 'embed':
2548  case 'img':
2549  case 'param':
2550  case 'spacer':
2551  case 'wbr':
2552  /* Reconstruct the active formatting elements, if any. */
2554 
2555  /* Insert an HTML element for the token. */
2556  $this->insertElement($token);
2557 
2558  /* Immediately pop the current node off the stack of open elements. */
2559  array_pop($this->stack);
2560  break;
2561 
2562  /* A start tag whose tag name is "hr" */
2563  case 'hr':
2564  /* If the stack of open elements has a p element in scope,
2565  then act as if an end tag with the tag name p had been seen. */
2566  if ($this->elementInScope('p')) {
2567  $this->emitToken(
2568  array(
2569  'name' => 'p',
2570  'type' => HTML5::ENDTAG
2571  )
2572  );
2573  }
2574 
2575  /* Insert an HTML element for the token. */
2576  $this->insertElement($token);
2577 
2578  /* Immediately pop the current node off the stack of open elements. */
2579  array_pop($this->stack);
2580  break;
2581 
2582  /* A start tag whose tag name is "image" */
2583  case 'image':
2584  /* Parse error. Change the token's tag name to "img" and
2585  reprocess it. (Don't ask.) */
2586  $token['name'] = 'img';
2587  return $this->inBody($token);
2588  break;
2589 
2590  /* A start tag whose tag name is "input" */
2591  case 'input':
2592  /* Reconstruct the active formatting elements, if any. */
2594 
2595  /* Insert an input element for the token. */
2596  $element = $this->insertElement($token, false);
2597 
2598  /* If the form element pointer is not null, then associate the
2599  input element with the form element pointed to by the form
2600  element pointer. */
2601  $this->form_pointer !== null
2602  ? $this->form_pointer->appendChild($element)
2603  : end($this->stack)->appendChild($element);
2604 
2605  /* Pop that input element off the stack of open elements. */
2606  array_pop($this->stack);
2607  break;
2608 
2609  /* A start tag whose tag name is "isindex" */
2610  case 'isindex':
2611  /* Parse error. */
2612  // w/e
2613 
2614  /* If the form element pointer is not null,
2615  then ignore the token. */
2616  if ($this->form_pointer === null) {
2617  /* Act as if a start tag token with the tag name "form" had
2618  been seen. */
2619  $this->inBody(
2620  array(
2621  'name' => 'body',
2622  'type' => HTML5::STARTTAG,
2623  'attr' => array()
2624  )
2625  );
2626 
2627  /* Act as if a start tag token with the tag name "hr" had
2628  been seen. */
2629  $this->inBody(
2630  array(
2631  'name' => 'hr',
2632  'type' => HTML5::STARTTAG,
2633  'attr' => array()
2634  )
2635  );
2636 
2637  /* Act as if a start tag token with the tag name "p" had
2638  been seen. */
2639  $this->inBody(
2640  array(
2641  'name' => 'p',
2642  'type' => HTML5::STARTTAG,
2643  'attr' => array()
2644  )
2645  );
2646 
2647  /* Act as if a start tag token with the tag name "label"
2648  had been seen. */
2649  $this->inBody(
2650  array(
2651  'name' => 'label',
2652  'type' => HTML5::STARTTAG,
2653  'attr' => array()
2654  )
2655  );
2656 
2657  /* Act as if a stream of character tokens had been seen. */
2658  $this->insertText(
2659  'This is a searchable index. ' .
2660  'Insert your search keywords here: '
2661  );
2662 
2663  /* Act as if a start tag token with the tag name "input"
2664  had been seen, with all the attributes from the "isindex"
2665  token, except with the "name" attribute set to the value
2666  "isindex" (ignoring any explicit "name" attribute). */
2667  $attr = $token['attr'];
2668  $attr[] = array('name' => 'name', 'value' => 'isindex');
2669 
2670  $this->inBody(
2671  array(
2672  'name' => 'input',
2673  'type' => HTML5::STARTTAG,
2674  'attr' => $attr
2675  )
2676  );
2677 
2678  /* Act as if a stream of character tokens had been seen
2679  (see below for what they should say). */
2680  $this->insertText(
2681  'This is a searchable index. ' .
2682  'Insert your search keywords here: '
2683  );
2684 
2685  /* Act as if an end tag token with the tag name "label"
2686  had been seen. */
2687  $this->inBody(
2688  array(
2689  'name' => 'label',
2690  'type' => HTML5::ENDTAG
2691  )
2692  );
2693 
2694  /* Act as if an end tag token with the tag name "p" had
2695  been seen. */
2696  $this->inBody(
2697  array(
2698  'name' => 'p',
2699  'type' => HTML5::ENDTAG
2700  )
2701  );
2702 
2703  /* Act as if a start tag token with the tag name "hr" had
2704  been seen. */
2705  $this->inBody(
2706  array(
2707  'name' => 'hr',
2708  'type' => HTML5::ENDTAG
2709  )
2710  );
2711 
2712  /* Act as if an end tag token with the tag name "form" had
2713  been seen. */
2714  $this->inBody(
2715  array(
2716  'name' => 'form',
2717  'type' => HTML5::ENDTAG
2718  )
2719  );
2720  }
2721  break;
2722 
2723  /* A start tag whose tag name is "textarea" */
2724  case 'textarea':
2725  $this->insertElement($token);
2726 
2727  /* Switch the tokeniser's content model flag to the
2728  RCDATA state. */
2729  return HTML5::RCDATA;
2730  break;
2731 
2732  /* A start tag whose tag name is one of: "iframe", "noembed",
2733  "noframes" */
2734  case 'iframe':
2735  case 'noembed':
2736  case 'noframes':
2737  $this->insertElement($token);
2738 
2739  /* Switch the tokeniser's content model flag to the CDATA state. */
2740  return HTML5::CDATA;
2741  break;
2742 
2743  /* A start tag whose tag name is "select" */
2744  case 'select':
2745  /* Reconstruct the active formatting elements, if any. */
2747 
2748  /* Insert an HTML element for the token. */
2749  $this->insertElement($token);
2750 
2751  /* Change the insertion mode to "in select". */
2752  $this->mode = self::IN_SELECT;
2753  break;
2754 
2755  /* A start or end tag whose tag name is one of: "caption", "col",
2756  "colgroup", "frame", "frameset", "head", "option", "optgroup",
2757  "tbody", "td", "tfoot", "th", "thead", "tr". */
2758  case 'caption':
2759  case 'col':
2760  case 'colgroup':
2761  case 'frame':
2762  case 'frameset':
2763  case 'head':
2764  case 'option':
2765  case 'optgroup':
2766  case 'tbody':
2767  case 'td':
2768  case 'tfoot':
2769  case 'th':
2770  case 'thead':
2771  case 'tr':
2772  // Parse error. Ignore the token.
2773  break;
2774 
2775  /* A start or end tag whose tag name is one of: "event-source",
2776  "section", "nav", "article", "aside", "header", "footer",
2777  "datagrid", "command" */
2778  case 'event-source':
2779  case 'section':
2780  case 'nav':
2781  case 'article':
2782  case 'aside':
2783  case 'header':
2784  case 'footer':
2785  case 'datagrid':
2786  case 'command':
2787  // Work in progress!
2788  break;
2789 
2790  /* A start tag token not covered by the previous entries */
2791  default:
2792  /* Reconstruct the active formatting elements, if any. */
2794 
2795  $this->insertElement($token, true, true);
2796  break;
2797  }
2798  break;
2799 
2800  case HTML5::ENDTAG:
2801  switch ($token['name']) {
2802  /* An end tag with the tag name "body" */
2803  case 'body':
2804  /* If the second element in the stack of open elements is
2805  not a body element, this is a parse error. Ignore the token.
2806  (innerHTML case) */
2807  if (count($this->stack) < 2 || $this->stack[1]->nodeName !== 'body') {
2808  // Ignore.
2809 
2810  /* If the current node is not the body element, then this
2811  is a parse error. */
2812  } elseif (end($this->stack)->nodeName !== 'body') {
2813  // Parse error.
2814  }
2815 
2816  /* Change the insertion mode to "after body". */
2817  $this->mode = self::AFTER_BODY;
2818  break;
2819 
2820  /* An end tag with the tag name "html" */
2821  case 'html':
2822  /* Act as if an end tag with tag name "body" had been seen,
2823  then, if that token wasn't ignored, reprocess the current
2824  token. */
2825  $this->inBody(
2826  array(
2827  'name' => 'body',
2828  'type' => HTML5::ENDTAG
2829  )
2830  );
2831 
2832  return $this->afterBody($token);
2833  break;
2834 
2835  /* An end tag whose tag name is one of: "address", "blockquote",
2836  "center", "dir", "div", "dl", "fieldset", "listing", "menu",
2837  "ol", "pre", "ul" */
2838  case 'address':
2839  case 'blockquote':
2840  case 'center':
2841  case 'dir':
2842  case 'div':
2843  case 'dl':
2844  case 'fieldset':
2845  case 'listing':
2846  case 'menu':
2847  case 'ol':
2848  case 'pre':
2849  case 'ul':
2850  /* If the stack of open elements has an element in scope
2851  with the same tag name as that of the token, then generate
2852  implied end tags. */
2853  if ($this->elementInScope($token['name'])) {
2854  $this->generateImpliedEndTags();
2855 
2856  /* Now, if the current node is not an element with
2857  the same tag name as that of the token, then this
2858  is a parse error. */
2859  // w/e
2860 
2861  /* If the stack of open elements has an element in
2862  scope with the same tag name as that of the token,
2863  then pop elements from this stack until an element
2864  with that tag name has been popped from the stack. */
2865  for ($n = count($this->stack) - 1; $n >= 0; $n--) {
2866  if ($this->stack[$n]->nodeName === $token['name']) {
2867  $n = -1;
2868  }
2869 
2870  array_pop($this->stack);
2871  }
2872  }
2873  break;
2874 
2875  /* An end tag whose tag name is "form" */
2876  case 'form':
2877  /* If the stack of open elements has an element in scope
2878  with the same tag name as that of the token, then generate
2879  implied end tags. */
2880  if ($this->elementInScope($token['name'])) {
2881  $this->generateImpliedEndTags();
2882 
2883  }
2884 
2885  if (end($this->stack)->nodeName !== $token['name']) {
2886  /* Now, if the current node is not an element with the
2887  same tag name as that of the token, then this is a parse
2888  error. */
2889  // w/e
2890 
2891  } else {
2892  /* Otherwise, if the current node is an element with
2893  the same tag name as that of the token pop that element
2894  from the stack. */
2895  array_pop($this->stack);
2896  }
2897 
2898  /* In any case, set the form element pointer to null. */
2899  $this->form_pointer = null;
2900  break;
2901 
2902  /* An end tag whose tag name is "p" */
2903  case 'p':
2904  /* If the stack of open elements has a p element in scope,
2905  then generate implied end tags, except for p elements. */
2906  if ($this->elementInScope('p')) {
2907  $this->generateImpliedEndTags(array('p'));
2908 
2909  /* If the current node is not a p element, then this is
2910  a parse error. */
2911  // k
2912 
2913  /* If the stack of open elements has a p element in
2914  scope, then pop elements from this stack until the stack
2915  no longer has a p element in scope. */
2916  for ($n = count($this->stack) - 1; $n >= 0; $n--) {
2917  if ($this->elementInScope('p')) {
2918  array_pop($this->stack);
2919 
2920  } else {
2921  break;
2922  }
2923  }
2924  }
2925  break;
2926 
2927  /* An end tag whose tag name is "dd", "dt", or "li" */
2928  case 'dd':
2929  case 'dt':
2930  case 'li':
2931  /* If the stack of open elements has an element in scope
2932  whose tag name matches the tag name of the token, then
2933  generate implied end tags, except for elements with the
2934  same tag name as the token. */
2935  if ($this->elementInScope($token['name'])) {
2936  $this->generateImpliedEndTags(array($token['name']));
2937 
2938  /* If the current node is not an element with the same
2939  tag name as the token, then this is a parse error. */
2940  // w/e
2941 
2942  /* If the stack of open elements has an element in scope
2943  whose tag name matches the tag name of the token, then
2944  pop elements from this stack until an element with that
2945  tag name has been popped from the stack. */
2946  for ($n = count($this->stack) - 1; $n >= 0; $n--) {
2947  if ($this->stack[$n]->nodeName === $token['name']) {
2948  $n = -1;
2949  }
2950 
2951  array_pop($this->stack);
2952  }
2953  }
2954  break;
2955 
2956  /* An end tag whose tag name is one of: "h1", "h2", "h3", "h4",
2957  "h5", "h6" */
2958  case 'h1':
2959  case 'h2':
2960  case 'h3':
2961  case 'h4':
2962  case 'h5':
2963  case 'h6':
2964  $elements = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6');
2965 
2966  /* If the stack of open elements has in scope an element whose
2967  tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then
2968  generate implied end tags. */
2969  if ($this->elementInScope($elements)) {
2970  $this->generateImpliedEndTags();
2971 
2972  /* Now, if the current node is not an element with the same
2973  tag name as that of the token, then this is a parse error. */
2974  // w/e
2975 
2976  /* If the stack of open elements has in scope an element
2977  whose tag name is one of "h1", "h2", "h3", "h4", "h5", or
2978  "h6", then pop elements from the stack until an element
2979  with one of those tag names has been popped from the stack. */
2980  while ($this->elementInScope($elements)) {
2981  array_pop($this->stack);
2982  }
2983  }
2984  break;
2985 
2986  /* An end tag whose tag name is one of: "a", "b", "big", "em",
2987  "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */
2988  case 'a':
2989  case 'b':
2990  case 'big':
2991  case 'em':
2992  case 'font':
2993  case 'i':
2994  case 'nobr':
2995  case 's':
2996  case 'small':
2997  case 'strike':
2998  case 'strong':
2999  case 'tt':
3000  case 'u':
3001  /* 1. Let the formatting element be the last element in
3002  the list of active formatting elements that:
3003  * is between the end of the list and the last scope
3004  marker in the list, if any, or the start of the list
3005  otherwise, and
3006  * has the same tag name as the token.
3007  */
3008  while (true) {
3009  for ($a = count($this->a_formatting) - 1; $a >= 0; $a--) {
3010  if ($this->a_formatting[$a] === self::MARKER) {
3011  break;
3012 
3013  } elseif ($this->a_formatting[$a]->tagName === $token['name']) {
3014  $formatting_element = $this->a_formatting[$a];
3015  $in_stack = in_array($formatting_element, $this->stack, true);
3016  $fe_af_pos = $a;
3017  break;
3018  }
3019  }
3020 
3021  /* If there is no such node, or, if that node is
3022  also in the stack of open elements but the element
3023  is not in scope, then this is a parse error. Abort
3024  these steps. The token is ignored. */
3025  if (!isset($formatting_element) || ($in_stack &&
3026  !$this->elementInScope($token['name']))
3027  ) {
3028  break;
3029 
3030  /* Otherwise, if there is such a node, but that node
3031  is not in the stack of open elements, then this is a
3032  parse error; remove the element from the list, and
3033  abort these steps. */
3034  } elseif (isset($formatting_element) && !$in_stack) {
3035  unset($this->a_formatting[$fe_af_pos]);
3036  $this->a_formatting = array_merge($this->a_formatting);
3037  break;
3038  }
3039 
3040  /* 2. Let the furthest block be the topmost node in the
3041  stack of open elements that is lower in the stack
3042  than the formatting element, and is not an element in
3043  the phrasing or formatting categories. There might
3044  not be one. */
3045  $fe_s_pos = array_search($formatting_element, $this->stack, true);
3046  $length = count($this->stack);
3047 
3048  for ($s = $fe_s_pos + 1; $s < $length; $s++) {
3049  $category = $this->getElementCategory($this->stack[$s]->nodeName);
3050 
3051  if ($category !== self::PHRASING && $category !== self::FORMATTING) {
3052  $furthest_block = $this->stack[$s];
3053  }
3054  }
3055 
3056  /* 3. If there is no furthest block, then the UA must
3057  skip the subsequent steps and instead just pop all
3058  the nodes from the bottom of the stack of open
3059  elements, from the current node up to the formatting
3060  element, and remove the formatting element from the
3061  list of active formatting elements. */
3062  if (!isset($furthest_block)) {
3063  for ($n = $length - 1; $n >= $fe_s_pos; $n--) {
3064  array_pop($this->stack);
3065  }
3066 
3067  unset($this->a_formatting[$fe_af_pos]);
3068  $this->a_formatting = array_merge($this->a_formatting);
3069  break;
3070  }
3071 
3072  /* 4. Let the common ancestor be the element
3073  immediately above the formatting element in the stack
3074  of open elements. */
3075  $common_ancestor = $this->stack[$fe_s_pos - 1];
3076 
3077  /* 5. If the furthest block has a parent node, then
3078  remove the furthest block from its parent node. */
3079  if ($furthest_block->parentNode !== null) {
3080  $furthest_block->parentNode->removeChild($furthest_block);
3081  }
3082 
3083  /* 6. Let a bookmark note the position of the
3084  formatting element in the list of active formatting
3085  elements relative to the elements on either side
3086  of it in the list. */
3087  $bookmark = $fe_af_pos;
3088 
3089  /* 7. Let node and last node be the furthest block.
3090  Follow these steps: */
3091  $node = $furthest_block;
3092  $last_node = $furthest_block;
3093 
3094  while (true) {
3095  for ($n = array_search($node, $this->stack, true) - 1; $n >= 0; $n--) {
3096  /* 7.1 Let node be the element immediately
3097  prior to node in the stack of open elements. */
3098  $node = $this->stack[$n];
3099 
3100  /* 7.2 If node is not in the list of active
3101  formatting elements, then remove node from
3102  the stack of open elements and then go back
3103  to step 1. */
3104  if (!in_array($node, $this->a_formatting, true)) {
3105  unset($this->stack[$n]);
3106  $this->stack = array_merge($this->stack);
3107 
3108  } else {
3109  break;
3110  }
3111  }
3112 
3113  /* 7.3 Otherwise, if node is the formatting
3114  element, then go to the next step in the overall
3115  algorithm. */
3116  if ($node === $formatting_element) {
3117  break;
3118 
3119  /* 7.4 Otherwise, if last node is the furthest
3120  block, then move the aforementioned bookmark to
3121  be immediately after the node in the list of
3122  active formatting elements. */
3123  } elseif ($last_node === $furthest_block) {
3124  $bookmark = array_search($node, $this->a_formatting, true) + 1;
3125  }
3126 
3127  /* 7.5 If node has any children, perform a
3128  shallow clone of node, replace the entry for
3129  node in the list of active formatting elements
3130  with an entry for the clone, replace the entry
3131  for node in the stack of open elements with an
3132  entry for the clone, and let node be the clone. */
3133  if ($node->hasChildNodes()) {
3134  $clone = $node->cloneNode();
3135  $s_pos = array_search($node, $this->stack, true);
3136  $a_pos = array_search($node, $this->a_formatting, true);
3137 
3138  $this->stack[$s_pos] = $clone;
3139  $this->a_formatting[$a_pos] = $clone;
3140  $node = $clone;
3141  }
3142 
3143  /* 7.6 Insert last node into node, first removing
3144  it from its previous parent node if any. */
3145  if ($last_node->parentNode !== null) {
3146  $last_node->parentNode->removeChild($last_node);
3147  }
3148 
3149  $node->appendChild($last_node);
3150 
3151  /* 7.7 Let last node be node. */
3152  $last_node = $node;
3153  }
3154 
3155  /* 8. Insert whatever last node ended up being in
3156  the previous step into the common ancestor node,
3157  first removing it from its previous parent node if
3158  any. */
3159  if ($last_node->parentNode !== null) {
3160  $last_node->parentNode->removeChild($last_node);
3161  }
3162 
3163  $common_ancestor->appendChild($last_node);
3164 
3165  /* 9. Perform a shallow clone of the formatting
3166  element. */
3167  $clone = $formatting_element->cloneNode();
3168 
3169  /* 10. Take all of the child nodes of the furthest
3170  block and append them to the clone created in the
3171  last step. */
3172  while ($furthest_block->hasChildNodes()) {
3173  $child = $furthest_block->firstChild;
3174  $furthest_block->removeChild($child);
3175  $clone->appendChild($child);
3176  }
3177 
3178  /* 11. Append that clone to the furthest block. */
3179  $furthest_block->appendChild($clone);
3180 
3181  /* 12. Remove the formatting element from the list
3182  of active formatting elements, and insert the clone
3183  into the list of active formatting elements at the
3184  position of the aforementioned bookmark. */
3185  $fe_af_pos = array_search($formatting_element, $this->a_formatting, true);
3186  unset($this->a_formatting[$fe_af_pos]);
3187  $this->a_formatting = array_merge($this->a_formatting);
3188 
3189  $af_part1 = array_slice($this->a_formatting, 0, $bookmark - 1);
3190  $af_part2 = array_slice($this->a_formatting, $bookmark, count($this->a_formatting));
3191  $this->a_formatting = array_merge($af_part1, array($clone), $af_part2);
3192 
3193  /* 13. Remove the formatting element from the stack
3194  of open elements, and insert the clone into the stack
3195  of open elements immediately after (i.e. in a more
3196  deeply nested position than) the position of the
3197  furthest block in that stack. */
3198  $fe_s_pos = array_search($formatting_element, $this->stack, true);
3199  $fb_s_pos = array_search($furthest_block, $this->stack, true);
3200  unset($this->stack[$fe_s_pos]);
3201 
3202  $s_part1 = array_slice($this->stack, 0, $fb_s_pos);
3203  $s_part2 = array_slice($this->stack, $fb_s_pos + 1, count($this->stack));
3204  $this->stack = array_merge($s_part1, array($clone), $s_part2);
3205 
3206  /* 14. Jump back to step 1 in this series of steps. */
3207  unset($formatting_element, $fe_af_pos, $fe_s_pos, $furthest_block);
3208  }
3209  break;
3210 
3211  /* An end tag token whose tag name is one of: "button",
3212  "marquee", "object" */
3213  case 'button':
3214  case 'marquee':
3215  case 'object':
3216  /* If the stack of open elements has an element in scope whose
3217  tag name matches the tag name of the token, then generate implied
3218  tags. */
3219  if ($this->elementInScope($token['name'])) {
3220  $this->generateImpliedEndTags();
3221 
3222  /* Now, if the current node is not an element with the same
3223  tag name as the token, then this is a parse error. */
3224  // k
3225 
3226  /* Now, if the stack of open elements has an element in scope
3227  whose tag name matches the tag name of the token, then pop
3228  elements from the stack until that element has been popped from
3229  the stack, and clear the list of active formatting elements up
3230  to the last marker. */
3231  for ($n = count($this->stack) - 1; $n >= 0; $n--) {
3232  if ($this->stack[$n]->nodeName === $token['name']) {
3233  $n = -1;
3234  }
3235 
3236  array_pop($this->stack);
3237  }
3238 
3239  $marker = end(array_keys($this->a_formatting, self::MARKER, true));
3240 
3241  for ($n = count($this->a_formatting) - 1; $n > $marker; $n--) {
3242  array_pop($this->a_formatting);
3243  }
3244  }
3245  break;
3246 
3247  /* Or an end tag whose tag name is one of: "area", "basefont",
3248  "bgsound", "br", "embed", "hr", "iframe", "image", "img",
3249  "input", "isindex", "noembed", "noframes", "param", "select",
3250  "spacer", "table", "textarea", "wbr" */
3251  case 'area':
3252  case 'basefont':
3253  case 'bgsound':
3254  case 'br':
3255  case 'embed':
3256  case 'hr':
3257  case 'iframe':
3258  case 'image':
3259  case 'img':
3260  case 'input':
3261  case 'isindex':
3262  case 'noembed':
3263  case 'noframes':
3264  case 'param':
3265  case 'select':
3266  case 'spacer':
3267  case 'table':
3268  case 'textarea':
3269  case 'wbr':
3270  // Parse error. Ignore the token.
3271  break;
3272 
3273  /* An end tag token not covered by the previous entries */
3274  default:
3275  for ($n = count($this->stack) - 1; $n >= 0; $n--) {
3276  /* Initialise node to be the current node (the bottommost
3277  node of the stack). */
3278  $node = end($this->stack);
3279 
3280  /* If node has the same tag name as the end tag token,
3281  then: */
3282  if ($token['name'] === $node->nodeName) {
3283  /* Generate implied end tags. */
3284  $this->generateImpliedEndTags();
3285 
3286  /* If the tag name of the end tag token does not
3287  match the tag name of the current node, this is a
3288  parse error. */
3289  // k
3290 
3291  /* Pop all the nodes from the current node up to
3292  node, including node, then stop this algorithm. */
3293  for ($x = count($this->stack) - $n; $x >= $n; $x--) {
3294  array_pop($this->stack);
3295  }
3296 
3297  } else {
3298  $category = $this->getElementCategory($node);
3299 
3300  if ($category !== self::SPECIAL && $category !== self::SCOPING) {
3301  /* Otherwise, if node is in neither the formatting
3302  category nor the phrasing category, then this is a
3303  parse error. Stop this algorithm. The end tag token
3304  is ignored. */
3305  return false;
3306  }
3307  }
3308  }
3309  break;
3310  }
3311  break;
3312  }
3313  }
emitToken($token)
Definition: PH5P.php:1712
const RCDATA
Definition: PH5P.php:450
getElementCategory($node)
Definition: PH5P.php:4634
const COMMENT
Definition: PH5P.php:457
$x
Definition: example_009.php:98
afterBody($token)
Definition: PH5P.php:4201
const CDATA
Definition: PH5P.php:451
const PLAINTEXT
Definition: PH5P.php:452
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4619
elementInScope($el, $table=false)
Definition: PH5P.php:4465
$n
Definition: RandomTest.php:80
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
reconstructActiveFormattingElements()
Definition: PH5P.php:4525

◆ inCaption() [1/2]

HTML5TreeConstructer::inCaption (   $token)
private

Definition at line 2782 of file PH5P.php.

References HTML5\$token, array, HTML5\ENDTAG, and HTML5\STARTTAG.

2783  {
2784  /* An end tag whose tag name is "caption" */
2785  if($token['type'] === HTML5::ENDTAG && $token['name'] === 'caption') {
2786  /* If the stack of open elements does not have an element in table
2787  scope with the same tag name as the token, this is a parse error.
2788  Ignore the token. (innerHTML case) */
2789  if(!$this->elementInScope($token['name'], true)) {
2790  // Ignore
2791 
2792  /* Otherwise: */
2793  } else {
2794  /* Generate implied end tags. */
2795  $this->generateImpliedEndTags();
2796 
2797  /* Now, if the current node is not a caption element, then this
2798  is a parse error. */
2799  // w/e
2800 
2801  /* Pop elements from this stack until a caption element has
2802  been popped from the stack. */
2803  while(true) {
2804  $node = end($this->stack)->nodeName;
2805  array_pop($this->stack);
2806 
2807  if($node === 'caption') {
2808  break;
2809  }
2810  }
2811 
2812  /* Clear the list of active formatting elements up to the last
2813  marker. */
2815 
2816  /* Switch the insertion mode to "in table". */
2817  $this->mode = self::IN_TABLE;
2818  }
2819 
2820  /* A start tag whose tag name is one of: "caption", "col", "colgroup",
2821  "tbody", "td", "tfoot", "th", "thead", "tr", or an end tag whose tag
2822  name is "table" */
2823  } elseif(($token['type'] === HTML5::STARTTAG && in_array($token['name'],
2824  array('caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th',
2825  'thead', 'tr'))) || ($token['type'] === HTML5::ENDTAG &&
2826  $token['name'] === 'table')) {
2827  /* Parse error. Act as if an end tag with the tag name "caption"
2828  had been seen, then, if that token wasn't ignored, reprocess the
2829  current token. */
2830  $this->inCaption(array(
2831  'name' => 'caption',
2832  'type' => HTML5::ENDTAG
2833  ));
2834 
2835  return $this->inTable($token);
2836 
2837  /* An end tag whose tag name is one of: "body", "col", "colgroup",
2838  "html", "tbody", "td", "tfoot", "th", "thead", "tr" */
2839  } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'],
2840  array('body', 'col', 'colgroup', 'html', 'tbody', 'tfoot', 'th',
2841  'thead', 'tr'))) {
2842  // Parse error. Ignore the token.
2843 
2844  /* Anything else */
2845  } else {
2846  /* Process the token as if the insertion mode was "in body". */
2847  $this->inBody($token);
2848  }
2849  }
clearTheActiveFormattingElementsUpToTheLastMarker()
Definition: PH5P.php:4597
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4619
inCaption($token)
Definition: PH5P.php:3527
elementInScope($el, $table=false)
Definition: PH5P.php:4465
Create styles array
The data for the language used.
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ inCaption() [2/2]

HTML5TreeConstructer::inCaption (   $token)
private

Definition at line 3527 of file PH5P.php.

References array, HTML5\ENDTAG, and HTML5\STARTTAG.

3528  {
3529  /* An end tag whose tag name is "caption" */
3530  if ($token['type'] === HTML5::ENDTAG && $token['name'] === 'caption') {
3531  /* If the stack of open elements does not have an element in table
3532  scope with the same tag name as the token, this is a parse error.
3533  Ignore the token. (innerHTML case) */
3534  if (!$this->elementInScope($token['name'], true)) {
3535  // Ignore
3536 
3537  /* Otherwise: */
3538  } else {
3539  /* Generate implied end tags. */
3540  $this->generateImpliedEndTags();
3541 
3542  /* Now, if the current node is not a caption element, then this
3543  is a parse error. */
3544  // w/e
3545 
3546  /* Pop elements from this stack until a caption element has
3547  been popped from the stack. */
3548  while (true) {
3549  $node = end($this->stack)->nodeName;
3550  array_pop($this->stack);
3551 
3552  if ($node === 'caption') {
3553  break;
3554  }
3555  }
3556 
3557  /* Clear the list of active formatting elements up to the last
3558  marker. */
3560 
3561  /* Switch the insertion mode to "in table". */
3562  $this->mode = self::IN_TABLE;
3563  }
3564 
3565  /* A start tag whose tag name is one of: "caption", "col", "colgroup",
3566  "tbody", "td", "tfoot", "th", "thead", "tr", or an end tag whose tag
3567  name is "table" */
3568  } elseif (($token['type'] === HTML5::STARTTAG && in_array(
3569  $token['name'],
3570  array(
3571  'caption',
3572  'col',
3573  'colgroup',
3574  'tbody',
3575  'td',
3576  'tfoot',
3577  'th',
3578  'thead',
3579  'tr'
3580  )
3581  )) || ($token['type'] === HTML5::ENDTAG &&
3582  $token['name'] === 'table')
3583  ) {
3584  /* Parse error. Act as if an end tag with the tag name "caption"
3585  had been seen, then, if that token wasn't ignored, reprocess the
3586  current token. */
3587  $this->inCaption(
3588  array(
3589  'name' => 'caption',
3590  'type' => HTML5::ENDTAG
3591  )
3592  );
3593 
3594  return $this->inTable($token);
3595 
3596  /* An end tag whose tag name is one of: "body", "col", "colgroup",
3597  "html", "tbody", "td", "tfoot", "th", "thead", "tr" */
3598  } elseif ($token['type'] === HTML5::ENDTAG && in_array(
3599  $token['name'],
3600  array(
3601  'body',
3602  'col',
3603  'colgroup',
3604  'html',
3605  'tbody',
3606  'tfoot',
3607  'th',
3608  'thead',
3609  'tr'
3610  )
3611  )
3612  ) {
3613  // Parse error. Ignore the token.
3614 
3615  /* Anything else */
3616  } else {
3617  /* Process the token as if the insertion mode was "in body". */
3618  $this->inBody($token);
3619  }
3620  }
clearTheActiveFormattingElementsUpToTheLastMarker()
Definition: PH5P.php:4597
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4619
inCaption($token)
Definition: PH5P.php:3527
elementInScope($el, $table=false)
Definition: PH5P.php:4465
Create styles array
The data for the language used.
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ inCell() [1/2]

HTML5TreeConstructer::inCell (   $token)
private

Definition at line 3082 of file PH5P.php.

References HTML5\$token, array, HTML5\ENDTAG, and HTML5\STARTTAG.

3083  {
3084  /* An end tag whose tag name is one of: "td", "th" */
3085  if($token['type'] === HTML5::ENDTAG &&
3086  ($token['name'] === 'td' || $token['name'] === 'th')) {
3087  /* If the stack of open elements does not have an element in table
3088  scope with the same tag name as that of the token, then this is a
3089  parse error and the token must be ignored. */
3090  if(!$this->elementInScope($token['name'], true)) {
3091  // Ignore.
3092 
3093  /* Otherwise: */
3094  } else {
3095  /* Generate implied end tags, except for elements with the same
3096  tag name as the token. */
3097  $this->generateImpliedEndTags(array($token['name']));
3098 
3099  /* Now, if the current node is not an element with the same tag
3100  name as the token, then this is a parse error. */
3101  // k
3102 
3103  /* Pop elements from this stack until an element with the same
3104  tag name as the token has been popped from the stack. */
3105  while(true) {
3106  $node = end($this->stack)->nodeName;
3107  array_pop($this->stack);
3108 
3109  if($node === $token['name']) {
3110  break;
3111  }
3112  }
3113 
3114  /* Clear the list of active formatting elements up to the last
3115  marker. */
3117 
3118  /* Switch the insertion mode to "in row". (The current node
3119  will be a tr element at this point.) */
3120  $this->mode = self::IN_ROW;
3121  }
3122 
3123  /* A start tag whose tag name is one of: "caption", "col", "colgroup",
3124  "tbody", "td", "tfoot", "th", "thead", "tr" */
3125  } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'],
3126  array('caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th',
3127  'thead', 'tr'))) {
3128  /* If the stack of open elements does not have a td or th element
3129  in table scope, then this is a parse error; ignore the token.
3130  (innerHTML case) */
3131  if(!$this->elementInScope(array('td', 'th'), true)) {
3132  // Ignore.
3133 
3134  /* Otherwise, close the cell (see below) and reprocess the current
3135  token. */
3136  } else {
3137  $this->closeCell();
3138  return $this->inRow($token);
3139  }
3140 
3141  /* A start tag whose tag name is one of: "caption", "col", "colgroup",
3142  "tbody", "td", "tfoot", "th", "thead", "tr" */
3143  } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'],
3144  array('caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th',
3145  'thead', 'tr'))) {
3146  /* If the stack of open elements does not have a td or th element
3147  in table scope, then this is a parse error; ignore the token.
3148  (innerHTML case) */
3149  if(!$this->elementInScope(array('td', 'th'), true)) {
3150  // Ignore.
3151 
3152  /* Otherwise, close the cell (see below) and reprocess the current
3153  token. */
3154  } else {
3155  $this->closeCell();
3156  return $this->inRow($token);
3157  }
3158 
3159  /* An end tag whose tag name is one of: "body", "caption", "col",
3160  "colgroup", "html" */
3161  } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'],
3162  array('body', 'caption', 'col', 'colgroup', 'html'))) {
3163  /* Parse error. Ignore the token. */
3164 
3165  /* An end tag whose tag name is one of: "table", "tbody", "tfoot",
3166  "thead", "tr" */
3167  } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'],
3168  array('table', 'tbody', 'tfoot', 'thead', 'tr'))) {
3169  /* If the stack of open elements does not have an element in table
3170  scope with the same tag name as that of the token (which can only
3171  happen for "tbody", "tfoot" and "thead", or, in the innerHTML case),
3172  then this is a parse error and the token must be ignored. */
3173  if(!$this->elementInScope($token['name'], true)) {
3174  // Ignore.
3175 
3176  /* Otherwise, close the cell (see below) and reprocess the current
3177  token. */
3178  } else {
3179  $this->closeCell();
3180  return $this->inRow($token);
3181  }
3182 
3183  /* Anything else */
3184  } else {
3185  /* Process the token as if the insertion mode was "in body". */
3186  $this->inBody($token);
3187  }
3188  }
clearTheActiveFormattingElementsUpToTheLastMarker()
Definition: PH5P.php:4597
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4619
elementInScope($el, $table=false)
Definition: PH5P.php:4465
Create styles array
The data for the language used.
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ inCell() [2/2]

HTML5TreeConstructer::inCell (   $token)
private

Definition at line 3881 of file PH5P.php.

References array, HTML5\ENDTAG, and HTML5\STARTTAG.

3882  {
3883  /* An end tag whose tag name is one of: "td", "th" */
3884  if ($token['type'] === HTML5::ENDTAG &&
3885  ($token['name'] === 'td' || $token['name'] === 'th')
3886  ) {
3887  /* If the stack of open elements does not have an element in table
3888  scope with the same tag name as that of the token, then this is a
3889  parse error and the token must be ignored. */
3890  if (!$this->elementInScope($token['name'], true)) {
3891  // Ignore.
3892 
3893  /* Otherwise: */
3894  } else {
3895  /* Generate implied end tags, except for elements with the same
3896  tag name as the token. */
3897  $this->generateImpliedEndTags(array($token['name']));
3898 
3899  /* Now, if the current node is not an element with the same tag
3900  name as the token, then this is a parse error. */
3901  // k
3902 
3903  /* Pop elements from this stack until an element with the same
3904  tag name as the token has been popped from the stack. */
3905  while (true) {
3906  $node = end($this->stack)->nodeName;
3907  array_pop($this->stack);
3908 
3909  if ($node === $token['name']) {
3910  break;
3911  }
3912  }
3913 
3914  /* Clear the list of active formatting elements up to the last
3915  marker. */
3917 
3918  /* Switch the insertion mode to "in row". (The current node
3919  will be a tr element at this point.) */
3920  $this->mode = self::IN_ROW;
3921  }
3922 
3923  /* A start tag whose tag name is one of: "caption", "col", "colgroup",
3924  "tbody", "td", "tfoot", "th", "thead", "tr" */
3925  } elseif ($token['type'] === HTML5::STARTTAG && in_array(
3926  $token['name'],
3927  array(
3928  'caption',
3929  'col',
3930  'colgroup',
3931  'tbody',
3932  'td',
3933  'tfoot',
3934  'th',
3935  'thead',
3936  'tr'
3937  )
3938  )
3939  ) {
3940  /* If the stack of open elements does not have a td or th element
3941  in table scope, then this is a parse error; ignore the token.
3942  (innerHTML case) */
3943  if (!$this->elementInScope(array('td', 'th'), true)) {
3944  // Ignore.
3945 
3946  /* Otherwise, close the cell (see below) and reprocess the current
3947  token. */
3948  } else {
3949  $this->closeCell();
3950  return $this->inRow($token);
3951  }
3952 
3953  /* A start tag whose tag name is one of: "caption", "col", "colgroup",
3954  "tbody", "td", "tfoot", "th", "thead", "tr" */
3955  } elseif ($token['type'] === HTML5::STARTTAG && in_array(
3956  $token['name'],
3957  array(
3958  'caption',
3959  'col',
3960  'colgroup',
3961  'tbody',
3962  'td',
3963  'tfoot',
3964  'th',
3965  'thead',
3966  'tr'
3967  )
3968  )
3969  ) {
3970  /* If the stack of open elements does not have a td or th element
3971  in table scope, then this is a parse error; ignore the token.
3972  (innerHTML case) */
3973  if (!$this->elementInScope(array('td', 'th'), true)) {
3974  // Ignore.
3975 
3976  /* Otherwise, close the cell (see below) and reprocess the current
3977  token. */
3978  } else {
3979  $this->closeCell();
3980  return $this->inRow($token);
3981  }
3982 
3983  /* An end tag whose tag name is one of: "body", "caption", "col",
3984  "colgroup", "html" */
3985  } elseif ($token['type'] === HTML5::ENDTAG && in_array(
3986  $token['name'],
3987  array('body', 'caption', 'col', 'colgroup', 'html')
3988  )
3989  ) {
3990  /* Parse error. Ignore the token. */
3991 
3992  /* An end tag whose tag name is one of: "table", "tbody", "tfoot",
3993  "thead", "tr" */
3994  } elseif ($token['type'] === HTML5::ENDTAG && in_array(
3995  $token['name'],
3996  array('table', 'tbody', 'tfoot', 'thead', 'tr')
3997  )
3998  ) {
3999  /* If the stack of open elements does not have an element in table
4000  scope with the same tag name as that of the token (which can only
4001  happen for "tbody", "tfoot" and "thead", or, in the innerHTML case),
4002  then this is a parse error and the token must be ignored. */
4003  if (!$this->elementInScope($token['name'], true)) {
4004  // Ignore.
4005 
4006  /* Otherwise, close the cell (see below) and reprocess the current
4007  token. */
4008  } else {
4009  $this->closeCell();
4010  return $this->inRow($token);
4011  }
4012 
4013  /* Anything else */
4014  } else {
4015  /* Process the token as if the insertion mode was "in body". */
4016  $this->inBody($token);
4017  }
4018  }
clearTheActiveFormattingElementsUpToTheLastMarker()
Definition: PH5P.php:4597
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4619
elementInScope($el, $table=false)
Definition: PH5P.php:4465
Create styles array
The data for the language used.
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ inColumnGroup() [1/2]

HTML5TreeConstructer::inColumnGroup (   $token)
private

Definition at line 2851 of file PH5P.php.

References $comment, $text, HTML5\$token, array, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

2852  {
2853  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
2854  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
2855  or U+0020 SPACE */
2856  if($token['type'] === HTML5::CHARACTR &&
2857  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) {
2858  /* Append the character to the current node. */
2859  $text = $this->dom->createTextNode($token['data']);
2860  end($this->stack)->appendChild($text);
2861 
2862  /* A comment token */
2863  } elseif($token['type'] === HTML5::COMMENT) {
2864  /* Append a Comment node to the current node with the data
2865  attribute set to the data given in the comment token. */
2866  $comment = $this->dom->createComment($token['data']);
2867  end($this->stack)->appendChild($comment);
2868 
2869  /* A start tag whose tag name is "col" */
2870  } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'col') {
2871  /* Insert a col element for the token. Immediately pop the current
2872  node off the stack of open elements. */
2873  $this->insertElement($token);
2874  array_pop($this->stack);
2875 
2876  /* An end tag whose tag name is "colgroup" */
2877  } elseif($token['type'] === HTML5::ENDTAG &&
2878  $token['name'] === 'colgroup') {
2879  /* If the current node is the root html element, then this is a
2880  parse error, ignore the token. (innerHTML case) */
2881  if(end($this->stack)->nodeName === 'html') {
2882  // Ignore
2883 
2884  /* Otherwise, pop the current node (which will be a colgroup
2885  element) from the stack of open elements. Switch the insertion
2886  mode to "in table". */
2887  } else {
2888  array_pop($this->stack);
2889  $this->mode = self::IN_TABLE;
2890  }
2891 
2892  /* An end tag whose tag name is "col" */
2893  } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'col') {
2894  /* Parse error. Ignore the token. */
2895 
2896  /* Anything else */
2897  } else {
2898  /* Act as if an end tag with the tag name "colgroup" had been seen,
2899  and then, if that token wasn't ignored, reprocess the current token. */
2900  $this->inColumnGroup(array(
2901  'name' => 'colgroup',
2902  'type' => HTML5::ENDTAG
2903  ));
2904 
2905  return $this->inTable($token);
2906  }
2907  }
const COMMENT
Definition: PH5P.php:457
inColumnGroup($token)
Definition: PH5P.php:3622
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
$comment
Definition: buildRTE.php:83
Create styles array
The data for the language used.
const CHARACTR
Definition: PH5P.php:458
$text
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ inColumnGroup() [2/2]

HTML5TreeConstructer::inColumnGroup (   $token)
private

Definition at line 3622 of file PH5P.php.

References $comment, $text, array, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

3623  {
3624  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
3625  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
3626  or U+0020 SPACE */
3627  if ($token['type'] === HTML5::CHARACTR &&
3628  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
3629  ) {
3630  /* Append the character to the current node. */
3631  $text = $this->dom->createTextNode($token['data']);
3632  end($this->stack)->appendChild($text);
3633 
3634  /* A comment token */
3635  } elseif ($token['type'] === HTML5::COMMENT) {
3636  /* Append a Comment node to the current node with the data
3637  attribute set to the data given in the comment token. */
3638  $comment = $this->dom->createComment($token['data']);
3639  end($this->stack)->appendChild($comment);
3640 
3641  /* A start tag whose tag name is "col" */
3642  } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'col') {
3643  /* Insert a col element for the token. Immediately pop the current
3644  node off the stack of open elements. */
3645  $this->insertElement($token);
3646  array_pop($this->stack);
3647 
3648  /* An end tag whose tag name is "colgroup" */
3649  } elseif ($token['type'] === HTML5::ENDTAG &&
3650  $token['name'] === 'colgroup'
3651  ) {
3652  /* If the current node is the root html element, then this is a
3653  parse error, ignore the token. (innerHTML case) */
3654  if (end($this->stack)->nodeName === 'html') {
3655  // Ignore
3656 
3657  /* Otherwise, pop the current node (which will be a colgroup
3658  element) from the stack of open elements. Switch the insertion
3659  mode to "in table". */
3660  } else {
3661  array_pop($this->stack);
3662  $this->mode = self::IN_TABLE;
3663  }
3664 
3665  /* An end tag whose tag name is "col" */
3666  } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'col') {
3667  /* Parse error. Ignore the token. */
3668 
3669  /* Anything else */
3670  } else {
3671  /* Act as if an end tag with the tag name "colgroup" had been seen,
3672  and then, if that token wasn't ignored, reprocess the current token. */
3673  $this->inColumnGroup(
3674  array(
3675  'name' => 'colgroup',
3676  'type' => HTML5::ENDTAG
3677  )
3678  );
3679 
3680  return $this->inTable($token);
3681  }
3682  }
const COMMENT
Definition: PH5P.php:457
inColumnGroup($token)
Definition: PH5P.php:3622
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
$comment
Definition: buildRTE.php:83
Create styles array
The data for the language used.
const CHARACTR
Definition: PH5P.php:458
$text
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ inFrameset() [1/2]

HTML5TreeConstructer::inFrameset (   $token)
private

Definition at line 3380 of file PH5P.php.

References HTML5\$token, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

3381  {
3382  /* Handle the token as follows: */
3383 
3384  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
3385  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
3386  U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */
3387  if($token['type'] === HTML5::CHARACTR &&
3388  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) {
3389  /* Append the character to the current node. */
3390  $this->insertText($token['data']);
3391 
3392  /* A comment token */
3393  } elseif($token['type'] === HTML5::COMMENT) {
3394  /* Append a Comment node to the current node with the data
3395  attribute set to the data given in the comment token. */
3396  $this->insertComment($token['data']);
3397 
3398  /* A start tag with the tag name "frameset" */
3399  } elseif($token['name'] === 'frameset' &&
3400  $token['type'] === HTML5::STARTTAG) {
3401  $this->insertElement($token);
3402 
3403  /* An end tag with the tag name "frameset" */
3404  } elseif($token['name'] === 'frameset' &&
3405  $token['type'] === HTML5::ENDTAG) {
3406  /* If the current node is the root html element, then this is a
3407  parse error; ignore the token. (innerHTML case) */
3408  if(end($this->stack)->nodeName === 'html') {
3409  // Ignore
3410 
3411  } else {
3412  /* Otherwise, pop the current node from the stack of open
3413  elements. */
3414  array_pop($this->stack);
3415 
3416  /* If the parser was not originally created in order to handle
3417  the setting of an element's innerHTML attribute (innerHTML case),
3418  and the current node is no longer a frameset element, then change
3419  the insertion mode to "after frameset". */
3420  $this->mode = self::AFTR_FRAME;
3421  }
3422 
3423  /* A start tag with the tag name "frame" */
3424  } elseif($token['name'] === 'frame' &&
3425  $token['type'] === HTML5::STARTTAG) {
3426  /* Insert an HTML element for the token. */
3427  $this->insertElement($token);
3428 
3429  /* Immediately pop the current node off the stack of open elements. */
3430  array_pop($this->stack);
3431 
3432  /* A start tag with the tag name "noframes" */
3433  } elseif($token['name'] === 'noframes' &&
3434  $token['type'] === HTML5::STARTTAG) {
3435  /* Process the token as if the insertion mode had been "in body". */
3436  $this->inBody($token);
3437 
3438  /* Anything else */
3439  } else {
3440  /* Parse error. Ignore the token. */
3441  }
3442  }
const COMMENT
Definition: PH5P.php:457
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ inFrameset() [2/2]

HTML5TreeConstructer::inFrameset (   $token)
private

Definition at line 4242 of file PH5P.php.

References HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

4243  {
4244  /* Handle the token as follows: */
4245 
4246  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
4247  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
4248  U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */
4249  if ($token['type'] === HTML5::CHARACTR &&
4250  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
4251  ) {
4252  /* Append the character to the current node. */
4253  $this->insertText($token['data']);
4254 
4255  /* A comment token */
4256  } elseif ($token['type'] === HTML5::COMMENT) {
4257  /* Append a Comment node to the current node with the data
4258  attribute set to the data given in the comment token. */
4259  $this->insertComment($token['data']);
4260 
4261  /* A start tag with the tag name "frameset" */
4262  } elseif ($token['name'] === 'frameset' &&
4263  $token['type'] === HTML5::STARTTAG
4264  ) {
4265  $this->insertElement($token);
4266 
4267  /* An end tag with the tag name "frameset" */
4268  } elseif ($token['name'] === 'frameset' &&
4269  $token['type'] === HTML5::ENDTAG
4270  ) {
4271  /* If the current node is the root html element, then this is a
4272  parse error; ignore the token. (innerHTML case) */
4273  if (end($this->stack)->nodeName === 'html') {
4274  // Ignore
4275 
4276  } else {
4277  /* Otherwise, pop the current node from the stack of open
4278  elements. */
4279  array_pop($this->stack);
4280 
4281  /* If the parser was not originally created in order to handle
4282  the setting of an element's innerHTML attribute (innerHTML case),
4283  and the current node is no longer a frameset element, then change
4284  the insertion mode to "after frameset". */
4285  $this->mode = self::AFTR_FRAME;
4286  }
4287 
4288  /* A start tag with the tag name "frame" */
4289  } elseif ($token['name'] === 'frame' &&
4290  $token['type'] === HTML5::STARTTAG
4291  ) {
4292  /* Insert an HTML element for the token. */
4293  $this->insertElement($token);
4294 
4295  /* Immediately pop the current node off the stack of open elements. */
4296  array_pop($this->stack);
4297 
4298  /* A start tag with the tag name "noframes" */
4299  } elseif ($token['name'] === 'noframes' &&
4300  $token['type'] === HTML5::STARTTAG
4301  ) {
4302  /* Process the token as if the insertion mode had been "in body". */
4303  $this->inBody($token);
4304 
4305  /* Anything else */
4306  } else {
4307  /* Parse error. Ignore the token. */
4308  }
4309  }
const COMMENT
Definition: PH5P.php:457
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ inHead() [1/2]

HTML5TreeConstructer::inHead (   $token)
private

Definition at line 1423 of file PH5P.php.

References HTML5\$token, array, HTML5\CDATA, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, HTML5\PCDATA, HTML5\RCDATA, and HTML5\STARTTAG.

1424  {
1425  /* Handle the token as follows: */
1426 
1427  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
1428  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1429  or U+0020 SPACE.
1430 
1431  THIS DIFFERS FROM THE SPEC: If the current node is either a title, style
1432  or script element, append the character to the current node regardless
1433  of its content. */
1434  if(($token['type'] === HTML5::CHARACTR &&
1435  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || (
1436  $token['type'] === HTML5::CHARACTR && in_array(end($this->stack)->nodeName,
1437  array('title', 'style', 'script')))) {
1438  /* Append the character to the current node. */
1439  $this->insertText($token['data']);
1440 
1441  /* A comment token */
1442  } elseif($token['type'] === HTML5::COMMENT) {
1443  /* Append a Comment node to the current node with the data attribute
1444  set to the data given in the comment token. */
1445  $this->insertComment($token['data']);
1446 
1447  } elseif($token['type'] === HTML5::ENDTAG &&
1448  in_array($token['name'], array('title', 'style', 'script'))) {
1449  array_pop($this->stack);
1450  return HTML5::PCDATA;
1451 
1452  /* A start tag with the tag name "title" */
1453  } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'title') {
1454  /* Create an element for the token and append the new element to the
1455  node pointed to by the head element pointer, or, if that is null
1456  (innerHTML case), to the current node. */
1457  if($this->head_pointer !== null) {
1458  $element = $this->insertElement($token, false);
1459  $this->head_pointer->appendChild($element);
1460 
1461  } else {
1462  $element = $this->insertElement($token);
1463  }
1464 
1465  /* Switch the tokeniser's content model flag to the RCDATA state. */
1466  return HTML5::RCDATA;
1467 
1468  /* A start tag with the tag name "style" */
1469  } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'style') {
1470  /* Create an element for the token and append the new element to the
1471  node pointed to by the head element pointer, or, if that is null
1472  (innerHTML case), to the current node. */
1473  if($this->head_pointer !== null) {
1474  $element = $this->insertElement($token, false);
1475  $this->head_pointer->appendChild($element);
1476 
1477  } else {
1478  $this->insertElement($token);
1479  }
1480 
1481  /* Switch the tokeniser's content model flag to the CDATA state. */
1482  return HTML5::CDATA;
1483 
1484  /* A start tag with the tag name "script" */
1485  } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'script') {
1486  /* Create an element for the token. */
1487  $element = $this->insertElement($token, false);
1488  $this->head_pointer->appendChild($element);
1489 
1490  /* Switch the tokeniser's content model flag to the CDATA state. */
1491  return HTML5::CDATA;
1492 
1493  /* A start tag with the tag name "base", "link", or "meta" */
1494  } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'],
1495  array('base', 'link', 'meta'))) {
1496  /* Create an element for the token and append the new element to the
1497  node pointed to by the head element pointer, or, if that is null
1498  (innerHTML case), to the current node. */
1499  if($this->head_pointer !== null) {
1500  $element = $this->insertElement($token, false);
1501  $this->head_pointer->appendChild($element);
1502  array_pop($this->stack);
1503 
1504  } else {
1505  $this->insertElement($token);
1506  }
1507 
1508  /* An end tag with the tag name "head" */
1509  } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'head') {
1510  /* If the current node is a head element, pop the current node off
1511  the stack of open elements. */
1512  if($this->head_pointer->isSameNode(end($this->stack))) {
1513  array_pop($this->stack);
1514 
1515  /* Otherwise, this is a parse error. */
1516  } else {
1517  // k
1518  }
1519 
1520  /* Change the insertion mode to "after head". */
1521  $this->mode = self::AFTER_HEAD;
1522 
1523  /* A start tag with the tag name "head" or an end tag except "html". */
1524  } elseif(($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') ||
1525  ($token['type'] === HTML5::ENDTAG && $token['name'] !== 'html')) {
1526  // Parse error. Ignore the token.
1527 
1528  /* Anything else */
1529  } else {
1530  /* If the current node is a head element, act as if an end tag
1531  token with the tag name "head" had been seen. */
1532  if($this->head_pointer->isSameNode(end($this->stack))) {
1533  $this->inHead(array(
1534  'name' => 'head',
1535  'type' => HTML5::ENDTAG
1536  ));
1537 
1538  /* Otherwise, change the insertion mode to "after head". */
1539  } else {
1540  $this->mode = self::AFTER_HEAD;
1541  }
1542 
1543  /* Then, reprocess the current token. */
1544  return $this->afterHead($token);
1545  }
1546  }
const RCDATA
Definition: PH5P.php:450
const COMMENT
Definition: PH5P.php:457
const CDATA
Definition: PH5P.php:451
afterHead($token)
Definition: PH5P.php:2112
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const PCDATA
Definition: PH5P.php:449
const STARTTAG
Definition: PH5P.php:455

◆ inHead() [2/2]

HTML5TreeConstructer::inHead (   $token)
private

Definition at line 1977 of file PH5P.php.

References array, HTML5\CDATA, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, HTML5\PCDATA, HTML5\RCDATA, and HTML5\STARTTAG.

1978  {
1979  /* Handle the token as follows: */
1980 
1981  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
1982  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1983  or U+0020 SPACE.
1984 
1985  THIS DIFFERS FROM THE SPEC: If the current node is either a title, style
1986  or script element, append the character to the current node regardless
1987  of its content. */
1988  if (($token['type'] === HTML5::CHARACTR &&
1989  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || (
1990  $token['type'] === HTML5::CHARACTR && in_array(
1991  end($this->stack)->nodeName,
1992  array('title', 'style', 'script')
1993  ))
1994  ) {
1995  /* Append the character to the current node. */
1996  $this->insertText($token['data']);
1997 
1998  /* A comment token */
1999  } elseif ($token['type'] === HTML5::COMMENT) {
2000  /* Append a Comment node to the current node with the data attribute
2001  set to the data given in the comment token. */
2002  $this->insertComment($token['data']);
2003 
2004  } elseif ($token['type'] === HTML5::ENDTAG &&
2005  in_array($token['name'], array('title', 'style', 'script'))
2006  ) {
2007  array_pop($this->stack);
2008  return HTML5::PCDATA;
2009 
2010  /* A start tag with the tag name "title" */
2011  } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'title') {
2012  /* Create an element for the token and append the new element to the
2013  node pointed to by the head element pointer, or, if that is null
2014  (innerHTML case), to the current node. */
2015  if ($this->head_pointer !== null) {
2016  $element = $this->insertElement($token, false);
2017  $this->head_pointer->appendChild($element);
2018 
2019  } else {
2020  $element = $this->insertElement($token);
2021  }
2022 
2023  /* Switch the tokeniser's content model flag to the RCDATA state. */
2024  return HTML5::RCDATA;
2025 
2026  /* A start tag with the tag name "style" */
2027  } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'style') {
2028  /* Create an element for the token and append the new element to the
2029  node pointed to by the head element pointer, or, if that is null
2030  (innerHTML case), to the current node. */
2031  if ($this->head_pointer !== null) {
2032  $element = $this->insertElement($token, false);
2033  $this->head_pointer->appendChild($element);
2034 
2035  } else {
2036  $this->insertElement($token);
2037  }
2038 
2039  /* Switch the tokeniser's content model flag to the CDATA state. */
2040  return HTML5::CDATA;
2041 
2042  /* A start tag with the tag name "script" */
2043  } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'script') {
2044  /* Create an element for the token. */
2045  $element = $this->insertElement($token, false);
2046  $this->head_pointer->appendChild($element);
2047 
2048  /* Switch the tokeniser's content model flag to the CDATA state. */
2049  return HTML5::CDATA;
2050 
2051  /* A start tag with the tag name "base", "link", or "meta" */
2052  } elseif ($token['type'] === HTML5::STARTTAG && in_array(
2053  $token['name'],
2054  array('base', 'link', 'meta')
2055  )
2056  ) {
2057  /* Create an element for the token and append the new element to the
2058  node pointed to by the head element pointer, or, if that is null
2059  (innerHTML case), to the current node. */
2060  if ($this->head_pointer !== null) {
2061  $element = $this->insertElement($token, false);
2062  $this->head_pointer->appendChild($element);
2063  array_pop($this->stack);
2064 
2065  } else {
2066  $this->insertElement($token);
2067  }
2068 
2069  /* An end tag with the tag name "head" */
2070  } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'head') {
2071  /* If the current node is a head element, pop the current node off
2072  the stack of open elements. */
2073  if ($this->head_pointer->isSameNode(end($this->stack))) {
2074  array_pop($this->stack);
2075 
2076  /* Otherwise, this is a parse error. */
2077  } else {
2078  // k
2079  }
2080 
2081  /* Change the insertion mode to "after head". */
2082  $this->mode = self::AFTER_HEAD;
2083 
2084  /* A start tag with the tag name "head" or an end tag except "html". */
2085  } elseif (($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') ||
2086  ($token['type'] === HTML5::ENDTAG && $token['name'] !== 'html')
2087  ) {
2088  // Parse error. Ignore the token.
2089 
2090  /* Anything else */
2091  } else {
2092  /* If the current node is a head element, act as if an end tag
2093  token with the tag name "head" had been seen. */
2094  if ($this->head_pointer->isSameNode(end($this->stack))) {
2095  $this->inHead(
2096  array(
2097  'name' => 'head',
2098  'type' => HTML5::ENDTAG
2099  )
2100  );
2101 
2102  /* Otherwise, change the insertion mode to "after head". */
2103  } else {
2104  $this->mode = self::AFTER_HEAD;
2105  }
2106 
2107  /* Then, reprocess the current token. */
2108  return $this->afterHead($token);
2109  }
2110  }
const RCDATA
Definition: PH5P.php:450
const COMMENT
Definition: PH5P.php:457
const CDATA
Definition: PH5P.php:451
afterHead($token)
Definition: PH5P.php:2112
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const PCDATA
Definition: PH5P.php:449
const STARTTAG
Definition: PH5P.php:455

◆ initPhase() [1/2]

HTML5TreeConstructer::initPhase (   $token)
private

Definition at line 1218 of file PH5P.php.

References $text, HTML5\$token, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, HTML5\EOF(), and HTML5\STARTTAG.

1219  {
1220  /* Initially, the tree construction stage must handle each token
1221  emitted from the tokenisation stage as follows: */
1222 
1223  /* A DOCTYPE token that is marked as being in error
1224  A comment token
1225  A start tag token
1226  An end tag token
1227  A character token that is not one of one of U+0009 CHARACTER TABULATION,
1228  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1229  or U+0020 SPACE
1230  An end-of-file token */
1231  if((isset($token['error']) && $token['error']) ||
1232  $token['type'] === HTML5::COMMENT ||
1233  $token['type'] === HTML5::STARTTAG ||
1234  $token['type'] === HTML5::ENDTAG ||
1235  $token['type'] === HTML5::EOF ||
1236  ($token['type'] === HTML5::CHARACTR && isset($token['data']) &&
1237  !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']))) {
1238  /* This specification does not define how to handle this case. In
1239  particular, user agents may ignore the entirety of this specification
1240  altogether for such documents, and instead invoke special parse modes
1241  with a greater emphasis on backwards compatibility. */
1242 
1243  $this->phase = self::ROOT_PHASE;
1244  return $this->rootElementPhase($token);
1245 
1246  /* A DOCTYPE token marked as being correct */
1247  } elseif(isset($token['error']) && !$token['error']) {
1248  /* Append a DocumentType node to the Document node, with the name
1249  attribute set to the name given in the DOCTYPE token (which will be
1250  "HTML"), and the other attributes specific to DocumentType objects
1251  set to null, empty lists, or the empty string as appropriate. */
1252  $doctype = new DOMDocumentType(null, null, 'HTML');
1253 
1254  /* Then, switch to the root element phase of the tree construction
1255  stage. */
1256  $this->phase = self::ROOT_PHASE;
1257 
1258  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
1259  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1260  or U+0020 SPACE */
1261  } elseif(isset($token['data']) && preg_match('/^[\t\n\x0b\x0c ]+$/',
1262  $token['data'])) {
1263  /* Append that character to the Document node. */
1264  $text = $this->dom->createTextNode($token['data']);
1265  $this->dom->appendChild($text);
1266  }
1267  }
const COMMENT
Definition: PH5P.php:457
EOF()
Definition: PH5P.php:1565
rootElementPhase($token)
Definition: PH5P.php:1785
const CHARACTR
Definition: PH5P.php:458
$text
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
+ Here is the call graph for this function:

◆ initPhase() [2/2]

HTML5TreeConstructer::initPhase (   $token)
private

Definition at line 1730 of file PH5P.php.

References $text, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, HTML5\EOF(), and HTML5\STARTTAG.

1731  {
1732  /* Initially, the tree construction stage must handle each token
1733  emitted from the tokenisation stage as follows: */
1734 
1735  /* A DOCTYPE token that is marked as being in error
1736  A comment token
1737  A start tag token
1738  An end tag token
1739  A character token that is not one of one of U+0009 CHARACTER TABULATION,
1740  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1741  or U+0020 SPACE
1742  An end-of-file token */
1743  if ((isset($token['error']) && $token['error']) ||
1744  $token['type'] === HTML5::COMMENT ||
1745  $token['type'] === HTML5::STARTTAG ||
1746  $token['type'] === HTML5::ENDTAG ||
1747  $token['type'] === HTML5::EOF ||
1748  ($token['type'] === HTML5::CHARACTR && isset($token['data']) &&
1749  !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']))
1750  ) {
1751  /* This specification does not define how to handle this case. In
1752  particular, user agents may ignore the entirety of this specification
1753  altogether for such documents, and instead invoke special parse modes
1754  with a greater emphasis on backwards compatibility. */
1755 
1756  $this->phase = self::ROOT_PHASE;
1757  return $this->rootElementPhase($token);
1758 
1759  /* A DOCTYPE token marked as being correct */
1760  } elseif (isset($token['error']) && !$token['error']) {
1761  /* Append a DocumentType node to the Document node, with the name
1762  attribute set to the name given in the DOCTYPE token (which will be
1763  "HTML"), and the other attributes specific to DocumentType objects
1764  set to null, empty lists, or the empty string as appropriate. */
1765  $doctype = new DOMDocumentType(null, null, 'HTML');
1766 
1767  /* Then, switch to the root element phase of the tree construction
1768  stage. */
1769  $this->phase = self::ROOT_PHASE;
1770 
1771  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
1772  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1773  or U+0020 SPACE */
1774  } elseif (isset($token['data']) && preg_match(
1775  '/^[\t\n\x0b\x0c ]+$/',
1776  $token['data']
1777  )
1778  ) {
1779  /* Append that character to the Document node. */
1780  $text = $this->dom->createTextNode($token['data']);
1781  $this->dom->appendChild($text);
1782  }
1783  }
const COMMENT
Definition: PH5P.php:457
EOF()
Definition: PH5P.php:1565
rootElementPhase($token)
Definition: PH5P.php:1785
const CHARACTR
Definition: PH5P.php:458
$text
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
+ Here is the call graph for this function:

◆ inRow() [1/2]

HTML5TreeConstructer::inRow (   $token)
private

Definition at line 2996 of file PH5P.php.

References HTML5\$token, array, HTML5\ENDTAG, and HTML5\STARTTAG.

2997  {
2998  $clear = array('tr', 'html');
2999 
3000  /* A start tag whose tag name is one of: "th", "td" */
3001  if($token['type'] === HTML5::STARTTAG &&
3002  ($token['name'] === 'th' || $token['name'] === 'td')) {
3003  /* Clear the stack back to a table row context. */
3004  $this->clearStackToTableContext($clear);
3005 
3006  /* Insert an HTML element for the token, then switch the insertion
3007  mode to "in cell". */
3008  $this->insertElement($token);
3009  $this->mode = self::IN_CELL;
3010 
3011  /* Insert a marker at the end of the list of active formatting
3012  elements. */
3013  $this->a_formatting[] = self::MARKER;
3014 
3015  /* An end tag whose tag name is "tr" */
3016  } elseif($token['type'] === HTML5::ENDTAG && $token['name'] === 'tr') {
3017  /* If the stack of open elements does not have an element in table
3018  scope with the same tag name as the token, this is a parse error.
3019  Ignore the token. (innerHTML case) */
3020  if(!$this->elementInScope($token['name'], true)) {
3021  // Ignore.
3022 
3023  /* Otherwise: */
3024  } else {
3025  /* Clear the stack back to a table row context. */
3026  $this->clearStackToTableContext($clear);
3027 
3028  /* Pop the current node (which will be a tr element) from the
3029  stack of open elements. Switch the insertion mode to "in table
3030  body". */
3031  array_pop($this->stack);
3032  $this->mode = self::IN_TBODY;
3033  }
3034 
3035  /* A start tag whose tag name is one of: "caption", "col", "colgroup",
3036  "tbody", "tfoot", "thead", "tr" or an end tag whose tag name is "table" */
3037  } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'],
3038  array('caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead', 'tr'))) {
3039  /* Act as if an end tag with the tag name "tr" had been seen, then,
3040  if that token wasn't ignored, reprocess the current token. */
3041  $this->inRow(array(
3042  'name' => 'tr',
3043  'type' => HTML5::ENDTAG
3044  ));
3045 
3046  return $this->inCell($token);
3047 
3048  /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */
3049  } elseif($token['type'] === HTML5::ENDTAG &&
3050  in_array($token['name'], array('tbody', 'tfoot', 'thead'))) {
3051  /* If the stack of open elements does not have an element in table
3052  scope with the same tag name as the token, this is a parse error.
3053  Ignore the token. */
3054  if(!$this->elementInScope($token['name'], true)) {
3055  // Ignore.
3056 
3057  /* Otherwise: */
3058  } else {
3059  /* Otherwise, act as if an end tag with the tag name "tr" had
3060  been seen, then reprocess the current token. */
3061  $this->inRow(array(
3062  'name' => 'tr',
3063  'type' => HTML5::ENDTAG
3064  ));
3065 
3066  return $this->inCell($token);
3067  }
3068 
3069  /* An end tag whose tag name is one of: "body", "caption", "col",
3070  "colgroup", "html", "td", "th" */
3071  } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'],
3072  array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr'))) {
3073  /* Parse error. Ignore the token. */
3074 
3075  /* Anything else */
3076  } else {
3077  /* Process the token as if the insertion mode was "in table". */
3078  $this->inTable($token);
3079  }
3080  }
clearStackToTableContext($elements)
Definition: PH5P.php:4648
elementInScope($el, $table=false)
Definition: PH5P.php:4465
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ inRow() [2/2]

HTML5TreeConstructer::inRow (   $token)
private

Definition at line 3783 of file PH5P.php.

References array, HTML5\ENDTAG, and HTML5\STARTTAG.

3784  {
3785  $clear = array('tr', 'html');
3786 
3787  /* A start tag whose tag name is one of: "th", "td" */
3788  if ($token['type'] === HTML5::STARTTAG &&
3789  ($token['name'] === 'th' || $token['name'] === 'td')
3790  ) {
3791  /* Clear the stack back to a table row context. */
3792  $this->clearStackToTableContext($clear);
3793 
3794  /* Insert an HTML element for the token, then switch the insertion
3795  mode to "in cell". */
3796  $this->insertElement($token);
3797  $this->mode = self::IN_CELL;
3798 
3799  /* Insert a marker at the end of the list of active formatting
3800  elements. */
3801  $this->a_formatting[] = self::MARKER;
3802 
3803  /* An end tag whose tag name is "tr" */
3804  } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'tr') {
3805  /* If the stack of open elements does not have an element in table
3806  scope with the same tag name as the token, this is a parse error.
3807  Ignore the token. (innerHTML case) */
3808  if (!$this->elementInScope($token['name'], true)) {
3809  // Ignore.
3810 
3811  /* Otherwise: */
3812  } else {
3813  /* Clear the stack back to a table row context. */
3814  $this->clearStackToTableContext($clear);
3815 
3816  /* Pop the current node (which will be a tr element) from the
3817  stack of open elements. Switch the insertion mode to "in table
3818  body". */
3819  array_pop($this->stack);
3820  $this->mode = self::IN_TBODY;
3821  }
3822 
3823  /* A start tag whose tag name is one of: "caption", "col", "colgroup",
3824  "tbody", "tfoot", "thead", "tr" or an end tag whose tag name is "table" */
3825  } elseif ($token['type'] === HTML5::STARTTAG && in_array(
3826  $token['name'],
3827  array('caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead', 'tr')
3828  )
3829  ) {
3830  /* Act as if an end tag with the tag name "tr" had been seen, then,
3831  if that token wasn't ignored, reprocess the current token. */
3832  $this->inRow(
3833  array(
3834  'name' => 'tr',
3835  'type' => HTML5::ENDTAG
3836  )
3837  );
3838 
3839  return $this->inCell($token);
3840 
3841  /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */
3842  } elseif ($token['type'] === HTML5::ENDTAG &&
3843  in_array($token['name'], array('tbody', 'tfoot', 'thead'))
3844  ) {
3845  /* If the stack of open elements does not have an element in table
3846  scope with the same tag name as the token, this is a parse error.
3847  Ignore the token. */
3848  if (!$this->elementInScope($token['name'], true)) {
3849  // Ignore.
3850 
3851  /* Otherwise: */
3852  } else {
3853  /* Otherwise, act as if an end tag with the tag name "tr" had
3854  been seen, then reprocess the current token. */
3855  $this->inRow(
3856  array(
3857  'name' => 'tr',
3858  'type' => HTML5::ENDTAG
3859  )
3860  );
3861 
3862  return $this->inCell($token);
3863  }
3864 
3865  /* An end tag whose tag name is one of: "body", "caption", "col",
3866  "colgroup", "html", "td", "th" */
3867  } elseif ($token['type'] === HTML5::ENDTAG && in_array(
3868  $token['name'],
3869  array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr')
3870  )
3871  ) {
3872  /* Parse error. Ignore the token. */
3873 
3874  /* Anything else */
3875  } else {
3876  /* Process the token as if the insertion mode was "in table". */
3877  $this->inTable($token);
3878  }
3879  }
clearStackToTableContext($elements)
Definition: PH5P.php:4648
elementInScope($el, $table=false)
Definition: PH5P.php:4465
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455

◆ inSelect() [1/2]

HTML5TreeConstructer::inSelect (   $token)
private

Definition at line 3190 of file PH5P.php.

References HTML5\$token, array, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

3191  {
3192  /* Handle the token as follows: */
3193 
3194  /* A character token */
3195  if($token['type'] === HTML5::CHARACTR) {
3196  /* Append the token's character to the current node. */
3197  $this->insertText($token['data']);
3198 
3199  /* A comment token */
3200  } elseif($token['type'] === HTML5::COMMENT) {
3201  /* Append a Comment node to the current node with the data
3202  attribute set to the data given in the comment token. */
3203  $this->insertComment($token['data']);
3204 
3205  /* A start tag token whose tag name is "option" */
3206  } elseif($token['type'] === HTML5::STARTTAG &&
3207  $token['name'] === 'option') {
3208  /* If the current node is an option element, act as if an end tag
3209  with the tag name "option" had been seen. */
3210  if(end($this->stack)->nodeName === 'option') {
3211  $this->inSelect(array(
3212  'name' => 'option',
3213  'type' => HTML5::ENDTAG
3214  ));
3215  }
3216 
3217  /* Insert an HTML element for the token. */
3218  $this->insertElement($token);
3219 
3220  /* A start tag token whose tag name is "optgroup" */
3221  } elseif($token['type'] === HTML5::STARTTAG &&
3222  $token['name'] === 'optgroup') {
3223  /* If the current node is an option element, act as if an end tag
3224  with the tag name "option" had been seen. */
3225  if(end($this->stack)->nodeName === 'option') {
3226  $this->inSelect(array(
3227  'name' => 'option',
3228  'type' => HTML5::ENDTAG
3229  ));
3230  }
3231 
3232  /* If the current node is an optgroup element, act as if an end tag
3233  with the tag name "optgroup" had been seen. */
3234  if(end($this->stack)->nodeName === 'optgroup') {
3235  $this->inSelect(array(
3236  'name' => 'optgroup',
3237  'type' => HTML5::ENDTAG
3238  ));
3239  }
3240 
3241  /* Insert an HTML element for the token. */
3242  $this->insertElement($token);
3243 
3244  /* An end tag token whose tag name is "optgroup" */
3245  } elseif($token['type'] === HTML5::ENDTAG &&
3246  $token['name'] === 'optgroup') {
3247  /* First, if the current node is an option element, and the node
3248  immediately before it in the stack of open elements is an optgroup
3249  element, then act as if an end tag with the tag name "option" had
3250  been seen. */
3251  $elements_in_stack = count($this->stack);
3252 
3253  if($this->stack[$elements_in_stack - 1]->nodeName === 'option' &&
3254  $this->stack[$elements_in_stack - 2]->nodeName === 'optgroup') {
3255  $this->inSelect(array(
3256  'name' => 'option',
3257  'type' => HTML5::ENDTAG
3258  ));
3259  }
3260 
3261  /* If the current node is an optgroup element, then pop that node
3262  from the stack of open elements. Otherwise, this is a parse error,
3263  ignore the token. */
3264  if($this->stack[$elements_in_stack - 1] === 'optgroup') {
3265  array_pop($this->stack);
3266  }
3267 
3268  /* An end tag token whose tag name is "option" */
3269  } elseif($token['type'] === HTML5::ENDTAG &&
3270  $token['name'] === 'option') {
3271  /* If the current node is an option element, then pop that node
3272  from the stack of open elements. Otherwise, this is a parse error,
3273  ignore the token. */
3274  if(end($this->stack)->nodeName === 'option') {
3275  array_pop($this->stack);
3276  }
3277 
3278  /* An end tag whose tag name is "select" */
3279  } elseif($token['type'] === HTML5::ENDTAG &&
3280  $token['name'] === 'select') {
3281  /* If the stack of open elements does not have an element in table
3282  scope with the same tag name as the token, this is a parse error.
3283  Ignore the token. (innerHTML case) */
3284  if(!$this->elementInScope($token['name'], true)) {
3285  // w/e
3286 
3287  /* Otherwise: */
3288  } else {
3289  /* Pop elements from the stack of open elements until a select
3290  element has been popped from the stack. */
3291  while(true) {
3292  $current = end($this->stack)->nodeName;
3293  array_pop($this->stack);
3294 
3295  if($current === 'select') {
3296  break;
3297  }
3298  }
3299 
3300  /* Reset the insertion mode appropriately. */
3301  $this->resetInsertionMode();
3302  }
3303 
3304  /* A start tag whose tag name is "select" */
3305  } elseif($token['name'] === 'select' &&
3306  $token['type'] === HTML5::STARTTAG) {
3307  /* Parse error. Act as if the token had been an end tag with the
3308  tag name "select" instead. */
3309  $this->inSelect(array(
3310  'name' => 'select',
3311  'type' => HTML5::ENDTAG
3312  ));
3313 
3314  /* An end tag whose tag name is one of: "caption", "table", "tbody",
3315  "tfoot", "thead", "tr", "td", "th" */
3316  } elseif(in_array($token['name'], array('caption', 'table', 'tbody',
3317  'tfoot', 'thead', 'tr', 'td', 'th')) && $token['type'] === HTML5::ENDTAG) {
3318  /* Parse error. */
3319  // w/e
3320 
3321  /* If the stack of open elements has an element in table scope with
3322  the same tag name as that of the token, then act as if an end tag
3323  with the tag name "select" had been seen, and reprocess the token.
3324  Otherwise, ignore the token. */
3325  if($this->elementInScope($token['name'], true)) {
3326  $this->inSelect(array(
3327  'name' => 'select',
3328  'type' => HTML5::ENDTAG
3329  ));
3330 
3331  $this->mainPhase($token);
3332  }
3333 
3334  /* Anything else */
3335  } else {
3336  /* Parse error. Ignore the token. */
3337  }
3338  }
inSelect($token)
Definition: PH5P.php:4020
const COMMENT
Definition: PH5P.php:457
elementInScope($el, $table=false)
Definition: PH5P.php:4465
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
mainPhase($token)
Definition: PH5P.php:1835

◆ inSelect() [2/2]

HTML5TreeConstructer::inSelect (   $token)
private

Definition at line 4020 of file PH5P.php.

References array, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

4021  {
4022  /* Handle the token as follows: */
4023 
4024  /* A character token */
4025  if ($token['type'] === HTML5::CHARACTR) {
4026  /* Append the token's character to the current node. */
4027  $this->insertText($token['data']);
4028 
4029  /* A comment token */
4030  } elseif ($token['type'] === HTML5::COMMENT) {
4031  /* Append a Comment node to the current node with the data
4032  attribute set to the data given in the comment token. */
4033  $this->insertComment($token['data']);
4034 
4035  /* A start tag token whose tag name is "option" */
4036  } elseif ($token['type'] === HTML5::STARTTAG &&
4037  $token['name'] === 'option'
4038  ) {
4039  /* If the current node is an option element, act as if an end tag
4040  with the tag name "option" had been seen. */
4041  if (end($this->stack)->nodeName === 'option') {
4042  $this->inSelect(
4043  array(
4044  'name' => 'option',
4045  'type' => HTML5::ENDTAG
4046  )
4047  );
4048  }
4049 
4050  /* Insert an HTML element for the token. */
4051  $this->insertElement($token);
4052 
4053  /* A start tag token whose tag name is "optgroup" */
4054  } elseif ($token['type'] === HTML5::STARTTAG &&
4055  $token['name'] === 'optgroup'
4056  ) {
4057  /* If the current node is an option element, act as if an end tag
4058  with the tag name "option" had been seen. */
4059  if (end($this->stack)->nodeName === 'option') {
4060  $this->inSelect(
4061  array(
4062  'name' => 'option',
4063  'type' => HTML5::ENDTAG
4064  )
4065  );
4066  }
4067 
4068  /* If the current node is an optgroup element, act as if an end tag
4069  with the tag name "optgroup" had been seen. */
4070  if (end($this->stack)->nodeName === 'optgroup') {
4071  $this->inSelect(
4072  array(
4073  'name' => 'optgroup',
4074  'type' => HTML5::ENDTAG
4075  )
4076  );
4077  }
4078 
4079  /* Insert an HTML element for the token. */
4080  $this->insertElement($token);
4081 
4082  /* An end tag token whose tag name is "optgroup" */
4083  } elseif ($token['type'] === HTML5::ENDTAG &&
4084  $token['name'] === 'optgroup'
4085  ) {
4086  /* First, if the current node is an option element, and the node
4087  immediately before it in the stack of open elements is an optgroup
4088  element, then act as if an end tag with the tag name "option" had
4089  been seen. */
4090  $elements_in_stack = count($this->stack);
4091 
4092  if ($this->stack[$elements_in_stack - 1]->nodeName === 'option' &&
4093  $this->stack[$elements_in_stack - 2]->nodeName === 'optgroup'
4094  ) {
4095  $this->inSelect(
4096  array(
4097  'name' => 'option',
4098  'type' => HTML5::ENDTAG
4099  )
4100  );
4101  }
4102 
4103  /* If the current node is an optgroup element, then pop that node
4104  from the stack of open elements. Otherwise, this is a parse error,
4105  ignore the token. */
4106  if ($this->stack[$elements_in_stack - 1] === 'optgroup') {
4107  array_pop($this->stack);
4108  }
4109 
4110  /* An end tag token whose tag name is "option" */
4111  } elseif ($token['type'] === HTML5::ENDTAG &&
4112  $token['name'] === 'option'
4113  ) {
4114  /* If the current node is an option element, then pop that node
4115  from the stack of open elements. Otherwise, this is a parse error,
4116  ignore the token. */
4117  if (end($this->stack)->nodeName === 'option') {
4118  array_pop($this->stack);
4119  }
4120 
4121  /* An end tag whose tag name is "select" */
4122  } elseif ($token['type'] === HTML5::ENDTAG &&
4123  $token['name'] === 'select'
4124  ) {
4125  /* If the stack of open elements does not have an element in table
4126  scope with the same tag name as the token, this is a parse error.
4127  Ignore the token. (innerHTML case) */
4128  if (!$this->elementInScope($token['name'], true)) {
4129  // w/e
4130 
4131  /* Otherwise: */
4132  } else {
4133  /* Pop elements from the stack of open elements until a select
4134  element has been popped from the stack. */
4135  while (true) {
4136  $current = end($this->stack)->nodeName;
4137  array_pop($this->stack);
4138 
4139  if ($current === 'select') {
4140  break;
4141  }
4142  }
4143 
4144  /* Reset the insertion mode appropriately. */
4145  $this->resetInsertionMode();
4146  }
4147 
4148  /* A start tag whose tag name is "select" */
4149  } elseif ($token['name'] === 'select' &&
4150  $token['type'] === HTML5::STARTTAG
4151  ) {
4152  /* Parse error. Act as if the token had been an end tag with the
4153  tag name "select" instead. */
4154  $this->inSelect(
4155  array(
4156  'name' => 'select',
4157  'type' => HTML5::ENDTAG
4158  )
4159  );
4160 
4161  /* An end tag whose tag name is one of: "caption", "table", "tbody",
4162  "tfoot", "thead", "tr", "td", "th" */
4163  } elseif (in_array(
4164  $token['name'],
4165  array(
4166  'caption',
4167  'table',
4168  'tbody',
4169  'tfoot',
4170  'thead',
4171  'tr',
4172  'td',
4173  'th'
4174  )
4175  ) && $token['type'] === HTML5::ENDTAG
4176  ) {
4177  /* Parse error. */
4178  // w/e
4179 
4180  /* If the stack of open elements has an element in table scope with
4181  the same tag name as that of the token, then act as if an end tag
4182  with the tag name "select" had been seen, and reprocess the token.
4183  Otherwise, ignore the token. */
4184  if ($this->elementInScope($token['name'], true)) {
4185  $this->inSelect(
4186  array(
4187  'name' => 'select',
4188  'type' => HTML5::ENDTAG
4189  )
4190  );
4191 
4192  $this->mainPhase($token);
4193  }
4194 
4195  /* Anything else */
4196  } else {
4197  /* Parse error. Ignore the token. */
4198  }
4199  }
inSelect($token)
Definition: PH5P.php:4020
const COMMENT
Definition: PH5P.php:457
elementInScope($el, $table=false)
Definition: PH5P.php:4465
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4428
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
mainPhase($token)
Definition: PH5P.php:1835

◆ insertComment() [1/2]

HTML5TreeConstructer::insertComment (   $data)
private

Definition at line 3543 of file PH5P.php.

References $comment, and HTML5\$data.

3544  {
3545  $comment = $this->dom->createComment($data);
3546  $this->appendToRealParent($comment);
3547  }
$comment
Definition: buildRTE.php:83
appendToRealParent($node)
Definition: PH5P.php:4434

◆ insertComment() [2/2]

HTML5TreeConstructer::insertComment (   $data)
private

Definition at line 4428 of file PH5P.php.

References $comment, and $data.

4429  {
4430  $comment = $this->dom->createComment($data);
4431  $this->appendToRealParent($comment);
4432  }
$comment
Definition: buildRTE.php:83
appendToRealParent($node)
Definition: PH5P.php:4434

◆ insertElement() [1/2]

HTML5TreeConstructer::insertElement (   $token,
  $append = true 
)
private

Definition at line 3521 of file PH5P.php.

References HTML5\$token.

3522  {
3523  $el = $this->dom->createElement($token['name']);
3524 
3525  foreach($token['attr'] as $attr) {
3526  if(!$el->hasAttribute($attr['name'])) {
3527  $el->setAttribute($attr['name'], $attr['value']);
3528  }
3529  }
3530 
3531  $this->appendToRealParent($el);
3532  $this->stack[] = $el;
3533 
3534  return $el;
3535  }
appendToRealParent($node)
Definition: PH5P.php:4434

◆ insertElement() [2/2]

HTML5TreeConstructer::insertElement (   $token,
  $append = true,
  $check = false 
)
private

Definition at line 4393 of file PH5P.php.

4394  {
4395  // Proprietary workaround for libxml2's limitations with tag names
4396  if ($check) {
4397  // Slightly modified HTML5 tag-name modification,
4398  // removing anything that's not an ASCII letter, digit, or hyphen
4399  $token['name'] = preg_replace('/[^a-z0-9-]/i', '', $token['name']);
4400  // Remove leading hyphens and numbers
4401  $token['name'] = ltrim($token['name'], '-0..9');
4402  // In theory, this should ever be needed, but just in case
4403  if ($token['name'] === '') {
4404  $token['name'] = 'span';
4405  } // arbitrary generic choice
4406  }
4407 
4408  $el = $this->dom->createElement($token['name']);
4409 
4410  foreach ($token['attr'] as $attr) {
4411  if (!$el->hasAttribute($attr['name'])) {
4412  $el->setAttribute($attr['name'], $attr['value']);
4413  }
4414  }
4415 
4416  $this->appendToRealParent($el);
4417  $this->stack[] = $el;
4418 
4419  return $el;
4420  }
appendToRealParent($node)
Definition: PH5P.php:4434

◆ insertText() [1/2]

HTML5TreeConstructer::insertText (   $data)
private

Definition at line 3537 of file PH5P.php.

References HTML5\$data, and $text.

3538  {
3539  $text = $this->dom->createTextNode($data);
3540  $this->appendToRealParent($text);
3541  }
appendToRealParent($node)
Definition: PH5P.php:4434
$text

◆ insertText() [2/2]

HTML5TreeConstructer::insertText (   $data)
private

Definition at line 4422 of file PH5P.php.

References $data, and $text.

4423  {
4424  $text = $this->dom->createTextNode($data);
4425  $this->appendToRealParent($text);
4426  }
appendToRealParent($node)
Definition: PH5P.php:4434
$text

◆ inTable() [1/2]

HTML5TreeConstructer::inTable (   $token)
private

Definition at line 2604 of file PH5P.php.

References $comment, $n, $text, HTML5\$token, array, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

2605  {
2606  $clear = array('html', 'table');
2607 
2608  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
2609  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
2610  or U+0020 SPACE */
2611  if($token['type'] === HTML5::CHARACTR &&
2612  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) {
2613  /* Append the character to the current node. */
2614  $text = $this->dom->createTextNode($token['data']);
2615  end($this->stack)->appendChild($text);
2616 
2617  /* A comment token */
2618  } elseif($token['type'] === HTML5::COMMENT) {
2619  /* Append a Comment node to the current node with the data
2620  attribute set to the data given in the comment token. */
2621  $comment = $this->dom->createComment($token['data']);
2622  end($this->stack)->appendChild($comment);
2623 
2624  /* A start tag whose tag name is "caption" */
2625  } elseif($token['type'] === HTML5::STARTTAG &&
2626  $token['name'] === 'caption') {
2627  /* Clear the stack back to a table context. */
2628  $this->clearStackToTableContext($clear);
2629 
2630  /* Insert a marker at the end of the list of active
2631  formatting elements. */
2632  $this->a_formatting[] = self::MARKER;
2633 
2634  /* Insert an HTML element for the token, then switch the
2635  insertion mode to "in caption". */
2636  $this->insertElement($token);
2637  $this->mode = self::IN_CAPTION;
2638 
2639  /* A start tag whose tag name is "colgroup" */
2640  } elseif($token['type'] === HTML5::STARTTAG &&
2641  $token['name'] === 'colgroup') {
2642  /* Clear the stack back to a table context. */
2643  $this->clearStackToTableContext($clear);
2644 
2645  /* Insert an HTML element for the token, then switch the
2646  insertion mode to "in column group". */
2647  $this->insertElement($token);
2648  $this->mode = self::IN_CGROUP;
2649 
2650  /* A start tag whose tag name is "col" */
2651  } elseif($token['type'] === HTML5::STARTTAG &&
2652  $token['name'] === 'col') {
2653  $this->inTable(array(
2654  'name' => 'colgroup',
2655  'type' => HTML5::STARTTAG,
2656  'attr' => array()
2657  ));
2658 
2659  $this->inColumnGroup($token);
2660 
2661  /* A start tag whose tag name is one of: "tbody", "tfoot", "thead" */
2662  } elseif($token['type'] === HTML5::STARTTAG && in_array($token['name'],
2663  array('tbody', 'tfoot', 'thead'))) {
2664  /* Clear the stack back to a table context. */
2665  $this->clearStackToTableContext($clear);
2666 
2667  /* Insert an HTML element for the token, then switch the insertion
2668  mode to "in table body". */
2669  $this->insertElement($token);
2670  $this->mode = self::IN_TBODY;
2671 
2672  /* A start tag whose tag name is one of: "td", "th", "tr" */
2673  } elseif($token['type'] === HTML5::STARTTAG &&
2674  in_array($token['name'], array('td', 'th', 'tr'))) {
2675  /* Act as if a start tag token with the tag name "tbody" had been
2676  seen, then reprocess the current token. */
2677  $this->inTable(array(
2678  'name' => 'tbody',
2679  'type' => HTML5::STARTTAG,
2680  'attr' => array()
2681  ));
2682 
2683  return $this->inTableBody($token);
2684 
2685  /* A start tag whose tag name is "table" */
2686  } elseif($token['type'] === HTML5::STARTTAG &&
2687  $token['name'] === 'table') {
2688  /* Parse error. Act as if an end tag token with the tag name "table"
2689  had been seen, then, if that token wasn't ignored, reprocess the
2690  current token. */
2691  $this->inTable(array(
2692  'name' => 'table',
2693  'type' => HTML5::ENDTAG
2694  ));
2695 
2696  return $this->mainPhase($token);
2697 
2698  /* An end tag whose tag name is "table" */
2699  } elseif($token['type'] === HTML5::ENDTAG &&
2700  $token['name'] === 'table') {
2701  /* If the stack of open elements does not have an element in table
2702  scope with the same tag name as the token, this is a parse error.
2703  Ignore the token. (innerHTML case) */
2704  if(!$this->elementInScope($token['name'], true)) {
2705  return false;
2706 
2707  /* Otherwise: */
2708  } else {
2709  /* Generate implied end tags. */
2710  $this->generateImpliedEndTags();
2711 
2712  /* Now, if the current node is not a table element, then this
2713  is a parse error. */
2714  // w/e
2715 
2716  /* Pop elements from this stack until a table element has been
2717  popped from the stack. */
2718  while(true) {
2719  $current = end($this->stack)->nodeName;
2720  array_pop($this->stack);
2721 
2722  if($current === 'table') {
2723  break;
2724  }
2725  }
2726 
2727  /* Reset the insertion mode appropriately. */
2728  $this->resetInsertionMode();
2729  }
2730 
2731  /* An end tag whose tag name is one of: "body", "caption", "col",
2732  "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */
2733  } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'],
2734  array('body', 'caption', 'col', 'colgroup', 'html', 'tbody', 'td',
2735  'tfoot', 'th', 'thead', 'tr'))) {
2736  // Parse error. Ignore the token.
2737 
2738  /* Anything else */
2739  } else {
2740  /* Parse error. Process the token as if the insertion mode was "in
2741  body", with the following exception: */
2742 
2743  /* If the current node is a table, tbody, tfoot, thead, or tr
2744  element, then, whenever a node would be inserted into the current
2745  node, it must instead be inserted into the foster parent element. */
2746  if(in_array(end($this->stack)->nodeName,
2747  array('table', 'tbody', 'tfoot', 'thead', 'tr'))) {
2748  /* The foster parent element is the parent element of the last
2749  table element in the stack of open elements, if there is a
2750  table element and it has such a parent element. If there is no
2751  table element in the stack of open elements (innerHTML case),
2752  then the foster parent element is the first element in the
2753  stack of open elements (the html element). Otherwise, if there
2754  is a table element in the stack of open elements, but the last
2755  table element in the stack of open elements has no parent, or
2756  its parent node is not an element, then the foster parent
2757  element is the element before the last table element in the
2758  stack of open elements. */
2759  for($n = count($this->stack) - 1; $n >= 0; $n--) {
2760  if($this->stack[$n]->nodeName === 'table') {
2761  $table = $this->stack[$n];
2762  break;
2763  }
2764  }
2765 
2766  if(isset($table) && $table->parentNode !== null) {
2767  $this->foster_parent = $table->parentNode;
2768 
2769  } elseif(!isset($table)) {
2770  $this->foster_parent = $this->stack[0];
2771 
2772  } elseif(isset($table) && ($table->parentNode === null ||
2773  $table->parentNode->nodeType !== XML_ELEMENT_NODE)) {
2774  $this->foster_parent = $this->stack[$n - 1];
2775  }
2776  }
2777 
2778  $this->inBody($token);
2779  }
2780  }
const COMMENT
Definition: PH5P.php:457
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4619
clearStackToTableContext($elements)
Definition: PH5P.php:4648
inTableBody($token)
Definition: PH5P.php:3684
elementInScope($el, $table=false)
Definition: PH5P.php:4465
inColumnGroup($token)
Definition: PH5P.php:3622
$n
Definition: RandomTest.php:80
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
$comment
Definition: buildRTE.php:83
Create styles array
The data for the language used.
const CHARACTR
Definition: PH5P.php:458
$text
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
mainPhase($token)
Definition: PH5P.php:1835

◆ inTable() [2/2]

HTML5TreeConstructer::inTable (   $token)
private

Definition at line 3315 of file PH5P.php.

References $comment, $n, $text, array, HTML5\CHARACTR, HTML5\COMMENT, HTML5\ENDTAG, and HTML5\STARTTAG.

3316  {
3317  $clear = array('html', 'table');
3318 
3319  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
3320  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
3321  or U+0020 SPACE */
3322  if ($token['type'] === HTML5::CHARACTR &&
3323  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
3324  ) {
3325  /* Append the character to the current node. */
3326  $text = $this->dom->createTextNode($token['data']);
3327  end($this->stack)->appendChild($text);
3328 
3329  /* A comment token */
3330  } elseif ($token['type'] === HTML5::COMMENT) {
3331  /* Append a Comment node to the current node with the data
3332  attribute set to the data given in the comment token. */
3333  $comment = $this->dom->createComment($token['data']);
3334  end($this->stack)->appendChild($comment);
3335 
3336  /* A start tag whose tag name is "caption" */
3337  } elseif ($token['type'] === HTML5::STARTTAG &&
3338  $token['name'] === 'caption'
3339  ) {
3340  /* Clear the stack back to a table context. */
3341  $this->clearStackToTableContext($clear);
3342 
3343  /* Insert a marker at the end of the list of active
3344  formatting elements. */
3345  $this->a_formatting[] = self::MARKER;
3346 
3347  /* Insert an HTML element for the token, then switch the
3348  insertion mode to "in caption". */
3349  $this->insertElement($token);
3350  $this->mode = self::IN_CAPTION;
3351 
3352  /* A start tag whose tag name is "colgroup" */
3353  } elseif ($token['type'] === HTML5::STARTTAG &&
3354  $token['name'] === 'colgroup'
3355  ) {
3356  /* Clear the stack back to a table context. */
3357  $this->clearStackToTableContext($clear);
3358 
3359  /* Insert an HTML element for the token, then switch the
3360  insertion mode to "in column group". */
3361  $this->insertElement($token);
3362  $this->mode = self::IN_CGROUP;
3363 
3364  /* A start tag whose tag name is "col" */
3365  } elseif ($token['type'] === HTML5::STARTTAG &&
3366  $token['name'] === 'col'
3367  ) {
3368  $this->inTable(
3369  array(
3370  'name' => 'colgroup',
3371  'type' => HTML5::STARTTAG,
3372  'attr' => array()
3373  )
3374  );
3375 
3376  $this->inColumnGroup($token);
3377 
3378  /* A start tag whose tag name is one of: "tbody", "tfoot", "thead" */
3379  } elseif ($token['type'] === HTML5::STARTTAG && in_array(
3380  $token['name'],
3381  array('tbody', 'tfoot', 'thead')
3382  )
3383  ) {
3384  /* Clear the stack back to a table context. */
3385  $this->clearStackToTableContext($clear);
3386 
3387  /* Insert an HTML element for the token, then switch the insertion
3388  mode to "in table body". */
3389  $this->insertElement($token);
3390  $this->mode = self::IN_TBODY;
3391 
3392  /* A start tag whose tag name is one of: "td", "th", "tr" */
3393  } elseif ($token['type'] === HTML5::STARTTAG &&
3394  in_array($token['name'], array('td', 'th', 'tr'))
3395  ) {
3396  /* Act as if a start tag token with the tag name "tbody" had been
3397  seen, then reprocess the current token. */
3398  $this->inTable(
3399  array(
3400  'name' => 'tbody',
3401  'type' => HTML5::STARTTAG,
3402  'attr' => array()
3403  )
3404  );
3405 
3406  return $this->inTableBody($token);
3407 
3408  /* A start tag whose tag name is "table" */
3409  } elseif ($token['type'] === HTML5::STARTTAG &&
3410  $token['name'] === 'table'
3411  ) {
3412  /* Parse error. Act as if an end tag token with the tag name "table"
3413  had been seen, then, if that token wasn't ignored, reprocess the
3414  current token. */
3415  $this->inTable(
3416  array(
3417  'name' => 'table',
3418  'type' => HTML5::ENDTAG
3419  )
3420  );
3421 
3422  return $this->mainPhase($token);
3423 
3424  /* An end tag whose tag name is "table" */
3425  } elseif ($token['type'] === HTML5::ENDTAG &&
3426  $token['name'] === 'table'
3427  ) {
3428  /* If the stack of open elements does not have an element in table
3429  scope with the same tag name as the token, this is a parse error.
3430  Ignore the token. (innerHTML case) */
3431  if (!$this->elementInScope($token['name'], true)) {
3432  return false;
3433 
3434  /* Otherwise: */
3435  } else {
3436  /* Generate implied end tags. */
3437  $this->generateImpliedEndTags();
3438 
3439  /* Now, if the current node is not a table element, then this
3440  is a parse error. */
3441  // w/e
3442 
3443  /* Pop elements from this stack until a table element has been
3444  popped from the stack. */
3445  while (true) {
3446  $current = end($this->stack)->nodeName;
3447  array_pop($this->stack);
3448 
3449  if ($current === 'table') {
3450  break;
3451  }
3452  }
3453 
3454  /* Reset the insertion mode appropriately. */
3455  $this->resetInsertionMode();
3456  }
3457 
3458  /* An end tag whose tag name is one of: "body", "caption", "col",
3459  "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */
3460  } elseif ($token['type'] === HTML5::ENDTAG && in_array(
3461  $token['name'],
3462  array(
3463  'body',
3464  'caption',
3465  'col',
3466  'colgroup',
3467  'html',
3468  'tbody',
3469  'td',
3470  'tfoot',
3471  'th',
3472  'thead',
3473  'tr'
3474  )
3475  )
3476  ) {
3477  // Parse error. Ignore the token.
3478 
3479  /* Anything else */
3480  } else {
3481  /* Parse error. Process the token as if the insertion mode was "in
3482  body", with the following exception: */
3483 
3484  /* If the current node is a table, tbody, tfoot, thead, or tr
3485  element, then, whenever a node would be inserted into the current
3486  node, it must instead be inserted into the foster parent element. */
3487  if (in_array(
3488  end($this->stack)->nodeName,
3489  array('table', 'tbody', 'tfoot', 'thead', 'tr')
3490  )
3491  ) {
3492  /* The foster parent element is the parent element of the last
3493  table element in the stack of open elements, if there is a
3494  table element and it has such a parent element. If there is no
3495  table element in the stack of open elements (innerHTML case),
3496  then the foster parent element is the first element in the
3497  stack of open elements (the html element). Otherwise, if there
3498  is a table element in the stack of open elements, but the last
3499  table element in the stack of open elements has no parent, or
3500  its parent node is not an element, then the foster parent
3501  element is the element before the last table element in the
3502  stack of open elements. */
3503  for ($n = count($this->stack) - 1; $n >= 0; $n--) {
3504  if ($this->stack[$n]->nodeName === 'table') {
3505  $table = $this->stack[$n];
3506  break;
3507  }
3508  }
3509 
3510  if (isset($table) && $table->parentNode !== null) {
3511  $this->foster_parent = $table->parentNode;
3512 
3513  } elseif (!isset($table)) {
3514  $this->foster_parent = $this->stack[0];
3515 
3516  } elseif (isset($table) && ($table->parentNode === null ||
3517  $table->parentNode->nodeType !== XML_ELEMENT_NODE)
3518  ) {
3519  $this->foster_parent = $this->stack[$n - 1];
3520  }
3521  }
3522 
3523  $this->inBody($token);
3524  }
3525  }
const COMMENT
Definition: PH5P.php:457
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4619
clearStackToTableContext($elements)
Definition: PH5P.php:4648
inTableBody($token)
Definition: PH5P.php:3684
elementInScope($el, $table=false)
Definition: PH5P.php:4465
inColumnGroup($token)
Definition: PH5P.php:3622
$n
Definition: RandomTest.php:80
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
$comment
Definition: buildRTE.php:83
Create styles array
The data for the language used.
const CHARACTR
Definition: PH5P.php:458
$text
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
mainPhase($token)
Definition: PH5P.php:1835

◆ inTableBody() [1/2]

HTML5TreeConstructer::inTableBody (   $token)
private

Definition at line 2909 of file PH5P.php.

References HTML5\$token, array, HTML5\ENDTAG, and HTML5\STARTTAG.

2910  {
2911  $clear = array('tbody', 'tfoot', 'thead', 'html');
2912 
2913  /* A start tag whose tag name is "tr" */
2914  if($token['type'] === HTML5::STARTTAG && $token['name'] === 'tr') {
2915  /* Clear the stack back to a table body context. */
2916  $this->clearStackToTableContext($clear);
2917 
2918  /* Insert a tr element for the token, then switch the insertion
2919  mode to "in row". */
2920  $this->insertElement($token);
2921  $this->mode = self::IN_ROW;
2922 
2923  /* A start tag whose tag name is one of: "th", "td" */
2924  } elseif($token['type'] === HTML5::STARTTAG &&
2925  ($token['name'] === 'th' || $token['name'] === 'td')) {
2926  /* Parse error. Act as if a start tag with the tag name "tr" had
2927  been seen, then reprocess the current token. */
2928  $this->inTableBody(array(
2929  'name' => 'tr',
2930  'type' => HTML5::STARTTAG,
2931  'attr' => array()
2932  ));
2933 
2934  return $this->inRow($token);
2935 
2936  /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */
2937  } elseif($token['type'] === HTML5::ENDTAG &&
2938  in_array($token['name'], array('tbody', 'tfoot', 'thead'))) {
2939  /* If the stack of open elements does not have an element in table
2940  scope with the same tag name as the token, this is a parse error.
2941  Ignore the token. */
2942  if(!$this->elementInScope($token['name'], true)) {
2943  // Ignore
2944 
2945  /* Otherwise: */
2946  } else {
2947  /* Clear the stack back to a table body context. */
2948  $this->clearStackToTableContext($clear);
2949 
2950  /* Pop the current node from the stack of open elements. Switch
2951  the insertion mode to "in table". */
2952  array_pop($this->stack);
2953  $this->mode = self::IN_TABLE;
2954  }
2955 
2956  /* A start tag whose tag name is one of: "caption", "col", "colgroup",
2957  "tbody", "tfoot", "thead", or an end tag whose tag name is "table" */
2958  } elseif(($token['type'] === HTML5::STARTTAG && in_array($token['name'],
2959  array('caption', 'col', 'colgroup', 'tbody', 'tfoor', 'thead'))) ||
2960  ($token['type'] === HTML5::STARTTAG && $token['name'] === 'table')) {
2961  /* If the stack of open elements does not have a tbody, thead, or
2962  tfoot element in table scope, this is a parse error. Ignore the
2963  token. (innerHTML case) */
2964  if(!$this->elementInScope(array('tbody', 'thead', 'tfoot'), true)) {
2965  // Ignore.
2966 
2967  /* Otherwise: */
2968  } else {
2969  /* Clear the stack back to a table body context. */
2970  $this->clearStackToTableContext($clear);
2971 
2972  /* Act as if an end tag with the same tag name as the current
2973  node ("tbody", "tfoot", or "thead") had been seen, then
2974  reprocess the current token. */
2975  $this->inTableBody(array(
2976  'name' => end($this->stack)->nodeName,
2977  'type' => HTML5::ENDTAG
2978  ));
2979 
2980  return $this->mainPhase($token);
2981  }
2982 
2983  /* An end tag whose tag name is one of: "body", "caption", "col",
2984  "colgroup", "html", "td", "th", "tr" */
2985  } elseif($token['type'] === HTML5::ENDTAG && in_array($token['name'],
2986  array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr'))) {
2987  /* Parse error. Ignore the token. */
2988 
2989  /* Anything else */
2990  } else {
2991  /* Process the token as if the insertion mode was "in table". */
2992  $this->inTable($token);
2993  }
2994  }
clearStackToTableContext($elements)
Definition: PH5P.php:4648
inTableBody($token)
Definition: PH5P.php:3684
elementInScope($el, $table=false)
Definition: PH5P.php:4465
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
mainPhase($token)
Definition: PH5P.php:1835

◆ inTableBody() [2/2]

HTML5TreeConstructer::inTableBody (   $token)
private

Definition at line 3684 of file PH5P.php.

References array, HTML5\ENDTAG, and HTML5\STARTTAG.

3685  {
3686  $clear = array('tbody', 'tfoot', 'thead', 'html');
3687 
3688  /* A start tag whose tag name is "tr" */
3689  if ($token['type'] === HTML5::STARTTAG && $token['name'] === 'tr') {
3690  /* Clear the stack back to a table body context. */
3691  $this->clearStackToTableContext($clear);
3692 
3693  /* Insert a tr element for the token, then switch the insertion
3694  mode to "in row". */
3695  $this->insertElement($token);
3696  $this->mode = self::IN_ROW;
3697 
3698  /* A start tag whose tag name is one of: "th", "td" */
3699  } elseif ($token['type'] === HTML5::STARTTAG &&
3700  ($token['name'] === 'th' || $token['name'] === 'td')
3701  ) {
3702  /* Parse error. Act as if a start tag with the tag name "tr" had
3703  been seen, then reprocess the current token. */
3704  $this->inTableBody(
3705  array(
3706  'name' => 'tr',
3707  'type' => HTML5::STARTTAG,
3708  'attr' => array()
3709  )
3710  );
3711 
3712  return $this->inRow($token);
3713 
3714  /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */
3715  } elseif ($token['type'] === HTML5::ENDTAG &&
3716  in_array($token['name'], array('tbody', 'tfoot', 'thead'))
3717  ) {
3718  /* If the stack of open elements does not have an element in table
3719  scope with the same tag name as the token, this is a parse error.
3720  Ignore the token. */
3721  if (!$this->elementInScope($token['name'], true)) {
3722  // Ignore
3723 
3724  /* Otherwise: */
3725  } else {
3726  /* Clear the stack back to a table body context. */
3727  $this->clearStackToTableContext($clear);
3728 
3729  /* Pop the current node from the stack of open elements. Switch
3730  the insertion mode to "in table". */
3731  array_pop($this->stack);
3732  $this->mode = self::IN_TABLE;
3733  }
3734 
3735  /* A start tag whose tag name is one of: "caption", "col", "colgroup",
3736  "tbody", "tfoot", "thead", or an end tag whose tag name is "table" */
3737  } elseif (($token['type'] === HTML5::STARTTAG && in_array(
3738  $token['name'],
3739  array('caption', 'col', 'colgroup', 'tbody', 'tfoor', 'thead')
3740  )) ||
3741  ($token['type'] === HTML5::STARTTAG && $token['name'] === 'table')
3742  ) {
3743  /* If the stack of open elements does not have a tbody, thead, or
3744  tfoot element in table scope, this is a parse error. Ignore the
3745  token. (innerHTML case) */
3746  if (!$this->elementInScope(array('tbody', 'thead', 'tfoot'), true)) {
3747  // Ignore.
3748 
3749  /* Otherwise: */
3750  } else {
3751  /* Clear the stack back to a table body context. */
3752  $this->clearStackToTableContext($clear);
3753 
3754  /* Act as if an end tag with the same tag name as the current
3755  node ("tbody", "tfoot", or "thead") had been seen, then
3756  reprocess the current token. */
3757  $this->inTableBody(
3758  array(
3759  'name' => end($this->stack)->nodeName,
3760  'type' => HTML5::ENDTAG
3761  )
3762  );
3763 
3764  return $this->mainPhase($token);
3765  }
3766 
3767  /* An end tag whose tag name is one of: "body", "caption", "col",
3768  "colgroup", "html", "td", "th", "tr" */
3769  } elseif ($token['type'] === HTML5::ENDTAG && in_array(
3770  $token['name'],
3771  array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr')
3772  )
3773  ) {
3774  /* Parse error. Ignore the token. */
3775 
3776  /* Anything else */
3777  } else {
3778  /* Process the token as if the insertion mode was "in table". */
3779  $this->inTable($token);
3780  }
3781  }
clearStackToTableContext($elements)
Definition: PH5P.php:4648
inTableBody($token)
Definition: PH5P.php:3684
elementInScope($el, $table=false)
Definition: PH5P.php:4465
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4393
Create styles array
The data for the language used.
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
mainPhase($token)
Definition: PH5P.php:1835

◆ mainPhase() [1/2]

HTML5TreeConstructer::mainPhase (   $token)
private

Definition at line 1317 of file PH5P.php.

References HTML5\$token, HTML5\DOCTYPE, HTML5\EOF(), and HTML5\STARTTAG.

1318  {
1319  /* Tokens in the main phase must be handled as follows: */
1320 
1321  /* A DOCTYPE token */
1322  if($token['type'] === HTML5::DOCTYPE) {
1323  // Parse error. Ignore the token.
1324 
1325  /* A start tag token with the tag name "html" */
1326  } elseif($token['type'] === HTML5::STARTTAG && $token['name'] === 'html') {
1327  /* If this start tag token was not the first start tag token, then
1328  it is a parse error. */
1329 
1330  /* For each attribute on the token, check to see if the attribute
1331  is already present on the top element of the stack of open elements.
1332  If it is not, add the attribute and its corresponding value to that
1333  element. */
1334  foreach($token['attr'] as $attr) {
1335  if(!$this->stack[0]->hasAttribute($attr['name'])) {
1336  $this->stack[0]->setAttribute($attr['name'], $attr['value']);
1337  }
1338  }
1339 
1340  /* An end-of-file token */
1341  } elseif($token['type'] === HTML5::EOF) {
1342  /* Generate implied end tags. */
1343  $this->generateImpliedEndTags();
1344 
1345  /* Anything else. */
1346  } else {
1347  /* Depends on the insertion mode: */
1348  switch($this->mode) {
1349  case self::BEFOR_HEAD: return $this->beforeHead($token); break;
1350  case self::IN_HEAD: return $this->inHead($token); break;
1351  case self::AFTER_HEAD: return $this->afterHead($token); break;
1352  case self::IN_BODY: return $this->inBody($token); break;
1353  case self::IN_TABLE: return $this->inTable($token); break;
1354  case self::IN_CAPTION: return $this->inCaption($token); break;
1355  case self::IN_CGROUP: return $this->inColumnGroup($token); break;
1356  case self::IN_TBODY: return $this->inTableBody($token); break;
1357  case self::IN_ROW: return $this->inRow($token); break;
1358  case self::IN_CELL: return $this->inCell($token); break;
1359  case self::IN_SELECT: return $this->inSelect($token); break;
1360  case self::AFTER_BODY: return $this->afterBody($token); break;
1361  case self::IN_FRAME: return $this->inFrameset($token); break;
1362  case self::AFTR_FRAME: return $this->afterFrameset($token); break;
1363  case self::END_PHASE: return $this->trailingEndPhase($token); break;
1364  }
1365  }
1366  }
inSelect($token)
Definition: PH5P.php:4020
EOF()
Definition: PH5P.php:1565
afterBody($token)
Definition: PH5P.php:4201
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4619
beforeHead($token)
Definition: PH5P.php:1916
afterHead($token)
Definition: PH5P.php:2112
inCaption($token)
Definition: PH5P.php:3527
afterFrameset($token)
Definition: PH5P.php:4311
inFrameset($token)
Definition: PH5P.php:4242
inTableBody($token)
Definition: PH5P.php:3684
const DOCTYPE
Definition: PH5P.php:454
inColumnGroup($token)
Definition: PH5P.php:3622
trailingEndPhase($token)
Definition: PH5P.php:4350
const STARTTAG
Definition: PH5P.php:455
+ Here is the call graph for this function:

◆ mainPhase() [2/2]

HTML5TreeConstructer::mainPhase (   $token)
private

Definition at line 1835 of file PH5P.php.

References HTML5\DOCTYPE, HTML5\EOF(), and HTML5\STARTTAG.

1836  {
1837  /* Tokens in the main phase must be handled as follows: */
1838 
1839  /* A DOCTYPE token */
1840  if ($token['type'] === HTML5::DOCTYPE) {
1841  // Parse error. Ignore the token.
1842 
1843  /* A start tag token with the tag name "html" */
1844  } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'html') {
1845  /* If this start tag token was not the first start tag token, then
1846  it is a parse error. */
1847 
1848  /* For each attribute on the token, check to see if the attribute
1849  is already present on the top element of the stack of open elements.
1850  If it is not, add the attribute and its corresponding value to that
1851  element. */
1852  foreach ($token['attr'] as $attr) {
1853  if (!$this->stack[0]->hasAttribute($attr['name'])) {
1854  $this->stack[0]->setAttribute($attr['name'], $attr['value']);
1855  }
1856  }
1857 
1858  /* An end-of-file token */
1859  } elseif ($token['type'] === HTML5::EOF) {
1860  /* Generate implied end tags. */
1861  $this->generateImpliedEndTags();
1862 
1863  /* Anything else. */
1864  } else {
1865  /* Depends on the insertion mode: */
1866  switch ($this->mode) {
1867  case self::BEFOR_HEAD:
1868  return $this->beforeHead($token);
1869  break;
1870  case self::IN_HEAD:
1871  return $this->inHead($token);
1872  break;
1873  case self::AFTER_HEAD:
1874  return $this->afterHead($token);
1875  break;
1876  case self::IN_BODY:
1877  return $this->inBody($token);
1878  break;
1879  case self::IN_TABLE:
1880  return $this->inTable($token);
1881  break;
1882  case self::IN_CAPTION:
1883  return $this->inCaption($token);
1884  break;
1885  case self::IN_CGROUP:
1886  return $this->inColumnGroup($token);
1887  break;
1888  case self::IN_TBODY:
1889  return $this->inTableBody($token);
1890  break;
1891  case self::IN_ROW:
1892  return $this->inRow($token);
1893  break;
1894  case self::IN_CELL:
1895  return $this->inCell($token);
1896  break;
1897  case self::IN_SELECT:
1898  return $this->inSelect($token);
1899  break;
1900  case self::AFTER_BODY:
1901  return $this->afterBody($token);
1902  break;
1903  case self::IN_FRAME:
1904  return $this->inFrameset($token);
1905  break;
1906  case self::AFTR_FRAME:
1907  return $this->afterFrameset($token);
1908  break;
1909  case self::END_PHASE:
1910  return $this->trailingEndPhase($token);
1911  break;
1912  }
1913  }
1914  }
inSelect($token)
Definition: PH5P.php:4020
EOF()
Definition: PH5P.php:1565
afterBody($token)
Definition: PH5P.php:4201
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4619
beforeHead($token)
Definition: PH5P.php:1916
afterHead($token)
Definition: PH5P.php:2112
inCaption($token)
Definition: PH5P.php:3527
afterFrameset($token)
Definition: PH5P.php:4311
inFrameset($token)
Definition: PH5P.php:4242
inTableBody($token)
Definition: PH5P.php:3684
const DOCTYPE
Definition: PH5P.php:454
inColumnGroup($token)
Definition: PH5P.php:3622
trailingEndPhase($token)
Definition: PH5P.php:4350
const STARTTAG
Definition: PH5P.php:455
+ Here is the call graph for this function:

◆ reconstructActiveFormattingElements() [1/2]

HTML5TreeConstructer::reconstructActiveFormattingElements ( )
private

Definition at line 3628 of file PH5P.php.

3629  {
3630  /* 1. If there are no entries in the list of active formatting elements,
3631  then there is nothing to reconstruct; stop this algorithm. */
3632  $formatting_elements = count($this->a_formatting);
3633 
3634  if($formatting_elements === 0) {
3635  return false;
3636  }
3637 
3638  /* 3. Let entry be the last (most recently added) element in the list
3639  of active formatting elements. */
3640  $entry = end($this->a_formatting);
3641 
3642  /* 2. If the last (most recently added) entry in the list of active
3643  formatting elements is a marker, or if it is an element that is in the
3644  stack of open elements, then there is nothing to reconstruct; stop this
3645  algorithm. */
3646  if($entry === self::MARKER || in_array($entry, $this->stack, true)) {
3647  return false;
3648  }
3649 
3650  for($a = $formatting_elements - 1; $a >= 0; true) {
3651  /* 4. If there are no entries before entry in the list of active
3652  formatting elements, then jump to step 8. */
3653  if($a === 0) {
3654  $step_seven = false;
3655  break;
3656  }
3657 
3658  /* 5. Let entry be the entry one earlier than entry in the list of
3659  active formatting elements. */
3660  $a--;
3661  $entry = $this->a_formatting[$a];
3662 
3663  /* 6. If entry is neither a marker nor an element that is also in
3664  thetack of open elements, go to step 4. */
3665  if($entry === self::MARKER || in_array($entry, $this->stack, true)) {
3666  break;
3667  }
3668  }
3669 
3670  while(true) {
3671  /* 7. Let entry be the element one later than entry in the list of
3672  active formatting elements. */
3673  if(isset($step_seven) && $step_seven === true) {
3674  $a++;
3675  $entry = $this->a_formatting[$a];
3676  }
3677 
3678  /* 8. Perform a shallow clone of the element entry to obtain clone. */
3679  $clone = $entry->cloneNode();
3680 
3681  /* 9. Append clone to the current node and push it onto the stack
3682  of open elements so that it is the new current node. */
3683  end($this->stack)->appendChild($clone);
3684  $this->stack[] = $clone;
3685 
3686  /* 10. Replace the entry for entry in the list with an entry for
3687  clone. */
3688  $this->a_formatting[$a] = $clone;
3689 
3690  /* 11. If the entry for clone in the list of active formatting
3691  elements is not the last entry in the list, return to step 7. */
3692  if(end($this->a_formatting) !== $clone) {
3693  $step_seven = true;
3694  } else {
3695  break;
3696  }
3697  }
3698  }

◆ reconstructActiveFormattingElements() [2/2]

HTML5TreeConstructer::reconstructActiveFormattingElements ( )
private

Definition at line 4525 of file PH5P.php.

4526  {
4527  /* 1. If there are no entries in the list of active formatting elements,
4528  then there is nothing to reconstruct; stop this algorithm. */
4529  $formatting_elements = count($this->a_formatting);
4530 
4531  if ($formatting_elements === 0) {
4532  return false;
4533  }
4534 
4535  /* 3. Let entry be the last (most recently added) element in the list
4536  of active formatting elements. */
4537  $entry = end($this->a_formatting);
4538 
4539  /* 2. If the last (most recently added) entry in the list of active
4540  formatting elements is a marker, or if it is an element that is in the
4541  stack of open elements, then there is nothing to reconstruct; stop this
4542  algorithm. */
4543  if ($entry === self::MARKER || in_array($entry, $this->stack, true)) {
4544  return false;
4545  }
4546 
4547  for ($a = $formatting_elements - 1; $a >= 0; true) {
4548  /* 4. If there are no entries before entry in the list of active
4549  formatting elements, then jump to step 8. */
4550  if ($a === 0) {
4551  $step_seven = false;
4552  break;
4553  }
4554 
4555  /* 5. Let entry be the entry one earlier than entry in the list of
4556  active formatting elements. */
4557  $a--;
4558  $entry = $this->a_formatting[$a];
4559 
4560  /* 6. If entry is neither a marker nor an element that is also in
4561  thetack of open elements, go to step 4. */
4562  if ($entry === self::MARKER || in_array($entry, $this->stack, true)) {
4563  break;
4564  }
4565  }
4566 
4567  while (true) {
4568  /* 7. Let entry be the element one later than entry in the list of
4569  active formatting elements. */
4570  if (isset($step_seven) && $step_seven === true) {
4571  $a++;
4572  $entry = $this->a_formatting[$a];
4573  }
4574 
4575  /* 8. Perform a shallow clone of the element entry to obtain clone. */
4576  $clone = $entry->cloneNode();
4577 
4578  /* 9. Append clone to the current node and push it onto the stack
4579  of open elements so that it is the new current node. */
4580  end($this->stack)->appendChild($clone);
4581  $this->stack[] = $clone;
4582 
4583  /* 10. Replace the entry for entry in the list with an entry for
4584  clone. */
4585  $this->a_formatting[$a] = $clone;
4586 
4587  /* 11. If the entry for clone in the list of active formatting
4588  elements is not the last entry in the list, return to step 7. */
4589  if (end($this->a_formatting) !== $clone) {
4590  $step_seven = true;
4591  } else {
4592  break;
4593  }
4594  }
4595  }

◆ resetInsertionMode() [1/2]

HTML5TreeConstructer::resetInsertionMode ( )
private

Definition at line 3770 of file PH5P.php.

References $n, and array.

3771  {
3772  /* 1. Let last be false. */
3773  $last = false;
3774  $leng = count($this->stack);
3775 
3776  for($n = $leng - 1; $n >= 0; $n--) {
3777  /* 2. Let node be the last node in the stack of open elements. */
3778  $node = $this->stack[$n];
3779 
3780  /* 3. If node is the first node in the stack of open elements, then
3781  set last to true. If the element whose innerHTML attribute is being
3782  set is neither a td element nor a th element, then set node to the
3783  element whose innerHTML attribute is being set. (innerHTML case) */
3784  if($this->stack[0]->isSameNode($node)) {
3785  $last = true;
3786  }
3787 
3788  /* 4. If node is a select element, then switch the insertion mode to
3789  "in select" and abort these steps. (innerHTML case) */
3790  if($node->nodeName === 'select') {
3791  $this->mode = self::IN_SELECT;
3792  break;
3793 
3794  /* 5. If node is a td or th element, then switch the insertion mode
3795  to "in cell" and abort these steps. */
3796  } elseif($node->nodeName === 'td' || $node->nodeName === 'th') {
3797  $this->mode = self::IN_CELL;
3798  break;
3799 
3800  /* 6. If node is a tr element, then switch the insertion mode to
3801  "in row" and abort these steps. */
3802  } elseif($node->nodeName === 'tr') {
3803  $this->mode = self::IN_ROW;
3804  break;
3805 
3806  /* 7. If node is a tbody, thead, or tfoot element, then switch the
3807  insertion mode to "in table body" and abort these steps. */
3808  } elseif(in_array($node->nodeName, array('tbody', 'thead', 'tfoot'))) {
3809  $this->mode = self::IN_TBODY;
3810  break;
3811 
3812  /* 8. If node is a caption element, then switch the insertion mode
3813  to "in caption" and abort these steps. */
3814  } elseif($node->nodeName === 'caption') {
3815  $this->mode = self::IN_CAPTION;
3816  break;
3817 
3818  /* 9. If node is a colgroup element, then switch the insertion mode
3819  to "in column group" and abort these steps. (innerHTML case) */
3820  } elseif($node->nodeName === 'colgroup') {
3821  $this->mode = self::IN_CGROUP;
3822  break;
3823 
3824  /* 10. If node is a table element, then switch the insertion mode
3825  to "in table" and abort these steps. */
3826  } elseif($node->nodeName === 'table') {
3827  $this->mode = self::IN_TABLE;
3828  break;
3829 
3830  /* 11. If node is a head element, then switch the insertion mode
3831  to "in body" ("in body"! not "in head"!) and abort these steps.
3832  (innerHTML case) */
3833  } elseif($node->nodeName === 'head') {
3834  $this->mode = self::IN_BODY;
3835  break;
3836 
3837  /* 12. If node is a body element, then switch the insertion mode to
3838  "in body" and abort these steps. */
3839  } elseif($node->nodeName === 'body') {
3840  $this->mode = self::IN_BODY;
3841  break;
3842 
3843  /* 13. If node is a frameset element, then switch the insertion
3844  mode to "in frameset" and abort these steps. (innerHTML case) */
3845  } elseif($node->nodeName === 'frameset') {
3846  $this->mode = self::IN_FRAME;
3847  break;
3848 
3849  /* 14. If node is an html element, then: if the head element
3850  pointer is null, switch the insertion mode to "before head",
3851  otherwise, switch the insertion mode to "after head". In either
3852  case, abort these steps. (innerHTML case) */
3853  } elseif($node->nodeName === 'html') {
3854  $this->mode = ($this->head_pointer === null)
3855  ? self::BEFOR_HEAD
3856  : self::AFTER_HEAD;
3857 
3858  break;
3859 
3860  /* 15. If last is true, then set the insertion mode to "in body"
3861  and abort these steps. (innerHTML case) */
3862  } elseif($last) {
3863  $this->mode = self::IN_BODY;
3864  break;
3865  }
3866  }
3867  }
$n
Definition: RandomTest.php:80
Create styles array
The data for the language used.

◆ resetInsertionMode() [2/2]

HTML5TreeConstructer::resetInsertionMode ( )
private

Definition at line 4666 of file PH5P.php.

References $n, and array.

4667  {
4668  /* 1. Let last be false. */
4669  $last = false;
4670  $leng = count($this->stack);
4671 
4672  for ($n = $leng - 1; $n >= 0; $n--) {
4673  /* 2. Let node be the last node in the stack of open elements. */
4674  $node = $this->stack[$n];
4675 
4676  /* 3. If node is the first node in the stack of open elements, then
4677  set last to true. If the element whose innerHTML attribute is being
4678  set is neither a td element nor a th element, then set node to the
4679  element whose innerHTML attribute is being set. (innerHTML case) */
4680  if ($this->stack[0]->isSameNode($node)) {
4681  $last = true;
4682  }
4683 
4684  /* 4. If node is a select element, then switch the insertion mode to
4685  "in select" and abort these steps. (innerHTML case) */
4686  if ($node->nodeName === 'select') {
4687  $this->mode = self::IN_SELECT;
4688  break;
4689 
4690  /* 5. If node is a td or th element, then switch the insertion mode
4691  to "in cell" and abort these steps. */
4692  } elseif ($node->nodeName === 'td' || $node->nodeName === 'th') {
4693  $this->mode = self::IN_CELL;
4694  break;
4695 
4696  /* 6. If node is a tr element, then switch the insertion mode to
4697  "in row" and abort these steps. */
4698  } elseif ($node->nodeName === 'tr') {
4699  $this->mode = self::IN_ROW;
4700  break;
4701 
4702  /* 7. If node is a tbody, thead, or tfoot element, then switch the
4703  insertion mode to "in table body" and abort these steps. */
4704  } elseif (in_array($node->nodeName, array('tbody', 'thead', 'tfoot'))) {
4705  $this->mode = self::IN_TBODY;
4706  break;
4707 
4708  /* 8. If node is a caption element, then switch the insertion mode
4709  to "in caption" and abort these steps. */
4710  } elseif ($node->nodeName === 'caption') {
4711  $this->mode = self::IN_CAPTION;
4712  break;
4713 
4714  /* 9. If node is a colgroup element, then switch the insertion mode
4715  to "in column group" and abort these steps. (innerHTML case) */
4716  } elseif ($node->nodeName === 'colgroup') {
4717  $this->mode = self::IN_CGROUP;
4718  break;
4719 
4720  /* 10. If node is a table element, then switch the insertion mode
4721  to "in table" and abort these steps. */
4722  } elseif ($node->nodeName === 'table') {
4723  $this->mode = self::IN_TABLE;
4724  break;
4725 
4726  /* 11. If node is a head element, then switch the insertion mode
4727  to "in body" ("in body"! not "in head"!) and abort these steps.
4728  (innerHTML case) */
4729  } elseif ($node->nodeName === 'head') {
4730  $this->mode = self::IN_BODY;
4731  break;
4732 
4733  /* 12. If node is a body element, then switch the insertion mode to
4734  "in body" and abort these steps. */
4735  } elseif ($node->nodeName === 'body') {
4736  $this->mode = self::IN_BODY;
4737  break;
4738 
4739  /* 13. If node is a frameset element, then switch the insertion
4740  mode to "in frameset" and abort these steps. (innerHTML case) */
4741  } elseif ($node->nodeName === 'frameset') {
4742  $this->mode = self::IN_FRAME;
4743  break;
4744 
4745  /* 14. If node is an html element, then: if the head element
4746  pointer is null, switch the insertion mode to "before head",
4747  otherwise, switch the insertion mode to "after head". In either
4748  case, abort these steps. (innerHTML case) */
4749  } elseif ($node->nodeName === 'html') {
4750  $this->mode = ($this->head_pointer === null)
4751  ? self::BEFOR_HEAD
4752  : self::AFTER_HEAD;
4753 
4754  break;
4755 
4756  /* 15. If last is true, then set the insertion mode to "in body"
4757  and abort these steps. (innerHTML case) */
4758  } elseif ($last) {
4759  $this->mode = self::IN_BODY;
4760  break;
4761  }
4762  }
4763  }
$n
Definition: RandomTest.php:80
Create styles array
The data for the language used.

◆ rootElementPhase() [1/2]

HTML5TreeConstructer::rootElementPhase (   $token)
private

Definition at line 1269 of file PH5P.php.

References $comment, $html, $text, HTML5\$token, HTML5\CHARACTR, HTML5\COMMENT, HTML5\DOCTYPE, HTML5\ENDTAG, HTML5\EOF(), and HTML5\STARTTAG.

1270  {
1271  /* After the initial phase, as each token is emitted from the tokenisation
1272  stage, it must be processed as described in this section. */
1273 
1274  /* A DOCTYPE token */
1275  if($token['type'] === HTML5::DOCTYPE) {
1276  // Parse error. Ignore the token.
1277 
1278  /* A comment token */
1279  } elseif($token['type'] === HTML5::COMMENT) {
1280  /* Append a Comment node to the Document object with the data
1281  attribute set to the data given in the comment token. */
1282  $comment = $this->dom->createComment($token['data']);
1283  $this->dom->appendChild($comment);
1284 
1285  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
1286  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1287  or U+0020 SPACE */
1288  } elseif($token['type'] === HTML5::CHARACTR &&
1289  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) {
1290  /* Append that character to the Document node. */
1291  $text = $this->dom->createTextNode($token['data']);
1292  $this->dom->appendChild($text);
1293 
1294  /* A character token that is not one of U+0009 CHARACTER TABULATION,
1295  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED
1296  (FF), or U+0020 SPACE
1297  A start tag token
1298  An end tag token
1299  An end-of-file token */
1300  } elseif(($token['type'] === HTML5::CHARACTR &&
1301  !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) ||
1302  $token['type'] === HTML5::STARTTAG ||
1303  $token['type'] === HTML5::ENDTAG ||
1304  $token['type'] === HTML5::EOF) {
1305  /* Create an HTMLElement node with the tag name html, in the HTML
1306  namespace. Append it to the Document object. Switch to the main
1307  phase and reprocess the current token. */
1308  $html = $this->dom->createElement('html');
1309  $this->dom->appendChild($html);
1310  $this->stack[] = $html;
1311 
1312  $this->phase = self::MAIN_PHASE;
1313  return $this->mainPhase($token);
1314  }
1315  }
const COMMENT
Definition: PH5P.php:457
EOF()
Definition: PH5P.php:1565
const DOCTYPE
Definition: PH5P.php:454
$comment
Definition: buildRTE.php:83
const CHARACTR
Definition: PH5P.php:458
$text
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
$html
Definition: example_001.php:87
mainPhase($token)
Definition: PH5P.php:1835
+ Here is the call graph for this function:

◆ rootElementPhase() [2/2]

HTML5TreeConstructer::rootElementPhase (   $token)
private

Definition at line 1785 of file PH5P.php.

References $comment, $html, $text, HTML5\CHARACTR, HTML5\COMMENT, HTML5\DOCTYPE, HTML5\ENDTAG, HTML5\EOF(), and HTML5\STARTTAG.

1786  {
1787  /* After the initial phase, as each token is emitted from the tokenisation
1788  stage, it must be processed as described in this section. */
1789 
1790  /* A DOCTYPE token */
1791  if ($token['type'] === HTML5::DOCTYPE) {
1792  // Parse error. Ignore the token.
1793 
1794  /* A comment token */
1795  } elseif ($token['type'] === HTML5::COMMENT) {
1796  /* Append a Comment node to the Document object with the data
1797  attribute set to the data given in the comment token. */
1798  $comment = $this->dom->createComment($token['data']);
1799  $this->dom->appendChild($comment);
1800 
1801  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
1802  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
1803  or U+0020 SPACE */
1804  } elseif ($token['type'] === HTML5::CHARACTR &&
1805  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
1806  ) {
1807  /* Append that character to the Document node. */
1808  $text = $this->dom->createTextNode($token['data']);
1809  $this->dom->appendChild($text);
1810 
1811  /* A character token that is not one of U+0009 CHARACTER TABULATION,
1812  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED
1813  (FF), or U+0020 SPACE
1814  A start tag token
1815  An end tag token
1816  An end-of-file token */
1817  } elseif (($token['type'] === HTML5::CHARACTR &&
1818  !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) ||
1819  $token['type'] === HTML5::STARTTAG ||
1820  $token['type'] === HTML5::ENDTAG ||
1821  $token['type'] === HTML5::EOF
1822  ) {
1823  /* Create an HTMLElement node with the tag name html, in the HTML
1824  namespace. Append it to the Document object. Switch to the main
1825  phase and reprocess the current token. */
1826  $html = $this->dom->createElement('html');
1827  $this->dom->appendChild($html);
1828  $this->stack[] = $html;
1829 
1830  $this->phase = self::MAIN_PHASE;
1831  return $this->mainPhase($token);
1832  }
1833  }
const COMMENT
Definition: PH5P.php:457
EOF()
Definition: PH5P.php:1565
const DOCTYPE
Definition: PH5P.php:454
$comment
Definition: buildRTE.php:83
const CHARACTR
Definition: PH5P.php:458
$text
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
$html
Definition: example_001.php:87
mainPhase($token)
Definition: PH5P.php:1835
+ Here is the call graph for this function:

◆ save() [1/2]

HTML5TreeConstructer::save ( )

Definition at line 3885 of file PH5P.php.

3886  {
3887  return $this->dom;
3888  }

◆ save() [2/2]

HTML5TreeConstructer::save ( )

Definition at line 4783 of file PH5P.php.

4784  {
4785  return $this->dom;
4786  }

◆ trailingEndPhase() [1/2]

HTML5TreeConstructer::trailingEndPhase (   $token)
private

Definition at line 3480 of file PH5P.php.

References $comment, HTML5\$token, HTML5\CHARACTR, HTML5\COMMENT, HTML5\DOCTYPE, HTML5\ENDTAG, HTML5\EOF(), and HTML5\STARTTAG.

3481  {
3482  /* After the main phase, as each token is emitted from the tokenisation
3483  stage, it must be processed as described in this section. */
3484 
3485  /* A DOCTYPE token */
3486  if($token['type'] === HTML5::DOCTYPE) {
3487  // Parse error. Ignore the token.
3488 
3489  /* A comment token */
3490  } elseif($token['type'] === HTML5::COMMENT) {
3491  /* Append a Comment node to the Document object with the data
3492  attribute set to the data given in the comment token. */
3493  $comment = $this->dom->createComment($token['data']);
3494  $this->dom->appendChild($comment);
3495 
3496  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
3497  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
3498  or U+0020 SPACE */
3499  } elseif($token['type'] === HTML5::CHARACTR &&
3500  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) {
3501  /* Process the token as it would be processed in the main phase. */
3502  $this->mainPhase($token);
3503 
3504  /* A character token that is not one of U+0009 CHARACTER TABULATION,
3505  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
3506  or U+0020 SPACE. Or a start tag token. Or an end tag token. */
3507  } elseif(($token['type'] === HTML5::CHARACTR &&
3508  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) ||
3509  $token['type'] === HTML5::STARTTAG || $token['type'] === HTML5::ENDTAG) {
3510  /* Parse error. Switch back to the main phase and reprocess the
3511  token. */
3512  $this->phase = self::MAIN_PHASE;
3513  return $this->mainPhase($token);
3514 
3515  /* An end-of-file token */
3516  } elseif($token['type'] === HTML5::EOF) {
3517  /* OMG DONE!! */
3518  }
3519  }
const COMMENT
Definition: PH5P.php:457
EOF()
Definition: PH5P.php:1565
const DOCTYPE
Definition: PH5P.php:454
$comment
Definition: buildRTE.php:83
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
mainPhase($token)
Definition: PH5P.php:1835
+ Here is the call graph for this function:

◆ trailingEndPhase() [2/2]

HTML5TreeConstructer::trailingEndPhase (   $token)
private

Definition at line 4350 of file PH5P.php.

References $comment, HTML5\CHARACTR, HTML5\COMMENT, HTML5\DOCTYPE, HTML5\ENDTAG, HTML5\EOF(), and HTML5\STARTTAG.

4351  {
4352  /* After the main phase, as each token is emitted from the tokenisation
4353  stage, it must be processed as described in this section. */
4354 
4355  /* A DOCTYPE token */
4356  if ($token['type'] === HTML5::DOCTYPE) {
4357  // Parse error. Ignore the token.
4358 
4359  /* A comment token */
4360  } elseif ($token['type'] === HTML5::COMMENT) {
4361  /* Append a Comment node to the Document object with the data
4362  attribute set to the data given in the comment token. */
4363  $comment = $this->dom->createComment($token['data']);
4364  $this->dom->appendChild($comment);
4365 
4366  /* A character token that is one of one of U+0009 CHARACTER TABULATION,
4367  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
4368  or U+0020 SPACE */
4369  } elseif ($token['type'] === HTML5::CHARACTR &&
4370  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])
4371  ) {
4372  /* Process the token as it would be processed in the main phase. */
4373  $this->mainPhase($token);
4374 
4375  /* A character token that is not one of U+0009 CHARACTER TABULATION,
4376  U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
4377  or U+0020 SPACE. Or a start tag token. Or an end tag token. */
4378  } elseif (($token['type'] === HTML5::CHARACTR &&
4379  preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) ||
4380  $token['type'] === HTML5::STARTTAG || $token['type'] === HTML5::ENDTAG
4381  ) {
4382  /* Parse error. Switch back to the main phase and reprocess the
4383  token. */
4384  $this->phase = self::MAIN_PHASE;
4385  return $this->mainPhase($token);
4386 
4387  /* An end-of-file token */
4388  } elseif ($token['type'] === HTML5::EOF) {
4389  /* OMG DONE!! */
4390  }
4391  }
const COMMENT
Definition: PH5P.php:457
EOF()
Definition: PH5P.php:1565
const DOCTYPE
Definition: PH5P.php:454
$comment
Definition: buildRTE.php:83
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
mainPhase($token)
Definition: PH5P.php:1835
+ Here is the call graph for this function:

Field Documentation

◆ $a_formatting

HTML5TreeConstructer::$a_formatting = array()
private

Definition at line 1584 of file PH5P.php.

◆ $dom

HTML5TreeConstructer::$dom
private

Definition at line 1582 of file PH5P.php.

◆ $form_pointer

HTML5TreeConstructer::$form_pointer = null
private

Definition at line 1587 of file PH5P.php.

◆ $formatting

HTML5TreeConstructer::$formatting
private
Initial value:
'a',
'b',
'big',
'em',
'font',
'i',
'nobr',
's',
'small',
'strike',
'strong',
'tt',
'u'
)

Definition at line 1590 of file PH5P.php.

◆ $foster_parent

HTML5TreeConstructer::$foster_parent = null
private

Definition at line 1583 of file PH5P.php.

◆ $head_pointer

HTML5TreeConstructer::$head_pointer = null
private

Definition at line 1586 of file PH5P.php.

◆ $mode

HTML5TreeConstructer::$mode
private

Definition at line 1581 of file PH5P.php.

◆ $phase

HTML5TreeConstructer::$phase
private

Definition at line 1580 of file PH5P.php.

◆ $scoping

HTML5TreeConstructer::$scoping = array('button', 'caption', 'html', 'marquee', 'object', 'table', 'td', 'th')
private

Definition at line 1589 of file PH5P.php.

◆ $special

HTML5TreeConstructer::$special
private

Definition at line 1605 of file PH5P.php.

◆ $stack

HTML5TreeConstructer::$stack = array()

Definition at line 1578 of file PH5P.php.

◆ AFTER_BODY

const HTML5TreeConstructer::AFTER_BODY = 11

Definition at line 1687 of file PH5P.php.

◆ AFTER_HEAD

const HTML5TreeConstructer::AFTER_HEAD = 2

Definition at line 1678 of file PH5P.php.

◆ AFTR_FRAME

const HTML5TreeConstructer::AFTR_FRAME = 13

Definition at line 1689 of file PH5P.php.

◆ BEFOR_HEAD

const HTML5TreeConstructer::BEFOR_HEAD = 0

Definition at line 1676 of file PH5P.php.

◆ END_PHASE

const HTML5TreeConstructer::END_PHASE = 3

Definition at line 1673 of file PH5P.php.

◆ FORMATTING

const HTML5TreeConstructer::FORMATTING = 2

Definition at line 1694 of file PH5P.php.

◆ IN_BODY

const HTML5TreeConstructer::IN_BODY = 3

Definition at line 1679 of file PH5P.php.

◆ IN_CAPTION

const HTML5TreeConstructer::IN_CAPTION = 5

Definition at line 1681 of file PH5P.php.

◆ IN_CELL

const HTML5TreeConstructer::IN_CELL = 9

Definition at line 1685 of file PH5P.php.

◆ IN_CGROUP

const HTML5TreeConstructer::IN_CGROUP = 6

Definition at line 1682 of file PH5P.php.

◆ IN_FRAME

const HTML5TreeConstructer::IN_FRAME = 12

Definition at line 1688 of file PH5P.php.

◆ IN_HEAD

const HTML5TreeConstructer::IN_HEAD = 1

Definition at line 1677 of file PH5P.php.

◆ IN_ROW

const HTML5TreeConstructer::IN_ROW = 8

Definition at line 1684 of file PH5P.php.

◆ IN_SELECT

const HTML5TreeConstructer::IN_SELECT = 10

Definition at line 1686 of file PH5P.php.

◆ IN_TABLE

const HTML5TreeConstructer::IN_TABLE = 4

Definition at line 1680 of file PH5P.php.

◆ IN_TBODY

const HTML5TreeConstructer::IN_TBODY = 7

Definition at line 1683 of file PH5P.php.

◆ INIT_PHASE

const HTML5TreeConstructer::INIT_PHASE = 0

Definition at line 1670 of file PH5P.php.

◆ MAIN_PHASE

const HTML5TreeConstructer::MAIN_PHASE = 2

Definition at line 1672 of file PH5P.php.

◆ MARKER

const HTML5TreeConstructer::MARKER = 0

Definition at line 1697 of file PH5P.php.

◆ PHRASING

const HTML5TreeConstructer::PHRASING = 3

Definition at line 1695 of file PH5P.php.

◆ ROOT_PHASE

const HTML5TreeConstructer::ROOT_PHASE = 1

Definition at line 1671 of file PH5P.php.

◆ SCOPING

const HTML5TreeConstructer::SCOPING = 1

Definition at line 1693 of file PH5P.php.

◆ SPECIAL

const HTML5TreeConstructer::SPECIAL = 0

Definition at line 1692 of file PH5P.php.


The documentation for this class was generated from the following file: