Exemplo n.º 1
0
 /**
  * Process the start tag.
  *
  * @todo
  *   - XMLNS namespace handling (we need to parse, even if it's not valid)
  *   - XLink, MathML and SVG namespace handling
  *   - Omission rules: 8.1.2.4 Optional tags
  */
 public function startTag($name, $attributes = array(), $selfClosing = FALSE)
 {
     // fprintf(STDOUT, $name);
     $lname = $this->normalizeTagName($name);
     // Make sure we have an html element.
     if (!$this->doc->documentElement && $name !== 'html') {
         $this->startTag('html');
     }
     // Set quirks mode if we're at IM_INITIAL with no doctype.
     if ($this->insertMode == static::IM_INITIAL) {
         $this->quirks = TRUE;
         $this->parseError("No DOCTYPE specified.");
     }
     // SPECIAL TAG HANDLING:
     // Spec says do this, and "don't ask."
     if ($name == 'image') {
         $name = 'img';
     }
     // Autoclose p tags where appropriate.
     if ($this->insertMode >= static::IM_IN_BODY && Elements::isA($name, Elements::AUTOCLOSE_P)) {
         $this->autoclose('p');
     }
     // Set insert mode:
     switch ($name) {
         case 'html':
             $this->insertMode = static::IM_BEFORE_HEAD;
             break;
         case 'head':
             if ($this->insertMode > static::IM_BEFORE_HEAD) {
                 $this->parseError("Unexpected head tag outside of head context.");
             } else {
                 $this->insertMode = static::IM_IN_HEAD;
             }
             break;
         case 'body':
             $this->insertMode = static::IM_IN_BODY;
             break;
         case 'svg':
             $this->insertMode = static::IM_IN_SVG;
             break;
         case 'math':
             $this->insertMode = static::IM_IN_MATHML;
             break;
         case 'noscript':
             if ($this->insertMode == static::IM_IN_HEAD) {
                 $this->insertMode = static::IM_IN_HEAD_NOSCRIPT;
             }
             break;
     }
     // Special case handling for SVG.
     if ($this->insertMode == static::IM_IN_SVG) {
         $lname = Elements::normalizeSvgElement($lname);
     }
     $ele = $this->doc->createElement($lname);
     foreach ($attributes as $aName => $aVal) {
         if ($this->insertMode == static::IM_IN_SVG) {
             $aName = Elements::normalizeSvgAttribute($aName);
         } elseif ($this->insertMode == static::IM_IN_MATHML) {
             $aName = Elements::normalizeMathMlAttribute($aName);
         }
         $ele->setAttribute($aName, $aVal);
         // This is necessary on a non-DTD schema, like HTML5.
         if ($aName == 'id') {
             $ele->setIdAttribute('id', TRUE);
         }
     }
     // Some elements have special processing rules. Handle those separately.
     if ($this->rules->hasRules($name)) {
         $this->current = $this->rules->evaluate($ele, $this->current);
     } else {
         $this->current->appendChild($ele);
         // XXX: Need to handle self-closing tags and unary tags.
         if (!Elements::isA($name, Elements::VOID_TAG)) {
             $this->current = $ele;
         }
     }
     // This is sort of a last-ditch attempt to correct for cases where no head/body
     // elements are provided.
     if ($this->insertMode <= static::IM_BEFORE_HEAD && $name != 'head' && $name != 'html') {
         $this->insertMode = static::IM_IN_BODY;
     }
     // Return the element mask, which the tokenizer can then use to set
     // various processing rules.
     return Elements::element($name);
 }
Exemplo n.º 2
0
 protected function attrs($ele)
 {
     // FIXME: Needs support for xml, xmlns, xlink, and namespaced elements.
     if (!$ele->hasAttributes()) {
         return $this;
     }
     // TODO: Currently, this always writes name="value", and does not do
     // value-less attributes.
     $map = $ele->attributes;
     $len = $map->length;
     for ($i = 0; $i < $len; ++$i) {
         $node = $map->item($i);
         $val = $this->enc($node->value, TRUE);
         // XXX: The spec says that we need to ensure that anything in
         // the XML, XMLNS, or XLink NS's should use the canonical
         // prefix. It seems that DOM does this for us already, but there
         // may be exceptions.
         $name = $node->name;
         // Special handling for attributes in SVG and MathML.
         // Using if/elseif instead of switch because it's faster in PHP.
         if ($this->outputMode == static::IM_IN_SVG) {
             $name = Elements::normalizeSvgAttribute($name);
         } elseif ($this->outputMode == static::IM_IN_MATHML) {
             $name = Elements::normalizeMathMlAttribute($name);
         }
         $this->wr(' ')->wr($name);
         if (isset($val) && $val !== '') {
             $this->wr('="')->wr($val)->wr('"');
         }
     }
 }