PageRenderTime 21ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/tutorial/node_modules/@angular/router/src/url_tree.js

https://gitlab.com/adriancarayol/django-angular2
JavaScript | 446 lines | 406 code | 0 blank | 40 comment | 83 complexity | 4a7f9cb7ee3fedb77f1f1d7ffd063e7f MD5 | raw file
  1. /**
  2. * @license
  3. * Copyright Google Inc. All Rights Reserved.
  4. *
  5. * Use of this source code is governed by an MIT-style license that can be
  6. * found in the LICENSE file at https://angular.io/license
  7. */
  8. "use strict";
  9. var shared_1 = require('./shared');
  10. var collection_1 = require('./utils/collection');
  11. function createEmptyUrlTree() {
  12. return new UrlTree(new UrlSegmentGroup([], {}), {}, null);
  13. }
  14. exports.createEmptyUrlTree = createEmptyUrlTree;
  15. function containsTree(container, containee, exact) {
  16. if (exact) {
  17. return equalSegmentGroups(container.root, containee.root);
  18. }
  19. else {
  20. return containsSegmentGroup(container.root, containee.root);
  21. }
  22. }
  23. exports.containsTree = containsTree;
  24. function equalSegmentGroups(container, containee) {
  25. if (!equalPath(container.segments, containee.segments))
  26. return false;
  27. if (container.numberOfChildren !== containee.numberOfChildren)
  28. return false;
  29. for (var c in containee.children) {
  30. if (!container.children[c])
  31. return false;
  32. if (!equalSegmentGroups(container.children[c], containee.children[c]))
  33. return false;
  34. }
  35. return true;
  36. }
  37. function containsSegmentGroup(container, containee) {
  38. return containsSegmentGroupHelper(container, containee, containee.segments);
  39. }
  40. function containsSegmentGroupHelper(container, containee, containeePaths) {
  41. if (container.segments.length > containeePaths.length) {
  42. var current = container.segments.slice(0, containeePaths.length);
  43. if (!equalPath(current, containeePaths))
  44. return false;
  45. if (containee.hasChildren())
  46. return false;
  47. return true;
  48. }
  49. else if (container.segments.length === containeePaths.length) {
  50. if (!equalPath(container.segments, containeePaths))
  51. return false;
  52. for (var c in containee.children) {
  53. if (!container.children[c])
  54. return false;
  55. if (!containsSegmentGroup(container.children[c], containee.children[c]))
  56. return false;
  57. }
  58. return true;
  59. }
  60. else {
  61. var current = containeePaths.slice(0, container.segments.length);
  62. var next = containeePaths.slice(container.segments.length);
  63. if (!equalPath(container.segments, current))
  64. return false;
  65. if (!container.children[shared_1.PRIMARY_OUTLET])
  66. return false;
  67. return containsSegmentGroupHelper(container.children[shared_1.PRIMARY_OUTLET], containee, next);
  68. }
  69. }
  70. /**
  71. * A URL in the tree form.
  72. *
  73. * @stable
  74. */
  75. var UrlTree = (function () {
  76. /**
  77. * @internal
  78. */
  79. function UrlTree(root, queryParams, fragment) {
  80. this.root = root;
  81. this.queryParams = queryParams;
  82. this.fragment = fragment;
  83. }
  84. UrlTree.prototype.toString = function () { return new DefaultUrlSerializer().serialize(this); };
  85. return UrlTree;
  86. }());
  87. exports.UrlTree = UrlTree;
  88. /**
  89. * @stable
  90. */
  91. var UrlSegmentGroup = (function () {
  92. function UrlSegmentGroup(segments, children) {
  93. var _this = this;
  94. this.segments = segments;
  95. this.children = children;
  96. this.parent = null;
  97. collection_1.forEach(children, function (v, k) { return v.parent = _this; });
  98. }
  99. /**
  100. * Return true if the segment has child segments
  101. */
  102. UrlSegmentGroup.prototype.hasChildren = function () { return this.numberOfChildren > 0; };
  103. Object.defineProperty(UrlSegmentGroup.prototype, "numberOfChildren", {
  104. /**
  105. * Returns the number of child sements.
  106. */
  107. get: function () { return Object.keys(this.children).length; },
  108. enumerable: true,
  109. configurable: true
  110. });
  111. UrlSegmentGroup.prototype.toString = function () { return serializePaths(this); };
  112. return UrlSegmentGroup;
  113. }());
  114. exports.UrlSegmentGroup = UrlSegmentGroup;
  115. /**
  116. * @stable
  117. */
  118. var UrlSegment = (function () {
  119. function UrlSegment(path, parameters) {
  120. this.path = path;
  121. this.parameters = parameters;
  122. }
  123. UrlSegment.prototype.toString = function () { return serializePath(this); };
  124. return UrlSegment;
  125. }());
  126. exports.UrlSegment = UrlSegment;
  127. function equalSegments(a, b) {
  128. if (a.length !== b.length)
  129. return false;
  130. for (var i = 0; i < a.length; ++i) {
  131. if (a[i].path !== b[i].path)
  132. return false;
  133. if (!collection_1.shallowEqual(a[i].parameters, b[i].parameters))
  134. return false;
  135. }
  136. return true;
  137. }
  138. exports.equalSegments = equalSegments;
  139. function equalPath(a, b) {
  140. if (a.length !== b.length)
  141. return false;
  142. for (var i = 0; i < a.length; ++i) {
  143. if (a[i].path !== b[i].path)
  144. return false;
  145. }
  146. return true;
  147. }
  148. exports.equalPath = equalPath;
  149. function mapChildrenIntoArray(segment, fn) {
  150. var res = [];
  151. collection_1.forEach(segment.children, function (child, childOutlet) {
  152. if (childOutlet === shared_1.PRIMARY_OUTLET) {
  153. res = res.concat(fn(child, childOutlet));
  154. }
  155. });
  156. collection_1.forEach(segment.children, function (child, childOutlet) {
  157. if (childOutlet !== shared_1.PRIMARY_OUTLET) {
  158. res = res.concat(fn(child, childOutlet));
  159. }
  160. });
  161. return res;
  162. }
  163. exports.mapChildrenIntoArray = mapChildrenIntoArray;
  164. /**
  165. * Defines a way to serialize/deserialize a url tree.
  166. *
  167. * @experimental
  168. */
  169. var UrlSerializer = (function () {
  170. function UrlSerializer() {
  171. }
  172. return UrlSerializer;
  173. }());
  174. exports.UrlSerializer = UrlSerializer;
  175. /**
  176. * A default implementation of the serialization.
  177. *
  178. * @experimental
  179. */
  180. var DefaultUrlSerializer = (function () {
  181. function DefaultUrlSerializer() {
  182. }
  183. DefaultUrlSerializer.prototype.parse = function (url) {
  184. var p = new UrlParser(url);
  185. return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment());
  186. };
  187. DefaultUrlSerializer.prototype.serialize = function (tree) {
  188. var segment = "/" + serializeSegment(tree.root, true);
  189. var query = serializeQueryParams(tree.queryParams);
  190. var fragment = tree.fragment !== null && tree.fragment !== undefined ?
  191. "#" + encodeURIComponent(tree.fragment) :
  192. '';
  193. return "" + segment + query + fragment;
  194. };
  195. return DefaultUrlSerializer;
  196. }());
  197. exports.DefaultUrlSerializer = DefaultUrlSerializer;
  198. function serializePaths(segment) {
  199. return segment.segments.map(function (p) { return serializePath(p); }).join('/');
  200. }
  201. exports.serializePaths = serializePaths;
  202. function serializeSegment(segment, root) {
  203. if (segment.hasChildren() && root) {
  204. var primary = segment.children[shared_1.PRIMARY_OUTLET] ?
  205. serializeSegment(segment.children[shared_1.PRIMARY_OUTLET], false) :
  206. '';
  207. var children_1 = [];
  208. collection_1.forEach(segment.children, function (v, k) {
  209. if (k !== shared_1.PRIMARY_OUTLET) {
  210. children_1.push(k + ":" + serializeSegment(v, false));
  211. }
  212. });
  213. if (children_1.length > 0) {
  214. return primary + "(" + children_1.join('//') + ")";
  215. }
  216. else {
  217. return "" + primary;
  218. }
  219. }
  220. else if (segment.hasChildren() && !root) {
  221. var children = mapChildrenIntoArray(segment, function (v, k) {
  222. if (k === shared_1.PRIMARY_OUTLET) {
  223. return [serializeSegment(segment.children[shared_1.PRIMARY_OUTLET], false)];
  224. }
  225. else {
  226. return [(k + ":" + serializeSegment(v, false))];
  227. }
  228. });
  229. return serializePaths(segment) + "/(" + children.join('//') + ")";
  230. }
  231. else {
  232. return serializePaths(segment);
  233. }
  234. }
  235. function encode(s) {
  236. return encodeURIComponent(s);
  237. }
  238. exports.encode = encode;
  239. function decode(s) {
  240. return decodeURIComponent(s);
  241. }
  242. exports.decode = decode;
  243. function serializePath(path) {
  244. return "" + encode(path.path) + serializeParams(path.parameters);
  245. }
  246. exports.serializePath = serializePath;
  247. function serializeParams(params) {
  248. return pairs(params).map(function (p) { return (";" + encode(p.first) + "=" + encode(p.second)); }).join('');
  249. }
  250. function serializeQueryParams(params) {
  251. var strs = pairs(params).map(function (p) { return (encode(p.first) + "=" + encode(p.second)); });
  252. return strs.length > 0 ? "?" + strs.join("&") : '';
  253. }
  254. var Pair = (function () {
  255. function Pair(first, second) {
  256. this.first = first;
  257. this.second = second;
  258. }
  259. return Pair;
  260. }());
  261. function pairs(obj) {
  262. var res = [];
  263. for (var prop in obj) {
  264. if (obj.hasOwnProperty(prop)) {
  265. res.push(new Pair(prop, obj[prop]));
  266. }
  267. }
  268. return res;
  269. }
  270. var SEGMENT_RE = /^[^\/\(\)\?;=&#]+/;
  271. function matchSegments(str) {
  272. SEGMENT_RE.lastIndex = 0;
  273. var match = str.match(SEGMENT_RE);
  274. return match ? match[0] : '';
  275. }
  276. var QUERY_PARAM_RE = /^[^=\?&#]+/;
  277. function matchQueryParams(str) {
  278. QUERY_PARAM_RE.lastIndex = 0;
  279. var match = str.match(SEGMENT_RE);
  280. return match ? match[0] : '';
  281. }
  282. var QUERY_PARAM_VALUE_RE = /^[^\?&#]+/;
  283. function matchUrlQueryParamValue(str) {
  284. QUERY_PARAM_VALUE_RE.lastIndex = 0;
  285. var match = str.match(QUERY_PARAM_VALUE_RE);
  286. return match ? match[0] : '';
  287. }
  288. var UrlParser = (function () {
  289. function UrlParser(url) {
  290. this.url = url;
  291. this.remaining = url;
  292. }
  293. UrlParser.prototype.peekStartsWith = function (str) { return this.remaining.startsWith(str); };
  294. UrlParser.prototype.capture = function (str) {
  295. if (!this.remaining.startsWith(str)) {
  296. throw new Error("Expected \"" + str + "\".");
  297. }
  298. this.remaining = this.remaining.substring(str.length);
  299. };
  300. UrlParser.prototype.parseRootSegment = function () {
  301. if (this.remaining.startsWith('/')) {
  302. this.capture('/');
  303. }
  304. if (this.remaining === '' || this.remaining.startsWith('?') || this.remaining.startsWith('#')) {
  305. return new UrlSegmentGroup([], {});
  306. }
  307. else {
  308. return new UrlSegmentGroup([], this.parseChildren());
  309. }
  310. };
  311. UrlParser.prototype.parseChildren = function () {
  312. if (this.remaining.length == 0) {
  313. return {};
  314. }
  315. if (this.peekStartsWith('/')) {
  316. this.capture('/');
  317. }
  318. var paths = [];
  319. if (!this.peekStartsWith('(')) {
  320. paths.push(this.parseSegments());
  321. }
  322. while (this.peekStartsWith('/') && !this.peekStartsWith('//') && !this.peekStartsWith('/(')) {
  323. this.capture('/');
  324. paths.push(this.parseSegments());
  325. }
  326. var children = {};
  327. if (this.peekStartsWith('/(')) {
  328. this.capture('/');
  329. children = this.parseParens(true);
  330. }
  331. var res = {};
  332. if (this.peekStartsWith('(')) {
  333. res = this.parseParens(false);
  334. }
  335. if (paths.length > 0 || Object.keys(children).length > 0) {
  336. res[shared_1.PRIMARY_OUTLET] = new UrlSegmentGroup(paths, children);
  337. }
  338. return res;
  339. };
  340. UrlParser.prototype.parseSegments = function () {
  341. var path = matchSegments(this.remaining);
  342. if (path === '' && this.peekStartsWith(';')) {
  343. throw new Error("Empty path url segment cannot have parameters: '" + this.remaining + "'.");
  344. }
  345. this.capture(path);
  346. var matrixParams = {};
  347. if (this.peekStartsWith(';')) {
  348. matrixParams = this.parseMatrixParams();
  349. }
  350. return new UrlSegment(decode(path), matrixParams);
  351. };
  352. UrlParser.prototype.parseQueryParams = function () {
  353. var params = {};
  354. if (this.peekStartsWith('?')) {
  355. this.capture('?');
  356. this.parseQueryParam(params);
  357. while (this.remaining.length > 0 && this.peekStartsWith('&')) {
  358. this.capture('&');
  359. this.parseQueryParam(params);
  360. }
  361. }
  362. return params;
  363. };
  364. UrlParser.prototype.parseFragment = function () {
  365. if (this.peekStartsWith('#')) {
  366. return decode(this.remaining.substring(1));
  367. }
  368. else {
  369. return null;
  370. }
  371. };
  372. UrlParser.prototype.parseMatrixParams = function () {
  373. var params = {};
  374. while (this.remaining.length > 0 && this.peekStartsWith(';')) {
  375. this.capture(';');
  376. this.parseParam(params);
  377. }
  378. return params;
  379. };
  380. UrlParser.prototype.parseParam = function (params) {
  381. var key = matchSegments(this.remaining);
  382. if (!key) {
  383. return;
  384. }
  385. this.capture(key);
  386. var value = 'true';
  387. if (this.peekStartsWith('=')) {
  388. this.capture('=');
  389. var valueMatch = matchSegments(this.remaining);
  390. if (valueMatch) {
  391. value = valueMatch;
  392. this.capture(value);
  393. }
  394. }
  395. params[decode(key)] = decode(value);
  396. };
  397. UrlParser.prototype.parseQueryParam = function (params) {
  398. var key = matchQueryParams(this.remaining);
  399. if (!key) {
  400. return;
  401. }
  402. this.capture(key);
  403. var value = '';
  404. if (this.peekStartsWith('=')) {
  405. this.capture('=');
  406. var valueMatch = matchUrlQueryParamValue(this.remaining);
  407. if (valueMatch) {
  408. value = valueMatch;
  409. this.capture(value);
  410. }
  411. }
  412. params[decode(key)] = decode(value);
  413. };
  414. UrlParser.prototype.parseParens = function (allowPrimary) {
  415. var segments = {};
  416. this.capture('(');
  417. while (!this.peekStartsWith(')') && this.remaining.length > 0) {
  418. var path = matchSegments(this.remaining);
  419. var next = this.remaining[path.length];
  420. // if is is not one of these characters, then the segment was unescaped
  421. // or the group was not closed
  422. if (next !== '/' && next !== ')' && next !== ';') {
  423. throw new Error("Cannot parse url '" + this.url + "'");
  424. }
  425. var outletName = void 0;
  426. if (path.indexOf(':') > -1) {
  427. outletName = path.substr(0, path.indexOf(':'));
  428. this.capture(outletName);
  429. this.capture(':');
  430. }
  431. else if (allowPrimary) {
  432. outletName = shared_1.PRIMARY_OUTLET;
  433. }
  434. var children = this.parseChildren();
  435. segments[outletName] = Object.keys(children).length === 1 ? children[shared_1.PRIMARY_OUTLET] :
  436. new UrlSegmentGroup([], children);
  437. if (this.peekStartsWith('//')) {
  438. this.capture('//');
  439. }
  440. }
  441. this.capture(')');
  442. return segments;
  443. };
  444. return UrlParser;
  445. }());
  446. //# sourceMappingURL=url_tree.js.map