示例#1
0
 public function testSkipByToken()
 {
     $content = new Content(' b c');
     $content->fastForward(1);
     $content->skipByToken('blank');
     $this->assertEquals('b', $content->char());
 }
 /**
  * Attempt to parse a tag out of the content.
  *
  * @return array
  */
 protected function parseTag()
 {
     $return = ['status' => false, 'closing' => false, 'node' => null];
     if ($this->content->char() != '<') {
         // we are not at the beginning of a tag
         return $return;
     }
     // check if this is a closing tag
     if ($this->content->fastForward(1)->char() == '/') {
         // end tag
         $tag = $this->content->fastForward(1)->copyByToken('slash', true);
         // move to end of tag
         $this->content->copyUntil('>');
         $this->content->fastForward(1);
         // check if this closing tag counts
         $tag = strtolower($tag);
         if (in_array($tag, $this->selfClosing)) {
             $return['status'] = true;
             return $return;
         } else {
             $return['status'] = true;
             $return['closing'] = true;
             $return['tag'] = strtolower($tag);
         }
         return $return;
     }
     $tag = strtolower($this->content->copyByToken('slash', true));
     $node = new HtmlNode($tag);
     // attributes
     while ($this->content->char() != '>' and $this->content->char() != '/') {
         $space = $this->content->skipByToken('blank', true);
         if (empty($space)) {
             break;
         }
         $name = $this->content->copyByToken('equal', true);
         if ($name == '/' or empty($name)) {
             break;
         }
         if (empty($name)) {
             $this->content->fastForward(1);
             continue;
         }
         $this->content->skipByToken('blank');
         if ($this->content->char() == '=') {
             $attr = [];
             $this->content->fastForward(1)->skipByToken('blank');
             switch ($this->content->char()) {
                 case '"':
                     $attr['doubleQuote'] = true;
                     $this->content->fastForward(1);
                     $attr['value'] = $this->content->copyUntil('"', false, true);
                     $this->content->fastForward(1);
                     $node->getTag()->{$name} = $attr;
                     break;
                 case "'":
                     $attr['doubleQuote'] = false;
                     $this->content->fastForward(1);
                     $attr['value'] = $this->content->copyUntil("'", false, true);
                     $this->content->fastForward(1);
                     $node->getTag()->{$name} = $attr;
                     break;
                 default:
                     $attr['doubleQuote'] = true;
                     $attr['value'] = $this->content->copyByToken('attr', true);
                     $node->getTag()->{$name} = $attr;
                     break;
             }
         } else {
             // no value attribute
             if ($this->options->strict) {
                 // can't have this in strict html
                 $character = $this->content->getPosition();
                 throw new StrictException("Tag '{$tag}' has an attribute '{$name}' with out a value! (character #{$character})");
             }
             $node->getTag()->{$name} = ['value' => null, 'doubleQuote' => true];
             $this->content->rewind(1);
         }
     }
     $this->content->skipByToken('blank');
     if ($this->content->char() == '/') {
         // self closing tag
         $node->getTag()->selfClosing();
         $this->content->fastForward(1);
     } elseif (in_array($tag, $this->selfClosing)) {
         // Should be a self closing tag, check if we are strict
         if ($this->options->strict) {
             $character = $this->content->getPosition();
             throw new StrictException("Tag '{$tag}' is not self clossing! (character #{$character})");
         }
         // We force self closing on this tag.
         $node->getTag()->selfClosing();
     }
     $this->content->fastForward(1);
     $return['status'] = true;
     $return['node'] = $node;
     return $return;
 }