ref: c43dc872397e19d8d23a5296b661cc7eced8223c
dir: /domino-lib/xmlnames.js/
"use strict"; // This grammar is from the XML and XML Namespace specs. It specifies whether // a string (such as an element or attribute name) is a valid Name or QName. // // Name ::= NameStartChar (NameChar)* // NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | // [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | // [#x370-#x37D] | [#x37F-#x1FFF] | // [#x200C-#x200D] | [#x2070-#x218F] | // [#x2C00-#x2FEF] | [#x3001-#xD7FF] | // [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | // [#x10000-#xEFFFF] // // NameChar ::= NameStartChar | "-" | "." | [0-9] | // #xB7 | [#x0300-#x036F] | [#x203F-#x2040] // // QName ::= PrefixedName| UnprefixedName // PrefixedName ::= Prefix ':' LocalPart // UnprefixedName ::= LocalPart // Prefix ::= NCName // LocalPart ::= NCName // NCName ::= Name - (Char* ':' Char*) // # An XML Name, minus the ":" // exports.isValidName = isValidName; exports.isValidQName = isValidQName; // Most names will be ASCII only. Try matching against simple regexps first var simplename = /^[_:A-Za-z][-.:\w]+$/; var simpleqname = /^([_A-Za-z][-.\w]+|[_A-Za-z][-.\w]+:[_A-Za-z][-.\w]+)$/; // If the regular expressions above fail, try more complex ones that work // for any identifiers using codepoints from the Unicode BMP var ncnamestartchars = "_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02ff\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD"; var ncnamechars = "-._A-Za-z0-9\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02ff\u0300-\u037D\u037F-\u1FFF\u200C\u200D\u203f\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD"; var ncname = "[" + ncnamestartchars + "][" + ncnamechars + "]*"; var namestartchars = ncnamestartchars + ":"; var namechars = ncnamechars + ":"; var name = new RegExp("^[" + namestartchars + "]" + "[" + namechars + "]*$"); var qname = new RegExp("^(" + ncname + "|" + ncname + ":" + ncname + ")$"); // XML says that these characters are also legal: // [#x10000-#xEFFFF]. So if the patterns above fail, and the // target string includes surrogates, then try the following // patterns that allow surrogates and then run an extra validation // step to make sure that the surrogates are in valid pairs and in // the right range. Note that since the characters \uf0000 to \u1f0000 // are not allowed, it means that the high surrogate can only go up to // \uDB7f instead of \uDBFF. var hassurrogates = /[\uD800-\uDB7F\uDC00-\uDFFF]/; var surrogatechars = /[\uD800-\uDB7F\uDC00-\uDFFF]/g; var surrogatepairs = /[\uD800-\uDB7F][\uDC00-\uDFFF]/g; // Modify the variables above to allow surrogates ncnamestartchars += "\uD800-\uDB7F\uDC00-\uDFFF"; ncnamechars += "\uD800-\uDB7F\uDC00-\uDFFF"; ncname = "[" + ncnamestartchars + "][" + ncnamechars + "]*"; namestartchars = ncnamestartchars + ":"; namechars = ncnamechars + ":"; // Build another set of regexps that include surrogates var surrogatename = new RegExp("^[" + namestartchars + "]" + "[" + namechars + "]*$"); var surrogateqname = new RegExp("^(" + ncname + "|" + ncname + ":" + ncname + ")$"); function isValidName(s) { if (simplename.test(s)) return true; // Plain ASCII if (name.test(s)) return true; // Unicode BMP // Maybe the tests above failed because s includes surrogate pairs // Most likely, though, they failed for some more basic syntax problem if (!hassurrogates.test(s)) return false; // Is the string a valid name if we allow surrogates? if (!surrogatename.test(s)) return false; // Finally, are the surrogates all correctly paired up? var chars = s.match(surrogatechars), pairs = s.match(surrogatepairs); return pairs !== null && 2*pairs.length === chars.length; } function isValidQName(s) { if (simpleqname.test(s)) return true; // Plain ASCII if (qname.test(s)) return true; // Unicode BMP if (!hassurrogates.test(s)) return false; if (!surrogateqname.test(s)) return false; var chars = s.match(surrogatechars), pairs = s.match(surrogatepairs); return pairs !== null && 2*pairs.length === chars.length; }