baseUrlResolver.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /**
  2. * Copyright © Magento, Inc. All rights reserved.
  3. * See COPYING.txt for license details.
  4. */
  5. /**
  6. * Sample configuration:
  7. *
  8. require.config({
  9. "config": {
  10. "baseUrlInterceptor": {
  11. "Magento_Ui/js/lib/knockout/bindings/collapsible.js": "../../../../frontend/Magento/luma/en_US/"
  12. }
  13. }
  14. });
  15. */
  16. /* global jsSuffixRegExp */
  17. /* eslint-disable max-depth */
  18. define('baseUrlInterceptor', [
  19. 'module'
  20. ], function (module) {
  21. 'use strict';
  22. /**
  23. * RequireJS Context object
  24. */
  25. var ctx = require.s.contexts._,
  26. /**
  27. * Original function
  28. *
  29. * @type {Function}
  30. */
  31. origNameToUrl = ctx.nameToUrl,
  32. /**
  33. * Original function
  34. *
  35. * @type {Function}
  36. */
  37. newContextConstr = require.s.newContext;
  38. /**
  39. * Remove dots from URL
  40. *
  41. * @param {Array} ary
  42. */
  43. function trimDots(ary) {
  44. var i, part, length = ary.length;
  45. for (i = 0; i < length; i++) {
  46. part = ary[i];
  47. if (part === '.') {
  48. ary.splice(i, 1);
  49. i -= 1;
  50. } else if (part === '..') {
  51. if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
  52. //End of the line. Keep at least one non-dot
  53. //path segment at the front so it can be mapped
  54. //correctly to disk. Otherwise, there is likely
  55. //no path mapping for a path starting with '..'.
  56. //This can still fail, but catches the most reasonable
  57. //uses of ..
  58. break;
  59. } else if (i > 0) {
  60. ary.splice(i - 1, 2);
  61. i -= 2;
  62. }
  63. }
  64. }
  65. }
  66. /**
  67. * Normalize URL string (remove '/../')
  68. *
  69. * @param {String} name
  70. * @param {String} baseName
  71. * @param {Object} applyMap
  72. * @param {Object} localContext
  73. * @returns {*}
  74. */
  75. function normalize(name, baseName, applyMap, localContext) {
  76. var lastIndex,
  77. baseParts = baseName && baseName.split('/'),
  78. normalizedBaseParts = baseParts;
  79. //Adjust any relative paths.
  80. if (name && name.charAt(0) === '.') {
  81. //If have a base name, try to normalize against it,
  82. //otherwise, assume it is a top-level require that will
  83. //be relative to baseUrl in the end.
  84. if (baseName) {
  85. //Convert baseName to array, and lop off the last part,
  86. //so that . matches that 'directory' and not name of the baseName's
  87. //module. For instance, baseName of 'one/two/three', maps to
  88. //'one/two/three.js', but we want the directory, 'one/two' for
  89. //this normalization.
  90. normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
  91. name = name.split('/');
  92. lastIndex = name.length - 1;
  93. // If wanting node ID compatibility, strip .js from end
  94. // of IDs. Have to do this here, and not in nameToUrl
  95. // because node allows either .js or non .js to map
  96. // to same file.
  97. if (localContext.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
  98. name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
  99. }
  100. name = normalizedBaseParts.concat(name);
  101. trimDots(name);
  102. name = name.join('/');
  103. } else if (name.indexOf('./') === 0) {
  104. // No baseName, so this is ID is resolved relative
  105. // to baseUrl, pull off the leading dot.
  106. name = name.substring(2);
  107. }
  108. }
  109. return name;
  110. }
  111. /**
  112. * Get full url.
  113. *
  114. * @param {Object} context
  115. * @param {String} url
  116. * @return {String}
  117. */
  118. function getUrl(context, url) {
  119. var baseUrl = context.config.baseUrl,
  120. newConfig = context.config,
  121. modulePath = url.replace(baseUrl, ''),
  122. newBaseUrl,
  123. rewrite = module.config()[modulePath];
  124. if (!rewrite) {
  125. return url;
  126. }
  127. newBaseUrl = normalize(rewrite, baseUrl, undefined, newConfig);
  128. return newBaseUrl + modulePath;
  129. }
  130. /**
  131. * Replace original function.
  132. *
  133. * @returns {*}
  134. */
  135. ctx.nameToUrl = function () {
  136. return getUrl(ctx, origNameToUrl.apply(ctx, arguments));
  137. };
  138. /**
  139. * Replace original function.
  140. *
  141. * @return {*}
  142. */
  143. require.s.newContext = function () {
  144. var newCtx = newContextConstr.apply(require.s, arguments),
  145. newOrigNameToUrl = newCtx.nameToUrl;
  146. /**
  147. * New implementation of native function.
  148. *
  149. * @returns {String}
  150. */
  151. newCtx.nameToUrl = function () {
  152. return getUrl(newCtx, newOrigNameToUrl.apply(newCtx, arguments));
  153. };
  154. return newCtx;
  155. };
  156. });
  157. require(['baseUrlInterceptor'], function () {
  158. 'use strict';
  159. });