diff options
| author | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 | 
|---|---|---|
| committer | Joel Kronqvist <joel.h.kronqvist@gmail.com> | 2022-03-05 19:02:27 +0200 | 
| commit | 5d309ff52cd399a6b71968a6b9a70c8ac0b98981 (patch) | |
| tree | 360f7eb50f956e2367ef38fa1fc6ac7ac5258042 /node_modules/w3c-xmlserializer/lib | |
| parent | b500a50f1b97d93c98b36ed9a980f8188d648147 (diff) | |
| download | LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.tar.gz LYLLRuoka-5d309ff52cd399a6b71968a6b9a70c8ac0b98981.zip  | |
Added node_modules for the updating to work properly.
Diffstat (limited to 'node_modules/w3c-xmlserializer/lib')
| -rw-r--r-- | node_modules/w3c-xmlserializer/lib/attributes.js | 128 | ||||
| -rw-r--r-- | node_modules/w3c-xmlserializer/lib/constants.js | 44 | ||||
| -rw-r--r-- | node_modules/w3c-xmlserializer/lib/serialize.js | 371 | 
3 files changed, 543 insertions, 0 deletions
diff --git a/node_modules/w3c-xmlserializer/lib/attributes.js b/node_modules/w3c-xmlserializer/lib/attributes.js new file mode 100644 index 0000000..eff9e41 --- /dev/null +++ b/node_modules/w3c-xmlserializer/lib/attributes.js @@ -0,0 +1,128 @@ +"use strict"; + +const xnv = require("xml-name-validator"); + +const { NAMESPACES } = require("./constants"); + +function generatePrefix(map, newNamespace, prefixIndex) { +  const generatedPrefix = "ns" + prefixIndex; +  map[newNamespace] = [generatedPrefix]; +  return generatedPrefix; +} + +function preferredPrefixString(map, ns, preferredPrefix) { +  const candidateList = map[ns]; +  if (!candidateList) { +    return null; +  } +  if (candidateList.includes(preferredPrefix)) { +    return preferredPrefix; +  } +  return candidateList[candidateList.length - 1]; +} + +function serializeAttributeValue(value/* , requireWellFormed*/) { +  if (value === null) { +    return ""; +  } +  // TODO: Check well-formedness +  return value +    .replace(/&/g, "&") +    .replace(/"/g, """) +    .replace(/</g, "<") +    .replace(/>/g, ">") +    .replace(/\t/g, "	") +    .replace(/\n/g, "
") +    .replace(/\r/g, "
"); +} + +function serializeAttributes( +  element, +  map, +  localPrefixes, +  ignoreNamespaceDefAttr, +  requireWellFormed, +  refs +) { +  let result = ""; +  const namespaceLocalnames = Object.create(null); +  for (const attr of element.attributes) { +    if ( +      requireWellFormed && +      namespaceLocalnames[attr.namespaceURI] && +      namespaceLocalnames[attr.namespaceURI].has(attr.localName) +    ) { +      throw new Error("Found duplicated attribute"); +    } +    if (!namespaceLocalnames[attr.namespaceURI]) { +      namespaceLocalnames[attr.namespaceURI] = new Set(); +    } +    namespaceLocalnames[attr.namespaceURI].add(attr.localName); +    const attributeNamespace = attr.namespaceURI; +    let candidatePrefix = null; +    if (attributeNamespace !== null) { +      candidatePrefix = preferredPrefixString( +        map, +        attributeNamespace, +        attr.prefix +      ); +      if (attributeNamespace === NAMESPACES.XMLNS) { +        if ( +          attr.value === NAMESPACES.XML || +          (attr.prefix === null && ignoreNamespaceDefAttr) || +          (attr.prefix !== null && +            localPrefixes[attr.localName] !== attr.value && +            map[attr.value].includes(attr.localName)) +        ) { +          continue; +        } +        if (requireWellFormed && attr.value === NAMESPACES.XMLNS) { +          throw new Error( +            "The XMLNS namespace is reserved and cannot be applied as an element's namespace via XML parsing" +          ); +        } +        if (requireWellFormed && attr.value === "") { +          throw new Error( +            "Namespace prefix declarations cannot be used to undeclare a namespace" +          ); +        } +        if (attr.prefix === "xmlns") { +          candidatePrefix = "xmlns"; +        } +      } else if (candidatePrefix === null) { +        candidatePrefix = generatePrefix( +          map, +          attributeNamespace, +          refs.prefixIndex++ +        ); +        result += ` xmlns:${candidatePrefix}="${serializeAttributeValue( +          attributeNamespace, +          requireWellFormed +        )}"`; +      } +    } + +    result += " "; +    if (candidatePrefix !== null) { +      result += candidatePrefix + ":"; +    } +    if ( +      requireWellFormed && +      (attr.localName.includes(":") || +        !xnv.name(attr.localName) || +        (attr.localName === "xmlns" && attributeNamespace === null)) +    ) { +      throw new Error("Invalid attribute localName value"); +    } +    result += `${attr.localName}="${serializeAttributeValue( +      attr.value, +      requireWellFormed +    )}"`; +  } +  return result; +} + +module.exports.preferredPrefixString = preferredPrefixString; +module.exports.generatePrefix = generatePrefix; +module.exports.serializeAttributeValue = serializeAttributeValue; +module.exports.serializeAttributes = serializeAttributes; diff --git a/node_modules/w3c-xmlserializer/lib/constants.js b/node_modules/w3c-xmlserializer/lib/constants.js new file mode 100644 index 0000000..a5525b6 --- /dev/null +++ b/node_modules/w3c-xmlserializer/lib/constants.js @@ -0,0 +1,44 @@ +"use strict"; + +module.exports.NAMESPACES = { +  HTML: "http://www.w3.org/1999/xhtml", +  XML: "http://www.w3.org/XML/1998/namespace", +  XMLNS: "http://www.w3.org/2000/xmlns/" +}; + +module.exports.NODE_TYPES = { +  ELEMENT_NODE: 1, +  ATTRIBUTE_NODE: 2, // historical +  TEXT_NODE: 3, +  CDATA_SECTION_NODE: 4, +  ENTITY_REFERENCE_NODE: 5, // historical +  ENTITY_NODE: 6, // historical +  PROCESSING_INSTRUCTION_NODE: 7, +  COMMENT_NODE: 8, +  DOCUMENT_NODE: 9, +  DOCUMENT_TYPE_NODE: 10, +  DOCUMENT_FRAGMENT_NODE: 11, +  NOTATION_NODE: 12 // historical +}; + +module.exports.VOID_ELEMENTS = new Set([ +  "area", +  "base", +  "basefont", +  "bgsound", +  "br", +  "col", +  "embed", +  "frame", +  "hr", +  "img", +  "input", +  "keygen", +  "link", +  "menuitem", +  "meta", +  "param", +  "source", +  "track", +  "wbr" +]); diff --git a/node_modules/w3c-xmlserializer/lib/serialize.js b/node_modules/w3c-xmlserializer/lib/serialize.js new file mode 100644 index 0000000..c9533ba --- /dev/null +++ b/node_modules/w3c-xmlserializer/lib/serialize.js @@ -0,0 +1,371 @@ +"use strict"; + +const xnv = require("xml-name-validator"); + +const attributeUtils = require("./attributes"); +const { NAMESPACES, VOID_ELEMENTS, NODE_TYPES } = require("./constants"); + +const XML_CHAR = /^(\x09|\x0A|\x0D|[\x20-\uD7FF]|[\uE000-\uFFFD]|(?:[\uD800-\uDBFF][\uDC00-\uDFFF]))*$/; +const PUBID_CHAR = /^(\x20|\x0D|\x0A|[a-zA-Z0-9]|[-'()+,./:=?;!*#@$_%])*$/; + +function asciiCaseInsensitiveMatch(a, b) { +  if (a.length !== b.length) { +    return false; +  } + +  for (let i = 0; i < a.length; ++i) { +    if ((a.charCodeAt(i) | 32) !== (b.charCodeAt(i) | 32)) { +      return false; +    } +  } + +  return true; +} + +function recordNamespaceInformation(element, map, prefixMap) { +  let defaultNamespaceAttrValue = null; +  for (let i = 0; i < element.attributes.length; ++i) { +    const attr = element.attributes[i]; +    if (attr.namespaceURI === NAMESPACES.XMLNS) { +      if (attr.prefix === null) { +        defaultNamespaceAttrValue = attr.value; +        continue; +      } +      let namespaceDefinition = attr.value; +      if (namespaceDefinition === NAMESPACES.XML) { +        continue; +      } +      // This is exactly the other way than the spec says, but that's intended. +      // All the maps coalesce null to the empty string (explained in the +      // spec), so instead of doing that every time, just do it once here. +      if (namespaceDefinition === null) { +        namespaceDefinition = ""; +      } + +      if ( +        namespaceDefinition in map && +        map[namespaceDefinition].includes(attr.localName) +      ) { +        continue; +      } +      if (!(namespaceDefinition in map)) { +        map[namespaceDefinition] = []; +      } +      map[namespaceDefinition].push(attr.localName); +      prefixMap[attr.localName] = namespaceDefinition; +    } +  } +  return defaultNamespaceAttrValue; +} + +function serializeDocumentType(node, namespace, prefixMap, requireWellFormed) { +  if (requireWellFormed && !PUBID_CHAR.test(node.publicId)) { +    throw new Error("Failed to serialize XML: document type node publicId is not well-formed."); +  } + +  if ( +    requireWellFormed && +    (!XML_CHAR.test(node.systemId) || +      (node.systemId.includes('"') && node.systemId.includes("'"))) +  ) { +    throw new Error("Failed to serialize XML: document type node systemId is not well-formed."); +  } + +  let markup = `<!DOCTYPE ${node.name}`; +  if (node.publicId !== "") { +    markup += ` PUBLIC "${node.publicId}"`; +  } else if (node.systemId !== "") { +    markup += " SYSTEM"; +  } +  if (node.systemId !== "") { +    markup += ` "${node.systemId}"`; +  } +  return markup + ">"; +} + +function serializeProcessingInstruction( +  node, +  namespace, +  prefixMap, +  requireWellFormed +) { +  if ( +    requireWellFormed && +    (node.target.includes(":") || asciiCaseInsensitiveMatch(node.target, "xml")) +  ) { +    throw new Error("Failed to serialize XML: processing instruction node target is not well-formed."); +  } +  if ( +    requireWellFormed && +    (!XML_CHAR.test(node.data) || node.data.includes("?>")) +  ) { +    throw new Error("Failed to serialize XML: processing instruction node data is not well-formed."); +  } +  return `<?${node.target} ${node.data}?>`; +} + +function serializeDocument( +  node, +  namespace, +  prefixMap, +  requireWellFormed, +  refs +) { +  if (requireWellFormed && node.documentElement === null) { +    throw new Error("Failed to serialize XML: document does not have a document element."); +  } +  let serializedDocument = ""; +  for (const child of node.childNodes) { +    serializedDocument += xmlSerialization( +      child, +      namespace, +      prefixMap, +      requireWellFormed, +      refs +    ); +  } +  return serializedDocument; +} + +function serializeDocumentFragment( +  node, +  namespace, +  prefixMap, +  requireWellFormed, +  refs +) { +  let markup = ""; +  for (const child of node.childNodes) { +    markup += xmlSerialization( +      child, +      namespace, +      prefixMap, +      requireWellFormed, +      refs +    ); +  } +  return markup; +} + +function serializeText(node, namespace, prefixMap, requireWellFormed) { +  if (requireWellFormed && !XML_CHAR.test(node.data)) { +    throw new Error("Failed to serialize XML: text node data is not well-formed."); +  } + +  return node.data +    .replace(/&/g, "&") +    .replace(/</g, "<") +    .replace(/>/g, ">"); +} + +function serializeComment(node, namespace, prefixMap, requireWellFormed) { +  if (requireWellFormed && !XML_CHAR.test(node.data)) { +    throw new Error("Failed to serialize XML: comment node data is not well-formed."); +  } + +  if ( +    requireWellFormed && +    (node.data.includes("--") || node.data.endsWith("-")) +  ) { +    throw new Error("Failed to serialize XML: found hyphens in illegal places in comment node data."); +  } +  return `<!--${node.data}-->`; +} + +function serializeElement(node, namespace, prefixMap, requireWellFormed, refs) { +  if ( +    requireWellFormed && +    (node.localName.includes(":") || !xnv.name(node.localName)) +  ) { +    throw new Error("Failed to serialize XML: element node localName is not a valid XML name."); +  } +  let markup = "<"; +  let qualifiedName = ""; +  let skipEndTag = false; +  let ignoreNamespaceDefinitionAttr = false; +  const map = Object.assign({}, prefixMap); +  const localPrefixesMap = Object.create(null); +  const localDefaultNamespace = recordNamespaceInformation( +    node, +    map, +    localPrefixesMap +  ); +  let inheritedNs = namespace; +  const ns = node.namespaceURI; +  if (inheritedNs === ns) { +    if (localDefaultNamespace !== null) { +      ignoreNamespaceDefinitionAttr = true; +    } +    if (ns === NAMESPACES.XML) { +      qualifiedName = "xml:" + node.localName; +    } else { +      qualifiedName = node.localName; +    } +    markup += qualifiedName; +  } else { +    let { prefix } = node; +    let candidatePrefix = attributeUtils.preferredPrefixString(map, ns, prefix); +    if (prefix === "xmlns") { +      if (requireWellFormed) { +        throw new Error("Failed to serialize XML: element nodes can't have a prefix of \"xmlns\"."); +      } +      candidatePrefix = "xmlns"; +    } +    if (candidatePrefix !== null) { +      qualifiedName = candidatePrefix + ":" + node.localName; +      if ( +        localDefaultNamespace !== null && +        localDefaultNamespace !== NAMESPACES.XML +      ) { +        inheritedNs = +          localDefaultNamespace === "" ? null : localDefaultNamespace; +      } +      markup += qualifiedName; +    } else if (prefix !== null) { +      if (prefix in localPrefixesMap) { +        prefix = attributeUtils.generatePrefix(map, ns, refs.prefixIndex++); +      } +      if (map[ns]) { +        map[ns].push(prefix); +      } else { +        map[ns] = [prefix]; +      } +      qualifiedName = prefix + ":" + node.localName; +      markup += `${qualifiedName} xmlns:${prefix}="${attributeUtils.serializeAttributeValue( +        ns, +        requireWellFormed +      )}"`; +      if (localDefaultNamespace !== null) { +        inheritedNs = +          localDefaultNamespace === "" ? null : localDefaultNamespace; +      } +    } else if (localDefaultNamespace === null || localDefaultNamespace !== ns) { +      ignoreNamespaceDefinitionAttr = true; +      qualifiedName = node.localName; +      inheritedNs = ns; +      markup += `${qualifiedName} xmlns="${attributeUtils.serializeAttributeValue( +        ns, +        requireWellFormed +      )}"`; +    } else { +      qualifiedName = node.localName; +      inheritedNs = ns; +      markup += qualifiedName; +    } +  } + +  markup += attributeUtils.serializeAttributes( +    node, +    map, +    localPrefixesMap, +    ignoreNamespaceDefinitionAttr, +    requireWellFormed, +    refs +  ); + +  if ( +    ns === NAMESPACES.HTML && +    node.childNodes.length === 0 && +    VOID_ELEMENTS.has(node.localName) +  ) { +    markup += " /"; +    skipEndTag = true; +  } else if (ns !== NAMESPACES.HTML && node.childNodes.length === 0) { +    markup += "/"; +    skipEndTag = true; +  } +  markup += ">"; +  if (skipEndTag) { +    return markup; +  } + +  if (ns === NAMESPACES.HTML && node.localName === "template") { +    markup += xmlSerialization( +      node.content, +      inheritedNs, +      map, +      requireWellFormed, +      refs +    ); +  } else { +    for (const child of node.childNodes) { +      markup += xmlSerialization( +        child, +        inheritedNs, +        map, +        requireWellFormed, +        refs +      ); +    } +  } +  markup += `</${qualifiedName}>`; +  return markup; +} + +function serializeCDATASection(node) { +  return "<![CDATA[" + node.data + "]]>"; +} + +/** + * @param {{prefixIndex: number}} refs + */ +function xmlSerialization(node, namespace, prefixMap, requireWellFormed, refs) { +  switch (node.nodeType) { +    case NODE_TYPES.ELEMENT_NODE: +      return serializeElement( +        node, +        namespace, +        prefixMap, +        requireWellFormed, +        refs +      ); +    case NODE_TYPES.DOCUMENT_NODE: +      return serializeDocument( +        node, +        namespace, +        prefixMap, +        requireWellFormed, +        refs +      ); +    case NODE_TYPES.COMMENT_NODE: +      return serializeComment(node, namespace, prefixMap, requireWellFormed); +    case NODE_TYPES.TEXT_NODE: +      return serializeText(node, namespace, prefixMap, requireWellFormed); +    case NODE_TYPES.DOCUMENT_FRAGMENT_NODE: +      return serializeDocumentFragment( +        node, +        namespace, +        prefixMap, +        requireWellFormed, +        refs +      ); +    case NODE_TYPES.DOCUMENT_TYPE_NODE: +      return serializeDocumentType( +        node, +        namespace, +        prefixMap, +        requireWellFormed +      ); +    case NODE_TYPES.PROCESSING_INSTRUCTION_NODE: +      return serializeProcessingInstruction( +        node, +        namespace, +        prefixMap, +        requireWellFormed +      ); +    case NODE_TYPES.ATTRIBUTE_NODE: +      return ""; +    case NODE_TYPES.CDATA_SECTION_NODE: +      return serializeCDATASection(node); +    default: +      throw new TypeError("Failed to serialize XML: only Nodes can be serialized."); +  } +} + +module.exports = (root, { requireWellFormed = false } = {}) => { +  const namespacePrefixMap = Object.create(null); +  namespacePrefixMap["http://www.w3.org/XML/1998/namespace"] = ["xml"]; +  return xmlSerialization(root, null, namespacePrefixMap, requireWellFormed, { +    prefixIndex: 1 +  }); +};  | 
