Standard output from `dhtmlparser` is single-linked tree. This will make it
    double-linked.

    Args:
        dom (obj): :class:`.HTMLElement` instance.
        parent (obj, default None): Don't use this, it is used in recursive
               call.
340770
def makeDoubleLinked(dom, parent=None):
    
    dom.parent = parent

    for child in dom.childs:
        child.parent = dom
        makeDoubleLinked(child, dom)
946233
function hasDirectTextDescendantTreeWalker() {
        var treeWalker = ownerDocument.createTreeWalker(element,
                                                        NodeFilter.SHOW_TEXT,
                                                        null,
                                                        false);
        while (treeWalker.nextNode()) {
            var resultElement = treeWalker.currentNode;
            var parent = resultElement.parentNode;
            // Handle elements hosted in <template>.content.
            parent = parent.host || parent;
            var tagName = parent.tagName.toLowerCase();
            var value = resultElement.nodeValue.trim();
            if (value && tagName !== 'script' && element !== resultElement)
                return true;
        }
        return false;
    }
1205676
function (dom, prev, next) {
      var sibling, tmpSibling, elementUtils = new ElementUtils(dom);

      // Check if next/prev exists and that they are elements
      if (prev && next) {
        // If previous sibling is empty then jump over it
        prev = findElementSibling(prev, 'previousSibling');
        next = findElementSibling(next, 'nextSibling');

        // Compare next and previous nodes
        if (elementUtils.compare(prev, next)) {
          // Append nodes between
          for (sibling = prev.nextSibling; sibling && sibling !== next;) {
            tmpSibling = sibling;
            sibling = sibling.nextSibling;
            prev.appendChild(tmpSibling);
          }

          dom.remove(next);

          each(Tools.grep(next.childNodes), function (node) {
            prev.appendChild(node);
          });

          return prev;
        }
      }

      return next;
    }
218524
function htmlTreeAsString (elem) {
  var MAX_TRAVERSE_HEIGHT = 5
  var MAX_OUTPUT_LEN = 80
  var out = []
  var height = 0
  var len = 0
  var separator = ' > '
  var sepLength = separator.length
  var nextStr

  while (elem && height++ < MAX_TRAVERSE_HEIGHT) {
    nextStr = htmlElementAsString(elem)
    // bail out if
    // - nextStr is the 'html' element
    // - the length of the string that would be created exceeds MAX_OUTPUT_LEN
    //   (ignore this limit if we are on the first iteration)
    if (
      nextStr === 'html' ||
      (height > 1 &&
       len + (out.length * sepLength) + nextStr.length >= MAX_OUTPUT_LEN)
    ) {
      break
    }

    out.push(nextStr)

    len += nextStr.length
    elem = elem.parentNode
  }

  return out.reverse().join(separator)
}
1231116
def parse_navigation_html_to_tree(html, id):
    
    def xpath(x):
        return html.xpath(x, namespaces=HTML_DOCUMENT_NAMESPACES)
    try:
        value = xpath('//*[@data-type="binding"]/@data-value')[0]
        is_translucent = value == 'translucent'
    except IndexError:
        is_translucent = False
    if is_translucent:
        id = TRANSLUCENT_BINDER_ID
    tree = {'id': id,
            'title': xpath('//*[@data-type="document-title"]/text()')[0],
            'contents': [x for x in _nav_to_tree(xpath('//xhtml:nav')[0])]
            }
    return tree
783371
function parse (node, self) {
  let block = false

  if (node.nodeType === 3) {
    let delimiters = self.templateDelimiters

    if (delimiters) {
      let tokens = parseTemplate(node.data, delimiters)

      if (tokens.length) {
        if (!(tokens.length === 1 && tokens[0].type === 0)) {
          tokens.forEach((token, i) => {
            let text = document.createTextNode(token.value)
            node.parentNode.insertBefore(text, node)

            if (token.type === 1) {
              self.buildBinding(TextBinding, text, null, token.value)
            }
          })

          node.parentNode.removeChild(node)
        }
      }
    }
  } else if (node.nodeType === 1) {
    block = self.traverse(node)
  }

  if (!block) {
    Array.prototype.slice.call(node.childNodes).forEach(function (node) { parse(node, self) })
  }
}
395520
function _appendNode(parent, child) {
  var parentName = _getHTMLNodeName(parent);

  var childName = _getHTMLNodeName(child);

  if (doc.createStyleSheet) {
    if (parentName === 'script') {
      parent.text = child.nodeValue;
      return;
    }

    if (parentName === 'style') {
      parent.cssText = child.nodeValue; // This will not apply it--just make it available within the DOM cotents

      return;
    }
  }

  if (parentName === 'template') {
    parent.content.appendChild(child);
    return;
  }

  try {
    parent.appendChild(child); // IE9 is now ok with this
  } catch (e) {
    if (parentName === 'select' && childName === 'option') {
      try {
        // Since this is now DOM Level 4 standard behavior (and what IE7+ can handle), we try it first
        parent.add(child);
      } catch (err) {
        // DOM Level 2 did require a second argument, so we try it too just in case the user is using an older version of Firefox, etc.
        parent.add(child, null); // IE7 has a problem with this, but IE8+ is ok
      }

      return;
    }

    throw e;
  }
}
416765
function(tag, attrs, children){
    var el = document.createElement(tag);

    if(attrs != null && typeof attrs === typeof {}){
      Object.keys(attrs).forEach(function(key){
        var val = attrs[key];

        el.setAttribute(key, val);
      });
    } else if(typeof attrs === typeof []){
      children = attrs;
    }

    if(children != null && typeof children === typeof []){
      children.forEach(function(child){
        el.appendChild(child);
      });
    } else if(children != null && typeof children === typeof ''){
      el.appendChild(document.createTextNode(children));
    }

    return el;
  }
135739
function appendSpy(child) {
        // ignore appending to the node that's not yet added to DOM tree
        if (!this.parentNode) {
            return;
        }

        var destNodePath = phantomas.getDOMPath(this),
            appendedNodePath = phantomas.getDOMPath(child);

        // skip undefined nodes (issue #560)
        if (destNodePath === false) {
            return;
        }

        // don't count elements added to fragments as a DOM inserts (issue #350)
        // DocumentFragment > div[0]
        if (destNodePath.indexOf('DocumentFragment') === 0) {
            return;
        }

        phantomas.incrMetric('DOMinserts');
        phantomas.addOffender('DOMinserts', {append: appendedNodePath, node: destNodePath});

        phantomas.log('DOM insert: node "%s" appended to "%s"', appendedNodePath, destNodePath);
    }
43407
function(dom_node) {
							var index = get_template_instance_index(getFirstDOMChild(dom_node)),
								instance = index >= 0 ? template_instances[index] : false;

							if(instance) {
								delete template_instances[index];
								instance.destroy();
							}
							return this;
						}
561585
function nodeOwnOnlyChildrenAttach(parentEl, beforeEl) {
    this.sel = document.createComment(this.id);
    insertBefore(this.sel, parentEl, beforeEl);

    for (var i = 0; i < this.aNode.children.length; i++) {
        var child = createNode(
            this.aNode.children[i],
            this,
            this.childScope || this.scope,
            this.childOwner || this.owner
        );
        this.children.push(child);
        child.attach(parentEl, beforeEl);
    }

    this.el = document.createComment(this.id);
    insertBefore(this.el, parentEl, beforeEl);

    this.lifeCycle = LifeCycle.attached;
}
60846
def transform(self, html=None, pretty_print=True, **kwargs):
        
        if html is not None and self.html is not None:
            raise TypeError("Can't pass html argument twice")
        elif html is None and self.html is None:
            raise TypeError("must pass html as first argument")
        elif html is None:
            html = self.html
        if hasattr(html, "getroottree"):
            # skip the next bit
            root = html.getroottree()
            page = root
            tree = root
        else:
            if self.method == "xml":
                parser = etree.XMLParser(ns_clean=False, resolve_entities=False)
            else:
                parser = etree.HTMLParser()
            stripped = html.strip()
            tree = etree.fromstring(stripped, parser).getroottree()
            page = tree.getroot()
            # lxml inserts a doctype if none exists, so only include it in
            # the root if it was in the original html.
            root = tree if stripped.startswith(tree.docinfo.doctype) else page

        assert page is not None

        if self.disable_leftover_css:
            head = None
        else:
            head = get_or_create_head(tree)
        #
        # style selectors
        #

        rules = []
        index = 0

        cssselector = ["style"]
        if self.allow_network:
            cssselector.append("link[rel~=stylesheet]")
        for element in _create_cssselector(",".join(cssselector))(page):
            # If we have a media attribute whose value is anything other than
            # 'all' or 'screen', ignore the ruleset.
            media = element.attrib.get("media")
            if media and media not in ("all", "screen"):
                continue

            data_attribute = element.attrib.get(self.attribute_name)
            if data_attribute:
                if data_attribute == "ignore":
                    del element.attrib[self.attribute_name]
                    continue
                else:
                    warnings.warn(
                        "Unrecognized %s attribute (%r)"
                        % (self.attribute_name, data_attribute)
                    )

            is_style = element.tag == "style"
            if is_style:
                css_body = element.text
            else:
                href = element.attrib.get("href")
                css_body = self._load_external(href)

            these_rules, these_leftover = self._parse_style_rules(css_body, index)

            index += 1
            rules.extend(these_rules)
            parent_of_element = element.getparent()
            if these_leftover or self.keep_style_tags:
                if is_style:
                    style = element
                else:
                    style = etree.Element("style")
                    style.attrib["type"] = "text/css"
                if self.keep_style_tags:
                    style.text = css_body
                else:
                    style.text = self._css_rules_to_string(these_leftover)
                if self.method == "xml":
                    style.text = etree.CDATA(style.text)

                if not is_style:
                    element.addprevious(style)
                    parent_of_element.remove(element)

            elif not self.keep_style_tags or not is_style:
                parent_of_element.remove(element)

        # external style files
        if self.external_styles and self.allow_network:
            for stylefile in self.external_styles:
                css_body = self._load_external(stylefile)
                self._process_css_text(css_body, index, rules, head)
                index += 1

        # css text
        if self.css_text:
            for css_body in self.css_text:
                self._process_css_text(css_body, index, rules, head)
                index += 1

        # rules is a tuple of (specificity, selector, styles), where
        # specificity is a tuple ordered such that more specific
        # rules sort larger.
        rules.sort(key=operator.itemgetter(0))

        # collecting all elements that we need to apply rules on
        # id is unique for the lifetime of the object
        # and lxml should give us the same everytime during this run
        # item id -> {item: item, classes: [], style: []}
        elements = {}
        for _, selector, style in rules:
            new_selector = selector
            class_ = ""
            if ":" in selector:
                new_selector, class_ = re.split(":", selector, 1)
                class_ = ":%s" % class_
            # Keep filter-type selectors untouched.
            if class_ in FILTER_PSEUDOSELECTORS or class_.startswith(":nth-child"):
                class_ = ""
            else:
                selector = new_selector

            assert selector
            sel = _create_cssselector(selector)
            items = sel(page)
            if len(items):
                # same so process it first
                processed_style = csstext_to_pairs(style)

                for item in items:
                    item_id = id(item)
                    if item_id not in elements:
                        elements[item_id] = {"item": item, "classes": [], "style": []}

                    elements[item_id]["style"].append(processed_style)
                    elements[item_id]["classes"].append(class_)

        # Now apply inline style
        # merge style only once for each element
        # crucial when you have a lot of pseudo/classes
        # and a long list of elements
        for _, element in elements.items():
            final_style = merge_styles(
                element["item"].attrib.get("style", ""),
                element["style"],
                element["classes"],
                remove_unset_properties=self.remove_unset_properties,
            )
            if final_style:
                # final style could be empty string because of
                # remove_unset_properties
                element["item"].attrib["style"] = final_style
            self._style_to_basic_html_attributes(
                element["item"], final_style, force=True
            )

        if self.remove_classes:
            # now we can delete all 'class' attributes
            for item in page.xpath("//@class"):
                parent = item.getparent()
                del parent.attrib["class"]

        # Capitalize Margin properties
        # To fix weird outlook bug
        # https://www.emailonacid.com/blog/article/email-development/outlook.com-does-support-margins
        if self.capitalize_float_margin:
            for item in page.xpath("//@style"):
                mangled = capitalize_float_margin(item)
                item.getparent().attrib["style"] = mangled

        # Add align attributes to images if they have a CSS float value of
        # right or left. Outlook (both on desktop and on the web) are bad at
        # understanding floats, but they do understand the HTML align attrib.
        if self.align_floating_images:
            for item in page.xpath("//img[@style]"):
                image_css = cssutils.parseStyle(item.attrib["style"])
                if image_css.float == "right":
                    item.attrib["align"] = "right"
                elif image_css.float == "left":
                    item.attrib["align"] = "left"

        #
        # URLs
        #
        if self.base_url and not self.disable_link_rewrites:
            if not urlparse(self.base_url).scheme:
                raise ValueError("Base URL must have a scheme")
            for attr in ("href", "src"):
                for item in page.xpath("//@%s" % attr):
                    parent = item.getparent()
                    url = parent.attrib[attr]
                    if (
                        attr == "href"
                        and self.preserve_internal_links
                        and url.startswith("#")
                    ):
                        continue
                    if (
                        attr == "src"
                        and self.preserve_inline_attachments
                        and url.startswith("cid:")
                    ):
                        continue
                    if attr == "href" and url.startswith("tel:"):
                        continue
                    parent.attrib[attr] = urljoin(self.base_url, url)

        if hasattr(html, "getroottree"):
            return root
        else:
            kwargs.setdefault("method", self.method)
            kwargs.setdefault("pretty_print", pretty_print)
            kwargs.setdefault("encoding", "utf-8")  # As Ken Thompson intended
            out = etree.tostring(root, **kwargs).decode(kwargs["encoding"])
            if self.method == "xml":
                out = _cdata_regex.sub(
                    lambda m: "/*<![CDATA[*/%s/*]]>*/" % m.group(1), out
                )
            if self.strip_important:
                out = _importants.sub("", out)
            return out
1077352
function(tag, parent, interpolated){
    this.indents++;
    var name = tag.name
      , pp = this.pp
      , self = this;
    var ast = [];

    function bufferName() {
      if (interpolated) {
        if (tag.astExpr) return self.bufferAST(tag.astExpr);
        return self.bufferExpression(tag.expr);
      }
      else return self.buffer(name);
    }

    if (WHITE_SPACE_SENSITIVE_TAGS[tag.name] === true) this.escapePrettyMode = true;

    if (!this.hasCompiledTag) {
      if (!this.hasCompiledDoctype && 'html' == name) {
        push.apply(ast, this.visitDoctype());
      }
      this.hasCompiledTag = true;
    }
    // pretty print
    if (pp && !tag.isInline)
      push.apply(ast, this.prettyIndent(0, true));
    if (tag.selfClosing || (!this.xml && selfClosing[tag.name])) {
      push.apply(ast, this.buffer('<'));
      push.apply(ast, bufferName());
      push.apply(ast, this.visitAttributes(tag.attrs, this.attributeBlocks(tag.attributeBlocks)));
      if (this.terse && !tag.selfClosing) {
        push.apply(ast, this.buffer('>'));
      } else {
        push.apply(ast, this.buffer('/>'));
      }
      // if it is non-empty throw an error
      if (tag.code ||
          tag.block &&
          !(tag.block.type === 'Block' && tag.block.nodes.length === 0) &&
          tag.block.nodes.some(function (tag) {
            return tag.type !== 'Text' || !/^\s*$/.test(tag.val)
          })) {
        this.error(name + ' is a self closing element: <'+name+'/> but contains nested content.', 'SELF_CLOSING_CONTENT', tag);
      }
    } else {
      // Optimize attributes buffering
      push.apply(ast, this.buffer('<'));
      push.apply(ast, bufferName());
      push.apply(ast, this.visitAttributes(tag.attrs, this.attributeBlocks(tag.attributeBlocks)));
      push.apply(ast, this.buffer('>'));
      if (tag.code) push.apply(ast, this.visitCode(tag.code));
      push.apply(ast, this.visit(tag.block, tag));

      // pretty print
      if (pp && !tag.isInline && WHITE_SPACE_SENSITIVE_TAGS[tag.name] !== true && !tagCanInline(tag))
        push.apply(ast, this.prettyIndent(0, true));

      push.apply(ast, this.buffer('</'));
      push.apply(ast, bufferName());
      push.apply(ast, this.buffer('>'));
    }

    if (WHITE_SPACE_SENSITIVE_TAGS[tag.name] === true) this.escapePrettyMode = false;

    this.indents--;
    return ast;
  }
1163180
function recursiveDiff(vtree, elem) {
  var output = '';
  if (vtree == null && elem != null) {
    // If the VTree ran out but DOM still exists
    output += '<ins>' + utils.elementToString(elem, chars) + '</ins>';
  } else if (isVNode(vtree)) {
    if (!elem || elem.nodeType !== utils.NODE_TYPES.ELEMENT) {
      // If vtree is a VNode, but elem isn't an Element
      output += '<del>' + vNodeToString(vtree, true, false) + '</del>';
      if (elem) {
        output += '<ins>' + utils.elementToString(elem, chars) + '</ins>';
      }
    } else {
      // Diff elements and recurse
      output += diffElements(vtree, elem);
    }
  } else if (isVText(vtree)) {
    if (!elem || elem.nodeType !== utils.NODE_TYPES.TEXT) {
      // If vtree is a VText, but elem isn't a textNode
      output += '<del>' + escapeString(vtree.text) + '</del>';
      if (elem) {
        output += '<ins>' + utils.elementToString(elem, chars) + '</ins>';
      }
    } else {
      output += textDiff(vtree.text, elem.textContent);
    }
  } else if (isWidget(vtree)) {
    var widgetName;
    // Widgets are the construct that hold childViews
    if (vtree.constructor === HTMLCommentWidget) {
      // HTMLCommentWidget is a special case
      if (!elem || elem.nodeType !== utils.NODE_TYPES.COMMENT) {
        output += '<del>' + utils.getCommentString(escapeString(vtree.text), chars) + '</del>';
        if (elem) {
          output += '<ins>' + utils.elementToString(elem, chars) + '</ins>';
        }
      } else {
        output += utils.getCommentString(textDiff(escapeString(vtree.text), elem.textContent), chars);
      }
    } else if (vtree && vtree.view) {
      widgetName = vtree.view.getDebugName();
      if (typeof vtree.templateToString === 'function') {
        widgetName = vtree.templateToString(recursiveDiff);
      }
      if (vtree.view.el !== elem) {
        // If the view at this position isn't bound to elem, something has gone terribly wrong
        output += '<del><ins>' + widgetName + '</ins></del>';
      } else {
        output += widgetName;
      }
    } else if (vtree && typeof vtree.diff === 'function') {
      output += vtree.diff(elem, recursiveDiff);
    } else {
      output += '<del>[Uninitialized child view]</del>';
      output += '<ins>' + utils.elementToString(elem, chars) + '</ins>';
    }
  }
  return output;
}
96662
function(element) {
			var result = 0;
			var parent = element.parentNode;
			if (parent) {
				var node = parent.firstElementChild;
				while (node) {
					if (node === element) {
						break;
					} else {
						node = node.nextElementSibling;
						result++;
					}
				}
			}
			return result;
		}
821268
function DOMPostOrder(root, visitFunc) {
	let node = root;
	while (true) {
		// Find leftmost (grand)child, and visit that first.
		while (node.firstChild) {
			node = node.firstChild;
		}
		visitFunc(node);
		while (true) {
			if (node === root) {
				return; // Visiting the root is the last thing we do.
			}
			/* Look for right sibling to continue traversal. */
			if (node.nextSibling) {
				node = node.nextSibling;
				/* Loop back and visit its leftmost (grand)child first. */
				break;
			}
			/* Visit parent only after we've run out of right siblings. */
			node = node.parentNode;
			visitFunc(node);
		}
	}
}
52137
function(parent) {
		var temp = this.document.createElement(parent.nodeName);
		temp.innerHTML = this.xelement.outerHTML;
		return temp.firstChild;
	}