ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 1577 of file PH5P.php.

Constructor & Destructor Documentation

◆ __construct() [1/2]

HTML5TreeConstructer::__construct ( )

Definition at line 1700 of file PH5P.php.

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

◆ __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 4202 of file PH5P.php.

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

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

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

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

◆ afterHead() [2/2]

HTML5TreeConstructer::afterHead (   $token)
private

Definition at line 2113 of file PH5P.php.

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

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

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:85
if(empty($password)) $table
Definition: pwgen.php:24

◆ appendToRealParent() [2/2]

HTML5TreeConstructer::appendToRealParent (   $node)
private

Definition at line 4435 of file PH5P.php.

References $n, and $table.

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

◆ 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:1917
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4394
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4429
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 1917 of file PH5P.php.

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

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

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

◆ 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 4598 of file PH5P.php.

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

◆ 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:4466
Create styles array
The data for the language used.
const ENDTAG
Definition: PH5P.php:456

◆ closeCell() [2/2]

HTML5TreeConstructer::closeCell ( )
private

Definition at line 4766 of file PH5P.php.

References array, and HTML5\ENDTAG.

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

◆ elementInScope() [2/2]

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

Definition at line 4466 of file PH5P.php.

References $n, $table, and array.

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

◆ 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:1786
initPhase($token)
Definition: PH5P.php:1731
trailingEndPhase($token)
Definition: PH5P.php:4351
mainPhase($token)
Definition: PH5P.php:1836

◆ emitToken() [2/2]

HTML5TreeConstructer::emitToken (   $token)

Definition at line 1713 of file PH5P.php.

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

◆ 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 4620 of file PH5P.php.

References $exclude, and array.

4621  {
4622  /* When the steps below require the UA to generate implied end tags,
4623  then, if the current node is a dd element, a dt element, an li element,
4624  a p element, a td element, a th element, or a tr element, the UA must
4625  act as if an end tag with the respective tag name had been seen and
4626  then generate implied end tags again. */
4627  $node = end($this->stack);
4628  $elements = array_diff(array('dd', 'dt', 'li', 'p', 'td', 'th', 'tr'), $exclude);
4629 
4630  while (in_array(end($this->stack)->nodeName, $elements)) {
4631  array_pop($this->stack);
4632  }
4633  }
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 $name, and 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
if($format !==null) $name
Definition: metadata.php:146

◆ getElementCategory() [2/2]

HTML5TreeConstructer::getElementCategory (   $node)
private

Definition at line 4635 of file PH5P.php.

References $name, and formatting.

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

◆ inBody() [1/2]

HTML5TreeConstructer::inBody (   $token)
private

Definition at line 1605 of file PH5P.php.

References $n, $s, 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:1713
const RCDATA
Definition: PH5P.php:450
getElementCategory($node)
Definition: PH5P.php:4635
const COMMENT
Definition: PH5P.php:457
$x
Definition: example_009.php:98
afterBody($token)
Definition: PH5P.php:4202
const CDATA
Definition: PH5P.php:451
$s
Definition: pwgen.php:45
const PLAINTEXT
Definition: PH5P.php:452
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4620
elementInScope($el, $table=false)
Definition: PH5P.php:4466
$n
Definition: RandomTest.php:85
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4394
Create styles array
The data for the language used.
insertComment($data)
Definition: PH5P.php:4429
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
const STARTTAG
Definition: PH5P.php:455
reconstructActiveFormattingElements()
Definition: PH5P.php:4526
+ Here is the call graph for this function:

◆ inBody() [2/2]

HTML5TreeConstructer::inBody (   $token)
private

Definition at line 2176 of file PH5P.php.

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

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

◆ 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:4598
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4620
inCaption($token)
Definition: PH5P.php:3528
elementInScope($el, $table=false)
Definition: PH5P.php:4466
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 3528 of file PH5P.php.

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

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

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

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

◆ inColumnGroup() [2/2]

HTML5TreeConstructer::inColumnGroup (   $token)
private

Definition at line 3623 of file PH5P.php.

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

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

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

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

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

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

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

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

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

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

◆ inSelect() [2/2]

HTML5TreeConstructer::inSelect (   $token)
private

Definition at line 4021 of file PH5P.php.

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

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

◆ 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:4435

◆ insertComment() [2/2]

HTML5TreeConstructer::insertComment (   $data)
private

Definition at line 4429 of file PH5P.php.

References $comment, and $data.

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

◆ 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:4435

◆ insertElement() [2/2]

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

Definition at line 4394 of file PH5P.php.

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

◆ 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  }
$text
Definition: errorreport.php:18
appendToRealParent($node)
Definition: PH5P.php:4435

◆ insertText() [2/2]

HTML5TreeConstructer::insertText (   $data)
private

Definition at line 4423 of file PH5P.php.

References $data, and $text.

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

◆ inTable() [1/2]

HTML5TreeConstructer::inTable (   $token)
private

Definition at line 2604 of file PH5P.php.

References $comment, $current, $n, $table, $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:4620
clearStackToTableContext($elements)
Definition: PH5P.php:4649
$text
Definition: errorreport.php:18
inTableBody($token)
Definition: PH5P.php:3685
elementInScope($el, $table=false)
Definition: PH5P.php:4466
inColumnGroup($token)
Definition: PH5P.php:3623
$n
Definition: RandomTest.php:85
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4394
$comment
Definition: buildRTE.php:83
Create styles array
The data for the language used.
const CHARACTR
Definition: PH5P.php:458
const ENDTAG
Definition: PH5P.php:456
if(empty($password)) $table
Definition: pwgen.php:24
const STARTTAG
Definition: PH5P.php:455
mainPhase($token)
Definition: PH5P.php:1836

◆ inTable() [2/2]

HTML5TreeConstructer::inTable (   $token)
private

Definition at line 3316 of file PH5P.php.

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

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

◆ 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:4649
inTableBody($token)
Definition: PH5P.php:3685
elementInScope($el, $table=false)
Definition: PH5P.php:4466
insertElement($token, $append=true, $check=false)
Definition: PH5P.php:4394
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:1836

◆ inTableBody() [2/2]

HTML5TreeConstructer::inTableBody (   $token)
private

Definition at line 3685 of file PH5P.php.

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

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

◆ 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:4021
EOF()
Definition: PH5P.php:1566
afterBody($token)
Definition: PH5P.php:4202
generateImpliedEndTags($exclude=array())
Definition: PH5P.php:4620
beforeHead($token)
Definition: PH5P.php:1917
afterHead($token)
Definition: PH5P.php:2113
inCaption($token)
Definition: PH5P.php:3528
afterFrameset($token)
Definition: PH5P.php:4312
inFrameset($token)
Definition: PH5P.php:4243
inTableBody($token)
Definition: PH5P.php:3685
const DOCTYPE
Definition: PH5P.php:454
inColumnGroup($token)
Definition: PH5P.php:3623
trailingEndPhase($token)
Definition: PH5P.php:4351
const STARTTAG
Definition: PH5P.php:455
+ Here is the call graph for this function:

◆ mainPhase() [2/2]

HTML5TreeConstructer::mainPhase (   $token)
private

Definition at line 1836 of file PH5P.php.

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

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

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

◆ 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:85
Create styles array
The data for the language used.

◆ resetInsertionMode() [2/2]

HTML5TreeConstructer::resetInsertionMode ( )
private

Definition at line 4667 of file PH5P.php.

References $n, and array.

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

◆ rootElementPhase() [2/2]

HTML5TreeConstructer::rootElementPhase (   $token)
private

Definition at line 1786 of file PH5P.php.

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

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

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

◆ 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:1566
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:1836
+ Here is the call graph for this function:

◆ trailingEndPhase() [2/2]

HTML5TreeConstructer::trailingEndPhase (   $token)
private

Definition at line 4351 of file PH5P.php.

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

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

Field Documentation

◆ $a_formatting

HTML5TreeConstructer::$a_formatting = array()
private

Definition at line 1585 of file PH5P.php.

◆ $dom

HTML5TreeConstructer::$dom
private

Definition at line 1583 of file PH5P.php.

◆ $form_pointer

HTML5TreeConstructer::$form_pointer = null
private

Definition at line 1588 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 1591 of file PH5P.php.

◆ $foster_parent

HTML5TreeConstructer::$foster_parent = null
private

Definition at line 1584 of file PH5P.php.

◆ $head_pointer

HTML5TreeConstructer::$head_pointer = null
private

Definition at line 1587 of file PH5P.php.

◆ $mode

HTML5TreeConstructer::$mode
private

Definition at line 1582 of file PH5P.php.

◆ $phase

HTML5TreeConstructer::$phase
private

Definition at line 1581 of file PH5P.php.

◆ $scoping

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

Definition at line 1590 of file PH5P.php.

◆ $special

HTML5TreeConstructer::$special
private

Definition at line 1606 of file PH5P.php.

◆ $stack

HTML5TreeConstructer::$stack = array()

Definition at line 1579 of file PH5P.php.

◆ AFTER_BODY

const HTML5TreeConstructer::AFTER_BODY = 11

Definition at line 1688 of file PH5P.php.

◆ AFTER_HEAD

const HTML5TreeConstructer::AFTER_HEAD = 2

Definition at line 1679 of file PH5P.php.

◆ AFTR_FRAME

const HTML5TreeConstructer::AFTR_FRAME = 13

Definition at line 1690 of file PH5P.php.

◆ BEFOR_HEAD

const HTML5TreeConstructer::BEFOR_HEAD = 0

Definition at line 1677 of file PH5P.php.

◆ END_PHASE

const HTML5TreeConstructer::END_PHASE = 3

Definition at line 1674 of file PH5P.php.

◆ FORMATTING

const HTML5TreeConstructer::FORMATTING = 2

Definition at line 1695 of file PH5P.php.

◆ IN_BODY

const HTML5TreeConstructer::IN_BODY = 3

Definition at line 1680 of file PH5P.php.

◆ IN_CAPTION

const HTML5TreeConstructer::IN_CAPTION = 5

Definition at line 1682 of file PH5P.php.

◆ IN_CELL

const HTML5TreeConstructer::IN_CELL = 9

Definition at line 1686 of file PH5P.php.

◆ IN_CGROUP

const HTML5TreeConstructer::IN_CGROUP = 6

Definition at line 1683 of file PH5P.php.

◆ IN_FRAME

const HTML5TreeConstructer::IN_FRAME = 12

Definition at line 1689 of file PH5P.php.

◆ IN_HEAD

const HTML5TreeConstructer::IN_HEAD = 1

Definition at line 1678 of file PH5P.php.

◆ IN_ROW

const HTML5TreeConstructer::IN_ROW = 8

Definition at line 1685 of file PH5P.php.

◆ IN_SELECT

const HTML5TreeConstructer::IN_SELECT = 10

Definition at line 1687 of file PH5P.php.

◆ IN_TABLE

const HTML5TreeConstructer::IN_TABLE = 4

Definition at line 1681 of file PH5P.php.

◆ IN_TBODY

const HTML5TreeConstructer::IN_TBODY = 7

Definition at line 1684 of file PH5P.php.

◆ INIT_PHASE

const HTML5TreeConstructer::INIT_PHASE = 0

Definition at line 1671 of file PH5P.php.

◆ MAIN_PHASE

const HTML5TreeConstructer::MAIN_PHASE = 2

Definition at line 1673 of file PH5P.php.

◆ MARKER

const HTML5TreeConstructer::MARKER = 0

Definition at line 1698 of file PH5P.php.

◆ PHRASING

const HTML5TreeConstructer::PHRASING = 3

Definition at line 1696 of file PH5P.php.

◆ ROOT_PHASE

const HTML5TreeConstructer::ROOT_PHASE = 1

Definition at line 1672 of file PH5P.php.

◆ SCOPING

const HTML5TreeConstructer::SCOPING = 1

Definition at line 1694 of file PH5P.php.

◆ SPECIAL

const HTML5TreeConstructer::SPECIAL = 0

Definition at line 1693 of file PH5P.php.


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