resources.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import * as extpath from './extpath.js';
  6. import { Schemas } from './network.js';
  7. import * as paths from './path.js';
  8. import { compare as strCompare } from './strings.js';
  9. import { URI, uriToFsPath } from './uri.js';
  10. export function originalFSPath(uri) {
  11. return uriToFsPath(uri, true);
  12. }
  13. export class ExtUri {
  14. constructor(_ignorePathCasing) {
  15. this._ignorePathCasing = _ignorePathCasing;
  16. }
  17. compare(uri1, uri2, ignoreFragment = false) {
  18. if (uri1 === uri2) {
  19. return 0;
  20. }
  21. return strCompare(this.getComparisonKey(uri1, ignoreFragment), this.getComparisonKey(uri2, ignoreFragment));
  22. }
  23. isEqual(uri1, uri2, ignoreFragment = false) {
  24. if (uri1 === uri2) {
  25. return true;
  26. }
  27. if (!uri1 || !uri2) {
  28. return false;
  29. }
  30. return this.getComparisonKey(uri1, ignoreFragment) === this.getComparisonKey(uri2, ignoreFragment);
  31. }
  32. getComparisonKey(uri, ignoreFragment = false) {
  33. return uri.with({
  34. path: this._ignorePathCasing(uri) ? uri.path.toLowerCase() : undefined,
  35. fragment: ignoreFragment ? null : undefined
  36. }).toString();
  37. }
  38. // --- path math
  39. joinPath(resource, ...pathFragment) {
  40. return URI.joinPath(resource, ...pathFragment);
  41. }
  42. basenameOrAuthority(resource) {
  43. return basename(resource) || resource.authority;
  44. }
  45. basename(resource) {
  46. return paths.posix.basename(resource.path);
  47. }
  48. dirname(resource) {
  49. if (resource.path.length === 0) {
  50. return resource;
  51. }
  52. let dirname;
  53. if (resource.scheme === Schemas.file) {
  54. dirname = URI.file(paths.dirname(originalFSPath(resource))).path;
  55. }
  56. else {
  57. dirname = paths.posix.dirname(resource.path);
  58. if (resource.authority && dirname.length && dirname.charCodeAt(0) !== 47 /* Slash */) {
  59. console.error(`dirname("${resource.toString})) resulted in a relative path`);
  60. dirname = '/'; // If a URI contains an authority component, then the path component must either be empty or begin with a CharCode.Slash ("/") character
  61. }
  62. }
  63. return resource.with({
  64. path: dirname
  65. });
  66. }
  67. normalizePath(resource) {
  68. if (!resource.path.length) {
  69. return resource;
  70. }
  71. let normalizedPath;
  72. if (resource.scheme === Schemas.file) {
  73. normalizedPath = URI.file(paths.normalize(originalFSPath(resource))).path;
  74. }
  75. else {
  76. normalizedPath = paths.posix.normalize(resource.path);
  77. }
  78. return resource.with({
  79. path: normalizedPath
  80. });
  81. }
  82. resolvePath(base, path) {
  83. if (base.scheme === Schemas.file) {
  84. const newURI = URI.file(paths.resolve(originalFSPath(base), path));
  85. return base.with({
  86. authority: newURI.authority,
  87. path: newURI.path
  88. });
  89. }
  90. path = extpath.toPosixPath(path); // we allow path to be a windows path
  91. return base.with({
  92. path: paths.posix.resolve(base.path, path)
  93. });
  94. }
  95. }
  96. /**
  97. * Unbiased utility that takes uris "as they are". This means it can be interchanged with
  98. * uri#toString() usages. The following is true
  99. * ```
  100. * assertEqual(aUri.toString() === bUri.toString(), exturi.isEqual(aUri, bUri))
  101. * ```
  102. */
  103. export const extUri = new ExtUri(() => false);
  104. export const isEqual = extUri.isEqual.bind(extUri);
  105. export const basenameOrAuthority = extUri.basenameOrAuthority.bind(extUri);
  106. export const basename = extUri.basename.bind(extUri);
  107. export const dirname = extUri.dirname.bind(extUri);
  108. export const joinPath = extUri.joinPath.bind(extUri);
  109. export const normalizePath = extUri.normalizePath.bind(extUri);
  110. export const resolvePath = extUri.resolvePath.bind(extUri);
  111. /**
  112. * Data URI related helpers.
  113. */
  114. export var DataUri;
  115. (function (DataUri) {
  116. DataUri.META_DATA_LABEL = 'label';
  117. DataUri.META_DATA_DESCRIPTION = 'description';
  118. DataUri.META_DATA_SIZE = 'size';
  119. DataUri.META_DATA_MIME = 'mime';
  120. function parseMetaData(dataUri) {
  121. const metadata = new Map();
  122. // Given a URI of: data:image/png;size:2313;label:SomeLabel;description:SomeDescription;base64,77+9UE5...
  123. // the metadata is: size:2313;label:SomeLabel;description:SomeDescription
  124. const meta = dataUri.path.substring(dataUri.path.indexOf(';') + 1, dataUri.path.lastIndexOf(';'));
  125. meta.split(';').forEach(property => {
  126. const [key, value] = property.split(':');
  127. if (key && value) {
  128. metadata.set(key, value);
  129. }
  130. });
  131. // Given a URI of: data:image/png;size:2313;label:SomeLabel;description:SomeDescription;base64,77+9UE5...
  132. // the mime is: image/png
  133. const mime = dataUri.path.substring(0, dataUri.path.indexOf(';'));
  134. if (mime) {
  135. metadata.set(DataUri.META_DATA_MIME, mime);
  136. }
  137. return metadata;
  138. }
  139. DataUri.parseMetaData = parseMetaData;
  140. })(DataUri || (DataUri = {}));