Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

web.url.js 32KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. 'use strict';
  2. // TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env`
  3. require('../modules/es.string.iterator');
  4. var $ = require('../internals/export');
  5. var DESCRIPTORS = require('../internals/descriptors');
  6. var USE_NATIVE_URL = require('../internals/native-url');
  7. var global = require('../internals/global');
  8. var defineProperties = require('../internals/object-define-properties');
  9. var redefine = require('../internals/redefine');
  10. var anInstance = require('../internals/an-instance');
  11. var has = require('../internals/has');
  12. var assign = require('../internals/object-assign');
  13. var arrayFrom = require('../internals/array-from');
  14. var codeAt = require('../internals/string-multibyte').codeAt;
  15. var toASCII = require('../internals/string-punycode-to-ascii');
  16. var setToStringTag = require('../internals/set-to-string-tag');
  17. var URLSearchParamsModule = require('../modules/web.url-search-params');
  18. var InternalStateModule = require('../internals/internal-state');
  19. var NativeURL = global.URL;
  20. var URLSearchParams = URLSearchParamsModule.URLSearchParams;
  21. var getInternalSearchParamsState = URLSearchParamsModule.getState;
  22. var setInternalState = InternalStateModule.set;
  23. var getInternalURLState = InternalStateModule.getterFor('URL');
  24. var floor = Math.floor;
  25. var pow = Math.pow;
  26. var INVALID_AUTHORITY = 'Invalid authority';
  27. var INVALID_SCHEME = 'Invalid scheme';
  28. var INVALID_HOST = 'Invalid host';
  29. var INVALID_PORT = 'Invalid port';
  30. var ALPHA = /[A-Za-z]/;
  31. // eslint-disable-next-line regexp/no-obscure-range -- safe
  32. var ALPHANUMERIC = /[\d+-.A-Za-z]/;
  33. var DIGIT = /\d/;
  34. var HEX_START = /^0x/i;
  35. var OCT = /^[0-7]+$/;
  36. var DEC = /^\d+$/;
  37. var HEX = /^[\dA-Fa-f]+$/;
  38. /* eslint-disable no-control-regex -- safe */
  39. var FORBIDDEN_HOST_CODE_POINT = /[\0\t\n\r #%/:<>?@[\\\]^|]/;
  40. var FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT = /[\0\t\n\r #/:<>?@[\\\]^|]/;
  41. var LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE = /^[\u0000-\u001F ]+|[\u0000-\u001F ]+$/g;
  42. var TAB_AND_NEW_LINE = /[\t\n\r]/g;
  43. /* eslint-enable no-control-regex -- safe */
  44. var EOF;
  45. var parseHost = function (url, input) {
  46. var result, codePoints, index;
  47. if (input.charAt(0) == '[') {
  48. if (input.charAt(input.length - 1) != ']') return INVALID_HOST;
  49. result = parseIPv6(input.slice(1, -1));
  50. if (!result) return INVALID_HOST;
  51. url.host = result;
  52. // opaque host
  53. } else if (!isSpecial(url)) {
  54. if (FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT.test(input)) return INVALID_HOST;
  55. result = '';
  56. codePoints = arrayFrom(input);
  57. for (index = 0; index < codePoints.length; index++) {
  58. result += percentEncode(codePoints[index], C0ControlPercentEncodeSet);
  59. }
  60. url.host = result;
  61. } else {
  62. input = toASCII(input);
  63. if (FORBIDDEN_HOST_CODE_POINT.test(input)) return INVALID_HOST;
  64. result = parseIPv4(input);
  65. if (result === null) return INVALID_HOST;
  66. url.host = result;
  67. }
  68. };
  69. var parseIPv4 = function (input) {
  70. var parts = input.split('.');
  71. var partsLength, numbers, index, part, radix, number, ipv4;
  72. if (parts.length && parts[parts.length - 1] == '') {
  73. parts.pop();
  74. }
  75. partsLength = parts.length;
  76. if (partsLength > 4) return input;
  77. numbers = [];
  78. for (index = 0; index < partsLength; index++) {
  79. part = parts[index];
  80. if (part == '') return input;
  81. radix = 10;
  82. if (part.length > 1 && part.charAt(0) == '0') {
  83. radix = HEX_START.test(part) ? 16 : 8;
  84. part = part.slice(radix == 8 ? 1 : 2);
  85. }
  86. if (part === '') {
  87. number = 0;
  88. } else {
  89. if (!(radix == 10 ? DEC : radix == 8 ? OCT : HEX).test(part)) return input;
  90. number = parseInt(part, radix);
  91. }
  92. numbers.push(number);
  93. }
  94. for (index = 0; index < partsLength; index++) {
  95. number = numbers[index];
  96. if (index == partsLength - 1) {
  97. if (number >= pow(256, 5 - partsLength)) return null;
  98. } else if (number > 255) return null;
  99. }
  100. ipv4 = numbers.pop();
  101. for (index = 0; index < numbers.length; index++) {
  102. ipv4 += numbers[index] * pow(256, 3 - index);
  103. }
  104. return ipv4;
  105. };
  106. // eslint-disable-next-line max-statements -- TODO
  107. var parseIPv6 = function (input) {
  108. var address = [0, 0, 0, 0, 0, 0, 0, 0];
  109. var pieceIndex = 0;
  110. var compress = null;
  111. var pointer = 0;
  112. var value, length, numbersSeen, ipv4Piece, number, swaps, swap;
  113. var char = function () {
  114. return input.charAt(pointer);
  115. };
  116. if (char() == ':') {
  117. if (input.charAt(1) != ':') return;
  118. pointer += 2;
  119. pieceIndex++;
  120. compress = pieceIndex;
  121. }
  122. while (char()) {
  123. if (pieceIndex == 8) return;
  124. if (char() == ':') {
  125. if (compress !== null) return;
  126. pointer++;
  127. pieceIndex++;
  128. compress = pieceIndex;
  129. continue;
  130. }
  131. value = length = 0;
  132. while (length < 4 && HEX.test(char())) {
  133. value = value * 16 + parseInt(char(), 16);
  134. pointer++;
  135. length++;
  136. }
  137. if (char() == '.') {
  138. if (length == 0) return;
  139. pointer -= length;
  140. if (pieceIndex > 6) return;
  141. numbersSeen = 0;
  142. while (char()) {
  143. ipv4Piece = null;
  144. if (numbersSeen > 0) {
  145. if (char() == '.' && numbersSeen < 4) pointer++;
  146. else return;
  147. }
  148. if (!DIGIT.test(char())) return;
  149. while (DIGIT.test(char())) {
  150. number = parseInt(char(), 10);
  151. if (ipv4Piece === null) ipv4Piece = number;
  152. else if (ipv4Piece == 0) return;
  153. else ipv4Piece = ipv4Piece * 10 + number;
  154. if (ipv4Piece > 255) return;
  155. pointer++;
  156. }
  157. address[pieceIndex] = address[pieceIndex] * 256 + ipv4Piece;
  158. numbersSeen++;
  159. if (numbersSeen == 2 || numbersSeen == 4) pieceIndex++;
  160. }
  161. if (numbersSeen != 4) return;
  162. break;
  163. } else if (char() == ':') {
  164. pointer++;
  165. if (!char()) return;
  166. } else if (char()) return;
  167. address[pieceIndex++] = value;
  168. }
  169. if (compress !== null) {
  170. swaps = pieceIndex - compress;
  171. pieceIndex = 7;
  172. while (pieceIndex != 0 && swaps > 0) {
  173. swap = address[pieceIndex];
  174. address[pieceIndex--] = address[compress + swaps - 1];
  175. address[compress + --swaps] = swap;
  176. }
  177. } else if (pieceIndex != 8) return;
  178. return address;
  179. };
  180. var findLongestZeroSequence = function (ipv6) {
  181. var maxIndex = null;
  182. var maxLength = 1;
  183. var currStart = null;
  184. var currLength = 0;
  185. var index = 0;
  186. for (; index < 8; index++) {
  187. if (ipv6[index] !== 0) {
  188. if (currLength > maxLength) {
  189. maxIndex = currStart;
  190. maxLength = currLength;
  191. }
  192. currStart = null;
  193. currLength = 0;
  194. } else {
  195. if (currStart === null) currStart = index;
  196. ++currLength;
  197. }
  198. }
  199. if (currLength > maxLength) {
  200. maxIndex = currStart;
  201. maxLength = currLength;
  202. }
  203. return maxIndex;
  204. };
  205. var serializeHost = function (host) {
  206. var result, index, compress, ignore0;
  207. // ipv4
  208. if (typeof host == 'number') {
  209. result = [];
  210. for (index = 0; index < 4; index++) {
  211. result.unshift(host % 256);
  212. host = floor(host / 256);
  213. } return result.join('.');
  214. // ipv6
  215. } else if (typeof host == 'object') {
  216. result = '';
  217. compress = findLongestZeroSequence(host);
  218. for (index = 0; index < 8; index++) {
  219. if (ignore0 && host[index] === 0) continue;
  220. if (ignore0) ignore0 = false;
  221. if (compress === index) {
  222. result += index ? ':' : '::';
  223. ignore0 = true;
  224. } else {
  225. result += host[index].toString(16);
  226. if (index < 7) result += ':';
  227. }
  228. }
  229. return '[' + result + ']';
  230. } return host;
  231. };
  232. var C0ControlPercentEncodeSet = {};
  233. var fragmentPercentEncodeSet = assign({}, C0ControlPercentEncodeSet, {
  234. ' ': 1, '"': 1, '<': 1, '>': 1, '`': 1
  235. });
  236. var pathPercentEncodeSet = assign({}, fragmentPercentEncodeSet, {
  237. '#': 1, '?': 1, '{': 1, '}': 1
  238. });
  239. var userinfoPercentEncodeSet = assign({}, pathPercentEncodeSet, {
  240. '/': 1, ':': 1, ';': 1, '=': 1, '@': 1, '[': 1, '\\': 1, ']': 1, '^': 1, '|': 1
  241. });
  242. var percentEncode = function (char, set) {
  243. var code = codeAt(char, 0);
  244. return code > 0x20 && code < 0x7F && !has(set, char) ? char : encodeURIComponent(char);
  245. };
  246. var specialSchemes = {
  247. ftp: 21,
  248. file: null,
  249. http: 80,
  250. https: 443,
  251. ws: 80,
  252. wss: 443
  253. };
  254. var isSpecial = function (url) {
  255. return has(specialSchemes, url.scheme);
  256. };
  257. var includesCredentials = function (url) {
  258. return url.username != '' || url.password != '';
  259. };
  260. var cannotHaveUsernamePasswordPort = function (url) {
  261. return !url.host || url.cannotBeABaseURL || url.scheme == 'file';
  262. };
  263. var isWindowsDriveLetter = function (string, normalized) {
  264. var second;
  265. return string.length == 2 && ALPHA.test(string.charAt(0))
  266. && ((second = string.charAt(1)) == ':' || (!normalized && second == '|'));
  267. };
  268. var startsWithWindowsDriveLetter = function (string) {
  269. var third;
  270. return string.length > 1 && isWindowsDriveLetter(string.slice(0, 2)) && (
  271. string.length == 2 ||
  272. ((third = string.charAt(2)) === '/' || third === '\\' || third === '?' || third === '#')
  273. );
  274. };
  275. var shortenURLsPath = function (url) {
  276. var path = url.path;
  277. var pathSize = path.length;
  278. if (pathSize && (url.scheme != 'file' || pathSize != 1 || !isWindowsDriveLetter(path[0], true))) {
  279. path.pop();
  280. }
  281. };
  282. var isSingleDot = function (segment) {
  283. return segment === '.' || segment.toLowerCase() === '%2e';
  284. };
  285. var isDoubleDot = function (segment) {
  286. segment = segment.toLowerCase();
  287. return segment === '..' || segment === '%2e.' || segment === '.%2e' || segment === '%2e%2e';
  288. };
  289. // States:
  290. var SCHEME_START = {};
  291. var SCHEME = {};
  292. var NO_SCHEME = {};
  293. var SPECIAL_RELATIVE_OR_AUTHORITY = {};
  294. var PATH_OR_AUTHORITY = {};
  295. var RELATIVE = {};
  296. var RELATIVE_SLASH = {};
  297. var SPECIAL_AUTHORITY_SLASHES = {};
  298. var SPECIAL_AUTHORITY_IGNORE_SLASHES = {};
  299. var AUTHORITY = {};
  300. var HOST = {};
  301. var HOSTNAME = {};
  302. var PORT = {};
  303. var FILE = {};
  304. var FILE_SLASH = {};
  305. var FILE_HOST = {};
  306. var PATH_START = {};
  307. var PATH = {};
  308. var CANNOT_BE_A_BASE_URL_PATH = {};
  309. var QUERY = {};
  310. var FRAGMENT = {};
  311. // eslint-disable-next-line max-statements -- TODO
  312. var parseURL = function (url, input, stateOverride, base) {
  313. var state = stateOverride || SCHEME_START;
  314. var pointer = 0;
  315. var buffer = '';
  316. var seenAt = false;
  317. var seenBracket = false;
  318. var seenPasswordToken = false;
  319. var codePoints, char, bufferCodePoints, failure;
  320. if (!stateOverride) {
  321. url.scheme = '';
  322. url.username = '';
  323. url.password = '';
  324. url.host = null;
  325. url.port = null;
  326. url.path = [];
  327. url.query = null;
  328. url.fragment = null;
  329. url.cannotBeABaseURL = false;
  330. input = input.replace(LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE, '');
  331. }
  332. input = input.replace(TAB_AND_NEW_LINE, '');
  333. codePoints = arrayFrom(input);
  334. while (pointer <= codePoints.length) {
  335. char = codePoints[pointer];
  336. switch (state) {
  337. case SCHEME_START:
  338. if (char && ALPHA.test(char)) {
  339. buffer += char.toLowerCase();
  340. state = SCHEME;
  341. } else if (!stateOverride) {
  342. state = NO_SCHEME;
  343. continue;
  344. } else return INVALID_SCHEME;
  345. break;
  346. case SCHEME:
  347. if (char && (ALPHANUMERIC.test(char) || char == '+' || char == '-' || char == '.')) {
  348. buffer += char.toLowerCase();
  349. } else if (char == ':') {
  350. if (stateOverride && (
  351. (isSpecial(url) != has(specialSchemes, buffer)) ||
  352. (buffer == 'file' && (includesCredentials(url) || url.port !== null)) ||
  353. (url.scheme == 'file' && !url.host)
  354. )) return;
  355. url.scheme = buffer;
  356. if (stateOverride) {
  357. if (isSpecial(url) && specialSchemes[url.scheme] == url.port) url.port = null;
  358. return;
  359. }
  360. buffer = '';
  361. if (url.scheme == 'file') {
  362. state = FILE;
  363. } else if (isSpecial(url) && base && base.scheme == url.scheme) {
  364. state = SPECIAL_RELATIVE_OR_AUTHORITY;
  365. } else if (isSpecial(url)) {
  366. state = SPECIAL_AUTHORITY_SLASHES;
  367. } else if (codePoints[pointer + 1] == '/') {
  368. state = PATH_OR_AUTHORITY;
  369. pointer++;
  370. } else {
  371. url.cannotBeABaseURL = true;
  372. url.path.push('');
  373. state = CANNOT_BE_A_BASE_URL_PATH;
  374. }
  375. } else if (!stateOverride) {
  376. buffer = '';
  377. state = NO_SCHEME;
  378. pointer = 0;
  379. continue;
  380. } else return INVALID_SCHEME;
  381. break;
  382. case NO_SCHEME:
  383. if (!base || (base.cannotBeABaseURL && char != '#')) return INVALID_SCHEME;
  384. if (base.cannotBeABaseURL && char == '#') {
  385. url.scheme = base.scheme;
  386. url.path = base.path.slice();
  387. url.query = base.query;
  388. url.fragment = '';
  389. url.cannotBeABaseURL = true;
  390. state = FRAGMENT;
  391. break;
  392. }
  393. state = base.scheme == 'file' ? FILE : RELATIVE;
  394. continue;
  395. case SPECIAL_RELATIVE_OR_AUTHORITY:
  396. if (char == '/' && codePoints[pointer + 1] == '/') {
  397. state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
  398. pointer++;
  399. } else {
  400. state = RELATIVE;
  401. continue;
  402. } break;
  403. case PATH_OR_AUTHORITY:
  404. if (char == '/') {
  405. state = AUTHORITY;
  406. break;
  407. } else {
  408. state = PATH;
  409. continue;
  410. }
  411. case RELATIVE:
  412. url.scheme = base.scheme;
  413. if (char == EOF) {
  414. url.username = base.username;
  415. url.password = base.password;
  416. url.host = base.host;
  417. url.port = base.port;
  418. url.path = base.path.slice();
  419. url.query = base.query;
  420. } else if (char == '/' || (char == '\\' && isSpecial(url))) {
  421. state = RELATIVE_SLASH;
  422. } else if (char == '?') {
  423. url.username = base.username;
  424. url.password = base.password;
  425. url.host = base.host;
  426. url.port = base.port;
  427. url.path = base.path.slice();
  428. url.query = '';
  429. state = QUERY;
  430. } else if (char == '#') {
  431. url.username = base.username;
  432. url.password = base.password;
  433. url.host = base.host;
  434. url.port = base.port;
  435. url.path = base.path.slice();
  436. url.query = base.query;
  437. url.fragment = '';
  438. state = FRAGMENT;
  439. } else {
  440. url.username = base.username;
  441. url.password = base.password;
  442. url.host = base.host;
  443. url.port = base.port;
  444. url.path = base.path.slice();
  445. url.path.pop();
  446. state = PATH;
  447. continue;
  448. } break;
  449. case RELATIVE_SLASH:
  450. if (isSpecial(url) && (char == '/' || char == '\\')) {
  451. state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
  452. } else if (char == '/') {
  453. state = AUTHORITY;
  454. } else {
  455. url.username = base.username;
  456. url.password = base.password;
  457. url.host = base.host;
  458. url.port = base.port;
  459. state = PATH;
  460. continue;
  461. } break;
  462. case SPECIAL_AUTHORITY_SLASHES:
  463. state = SPECIAL_AUTHORITY_IGNORE_SLASHES;
  464. if (char != '/' || buffer.charAt(pointer + 1) != '/') continue;
  465. pointer++;
  466. break;
  467. case SPECIAL_AUTHORITY_IGNORE_SLASHES:
  468. if (char != '/' && char != '\\') {
  469. state = AUTHORITY;
  470. continue;
  471. } break;
  472. case AUTHORITY:
  473. if (char == '@') {
  474. if (seenAt) buffer = '%40' + buffer;
  475. seenAt = true;
  476. bufferCodePoints = arrayFrom(buffer);
  477. for (var i = 0; i < bufferCodePoints.length; i++) {
  478. var codePoint = bufferCodePoints[i];
  479. if (codePoint == ':' && !seenPasswordToken) {
  480. seenPasswordToken = true;
  481. continue;
  482. }
  483. var encodedCodePoints = percentEncode(codePoint, userinfoPercentEncodeSet);
  484. if (seenPasswordToken) url.password += encodedCodePoints;
  485. else url.username += encodedCodePoints;
  486. }
  487. buffer = '';
  488. } else if (
  489. char == EOF || char == '/' || char == '?' || char == '#' ||
  490. (char == '\\' && isSpecial(url))
  491. ) {
  492. if (seenAt && buffer == '') return INVALID_AUTHORITY;
  493. pointer -= arrayFrom(buffer).length + 1;
  494. buffer = '';
  495. state = HOST;
  496. } else buffer += char;
  497. break;
  498. case HOST:
  499. case HOSTNAME:
  500. if (stateOverride && url.scheme == 'file') {
  501. state = FILE_HOST;
  502. continue;
  503. } else if (char == ':' && !seenBracket) {
  504. if (buffer == '') return INVALID_HOST;
  505. failure = parseHost(url, buffer);
  506. if (failure) return failure;
  507. buffer = '';
  508. state = PORT;
  509. if (stateOverride == HOSTNAME) return;
  510. } else if (
  511. char == EOF || char == '/' || char == '?' || char == '#' ||
  512. (char == '\\' && isSpecial(url))
  513. ) {
  514. if (isSpecial(url) && buffer == '') return INVALID_HOST;
  515. if (stateOverride && buffer == '' && (includesCredentials(url) || url.port !== null)) return;
  516. failure = parseHost(url, buffer);
  517. if (failure) return failure;
  518. buffer = '';
  519. state = PATH_START;
  520. if (stateOverride) return;
  521. continue;
  522. } else {
  523. if (char == '[') seenBracket = true;
  524. else if (char == ']') seenBracket = false;
  525. buffer += char;
  526. } break;
  527. case PORT:
  528. if (DIGIT.test(char)) {
  529. buffer += char;
  530. } else if (
  531. char == EOF || char == '/' || char == '?' || char == '#' ||
  532. (char == '\\' && isSpecial(url)) ||
  533. stateOverride
  534. ) {
  535. if (buffer != '') {
  536. var port = parseInt(buffer, 10);
  537. if (port > 0xFFFF) return INVALID_PORT;
  538. url.port = (isSpecial(url) && port === specialSchemes[url.scheme]) ? null : port;
  539. buffer = '';
  540. }
  541. if (stateOverride) return;
  542. state = PATH_START;
  543. continue;
  544. } else return INVALID_PORT;
  545. break;
  546. case FILE:
  547. url.scheme = 'file';
  548. if (char == '/' || char == '\\') state = FILE_SLASH;
  549. else if (base && base.scheme == 'file') {
  550. if (char == EOF) {
  551. url.host = base.host;
  552. url.path = base.path.slice();
  553. url.query = base.query;
  554. } else if (char == '?') {
  555. url.host = base.host;
  556. url.path = base.path.slice();
  557. url.query = '';
  558. state = QUERY;
  559. } else if (char == '#') {
  560. url.host = base.host;
  561. url.path = base.path.slice();
  562. url.query = base.query;
  563. url.fragment = '';
  564. state = FRAGMENT;
  565. } else {
  566. if (!startsWithWindowsDriveLetter(codePoints.slice(pointer).join(''))) {
  567. url.host = base.host;
  568. url.path = base.path.slice();
  569. shortenURLsPath(url);
  570. }
  571. state = PATH;
  572. continue;
  573. }
  574. } else {
  575. state = PATH;
  576. continue;
  577. } break;
  578. case FILE_SLASH:
  579. if (char == '/' || char == '\\') {
  580. state = FILE_HOST;
  581. break;
  582. }
  583. if (base && base.scheme == 'file' && !startsWithWindowsDriveLetter(codePoints.slice(pointer).join(''))) {
  584. if (isWindowsDriveLetter(base.path[0], true)) url.path.push(base.path[0]);
  585. else url.host = base.host;
  586. }
  587. state = PATH;
  588. continue;
  589. case FILE_HOST:
  590. if (char == EOF || char == '/' || char == '\\' || char == '?' || char == '#') {
  591. if (!stateOverride && isWindowsDriveLetter(buffer)) {
  592. state = PATH;
  593. } else if (buffer == '') {
  594. url.host = '';
  595. if (stateOverride) return;
  596. state = PATH_START;
  597. } else {
  598. failure = parseHost(url, buffer);
  599. if (failure) return failure;
  600. if (url.host == 'localhost') url.host = '';
  601. if (stateOverride) return;
  602. buffer = '';
  603. state = PATH_START;
  604. } continue;
  605. } else buffer += char;
  606. break;
  607. case PATH_START:
  608. if (isSpecial(url)) {
  609. state = PATH;
  610. if (char != '/' && char != '\\') continue;
  611. } else if (!stateOverride && char == '?') {
  612. url.query = '';
  613. state = QUERY;
  614. } else if (!stateOverride && char == '#') {
  615. url.fragment = '';
  616. state = FRAGMENT;
  617. } else if (char != EOF) {
  618. state = PATH;
  619. if (char != '/') continue;
  620. } break;
  621. case PATH:
  622. if (
  623. char == EOF || char == '/' ||
  624. (char == '\\' && isSpecial(url)) ||
  625. (!stateOverride && (char == '?' || char == '#'))
  626. ) {
  627. if (isDoubleDot(buffer)) {
  628. shortenURLsPath(url);
  629. if (char != '/' && !(char == '\\' && isSpecial(url))) {
  630. url.path.push('');
  631. }
  632. } else if (isSingleDot(buffer)) {
  633. if (char != '/' && !(char == '\\' && isSpecial(url))) {
  634. url.path.push('');
  635. }
  636. } else {
  637. if (url.scheme == 'file' && !url.path.length && isWindowsDriveLetter(buffer)) {
  638. if (url.host) url.host = '';
  639. buffer = buffer.charAt(0) + ':'; // normalize windows drive letter
  640. }
  641. url.path.push(buffer);
  642. }
  643. buffer = '';
  644. if (url.scheme == 'file' && (char == EOF || char == '?' || char == '#')) {
  645. while (url.path.length > 1 && url.path[0] === '') {
  646. url.path.shift();
  647. }
  648. }
  649. if (char == '?') {
  650. url.query = '';
  651. state = QUERY;
  652. } else if (char == '#') {
  653. url.fragment = '';
  654. state = FRAGMENT;
  655. }
  656. } else {
  657. buffer += percentEncode(char, pathPercentEncodeSet);
  658. } break;
  659. case CANNOT_BE_A_BASE_URL_PATH:
  660. if (char == '?') {
  661. url.query = '';
  662. state = QUERY;
  663. } else if (char == '#') {
  664. url.fragment = '';
  665. state = FRAGMENT;
  666. } else if (char != EOF) {
  667. url.path[0] += percentEncode(char, C0ControlPercentEncodeSet);
  668. } break;
  669. case QUERY:
  670. if (!stateOverride && char == '#') {
  671. url.fragment = '';
  672. state = FRAGMENT;
  673. } else if (char != EOF) {
  674. if (char == "'" && isSpecial(url)) url.query += '%27';
  675. else if (char == '#') url.query += '%23';
  676. else url.query += percentEncode(char, C0ControlPercentEncodeSet);
  677. } break;
  678. case FRAGMENT:
  679. if (char != EOF) url.fragment += percentEncode(char, fragmentPercentEncodeSet);
  680. break;
  681. }
  682. pointer++;
  683. }
  684. };
  685. // `URL` constructor
  686. // https://url.spec.whatwg.org/#url-class
  687. var URLConstructor = function URL(url /* , base */) {
  688. var that = anInstance(this, URLConstructor, 'URL');
  689. var base = arguments.length > 1 ? arguments[1] : undefined;
  690. var urlString = String(url);
  691. var state = setInternalState(that, { type: 'URL' });
  692. var baseState, failure;
  693. if (base !== undefined) {
  694. if (base instanceof URLConstructor) baseState = getInternalURLState(base);
  695. else {
  696. failure = parseURL(baseState = {}, String(base));
  697. if (failure) throw TypeError(failure);
  698. }
  699. }
  700. failure = parseURL(state, urlString, null, baseState);
  701. if (failure) throw TypeError(failure);
  702. var searchParams = state.searchParams = new URLSearchParams();
  703. var searchParamsState = getInternalSearchParamsState(searchParams);
  704. searchParamsState.updateSearchParams(state.query);
  705. searchParamsState.updateURL = function () {
  706. state.query = String(searchParams) || null;
  707. };
  708. if (!DESCRIPTORS) {
  709. that.href = serializeURL.call(that);
  710. that.origin = getOrigin.call(that);
  711. that.protocol = getProtocol.call(that);
  712. that.username = getUsername.call(that);
  713. that.password = getPassword.call(that);
  714. that.host = getHost.call(that);
  715. that.hostname = getHostname.call(that);
  716. that.port = getPort.call(that);
  717. that.pathname = getPathname.call(that);
  718. that.search = getSearch.call(that);
  719. that.searchParams = getSearchParams.call(that);
  720. that.hash = getHash.call(that);
  721. }
  722. };
  723. var URLPrototype = URLConstructor.prototype;
  724. var serializeURL = function () {
  725. var url = getInternalURLState(this);
  726. var scheme = url.scheme;
  727. var username = url.username;
  728. var password = url.password;
  729. var host = url.host;
  730. var port = url.port;
  731. var path = url.path;
  732. var query = url.query;
  733. var fragment = url.fragment;
  734. var output = scheme + ':';
  735. if (host !== null) {
  736. output += '//';
  737. if (includesCredentials(url)) {
  738. output += username + (password ? ':' + password : '') + '@';
  739. }
  740. output += serializeHost(host);
  741. if (port !== null) output += ':' + port;
  742. } else if (scheme == 'file') output += '//';
  743. output += url.cannotBeABaseURL ? path[0] : path.length ? '/' + path.join('/') : '';
  744. if (query !== null) output += '?' + query;
  745. if (fragment !== null) output += '#' + fragment;
  746. return output;
  747. };
  748. var getOrigin = function () {
  749. var url = getInternalURLState(this);
  750. var scheme = url.scheme;
  751. var port = url.port;
  752. if (scheme == 'blob') try {
  753. return new URLConstructor(scheme.path[0]).origin;
  754. } catch (error) {
  755. return 'null';
  756. }
  757. if (scheme == 'file' || !isSpecial(url)) return 'null';
  758. return scheme + '://' + serializeHost(url.host) + (port !== null ? ':' + port : '');
  759. };
  760. var getProtocol = function () {
  761. return getInternalURLState(this).scheme + ':';
  762. };
  763. var getUsername = function () {
  764. return getInternalURLState(this).username;
  765. };
  766. var getPassword = function () {
  767. return getInternalURLState(this).password;
  768. };
  769. var getHost = function () {
  770. var url = getInternalURLState(this);
  771. var host = url.host;
  772. var port = url.port;
  773. return host === null ? ''
  774. : port === null ? serializeHost(host)
  775. : serializeHost(host) + ':' + port;
  776. };
  777. var getHostname = function () {
  778. var host = getInternalURLState(this).host;
  779. return host === null ? '' : serializeHost(host);
  780. };
  781. var getPort = function () {
  782. var port = getInternalURLState(this).port;
  783. return port === null ? '' : String(port);
  784. };
  785. var getPathname = function () {
  786. var url = getInternalURLState(this);
  787. var path = url.path;
  788. return url.cannotBeABaseURL ? path[0] : path.length ? '/' + path.join('/') : '';
  789. };
  790. var getSearch = function () {
  791. var query = getInternalURLState(this).query;
  792. return query ? '?' + query : '';
  793. };
  794. var getSearchParams = function () {
  795. return getInternalURLState(this).searchParams;
  796. };
  797. var getHash = function () {
  798. var fragment = getInternalURLState(this).fragment;
  799. return fragment ? '#' + fragment : '';
  800. };
  801. var accessorDescriptor = function (getter, setter) {
  802. return { get: getter, set: setter, configurable: true, enumerable: true };
  803. };
  804. if (DESCRIPTORS) {
  805. defineProperties(URLPrototype, {
  806. // `URL.prototype.href` accessors pair
  807. // https://url.spec.whatwg.org/#dom-url-href
  808. href: accessorDescriptor(serializeURL, function (href) {
  809. var url = getInternalURLState(this);
  810. var urlString = String(href);
  811. var failure = parseURL(url, urlString);
  812. if (failure) throw TypeError(failure);
  813. getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query);
  814. }),
  815. // `URL.prototype.origin` getter
  816. // https://url.spec.whatwg.org/#dom-url-origin
  817. origin: accessorDescriptor(getOrigin),
  818. // `URL.prototype.protocol` accessors pair
  819. // https://url.spec.whatwg.org/#dom-url-protocol
  820. protocol: accessorDescriptor(getProtocol, function (protocol) {
  821. var url = getInternalURLState(this);
  822. parseURL(url, String(protocol) + ':', SCHEME_START);
  823. }),
  824. // `URL.prototype.username` accessors pair
  825. // https://url.spec.whatwg.org/#dom-url-username
  826. username: accessorDescriptor(getUsername, function (username) {
  827. var url = getInternalURLState(this);
  828. var codePoints = arrayFrom(String(username));
  829. if (cannotHaveUsernamePasswordPort(url)) return;
  830. url.username = '';
  831. for (var i = 0; i < codePoints.length; i++) {
  832. url.username += percentEncode(codePoints[i], userinfoPercentEncodeSet);
  833. }
  834. }),
  835. // `URL.prototype.password` accessors pair
  836. // https://url.spec.whatwg.org/#dom-url-password
  837. password: accessorDescriptor(getPassword, function (password) {
  838. var url = getInternalURLState(this);
  839. var codePoints = arrayFrom(String(password));
  840. if (cannotHaveUsernamePasswordPort(url)) return;
  841. url.password = '';
  842. for (var i = 0; i < codePoints.length; i++) {
  843. url.password += percentEncode(codePoints[i], userinfoPercentEncodeSet);
  844. }
  845. }),
  846. // `URL.prototype.host` accessors pair
  847. // https://url.spec.whatwg.org/#dom-url-host
  848. host: accessorDescriptor(getHost, function (host) {
  849. var url = getInternalURLState(this);
  850. if (url.cannotBeABaseURL) return;
  851. parseURL(url, String(host), HOST);
  852. }),
  853. // `URL.prototype.hostname` accessors pair
  854. // https://url.spec.whatwg.org/#dom-url-hostname
  855. hostname: accessorDescriptor(getHostname, function (hostname) {
  856. var url = getInternalURLState(this);
  857. if (url.cannotBeABaseURL) return;
  858. parseURL(url, String(hostname), HOSTNAME);
  859. }),
  860. // `URL.prototype.port` accessors pair
  861. // https://url.spec.whatwg.org/#dom-url-port
  862. port: accessorDescriptor(getPort, function (port) {
  863. var url = getInternalURLState(this);
  864. if (cannotHaveUsernamePasswordPort(url)) return;
  865. port = String(port);
  866. if (port == '') url.port = null;
  867. else parseURL(url, port, PORT);
  868. }),
  869. // `URL.prototype.pathname` accessors pair
  870. // https://url.spec.whatwg.org/#dom-url-pathname
  871. pathname: accessorDescriptor(getPathname, function (pathname) {
  872. var url = getInternalURLState(this);
  873. if (url.cannotBeABaseURL) return;
  874. url.path = [];
  875. parseURL(url, pathname + '', PATH_START);
  876. }),
  877. // `URL.prototype.search` accessors pair
  878. // https://url.spec.whatwg.org/#dom-url-search
  879. search: accessorDescriptor(getSearch, function (search) {
  880. var url = getInternalURLState(this);
  881. search = String(search);
  882. if (search == '') {
  883. url.query = null;
  884. } else {
  885. if ('?' == search.charAt(0)) search = search.slice(1);
  886. url.query = '';
  887. parseURL(url, search, QUERY);
  888. }
  889. getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query);
  890. }),
  891. // `URL.prototype.searchParams` getter
  892. // https://url.spec.whatwg.org/#dom-url-searchparams
  893. searchParams: accessorDescriptor(getSearchParams),
  894. // `URL.prototype.hash` accessors pair
  895. // https://url.spec.whatwg.org/#dom-url-hash
  896. hash: accessorDescriptor(getHash, function (hash) {
  897. var url = getInternalURLState(this);
  898. hash = String(hash);
  899. if (hash == '') {
  900. url.fragment = null;
  901. return;
  902. }
  903. if ('#' == hash.charAt(0)) hash = hash.slice(1);
  904. url.fragment = '';
  905. parseURL(url, hash, FRAGMENT);
  906. })
  907. });
  908. }
  909. // `URL.prototype.toJSON` method
  910. // https://url.spec.whatwg.org/#dom-url-tojson
  911. redefine(URLPrototype, 'toJSON', function toJSON() {
  912. return serializeURL.call(this);
  913. }, { enumerable: true });
  914. // `URL.prototype.toString` method
  915. // https://url.spec.whatwg.org/#URL-stringification-behavior
  916. redefine(URLPrototype, 'toString', function toString() {
  917. return serializeURL.call(this);
  918. }, { enumerable: true });
  919. if (NativeURL) {
  920. var nativeCreateObjectURL = NativeURL.createObjectURL;
  921. var nativeRevokeObjectURL = NativeURL.revokeObjectURL;
  922. // `URL.createObjectURL` method
  923. // https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
  924. // eslint-disable-next-line no-unused-vars -- required for `.length`
  925. if (nativeCreateObjectURL) redefine(URLConstructor, 'createObjectURL', function createObjectURL(blob) {
  926. return nativeCreateObjectURL.apply(NativeURL, arguments);
  927. });
  928. // `URL.revokeObjectURL` method
  929. // https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL
  930. // eslint-disable-next-line no-unused-vars -- required for `.length`
  931. if (nativeRevokeObjectURL) redefine(URLConstructor, 'revokeObjectURL', function revokeObjectURL(url) {
  932. return nativeRevokeObjectURL.apply(NativeURL, arguments);
  933. });
  934. }
  935. setToStringTag(URLConstructor, 'URL');
  936. $({ global: true, forced: !USE_NATIVE_URL, sham: !DESCRIPTORS }, {
  937. URL: URLConstructor
  938. });