AngularLocationWrapper.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import { deprecationWarning, urlUtil } from '@grafana/data';
  2. import { locationSearchToObject, locationService, navigationLogger } from '@grafana/runtime';
  3. // Ref: https://github.com/angular/angular.js/blob/ae8e903edf88a83fedd116ae02c0628bf72b150c/src/ng/location.js#L5
  4. const DEFAULT_PORTS: Record<string, number> = { http: 80, https: 443, ftp: 21 };
  5. export class AngularLocationWrapper {
  6. constructor() {
  7. this.absUrl = this.wrapInDeprecationWarning(this.absUrl);
  8. this.hash = this.wrapInDeprecationWarning(this.hash);
  9. this.host = this.wrapInDeprecationWarning(this.host);
  10. this.path = this.wrapInDeprecationWarning(this.path);
  11. this.port = this.wrapInDeprecationWarning(this.port, 'window.location');
  12. this.protocol = this.wrapInDeprecationWarning(this.protocol, 'window.location');
  13. this.replace = this.wrapInDeprecationWarning(this.replace);
  14. this.search = this.wrapInDeprecationWarning(this.search);
  15. this.state = this.wrapInDeprecationWarning(this.state);
  16. this.url = this.wrapInDeprecationWarning(this.url);
  17. }
  18. wrapInDeprecationWarning(fn: Function, replacement?: string) {
  19. let self = this;
  20. return function wrapper() {
  21. deprecationWarning('$location', fn.name, replacement || 'locationService');
  22. return fn.apply(self, arguments);
  23. };
  24. }
  25. absUrl(): string {
  26. return `${window.location.origin}${this.url()}`;
  27. }
  28. hash(newHash?: string | null) {
  29. navigationLogger('AngularLocationWrapper', false, 'Angular compat layer: hash');
  30. if (!newHash) {
  31. return locationService.getLocation().hash.slice(1);
  32. } else {
  33. throw new Error('AngularLocationWrapper method not implemented.');
  34. }
  35. }
  36. host(): string {
  37. return new URL(window.location.href).hostname;
  38. }
  39. path(pathname?: any) {
  40. navigationLogger('AngularLocationWrapper', false, 'Angular compat layer: path');
  41. const location = locationService.getLocation();
  42. if (pathname !== undefined && pathname !== null) {
  43. let parsedPath = String(pathname);
  44. parsedPath = parsedPath.startsWith('/') ? parsedPath : `/${parsedPath}`;
  45. const url = new URL(`${window.location.origin}${parsedPath}`);
  46. locationService.push({
  47. pathname: url.pathname,
  48. search: url.search.length > 0 ? url.search : location.search,
  49. hash: url.hash.length > 0 ? url.hash : location.hash,
  50. });
  51. return this;
  52. }
  53. if (pathname === null) {
  54. locationService.push('/');
  55. return this;
  56. }
  57. return location.pathname;
  58. }
  59. port(): number | null {
  60. const url = new URL(window.location.href);
  61. return parseInt(url.port, 10) || DEFAULT_PORTS[url.protocol] || null;
  62. }
  63. protocol(): string {
  64. return new URL(window.location.href).protocol.slice(0, -1);
  65. }
  66. replace() {
  67. throw new Error('AngularLocationWrapper method not implemented.');
  68. }
  69. search(search?: any, paramValue?: any) {
  70. navigationLogger('AngularLocationWrapper', false, 'Angular compat layer: search');
  71. if (!search) {
  72. return locationService.getSearchObject();
  73. }
  74. if (search && arguments.length > 1) {
  75. locationService.partial({
  76. [search]: paramValue,
  77. });
  78. return this;
  79. }
  80. if (search) {
  81. let newQuery;
  82. if (typeof search === 'object') {
  83. newQuery = { ...search };
  84. } else {
  85. newQuery = locationSearchToObject(search);
  86. }
  87. for (const key of Object.keys(newQuery)) {
  88. // removing params with null | undefined
  89. if (newQuery[key] === null || newQuery[key] === undefined) {
  90. delete newQuery[key];
  91. }
  92. }
  93. const updatedUrl = urlUtil.renderUrl(locationService.getLocation().pathname, newQuery);
  94. locationService.push(updatedUrl);
  95. }
  96. return this;
  97. }
  98. state(state?: any) {
  99. navigationLogger('AngularLocationWrapper', false, 'Angular compat layer: state');
  100. throw new Error('AngularLocationWrapper method not implemented.');
  101. }
  102. url(newUrl?: any) {
  103. navigationLogger('AngularLocationWrapper', false, 'Angular compat layer: url');
  104. if (newUrl !== undefined) {
  105. if (newUrl.startsWith('#')) {
  106. locationService.push({ ...locationService.getLocation(), hash: newUrl });
  107. } else if (newUrl.startsWith('?')) {
  108. locationService.push({ ...locationService.getLocation(), search: newUrl });
  109. } else if (newUrl.trim().length === 0) {
  110. locationService.push('/');
  111. } else {
  112. locationService.push(newUrl);
  113. }
  114. return locationService;
  115. }
  116. const location = locationService.getLocation();
  117. return `${location.pathname}${location.search}${location.hash}`;
  118. }
  119. }