uri-js-rails 1.10.2 → 1.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a7679fe260f287fbf4cd1b2e7343099c24d65db
4
- data.tar.gz: 840a0a784bea3cf14f18bf2e713413d68f855b01
3
+ metadata.gz: 832749544eac4e151c71f2eca3a7c721f0fc09ab
4
+ data.tar.gz: d6066ba989fb1c729d59cbe6c04fa4daa9437ef0
5
5
  SHA512:
6
- metadata.gz: 6096b252b722dd13466b81cbea3f59a386ddac30d7c7d478ee1d1a1df0bb5ad16b55829673bb765ac2f16dae1636f15202fa066d03b2db678f9a942d0f780ecc
7
- data.tar.gz: bfecfe90b7073d03073724c1f9eae3dbb5f8f9b5b68bc555c2eafdd8a49f29536e54f8843483724b829001d35e38038a0a3c7e519321a9b4563d7f2d8ee1edd3
6
+ metadata.gz: 06ab4a80a1df8c24dccbc9804d8bed2565b8ca1aac198ad7af6801e3b7b5fadc64263102bc11813cb34924eddec0f44d67ac0326daf896a101042bc0e83a6dad
7
+ data.tar.gz: 8d9d8637df1038a7c92a69d5690215b1d3bb2dd2b52d85ab10368808e1db0441121572b70569e07f365d7d72893cca3f19a9931360d8789ae1ec679492647aad
@@ -1,7 +1,7 @@
1
1
  module Uri
2
2
  module Js
3
3
  module Rails
4
- VERSION = "1.10.2"
4
+ VERSION = "1.11.2"
5
5
  end
6
6
  end
7
7
  end
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * URI.js - Mutating URLs
3
3
  *
4
- * Version: 1.10.2
4
+ * Version: 1.11.2
5
5
  *
6
6
  * Author: Rodney Rehm
7
7
  * Web: http://medialize.github.com/URI.js/
@@ -21,11 +21,14 @@
21
21
  define(['./punycode', './IPv6', './SecondLevelDomains'], factory);
22
22
  } else {
23
23
  // Browser globals (root is window)
24
- root.URI = factory(root.punycode, root.IPv6, root.SecondLevelDomains);
24
+ root.URI = factory(root.punycode, root.IPv6, root.SecondLevelDomains, root);
25
25
  }
26
- }(this, function (punycode, IPv6, SLD) {
26
+ }(this, function (punycode, IPv6, SLD, root) {
27
27
  "use strict";
28
28
 
29
+ // save current URI variable, if any
30
+ var _URI = root && root.URI;
31
+
29
32
  function URI(url, base) {
30
33
  // Allow instantiation without the 'new' keyword
31
34
  if (!(this instanceof URI)) {
@@ -59,6 +62,11 @@ function escapeRegEx(string) {
59
62
  }
60
63
 
61
64
  function getType(value) {
65
+ // IE8 doesn't return [Object Undefined] but [Object Object] for undefined value
66
+ if (value === undefined) {
67
+ return 'Undefined';
68
+ }
69
+
62
70
  return String(Object.prototype.toString.call(value)).slice(8, -1);
63
71
  }
64
72
 
@@ -152,11 +160,14 @@ URI._parts = function() {
152
160
  query: null,
153
161
  fragment: null,
154
162
  // state
155
- duplicateQueryParameters: URI.duplicateQueryParameters
163
+ duplicateQueryParameters: URI.duplicateQueryParameters,
164
+ escapeQuerySpace: URI.escapeQuerySpace
156
165
  };
157
166
  };
158
167
  // state: allow duplicate query parameters (a=1&a=1)
159
168
  URI.duplicateQueryParameters = false;
169
+ // state: replaces + with %20 (space in query strings)
170
+ URI.escapeQuerySpace = true;
160
171
  // static properties
161
172
  URI.protocol_expression = /^[a-z][a-z0-9-+-]*$/i;
162
173
  URI.idn_expression = /[^a-z0-9\.-]/i;
@@ -183,11 +194,46 @@ URI.defaultPorts = {
183
194
  // ALPHA DIGIT "-" "." "_" "~" "!" "$" "&" "'" "(" ")" "*" "+" "," ";" "=" %encoded
184
195
  // I've never seen a (non-IDN) hostname other than: ALPHA DIGIT . -
185
196
  URI.invalid_hostname_characters = /[^a-zA-Z0-9\.-]/;
197
+ // map DOM Elements to their URI attribute
198
+ URI.domAttributes = {
199
+ 'a': 'href',
200
+ 'blockquote': 'cite',
201
+ 'link': 'href',
202
+ 'base': 'href',
203
+ 'script': 'src',
204
+ 'form': 'action',
205
+ 'img': 'src',
206
+ 'area': 'href',
207
+ 'iframe': 'src',
208
+ 'embed': 'src',
209
+ 'source': 'src',
210
+ 'track': 'src',
211
+ 'input': 'src' // but only if type="image"
212
+ };
213
+ URI.getDomAttribute = function(node) {
214
+ if (!node || !node.nodeName) {
215
+ return undefined;
216
+ }
217
+
218
+ var nodeName = node.nodeName.toLowerCase();
219
+ // <input> should only expose src for type="image"
220
+ if (nodeName === 'input' && node.type !== 'image') {
221
+ return undefined;
222
+ }
223
+
224
+ return URI.domAttributes[nodeName];
225
+ };
226
+
227
+ function escapeForDumbFirefox36(value) {
228
+ // https://github.com/medialize/URI.js/issues/91
229
+ return escape(value);
230
+ }
231
+
186
232
  // encoding / decoding according to RFC3986
187
233
  function strictEncodeURIComponent(string) {
188
234
  // see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURIComponent
189
235
  return encodeURIComponent(string)
190
- .replace(/[!'()*]/g, escape)
236
+ .replace(/[!'()*]/g, escapeForDumbFirefox36)
191
237
  .replace(/\*/g, "%2A");
192
238
  }
193
239
  URI.encode = strictEncodeURIComponent;
@@ -257,11 +303,21 @@ URI.characters = {
257
303
  }
258
304
  }
259
305
  };
260
- URI.encodeQuery = function(string) {
261
- return URI.encode(string + "").replace(/%20/g, '+');
306
+ URI.encodeQuery = function(string, escapeQuerySpace) {
307
+ var escaped = URI.encode(string + "");
308
+ return escapeQuerySpace ? escaped.replace(/%20/g, '+') : escaped;
262
309
  };
263
- URI.decodeQuery = function(string) {
264
- return URI.decode((string + "").replace(/\+/g, '%20'));
310
+ URI.decodeQuery = function(string, escapeQuerySpace) {
311
+ string += "";
312
+ try {
313
+ return URI.decode(escapeQuerySpace ? string.replace(/\+/g, '%20') : string);
314
+ } catch(e) {
315
+ // we're not going to mess with weird encodings,
316
+ // give up and return the undecoded original string
317
+ // see https://github.com/medialize/URI.js/issues/87
318
+ // see https://github.com/medialize/URI.js/issues/92
319
+ return string;
320
+ }
265
321
  };
266
322
  URI.recodePath = function(string) {
267
323
  var segments = (string + "").split('/');
@@ -297,7 +353,7 @@ for (_part in _parts) {
297
353
  URI.encodeReserved = generateAccessor("reserved", "encode");
298
354
 
299
355
  URI.parse = function(string, parts) {
300
- var pos, t;
356
+ var pos;
301
357
  if (!parts) {
302
358
  parts = {};
303
359
  }
@@ -322,14 +378,14 @@ URI.parse = function(string, parts) {
322
378
  // extract protocol
323
379
  if (string.substring(0, 2) === '//') {
324
380
  // relative-scheme
325
- parts.protocol = '';
381
+ parts.protocol = null;
326
382
  string = string.substring(2);
327
383
  // extract "user:pass@host:port"
328
384
  string = URI.parseAuthority(string, parts);
329
385
  } else {
330
386
  pos = string.indexOf(':');
331
387
  if (pos > -1) {
332
- parts.protocol = string.substring(0, pos);
388
+ parts.protocol = string.substring(0, pos) || null;
333
389
  if (parts.protocol && !parts.protocol.match(URI.protocol_expression)) {
334
390
  // : may be within the path
335
391
  parts.protocol = undefined;
@@ -395,8 +451,10 @@ URI.parseAuthority = function(string, parts) {
395
451
  };
396
452
  URI.parseUserinfo = function(string, parts) {
397
453
  // extract username:password
398
- var pos = string.indexOf('@');
399
454
  var firstSlash = string.indexOf('/');
455
+ var pos = firstSlash > -1
456
+ ? string.lastIndexOf('@', firstSlash)
457
+ : string.indexOf('@');
400
458
  var t;
401
459
 
402
460
  // authority@ must come before /path
@@ -413,7 +471,7 @@ URI.parseUserinfo = function(string, parts) {
413
471
 
414
472
  return string;
415
473
  };
416
- URI.parseQuery = function(string) {
474
+ URI.parseQuery = function(string, escapeQuerySpace) {
417
475
  if (!string) {
418
476
  return {};
419
477
  }
@@ -432,9 +490,9 @@ URI.parseQuery = function(string) {
432
490
 
433
491
  for (var i = 0; i < length; i++) {
434
492
  v = splits[i].split('=');
435
- name = URI.decodeQuery(v.shift());
493
+ name = URI.decodeQuery(v.shift(), escapeQuerySpace);
436
494
  // no "=" is null according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#collect-url-parameters
437
- value = v.length ? URI.decodeQuery(v.join('=')) : null;
495
+ value = v.length ? URI.decodeQuery(v.join('='), escapeQuerySpace) : null;
438
496
 
439
497
  if (items[name]) {
440
498
  if (typeof items[name] === "string") {
@@ -520,7 +578,7 @@ URI.buildUserinfo = function(parts) {
520
578
 
521
579
  return t;
522
580
  };
523
- URI.buildQuery = function(data, duplicates) {
581
+ URI.buildQuery = function(data, duplicateQueryParameters, escapeQuerySpace) {
524
582
  // according to http://tools.ietf.org/html/rfc3986 or http://labs.apache.org/webarch/uri/rfc/rfc3986.html
525
583
  // being »-._~!$&'()*+,;=:@/?« %HEX and alnum are allowed
526
584
  // the RFC explicitly states ?/foo being a valid use case, no mention of parameter syntax!
@@ -535,24 +593,24 @@ URI.buildQuery = function(data, duplicates) {
535
593
  unique = {};
536
594
  for (i = 0, length = data[key].length; i < length; i++) {
537
595
  if (data[key][i] !== undefined && unique[data[key][i] + ""] === undefined) {
538
- t += "&" + URI.buildQueryParameter(key, data[key][i]);
539
- if (duplicates !== true) {
596
+ t += "&" + URI.buildQueryParameter(key, data[key][i], escapeQuerySpace);
597
+ if (duplicateQueryParameters !== true) {
540
598
  unique[data[key][i] + ""] = true;
541
599
  }
542
600
  }
543
601
  }
544
602
  } else if (data[key] !== undefined) {
545
- t += '&' + URI.buildQueryParameter(key, data[key]);
603
+ t += '&' + URI.buildQueryParameter(key, data[key], escapeQuerySpace);
546
604
  }
547
605
  }
548
606
  }
549
607
 
550
608
  return t.substring(1);
551
609
  };
552
- URI.buildQueryParameter = function(name, value) {
610
+ URI.buildQueryParameter = function(name, value, escapeQuerySpace) {
553
611
  // http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type -- application/x-www-form-urlencoded
554
612
  // don't append "=" for null values, according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#url-parameter-serialization
555
- return URI.encodeQuery(name) + (value !== null ? "=" + URI.encodeQuery(value) : "");
613
+ return URI.encodeQuery(name, escapeQuerySpace) + (value !== null ? "=" + URI.encodeQuery(value, escapeQuerySpace) : "");
556
614
  };
557
615
 
558
616
  URI.addQuery = function(data, name, value) {
@@ -723,6 +781,33 @@ URI.ensureValidHostname = function(v) {
723
781
  }
724
782
  };
725
783
 
784
+ // noConflict
785
+ URI.noConflict = function(removeAll) {
786
+ if (removeAll) {
787
+ var unconflicted = {
788
+ URI: this.noConflict()
789
+ };
790
+
791
+ if (URITemplate && typeof URITemplate.noConflict == "function") {
792
+ unconflicted.URITemplate = URITemplate.noConflict();
793
+ }
794
+
795
+ if (IPv6 && typeof IPv6.noConflict == "function") {
796
+ unconflicted.IPv6 = IPv6.noConflict();
797
+ }
798
+
799
+ if (SecondLevelDomains && typeof SecondLevelDomains.noConflict == "function") {
800
+ unconflicted.SecondLevelDomains = SecondLevelDomains.noConflict();
801
+ }
802
+
803
+ return unconflicted;
804
+ } else if (root.URI === this) {
805
+ root.URI = _URI;
806
+ }
807
+
808
+ return this;
809
+ };
810
+
726
811
  p.build = function(deferBuild) {
727
812
  if (deferBuild === true) {
728
813
  this._deferred_build = true;
@@ -749,7 +834,7 @@ generateAccessor = function(_part){
749
834
  if (v === undefined) {
750
835
  return this._parts[_part] || "";
751
836
  } else {
752
- this._parts[_part] = v;
837
+ this._parts[_part] = v || null;
753
838
  this.build(!build);
754
839
  return this;
755
840
  }
@@ -800,7 +885,7 @@ for (_part in _parts) {
800
885
 
801
886
  p.pathname = function(v, build) {
802
887
  if (v === undefined || v === true) {
803
- var res = this._parts.path || (this._parts.urn ? '' : '/');
888
+ var res = this._parts.path || (this._parts.hostname ? '/' : '');
804
889
  return v ? URI.decodePath(res) : res;
805
890
  } else {
806
891
  this._parts.path = v ? URI.recodePath(v) : "/";
@@ -820,8 +905,12 @@ p.href = function(href, build) {
820
905
  this._parts = URI._parts();
821
906
 
822
907
  var _URI = href instanceof URI;
823
- var _object = typeof href === "object" && (href.hostname || href.path);
824
-
908
+ var _object = typeof href === "object" && (href.hostname || href.path || href.pathname);
909
+ if (href.nodeName) {
910
+ var attribute = URI.getDomAttribute(href);
911
+ href = href[attribute] || "";
912
+ _object = false;
913
+ }
825
914
 
826
915
  // window.location is reported to be an object, but it's not the sort
827
916
  // of object we're looking for:
@@ -1301,7 +1390,7 @@ p.segment = function(segment, v, build) {
1301
1390
  var absolute = path.substring(0, 1) === '/';
1302
1391
  var segments = path.split(separator);
1303
1392
 
1304
- if (typeof segment !== 'number') {
1393
+ if (segment !== undefined && typeof segment !== 'number') {
1305
1394
  build = v;
1306
1395
  v = segment;
1307
1396
  segment = undefined;
@@ -1326,11 +1415,23 @@ p.segment = function(segment, v, build) {
1326
1415
  : segments[segment];
1327
1416
  } else if (segment === null || segments[segment] === undefined) {
1328
1417
  if (isArray(v)) {
1329
- segments = v;
1330
- } else if (v || (typeof v === "string" && v.length)) {
1418
+ segments = [];
1419
+ // collapse empty elements within array
1420
+ for (var i=0, l=v.length; i < l; i++) {
1421
+ if (!v[i].length && (!segments.length || !segments[segments.length -1].length)) {
1422
+ continue;
1423
+ }
1424
+
1425
+ if (segments.length && !segments[segments.length -1].length) {
1426
+ segments.pop();
1427
+ }
1428
+
1429
+ segments.push(v[i]);
1430
+ }
1431
+ } else if (v || (typeof v === "string")) {
1331
1432
  if (segments[segments.length -1] === "") {
1332
1433
  // empty trailing elements have to be overwritten
1333
- // to prefent results such as /foo//bar
1434
+ // to prevent results such as /foo//bar
1334
1435
  segments[segments.length -1] = v;
1335
1436
  } else {
1336
1437
  segments.push(v);
@@ -1350,20 +1451,52 @@ p.segment = function(segment, v, build) {
1350
1451
 
1351
1452
  return this.path(segments.join(separator), build);
1352
1453
  };
1454
+ p.segmentCoded = function(segment, v, build) {
1455
+ var segments, i, l;
1456
+
1457
+ if (typeof segment !== 'number') {
1458
+ build = v;
1459
+ v = segment;
1460
+ segment = undefined;
1461
+ }
1462
+
1463
+ if (v === undefined) {
1464
+ segments = this.segment(segment, v, build);
1465
+ if (!isArray(segments)) {
1466
+ segments = segments !== undefined ? URI.decode(segments) : undefined;
1467
+ } else {
1468
+ for (i = 0, l = segments.length; i < l; i++) {
1469
+ segments[i] = URI.decode(segments[i]);
1470
+ }
1471
+ }
1472
+
1473
+ return segments;
1474
+ }
1475
+
1476
+ if (!isArray(v)) {
1477
+ v = typeof v === 'string' ? URI.encode(v) : v;
1478
+ } else {
1479
+ for (i = 0, l = v.length; i < l; i++) {
1480
+ v[i] = URI.decode(v[i]);
1481
+ }
1482
+ }
1483
+
1484
+ return this.segment(segment, v, build);
1485
+ };
1353
1486
 
1354
1487
  // mutating query string
1355
1488
  var q = p.query;
1356
1489
  p.query = function(v, build) {
1357
1490
  if (v === true) {
1358
- return URI.parseQuery(this._parts.query);
1491
+ return URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
1359
1492
  } else if (typeof v === "function") {
1360
- var data = URI.parseQuery(this._parts.query);
1493
+ var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
1361
1494
  var result = v.call(this, data);
1362
- this._parts.query = URI.buildQuery(result || data, this._parts.duplicateQueryParameters);
1495
+ this._parts.query = URI.buildQuery(result || data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
1363
1496
  this.build(!build);
1364
1497
  return this;
1365
1498
  } else if (v !== undefined && typeof v !== "string") {
1366
- this._parts.query = URI.buildQuery(v, this._parts.duplicateQueryParameters);
1499
+ this._parts.query = URI.buildQuery(v, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
1367
1500
  this.build(!build);
1368
1501
  return this;
1369
1502
  } else {
@@ -1371,7 +1504,7 @@ p.query = function(v, build) {
1371
1504
  }
1372
1505
  };
1373
1506
  p.setQuery = function(name, value, build) {
1374
- var data = URI.parseQuery(this._parts.query);
1507
+ var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
1375
1508
 
1376
1509
  if (typeof name === "object") {
1377
1510
  for (var key in name) {
@@ -1385,7 +1518,7 @@ p.setQuery = function(name, value, build) {
1385
1518
  throw new TypeError("URI.addQuery() accepts an object, string as the name parameter");
1386
1519
  }
1387
1520
 
1388
- this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters);
1521
+ this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
1389
1522
  if (typeof name !== "string") {
1390
1523
  build = value;
1391
1524
  }
@@ -1394,9 +1527,9 @@ p.setQuery = function(name, value, build) {
1394
1527
  return this;
1395
1528
  };
1396
1529
  p.addQuery = function(name, value, build) {
1397
- var data = URI.parseQuery(this._parts.query);
1530
+ var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
1398
1531
  URI.addQuery(data, name, value === undefined ? null : value);
1399
- this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters);
1532
+ this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
1400
1533
  if (typeof name !== "string") {
1401
1534
  build = value;
1402
1535
  }
@@ -1405,9 +1538,9 @@ p.addQuery = function(name, value, build) {
1405
1538
  return this;
1406
1539
  };
1407
1540
  p.removeQuery = function(name, value, build) {
1408
- var data = URI.parseQuery(this._parts.query);
1541
+ var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
1409
1542
  URI.removeQuery(data, name, value);
1410
- this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters);
1543
+ this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
1411
1544
  if (typeof name !== "string") {
1412
1545
  build = value;
1413
1546
  }
@@ -1416,7 +1549,7 @@ p.removeQuery = function(name, value, build) {
1416
1549
  return this;
1417
1550
  };
1418
1551
  p.hasQuery = function(name, value, withinArray) {
1419
- var data = URI.parseQuery(this._parts.query);
1552
+ var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
1420
1553
  return URI.hasQuery(data, name, value, withinArray);
1421
1554
  };
1422
1555
  p.setSearch = p.setQuery;
@@ -1484,20 +1617,20 @@ p.normalizePath = function(build) {
1484
1617
  }
1485
1618
 
1486
1619
  var _was_relative;
1487
- var _was_relative_prefix;
1488
1620
  var _path = this._parts.path;
1489
1621
  var _parent, _pos;
1490
1622
 
1491
1623
  // handle relative paths
1492
1624
  if (_path.charAt(0) !== '/') {
1493
- if (_path.charAt(0) === '.') {
1494
- _was_relative_prefix = _path.substring(0, _path.indexOf('/'));
1495
- }
1496
1625
  _was_relative = true;
1497
1626
  _path = '/' + _path;
1498
1627
  }
1628
+
1499
1629
  // resolve simples
1500
- _path = _path.replace(/(\/(\.\/)+)|\/{2,}/g, '/');
1630
+ _path = _path
1631
+ .replace(/(\/(\.\/)+)|(\/\.$)/g, '/')
1632
+ .replace(/\/{2,}/g, '/');
1633
+
1501
1634
  // resolve parents
1502
1635
  while (true) {
1503
1636
  _parent = _path.indexOf('/../');
@@ -1516,6 +1649,7 @@ p.normalizePath = function(build) {
1516
1649
  }
1517
1650
  _path = _path.substring(0, _pos) + _path.substring(_parent + 3);
1518
1651
  }
1652
+
1519
1653
  // revert to relative
1520
1654
  if (_was_relative && this.is('relative')) {
1521
1655
  _path = _path.substring(1);
@@ -1532,7 +1666,7 @@ p.normalizeQuery = function(build) {
1532
1666
  if (!this._parts.query.length) {
1533
1667
  this._parts.query = null;
1534
1668
  } else {
1535
- this.query(URI.parseQuery(this._parts.query));
1669
+ this.query(URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace));
1536
1670
  }
1537
1671
 
1538
1672
  this.build(!build);
@@ -1606,18 +1740,18 @@ p.readable = function() {
1606
1740
  var q = '';
1607
1741
  for (var i = 0, qp = uri._parts.query.split('&'), l = qp.length; i < l; i++) {
1608
1742
  var kv = (qp[i] || "").split('=');
1609
- q += '&' + URI.decodeQuery(kv[0])
1743
+ q += '&' + URI.decodeQuery(kv[0], this._parts.escapeQuerySpace)
1610
1744
  .replace(/&/g, '%26');
1611
1745
 
1612
1746
  if (kv[1] !== undefined) {
1613
- q += "=" + URI.decodeQuery(kv[1])
1747
+ q += "=" + URI.decodeQuery(kv[1], this._parts.escapeQuerySpace)
1614
1748
  .replace(/&/g, '%26');
1615
1749
  }
1616
1750
  }
1617
1751
  t += '?' + q.substring(1);
1618
1752
  }
1619
1753
 
1620
- t += uri.hash();
1754
+ t += URI.decodeQuery(uri.hash(), true);
1621
1755
  return t;
1622
1756
  };
1623
1757
 
@@ -1628,7 +1762,7 @@ p.absoluteTo = function(base) {
1628
1762
  var basedir, i, p;
1629
1763
 
1630
1764
  if (this._parts.urn) {
1631
- throw new Error('URNs do not have any generally defined hierachical components');
1765
+ throw new Error('URNs do not have any generally defined hierarchical components');
1632
1766
  }
1633
1767
 
1634
1768
  if (!(base instanceof URI)) {
@@ -1643,12 +1777,12 @@ p.absoluteTo = function(base) {
1643
1777
  return resolved;
1644
1778
  }
1645
1779
 
1646
- for (i = 0, p; p = properties[i]; i++) {
1780
+ for (i = 0; p = properties[i]; i++) {
1647
1781
  resolved._parts[p] = base._parts[p];
1648
1782
  }
1649
1783
 
1650
1784
  properties = ['query', 'path'];
1651
- for (i = 0, p; p = properties[i]; i++) {
1785
+ for (i = 0; p = properties[i]; i++) {
1652
1786
  if (!resolved._parts[p] && base._parts[p]) {
1653
1787
  resolved._parts[p] = base._parts[p];
1654
1788
  }
@@ -1664,70 +1798,66 @@ p.absoluteTo = function(base) {
1664
1798
  return resolved;
1665
1799
  };
1666
1800
  p.relativeTo = function(base) {
1667
- var relative = this.clone();
1668
- var properties = ['protocol', 'username', 'password', 'hostname', 'port'];
1669
- var common, _base, _this, _base_diff, _this_diff;
1801
+ var relative = this.clone().normalize();
1802
+ var relativeParts, baseParts, common, relativePath, basePath;
1670
1803
 
1671
1804
  if (relative._parts.urn) {
1672
- throw new Error('URNs do not have any generally defined hierachical components');
1805
+ throw new Error('URNs do not have any generally defined hierarchical components');
1673
1806
  }
1674
1807
 
1675
- if (!(base instanceof URI)) {
1676
- base = new URI(base);
1808
+ base = new URI(base).normalize();
1809
+ relativeParts = relative._parts;
1810
+ baseParts = base._parts;
1811
+ relativePath = relative.path();
1812
+ basePath = base.path();
1813
+
1814
+ if (relativePath.charAt(0) !== '/') {
1815
+ throw new Error('URI is already relative');
1677
1816
  }
1678
1817
 
1679
- if (relative.path().charAt(0) !== '/' || base.path().charAt(0) !== '/') {
1680
- throw new Error('Cannot calculate common path from non-relative URLs');
1818
+ if (basePath.charAt(0) !== '/') {
1819
+ throw new Error('Cannot calculate a URI relative to another relative URI');
1681
1820
  }
1682
1821
 
1683
- // determine common sub path
1684
- common = URI.commonPath(relative.path(), base.path());
1685
-
1686
- // relative paths don't have authority
1687
- for (var i = 0, p; p = properties[i]; i++) {
1688
- relative._parts[p] = null;
1822
+ if (relativeParts.protocol === baseParts.protocol) {
1823
+ relativeParts.protocol = null;
1689
1824
  }
1690
1825
 
1691
- // no relation if there's nothing in common
1692
- if (common === '/') {
1693
- return relative;
1694
- } else if (!common) {
1695
- // there's absolutely nothing in common here
1696
- return this.clone();
1826
+ if (relativeParts.username !== baseParts.username || relativeParts.password !== baseParts.password) {
1827
+ return relative.build();
1697
1828
  }
1698
-
1699
- _base = base.directory();
1700
- _this = relative.directory();
1701
1829
 
1702
- // base and this are on the same level
1703
- if (_base === _this) {
1704
- relative._parts.path = relative.filename();
1830
+ if (relativeParts.protocol !== null || relativeParts.username !== null || relativeParts.password !== null) {
1705
1831
  return relative.build();
1706
1832
  }
1707
-
1708
- _base_diff = _base.substring(common.length);
1709
- _this_diff = _this.substring(common.length);
1710
-
1711
- // this is a descendant of base
1712
- if (_base + '/' === common) {
1713
- if (_this_diff) {
1714
- _this_diff += '/';
1715
- }
1716
-
1717
- relative._parts.path = _this_diff + relative.filename();
1833
+
1834
+ if (relativeParts.hostname === baseParts.hostname && relativeParts.port === baseParts.port) {
1835
+ relativeParts.hostname = null;
1836
+ relativeParts.port = null;
1837
+ } else {
1718
1838
  return relative.build();
1719
- }
1839
+ }
1720
1840
 
1721
- // this is a descendant of base
1722
- var parents = '../';
1723
- var _common = new RegExp('^' + escapeRegEx(common));
1724
- var _parents = _base.replace(_common, '/').match(/\//g).length -1;
1841
+ if (relativePath === basePath) {
1842
+ relativeParts.path = '';
1843
+ return relative.build();
1844
+ }
1845
+
1846
+ // determine common sub path
1847
+ common = URI.commonPath(relative.path(), base.path());
1725
1848
 
1726
- while (_parents--) {
1727
- parents += '../';
1849
+ // If the paths have nothing in common, return a relative URL with the absolute path.
1850
+ if (!common) {
1851
+ return relative.build();
1728
1852
  }
1729
1853
 
1730
- relative._parts.path = relative._parts.path.replace(_common, parents);
1854
+ var parents = baseParts.path
1855
+ .substring(common.length)
1856
+ .replace(/[^\/]*$/, '')
1857
+ .replace(/.*?\//g, '../');
1858
+
1859
+ relativeParts.path = parents + relativeParts.path.substring(common.length);
1860
+
1731
1861
  return relative.build();
1732
1862
  };
1733
1863
 
@@ -1759,13 +1889,13 @@ p.equals = function(uri) {
1759
1889
  return false;
1760
1890
  }
1761
1891
 
1762
- // query parameters have the same length, even if they're permutated
1892
+ // query parameters have the same length, even if they're permuted
1763
1893
  if (one_query.length !== two_query.length) {
1764
1894
  return false;
1765
1895
  }
1766
1896
 
1767
- one_map = URI.parseQuery(one_query);
1768
- two_map = URI.parseQuery(two_query);
1897
+ one_map = URI.parseQuery(one_query, this._parts.escapeQuerySpace);
1898
+ two_map = URI.parseQuery(two_query, this._parts.escapeQuerySpace);
1769
1899
 
1770
1900
  for (key in one_map) {
1771
1901
  if (hasOwn.call(one_map, key)) {
@@ -1799,5 +1929,10 @@ p.duplicateQueryParameters = function(v) {
1799
1929
  return this;
1800
1930
  };
1801
1931
 
1932
+ p.escapeQuerySpace = function(v) {
1933
+ this._parts.escapeQuerySpace = !!v;
1934
+ return this;
1935
+ };
1936
+
1802
1937
  return URI;
1803
- }));
1938
+ }));
@@ -2,7 +2,7 @@
2
2
  * URI.js - Mutating URLs
3
3
  * jQuery Plugin
4
4
  *
5
- * Version: 1.10.2
5
+ * Version: 1.11.2
6
6
  *
7
7
  * Author: Rodney Rehm
8
8
  * Web: http://medialize.github.com/URI.js/jquery-uri-plugin.html
@@ -67,30 +67,16 @@ function escapeRegEx(string) {
67
67
  }
68
68
 
69
69
  function getUriProperty(elem) {
70
- var property;
71
-
72
- // Note: IE9 will report img.href, so check img.src first (Issue #48)
73
- $.each(['src', 'href', 'action'], function(k, v) {
74
- if (v in elem ) {
75
- property = v;
76
- return false;
77
- }
78
-
79
- return true;
80
- });
81
-
82
- // compensate ambiguous <input>
83
- if (elem.nodeName.toLowerCase() === 'input' && elem.type !== 'image') {
70
+ var nodeName = elem.nodeName.toLowerCase();
71
+ var property = URI.domAttributes[nodeName];
72
+ if (nodeName === 'input' && elem.type !== 'image') {
73
+ // compensate ambiguous <input> that is not an image
84
74
  return undefined;
85
75
  }
86
76
 
87
- if (!property) {
88
- // you can set any property you wish. So for elements that don't have
89
- // either of [src, href, action] we simply return src.
90
- // https://github.com/medialize/URI.js/issues/69
91
- return 'src';
92
- }
93
-
77
+ // NOTE: as we use a static mapping from element to attribute,
78
+ // the HTML5 attribute issue should not come up again
79
+ // https://github.com/medialize/URI.js/issues/69
94
80
  return property;
95
81
  }
96
82
 
@@ -121,7 +107,7 @@ var _attrHooks = {
121
107
  return $(elem).uri().href(value).toString();
122
108
  }
123
109
  };
124
- $.each(['src', 'href', 'action', 'uri'], function(k, v) {
110
+ $.each(['src', 'href', 'action', 'uri', 'cite'], function(k, v) {
125
111
  $.attrHooks[v] = {
126
112
  set: _attrHooks.set
127
113
  };
@@ -135,7 +121,7 @@ $.fn.uri = function(uri) {
135
121
  var property = getUriProperty(elem);
136
122
 
137
123
  if (!property) {
138
- throw new Error('Element "' + elem.nodeName + '" does not have either property: href, src, action');
124
+ throw new Error('Element "' + elem.nodeName + '" does not have either property: href, src, action, cite');
139
125
  }
140
126
 
141
127
  if (uri !== undefined) {
@@ -145,14 +131,14 @@ $.fn.uri = function(uri) {
145
131
  }
146
132
 
147
133
  if (!(uri instanceof URI)) {
148
- uri = URI(uri);
134
+ uri = URI(uri || '');
149
135
  }
150
136
  } else {
151
137
  uri = $this.data('uri');
152
138
  if (uri) {
153
139
  return uri;
154
140
  } else {
155
- uri = URI($this.attr(property));
141
+ uri = URI($this.attr(property) || '');
156
142
  }
157
143
  }
158
144
 
@@ -243,4 +229,4 @@ $.expr[":"].uri = uriSizzle;
243
229
 
244
230
  // extending existing object rather than defining something new
245
231
  return {};
246
- }));
232
+ }));
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uri-js-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.2
4
+ version: 1.11.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robin Wenglewski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-16 00:00:00.000000000 Z
11
+ date: 2014-01-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: ''
14
14
  email:
@@ -47,9 +47,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
47
47
  version: '0'
48
48
  requirements: []
49
49
  rubyforge_project:
50
- rubygems_version: 2.0.3
50
+ rubygems_version: 2.1.11
51
51
  signing_key:
52
52
  specification_version: 4
53
53
  summary: URI.js for rails
54
54
  test_files: []
55
- has_rdoc: