Projekt

Obecné

Profil

Stáhnout (15.8 KB) Statistiky
| Větev: | Revize:
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.URLParse = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2
(function (global){
3
'use strict';
4

    
5
var required = require('requires-port')
6
  , qs = require('querystringify')
7
  , slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//
8
  , protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i
9
  , whitespace = '[\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF]'
10
  , left = new RegExp('^'+ whitespace +'+');
11

    
12
/**
13
 * Trim a given string.
14
 *
15
 * @param {String} str String to trim.
16
 * @public
17
 */
18
function trimLeft(str) {
19
  return (str ? str : '').toString().replace(left, '');
20
}
21

    
22
/**
23
 * These are the parse rules for the URL parser, it informs the parser
24
 * about:
25
 *
26
 * 0. The char it Needs to parse, if it's a string it should be done using
27
 *    indexOf, RegExp using exec and NaN means set as current value.
28
 * 1. The property we should set when parsing this value.
29
 * 2. Indication if it's backwards or forward parsing, when set as number it's
30
 *    the value of extra chars that should be split off.
31
 * 3. Inherit from location if non existing in the parser.
32
 * 4. `toLowerCase` the resulting value.
33
 */
34
var rules = [
35
  ['#', 'hash'],                        // Extract from the back.
36
  ['?', 'query'],                       // Extract from the back.
37
  function sanitize(address) {          // Sanitize what is left of the address
38
    return address.replace('\\', '/');
39
  },
40
  ['/', 'pathname'],                    // Extract from the back.
41
  ['@', 'auth', 1],                     // Extract from the front.
42
  [NaN, 'host', undefined, 1, 1],       // Set left over value.
43
  [/:(\d+)$/, 'port', undefined, 1],    // RegExp the back.
44
  [NaN, 'hostname', undefined, 1, 1]    // Set left over.
45
];
46

    
47
/**
48
 * These properties should not be copied or inherited from. This is only needed
49
 * for all non blob URL's as a blob URL does not include a hash, only the
50
 * origin.
51
 *
52
 * @type {Object}
53
 * @private
54
 */
55
var ignore = { hash: 1, query: 1 };
56

    
57
/**
58
 * The location object differs when your code is loaded through a normal page,
59
 * Worker or through a worker using a blob. And with the blobble begins the
60
 * trouble as the location object will contain the URL of the blob, not the
61
 * location of the page where our code is loaded in. The actual origin is
62
 * encoded in the `pathname` so we can thankfully generate a good "default"
63
 * location from it so we can generate proper relative URL's again.
64
 *
65
 * @param {Object|String} loc Optional default location object.
66
 * @returns {Object} lolcation object.
67
 * @public
68
 */
69
function lolcation(loc) {
70
  var globalVar;
71

    
72
  if (typeof window !== 'undefined') globalVar = window;
73
  else if (typeof global !== 'undefined') globalVar = global;
74
  else if (typeof self !== 'undefined') globalVar = self;
75
  else globalVar = {};
76

    
77
  var location = globalVar.location || {};
78
  loc = loc || location;
79

    
80
  var finaldestination = {}
81
    , type = typeof loc
82
    , key;
83

    
84
  if ('blob:' === loc.protocol) {
85
    finaldestination = new Url(unescape(loc.pathname), {});
86
  } else if ('string' === type) {
87
    finaldestination = new Url(loc, {});
88
    for (key in ignore) delete finaldestination[key];
89
  } else if ('object' === type) {
90
    for (key in loc) {
91
      if (key in ignore) continue;
92
      finaldestination[key] = loc[key];
93
    }
94

    
95
    if (finaldestination.slashes === undefined) {
96
      finaldestination.slashes = slashes.test(loc.href);
97
    }
98
  }
99

    
100
  return finaldestination;
101
}
102

    
103
/**
104
 * @typedef ProtocolExtract
105
 * @type Object
106
 * @property {String} protocol Protocol matched in the URL, in lowercase.
107
 * @property {Boolean} slashes `true` if protocol is followed by "//", else `false`.
108
 * @property {String} rest Rest of the URL that is not part of the protocol.
109
 */
110

    
111
/**
112
 * Extract protocol information from a URL with/without double slash ("//").
113
 *
114
 * @param {String} address URL we want to extract from.
115
 * @return {ProtocolExtract} Extracted information.
116
 * @private
117
 */
118
function extractProtocol(address) {
119
  address = trimLeft(address);
120
  var match = protocolre.exec(address);
121

    
122
  return {
123
    protocol: match[1] ? match[1].toLowerCase() : '',
124
    slashes: !!match[2],
125
    rest: match[3]
126
  };
127
}
128

    
129
/**
130
 * Resolve a relative URL pathname against a base URL pathname.
131
 *
132
 * @param {String} relative Pathname of the relative URL.
133
 * @param {String} base Pathname of the base URL.
134
 * @return {String} Resolved pathname.
135
 * @private
136
 */
137
function resolve(relative, base) {
138
  if (relative === '') return base;
139

    
140
  var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/'))
141
    , i = path.length
142
    , last = path[i - 1]
143
    , unshift = false
144
    , up = 0;
145

    
146
  while (i--) {
147
    if (path[i] === '.') {
148
      path.splice(i, 1);
149
    } else if (path[i] === '..') {
150
      path.splice(i, 1);
151
      up++;
152
    } else if (up) {
153
      if (i === 0) unshift = true;
154
      path.splice(i, 1);
155
      up--;
156
    }
157
  }
158

    
159
  if (unshift) path.unshift('');
160
  if (last === '.' || last === '..') path.push('');
161

    
162
  return path.join('/');
163
}
164

    
165
/**
166
 * The actual URL instance. Instead of returning an object we've opted-in to
167
 * create an actual constructor as it's much more memory efficient and
168
 * faster and it pleases my OCD.
169
 *
170
 * It is worth noting that we should not use `URL` as class name to prevent
171
 * clashes with the global URL instance that got introduced in browsers.
172
 *
173
 * @constructor
174
 * @param {String} address URL we want to parse.
175
 * @param {Object|String} [location] Location defaults for relative paths.
176
 * @param {Boolean|Function} [parser] Parser for the query string.
177
 * @private
178
 */
179
function Url(address, location, parser) {
180
  address = trimLeft(address);
181

    
182
  if (!(this instanceof Url)) {
183
    return new Url(address, location, parser);
184
  }
185

    
186
  var relative, extracted, parse, instruction, index, key
187
    , instructions = rules.slice()
188
    , type = typeof location
189
    , url = this
190
    , i = 0;
191

    
192
  //
193
  // The following if statements allows this module two have compatibility with
194
  // 2 different API:
195
  //
196
  // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments
197
  //    where the boolean indicates that the query string should also be parsed.
198
  //
199
  // 2. The `URL` interface of the browser which accepts a URL, object as
200
  //    arguments. The supplied object will be used as default values / fall-back
201
  //    for relative paths.
202
  //
203
  if ('object' !== type && 'string' !== type) {
204
    parser = location;
205
    location = null;
206
  }
207

    
208
  if (parser && 'function' !== typeof parser) parser = qs.parse;
209

    
210
  location = lolcation(location);
211

    
212
  //
213
  // Extract protocol information before running the instructions.
214
  //
215
  extracted = extractProtocol(address || '');
216
  relative = !extracted.protocol && !extracted.slashes;
217
  url.slashes = extracted.slashes || relative && location.slashes;
218
  url.protocol = extracted.protocol || location.protocol || '';
219
  address = extracted.rest;
220

    
221
  //
222
  // When the authority component is absent the URL starts with a path
223
  // component.
224
  //
225
  if (!extracted.slashes) instructions[3] = [/(.*)/, 'pathname'];
226

    
227
  for (; i < instructions.length; i++) {
228
    instruction = instructions[i];
229

    
230
    if (typeof instruction === 'function') {
231
      address = instruction(address);
232
      continue;
233
    }
234

    
235
    parse = instruction[0];
236
    key = instruction[1];
237

    
238
    if (parse !== parse) {
239
      url[key] = address;
240
    } else if ('string' === typeof parse) {
241
      if (~(index = address.indexOf(parse))) {
242
        if ('number' === typeof instruction[2]) {
243
          url[key] = address.slice(0, index);
244
          address = address.slice(index + instruction[2]);
245
        } else {
246
          url[key] = address.slice(index);
247
          address = address.slice(0, index);
248
        }
249
      }
250
    } else if ((index = parse.exec(address))) {
251
      url[key] = index[1];
252
      address = address.slice(0, index.index);
253
    }
254

    
255
    url[key] = url[key] || (
256
      relative && instruction[3] ? location[key] || '' : ''
257
    );
258

    
259
    //
260
    // Hostname, host and protocol should be lowercased so they can be used to
261
    // create a proper `origin`.
262
    //
263
    if (instruction[4]) url[key] = url[key].toLowerCase();
264
  }
265

    
266
  //
267
  // Also parse the supplied query string in to an object. If we're supplied
268
  // with a custom parser as function use that instead of the default build-in
269
  // parser.
270
  //
271
  if (parser) url.query = parser(url.query);
272

    
273
  //
274
  // If the URL is relative, resolve the pathname against the base URL.
275
  //
276
  if (
277
      relative
278
    && location.slashes
279
    && url.pathname.charAt(0) !== '/'
280
    && (url.pathname !== '' || location.pathname !== '')
281
  ) {
282
    url.pathname = resolve(url.pathname, location.pathname);
283
  }
284

    
285
  //
286
  // We should not add port numbers if they are already the default port number
287
  // for a given protocol. As the host also contains the port number we're going
288
  // override it with the hostname which contains no port number.
289
  //
290
  if (!required(url.port, url.protocol)) {
291
    url.host = url.hostname;
292
    url.port = '';
293
  }
294

    
295
  //
296
  // Parse down the `auth` for the username and password.
297
  //
298
  url.username = url.password = '';
299
  if (url.auth) {
300
    instruction = url.auth.split(':');
301
    url.username = instruction[0] || '';
302
    url.password = instruction[1] || '';
303
  }
304

    
305
  url.origin = url.protocol && url.host && url.protocol !== 'file:'
306
    ? url.protocol +'//'+ url.host
307
    : 'null';
308

    
309
  //
310
  // The href is just the compiled result.
311
  //
312
  url.href = url.toString();
313
}
314

    
315
/**
316
 * This is convenience method for changing properties in the URL instance to
317
 * insure that they all propagate correctly.
318
 *
319
 * @param {String} part          Property we need to adjust.
320
 * @param {Mixed} value          The newly assigned value.
321
 * @param {Boolean|Function} fn  When setting the query, it will be the function
322
 *                               used to parse the query.
323
 *                               When setting the protocol, double slash will be
324
 *                               removed from the final url if it is true.
325
 * @returns {URL} URL instance for chaining.
326
 * @public
327
 */
328
function set(part, value, fn) {
329
  var url = this;
330

    
331
  switch (part) {
332
    case 'query':
333
      if ('string' === typeof value && value.length) {
334
        value = (fn || qs.parse)(value);
335
      }
336

    
337
      url[part] = value;
338
      break;
339

    
340
    case 'port':
341
      url[part] = value;
342

    
343
      if (!required(value, url.protocol)) {
344
        url.host = url.hostname;
345
        url[part] = '';
346
      } else if (value) {
347
        url.host = url.hostname +':'+ value;
348
      }
349

    
350
      break;
351

    
352
    case 'hostname':
353
      url[part] = value;
354

    
355
      if (url.port) value += ':'+ url.port;
356
      url.host = value;
357
      break;
358

    
359
    case 'host':
360
      url[part] = value;
361

    
362
      if (/:\d+$/.test(value)) {
363
        value = value.split(':');
364
        url.port = value.pop();
365
        url.hostname = value.join(':');
366
      } else {
367
        url.hostname = value;
368
        url.port = '';
369
      }
370

    
371
      break;
372

    
373
    case 'protocol':
374
      url.protocol = value.toLowerCase();
375
      url.slashes = !fn;
376
      break;
377

    
378
    case 'pathname':
379
    case 'hash':
380
      if (value) {
381
        var char = part === 'pathname' ? '/' : '#';
382
        url[part] = value.charAt(0) !== char ? char + value : value;
383
      } else {
384
        url[part] = value;
385
      }
386
      break;
387

    
388
    default:
389
      url[part] = value;
390
  }
391

    
392
  for (var i = 0; i < rules.length; i++) {
393
    var ins = rules[i];
394

    
395
    if (ins[4]) url[ins[1]] = url[ins[1]].toLowerCase();
396
  }
397

    
398
  url.origin = url.protocol && url.host && url.protocol !== 'file:'
399
    ? url.protocol +'//'+ url.host
400
    : 'null';
401

    
402
  url.href = url.toString();
403

    
404
  return url;
405
}
406

    
407
/**
408
 * Transform the properties back in to a valid and full URL string.
409
 *
410
 * @param {Function} stringify Optional query stringify function.
411
 * @returns {String} Compiled version of the URL.
412
 * @public
413
 */
414
function toString(stringify) {
415
  if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify;
416

    
417
  var query
418
    , url = this
419
    , protocol = url.protocol;
420

    
421
  if (protocol && protocol.charAt(protocol.length - 1) !== ':') protocol += ':';
422

    
423
  var result = protocol + (url.slashes ? '//' : '');
424

    
425
  if (url.username) {
426
    result += url.username;
427
    if (url.password) result += ':'+ url.password;
428
    result += '@';
429
  }
430

    
431
  result += url.host + url.pathname;
432

    
433
  query = 'object' === typeof url.query ? stringify(url.query) : url.query;
434
  if (query) result += '?' !== query.charAt(0) ? '?'+ query : query;
435

    
436
  if (url.hash) result += url.hash;
437

    
438
  return result;
439
}
440

    
441
Url.prototype = { set: set, toString: toString };
442

    
443
//
444
// Expose the URL parser and some additional properties that might be useful for
445
// others or testing.
446
//
447
Url.extractProtocol = extractProtocol;
448
Url.location = lolcation;
449
Url.trimLeft = trimLeft;
450
Url.qs = qs;
451

    
452
module.exports = Url;
453

    
454
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
455
},{"querystringify":2,"requires-port":3}],2:[function(require,module,exports){
456
'use strict';
457

    
458
var has = Object.prototype.hasOwnProperty;
459

    
460
/**
461
 * Decode a URI encoded string.
462
 *
463
 * @param {String} input The URI encoded string.
464
 * @returns {String} The decoded string.
465
 * @api private
466
 */
467
function decode(input) {
468
  return decodeURIComponent(input.replace(/\+/g, ' '));
469
}
470

    
471
/**
472
 * Simple query string parser.
473
 *
474
 * @param {String} query The query string that needs to be parsed.
475
 * @returns {Object}
476
 * @api public
477
 */
478
function querystring(query) {
479
  var parser = /([^=?&]+)=?([^&]*)/g
480
    , result = {}
481
    , part;
482

    
483
  while (part = parser.exec(query)) {
484
    var key = decode(part[1])
485
      , value = decode(part[2]);
486

    
487
    //
488
    // Prevent overriding of existing properties. This ensures that build-in
489
    // methods like `toString` or __proto__ are not overriden by malicious
490
    // querystrings.
491
    //
492
    if (key in result) continue;
493
    result[key] = value;
494
  }
495

    
496
  return result;
497
}
498

    
499
/**
500
 * Transform a query string to an object.
501
 *
502
 * @param {Object} obj Object that should be transformed.
503
 * @param {String} prefix Optional prefix.
504
 * @returns {String}
505
 * @api public
506
 */
507
function querystringify(obj, prefix) {
508
  prefix = prefix || '';
509

    
510
  var pairs = [];
511

    
512
  //
513
  // Optionally prefix with a '?' if needed
514
  //
515
  if ('string' !== typeof prefix) prefix = '?';
516

    
517
  for (var key in obj) {
518
    if (has.call(obj, key)) {
519
      pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(obj[key]));
520
    }
521
  }
522

    
523
  return pairs.length ? prefix + pairs.join('&') : '';
524
}
525

    
526
//
527
// Expose the module.
528
//
529
exports.stringify = querystringify;
530
exports.parse = querystring;
531

    
532
},{}],3:[function(require,module,exports){
533
'use strict';
534

    
535
/**
536
 * Check if we're required to add a port number.
537
 *
538
 * @see https://url.spec.whatwg.org/#default-port
539
 * @param {Number|String} port Port number we need to check
540
 * @param {String} protocol Protocol we need to check against.
541
 * @returns {Boolean} Is it a default port for the given protocol
542
 * @api private
543
 */
544
module.exports = function required(port, protocol) {
545
  protocol = protocol.split(':')[0];
546
  port = +port;
547

    
548
  if (!port) return false;
549

    
550
  switch (protocol) {
551
    case 'http':
552
    case 'ws':
553
    return port !== 80;
554

    
555
    case 'https':
556
    case 'wss':
557
    return port !== 443;
558

    
559
    case 'ftp':
560
    return port !== 21;
561

    
562
    case 'gopher':
563
    return port !== 70;
564

    
565
    case 'file':
566
    return false;
567
  }
568

    
569
  return port !== 0;
570
};
571

    
572
},{}]},{},[1])(1)
573
});
(1-1/3)