fetch-readablestream

https://github.com/jonnyreeves/fetch-readablestream/blob/master/README.md

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/29306/191832/fetch-readablestream.js

  1. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.fetchStream = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  2. 'use strict';
  3.  
  4. Object.defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.default = defaultTransportFactory;
  8.  
  9. var _fetch = require('./fetch');
  10.  
  11. var _fetch2 = _interopRequireDefault(_fetch);
  12.  
  13. var _xhr = require('./xhr');
  14.  
  15. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  16.  
  17. // selected is used to cache the detected transport.
  18. var selected = null;
  19.  
  20. // defaultTransportFactory selects the most appropriate transport based on the
  21. // capabilities of the current environment.
  22. function defaultTransportFactory() {
  23. if (!selected) {
  24. selected = detectTransport();
  25. }
  26. return selected;
  27. }
  28.  
  29. function detectTransport() {
  30. if (typeof Response !== 'undefined' && Response.prototype.hasOwnProperty("body")) {
  31. // fetch with ReadableStream support.
  32. return _fetch2.default;
  33. }
  34.  
  35. var mozChunked = 'moz-chunked-arraybuffer';
  36. if (supportsXhrResponseType(mozChunked)) {
  37. // Firefox, ArrayBuffer support.
  38. return (0, _xhr.makeXhrTransport)({
  39. responseType: mozChunked,
  40. responseParserFactory: function responseParserFactory() {
  41. return function (response) {
  42. return new Uint8Array(response);
  43. };
  44. }
  45. });
  46. }
  47.  
  48. // Bog-standard, expensive, text concatenation with byte encoding :(
  49. return (0, _xhr.makeXhrTransport)({
  50. responseType: 'text',
  51. responseParserFactory: function responseParserFactory() {
  52. var encoder = new TextEncoder();
  53. var offset = 0;
  54. return function (response) {
  55. var chunk = response.substr(offset);
  56. offset = response.length;
  57. return encoder.encode(chunk, { stream: true });
  58. };
  59. }
  60. });
  61. }
  62.  
  63. function supportsXhrResponseType(type) {
  64. try {
  65. var tmpXhr = new XMLHttpRequest();
  66. tmpXhr.responseType = type;
  67. return tmpXhr.responseType === type;
  68. } catch (e) {/* IE throws on setting responseType to an unsupported value */}
  69. return false;
  70. }
  71. },{"./fetch":3,"./xhr":6}],2:[function(require,module,exports){
  72. module.exports = require("./index").default;
  73.  
  74. },{"./index":4}],3:[function(require,module,exports){
  75. "use strict";
  76.  
  77. Object.defineProperty(exports, "__esModule", {
  78. value: true
  79. });
  80. exports.default = fetchRequest;
  81. // thin wrapper around `fetch()` to ensure we only expose the properties provided by
  82. // the XHR polyfil; / fetch-readablestream Response API.
  83. function fetchRequest(url, options) {
  84. return fetch(url, options).then(function (r) {
  85. return {
  86. body: r.body,
  87. headers: r.headers,
  88. ok: r.ok,
  89. status: r.status,
  90. statusText: r.statusText,
  91. url: r.url
  92. };
  93. });
  94. }
  95. },{}],4:[function(require,module,exports){
  96. 'use strict';
  97.  
  98. Object.defineProperty(exports, "__esModule", {
  99. value: true
  100. });
  101. exports.default = fetchStream;
  102.  
  103. var _defaultTransportFactory = require('./defaultTransportFactory');
  104.  
  105. var _defaultTransportFactory2 = _interopRequireDefault(_defaultTransportFactory);
  106.  
  107. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  108.  
  109. function fetchStream(url) {
  110. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  111.  
  112. var transport = options.transport;
  113. if (!transport) {
  114. transport = fetchStream.transportFactory();
  115. }
  116.  
  117. return transport(url, options);
  118. }
  119.  
  120. // override this function to delegate to an alternative transport function selection
  121. // strategy; useful when testing.
  122. fetchStream.transportFactory = _defaultTransportFactory2.default;
  123. },{"./defaultTransportFactory":1}],5:[function(require,module,exports){
  124. "use strict";
  125.  
  126. Object.defineProperty(exports, "__esModule", {
  127. value: true
  128. });
  129.  
  130. var _createClass = 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, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  131.  
  132. function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  133.  
  134. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  135.  
  136. // Headers is a partial polyfill for the HTML5 Headers class.
  137. var Headers = exports.Headers = function () {
  138. function Headers() {
  139. var _this = this;
  140.  
  141. var h = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  142.  
  143. _classCallCheck(this, Headers);
  144.  
  145. this.h = {};
  146. if (h instanceof Headers) {
  147. h.forEach(function (value, key) {
  148. return _this.append(key, value);
  149. });
  150. }
  151. Object.getOwnPropertyNames(h).forEach(function (key) {
  152. return _this.append(key, h[key]);
  153. });
  154. }
  155.  
  156. _createClass(Headers, [{
  157. key: "append",
  158. value: function append(key, value) {
  159. key = key.toLowerCase();
  160. if (!Array.isArray(this.h[key])) {
  161. this.h[key] = [];
  162. }
  163. this.h[key].push(value);
  164. }
  165. }, {
  166. key: "set",
  167. value: function set(key, value) {
  168. this.h[key.toLowerCase()] = [value];
  169. }
  170. }, {
  171. key: "has",
  172. value: function has(key) {
  173. return Array.isArray(this.h[key.toLowerCase()]);
  174. }
  175. }, {
  176. key: "get",
  177. value: function get(key) {
  178. key = key.toLowerCase();
  179. if (Array.isArray(this.h[key])) {
  180. return this.h[key][0];
  181. }
  182. }
  183. }, {
  184. key: "getAll",
  185. value: function getAll(key) {
  186. return this.h[key.toLowerCase()].concat();
  187. }
  188. }, {
  189. key: "entries",
  190. value: function entries() {
  191. var items = [];
  192. this.forEach(function (value, key) {
  193. items.push([key, value]);
  194. });
  195. return makeIterator(items);
  196. }
  197.  
  198. // forEach is not part of the official spec.
  199.  
  200. }, {
  201. key: "forEach",
  202. value: function forEach(callback, thisArg) {
  203. var _this2 = this;
  204.  
  205. Object.getOwnPropertyNames(this.h).forEach(function (key) {
  206. _this2.h[key].forEach(function (value) {
  207. return callback.call(thisArg, value, key, _this2);
  208. });
  209. }, this);
  210. }
  211. }]);
  212.  
  213. return Headers;
  214. }();
  215.  
  216. function makeIterator(items) {
  217. return _defineProperty({
  218. next: function next() {
  219. var value = items.shift();
  220. return {
  221. done: value === undefined,
  222. value: value
  223. };
  224. }
  225. }, Symbol.iterator, function () {
  226. return this;
  227. });
  228. }
  229. },{}],6:[function(require,module,exports){
  230. 'use strict';
  231.  
  232. Object.defineProperty(exports, "__esModule", {
  233. value: true
  234. });
  235. exports.makeXhrTransport = makeXhrTransport;
  236. exports.parseResposneHeaders = parseResposneHeaders;
  237.  
  238. var _Headers = require('./polyfill/Headers');
  239.  
  240. var _original = require('original');
  241.  
  242. var _original2 = _interopRequireDefault(_original);
  243.  
  244. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  245.  
  246. function makeXhrTransport(_ref) {
  247. var responseType = _ref.responseType,
  248. responseParserFactory = _ref.responseParserFactory;
  249.  
  250. return function xhrTransport(url, options) {
  251. var xhr = new XMLHttpRequest();
  252. var responseParser = responseParserFactory();
  253.  
  254. var responseStreamController = void 0;
  255. var cancelled = false;
  256.  
  257. var responseStream = new ReadableStream({
  258. start: function start(c) {
  259. responseStreamController = c;
  260. },
  261. cancel: function cancel() {
  262. cancelled = true;
  263. xhr.abort();
  264. }
  265. });
  266.  
  267. var _options$method = options.method,
  268. method = _options$method === undefined ? 'GET' : _options$method;
  269.  
  270.  
  271. xhr.open(method, url);
  272. xhr.responseType = responseType;
  273. xhr.withCredentials = options.credentials === 'include' || options.credentials === 'same-origin' && _original2.default.same(url, location.origin);
  274. if (options.headers) {
  275. var _iteratorNormalCompletion = true;
  276. var _didIteratorError = false;
  277. var _iteratorError = undefined;
  278.  
  279. try {
  280. for (var _iterator = options.headers.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
  281. var pair = _step.value;
  282.  
  283. xhr.setRequestHeader(pair[0], pair[1]);
  284. }
  285. } catch (err) {
  286. _didIteratorError = true;
  287. _iteratorError = err;
  288. } finally {
  289. try {
  290. if (!_iteratorNormalCompletion && _iterator.return) {
  291. _iterator.return();
  292. }
  293. } finally {
  294. if (_didIteratorError) {
  295. throw _iteratorError;
  296. }
  297. }
  298. }
  299. }
  300.  
  301. return new Promise(function (resolve, reject) {
  302. if (options.body && (method === 'GET' || method === 'HEAD')) {
  303. reject(new TypeError("Failed to execute 'fetchStream' on 'Window': Request with GET/HEAD method cannot have body"));
  304. }
  305.  
  306. xhr.onreadystatechange = function () {
  307. if (xhr.readyState === xhr.HEADERS_RECEIVED) {
  308. return resolve({
  309. body: responseStream,
  310. headers: parseResposneHeaders(xhr.getAllResponseHeaders()),
  311. ok: xhr.status >= 200 && xhr.status < 300,
  312. status: xhr.status,
  313. statusText: xhr.statusText,
  314. url: makeResponseUrl(xhr.responseURL, url)
  315. });
  316. }
  317. };
  318.  
  319. xhr.onerror = function () {
  320. return reject(new TypeError('Network request failed'));
  321. };
  322.  
  323. xhr.ontimeout = function () {
  324. reject(new TypeError('Network request failed'));
  325. };
  326.  
  327. xhr.onprogress = function () {
  328. if (!cancelled) {
  329. var bytes = responseParser(xhr.response);
  330. responseStreamController.enqueue(bytes);
  331. }
  332. };
  333.  
  334. xhr.onload = function () {
  335. responseStreamController.close();
  336. };
  337.  
  338. xhr.send(options.body);
  339. });
  340. };
  341. }
  342.  
  343. function makeHeaders() {
  344. // Prefer the native method if provided by the browser.
  345. if (typeof Headers !== 'undefined') {
  346. return new Headers();
  347. }
  348. return new _Headers.Headers();
  349. }
  350.  
  351. function makeResponseUrl(responseUrl, requestUrl) {
  352. if (!responseUrl) {
  353. // best guess; note this will not correctly handle redirects.
  354. if (requestUrl.substring(0, 4) !== "http") {
  355. return location.origin + requestUrl;
  356. }
  357. return requestUrl;
  358. }
  359. return responseUrl;
  360. }
  361.  
  362. function parseResposneHeaders(str) {
  363. var hdrs = makeHeaders();
  364. if (str) {
  365. var pairs = str.split('\r\n');
  366. for (var i = 0; i < pairs.length; i++) {
  367. var p = pairs[i];
  368. var index = p.indexOf(': ');
  369. if (index > 0) {
  370. var key = p.substring(0, index);
  371. var value = p.substring(index + 2);
  372. hdrs.append(key, value);
  373. }
  374. }
  375. }
  376. return hdrs;
  377. }
  378. },{"./polyfill/Headers":5,"original":7}],7:[function(require,module,exports){
  379. 'use strict';
  380.  
  381. var parse = require('url-parse');
  382.  
  383. /**
  384. * Transform an URL to a valid origin value.
  385. *
  386. * @param {String|Object} url URL to transform to it's origin.
  387. * @returns {String} The origin.
  388. * @api public
  389. */
  390. function origin(url) {
  391. if ('string' === typeof url) url = parse(url);
  392.  
  393. //
  394. // 6.2. ASCII Serialization of an Origin
  395. // http://tools.ietf.org/html/rfc6454#section-6.2
  396. //
  397. if (!url.protocol || !url.hostname) return 'null';
  398.  
  399. //
  400. // 4. Origin of a URI
  401. // http://tools.ietf.org/html/rfc6454#section-4
  402. //
  403. // States that url.scheme, host should be converted to lower case. This also
  404. // makes it easier to match origins as everything is just lower case.
  405. //
  406. return (url.protocol +'//'+ url.host).toLowerCase();
  407. }
  408.  
  409. /**
  410. * Check if the origins are the same.
  411. *
  412. * @param {String} a URL or origin of a.
  413. * @param {String} b URL or origin of b.
  414. * @returns {Boolean}
  415. * @api public
  416. */
  417. origin.same = function same(a, b) {
  418. return origin(a) === origin(b);
  419. };
  420.  
  421. //
  422. // Expose the origin
  423. //
  424. module.exports = origin;
  425.  
  426. },{"url-parse":10}],8:[function(require,module,exports){
  427. 'use strict';
  428.  
  429. var has = Object.prototype.hasOwnProperty;
  430.  
  431. /**
  432. * Simple query string parser.
  433. *
  434. * @param {String} query The query string that needs to be parsed.
  435. * @returns {Object}
  436. * @api public
  437. */
  438. function querystring(query) {
  439. var parser = /([^=?&]+)=?([^&]*)/g
  440. , result = {}
  441. , part;
  442.  
  443. //
  444. // Little nifty parsing hack, leverage the fact that RegExp.exec increments
  445. // the lastIndex property so we can continue executing this loop until we've
  446. // parsed all results.
  447. //
  448. for (;
  449. part = parser.exec(query);
  450. result[decodeURIComponent(part[1])] = decodeURIComponent(part[2])
  451. );
  452.  
  453. return result;
  454. }
  455.  
  456. /**
  457. * Transform a query string to an object.
  458. *
  459. * @param {Object} obj Object that should be transformed.
  460. * @param {String} prefix Optional prefix.
  461. * @returns {String}
  462. * @api public
  463. */
  464. function querystringify(obj, prefix) {
  465. prefix = prefix || '';
  466.  
  467. var pairs = [];
  468.  
  469. //
  470. // Optionally prefix with a '?' if needed
  471. //
  472. if ('string' !== typeof prefix) prefix = '?';
  473.  
  474. for (var key in obj) {
  475. if (has.call(obj, key)) {
  476. pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(obj[key]));
  477. }
  478. }
  479.  
  480. return pairs.length ? prefix + pairs.join('&') : '';
  481. }
  482.  
  483. //
  484. // Expose the module.
  485. //
  486. exports.stringify = querystringify;
  487. exports.parse = querystring;
  488.  
  489. },{}],9:[function(require,module,exports){
  490. 'use strict';
  491.  
  492. /**
  493. * Check if we're required to add a port number.
  494. *
  495. * @see https://url.spec.whatwg.org/#default-port
  496. * @param {Number|String} port Port number we need to check
  497. * @param {String} protocol Protocol we need to check against.
  498. * @returns {Boolean} Is it a default port for the given protocol
  499. * @api private
  500. */
  501. module.exports = function required(port, protocol) {
  502. protocol = protocol.split(':')[0];
  503. port = +port;
  504.  
  505. if (!port) return false;
  506.  
  507. switch (protocol) {
  508. case 'http':
  509. case 'ws':
  510. return port !== 80;
  511.  
  512. case 'https':
  513. case 'wss':
  514. return port !== 443;
  515.  
  516. case 'ftp':
  517. return port !== 21;
  518.  
  519. case 'gopher':
  520. return port !== 70;
  521.  
  522. case 'file':
  523. return false;
  524. }
  525.  
  526. return port !== 0;
  527. };
  528.  
  529. },{}],10:[function(require,module,exports){
  530. 'use strict';
  531.  
  532. var required = require('requires-port')
  533. , lolcation = require('./lolcation')
  534. , qs = require('querystringify')
  535. , relativere = /^\/(?!\/)/;
  536.  
  537. /**
  538. * These are the parse instructions for the URL parsers, it informs the parser
  539. * about:
  540. *
  541. * 0. The char it Needs to parse, if it's a string it should be done using
  542. * indexOf, RegExp using exec and NaN means set as current value.
  543. * 1. The property we should set when parsing this value.
  544. * 2. Indication if it's backwards or forward parsing, when set as number it's
  545. * the value of extra chars that should be split off.
  546. * 3. Inherit from location if non existing in the parser.
  547. * 4. `toLowerCase` the resulting value.
  548. */
  549. var instructions = [
  550. ['#', 'hash'], // Extract from the back.
  551. ['?', 'query'], // Extract from the back.
  552. ['//', 'protocol', 2, 1, 1], // Extract from the front.
  553. ['/', 'pathname'], // Extract from the back.
  554. ['@', 'auth', 1], // Extract from the front.
  555. [NaN, 'host', undefined, 1, 1], // Set left over value.
  556. [/\:(\d+)$/, 'port'], // RegExp the back.
  557. [NaN, 'hostname', undefined, 1, 1] // Set left over.
  558. ];
  559.  
  560. /**
  561. * The actual URL instance. Instead of returning an object we've opted-in to
  562. * create an actual constructor as it's much more memory efficient and
  563. * faster and it pleases my CDO.
  564. *
  565. * @constructor
  566. * @param {String} address URL we want to parse.
  567. * @param {Boolean|function} parser Parser for the query string.
  568. * @param {Object} location Location defaults for relative paths.
  569. * @api public
  570. */
  571. function URL(address, location, parser) {
  572. if (!(this instanceof URL)) {
  573. return new URL(address, location, parser);
  574. }
  575.  
  576. var relative = relativere.test(address)
  577. , parse, instruction, index, key
  578. , type = typeof location
  579. , url = this
  580. , i = 0;
  581.  
  582. //
  583. // The following if statements allows this module two have compatibility with
  584. // 2 different API:
  585. //
  586. // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments
  587. // where the boolean indicates that the query string should also be parsed.
  588. //
  589. // 2. The `URL` interface of the browser which accepts a URL, object as
  590. // arguments. The supplied object will be used as default values / fall-back
  591. // for relative paths.
  592. //
  593. if ('object' !== type && 'string' !== type) {
  594. parser = location;
  595. location = null;
  596. }
  597.  
  598. if (parser && 'function' !== typeof parser) {
  599. parser = qs.parse;
  600. }
  601.  
  602. location = lolcation(location);
  603.  
  604. for (; i < instructions.length; i++) {
  605. instruction = instructions[i];
  606. parse = instruction[0];
  607. key = instruction[1];
  608.  
  609. if (parse !== parse) {
  610. url[key] = address;
  611. } else if ('string' === typeof parse) {
  612. if (~(index = address.indexOf(parse))) {
  613. if ('number' === typeof instruction[2]) {
  614. url[key] = address.slice(0, index);
  615. address = address.slice(index + instruction[2]);
  616. } else {
  617. url[key] = address.slice(index);
  618. address = address.slice(0, index);
  619. }
  620. }
  621. } else if (index = parse.exec(address)) {
  622. url[key] = index[1];
  623. address = address.slice(0, address.length - index[0].length);
  624. }
  625.  
  626. url[key] = url[key] || (instruction[3] || ('port' === key && relative) ? location[key] || '' : '');
  627.  
  628. //
  629. // Hostname, host and protocol should be lowercased so they can be used to
  630. // create a proper `origin`.
  631. //
  632. if (instruction[4]) {
  633. url[key] = url[key].toLowerCase();
  634. }
  635. }
  636.  
  637. //
  638. // Also parse the supplied query string in to an object. If we're supplied
  639. // with a custom parser as function use that instead of the default build-in
  640. // parser.
  641. //
  642. if (parser) url.query = parser(url.query);
  643.  
  644. //
  645. // We should not add port numbers if they are already the default port number
  646. // for a given protocol. As the host also contains the port number we're going
  647. // override it with the hostname which contains no port number.
  648. //
  649. if (!required(url.port, url.protocol)) {
  650. url.host = url.hostname;
  651. url.port = '';
  652. }
  653.  
  654. //
  655. // Parse down the `auth` for the username and password.
  656. //
  657. url.username = url.password = '';
  658. if (url.auth) {
  659. instruction = url.auth.split(':');
  660. url.username = instruction[0] || '';
  661. url.password = instruction[1] || '';
  662. }
  663.  
  664. //
  665. // The href is just the compiled result.
  666. //
  667. url.href = url.toString();
  668. }
  669.  
  670. /**
  671. * This is convenience method for changing properties in the URL instance to
  672. * insure that they all propagate correctly.
  673. *
  674. * @param {String} prop Property we need to adjust.
  675. * @param {Mixed} value The newly assigned value.
  676. * @returns {URL}
  677. * @api public
  678. */
  679. URL.prototype.set = function set(part, value, fn) {
  680. var url = this;
  681.  
  682. if ('query' === part) {
  683. if ('string' === typeof value && value.length) {
  684. value = (fn || qs.parse)(value);
  685. }
  686.  
  687. url[part] = value;
  688. } else if ('port' === part) {
  689. url[part] = value;
  690.  
  691. if (!required(value, url.protocol)) {
  692. url.host = url.hostname;
  693. url[part] = '';
  694. } else if (value) {
  695. url.host = url.hostname +':'+ value;
  696. }
  697. } else if ('hostname' === part) {
  698. url[part] = value;
  699.  
  700. if (url.port) value += ':'+ url.port;
  701. url.host = value;
  702. } else if ('host' === part) {
  703. url[part] = value;
  704.  
  705. if (/\:\d+/.test(value)) {
  706. value = value.split(':');
  707. url.hostname = value[0];
  708. url.port = value[1];
  709. }
  710. } else {
  711. url[part] = value;
  712. }
  713.  
  714. url.href = url.toString();
  715. return url;
  716. };
  717.  
  718. /**
  719. * Transform the properties back in to a valid and full URL string.
  720. *
  721. * @param {Function} stringify Optional query stringify function.
  722. * @returns {String}
  723. * @api public
  724. */
  725. URL.prototype.toString = function toString(stringify) {
  726. if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify;
  727.  
  728. var query
  729. , url = this
  730. , result = url.protocol +'//';
  731.  
  732. if (url.username) {
  733. result += url.username;
  734. if (url.password) result += ':'+ url.password;
  735. result += '@';
  736. }
  737.  
  738. result += url.hostname;
  739. if (url.port) result += ':'+ url.port;
  740.  
  741. result += url.pathname;
  742.  
  743. query = 'object' === typeof url.query ? stringify(url.query) : url.query;
  744. if (query) result += '?' !== query.charAt(0) ? '?'+ query : query;
  745.  
  746. if (url.hash) result += url.hash;
  747.  
  748. return result;
  749. };
  750.  
  751. //
  752. // Expose the URL parser and some additional properties that might be useful for
  753. // others.
  754. //
  755. URL.qs = qs;
  756. URL.location = lolcation;
  757. module.exports = URL;
  758.  
  759. },{"./lolcation":11,"querystringify":8,"requires-port":9}],11:[function(require,module,exports){
  760. (function (global){
  761. 'use strict';
  762.  
  763. /**
  764. * These properties should not be copied or inherited from. This is only needed
  765. * for all non blob URL's as the a blob URL does not include a hash, only the
  766. * origin.
  767. *
  768. * @type {Object}
  769. * @private
  770. */
  771. var ignore = { hash: 1, query: 1 }
  772. , URL;
  773.  
  774. /**
  775. * The location object differs when your code is loaded through a normal page,
  776. * Worker or through a worker using a blob. And with the blobble begins the
  777. * trouble as the location object will contain the URL of the blob, not the
  778. * location of the page where our code is loaded in. The actual origin is
  779. * encoded in the `pathname` so we can thankfully generate a good "default"
  780. * location from it so we can generate proper relative URL's again.
  781. *
  782. * @param {Object} loc Optional default location object.
  783. * @returns {Object} lolcation object.
  784. * @api public
  785. */
  786. module.exports = function lolcation(loc) {
  787. loc = loc || global.location || {};
  788. URL = URL || require('./');
  789.  
  790. var finaldestination = {}
  791. , type = typeof loc
  792. , key;
  793.  
  794. if ('blob:' === loc.protocol) {
  795. finaldestination = new URL(unescape(loc.pathname), {});
  796. } else if ('string' === type) {
  797. finaldestination = new URL(loc, {});
  798. for (key in ignore) delete finaldestination[key];
  799. } else if ('object' === type) for (key in loc) {
  800. if (key in ignore) continue;
  801. finaldestination[key] = loc[key];
  802. }
  803.  
  804. return finaldestination;
  805. };
  806.  
  807. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  808. },{"./":10}]},{},[2])(2)
  809. });