docs: function () {
        var c = this.nextChar();
  
        if (c === undefined)
          return null;
  
        // Read any text as Text node
        if (c !== "<") {
          --this.currentChar;
          var textNode = new Text();
          var n = this.html.indexOf("<", this.currentChar);
          if (n === -1) {
            textNode.innerHTML = this.html.substring(this.currentChar, this.html.length);
            this.currentChar = this.html.length;
          } else {
            textNode.innerHTML = this.html.substring(this.currentChar, n);
            this.currentChar = n;
          }
          return textNode;
        }
  
        c = this.peekNext();
  
        // Read Comment node. Normally, Comment nodes know their inner
        // textContent, but we don't really care about Comment nodes (we throw
        // them away in readChildren()). So just returning an empty Comment node
        // here is sufficient.
        if (c === "!" || c === "?") {
          // We're still before the ! or ? that is starting this comment:
          this.currentChar++;
          return this.discardNextComment();
        }
  
        // If we're reading a closing tag, return null. This means we've reached
        // the end of this set of child nodes.
        if (c === "/") {
          --this.currentChar;
          return null;
        }
  
        // Otherwise, we're looking at an Element node
        var result = this.makeElementNode(this.retPair);
        if (!result)
          return null;
  
        var node = this.retPair[0];
        var closed = this.retPair[1];
        var localName = node.localName;
  
        // If this isn't a void Element, read its child nodes
        if (!closed) {
          this.readChildren(node);
          var closingTag = "</" + localName + ">";
          if (!this.match(closingTag)) {
            this.error("expected '" + closingTag + "' and got " + this.html.substr(this.currentChar, closingTag.length));
            return null;
          }
        }
  
        // Only use the first title, because SVG might have other
        // title elements which we don't care about (medium.com
        // does this, at least).
        if (localName === "title" && !this.doc.title) {
          this.doc.title = node.textContent.trim();
        } else if (localName === "head") {
          this.doc.head = node;
        } else if (localName === "body") {
          this.doc.body = node;
        } else if (localName === "html") {
          this.doc.documentElement = node;
        }
  
        return node;
      }