| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 | "use strict";const { isASCIIHex } = require("./infra");const { utf8Encode } = require("./encoding");function p(char) {  return char.codePointAt(0);}// https://url.spec.whatwg.org/#percent-encodefunction percentEncode(c) {  let hex = c.toString(16).toUpperCase();  if (hex.length === 1) {    hex = `0${hex}`;  }  return `%${hex}`;}// https://url.spec.whatwg.org/#percent-decodefunction percentDecodeBytes(input) {  const output = new Uint8Array(input.byteLength);  let outputIndex = 0;  for (let i = 0; i < input.byteLength; ++i) {    const byte = input[i];    if (byte !== 0x25) {      output[outputIndex++] = byte;    } else if (byte === 0x25 && (!isASCIIHex(input[i + 1]) || !isASCIIHex(input[i + 2]))) {      output[outputIndex++] = byte;    } else {      const bytePoint = parseInt(String.fromCodePoint(input[i + 1], input[i + 2]), 16);      output[outputIndex++] = bytePoint;      i += 2;    }  }  return output.slice(0, outputIndex);}// https://url.spec.whatwg.org/#string-percent-decodefunction percentDecodeString(input) {  const bytes = utf8Encode(input);  return percentDecodeBytes(bytes);}// https://url.spec.whatwg.org/#c0-control-percent-encode-setfunction isC0ControlPercentEncode(c) {  return c <= 0x1F || c > 0x7E;}// https://url.spec.whatwg.org/#fragment-percent-encode-setconst extraFragmentPercentEncodeSet = new Set([p(" "), p("\""), p("<"), p(">"), p("`")]);function isFragmentPercentEncode(c) {  return isC0ControlPercentEncode(c) || extraFragmentPercentEncodeSet.has(c);}// https://url.spec.whatwg.org/#query-percent-encode-setconst extraQueryPercentEncodeSet = new Set([p(" "), p("\""), p("#"), p("<"), p(">")]);function isQueryPercentEncode(c) {  return isC0ControlPercentEncode(c) || extraQueryPercentEncodeSet.has(c);}// https://url.spec.whatwg.org/#special-query-percent-encode-setfunction isSpecialQueryPercentEncode(c) {  return isQueryPercentEncode(c) || c === p("'");}// https://url.spec.whatwg.org/#path-percent-encode-setconst extraPathPercentEncodeSet = new Set([p("?"), p("`"), p("{"), p("}")]);function isPathPercentEncode(c) {  return isQueryPercentEncode(c) || extraPathPercentEncodeSet.has(c);}// https://url.spec.whatwg.org/#userinfo-percent-encode-setconst extraUserinfoPercentEncodeSet =  new Set([p("/"), p(":"), p(";"), p("="), p("@"), p("["), p("\\"), p("]"), p("^"), p("|")]);function isUserinfoPercentEncode(c) {  return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c);}// https://url.spec.whatwg.org/#component-percent-encode-setconst extraComponentPercentEncodeSet = new Set([p("$"), p("%"), p("&"), p("+"), p(",")]);function isComponentPercentEncode(c) {  return isUserinfoPercentEncode(c) || extraComponentPercentEncodeSet.has(c);}// https://url.spec.whatwg.org/#application-x-www-form-urlencoded-percent-encode-setconst extraURLEncodedPercentEncodeSet = new Set([p("!"), p("'"), p("("), p(")"), p("~")]);function isURLEncodedPercentEncode(c) {  return isComponentPercentEncode(c) || extraURLEncodedPercentEncodeSet.has(c);}// https://url.spec.whatwg.org/#code-point-percent-encode-after-encoding// https://url.spec.whatwg.org/#utf-8-percent-encode// Assuming encoding is always utf-8 allows us to trim one of the logic branches. TODO: support encoding.// The "-Internal" variant here has code points as JS strings. The external version used by other files has code points// as JS numbers, like the rest of the codebase.function utf8PercentEncodeCodePointInternal(codePoint, percentEncodePredicate) {  const bytes = utf8Encode(codePoint);  let output = "";  for (const byte of bytes) {    // Our percentEncodePredicate operates on bytes, not code points, so this is slightly different from the spec.    if (!percentEncodePredicate(byte)) {      output += String.fromCharCode(byte);    } else {      output += percentEncode(byte);    }  }  return output;}function utf8PercentEncodeCodePoint(codePoint, percentEncodePredicate) {  return utf8PercentEncodeCodePointInternal(String.fromCodePoint(codePoint), percentEncodePredicate);}// https://url.spec.whatwg.org/#string-percent-encode-after-encoding// https://url.spec.whatwg.org/#string-utf-8-percent-encodefunction utf8PercentEncodeString(input, percentEncodePredicate, spaceAsPlus = false) {  let output = "";  for (const codePoint of input) {    if (spaceAsPlus && codePoint === " ") {      output += "+";    } else {      output += utf8PercentEncodeCodePointInternal(codePoint, percentEncodePredicate);    }  }  return output;}module.exports = {  isC0ControlPercentEncode,  isFragmentPercentEncode,  isQueryPercentEncode,  isSpecialQueryPercentEncode,  isPathPercentEncode,  isUserinfoPercentEncode,  isURLEncodedPercentEncode,  percentDecodeString,  percentDecodeBytes,  utf8PercentEncodeString,  utf8PercentEncodeCodePoint};
 |