utils.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /**
  2. * This JS file contains utils functions
  3. */
  4. class Utils {
  5. constructor(parent) {
  6. this.parent = parent;
  7. this.multipleSize = [1280, 1024, 'Mobile'];
  8. }
  9. /**
  10. * When something is written in the editor, it reset the safe mode
  11. */
  12. markDirty() {
  13. if (this.parent.monacoCreator.BlockEditorChange) return;
  14. this.setToMultipleID("safemodeToggle", "addClass", "checked");
  15. this.setToMultipleID('safemodeToggle', 'innerHTML', 'Safe mode <i class="fa fa-check-square" aria-hidden="true"></i>');
  16. };
  17. toLocationError(errorMessage, errorEvent) {
  18. if (!errorEvent) {
  19. return null;
  20. }
  21. // Do we have any location info?
  22. if (errorEvent.hasOwnProperty('lineNumber') && errorEvent.hasOwnProperty('columnNumber'))
  23. return errorEvent;
  24. // Else try to parse the stack to retrieve location...
  25. var regEx = /\(.+:(\d+):(\d+)\)\n/g;
  26. var match = regEx.exec(errorEvent.stack);
  27. if (match) {
  28. var error = new EvalError(errorMessage);
  29. error.lineNumber = match[1];
  30. error.columnNumber = match[2];
  31. return error;
  32. }
  33. // Not an error with proper location
  34. return null;
  35. }
  36. /**
  37. * Used to show error messages
  38. * @param {String} errorMessage
  39. * @param {String} errorEvent
  40. */
  41. showError(errorMessage, errorEvent) {
  42. let errorContent = '<div class="alert alert-error"><button type="button" class="close" data-dismiss="alert">&times;</button>';
  43. const locationError = this.toLocationError(errorMessage, errorEvent);
  44. if (locationError == null) {
  45. // use a regular message
  46. errorContent += `${errorMessage}</div>`;
  47. } else {
  48. // we have location information
  49. errorContent += `<span id="gotoLocation">Line ${locationError.lineNumber} : ${locationError.columnNumber} - ${errorMessage}</span></div>`;
  50. }
  51. document.getElementById("errorZone").style.display = 'block';
  52. document.getElementById("errorZone").innerHTML = errorContent;
  53. // Close button error
  54. document.getElementById("errorZone").querySelector('.close').addEventListener('click', function () {
  55. document.getElementById("errorZone").style.display = 'none';
  56. });
  57. // Go To Location
  58. const gotoLocation = document.getElementById("gotoLocation");
  59. const jsEditor = this.parent.monacoCreator.jsEditor;
  60. if (gotoLocation) {
  61. gotoLocation.addEventListener('click', function () {
  62. const position = {
  63. lineNumber: Number(locationError.lineNumber),
  64. column: Number(locationError.columnNumber)
  65. };
  66. jsEditor.revealPositionInCenter(position, monaco.editor.ScrollType.Smooth);
  67. jsEditor.setPosition(position);
  68. });
  69. }
  70. };
  71. /**
  72. * Apply things to the differents menu sizes
  73. */
  74. setToMultipleID(id, thingToDo, param) {
  75. this.multipleSize.forEach(function (size) {
  76. if (thingToDo == "innerHTML") {
  77. document.getElementById(id + size).innerHTML = param
  78. } else if (thingToDo == "click") {
  79. if (param.length > 1) {
  80. for (var i = 0; i < param.length; i++) {
  81. document.getElementById(id + size).addEventListener("click", param[i]);
  82. }
  83. } else
  84. document.getElementById(id + size).addEventListener("click", param);
  85. } else if (thingToDo == "addClass") {
  86. document.getElementById(id + size).classList.add(param);
  87. } else if (thingToDo == "removeClass") {
  88. document.getElementById(id + size).classList.remove(param);
  89. } else if (thingToDo == "display") {
  90. document.getElementById(id + size).style.display = param;
  91. } else if (thingToDo === "title") {
  92. document.getElementById(id + size).setAttribute("title", param);
  93. }
  94. });
  95. };
  96. /**
  97. * Function to get the current screen size
  98. */
  99. getCurrentSize() {
  100. for (var i = 0; i < this.multipleSize.length; i++) {
  101. if (document.getElementById("menuButton" + this.multipleSize[i]).offsetHeight > 0) return this.multipleSize[i];
  102. }
  103. };
  104. debounceAsync(fn, wait = 0, options = {}) {
  105. let lastCallAt
  106. let deferred
  107. let timer
  108. let pendingArgs = []
  109. return function debounced(...args) {
  110. const currentWait = getWait(wait)
  111. const currentTime = new Date().getTime()
  112. const isCold = !lastCallAt || (currentTime - lastCallAt) > currentWait
  113. lastCallAt = currentTime
  114. if (isCold && options.leading) {
  115. return options.accumulate ?
  116. Promise.resolve(fn.call(this, [args])).then(result => result[0]) :
  117. Promise.resolve(fn.call(this, ...args))
  118. }
  119. if (deferred) {
  120. clearTimeout(timer)
  121. } else {
  122. deferred = defer()
  123. }
  124. pendingArgs.push(args)
  125. timer = setTimeout(flush.bind(this), currentWait)
  126. if (options.accumulate) {
  127. const argsIndex = pendingArgs.length - 1
  128. return deferred.promise.then(results => results[argsIndex])
  129. }
  130. return deferred.promise
  131. }
  132. function getWait(wait) {
  133. return (typeof wait === 'function') ? wait() : wait
  134. }
  135. function defer() {
  136. const deferred = {}
  137. deferred.promise = new Promise((resolve, reject) => {
  138. deferred.resolve = resolve
  139. deferred.reject = reject
  140. })
  141. return deferred
  142. }
  143. function flush() {
  144. const thisDeferred = deferred
  145. clearTimeout(timer)
  146. Promise.resolve(
  147. options.accumulate ?
  148. fn.call(this, pendingArgs) :
  149. fn.apply(this, pendingArgs[pendingArgs.length - 1])
  150. )
  151. .then(thisDeferred.resolve, thisDeferred.reject)
  152. pendingArgs = []
  153. deferred = null
  154. }
  155. }
  156. }