parseKeyValue.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // tslint:disable
  2. // Most of this file is just a copy of some content from
  3. // https://github.com/angular/angular.js/blob/937fb891fa4fcf79e9fa02f8e0d517593e781077/src/Angular.js
  4. // Long term this code should be refactored to tru-type-script ;)
  5. // tslint disabled on purpose
  6. const getPrototypeOf = Object.getPrototypeOf;
  7. const toString = Object.prototype.toString;
  8. const hasOwnProperty = Object.prototype.hasOwnProperty;
  9. let jqLite: any;
  10. export function isArray(arr: any) {
  11. return Array.isArray(arr) || arr instanceof Array;
  12. }
  13. export function isError(value: any) {
  14. var tag = toString.call(value);
  15. switch (tag) {
  16. case '[object Error]':
  17. return true;
  18. case '[object Exception]':
  19. return true;
  20. case '[object DOMException]':
  21. return true;
  22. default:
  23. return value instanceof Error;
  24. }
  25. }
  26. export function isDate(value: any) {
  27. return toString.call(value) === '[object Date]';
  28. }
  29. export function isNumber(value: any) {
  30. return typeof value === 'number';
  31. }
  32. export function isString(value: any) {
  33. return typeof value === 'string';
  34. }
  35. export function isBlankObject(value: any) {
  36. return value !== null && typeof value === 'object' && !getPrototypeOf(value);
  37. }
  38. export function isObject(value: any) {
  39. // http://jsperf.com/isobject4
  40. return value !== null && typeof value === 'object';
  41. }
  42. export function isWindow(obj: { window: any }) {
  43. return obj && obj.window === obj;
  44. }
  45. export function isArrayLike(obj: any) {
  46. // `null`, `undefined` and `window` are not array-like
  47. if (obj == null || isWindow(obj)) {
  48. return false;
  49. }
  50. // arrays, strings and jQuery/jqLite objects are array like
  51. // * jqLite is either the jQuery or jqLite constructor function
  52. // * we have to check the existence of jqLite first as this method is called
  53. // via the forEach method when constructing the jqLite object in the first place
  54. if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) {
  55. return true;
  56. }
  57. // Support: iOS 8.2 (not reproducible in simulator)
  58. // "length" in obj used to prevent JIT error (gh-11508)
  59. var length = 'length' in Object(obj) && obj.length;
  60. // NodeList objects (with `item` method) and
  61. // other objects with suitable length characteristics are array-like
  62. return isNumber(length) && ((length >= 0 && length - 1 in obj) || typeof obj.item === 'function');
  63. }
  64. export function isFunction(value: any) {
  65. return typeof value === 'function';
  66. }
  67. export function forEach(obj: any, iterator: any, context?: any) {
  68. var key, length;
  69. if (obj) {
  70. if (isFunction(obj)) {
  71. for (key in obj) {
  72. if (key !== 'prototype' && key !== 'length' && key !== 'name' && obj.hasOwnProperty(key)) {
  73. iterator.call(context, obj[key], key, obj);
  74. }
  75. }
  76. } else if (isArray(obj) || isArrayLike(obj)) {
  77. var isPrimitive = typeof obj !== 'object';
  78. for (key = 0, length = obj.length; key < length; key++) {
  79. if (isPrimitive || key in obj) {
  80. iterator.call(context, obj[key], key, obj);
  81. }
  82. }
  83. } else if (obj.forEach && obj.forEach !== forEach) {
  84. obj.forEach(iterator, context, obj);
  85. } else if (isBlankObject(obj)) {
  86. // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
  87. for (key in obj) {
  88. iterator.call(context, obj[key], key, obj);
  89. }
  90. } else if (typeof obj.hasOwnProperty === 'function') {
  91. // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed
  92. for (key in obj) {
  93. if (obj.hasOwnProperty(key)) {
  94. iterator.call(context, obj[key], key, obj);
  95. }
  96. }
  97. } else {
  98. // Slow path for objects which do not have a method `hasOwnProperty`
  99. for (key in obj) {
  100. if (hasOwnProperty.call(obj, key)) {
  101. iterator.call(context, obj[key], key, obj);
  102. }
  103. }
  104. }
  105. }
  106. return obj;
  107. }
  108. export function tryDecodeURIComponent(value: string): string {
  109. try {
  110. return decodeURIComponent(value);
  111. } catch (e) {
  112. // Ignore any invalid uri component.
  113. return '';
  114. }
  115. }
  116. function parseKeyValue(keyValue: string | null) {
  117. var obj = {};
  118. forEach((keyValue || '').split('&'), function (keyValue: string) {
  119. var splitPoint, key, val;
  120. if (keyValue) {
  121. key = keyValue = keyValue.replace(/\+/g, '%20');
  122. splitPoint = keyValue.indexOf('=');
  123. if (splitPoint !== -1) {
  124. key = keyValue.substring(0, splitPoint);
  125. val = keyValue.substring(splitPoint + 1);
  126. }
  127. key = tryDecodeURIComponent(key);
  128. if (key) {
  129. val = val !== undefined ? tryDecodeURIComponent(val) : true;
  130. if (!hasOwnProperty.call(obj, key)) {
  131. // @ts-ignore
  132. obj[key] = val;
  133. // @ts-ignore
  134. } else if (isArray(obj[key])) {
  135. // @ts-ignore
  136. obj[key].push(val);
  137. } else {
  138. // @ts-ignore
  139. obj[key] = [obj[key], val];
  140. }
  141. }
  142. }
  143. });
  144. return obj;
  145. }
  146. export default parseKeyValue;
  147. // tslint:enable