index.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var tslib_1 = require("tslib");
  4. //
  5. // index.js
  6. // Should expose the additional browser functions on to the less object
  7. //
  8. var utils_1 = require("./utils");
  9. var less_1 = tslib_1.__importDefault(require("../less"));
  10. var browser_1 = tslib_1.__importDefault(require("./browser"));
  11. var file_manager_1 = tslib_1.__importDefault(require("./file-manager"));
  12. var plugin_loader_1 = tslib_1.__importDefault(require("./plugin-loader"));
  13. var log_listener_1 = tslib_1.__importDefault(require("./log-listener"));
  14. var error_reporting_1 = tslib_1.__importDefault(require("./error-reporting"));
  15. var cache_1 = tslib_1.__importDefault(require("./cache"));
  16. var image_size_1 = tslib_1.__importDefault(require("./image-size"));
  17. exports.default = (function (window, options) {
  18. var document = window.document;
  19. var less = less_1.default();
  20. less.options = options;
  21. var environment = less.environment;
  22. var FileManager = file_manager_1.default(options, less.logger);
  23. var fileManager = new FileManager();
  24. environment.addFileManager(fileManager);
  25. less.FileManager = FileManager;
  26. less.PluginLoader = plugin_loader_1.default;
  27. log_listener_1.default(less, options);
  28. var errors = error_reporting_1.default(window, less, options);
  29. var cache = less.cache = options.cache || cache_1.default(window, options, less.logger);
  30. image_size_1.default(less.environment);
  31. // Setup user functions - Deprecate?
  32. if (options.functions) {
  33. less.functions.functionRegistry.addMultiple(options.functions);
  34. }
  35. var typePattern = /^text\/(x-)?less$/;
  36. function clone(obj) {
  37. var cloned = {};
  38. for (var prop in obj) {
  39. if (obj.hasOwnProperty(prop)) {
  40. cloned[prop] = obj[prop];
  41. }
  42. }
  43. return cloned;
  44. }
  45. // only really needed for phantom
  46. function bind(func, thisArg) {
  47. var curryArgs = Array.prototype.slice.call(arguments, 2);
  48. return function () {
  49. var args = curryArgs.concat(Array.prototype.slice.call(arguments, 0));
  50. return func.apply(thisArg, args);
  51. };
  52. }
  53. function loadStyles(modifyVars) {
  54. var styles = document.getElementsByTagName('style');
  55. var style;
  56. for (var i = 0; i < styles.length; i++) {
  57. style = styles[i];
  58. if (style.type.match(typePattern)) {
  59. var instanceOptions = clone(options);
  60. instanceOptions.modifyVars = modifyVars;
  61. var lessText = style.innerHTML || '';
  62. instanceOptions.filename = document.location.href.replace(/#.*$/, '');
  63. /* jshint loopfunc:true */
  64. // use closure to store current style
  65. less.render(lessText, instanceOptions, bind(function (style, e, result) {
  66. if (e) {
  67. errors.add(e, 'inline');
  68. }
  69. else {
  70. style.type = 'text/css';
  71. if (style.styleSheet) {
  72. style.styleSheet.cssText = result.css;
  73. }
  74. else {
  75. style.innerHTML = result.css;
  76. }
  77. }
  78. }, null, style));
  79. }
  80. }
  81. }
  82. function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {
  83. var instanceOptions = clone(options);
  84. utils_1.addDataAttr(instanceOptions, sheet);
  85. instanceOptions.mime = sheet.type;
  86. if (modifyVars) {
  87. instanceOptions.modifyVars = modifyVars;
  88. }
  89. function loadInitialFileCallback(loadedFile) {
  90. var data = loadedFile.contents;
  91. var path = loadedFile.filename;
  92. var webInfo = loadedFile.webInfo;
  93. var newFileInfo = {
  94. currentDirectory: fileManager.getPath(path),
  95. filename: path,
  96. rootFilename: path,
  97. rewriteUrls: instanceOptions.rewriteUrls
  98. };
  99. newFileInfo.entryPath = newFileInfo.currentDirectory;
  100. newFileInfo.rootpath = instanceOptions.rootpath || newFileInfo.currentDirectory;
  101. if (webInfo) {
  102. webInfo.remaining = remaining;
  103. var css = cache.getCSS(path, webInfo, instanceOptions.modifyVars);
  104. if (!reload && css) {
  105. webInfo.local = true;
  106. callback(null, css, data, sheet, webInfo, path);
  107. return;
  108. }
  109. }
  110. // TODO add tests around how this behaves when reloading
  111. errors.remove(path);
  112. instanceOptions.rootFileInfo = newFileInfo;
  113. less.render(data, instanceOptions, function (e, result) {
  114. if (e) {
  115. e.href = path;
  116. callback(e);
  117. }
  118. else {
  119. cache.setCSS(sheet.href, webInfo.lastModified, instanceOptions.modifyVars, result.css);
  120. callback(null, result.css, data, sheet, webInfo, path);
  121. }
  122. });
  123. }
  124. fileManager.loadFile(sheet.href, null, instanceOptions, environment)
  125. .then(function (loadedFile) {
  126. loadInitialFileCallback(loadedFile);
  127. }).catch(function (err) {
  128. console.log(err);
  129. callback(err);
  130. });
  131. }
  132. function loadStyleSheets(callback, reload, modifyVars) {
  133. for (var i = 0; i < less.sheets.length; i++) {
  134. loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars);
  135. }
  136. }
  137. function initRunningMode() {
  138. if (less.env === 'development') {
  139. less.watchTimer = setInterval(function () {
  140. if (less.watchMode) {
  141. fileManager.clearFileCache();
  142. loadStyleSheets(function (e, css, _, sheet, webInfo) {
  143. if (e) {
  144. errors.add(e, e.href || sheet.href);
  145. }
  146. else if (css) {
  147. browser_1.default.createCSS(window.document, css, sheet);
  148. }
  149. });
  150. }
  151. }, options.poll);
  152. }
  153. }
  154. //
  155. // Watch mode
  156. //
  157. less.watch = function () {
  158. if (!less.watchMode) {
  159. less.env = 'development';
  160. initRunningMode();
  161. }
  162. this.watchMode = true;
  163. return true;
  164. };
  165. less.unwatch = function () { clearInterval(less.watchTimer); this.watchMode = false; return false; };
  166. //
  167. // Synchronously get all <link> tags with the 'rel' attribute set to
  168. // "stylesheet/less".
  169. //
  170. less.registerStylesheetsImmediately = function () {
  171. var links = document.getElementsByTagName('link');
  172. less.sheets = [];
  173. for (var i = 0; i < links.length; i++) {
  174. if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
  175. (links[i].type.match(typePattern)))) {
  176. less.sheets.push(links[i]);
  177. }
  178. }
  179. };
  180. //
  181. // Asynchronously get all <link> tags with the 'rel' attribute set to
  182. // "stylesheet/less", returning a Promise.
  183. //
  184. less.registerStylesheets = function () { return new Promise(function (resolve, reject) {
  185. less.registerStylesheetsImmediately();
  186. resolve();
  187. }); };
  188. //
  189. // With this function, it's possible to alter variables and re-render
  190. // CSS without reloading less-files
  191. //
  192. less.modifyVars = function (record) { return less.refresh(true, record, false); };
  193. less.refresh = function (reload, modifyVars, clearFileCache) {
  194. if ((reload || clearFileCache) && clearFileCache !== false) {
  195. fileManager.clearFileCache();
  196. }
  197. return new Promise(function (resolve, reject) {
  198. var startTime;
  199. var endTime;
  200. var totalMilliseconds;
  201. var remainingSheets;
  202. startTime = endTime = new Date();
  203. // Set counter for remaining unprocessed sheets
  204. remainingSheets = less.sheets.length;
  205. if (remainingSheets === 0) {
  206. endTime = new Date();
  207. totalMilliseconds = endTime - startTime;
  208. less.logger.info('Less has finished and no sheets were loaded.');
  209. resolve({
  210. startTime: startTime,
  211. endTime: endTime,
  212. totalMilliseconds: totalMilliseconds,
  213. sheets: less.sheets.length
  214. });
  215. }
  216. else {
  217. // Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array
  218. loadStyleSheets(function (e, css, _, sheet, webInfo) {
  219. if (e) {
  220. errors.add(e, e.href || sheet.href);
  221. reject(e);
  222. return;
  223. }
  224. if (webInfo.local) {
  225. less.logger.info("Loading " + sheet.href + " from cache.");
  226. }
  227. else {
  228. less.logger.info("Rendered " + sheet.href + " successfully.");
  229. }
  230. browser_1.default.createCSS(window.document, css, sheet);
  231. less.logger.info("CSS for " + sheet.href + " generated in " + (new Date() - endTime) + "ms");
  232. // Count completed sheet
  233. remainingSheets--;
  234. // Check if the last remaining sheet was processed and then call the promise
  235. if (remainingSheets === 0) {
  236. totalMilliseconds = new Date() - startTime;
  237. less.logger.info("Less has finished. CSS generated in " + totalMilliseconds + "ms");
  238. resolve({
  239. startTime: startTime,
  240. endTime: endTime,
  241. totalMilliseconds: totalMilliseconds,
  242. sheets: less.sheets.length
  243. });
  244. }
  245. endTime = new Date();
  246. }, reload, modifyVars);
  247. }
  248. loadStyles(modifyVars);
  249. });
  250. };
  251. less.refreshStyles = loadStyles;
  252. return less;
  253. });
  254. //# sourceMappingURL=index.js.map