Repository: angular/angular.js
File: src/jqLite.js (JavaScript)

Code before:
  // The window object can accept data but has no nodeType
  // Otherwise we are only interested in elements (1) and documents (9)
  var nodeType = node.nodeType;
  return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;
}

function jqLiteHasData(node) {
  for (var key in jqCache[node.ng339]) {
    return true;
  }
  return false;
}

function jqLiteBuildFragment(html, context) {
  var tmp, tag, wrap, finalHtml,
      fragment = context.createDocumentFragment(),
      nodes = [], i;

  if (jqLiteIsTextNode(html)) {
    // Convert non-html into a text node
    nodes.push(context.createTextNode(html));
  } else {
    // Convert html into DOM nodes
    tmp = fragment.appendChild(context.createElement('div'));
    tag = (TAG_NAME_REGEXP.exec(html) || ['', ''])[1].toLowerCase();
    wrap = wrapMap[tag] || wrapMap._default;
    finalHtml = JQLite.legacyXHTMLReplacement ?
      html.replace(XHTML_TAG_REGEXP, '<$1></$2>') :
      html;
    tmp.innerHTML = wrap[1] + finalHtml + wrap[2];

    // Descend through wrappers to the right content
    i = wrap[0];
    while (i--) {
      tmp = tmp.lastChild;
    }

    nodes = concat(nodes, tmp.childNodes);

    tmp = fragment.firstChild;
    tmp.textContent = '';
  }

  // Remove wrapper from fragment
  fragment.textContent = '';
  fragment.innerHTML = ''; // Clear inner HTML
  forEach(nodes, function(node) {
    fragment.appendChild(node);
  });

  return fragment;

Review comment (security):
You could get rid of `_default`, e.g. like this:

```javascript
wrap = wrapMap[tag]
finalHTML = ...
tmp.innerHTML = wrap ? wrap[1] + finalHtml + wrap[2]  : finalHtml;
i = wrap ? wrap[0] : 0;
while (i--) { //...
```

That's a no-op for the security fix, but is shorter - and lets you pipe through the data without any string concatenation (e.g. letting through `TrustedHTML` objects that DOMPurify might return).

Code after:
  var wrapMapValueClosing = wrapMap[key];
  var wrapMapValue = wrapMapValueClosing.slice().reverse();
  wrapMapIE9[key] = [wrapMapValue.length, '<' + wrapMapValue.join('><') + '>', '</' + wrapMapValueClosing.join('></') + '>'];
}

wrapMapIE9.optgroup = wrapMapIE9.option;

function jqLiteIsTextNode(html) {
  return !HTML_REGEXP.test(html);
}

function jqLiteAcceptsData(node) {
  // The window object can accept data but has no nodeType
  // Otherwise we are only interested in elements (1) and documents (9)
  var nodeType = node.nodeType;
  return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;
}

function jqLiteHasData(node) {
  for (var key in jqCache[node.ng339]) {
    return true;
  }
  return false;
}

function jqLiteBuildFragment(html, context) {
  var tmp, tag, wrap, finalHtml,
      fragment = context.createDocumentFragment(),
      nodes = [], i;

  if (jqLiteIsTextNode(html)) {
    // Convert non-html into a text node
    nodes.push(context.createTextNode(html));
  } else {
    // Convert html into DOM nodes
    tmp = fragment.appendChild(context.createElement('div'));
    tag = (TAG_NAME_REGEXP.exec(html) || ['', ''])[1].toLowerCase();
    finalHtml = JQLite.legacyXHTMLReplacement ?
      html.replace(XHTML_TAG_REGEXP, '<$1></$2>') :
      html;

    if (msie < 10) {
      wrap = wrapMapIE9[tag] || wrapMapIE9._default;
      tmp.innerHTML = wrap[1] + finalHtml + wrap[2];

      // Descend through wrappers to the right content
      i = wrap[0];
      while (i--) {
        tmp = tmp.firstChild;
      }
    } else {