How to use next method of Anything class

Best AspectMock code snippet using Anything.next

Tokenizer.php

Source:Tokenizer.php Github

copy

Full Screen

...123 if ($escape) echo " escape";124 echo "\n";*/125 switch($state) {126 case 'data':127 /* Consume the next input character */128 $char = $this->stream->char();129 $lastFourChars .= $char;130 if (strlen($lastFourChars) > 4) {131 $lastFourChars = substr($lastFourChars, -4);132 }133 // see below for meaning134 $hyp_cond =135 !$escape &&136 (137 $this->content_model === self::RCDATA ||138 $this->content_model === self::CDATA139 );140 $amp_cond =141 !$escape &&142 (143 $this->content_model === self::PCDATA ||144 $this->content_model === self::RCDATA145 );146 $lt_cond =147 $this->content_model === self::PCDATA ||148 (149 (150 $this->content_model === self::RCDATA ||151 $this->content_model === self::CDATA152 ) &&153 !$escape154 );155 $gt_cond =156 $escape &&157 (158 $this->content_model === self::RCDATA ||159 $this->content_model === self::CDATA160 );161 if ($char === '&' && $amp_cond === true) {162 /* U+0026 AMPERSAND (&)163 When the content model flag is set to one of the PCDATA or RCDATA164 states and the escape flag is false: switch to the165 character reference data state. Otherwise: treat it as per166 the "anything else" entry below. */167 $state = 'character reference data';168 } elseif (169 $char === '-' &&170 $hyp_cond === true &&171 $lastFourChars === '<!--'172 ) {173 /*174 U+002D HYPHEN-MINUS (-)175 If the content model flag is set to either the RCDATA state or176 the CDATA state, and the escape flag is false, and there are at177 least three characters before this one in the input stream, and the178 last four characters in the input stream, including this one, are179 U+003C LESS-THAN SIGN, U+0021 EXCLAMATION MARK, U+002D HYPHEN-MINUS,180 and U+002D HYPHEN-MINUS ("<!--"), then set the escape flag to true. */181 $escape = true;182 /* In any case, emit the input character as a character token. Stay183 in the data state. */184 $this->emitToken([185 'type' => self::CHARACTER,186 'data' => '-'187 ]);188 // We do the "any case" part as part of "anything else".189 /* U+003C LESS-THAN SIGN (<) */190 } elseif ($char === '<' && $lt_cond === true) {191 /* When the content model flag is set to the PCDATA state: switch192 to the tag open state.193 When the content model flag is set to either the RCDATA state or194 the CDATA state and the escape flag is false: switch to the tag195 open state.196 Otherwise: treat it as per the "anything else" entry below. */197 $state = 'tag open';198 /* U+003E GREATER-THAN SIGN (>) */199 } elseif (200 $char === '>' &&201 $gt_cond === true &&202 substr($lastFourChars, 1) === '-->'203 ) {204 /* If the content model flag is set to either the RCDATA state or205 the CDATA state, and the escape flag is true, and the last three206 characters in the input stream including this one are U+002D207 HYPHEN-MINUS, U+002D HYPHEN-MINUS, U+003E GREATER-THAN SIGN ("-->"),208 set the escape flag to false. */209 $escape = false;210 /* In any case, emit the input character as a character token.211 Stay in the data state. */212 $this->emitToken([213 'type' => self::CHARACTER,214 'data' => '>'215 ]);216 // We do the "any case" part as part of "anything else".217 } elseif ($char === false) {218 /* EOF219 Emit an end-of-file token. */220 $state = null;221 $this->tree->emitToken([222 'type' => self::EOF223 ]);224 } elseif ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {225 // Directly after emitting a token you switch back to the "data226 // state". At that point spaceCharacters are important so they are227 // emitted separately.228 $chars = $this->stream->charsWhile(self::WHITESPACE);229 $this->emitToken([230 'type' => self::SPACECHARACTER,231 'data' => $char . $chars232 ]);233 $lastFourChars .= $chars;234 if (strlen($lastFourChars) > 4) {235 $lastFourChars = substr($lastFourChars, -4);236 }237 } else {238 /* Anything else239 THIS IS AN OPTIMIZATION: Get as many character that240 otherwise would also be treated as a character token and emit it241 as a single character token. Stay in the data state. */242 $mask = '';243 if ($hyp_cond === true) {244 $mask .= '-';245 }246 if ($amp_cond === true) {247 $mask .= '&';248 }249 if ($lt_cond === true) {250 $mask .= '<';251 }252 if ($gt_cond === true) {253 $mask .= '>';254 }255 if ($mask === '') {256 $chars = $this->stream->remainingChars();257 } else {258 $chars = $this->stream->charsUntil($mask);259 }260 $this->emitToken([261 'type' => self::CHARACTER,262 'data' => $char . $chars263 ]);264 $lastFourChars .= $chars;265 if (strlen($lastFourChars) > 4) {266 $lastFourChars = substr($lastFourChars, -4);267 }268 $state = 'data';269 }270 break;271 case 'character reference data':272 /* (This cannot happen if the content model flag273 is set to the CDATA state.) */274 /* Attempt to consume a character reference, with no275 additional allowed character. */276 $entity = $this->consumeCharacterReference();277 /* If nothing is returned, emit a U+0026 AMPERSAND278 character token. Otherwise, emit the character token that279 was returned. */280 // This is all done when consuming the character reference.281 $this->emitToken([282 'type' => self::CHARACTER,283 'data' => $entity284 ]);285 /* Finally, switch to the data state. */286 $state = 'data';287 break;288 case 'tag open':289 $char = $this->stream->char();290 switch ($this->content_model) {291 case self::RCDATA:292 case self::CDATA:293 /* Consume the next input character. If it is a294 U+002F SOLIDUS (/) character, switch to the close295 tag open state. Otherwise, emit a U+003C LESS-THAN296 SIGN character token and reconsume the current input297 character in the data state. */298 // We consumed above.299 if ($char === '/') {300 $state = 'close tag open';301 } else {302 $this->emitToken([303 'type' => self::CHARACTER,304 'data' => '<'305 ]);306 $this->stream->unget();307 $state = 'data';308 }309 break;310 case self::PCDATA:311 /* If the content model flag is set to the PCDATA state312 Consume the next input character: */313 // We consumed above.314 if ($char === '!') {315 /* U+0021 EXCLAMATION MARK (!)316 Switch to the markup declaration open state. */317 $state = 'markup declaration open';318 } elseif ($char === '/') {319 /* U+002F SOLIDUS (/)320 Switch to the close tag open state. */321 $state = 'close tag open';322 } elseif ('A' <= $char && $char <= 'Z') {323 /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z324 Create a new start tag token, set its tag name to the lowercase325 version of the input character (add 0x0020 to the character's code326 point), then switch to the tag name state. (Don't emit the token327 yet; further details will be filled in before it is emitted.) */328 $this->token = [329 'name' => strtolower($char),330 'type' => self::STARTTAG,331 'attr' => []332 ];333 $state = 'tag name';334 } elseif ('a' <= $char && $char <= 'z') {335 /* U+0061 LATIN SMALL LETTER A through to U+007A LATIN SMALL LETTER Z336 Create a new start tag token, set its tag name to the input337 character, then switch to the tag name state. (Don't emit338 the token yet; further details will be filled in before it339 is emitted.) */340 $this->token = [341 'name' => $char,342 'type' => self::STARTTAG,343 'attr' => []344 ];345 $state = 'tag name';346 } elseif ($char === '>') {347 /* U+003E GREATER-THAN SIGN (>)348 Parse error. Emit a U+003C LESS-THAN SIGN character token and a349 U+003E GREATER-THAN SIGN character token. Switch to the data state. */350 $this->emitToken([351 'type' => self::PARSEERROR,352 'data' => 'expected-tag-name-but-got-right-bracket'353 ]);354 $this->emitToken([355 'type' => self::CHARACTER,356 'data' => '<>'357 ]);358 $state = 'data';359 } elseif ($char === '?') {360 /* U+003F QUESTION MARK (?)361 Parse error. Switch to the bogus comment state. */362 $this->emitToken([363 'type' => self::PARSEERROR,364 'data' => 'expected-tag-name-but-got-question-mark'365 ]);366 $this->token = [367 'data' => '?',368 'type' => self::COMMENT369 ];370 $state = 'bogus comment';371 } else {372 /* Anything else373 Parse error. Emit a U+003C LESS-THAN SIGN character token and374 reconsume the current input character in the data state. */375 $this->emitToken([376 'type' => self::PARSEERROR,377 'data' => 'expected-tag-name'378 ]);379 $this->emitToken([380 'type' => self::CHARACTER,381 'data' => '<'382 ]);383 $state = 'data';384 $this->stream->unget();385 }386 break;387 }388 break;389 case 'close tag open':390 if (391 $this->content_model === self::RCDATA ||392 $this->content_model === self::CDATA393 ) {394 /* If the content model flag is set to the RCDATA or CDATA395 states... */396 $name = strtolower($this->stream->charsWhile(self::ALPHA));397 $following = $this->stream->char();398 $this->stream->unget();399 if (400 !$this->token ||401 $this->token['name'] !== $name ||402 $this->token['name'] === $name && !in_array($following, ["\x09", "\x0A", "\x0C", "\x20", "\x3E", "\x2F", false])403 ) {404 /* if no start tag token has ever been emitted by this instance405 of the tokenizer (fragment case), or, if the next few406 characters do not match the tag name of the last start tag407 token emitted (compared in an ASCII case-insensitive manner),408 or if they do but they are not immediately followed by one of409 the following characters:410 * U+0009 CHARACTER TABULATION411 * U+000A LINE FEED (LF)412 * U+000C FORM FEED (FF)413 * U+0020 SPACE414 * U+003E GREATER-THAN SIGN (>)415 * U+002F SOLIDUS (/)416 * EOF417 ...then emit a U+003C LESS-THAN SIGN character token, a418 U+002F SOLIDUS character token, and switch to the data419 state to process the next input character. */420 // XXX: Probably ought to replace in_array with $following === x ||...421 // We also need to emit $name now we've consumed that, as we422 // know it'll just be emitted as a character token.423 $this->emitToken([424 'type' => self::CHARACTER,425 'data' => '</' . $name426 ]);427 $state = 'data';428 } else {429 // This matches what would happen if we actually did the430 // otherwise below (but we can't because we've consumed too431 // much).432 // Start the end tag token with the name we already have.433 $this->token = [434 'name' => $name,435 'type' => self::ENDTAG436 ];437 // Change to tag name state.438 $state = 'tag name';439 }440 } elseif ($this->content_model === self::PCDATA) {441 /* Otherwise, if the content model flag is set to the PCDATA442 state [...]: */443 $char = $this->stream->char();444 if ('A' <= $char && $char <= 'Z') {445 /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z446 Create a new end tag token, set its tag name to the lowercase version447 of the input character (add 0x0020 to the character's code point), then448 switch to the tag name state. (Don't emit the token yet; further details449 will be filled in before it is emitted.) */450 $this->token = [451 'name' => strtolower($char),452 'type' => self::ENDTAG453 ];454 $state = 'tag name';455 } elseif ('a' <= $char && $char <= 'z') {456 /* U+0061 LATIN SMALL LETTER A through to U+007A LATIN SMALL LETTER Z457 Create a new end tag token, set its tag name to the458 input character, then switch to the tag name state.459 (Don't emit the token yet; further details will be460 filled in before it is emitted.) */461 $this->token = [462 'name' => $char,463 'type' => self::ENDTAG464 ];465 $state = 'tag name';466 } elseif ($char === '>') {467 /* U+003E GREATER-THAN SIGN (>)468 Parse error. Switch to the data state. */469 $this->emitToken([470 'type' => self::PARSEERROR,471 'data' => 'expected-closing-tag-but-got-right-bracket'472 ]);473 $state = 'data';474 } elseif ($char === false) {475 /* EOF476 Parse error. Emit a U+003C LESS-THAN SIGN character token and a U+002F477 SOLIDUS character token. Reconsume the EOF character in the data state. */478 $this->emitToken([479 'type' => self::PARSEERROR,480 'data' => 'expected-closing-tag-but-got-eof'481 ]);482 $this->emitToken([483 'type' => self::CHARACTER,484 'data' => '</'485 ]);486 $this->stream->unget();487 $state = 'data';488 } else {489 /* Parse error. Switch to the bogus comment state. */490 $this->emitToken([491 'type' => self::PARSEERROR,492 'data' => 'expected-closing-tag-but-got-char'493 ]);494 $this->token = [495 'data' => $char,496 'type' => self::COMMENT497 ];498 $state = 'bogus comment';499 }500 }501 break;502 case 'tag name':503 /* Consume the next input character: */504 $char = $this->stream->char();505 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {506 /* U+0009 CHARACTER TABULATION507 U+000A LINE FEED (LF)508 U+000C FORM FEED (FF)509 U+0020 SPACE510 Switch to the before attribute name state. */511 $state = 'before attribute name';512 } elseif ($char === '/') {513 /* U+002F SOLIDUS (/)514 Switch to the self-closing start tag state. */515 $state = 'self-closing start tag';516 } elseif ($char === '>') {517 /* U+003E GREATER-THAN SIGN (>)518 Emit the current tag token. Switch to the data state. */519 $this->emitToken($this->token);520 $state = 'data';521 } elseif ('A' <= $char && $char <= 'Z') {522 /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z523 Append the lowercase version of the current input524 character (add 0x0020 to the character's code point) to525 the current tag token's tag name. Stay in the tag name state. */526 $chars = $this->stream->charsWhile(self::UPPER_ALPHA);527 $this->token['name'] .= strtolower($char . $chars);528 $state = 'tag name';529 } elseif ($char === false) {530 /* EOF531 Parse error. Reconsume the EOF character in the data state. */532 $this->emitToken([533 'type' => self::PARSEERROR,534 'data' => 'eof-in-tag-name'535 ]);536 $this->stream->unget();537 $state = 'data';538 } else {539 /* Anything else540 Append the current input character to the current tag token's tag name.541 Stay in the tag name state. */542 $chars = $this->stream->charsUntil("\t\n\x0C />" . self::UPPER_ALPHA);543 $this->token['name'] .= $char . $chars;544 $state = 'tag name';545 }546 break;547 case 'before attribute name':548 /* Consume the next input character: */549 $char = $this->stream->char();550 // this conditional is optimized, check bottom551 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {552 /* U+0009 CHARACTER TABULATION553 U+000A LINE FEED (LF)554 U+000C FORM FEED (FF)555 U+0020 SPACE556 Stay in the before attribute name state. */557 $state = 'before attribute name';558 } elseif ($char === '/') {559 /* U+002F SOLIDUS (/)560 Switch to the self-closing start tag state. */561 $state = 'self-closing start tag';562 } elseif ($char === '>') {563 /* U+003E GREATER-THAN SIGN (>)564 Emit the current tag token. Switch to the data state. */565 $this->emitToken($this->token);566 $state = 'data';567 } elseif ('A' <= $char && $char <= 'Z') {568 /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z569 Start a new attribute in the current tag token. Set that570 attribute's name to the lowercase version of the current571 input character (add 0x0020 to the character's code572 point), and its value to the empty string. Switch to the573 attribute name state.*/574 $this->token['attr'][] = [575 'name' => strtolower($char),576 'value' => ''577 ];578 $state = 'attribute name';579 } elseif ($char === false) {580 /* EOF581 Parse error. Reconsume the EOF character in the data state. */582 $this->emitToken([583 'type' => self::PARSEERROR,584 'data' => 'expected-attribute-name-but-got-eof'585 ]);586 $this->stream->unget();587 $state = 'data';588 } else {589 /* U+0022 QUOTATION MARK (")590 U+0027 APOSTROPHE (')591 U+003C LESS-THAN SIGN (<)592 U+003D EQUALS SIGN (=)593 Parse error. Treat it as per the "anything else" entry594 below. */595 if ($char === '"' || $char === "'" || $char === '<' || $char === '=') {596 $this->emitToken([597 'type' => self::PARSEERROR,598 'data' => 'invalid-character-in-attribute-name'599 ]);600 }601 /* Anything else602 Start a new attribute in the current tag token. Set that attribute's603 name to the current input character, and its value to the empty string.604 Switch to the attribute name state. */605 $this->token['attr'][] = [606 'name' => $char,607 'value' => ''608 ];609 $state = 'attribute name';610 }611 break;612 case 'attribute name':613 // Consume the next input character:614 $char = $this->stream->char();615 // this conditional is optimized, check bottom616 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {617 /* U+0009 CHARACTER TABULATION618 U+000A LINE FEED (LF)619 U+000C FORM FEED (FF)620 U+0020 SPACE621 Switch to the after attribute name state. */622 $state = 'after attribute name';623 } elseif ($char === '/') {624 /* U+002F SOLIDUS (/)625 Switch to the self-closing start tag state. */626 $state = 'self-closing start tag';627 } elseif ($char === '=') {628 /* U+003D EQUALS SIGN (=)629 Switch to the before attribute value state. */630 $state = 'before attribute value';631 } elseif ($char === '>') {632 /* U+003E GREATER-THAN SIGN (>)633 Emit the current tag token. Switch to the data state. */634 $this->emitToken($this->token);635 $state = 'data';636 } elseif ('A' <= $char && $char <= 'Z') {637 /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z638 Append the lowercase version of the current input639 character (add 0x0020 to the character's code point) to640 the current attribute's name. Stay in the attribute name641 state. */642 $chars = $this->stream->charsWhile(self::UPPER_ALPHA);643 $last = count($this->token['attr']) - 1;644 $this->token['attr'][$last]['name'] .= strtolower($char . $chars);645 $state = 'attribute name';646 } elseif ($char === false) {647 /* EOF648 Parse error. Reconsume the EOF character in the data state. */649 $this->emitToken([650 'type' => self::PARSEERROR,651 'data' => 'eof-in-attribute-name'652 ]);653 $this->stream->unget();654 $state = 'data';655 } else {656 /* U+0022 QUOTATION MARK (")657 U+0027 APOSTROPHE (')658 U+003C LESS-THAN SIGN (<)659 Parse error. Treat it as per the "anything else"660 entry below. */661 if ($char === '"' || $char === "'" || $char === '<') {662 $this->emitToken([663 'type' => self::PARSEERROR,664 'data' => 'invalid-character-in-attribute-name'665 ]);666 }667 /* Anything else668 Append the current input character to the current attribute's name.669 Stay in the attribute name state. */670 $chars = $this->stream->charsUntil("\t\n\x0C /=>\"'" . self::UPPER_ALPHA);671 $last = count($this->token['attr']) - 1;672 $this->token['attr'][$last]['name'] .= $char . $chars;673 $state = 'attribute name';674 }675 /* When the user agent leaves the attribute name state676 (and before emitting the tag token, if appropriate), the677 complete attribute's name must be compared to the other678 attributes on the same token; if there is already an679 attribute on the token with the exact same name, then this680 is a parse error and the new attribute must be dropped, along681 with the value that gets associated with it (if any). */682 // this might be implemented in the emitToken method683 break;684 case 'after attribute name':685 // Consume the next input character:686 $char = $this->stream->char();687 // this is an optimized conditional, check the bottom688 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {689 /* U+0009 CHARACTER TABULATION690 U+000A LINE FEED (LF)691 U+000C FORM FEED (FF)692 U+0020 SPACE693 Stay in the after attribute name state. */694 $state = 'after attribute name';695 } elseif ($char === '/') {696 /* U+002F SOLIDUS (/)697 Switch to the self-closing start tag state. */698 $state = 'self-closing start tag';699 } elseif ($char === '=') {700 /* U+003D EQUALS SIGN (=)701 Switch to the before attribute value state. */702 $state = 'before attribute value';703 } elseif ($char === '>') {704 /* U+003E GREATER-THAN SIGN (>)705 Emit the current tag token. Switch to the data state. */706 $this->emitToken($this->token);707 $state = 'data';708 } elseif ('A' <= $char && $char <= 'Z') {709 /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z710 Start a new attribute in the current tag token. Set that711 attribute's name to the lowercase version of the current712 input character (add 0x0020 to the character's code713 point), and its value to the empty string. Switch to the714 attribute name state. */715 $this->token['attr'][] = [716 'name' => strtolower($char),717 'value' => ''718 ];719 $state = 'attribute name';720 } elseif ($char === false) {721 /* EOF722 Parse error. Reconsume the EOF character in the data state. */723 $this->emitToken([724 'type' => self::PARSEERROR,725 'data' => 'expected-end-of-tag-but-got-eof'726 ]);727 $this->stream->unget();728 $state = 'data';729 } else {730 /* U+0022 QUOTATION MARK (")731 U+0027 APOSTROPHE (')732 U+003C LESS-THAN SIGN(<)733 Parse error. Treat it as per the "anything else"734 entry below. */735 if ($char === '"' || $char === "'" || $char === "<") {736 $this->emitToken([737 'type' => self::PARSEERROR,738 'data' => 'invalid-character-after-attribute-name'739 ]);740 }741 /* Anything else742 Start a new attribute in the current tag token. Set that attribute's743 name to the current input character, and its value to the empty string.744 Switch to the attribute name state. */745 $this->token['attr'][] = [746 'name' => $char,747 'value' => ''748 ];749 $state = 'attribute name';750 }751 break;752 case 'before attribute value':753 // Consume the next input character:754 $char = $this->stream->char();755 // this is an optimized conditional756 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {757 /* U+0009 CHARACTER TABULATION758 U+000A LINE FEED (LF)759 U+000C FORM FEED (FF)760 U+0020 SPACE761 Stay in the before attribute value state. */762 $state = 'before attribute value';763 } elseif ($char === '"') {764 /* U+0022 QUOTATION MARK (")765 Switch to the attribute value (double-quoted) state. */766 $state = 'attribute value (double-quoted)';767 } elseif ($char === '&') {768 /* U+0026 AMPERSAND (&)769 Switch to the attribute value (unquoted) state and reconsume770 this input character. */771 $this->stream->unget();772 $state = 'attribute value (unquoted)';773 } elseif ($char === '\'') {774 /* U+0027 APOSTROPHE (')775 Switch to the attribute value (single-quoted) state. */776 $state = 'attribute value (single-quoted)';777 } elseif ($char === '>') {778 /* U+003E GREATER-THAN SIGN (>)779 Parse error. Emit the current tag token. Switch to the data state. */780 $this->emitToken([781 'type' => self::PARSEERROR,782 'data' => 'expected-attribute-value-but-got-right-bracket'783 ]);784 $this->emitToken($this->token);785 $state = 'data';786 } elseif ($char === false) {787 /* EOF788 Parse error. Reconsume the EOF character in the data state. */789 $this->emitToken([790 'type' => self::PARSEERROR,791 'data' => 'expected-attribute-value-but-got-eof'792 ]);793 $this->stream->unget();794 $state = 'data';795 } else {796 /* U+003D EQUALS SIGN (=)797 * U+003C LESS-THAN SIGN (<)798 Parse error. Treat it as per the "anything else" entry below. */799 if ($char === '=' || $char === '<') {800 $this->emitToken([801 'type' => self::PARSEERROR,802 'data' => 'equals-in-unquoted-attribute-value'803 ]);804 }805 /* Anything else806 Append the current input character to the current attribute's value.807 Switch to the attribute value (unquoted) state. */808 $last = count($this->token['attr']) - 1;809 $this->token['attr'][$last]['value'] .= $char;810 $state = 'attribute value (unquoted)';811 }812 break;813 case 'attribute value (double-quoted)':814 // Consume the next input character:815 $char = $this->stream->char();816 if ($char === '"') {817 /* U+0022 QUOTATION MARK (")818 Switch to the after attribute value (quoted) state. */819 $state = 'after attribute value (quoted)';820 } elseif ($char === '&') {821 /* U+0026 AMPERSAND (&)822 Switch to the character reference in attribute value823 state, with the additional allowed character824 being U+0022 QUOTATION MARK ("). */825 $this->characterReferenceInAttributeValue('"');826 } elseif ($char === false) {827 /* EOF828 Parse error. Reconsume the EOF character in the data state. */829 $this->emitToken([830 'type' => self::PARSEERROR,831 'data' => 'eof-in-attribute-value-double-quote'832 ]);833 $this->stream->unget();834 $state = 'data';835 } else {836 /* Anything else837 Append the current input character to the current attribute's value.838 Stay in the attribute value (double-quoted) state. */839 $chars = $this->stream->charsUntil('"&');840 $last = count($this->token['attr']) - 1;841 $this->token['attr'][$last]['value'] .= $char . $chars;842 $state = 'attribute value (double-quoted)';843 }844 break;845 case 'attribute value (single-quoted)':846 // Consume the next input character:847 $char = $this->stream->char();848 if ($char === "'") {849 /* U+0022 QUOTATION MARK (')850 Switch to the after attribute value state. */851 $state = 'after attribute value (quoted)';852 } elseif ($char === '&') {853 /* U+0026 AMPERSAND (&)854 Switch to the entity in attribute value state. */855 $this->characterReferenceInAttributeValue("'");856 } elseif ($char === false) {857 /* EOF858 Parse error. Reconsume the EOF character in the data state. */859 $this->emitToken([860 'type' => self::PARSEERROR,861 'data' => 'eof-in-attribute-value-single-quote'862 ]);863 $this->stream->unget();864 $state = 'data';865 } else {866 /* Anything else867 Append the current input character to the current attribute's value.868 Stay in the attribute value (single-quoted) state. */869 $chars = $this->stream->charsUntil("'&");870 $last = count($this->token['attr']) - 1;871 $this->token['attr'][$last]['value'] .= $char . $chars;872 $state = 'attribute value (single-quoted)';873 }874 break;875 case 'attribute value (unquoted)':876 // Consume the next input character:877 $char = $this->stream->char();878 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {879 /* U+0009 CHARACTER TABULATION880 U+000A LINE FEED (LF)881 U+000C FORM FEED (FF)882 U+0020 SPACE883 Switch to the before attribute name state. */884 $state = 'before attribute name';885 } elseif ($char === '&') {886 /* U+0026 AMPERSAND (&)887 Switch to the entity in attribute value state, with the888 additional allowed character being U+003E889 GREATER-THAN SIGN (>). */890 $this->characterReferenceInAttributeValue('>');891 } elseif ($char === '>') {892 /* U+003E GREATER-THAN SIGN (>)893 Emit the current tag token. Switch to the data state. */894 $this->emitToken($this->token);895 $state = 'data';896 } elseif ($char === false) {897 /* EOF898 Parse error. Reconsume the EOF character in the data state. */899 $this->emitToken([900 'type' => self::PARSEERROR,901 'data' => 'eof-in-attribute-value-no-quotes'902 ]);903 $this->stream->unget();904 $state = 'data';905 } else {906 /* U+0022 QUOTATION MARK (")907 U+0027 APOSTROPHE (')908 U+003C LESS-THAN SIGN (<)909 U+003D EQUALS SIGN (=)910 Parse error. Treat it as per the "anything else"911 entry below. */912 if ($char === '"' || $char === "'" || $char === '=' || $char == '<') {913 $this->emitToken([914 'type' => self::PARSEERROR,915 'data' => 'unexpected-character-in-unquoted-attribute-value'916 ]);917 }918 /* Anything else919 Append the current input character to the current attribute's value.920 Stay in the attribute value (unquoted) state. */921 $chars = $this->stream->charsUntil("\t\n\x0c &>\"'=");922 $last = count($this->token['attr']) - 1;923 $this->token['attr'][$last]['value'] .= $char . $chars;924 $state = 'attribute value (unquoted)';925 }926 break;927 case 'after attribute value (quoted)':928 /* Consume the next input character: */929 $char = $this->stream->char();930 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {931 /* U+0009 CHARACTER TABULATION932 U+000A LINE FEED (LF)933 U+000C FORM FEED (FF)934 U+0020 SPACE935 Switch to the before attribute name state. */936 $state = 'before attribute name';937 } elseif ($char === '/') {938 /* U+002F SOLIDUS (/)939 Switch to the self-closing start tag state. */940 $state = 'self-closing start tag';941 } elseif ($char === '>') {942 /* U+003E GREATER-THAN SIGN (>)943 Emit the current tag token. Switch to the data state. */944 $this->emitToken($this->token);945 $state = 'data';946 } elseif ($char === false) {947 /* EOF948 Parse error. Reconsume the EOF character in the data state. */949 $this->emitToken([950 'type' => self::PARSEERROR,951 'data' => 'unexpected-EOF-after-attribute-value'952 ]);953 $this->stream->unget();954 $state = 'data';955 } else {956 /* Anything else957 Parse error. Reconsume the character in the before attribute958 name state. */959 $this->emitToken([960 'type' => self::PARSEERROR,961 'data' => 'unexpected-character-after-attribute-value'962 ]);963 $this->stream->unget();964 $state = 'before attribute name';965 }966 break;967 case 'self-closing start tag':968 /* Consume the next input character: */969 $char = $this->stream->char();970 if ($char === '>') {971 /* U+003E GREATER-THAN SIGN (>)972 Set the self-closing flag of the current tag token.973 Emit the current tag token. Switch to the data state. */974 // not sure if this is the name we want975 $this->token['self-closing'] = true;976 $this->emitToken($this->token);977 $state = 'data';978 } elseif ($char === false) {979 /* EOF980 Parse error. Reconsume the EOF character in the data state. */981 $this->emitToken([982 'type' => self::PARSEERROR,983 'data' => 'unexpected-eof-after-self-closing'984 ]);985 $this->stream->unget();986 $state = 'data';987 } else {988 /* Anything else989 Parse error. Reconsume the character in the before attribute name state. */990 $this->emitToken([991 'type' => self::PARSEERROR,992 'data' => 'unexpected-character-after-self-closing'993 ]);994 $this->stream->unget();995 $state = 'before attribute name';996 }997 break;998 case 'bogus comment':999 /* (This can only happen if the content model flag is set to the PCDATA state.) */1000 /* Consume every character up to the first U+003E GREATER-THAN SIGN1001 character (>) or the end of the file (EOF), whichever comes first. Emit1002 a comment token whose data is the concatenation of all the characters1003 starting from and including the character that caused the state machine1004 to switch into the bogus comment state, up to and including the last1005 consumed character before the U+003E character, if any, or up to the1006 end of the file otherwise. (If the comment was started by the end of1007 the file (EOF), the token is empty.) */1008 $this->token['data'] .= (string) $this->stream->charsUntil('>');1009 $this->stream->char();1010 $this->emitToken($this->token);1011 /* Switch to the data state. */1012 $state = 'data';1013 break;1014 case 'markup declaration open':1015 // Consume for below1016 $hyphens = $this->stream->charsWhile('-', 2);1017 if ($hyphens === '-') {1018 $this->stream->unget();1019 }1020 if ($hyphens !== '--') {1021 $alpha = $this->stream->charsWhile(self::ALPHA, 7);1022 }1023 /* If the next two characters are both U+002D HYPHEN-MINUS (-)1024 characters, consume those two characters, create a comment token whose1025 data is the empty string, and switch to the comment state. */1026 if ($hyphens === '--') {1027 $state = 'comment start';1028 $this->token = [1029 'data' => '',1030 'type' => self::COMMENT1031 ];1032 /* Otherwise if the next seven characters are a case-insensitive match1033 for the word "DOCTYPE", then consume those characters and switch to the1034 DOCTYPE state. */1035 } elseif (strtoupper($alpha) === 'DOCTYPE') {1036 $state = 'DOCTYPE';1037 // XXX not implemented1038 /* Otherwise, if the insertion mode is "in foreign content"1039 and the current node is not an element in the HTML namespace1040 and the next seven characters are an ASCII case-sensitive1041 match for the string "[CDATA[" (the five uppercase letters1042 "CDATA" with a U+005B LEFT SQUARE BRACKET character before1043 and after), then consume those characters and switch to the1044 CDATA section state (which is unrelated to the content model1045 flag's CDATA state). */1046 /* Otherwise, is is a parse error. Switch to the bogus comment state.1047 The next character that is consumed, if any, is the first character1048 that will be in the comment. */1049 } else {1050 $this->emitToken([1051 'type' => self::PARSEERROR,1052 'data' => 'expected-dashes-or-doctype'1053 ]);1054 $this->token = [1055 'data' => (string) $alpha,1056 'type' => self::COMMENT1057 ];1058 $state = 'bogus comment';1059 }1060 break;1061 case 'comment start':1062 /* Consume the next input character: */1063 $char = $this->stream->char();1064 if ($char === '-') {1065 /* U+002D HYPHEN-MINUS (-)1066 Switch to the comment start dash state. */1067 $state = 'comment start dash';1068 } elseif ($char === '>') {1069 /* U+003E GREATER-THAN SIGN (>)1070 Parse error. Emit the comment token. Switch to the1071 data state. */1072 $this->emitToken([1073 'type' => self::PARSEERROR,1074 'data' => 'incorrect-comment'1075 ]);1076 $this->emitToken($this->token);1077 $state = 'data';1078 } elseif ($char === false) {1079 /* EOF1080 Parse error. Emit the comment token. Reconsume the1081 EOF character in the data state. */1082 $this->emitToken([1083 'type' => self::PARSEERROR,1084 'data' => 'eof-in-comment'1085 ]);1086 $this->emitToken($this->token);1087 $this->stream->unget();1088 $state = 'data';1089 } else {1090 /* Anything else1091 Append the input character to the comment token's1092 data. Switch to the comment state. */1093 $this->token['data'] .= $char;1094 $state = 'comment';1095 }1096 break;1097 case 'comment start dash':1098 /* Consume the next input character: */1099 $char = $this->stream->char();1100 if ($char === '-') {1101 /* U+002D HYPHEN-MINUS (-)1102 Switch to the comment end state */1103 $state = 'comment end';1104 } elseif ($char === '>') {1105 /* U+003E GREATER-THAN SIGN (>)1106 Parse error. Emit the comment token. Switch to the1107 data state. */1108 $this->emitToken([1109 'type' => self::PARSEERROR,1110 'data' => 'incorrect-comment'1111 ]);1112 $this->emitToken($this->token);1113 $state = 'data';1114 } elseif ($char === false) {1115 /* Parse error. Emit the comment token. Reconsume the1116 EOF character in the data state. */1117 $this->emitToken([1118 'type' => self::PARSEERROR,1119 'data' => 'eof-in-comment'1120 ]);1121 $this->emitToken($this->token);1122 $this->stream->unget();1123 $state = 'data';1124 } else {1125 $this->token['data'] .= '-' . $char;1126 $state = 'comment';1127 }1128 break;1129 case 'comment':1130 /* Consume the next input character: */1131 $char = $this->stream->char();1132 if ($char === '-') {1133 /* U+002D HYPHEN-MINUS (-)1134 Switch to the comment end dash state */1135 $state = 'comment end dash';1136 } elseif ($char === false) {1137 /* EOF1138 Parse error. Emit the comment token. Reconsume the EOF character1139 in the data state. */1140 $this->emitToken([1141 'type' => self::PARSEERROR,1142 'data' => 'eof-in-comment'1143 ]);1144 $this->emitToken($this->token);1145 $this->stream->unget();1146 $state = 'data';1147 } else {1148 /* Anything else1149 Append the input character to the comment token's data. Stay in1150 the comment state. */1151 $chars = $this->stream->charsUntil('-');1152 $this->token['data'] .= $char . $chars;1153 }1154 break;1155 case 'comment end dash':1156 /* Consume the next input character: */1157 $char = $this->stream->char();1158 if ($char === '-') {1159 /* U+002D HYPHEN-MINUS (-)1160 Switch to the comment end state */1161 $state = 'comment end';1162 } elseif ($char === false) {1163 /* EOF1164 Parse error. Emit the comment token. Reconsume the EOF character1165 in the data state. */1166 $this->emitToken([1167 'type' => self::PARSEERROR,1168 'data' => 'eof-in-comment-end-dash'1169 ]);1170 $this->emitToken($this->token);1171 $this->stream->unget();1172 $state = 'data';1173 } else {1174 /* Anything else1175 Append a U+002D HYPHEN-MINUS (-) character and the input1176 character to the comment token's data. Switch to the comment state. */1177 $this->token['data'] .= '-'.$char;1178 $state = 'comment';1179 }1180 break;1181 case 'comment end':1182 /* Consume the next input character: */1183 $char = $this->stream->char();1184 if ($char === '>') {1185 /* U+003E GREATER-THAN SIGN (>)1186 Emit the comment token. Switch to the data state. */1187 $this->emitToken($this->token);1188 $state = 'data';1189 } elseif ($char === '-') {1190 /* U+002D HYPHEN-MINUS (-)1191 Parse error. Append a U+002D HYPHEN-MINUS (-) character1192 to the comment token's data. Stay in the comment end1193 state. */1194 $this->emitToken([1195 'type' => self::PARSEERROR,1196 'data' => 'unexpected-dash-after-double-dash-in-comment'1197 ]);1198 $this->token['data'] .= '-';1199 } elseif ($char === "\t" || $char === "\n" || $char === "\x0a" || $char === ' ') {1200 $this->emitToken([1201 'type' => self::PARSEERROR,1202 'data' => 'unexpected-space-after-double-dash-in-comment'1203 ]);1204 $this->token['data'] .= '--' . $char;1205 $state = 'comment end space';1206 } elseif ($char === '!') {1207 $this->emitToken([1208 'type' => self::PARSEERROR,1209 'data' => 'unexpected-bang-after-double-dash-in-comment'1210 ]);1211 $state = 'comment end bang';1212 } elseif ($char === false) {1213 /* EOF1214 Parse error. Emit the comment token. Reconsume the1215 EOF character in the data state. */1216 $this->emitToken([1217 'type' => self::PARSEERROR,1218 'data' => 'eof-in-comment-double-dash'1219 ]);1220 $this->emitToken($this->token);1221 $this->stream->unget();1222 $state = 'data';1223 } else {1224 /* Anything else1225 Parse error. Append two U+002D HYPHEN-MINUS (-)1226 characters and the input character to the comment token's1227 data. Switch to the comment state. */1228 $this->emitToken([1229 'type' => self::PARSEERROR,1230 'data' => 'unexpected-char-in-comment'1231 ]);1232 $this->token['data'] .= '--'.$char;1233 $state = 'comment';1234 }1235 break;1236 case 'comment end bang':1237 $char = $this->stream->char();1238 if ($char === '>') {1239 $this->emitToken($this->token);1240 $state = 'data';1241 } elseif ($char === "-") {1242 $this->token['data'] .= '--!';1243 $state = 'comment end dash';1244 } elseif ($char === false) {1245 $this->emitToken([1246 'type' => self::PARSEERROR,1247 'data' => 'eof-in-comment-end-bang'1248 ]);1249 $this->emitToken($this->token);1250 $this->stream->unget();1251 $state = 'data';1252 } else {1253 $this->token['data'] .= '--!' . $char;1254 $state = 'comment';1255 }1256 break;1257 case 'comment end space':1258 $char = $this->stream->char();1259 if ($char === '>') {1260 $this->emitToken($this->token);1261 $state = 'data';1262 } elseif ($char === '-') {1263 $state = 'comment end dash';1264 } elseif ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {1265 $this->token['data'] .= $char;1266 } elseif ($char === false) {1267 $this->emitToken([1268 'type' => self::PARSEERROR,1269 'data' => 'unexpected-eof-in-comment-end-space',1270 ]);1271 $this->emitToken($this->token);1272 $this->stream->unget();1273 $state = 'data';1274 } else {1275 $this->token['data'] .= $char;1276 $state = 'comment';1277 }1278 break;1279 case 'DOCTYPE':1280 /* Consume the next input character: */1281 $char = $this->stream->char();1282 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {1283 /* U+0009 CHARACTER TABULATION1284 U+000A LINE FEED (LF)1285 U+000C FORM FEED (FF)1286 U+0020 SPACE1287 Switch to the before DOCTYPE name state. */1288 $state = 'before DOCTYPE name';1289 } elseif ($char === false) {1290 /* EOF1291 Parse error. Create a new DOCTYPE token. Set its1292 force-quirks flag to on. Emit the token. Reconsume the1293 EOF character in the data state. */1294 $this->emitToken([1295 'type' => self::PARSEERROR,1296 'data' => 'need-space-after-doctype-but-got-eof'1297 ]);1298 $this->emitToken([1299 'name' => '',1300 'type' => self::DOCTYPE,1301 'force-quirks' => true,1302 'error' => true1303 ]);1304 $this->stream->unget();1305 $state = 'data';1306 } else {1307 /* Anything else1308 Parse error. Reconsume the current character in the1309 before DOCTYPE name state. */1310 $this->emitToken([1311 'type' => self::PARSEERROR,1312 'data' => 'need-space-after-doctype'1313 ]);1314 $this->stream->unget();1315 $state = 'before DOCTYPE name';1316 }1317 break;1318 case 'before DOCTYPE name':1319 /* Consume the next input character: */1320 $char = $this->stream->char();1321 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {1322 /* U+0009 CHARACTER TABULATION1323 U+000A LINE FEED (LF)1324 U+000C FORM FEED (FF)1325 U+0020 SPACE1326 Stay in the before DOCTYPE name state. */1327 } elseif ($char === '>') {1328 /* U+003E GREATER-THAN SIGN (>)1329 Parse error. Create a new DOCTYPE token. Set its1330 force-quirks flag to on. Emit the token. Switch to the1331 data state. */1332 $this->emitToken([1333 'type' => self::PARSEERROR,1334 'data' => 'expected-doctype-name-but-got-right-bracket'1335 ]);1336 $this->emitToken([1337 'name' => '',1338 'type' => self::DOCTYPE,1339 'force-quirks' => true,1340 'error' => true1341 ]);1342 $state = 'data';1343 } elseif ('A' <= $char && $char <= 'Z') {1344 /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z1345 Create a new DOCTYPE token. Set the token's name to the1346 lowercase version of the input character (add 0x0020 to1347 the character's code point). Switch to the DOCTYPE name1348 state. */1349 $this->token = [1350 'name' => strtolower($char),1351 'type' => self::DOCTYPE,1352 'error' => true1353 ];1354 $state = 'DOCTYPE name';1355 } elseif ($char === false) {1356 /* EOF1357 Parse error. Create a new DOCTYPE token. Set its1358 force-quirks flag to on. Emit the token. Reconsume the1359 EOF character in the data state. */1360 $this->emitToken([1361 'type' => self::PARSEERROR,1362 'data' => 'expected-doctype-name-but-got-eof'1363 ]);1364 $this->emitToken([1365 'name' => '',1366 'type' => self::DOCTYPE,1367 'force-quirks' => true,1368 'error' => true1369 ]);1370 $this->stream->unget();1371 $state = 'data';1372 } else {1373 /* Anything else1374 Create a new DOCTYPE token. Set the token's name to the1375 current input character. Switch to the DOCTYPE name state. */1376 $this->token = [1377 'name' => $char,1378 'type' => self::DOCTYPE,1379 'error' => true1380 ];1381 $state = 'DOCTYPE name';1382 }1383 break;1384 case 'DOCTYPE name':1385 /* Consume the next input character: */1386 $char = $this->stream->char();1387 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {1388 /* U+0009 CHARACTER TABULATION1389 U+000A LINE FEED (LF)1390 U+000C FORM FEED (FF)1391 U+0020 SPACE1392 Switch to the after DOCTYPE name state. */1393 $state = 'after DOCTYPE name';1394 } elseif ($char === '>') {1395 /* U+003E GREATER-THAN SIGN (>)1396 Emit the current DOCTYPE token. Switch to the data state. */1397 $this->emitToken($this->token);1398 $state = 'data';1399 } elseif ('A' <= $char && $char <= 'Z') {1400 /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z1401 Append the lowercase version of the input character1402 (add 0x0020 to the character's code point) to the current1403 DOCTYPE token's name. Stay in the DOCTYPE name state. */1404 $this->token['name'] .= strtolower($char);1405 } elseif ($char === false) {1406 /* EOF1407 Parse error. Set the DOCTYPE token's force-quirks flag1408 to on. Emit that DOCTYPE token. Reconsume the EOF1409 character in the data state. */1410 $this->emitToken([1411 'type' => self::PARSEERROR,1412 'data' => 'eof-in-doctype-name'1413 ]);1414 $this->token['force-quirks'] = true;1415 $this->emitToken($this->token);1416 $this->stream->unget();1417 $state = 'data';1418 } else {1419 /* Anything else1420 Append the current input character to the current1421 DOCTYPE token's name. Stay in the DOCTYPE name state. */1422 $this->token['name'] .= $char;1423 }1424 // XXX this is probably some sort of quirks mode designation,1425 // check tree-builder to be sure. In general 'error' needs1426 // to be specc'ified, this probably means removing it at the end1427 $this->token['error'] = ($this->token['name'] === 'HTML')1428 ? false1429 : true;1430 break;1431 case 'after DOCTYPE name':1432 /* Consume the next input character: */1433 $char = $this->stream->char();1434 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {1435 /* U+0009 CHARACTER TABULATION1436 U+000A LINE FEED (LF)1437 U+000C FORM FEED (FF)1438 U+0020 SPACE1439 Stay in the after DOCTYPE name state. */1440 } elseif ($char === '>') {1441 /* U+003E GREATER-THAN SIGN (>)1442 Emit the current DOCTYPE token. Switch to the data state. */1443 $this->emitToken($this->token);1444 $state = 'data';1445 } elseif ($char === false) {1446 /* EOF1447 Parse error. Set the DOCTYPE token's force-quirks flag1448 to on. Emit that DOCTYPE token. Reconsume the EOF1449 character in the data state. */1450 $this->emitToken([1451 'type' => self::PARSEERROR,1452 'data' => 'eof-in-doctype'1453 ]);1454 $this->token['force-quirks'] = true;1455 $this->emitToken($this->token);1456 $this->stream->unget();1457 $state = 'data';1458 } else {1459 /* Anything else */1460 $nextSix = strtoupper($char . $this->stream->charsWhile(self::ALPHA, 5));1461 if ($nextSix === 'PUBLIC') {1462 /* If the next six characters are an ASCII1463 case-insensitive match for the word "PUBLIC", then1464 consume those characters and switch to the before1465 DOCTYPE public identifier state. */1466 $state = 'before DOCTYPE public identifier';1467 } elseif ($nextSix === 'SYSTEM') {1468 /* Otherwise, if the next six characters are an ASCII1469 case-insensitive match for the word "SYSTEM", then1470 consume those characters and switch to the before1471 DOCTYPE system identifier state. */1472 $state = 'before DOCTYPE system identifier';1473 } else {1474 /* Otherwise, this is the parse error. Set the DOCTYPE1475 token's force-quirks flag to on. Switch to the bogus1476 DOCTYPE state. */1477 $this->emitToken([1478 'type' => self::PARSEERROR,1479 'data' => 'expected-space-or-right-bracket-in-doctype'1480 ]);1481 $this->token['force-quirks'] = true;1482 $this->token['error'] = true;1483 $state = 'bogus DOCTYPE';1484 }1485 }1486 break;1487 case 'before DOCTYPE public identifier':1488 /* Consume the next input character: */1489 $char = $this->stream->char();1490 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {1491 /* U+0009 CHARACTER TABULATION1492 U+000A LINE FEED (LF)1493 U+000C FORM FEED (FF)1494 U+0020 SPACE1495 Stay in the before DOCTYPE public identifier state. */1496 } elseif ($char === '"') {1497 /* U+0022 QUOTATION MARK (")1498 Set the DOCTYPE token's public identifier to the empty1499 string (not missing), then switch to the DOCTYPE public1500 identifier (double-quoted) state. */1501 $this->token['public'] = '';1502 $state = 'DOCTYPE public identifier (double-quoted)';1503 } elseif ($char === "'") {1504 /* U+0027 APOSTROPHE (')1505 Set the DOCTYPE token's public identifier to the empty1506 string (not missing), then switch to the DOCTYPE public1507 identifier (single-quoted) state. */1508 $this->token['public'] = '';1509 $state = 'DOCTYPE public identifier (single-quoted)';1510 } elseif ($char === '>') {1511 /* Parse error. Set the DOCTYPE token's force-quirks flag1512 to on. Emit that DOCTYPE token. Switch to the data state. */1513 $this->emitToken([1514 'type' => self::PARSEERROR,1515 'data' => 'unexpected-end-of-doctype'1516 ]);1517 $this->token['force-quirks'] = true;1518 $this->emitToken($this->token);1519 $state = 'data';1520 } elseif ($char === false) {1521 /* Parse error. Set the DOCTYPE token's force-quirks1522 flag to on. Emit that DOCTYPE token. Reconsume the EOF1523 character in the data state. */1524 $this->emitToken([1525 'type' => self::PARSEERROR,1526 'data' => 'eof-in-doctype'1527 ]);1528 $this->token['force-quirks'] = true;1529 $this->emitToken($this->token);1530 $this->stream->unget();1531 $state = 'data';1532 } else {1533 /* Parse error. Set the DOCTYPE token's force-quirks flag1534 to on. Switch to the bogus DOCTYPE state. */1535 $this->emitToken([1536 'type' => self::PARSEERROR,1537 'data' => 'unexpected-char-in-doctype'1538 ]);1539 $this->token['force-quirks'] = true;1540 $state = 'bogus DOCTYPE';1541 }1542 break;1543 case 'DOCTYPE public identifier (double-quoted)':1544 /* Consume the next input character: */1545 $char = $this->stream->char();1546 if ($char === '"') {1547 /* U+0022 QUOTATION MARK (")1548 Switch to the after DOCTYPE public identifier state. */1549 $state = 'after DOCTYPE public identifier';1550 } elseif ($char === '>') {1551 /* U+003E GREATER-THAN SIGN (>)1552 Parse error. Set the DOCTYPE token's force-quirks flag1553 to on. Emit that DOCTYPE token. Switch to the data state. */1554 $this->emitToken([1555 'type' => self::PARSEERROR,1556 'data' => 'unexpected-end-of-doctype'1557 ]);1558 $this->token['force-quirks'] = true;1559 $this->emitToken($this->token);1560 $state = 'data';1561 } elseif ($char === false) {1562 /* EOF1563 Parse error. Set the DOCTYPE token's force-quirks flag1564 to on. Emit that DOCTYPE token. Reconsume the EOF1565 character in the data state. */1566 $this->emitToken([1567 'type' => self::PARSEERROR,1568 'data' => 'eof-in-doctype'1569 ]);1570 $this->token['force-quirks'] = true;1571 $this->emitToken($this->token);1572 $this->stream->unget();1573 $state = 'data';1574 } else {1575 /* Anything else1576 Append the current input character to the current1577 DOCTYPE token's public identifier. Stay in the DOCTYPE1578 public identifier (double-quoted) state. */1579 $this->token['public'] .= $char;1580 }1581 break;1582 case 'DOCTYPE public identifier (single-quoted)':1583 /* Consume the next input character: */1584 $char = $this->stream->char();1585 if ($char === "'") {1586 /* U+0027 APOSTROPHE (')1587 Switch to the after DOCTYPE public identifier state. */1588 $state = 'after DOCTYPE public identifier';1589 } elseif ($char === '>') {1590 /* U+003E GREATER-THAN SIGN (>)1591 Parse error. Set the DOCTYPE token's force-quirks flag1592 to on. Emit that DOCTYPE token. Switch to the data state. */1593 $this->emitToken([1594 'type' => self::PARSEERROR,1595 'data' => 'unexpected-end-of-doctype'1596 ]);1597 $this->token['force-quirks'] = true;1598 $this->emitToken($this->token);1599 $state = 'data';1600 } elseif ($char === false) {1601 /* EOF1602 Parse error. Set the DOCTYPE token's force-quirks flag1603 to on. Emit that DOCTYPE token. Reconsume the EOF1604 character in the data state. */1605 $this->emitToken([1606 'type' => self::PARSEERROR,1607 'data' => 'eof-in-doctype'1608 ]);1609 $this->token['force-quirks'] = true;1610 $this->emitToken($this->token);1611 $this->stream->unget();1612 $state = 'data';1613 } else {1614 /* Anything else1615 Append the current input character to the current1616 DOCTYPE token's public identifier. Stay in the DOCTYPE1617 public identifier (double-quoted) state. */1618 $this->token['public'] .= $char;1619 }1620 break;1621 case 'after DOCTYPE public identifier':1622 /* Consume the next input character: */1623 $char = $this->stream->char();1624 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {1625 /* U+0009 CHARACTER TABULATION1626 U+000A LINE FEED (LF)1627 U+000C FORM FEED (FF)1628 U+0020 SPACE1629 Stay in the after DOCTYPE public identifier state. */1630 } elseif ($char === '"') {1631 /* U+0022 QUOTATION MARK (")1632 Set the DOCTYPE token's system identifier to the1633 empty string (not missing), then switch to the DOCTYPE1634 system identifier (double-quoted) state. */1635 $this->token['system'] = '';1636 $state = 'DOCTYPE system identifier (double-quoted)';1637 } elseif ($char === "'") {1638 /* U+0027 APOSTROPHE (')1639 Set the DOCTYPE token's system identifier to the1640 empty string (not missing), then switch to the DOCTYPE1641 system identifier (single-quoted) state. */1642 $this->token['system'] = '';1643 $state = 'DOCTYPE system identifier (single-quoted)';1644 } elseif ($char === '>') {1645 /* U+003E GREATER-THAN SIGN (>)1646 Emit the current DOCTYPE token. Switch to the data state. */1647 $this->emitToken($this->token);1648 $state = 'data';1649 } elseif ($char === false) {1650 /* Parse error. Set the DOCTYPE token's force-quirks1651 flag to on. Emit that DOCTYPE token. Reconsume the EOF1652 character in the data state. */1653 $this->emitToken([1654 'type' => self::PARSEERROR,1655 'data' => 'eof-in-doctype'1656 ]);1657 $this->token['force-quirks'] = true;1658 $this->emitToken($this->token);1659 $this->stream->unget();1660 $state = 'data';1661 } else {1662 /* Anything else1663 Parse error. Set the DOCTYPE token's force-quirks flag1664 to on. Switch to the bogus DOCTYPE state. */1665 $this->emitToken([1666 'type' => self::PARSEERROR,1667 'data' => 'unexpected-char-in-doctype'1668 ]);1669 $this->token['force-quirks'] = true;1670 $state = 'bogus DOCTYPE';1671 }1672 break;1673 case 'before DOCTYPE system identifier':1674 /* Consume the next input character: */1675 $char = $this->stream->char();1676 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {1677 /* U+0009 CHARACTER TABULATION1678 U+000A LINE FEED (LF)1679 U+000C FORM FEED (FF)1680 U+0020 SPACE1681 Stay in the before DOCTYPE system identifier state. */1682 } elseif ($char === '"') {1683 /* U+0022 QUOTATION MARK (")1684 Set the DOCTYPE token's system identifier to the empty1685 string (not missing), then switch to the DOCTYPE system1686 identifier (double-quoted) state. */1687 $this->token['system'] = '';1688 $state = 'DOCTYPE system identifier (double-quoted)';1689 } elseif ($char === "'") {1690 /* U+0027 APOSTROPHE (')1691 Set the DOCTYPE token's system identifier to the empty1692 string (not missing), then switch to the DOCTYPE system1693 identifier (single-quoted) state. */1694 $this->token['system'] = '';1695 $state = 'DOCTYPE system identifier (single-quoted)';1696 } elseif ($char === '>') {1697 /* Parse error. Set the DOCTYPE token's force-quirks flag1698 to on. Emit that DOCTYPE token. Switch to the data state. */1699 $this->emitToken([1700 'type' => self::PARSEERROR,1701 'data' => 'unexpected-char-in-doctype'1702 ]);1703 $this->token['force-quirks'] = true;1704 $this->emitToken($this->token);1705 $state = 'data';1706 } elseif ($char === false) {1707 /* Parse error. Set the DOCTYPE token's force-quirks1708 flag to on. Emit that DOCTYPE token. Reconsume the EOF1709 character in the data state. */1710 $this->emitToken([1711 'type' => self::PARSEERROR,1712 'data' => 'eof-in-doctype'1713 ]);1714 $this->token['force-quirks'] = true;1715 $this->emitToken($this->token);1716 $this->stream->unget();1717 $state = 'data';1718 } else {1719 /* Parse error. Set the DOCTYPE token's force-quirks flag1720 to on. Switch to the bogus DOCTYPE state. */1721 $this->emitToken([1722 'type' => self::PARSEERROR,1723 'data' => 'unexpected-char-in-doctype'1724 ]);1725 $this->token['force-quirks'] = true;1726 $state = 'bogus DOCTYPE';1727 }1728 break;1729 case 'DOCTYPE system identifier (double-quoted)':1730 /* Consume the next input character: */1731 $char = $this->stream->char();1732 if ($char === '"') {1733 /* U+0022 QUOTATION MARK (")1734 Switch to the after DOCTYPE system identifier state. */1735 $state = 'after DOCTYPE system identifier';1736 } elseif ($char === '>') {1737 /* U+003E GREATER-THAN SIGN (>)1738 Parse error. Set the DOCTYPE token's force-quirks flag1739 to on. Emit that DOCTYPE token. Switch to the data state. */1740 $this->emitToken([1741 'type' => self::PARSEERROR,1742 'data' => 'unexpected-end-of-doctype'1743 ]);1744 $this->token['force-quirks'] = true;1745 $this->emitToken($this->token);1746 $state = 'data';1747 } elseif ($char === false) {1748 /* EOF1749 Parse error. Set the DOCTYPE token's force-quirks flag1750 to on. Emit that DOCTYPE token. Reconsume the EOF1751 character in the data state. */1752 $this->emitToken([1753 'type' => self::PARSEERROR,1754 'data' => 'eof-in-doctype'1755 ]);1756 $this->token['force-quirks'] = true;1757 $this->emitToken($this->token);1758 $this->stream->unget();1759 $state = 'data';1760 } else {1761 /* Anything else1762 Append the current input character to the current1763 DOCTYPE token's system identifier. Stay in the DOCTYPE1764 system identifier (double-quoted) state. */1765 $this->token['system'] .= $char;1766 }1767 break;1768 case 'DOCTYPE system identifier (single-quoted)':1769 /* Consume the next input character: */1770 $char = $this->stream->char();1771 if ($char === "'") {1772 /* U+0027 APOSTROPHE (')1773 Switch to the after DOCTYPE system identifier state. */1774 $state = 'after DOCTYPE system identifier';1775 } elseif ($char === '>') {1776 /* U+003E GREATER-THAN SIGN (>)1777 Parse error. Set the DOCTYPE token's force-quirks flag1778 to on. Emit that DOCTYPE token. Switch to the data state. */1779 $this->emitToken([1780 'type' => self::PARSEERROR,1781 'data' => 'unexpected-end-of-doctype'1782 ]);1783 $this->token['force-quirks'] = true;1784 $this->emitToken($this->token);1785 $state = 'data';1786 } elseif ($char === false) {1787 /* EOF1788 Parse error. Set the DOCTYPE token's force-quirks flag1789 to on. Emit that DOCTYPE token. Reconsume the EOF1790 character in the data state. */1791 $this->emitToken([1792 'type' => self::PARSEERROR,1793 'data' => 'eof-in-doctype'1794 ]);1795 $this->token['force-quirks'] = true;1796 $this->emitToken($this->token);1797 $this->stream->unget();1798 $state = 'data';1799 } else {1800 /* Anything else1801 Append the current input character to the current1802 DOCTYPE token's system identifier. Stay in the DOCTYPE1803 system identifier (double-quoted) state. */1804 $this->token['system'] .= $char;1805 }1806 break;1807 case 'after DOCTYPE system identifier':1808 /* Consume the next input character: */1809 $char = $this->stream->char();1810 if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') {1811 /* U+0009 CHARACTER TABULATION1812 U+000A LINE FEED (LF)1813 U+000C FORM FEED (FF)1814 U+0020 SPACE1815 Stay in the after DOCTYPE system identifier state. */1816 } elseif ($char === '>') {1817 /* U+003E GREATER-THAN SIGN (>)1818 Emit the current DOCTYPE token. Switch to the data state. */1819 $this->emitToken($this->token);1820 $state = 'data';1821 } elseif ($char === false) {1822 /* Parse error. Set the DOCTYPE token's force-quirks1823 flag to on. Emit that DOCTYPE token. Reconsume the EOF1824 character in the data state. */1825 $this->emitToken([1826 'type' => self::PARSEERROR,1827 'data' => 'eof-in-doctype'1828 ]);1829 $this->token['force-quirks'] = true;1830 $this->emitToken($this->token);1831 $this->stream->unget();1832 $state = 'data';1833 } else {1834 /* Anything else1835 Parse error. Switch to the bogus DOCTYPE state.1836 (This does not set the DOCTYPE token's force-quirks1837 flag to on.) */1838 $this->emitToken([1839 'type' => self::PARSEERROR,1840 'data' => 'unexpected-char-in-doctype'1841 ]);1842 $state = 'bogus DOCTYPE';1843 }1844 break;1845 case 'bogus DOCTYPE':1846 /* Consume the next input character: */1847 $char = $this->stream->char();1848 if ($char === '>') {1849 /* U+003E GREATER-THAN SIGN (>)1850 Emit the DOCTYPE token. Switch to the data state. */1851 $this->emitToken($this->token);1852 $state = 'data';1853 } elseif ($char === false) {1854 /* EOF1855 Emit the DOCTYPE token. Reconsume the EOF character in1856 the data state. */1857 $this->emitToken($this->token);1858 $this->stream->unget();1859 $state = 'data';1860 } else {1861 /* Anything else1862 Stay in the bogus DOCTYPE state. */1863 }1864 break;1865 // case 'cdataSection':1866 }1867 }1868 }1869 /**1870 * Returns a serialized representation of the tree.1871 *1872 * @return DOMDocument|DOMNodeList1873 */1874 public function save() {1875 return $this->tree->save();1876 }1877 /**1878 * @return HTML5_TreeBuilder The tree1879 */1880 public function getTree()1881 {1882 return $this->tree;1883 }1884 /**1885 * Returns the input stream.1886 *1887 * @return HTML5_InputStream1888 */1889 public function stream() {1890 return $this->stream;1891 }1892 /**1893 * @param bool $allowed1894 * @param bool $inattr1895 * @return string1896 */1897 private function consumeCharacterReference($allowed = false, $inattr = false) {1898 // This goes quite far against spec, and is far closer to the Python1899 // impl., mainly because we don't do the large unconsuming the spec1900 // requires.1901 // All consumed characters.1902 $chars = $this->stream->char();1903 /* This section defines how to consume a character1904 reference. This definition is used when parsing character1905 references in text and in attributes.1906 The behavior depends on the identity of the next character1907 (the one immediately after the U+0026 AMPERSAND character): */1908 if (1909 $chars[0] === "\x09" ||1910 $chars[0] === "\x0A" ||1911 $chars[0] === "\x0C" ||1912 $chars[0] === "\x20" ||1913 $chars[0] === '<' ||1914 $chars[0] === '&' ||1915 $chars === false ||1916 $chars[0] === $allowed1917 ) {1918 /* U+0009 CHARACTER TABULATION1919 U+000A LINE FEED (LF)1920 U+000C FORM FEED (FF)1921 U+0020 SPACE1922 U+003C LESS-THAN SIGN1923 U+0026 AMPERSAND1924 EOF1925 The additional allowed character, if there is one1926 Not a character reference. No characters are consumed,1927 and nothing is returned. (This is not an error, either.) */1928 // We already consumed, so unconsume.1929 $this->stream->unget();1930 return '&';1931 } elseif ($chars[0] === '#') {1932 /* Consume the U+0023 NUMBER SIGN. */1933 // Um, yeah, we already did that.1934 /* The behavior further depends on the character after1935 the U+0023 NUMBER SIGN: */1936 $chars .= $this->stream->char();1937 if (isset($chars[1]) && ($chars[1] === 'x' || $chars[1] === 'X')) {1938 /* U+0078 LATIN SMALL LETTER X1939 U+0058 LATIN CAPITAL LETTER X */1940 /* Consume the X. */1941 // Um, yeah, we already did that.1942 /* Follow the steps below, but using the range of1943 characters U+0030 DIGIT ZERO through to U+0039 DIGIT1944 NINE, U+0061 LATIN SMALL LETTER A through to U+00661945 LATIN SMALL LETTER F, and U+0041 LATIN CAPITAL LETTER1946 A, through to U+0046 LATIN CAPITAL LETTER F (in other1947 words, 0123456789, ABCDEF, abcdef). */1948 $char_class = self::HEX;1949 /* When it comes to interpreting the1950 number, interpret it as a hexadecimal number. */1951 $hex = true;1952 } else {1953 /* Anything else */1954 // Unconsume because we shouldn't have consumed this.1955 $chars = $chars[0];1956 $this->stream->unget();1957 /* Follow the steps below, but using the range of1958 characters U+0030 DIGIT ZERO through to U+0039 DIGIT1959 NINE (i.e. just 0123456789). */1960 $char_class = self::DIGIT;1961 /* When it comes to interpreting the number,1962 interpret it as a decimal number. */1963 $hex = false;1964 }1965 /* Consume as many characters as match the range of characters given above. */1966 $consumed = $this->stream->charsWhile($char_class);1967 if ($consumed === '' || $consumed === false) {1968 /* If no characters match the range, then don't consume1969 any characters (and unconsume the U+0023 NUMBER SIGN1970 character and, if appropriate, the X character). This1971 is a parse error; nothing is returned. */1972 $this->emitToken([1973 'type' => self::PARSEERROR,1974 'data' => 'expected-numeric-entity'1975 ]);1976 return '&' . $chars;1977 } else {1978 /* Otherwise, if the next character is a U+003B SEMICOLON,1979 consume that too. If it isn't, there is a parse error. */1980 if ($this->stream->char() !== ';') {1981 $this->stream->unget();1982 $this->emitToken([1983 'type' => self::PARSEERROR,1984 'data' => 'numeric-entity-without-semicolon'1985 ]);1986 }1987 /* If one or more characters match the range, then take1988 them all and interpret the string of characters as a number1989 (either hexadecimal or decimal as appropriate). */1990 $codepoint = $hex ? hexdec($consumed) : (int) $consumed;1991 /* If that number is one of the numbers in the first column1992 of the following table, then this is a parse error. Find the1993 row with that number in the first column, and return a1994 character token for the Unicode character given in the1995 second column of that row. */1996 $new_codepoint = HTML5_Data::getRealCodepoint($codepoint);1997 if ($new_codepoint) {1998 $this->emitToken([1999 'type' => self::PARSEERROR,2000 'data' => 'illegal-windows-1252-entity'2001 ]);2002 return HTML5_Data::utf8chr($new_codepoint);2003 } else {2004 /* Otherwise, if the number is greater than 0x10FFFF, then2005 * this is a parse error. Return a U+FFFD REPLACEMENT2006 * CHARACTER. */2007 if ($codepoint > 0x10FFFF) {2008 $this->emitToken([2009 'type' => self::PARSEERROR,2010 'data' => 'overlong-character-entity' // XXX probably not correct2011 ]);2012 return "\xEF\xBF\xBD";2013 }2014 /* Otherwise, return a character token for the Unicode2015 * character whose code point is that number. If the2016 * number is in the range 0x0001 to 0x0008, 0x000E to2017 * 0x001F, 0x007F to 0x009F, 0xD800 to 0xDFFF, 0xFDD0 to2018 * 0xFDEF, or is one of 0x000B, 0xFFFE, 0xFFFF, 0x1FFFE,2019 * 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, 0x3FFFF, 0x4FFFE,2020 * 0x4FFFF, 0x5FFFE, 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE,2021 * 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE,2022 * 0xAFFFF, 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE,2023 * 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, 0x10FFFE,2024 * or 0x10FFFF, then this is a parse error. */2025 // && has higher precedence than ||2026 if (2027 $codepoint >= 0x0000 && $codepoint <= 0x0008 ||2028 $codepoint === 0x000B ||2029 $codepoint >= 0x000E && $codepoint <= 0x001F ||2030 $codepoint >= 0x007F && $codepoint <= 0x009F ||2031 $codepoint >= 0xD800 && $codepoint <= 0xDFFF ||2032 $codepoint >= 0xFDD0 && $codepoint <= 0xFDEF ||2033 ($codepoint & 0xFFFE) === 0xFFFE ||2034 $codepoint == 0x10FFFF || $codepoint == 0x10FFFE2035 ) {2036 $this->emitToken([2037 'type' => self::PARSEERROR,2038 'data' => 'illegal-codepoint-for-numeric-entity'2039 ]);2040 }2041 return HTML5_Data::utf8chr($codepoint);2042 }2043 }2044 } else {2045 /* Anything else */2046 /* Consume the maximum number of characters possible,2047 with the consumed characters matching one of the2048 identifiers in the first column of the named character2049 references table (in a case-sensitive manner). */2050 // What we actually do here is consume as much as we can while it2051 // matches the start of one of the identifiers in the first column.2052 $refs = HTML5_Data::getNamedCharacterReferences();2053 // Get the longest string which is the start of an identifier2054 // ($chars) as well as the longest identifier which matches ($id)2055 // and its codepoint ($codepoint).2056 $codepoint = false;2057 $char = $chars;2058 while ($char !== false && isset($refs[$char])) {2059 $refs = $refs[$char];2060 if (isset($refs['codepoint'])) {2061 $id = $chars;2062 $codepoint = $refs['codepoint'];2063 }2064 $chars .= $char = $this->stream->char();2065 }2066 // Unconsume the one character we just took which caused the while2067 // statement to fail. This could be anything and could cause state2068 // changes (as if it matches the while loop it must be2069 // alphanumeric so we can just concat it to whatever we get later).2070 $this->stream->unget();2071 if ($char !== false) {2072 $chars = substr($chars, 0, -1);2073 }2074 /* If no match can be made, then this is a parse error.2075 No characters are consumed, and nothing is returned. */2076 if (!$codepoint) {2077 $this->emitToken([2078 'type' => self::PARSEERROR,2079 'data' => 'expected-named-entity'2080 ]);2081 return '&' . $chars;2082 }2083 /* If the last character matched is not a U+003B SEMICOLON2084 (;), there is a parse error. */2085 $semicolon = true;2086 if (substr($id, -1) !== ';') {2087 $this->emitToken([2088 'type' => self::PARSEERROR,2089 'data' => 'named-entity-without-semicolon'2090 ]);2091 $semicolon = false;2092 }2093 /* If the character reference is being consumed as part of2094 an attribute, and the last character matched is not a2095 U+003B SEMICOLON (;), and the next character is in the2096 range U+0030 DIGIT ZERO to U+0039 DIGIT NINE, U+00412097 LATIN CAPITAL LETTER A to U+005A LATIN CAPITAL LETTER Z,2098 or U+0061 LATIN SMALL LETTER A to U+007A LATIN SMALL LETTER Z,2099 then, for historical reasons, all the characters that were2100 matched after the U+0026 AMPERSAND (&) must be unconsumed,2101 and nothing is returned. */2102 if ($inattr && !$semicolon) {2103 // The next character is either the next character in $chars or in the stream.2104 if (strlen($chars) > strlen($id)) {2105 $next = substr($chars, strlen($id), 1);2106 } else {2107 $next = $this->stream->char();2108 $this->stream->unget();2109 }2110 if (2111 '0' <= $next && $next <= '9' ||2112 'A' <= $next && $next <= 'Z' ||2113 'a' <= $next && $next <= 'z'2114 ) {2115 return '&' . $chars;2116 }2117 }2118 /* Otherwise, return a character token for the character2119 corresponding to the character reference name (as given2120 by the second column of the named character references table). */2121 return HTML5_Data::utf8chr($codepoint) . substr($chars, strlen($id));2122 }2123 }2124 /**2125 * @param bool $allowed2126 */2127 private function characterReferenceInAttributeValue($allowed = false) {...

Full Screen

Full Screen

MessageBusTest.php

Source:MessageBusTest.php Github

copy

Full Screen

...39 $firstMiddleware = $this->getMockBuilder(MiddlewareInterface::class)->getMock();40 $firstMiddleware->expects($this->once())41 ->method('handle')42 ->with($message, $this->anything())43 ->will($this->returnCallback(function ($message, $next) {44 return $next($message);45 }));46 $secondMiddleware = $this->getMockBuilder(MiddlewareInterface::class)->getMock();47 $secondMiddleware->expects($this->once())48 ->method('handle')49 ->with($message, $this->anything())50 ->willReturn($responseFromDepthMiddleware);51 $bus = new MessageBus([52 $firstMiddleware,53 $secondMiddleware,54 ]);55 $this->assertEquals($responseFromDepthMiddleware, $bus->dispatch($message));56 }57 public function testItKeepsTheEnvelopeEvenThroughAMiddlewareThatIsNotEnvelopeAware()58 {59 $message = new DummyMessage('Hello');60 $envelope = new Envelope($message, [new ReceivedMessage()]);61 $firstMiddleware = $this->getMockBuilder(MiddlewareInterface::class)->getMock();62 $firstMiddleware->expects($this->once())63 ->method('handle')64 ->with($message, $this->anything())65 ->will($this->returnCallback(function ($message, $next) {66 return $next($message);67 }));68 $secondMiddleware = $this->getMockBuilder([MiddlewareInterface::class, EnvelopeAwareInterface::class])->getMock();69 $secondMiddleware->expects($this->once())70 ->method('handle')71 ->with($envelope, $this->anything())72 ;73 $bus = new MessageBus([74 $firstMiddleware,75 $secondMiddleware,76 ]);77 $bus->dispatch($envelope);78 }79 public function testThatAMiddlewareCanAddSomeItemsToTheEnvelope()80 {81 $message = new DummyMessage('Hello');82 $envelope = new Envelope($message, [new ReceivedMessage()]);83 $envelopeWithAnotherItem = $envelope->with(new AnEnvelopeItem());84 $firstMiddleware = $this->getMockBuilder([MiddlewareInterface::class, EnvelopeAwareInterface::class])->getMock();85 $firstMiddleware->expects($this->once())86 ->method('handle')87 ->with($envelope, $this->anything())88 ->will($this->returnCallback(function ($message, $next) {89 return $next($message->with(new AnEnvelopeItem()));90 }));91 $secondMiddleware = $this->getMockBuilder(MiddlewareInterface::class)->getMock();92 $secondMiddleware->expects($this->once())93 ->method('handle')94 ->with($message, $this->anything())95 ->will($this->returnCallback(function ($message, $next) {96 return $next($message);97 }));98 $thirdMiddleware = $this->getMockBuilder([MiddlewareInterface::class, EnvelopeAwareInterface::class])->getMock();99 $thirdMiddleware->expects($this->once())100 ->method('handle')101 ->with($envelopeWithAnotherItem, $this->anything())102 ;103 $bus = new MessageBus([104 $firstMiddleware,105 $secondMiddleware,106 $thirdMiddleware,107 ]);108 $bus->dispatch($envelope);109 }110 public function testThatAMiddlewareCanUpdateTheMessageWhileKeepingTheEnvelopeItems()111 {112 $message = new DummyMessage('Hello');113 $envelope = new Envelope($message, $items = [new ReceivedMessage()]);114 $changedMessage = new DummyMessage('Changed');115 $expectedEnvelope = new Envelope($changedMessage, $items);116 $firstMiddleware = $this->getMockBuilder(MiddlewareInterface::class)->getMock();117 $firstMiddleware->expects($this->once())118 ->method('handle')119 ->with($message, $this->anything())120 ->will($this->returnCallback(function ($message, $next) use ($changedMessage) {121 return $next($changedMessage);122 }));123 $secondMiddleware = $this->getMockBuilder([MiddlewareInterface::class, EnvelopeAwareInterface::class])->getMock();124 $secondMiddleware->expects($this->once())125 ->method('handle')126 ->with($expectedEnvelope, $this->anything())127 ;128 $bus = new MessageBus([129 $firstMiddleware,130 $secondMiddleware,131 ]);132 $bus->dispatch($envelope);133 }134}...

Full Screen

Full Screen

helper.php

Source:helper.php Github

copy

Full Screen

1<?php2// Helper file3// - will contain helping function available inside overall system4$base_url = '';5$root = '';6function resolve($core_class, $constructor = NULL)7{8 return new $core_class($constructor);9}10function migrate($table, $structure_callback)11{12 $schema = resolve('\\Core\\Database\\DB')->schema();13 $schema->create($table, $structure_callback);14}15function base($dir, $base)16{17 global $base_url;18 global $root;19 $root = $dir;20 $dir = str_replace("\\", "/", $dir);21 $dir = str_replace($base, '', $dir);22 $base_url = $dir;23}24function root()25{26 global $root;27 return $root;28}29function url($link = '')30{31 global $base_url;32 return $base_url.$link;33}34function config($key)35{36 return \Core\Config::get($key);37}38function dd($data)39{40 echo '<pre>';41 var_dump($data);42 echo '</pre>';43 exit;44}45function match($string, $condition, $recursive = FALSE)46{47 $gotStrings = Array();48 $gotCount = -1;49 if(strlen($condition)<1)50 return FALSE;51 $index = 0;52 $resetPoint = 0;53 $findNext = $condition[$index];54 $expecting = 'exact_match';55 if($findNext=='*'){56 $expecting = 'anything';57 if(isset($condition[$index+1]))58 $findNext = $condition[++$index];59 }60 if($findNext=='?'){61 $gotCount++;62 $gotStrings[$gotCount] = '';63 $expecting = 'get'; 64 if(isset($condition[$index+1])){65 $resetPoint = $index+1;66 $findNext = $condition[++$index];67 }elseif ($recursive){68 $index = 0;69 $findNext = $condition[$index];70 }71 }72 for ($i=0; $i < strlen($string); $i++) { 73 $char = $string[$i];74 //echo "FN: ".$findNext." ACTUAL: ".$char." --exp ".$expecting." ".($findNext==$char?'<i style="color: green">MATCHED</i>':'')."<br/>";75 if($expecting=='get' && $findNext != $char){76 $gotStrings[$gotCount] = $gotStrings[$gotCount] . $char;77 }78 if($findNext == $char){79 $expecting = 'exact_match';80 if(isset($condition[$index+1]) && $i < strlen($string) -1){81 $findNext = $condition[++$index];82 }elseif ($recursive){83 $index = 0;84 $findNext = $condition[$index];85 }86 if($findNext=='*'){87 $expecting = 'anything';88 if(isset($condition[$index+1])){89 $findNext = $condition[++$index];90 }elseif ($recursive){91 $index = 0;92 $findNext = $condition[$index];93 if($findNext=='*'){94 $expecting = 'anything';95 if(isset($condition[$index+1]))96 $findNext = $condition[++$index];97 }98 }99 }100 if($findNext=='?'){101 $gotCount++;102 $gotStrings[$gotCount] = '';103 $expecting = 'get';104 if(isset($condition[$index+1])){105 $resetPoint = $index+1;106 $findNext = $condition[++$index];107 }elseif ($recursive){108 $index = 0;109 $findNext = $condition[$index];110 }111 }112 }else{113 if($expecting == 'exact_match' && !$recursive)114 return FALSE;115 if($expecting == 'exact_match' && $recursive){116 $index = $resetPoint;117 $findNext = $condition[$index];118 if($findNext=='*'){119 $expecting = 'anything';120 if(isset($condition[$index+1]))121 $findNext = $condition[++$index];122 }123 }124 }125 }126 if(count($gotStrings)>0 && $recursive)127 return $gotStrings;128 if($index == strlen($condition)-1){129 if(count($gotStrings)>0)130 return $gotStrings;131 return TRUE;132 }133 return FALSE;134}...

Full Screen

Full Screen

next

Using AI Code Generation

copy

Full Screen

1echo $anything->next();2echo $anything->previous();3echo $anything->first();4echo $anything->last();5echo $anything->key();6echo $anything->current();7echo $anything->valid();8echo $anything->rewind();9echo $anything->count();10echo $anything->offsetExists(1);11echo $anything->offsetGet(1);12echo $anything->offsetSet(1, 2);13echo $anything->offsetUnset(1);14echo $anything->__toString();15echo $anything->__invoke();16echo $anything->__call('test', 'test');17echo $anything->__callStatic('test', 'test');18echo $anything->__get('test');19echo $anything->__set('test', 'test');20echo $anything->__isset('test');

Full Screen

Full Screen

next

Using AI Code Generation

copy

Full Screen

1$anything = new Anything();2$anything->next();3$anything->next();4$anything = new Anything();5$anything->prev();6$anything->prev();7$anything = new Anything();8$anything->reset();9$anything->reset();10$anything = new Anything();11$anything->current();12$anything->current();13$anything = new Anything();14$anything->key();15$anything->key();16$anything = new Anything();17$anything->valid();18$anything->valid();19$anything = new Anything();20$anything->count();21$anything->count();22$anything = new Anything();23$anything->rewind();24$anything->rewind();25$anything = new Anything();26$anything->seek();27$anything->seek();28$anything = new Anything();29$anything->offsetExists();30$anything->offsetExists();31$anything = new Anything();32$anything->offsetGet();33$anything->offsetGet();34$anything = new Anything();35$anything->offsetSet();36$anything->offsetSet();37$anything = new Anything();38$anything->offsetUnset();39$anything->offsetUnset();40$anything = new Anything();41$anything->__call();42$anything->__call();43$anything = new Anything();44$anything->__callStatic();

Full Screen

Full Screen

next

Using AI Code Generation

copy

Full Screen

1$anything = new Anything();2$anything = new Anything();3$anything = new Anything();4$anything = new Anything();5$anything = new Anything();6$anything = new Anything();7$anything = new Anything();8$anything = new Anything();9$anything = new Anything();10$anything = new Anything();11$anything = new Anything();12$anything = new Anything();13$anything = new Anything();14$anything = new Anything();15$anything = new Anything();

Full Screen

Full Screen

next

Using AI Code Generation

copy

Full Screen

1$obj=new Anything();2$obj->next();3$obj=new Anything();4$obj->prev();5$obj=new Anything();6$obj->first();7$obj=new Anything();8$obj->last();9$obj=new Anything();10$obj->count();11$obj=new Anything();12$obj->current();13$obj=new Anything();14$obj->key();15$obj=new Anything();16$obj->valid();17$obj=new Anything();18$obj->rewind();19$obj=new Anything();20$obj->offsetExists();21$obj=new Anything();22$obj->offsetGet();23$obj=new Anything();24$obj->offsetSet();25$obj=new Anything();26$obj->offsetUnset();27$obj=new Anything();28$obj=new Anything();29$obj=new Anything();30$obj->__call();31$obj=new Anything();32$obj->__get();33$obj=new Anything();34$obj->__set();35$obj=new Anything();36$obj->__isset();37$obj=new Anything();38$obj->__unset();

Full Screen

Full Screen

next

Using AI Code Generation

copy

Full Screen

1$anything->next();2echo $anything->current();3echo "\n";4$anything->prev();5echo $anything->current();6echo "\n";7$anything->reset();8echo $anything->current();9echo "\n";10$anything->end();11echo $anything->current();12echo "\n";13$anything->end();14echo $anything->key();15echo "\n";16$anything->end();17echo $anything->valid();18echo "\n";19$anything->end();20echo $anything->count();21echo "\n";22$anything->end();23echo $anything->offsetExists(3);24echo "\n";25$anything->end();26echo $anything->offsetGet(3);27echo "\n";28$anything->end();29$anything->offsetSet(3, 'test');30echo $anything->offsetGet(3);31echo "\n";32$anything->end();33$anything->offsetUnset(3);34echo $anything->offsetGet(3);35echo "\n";36$anything->end();37$anything->rewind();38echo $anything->current();39echo "\n";40$anything->end();41echo $anything->current();42echo "\n";43$anything->end();44$anything->next();45echo $anything->current();46echo "\n";

Full Screen

Full Screen

next

Using AI Code Generation

copy

Full Screen

1include_once 'Anything.php';2$anything = new Anything();3$anything->next();4include_once 'Anything.php';5$anything = new Anything();6$anything->next();7include_once 'Anything.php';8$anything = new Anything();9$anything->next();10include_once 'Anything.php';11$anything = new Anything();12$anything->next();13include_once 'Anything.php';14$anything = new Anything();15$anything->next();16include_once 'Anything.php';17$anything = new Anything();18$anything->next();19include_once 'Anything.php';20$anything = new Anything();21$anything->next();22include_once 'Anything.php';23$anything = new Anything();24$anything->next();25include_once 'Anything.php';26$anything = new Anything();27$anything->next();28include_once 'Anything.php';29$anything = new Anything();30$anything->next();31include_once 'Anything.php';32$anything = new Anything();33$anything->next();34include_once 'Anything.php';35$anything = new Anything();36$anything->next();37include_once 'Anything.php';38$anything = new Anything();39$anything->next();

Full Screen

Full Screen

next

Using AI Code Generation

copy

Full Screen

1$anything = new Anything;2$anything->next();3$anything->previous();4$anything = new Anything;5$anything->previous();6$anything->next();7$anything = new Anything;8$anything->next();9$anything->next();10$anything = new Anything;11$anything->previous();12$anything->previous();13$anything = new Anything;14$anything->next();15$anything->previous();16$anything = new Anything;17$anything->previous();18$anything->next();19$anything = new Anything;20$anything->next();21$anything->next();22$anything = new Anything;23$anything->previous();24$anything->previous();25$anything = new Anything;26$anything->next();27$anything->previous();28$anything = new Anything;29$anything->previous();30$anything->next();31$anything = new Anything;32$anything->next();33$anything->next();34$anything = new Anything;35$anything->previous();36$anything->previous();37$anything = new Anything;38$anything->next();

Full Screen

Full Screen

next

Using AI Code Generation

copy

Full Screen

1$anything = new Anything();2$anything->next();3$anything = new Anything();4$anything->previous();5$anything = new Anything();6$anything->rewind();7$anything = new Anything();8$anything->valid();9$anything = new Anything();10$anything->key();11$anything = new Anything();12$anything->current();13$anything = new Anything();14$anything->offsetExists();

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run AspectMock automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Trigger next code on LambdaTest Cloud Grid

Execute automation tests with next on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful