file-manager.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*global window, XMLHttpRequest */
  2. module.exports = function(options, logger) {
  3. var AbstractFileManager = require("../less/environment/abstract-file-manager.js");
  4. var fileCache = {};
  5. //TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load
  6. function getXMLHttpRequest() {
  7. if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !("ActiveXObject" in window))) {
  8. return new XMLHttpRequest();
  9. } else {
  10. try {
  11. /*global ActiveXObject */
  12. return new ActiveXObject("Microsoft.XMLHTTP");
  13. } catch (e) {
  14. logger.error("browser doesn't support AJAX.");
  15. return null;
  16. }
  17. }
  18. }
  19. var FileManager = function() {
  20. };
  21. FileManager.prototype = new AbstractFileManager();
  22. FileManager.prototype.alwaysMakePathsAbsolute = function alwaysMakePathsAbsolute() {
  23. return true;
  24. };
  25. FileManager.prototype.join = function join(basePath, laterPath) {
  26. if (!basePath) {
  27. return laterPath;
  28. }
  29. return this.extractUrlParts(laterPath, basePath).path;
  30. };
  31. FileManager.prototype.doXHR = function doXHR(url, type, callback, errback) {
  32. var xhr = getXMLHttpRequest();
  33. var async = options.isFileProtocol ? options.fileAsync : true;
  34. if (typeof xhr.overrideMimeType === 'function') {
  35. xhr.overrideMimeType('text/css');
  36. }
  37. logger.debug("XHR: Getting '" + url + "'");
  38. xhr.open('GET', url, async);
  39. xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
  40. xhr.send(null);
  41. function handleResponse(xhr, callback, errback) {
  42. if (xhr.status >= 200 && xhr.status < 300) {
  43. callback(xhr.responseText,
  44. xhr.getResponseHeader("Last-Modified"));
  45. } else if (typeof errback === 'function') {
  46. errback(xhr.status, url);
  47. }
  48. }
  49. if (options.isFileProtocol && !options.fileAsync) {
  50. if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
  51. callback(xhr.responseText);
  52. } else {
  53. errback(xhr.status, url);
  54. }
  55. } else if (async) {
  56. xhr.onreadystatechange = function () {
  57. if (xhr.readyState == 4) {
  58. handleResponse(xhr, callback, errback);
  59. }
  60. };
  61. } else {
  62. handleResponse(xhr, callback, errback);
  63. }
  64. };
  65. FileManager.prototype.supports = function(filename, currentDirectory, options, environment) {
  66. return true;
  67. };
  68. FileManager.prototype.clearFileCache = function() {
  69. fileCache = {};
  70. };
  71. FileManager.prototype.loadFile = function loadFile(filename, currentDirectory, options, environment, callback) {
  72. if (currentDirectory && !this.isPathAbsolute(filename)) {
  73. filename = currentDirectory + filename;
  74. }
  75. options = options || {};
  76. // sheet may be set to the stylesheet for the initial load or a collection of properties including
  77. // some context variables for imports
  78. var hrefParts = this.extractUrlParts(filename, window.location.href);
  79. var href = hrefParts.url;
  80. if (options.useFileCache && fileCache[href]) {
  81. try {
  82. var lessText = fileCache[href];
  83. callback(null, { contents: lessText, filename: href, webInfo: { lastModified: new Date() }});
  84. } catch (e) {
  85. callback({filename: href, message: "Error loading file " + href + " error was " + e.message});
  86. }
  87. return;
  88. }
  89. this.doXHR(href, options.mime, function doXHRCallback(data, lastModified) {
  90. // per file cache
  91. fileCache[href] = data;
  92. // Use remote copy (re-parse)
  93. callback(null, { contents: data, filename: href, webInfo: { lastModified: lastModified }});
  94. }, function doXHRError(status, url) {
  95. callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")", href: href });
  96. });
  97. };
  98. return FileManager;
  99. };