@difizen/mana-common
Version:
643 lines (619 loc) • 27.1 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.URI = void 0;
exports.uriToFsPath = uriToFsPath;
var _charCode = require("./char-code");
var _platform = require("./platform");
var _encodeTable;
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var _schemePattern = /^\w[\w\d+.-]*$/;
var _singleSlashStart = /^\//;
var _doubleSlashStart = /^\/\//;
function _validateUri(ret, _strict) {
// scheme, must be set
if (!ret.scheme && _strict) {
throw new Error("[UriError]: Scheme is missing: {scheme: \"\", authority: \"".concat(ret.authority, "\", path: \"").concat(ret.path, "\", query: \"").concat(ret.query, "\", fragment: \"").concat(ret.fragment, "\"}"));
}
// scheme, https://tools.ietf.org/html/rfc3986#section-3.1
// ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
if (ret.scheme && !_schemePattern.test(ret.scheme)) {
throw new Error('[UriError]: Scheme contains illegal characters.');
}
// path, http://tools.ietf.org/html/rfc3986#section-3.3
// If a URI contains an authority component, then the path component
// must either be empty or begin with a slash ("/") character. If a URI
// does not contain an authority component, then the path cannot begin
// with two slash characters ("//").
if (ret.path) {
if (ret.authority) {
if (!_singleSlashStart.test(ret.path)) {
throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character');
}
} else {
if (_doubleSlashStart.test(ret.path)) {
throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")');
}
}
}
}
// for a while we allowed uris *without* schemes and this is the migration
// for them, e.g. an uri without scheme and without strict-mode warns and falls
// back to the file-scheme. that should cause the least carnage and still be a
// clear warning
function _schemeFix(scheme, _strict) {
if (!scheme && !_strict) {
return 'file';
}
return scheme;
}
// implements a bit of https://tools.ietf.org/html/rfc3986#section-5
function _referenceResolution(scheme, path) {
// the slash-character is our 'default base' as we don't
// support constructing URIs relative to other URIs. This
// also means that we alter and potentially break paths.
// see https://tools.ietf.org/html/rfc3986#section-5.1.4
switch (scheme) {
case 'https':
case 'http':
case 'file':
if (!path) {
path = _slash;
} else if (path[0] !== _slash) {
path = _slash + path;
}
break;
}
return path;
}
var _empty = '';
var _slash = '/';
var _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
var _regexpSimple = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?(.*?)$/;
/**
* Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.
* This class is a simple parser which creates the basic component parts
* (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation
* and encoding.
*
* ```txt
* foo://example.com:8042/over/there?name=ferret#nose
* \_/ \______________/\_________/ \_________/ \__/
* | | | | |
* scheme authority path query fragment
* | _____________________|__
* / \ / \
* urn:example:animal:ferret:nose
* ```
*/
var URI = exports.URI = /*#__PURE__*/function () {
/**
* @internal
*/
function URI(schemeOrData, authority, path, query, fragment) {
var _strict = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
var options = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {
simpleMode: true
};
_classCallCheck(this, URI);
/**
* scheme is the 'http' part of 'http://www.example.com/some/path?query#fragment'.
* The part before the first colon.
*/
_defineProperty(this, "scheme", void 0);
/**
* authority is the 'www.example.com' part of 'http://www.example.com/some/path?query#fragment'.
* The part between the first double slashes and the next slash.
*/
_defineProperty(this, "authority", void 0);
/**
* path is the '/some/path' part of 'http://www.example.com/some/path?query#fragment'.
*/
_defineProperty(this, "path", void 0);
/**
* query is the 'query' part of 'http://www.example.com/some/path?query#fragment'.
*/
_defineProperty(this, "query", void 0);
/**
* fragment is the 'fragment' part of 'http://www.example.com/some/path?query#fragment'.
*/
_defineProperty(this, "fragment", void 0);
_defineProperty(this, "simpleMode", void 0);
if (_typeof(schemeOrData) === 'object') {
this.scheme = schemeOrData.scheme || _empty;
this.authority = schemeOrData.authority || _empty;
this.path = schemeOrData.path || _empty;
this.query = schemeOrData.query || _empty;
this.fragment = schemeOrData.fragment || _empty;
// no validation because it's this URI
// that creates uri components.
// _validateUri(this);
} else {
this.scheme = _schemeFix(schemeOrData, _strict);
this.authority = authority || _empty;
this.path = _referenceResolution(this.scheme, path || _empty);
this.query = query || _empty;
this.fragment = fragment || _empty;
_validateUri(this, _strict);
}
this.simpleMode = options.simpleMode;
}
// ---- filesystem path -----------------------
/**
* Returns a string representing the corresponding file system path of this URI.
* Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the
* platform specific path separator.
*
* * Will *not* validate the path for invalid characters and semantics.
* * Will *not* look at the scheme of this URI.
* * The result shall *not* be used for display purposes but for accessing a file on disk.
*
*
* The *difference* to `URI#path` is the use of the platform specific separator and the handling
* of UNC paths. See the below sample of a file-uri with an authority (UNC path).
*
* ```ts
const u = URI.parse('file://server/c$/folder/file.txt')
u.authority === 'server'
u.path === '/shares/c$/file.txt'
u.fsPath === '\\server\c$\folder\file.txt'
```
*
* Using `URI#path` to read a file (using fs-apis) would not be enough because parts of the path,
* namely the server name, would be missing. Therefore `URI#fsPath` exists - it's sugar to ease working
* with URIs that represent files on disk (`file` scheme).
*/
_createClass(URI, [{
key: "fsPath",
get: function get() {
// if (this.scheme !== 'file') {
// console.warn(`[UriError] calling fsPath with scheme ${this.scheme}`);
// }
return uriToFsPath(this, false);
}
// ---- modify to new -------------------------
}, {
key: "with",
value: function _with(change) {
if (!change) {
return this;
}
var scheme = change.scheme,
authority = change.authority,
path = change.path,
query = change.query,
fragment = change.fragment;
if (scheme === undefined) {
scheme = this.scheme;
} else if (scheme === null) {
scheme = _empty;
}
if (authority === undefined) {
authority = this.authority;
} else if (authority === null) {
authority = _empty;
}
if (path === undefined) {
path = this.path;
} else if (path === null) {
path = _empty;
}
if (query === undefined) {
query = this.query;
} else if (query === null) {
query = _empty;
}
if (fragment === undefined) {
fragment = this.fragment;
} else if (fragment === null) {
fragment = _empty;
}
if (scheme === this.scheme && authority === this.authority && path === this.path && query === this.query && fragment === this.fragment) {
return this;
}
return new Uri(scheme, authority, path, query, fragment);
}
// ---- parse & validate ------------------------
/**
* Creates a new URI from a string, e.g. `http://www.example.com/some/path`,
* `file:///usr/home`, or `scheme:with/path`.
*
* @param value A string which represents an URI (see `URI#toString`).
*/
}, {
key: "toString",
value:
// ---- printing/externalize ---------------------------
/**
* Creates a string representation for this URI. It's guaranteed that calling
* `URI.parse` with the result of this function creates an URI which is equal
* to this URI.
*
* * The result shall *not* be used for display purposes but for externalization or transport.
* * The result will be encoded using the percentage encoding and encoding happens mostly
* ignore the scheme-specific encoding rules.
*
* @param skipEncoding Do not encode the result, default is `false`
*/
function toString() {
var skipEncoding = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
return _asFormatted(this, skipEncoding);
}
}, {
key: "toJSON",
value: function toJSON() {
return this;
}
}], [{
key: "isUri",
value: function isUri(thing) {
if (thing instanceof URI) {
return true;
}
if (!thing) {
return false;
}
return typeof thing.authority === 'string' && typeof thing.fragment === 'string' && typeof thing.path === 'string' && typeof thing.query === 'string' && typeof thing.scheme === 'string' && typeof thing.fsPath === 'string' && typeof thing.with === 'function' && typeof thing.toString === 'function';
}
}, {
key: "parse",
value: function parse(value) {
var _strict = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
simpleMode: true
};
if (options.simpleMode) {
var match = _regexpSimple.exec(value);
if (!match) {
return new Uri(_empty, _empty, _empty, _empty, _empty);
}
return new Uri(match[2] || _empty, match[4] || _empty, match[5] || _empty, _empty, _empty, _strict, options);
} else {
var _match = _regexp.exec(value);
if (!_match) {
return new Uri(_empty, _empty, _empty, _empty, _empty);
}
return new Uri(_match[2] || _empty, percentDecode(_match[4] || _empty), percentDecode(_match[5] || _empty), percentDecode(_match[7] || _empty), percentDecode(_match[9] || _empty), _strict, options);
}
}
/**
* Creates a new URI from a file system path, e.g. `c:\my\files`,
* `/usr/home`, or `\\server\share\some\path`.
*
* The *difference* between `URI#parse` and `URI#file` is that the latter treats the argument
* as path, not as stringified-uri. E.g. `URI.file(path)` is **not the same as**
* `URI.parse('file://' + path)` because the path might contain characters that are
* interpreted (# and ?). See the following sample:
* ```ts
const good = URI.file('/coding/c#/project1');
good.scheme === 'file';
good.path === '/coding/c#/project1';
good.fragment === '';
const bad = URI.parse('file://' + '/coding/c#/project1');
bad.scheme === 'file';
bad.path === '/coding/c'; // path is now broken
bad.fragment === '/project1';
```
*
* @param path A file system path (see `URI#fsPath`)
*/
}, {
key: "file",
value: function file(path) {
var authority = _empty;
// normalize to fwd-slashes on windows,
// on other systems bwd-slashes are valid
// filename character, eg /f\oo/ba\r.txt
if (_platform.isWindows) {
path = path.replace(/\\/g, _slash);
}
// check for authority as used in UNC shares
// or use the path as given
if (path[0] === _slash && path[1] === _slash) {
var idx = path.indexOf(_slash, 2);
if (idx === -1) {
authority = path.substring(2);
path = _slash;
} else {
authority = path.substring(2, idx);
path = path.substring(idx) || _slash;
}
}
return new Uri('file', authority, path, _empty, _empty);
}
}, {
key: "from",
value: function from(components) {
var result = new Uri(components.scheme, components.authority, components.path, components.query, components.fragment);
_validateUri(result, true);
return result;
}
}, {
key: "revive",
value: function revive(data) {
if (!data) {
return data;
} else if (data instanceof URI) {
return data;
} else {
var result = new Uri(data);
result._formatted = data.external;
result._fsPath = data._sep === _pathSepMarker ? data.fsPath : null;
return result;
}
}
}]);
return URI;
}();
var _pathSepMarker = _platform.isWindows ? 1 : undefined;
// This class exists so that URI is compatible with vscode.Uri (API).
var Uri = /*#__PURE__*/function (_URI) {
_inherits(Uri, _URI);
var _super = _createSuper(Uri);
function Uri() {
var _this;
_classCallCheck(this, Uri);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _super.call.apply(_super, [this].concat(args));
_defineProperty(_assertThisInitialized(_this), "_formatted", null);
_defineProperty(_assertThisInitialized(_this), "_fsPath", null);
return _this;
}
_createClass(Uri, [{
key: "fsPath",
get: function get() {
if (!this._fsPath) {
this._fsPath = uriToFsPath(this, false);
}
return this._fsPath;
}
}, {
key: "toString",
value: function toString() {
var skipEncoding = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
if (!skipEncoding) {
if (!this._formatted) {
this._formatted = _asFormatted(this, false);
}
return this._formatted;
} else {
// we don't cache that
return _asFormatted(this, true);
}
}
}, {
key: "toJSON",
value: function toJSON() {
var res = {
$mid: 1
};
// cached state
if (this._fsPath) {
res.fsPath = this._fsPath;
res._sep = _pathSepMarker;
}
if (this._formatted) {
res.external = this._formatted;
}
// uri components
if (this.path) {
res.path = this.path;
}
if (this.scheme) {
res.scheme = this.scheme;
}
if (this.authority) {
res.authority = this.authority;
}
if (this.query) {
res.query = this.query;
}
if (this.fragment) {
res.fragment = this.fragment;
}
return res;
}
}]);
return Uri;
}(URI); // reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2
var encodeTable = (_encodeTable = {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_encodeTable, _charCode.CharCode.Colon, '%3A'), _charCode.CharCode.Slash, '%2F'), _charCode.CharCode.QuestionMark, '%3F'), _charCode.CharCode.Hash, '%23'), _charCode.CharCode.OpenSquareBracket, '%5B'), _charCode.CharCode.CloseSquareBracket, '%5D'), _charCode.CharCode.AtSign, '%40'), _charCode.CharCode.ExclamationMark, '%21'), _charCode.CharCode.DollarSign, '%24'), _charCode.CharCode.Ampersand, '%26'), _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_encodeTable, _charCode.CharCode.SingleQuote, '%27'), _charCode.CharCode.OpenParen, '%28'), _charCode.CharCode.CloseParen, '%29'), _charCode.CharCode.Asterisk, '%2A'), _charCode.CharCode.Plus, '%2B'), _charCode.CharCode.Comma, '%2C'), _charCode.CharCode.Semicolon, '%3B'), _charCode.CharCode.Equals, '%3D'), _charCode.CharCode.Space, '%20'));
function encodeURIComponentFast(uriComponent, isPath, isAuthority) {
var res = undefined;
var nativeEncodePos = -1;
for (var pos = 0; pos < uriComponent.length; pos++) {
var code = uriComponent.charCodeAt(pos);
// unreserved characters: https://tools.ietf.org/html/rfc3986#section-2.3
if (code >= _charCode.CharCode.a && code <= _charCode.CharCode.z || code >= _charCode.CharCode.A && code <= _charCode.CharCode.Z || code >= _charCode.CharCode.Digit0 && code <= _charCode.CharCode.Digit9 || code === _charCode.CharCode.Dash || code === _charCode.CharCode.Period || code === _charCode.CharCode.Underline || code === _charCode.CharCode.Tilde || isPath && code === _charCode.CharCode.Slash || isAuthority && code === _charCode.CharCode.OpenSquareBracket || isAuthority && code === _charCode.CharCode.CloseSquareBracket || isAuthority && code === _charCode.CharCode.Colon) {
// check if we are delaying native encode
if (nativeEncodePos !== -1) {
res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));
nativeEncodePos = -1;
}
// check if we write into a new string (by default we try to return the param)
if (res !== undefined) {
res += uriComponent.charAt(pos);
}
} else {
// encoding needed, we need to allocate a new string
if (res === undefined) {
res = uriComponent.substr(0, pos);
}
// check with default table first
var escaped = encodeTable[code];
if (escaped !== undefined) {
// check if we are delaying native encode
if (nativeEncodePos !== -1) {
res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));
nativeEncodePos = -1;
}
// append escaped variant to result
res += escaped;
} else if (nativeEncodePos === -1) {
// use native encode only when needed
nativeEncodePos = pos;
}
}
}
if (nativeEncodePos !== -1) {
res += encodeURIComponent(uriComponent.substring(nativeEncodePos));
}
return res !== undefined ? res : uriComponent;
}
function encodeURIComponentMinimal(path) {
var res = undefined;
for (var pos = 0; pos < path.length; pos++) {
var code = path.charCodeAt(pos);
if (code === _charCode.CharCode.Hash || code === _charCode.CharCode.QuestionMark) {
if (res === undefined) {
res = path.substr(0, pos);
}
res += encodeTable[code];
} else {
if (res !== undefined) {
res += path[pos];
}
}
}
return res !== undefined ? res : path;
}
/**
* Compute `fsPath` for the given uri
*/
function uriToFsPath(uri, keepDriveLetterCasing) {
var value;
if (uri.authority && uri.path.length > 1 && uri.scheme === 'file') {
// unc path: file://shares/c$/far/boo
value = "//".concat(uri.authority).concat(uri.path);
} else if (uri.path.charCodeAt(0) === _charCode.CharCode.Slash && (uri.path.charCodeAt(1) >= _charCode.CharCode.A && uri.path.charCodeAt(1) <= _charCode.CharCode.Z || uri.path.charCodeAt(1) >= _charCode.CharCode.a && uri.path.charCodeAt(1) <= _charCode.CharCode.z) && uri.path.charCodeAt(2) === _charCode.CharCode.Colon) {
if (!keepDriveLetterCasing) {
// windows drive letter: file:///c:/far/boo
value = uri.path[1].toLowerCase() + uri.path.substr(2);
} else {
value = uri.path.substr(1);
}
} else {
// other path
value = uri.path;
}
if (_platform.isWindows) {
value = value.replace(/\//g, '\\');
}
return value;
}
/**
* Create the external version of a uri
*/
function _asFormatted(uri, skipEncoding) {
var encoder = !skipEncoding ? encodeURIComponentFast : encodeURIComponentMinimal;
var res = '';
var scheme = uri.scheme,
query = uri.query,
fragment = uri.fragment,
simpleMode = uri.simpleMode;
var authority = uri.authority,
path = uri.path;
if (scheme) {
res += scheme;
res += ':';
}
if (authority || scheme === 'file') {
res += _slash;
res += _slash;
}
if (authority) {
var idx = authority.indexOf('@');
if (idx !== -1) {
// <user>@<auth>
var userinfo = authority.substr(0, idx);
authority = authority.substr(idx + 1);
idx = userinfo.lastIndexOf(':');
if (idx === -1) {
res += simpleMode ? userinfo : encoder(userinfo, false, false);
} else {
// <user>:<pass>@<auth>
res += simpleMode ? userinfo.substr(0, idx) : encoder(userinfo.substr(0, idx), false, false);
res += ':';
res += simpleMode ? userinfo.substr(idx + 1) : encoder(userinfo.substr(idx + 1), false, true);
}
res += '@';
}
authority = authority.toLowerCase();
idx = authority.lastIndexOf(':');
if (idx === -1) {
res += simpleMode ? authority : encoder(authority, false, true);
} else {
// <auth>:<port>
res += simpleMode ? authority.substr(0, idx) : encoder(authority.substr(0, idx), false, true);
res += authority.substr(idx);
}
}
if (path) {
// lower-case windows drive letters in /C:/fff or C:/fff
if (path.length >= 3 && path.charCodeAt(0) === _charCode.CharCode.Slash && path.charCodeAt(2) === _charCode.CharCode.Colon) {
var code = path.charCodeAt(1);
if (code >= _charCode.CharCode.A && code <= _charCode.CharCode.Z) {
path = "/".concat(String.fromCharCode(code + 32), ":").concat(path.substr(3)); // "/c:".length === 3
}
} else if (path.length >= 2 && path.charCodeAt(1) === _charCode.CharCode.Colon) {
var _code = path.charCodeAt(0);
if (_code >= _charCode.CharCode.A && _code <= _charCode.CharCode.Z) {
path = "".concat(String.fromCharCode(_code + 32), ":").concat(path.substr(2)); // "/c:".length === 3
}
}
// encode the rest of the path
res += simpleMode ? path : encoder(path, true, false);
}
if (query) {
res += '?';
res += simpleMode ? query : encoder(query, false, false);
}
if (fragment) {
res += '#';
res += !skipEncoding || !simpleMode ? encodeURIComponentFast(fragment, false, false) : fragment;
}
return res;
}
// --- decode
function decodeURIComponentGraceful(str) {
try {
return decodeURIComponent(str);
} catch (_unused) {
if (str.length > 3) {
return str.substr(0, 3) + decodeURIComponentGraceful(str.substr(3));
} else {
return str;
}
}
}
var _rEncodedAsHex = /(%[0-9A-Za-z][0-9A-Za-z])+/g;
function percentDecode(str) {
if (!str.match(_rEncodedAsHex)) {
return str;
}
return str.replace(_rEncodedAsHex, function (match) {
return decodeURIComponentGraceful(match);
});
}
/**
* Mapped-type that replaces all occurrences of URI with UriComponents
*/