js/ui.log.js

  1. const logger = function(ui = {}) {
  2. /**
  3. * Log a message to the console
  4. *
  5. */
  6. ui.log = async function(message) {
  7. //console.warn(message);
  8. const maxWaitTime = 250; // half second for node change is already too slow
  9. var $console = $("#loadingOverlay .console");
  10. if (!$console.is(":visible")) return console.log(message);
  11. var texts = [];
  12. for (var i=0; i<arguments.length; i++) {
  13. if (typeof arguments[i] !== "string") {
  14. texts.push(JSON.stringify(arguments[i], undefined, 2));
  15. } else {
  16. texts.push(arguments[i]);
  17. }
  18. }
  19. if (ui.log.getConfig().type) {
  20. $console.append(`<pre data-type="${ui.log.getConfig().type}">${texts.join("\n ")}</pre>`);
  21. } else if (message.constructor.name == "jQuery") {
  22. // append as is
  23. let thisPre = $("<pre></pre>");
  24. thisPre.append(message);
  25. $console.append(thisPre);
  26. } else {
  27. $console.append("<pre>"+texts.join("\n ")+"</pre>");
  28. }
  29. console.log.apply(this, arguments);
  30. var resolver;
  31. var promise = new Promise((resolve, reject) => {
  32. resolver = resolve;
  33. ui.one("logIsAdded", async ()=>{
  34. resolve();
  35. });
  36. })
  37. window.setTimeout(()=>{
  38. resolver();
  39. }, maxWaitTime)
  40. return promise;
  41. }
  42. ui.log.isShown = function() {
  43. return $("#loadingOverlay .console").is(":visible");
  44. }
  45. ui.log.show = function(options) {
  46. /*
  47. options.buttons = [{
  48. text: "text to display",
  49. onClick : function
  50. }]
  51. */
  52. options = options||{};
  53. options.buttons = options.buttons||[];
  54. $("#applicationBar .appActionsLeft").hide();
  55. // autofix direct options.buttons object
  56. if (Array.isArray(options.buttons) == false) {
  57. if (typeof options.buttons.text !== "undefined") options.buttons = [options.buttons];
  58. }
  59. ui.consoleIsShown = true;
  60. $("#loadingOverlay .console").empty();
  61. $("#loadingOverlay .loadingBarProgress").empty();
  62. //$("#loadingOverlay .console").addClass("stickToBottom");
  63. $("#loadingOverlay .loadingBarProgress").removeClass("stopped");
  64. $("#loadingOverlay .loadingBarProgress").removeClass("error");
  65. $(".loadingBarButtons").empty();
  66. for (var i=0; i<options.buttons.length; i++) {
  67. var thisButton = $("<a href='#'>"+options.buttons[i].text+"</a>");
  68. if (typeof options.buttons[i].onClick == 'function') {
  69. thisButton.data("onClick", options.buttons[i].onClick)
  70. thisButton.on("click", function(e) {
  71. $(this).data("onClick").call(this);
  72. });
  73. }
  74. $(".loadingBarButtons").append(thisButton);
  75. }
  76. if ($("#loadingOverlay").hasClass("initialized") == false) {
  77. $("#loadingOverlay").addClass("initialized");
  78. ui.log.init();
  79. }
  80. ui.appBarTheme("dark");
  81. $("#loadingOverlay").removeClass("hidden");
  82. $(document).trigger("showLoading");
  83. ui.log("Log started!");
  84. ui._logTimeStart = Date.now();
  85. if (nw.process.versions["nw-flavor"] == "sdk") ui.log(t("You can view the more detailed information on console log (F12)"));
  86. return $("#loadingOverlay");
  87. }
  88. ui.log.start = ui.log.show;
  89. ui.log.hide = function(destroy) {
  90. ui.consoleIsShown = false;
  91. destroy = destroy||false;
  92. $("#loadingOverlay .loadingStatus").text("");
  93. if (destroy) {
  94. $("#loadingOverlay .console").empty();
  95. }
  96. $("#loadingOverlay").addClass("hidden");
  97. ui.appBarTheme("");
  98. $("#applicationBar .appActionsLeft").show();
  99. /**
  100. * Triggered when loading console closed
  101. * @event ui#loadingScreenIsClosed
  102. * @since 4.3.20
  103. */
  104. ui.trigger("loadingConsoleClosed")
  105. return $("#loadingOverlay");
  106. }
  107. ui.log.clearButtons = function() {
  108. $(".loadingBarButtons").empty();
  109. }
  110. ui.log.showCloseButton = function(options) {
  111. options=options||{};
  112. var $loadingBarBtn = $(".loadingBarButtons");
  113. if ($loadingBarBtn.find(".closeButton").length > 0) return;
  114. var thisButton = $("<a class='closeButton icon-cancel-1' href='#'>"+t("Close")+"</a>");
  115. thisButton.on("click", function(e) {
  116. ui.log.hide.call(this, true);
  117. ui.log.clearButtons();
  118. });
  119. $loadingBarBtn.append(thisButton);
  120. }
  121. ui.log.showOpenCacheButton = function(target, options) {
  122. options=options||{};
  123. if (typeof target == 'undefined') return false;
  124. $(".loadingBarButtons").find(".openCache").remove();
  125. var thisButton = $("<a href='#' class='openCache icon-folder-open'>Open Cache</a>");
  126. thisButton.on("click", function(e) {
  127. //var thisTmpPath = str_ireplace("\\", "\\\\", target);
  128. //console.log("running command : \r\n"+'explorer "'+thisTmpPath+'"');
  129. require('child_process').exec('explorer "'+target+'"' , function (err, stdout, stderr) { console.log("Explorer opened") });
  130. });
  131. $(".loadingBarButtons").append(thisButton);
  132. }
  133. ui.log.addButton = function(text, onClick, options) {
  134. options=options||{};
  135. options.class=options.class||"";
  136. if (typeof text == 'undefined') return false
  137. if (typeof onClick !== 'function') onClick = function(){};
  138. text = text||"";
  139. options.a = options.a||"#";
  140. var thisButton = $("<a class='"+options.class+"' href='"+options.a+"'>"+text+"</a>");
  141. thisButton.on("click", function(e) {
  142. onClick.call(this);
  143. });
  144. $(".loadingBarButtons").append(thisButton);
  145. return thisButton;
  146. }
  147. ui.log.stickToBottom = function($elm) {
  148. if ($elm.length == 0) return $elm;
  149. console.log($elm[0].scrollTop+"+"+$elm.height()+" >= "+$elm[0].scrollHeight);
  150. if (($elm[0].scrollTop+$elm.height() >= $elm[0].scrollHeight)) {
  151. $elm[0].scrollTop=$elm[0].scrollHeight;
  152. }
  153. return $elm;
  154. }
  155. ui.log.progress = async function(percent, status, options) {
  156. /*
  157. options.mode = consoleOutput -> no pre wrapper
  158. */
  159. var $loading = $("#loadingOverlay");
  160. options = options||{};
  161. options.consoleOnly = options.consoleOnly||false;
  162. options.mode = options.mode||"";
  163. options.classStr = options.classStr||"";
  164. if (typeof percent == 'string') {
  165. //$loading.find(".loadingBarProgress").css("width", 100+"%");
  166. $loading.find(".loadingBarProgress").css("left", "0%");
  167. $loading.find(".loadingBarOverlay").text(percent);
  168. } else if (typeof percent !== 'undefined') {
  169. percent = percent||0;
  170. percent = Math.round(percent);
  171. //$loading.find(".loadingBarProgress").css("width", percent+"%");
  172. $loading.find(".loadingBarProgress").css("left", (-100+percent)+"%");
  173. $loading.find(".loadingBarOverlay").text(percent+"%");
  174. }
  175. var classStr = "";
  176. if (options.classStr) {
  177. classStr = ' class="'+options.classStr+'"';
  178. }
  179. if (typeof status !== "undefined") {
  180. if (options.consoleOnly == false) {
  181. $loading.find(".loadingStatus").text(status);
  182. }
  183. var console = $("#loadingOverlay .console");
  184. if (options.mode == "consoleOutput") {
  185. console.append("<span"+classStr+">"+status+"</span>");
  186. } else {
  187. console.append("<pre"+classStr+">"+status+"</pre>");
  188. }
  189. /*
  190. if (console.hasClass("stickToBottom")) {
  191. console[0].scrollTop=console[0].scrollHeight;
  192. }
  193. */
  194. return status;
  195. }
  196. }
  197. ui.log.addHtml = async function(html) {
  198. const $console = $("#loadingOverlay .console");
  199. let thisPre = $("<pre></pre>");
  200. thisPre.append($(html));
  201. $console.append(thisPre);
  202. }
  203. ui.log.setConfig = function(config = {}) {
  204. ui.logConfig = config;
  205. }
  206. ui.log.getConfig = function() {
  207. return ui.logConfig || {};
  208. }
  209. ui.log.error = async function() {
  210. this.setConfig({type:"error"});
  211. await ui.log.apply(this, Array.from(arguments));
  212. this.setConfig({type:undefined});
  213. return;
  214. }
  215. ui.log.warning = async function() {
  216. this.setConfig({type:"warning"});
  217. await ui.log.apply(this, Array.from(arguments));
  218. this.setConfig({type:undefined});
  219. return;
  220. }
  221. ui.log.info = async function() {
  222. this.setConfig({type:"info"});
  223. await ui.log.apply(this, Array.from(arguments));
  224. this.setConfig({type:undefined});
  225. return;
  226. }
  227. ui.log.success = async function() {
  228. this.setConfig({type:"success"});
  229. await ui.log.apply(this, Array.from(arguments));
  230. this.setConfig({type:undefined});
  231. return;
  232. }
  233. ui.log.init = function() {
  234. if (this.loadingObserverIsInitialized) return;
  235. // Select the node that will be observed for mutations
  236. const targetNode = $("#loadingOverlay")[0];
  237. // Options for the observer (which mutations to observe)
  238. const config = { attributes: false, childList: true, subtree: true };
  239. // Callback function to execute when mutations are observed
  240. const callback = function(mutationsList, observer) {
  241. ui.trigger("logIsAdded");
  242. };
  243. // Create an observer instance linked to the callback function
  244. const observer = new MutationObserver(callback);
  245. // Start observing the target node for configured mutations
  246. observer.observe(targetNode, config);
  247. this.loadingObserverIsInitialized = true;
  248. }
  249. ui.log.end = function(percent, status, options) {
  250. options = options||{};
  251. console.log("Loading end", arguments);
  252. var elapsed = Date.now() - ui._logTimeStart;
  253. ui.log("Log ended!");
  254. ui.log("Elapsed time : "+elapsed+"ms");
  255. ui.log.progress(percent, status, options);
  256. var $loading = $("#loadingOverlay");
  257. options.error = options.error || false;
  258. var thisClass = "stopped";
  259. if (options.warning) thisClass = "warning";
  260. if (options.error) thisClass = "error";
  261. $loading.find(".loadingBarProgress").addClass(thisClass);
  262. ui.log.showCloseButton();
  263. }
  264. }
  265. module.exports = logger;