/*global window, XMLHttpRequest */ module.exports = function(options, logger) { var AbstractFileManager = require("../less/environment/abstract-file-manager.js"); var fileCache = {}; //TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load function getXMLHttpRequest() { if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !("ActiveXObject" in window))) { return new XMLHttpRequest(); } else { try { /*global ActiveXObject */ return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { logger.error("browser doesn't support AJAX."); return null; } } } var FileManager = function() { }; FileManager.prototype = new AbstractFileManager(); FileManager.prototype.alwaysMakePathsAbsolute = function alwaysMakePathsAbsolute() { return true; }; FileManager.prototype.join = function join(basePath, laterPath) { if (!basePath) { return laterPath; } return this.extractUrlParts(laterPath, basePath).path; }; FileManager.prototype.doXHR = function doXHR(url, type, callback, errback) { var xhr = getXMLHttpRequest(); var async = options.isFileProtocol ? options.fileAsync : true; if (typeof xhr.overrideMimeType === 'function') { xhr.overrideMimeType('text/css'); } logger.debug("XHR: Getting '" + url + "'"); xhr.open('GET', url, async); xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5'); xhr.send(null); function handleResponse(xhr, callback, errback) { if (xhr.status >= 200 && xhr.status < 300) { callback(xhr.responseText, xhr.getResponseHeader("Last-Modified")); } else if (typeof errback === 'function') { errback(xhr.status, url); } } if (options.isFileProtocol && !options.fileAsync) { if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) { callback(xhr.responseText); } else { errback(xhr.status, url); } } else if (async) { xhr.onreadystatechange = function () { if (xhr.readyState == 4) { handleResponse(xhr, callback, errback); } }; } else { handleResponse(xhr, callback, errback); } }; FileManager.prototype.supports = function(filename, currentDirectory, options, environment) { return true; }; FileManager.prototype.clearFileCache = function() { fileCache = {}; }; FileManager.prototype.loadFile = function loadFile(filename, currentDirectory, options, environment, callback) { if (currentDirectory && !this.isPathAbsolute(filename)) { filename = currentDirectory + filename; } options = options || {}; // sheet may be set to the stylesheet for the initial load or a collection of properties including // some context variables for imports var hrefParts = this.extractUrlParts(filename, window.location.href); var href = hrefParts.url; if (options.useFileCache && fileCache[href]) { try { var lessText = fileCache[href]; callback(null, { contents: lessText, filename: href, webInfo: { lastModified: new Date() }}); } catch (e) { callback({filename: href, message: "Error loading file " + href + " error was " + e.message}); } return; } this.doXHR(href, options.mime, function doXHRCallback(data, lastModified) { // per file cache fileCache[href] = data; // Use remote copy (re-parse) callback(null, { contents: data, filename: href, webInfo: { lastModified: lastModified }}); }, function doXHRError(status, url) { callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")", href: href }); }); }; return FileManager; };