/**
* This JS file contains utils functions
*/
class Utils {
constructor(parent) {
this.parent = parent;
this.multipleSize = [1280, 1024, 'Mobile'];
}
/**
* When something is written in the editor, it reset the safe mode
*/
markDirty() {
if (this.parent.monacoCreator.BlockEditorChange) return;
this.setToMultipleID("safemodeToggle", "addClass", "checked");!
this.setToMultipleID('safemodeToggle', 'innerHTML', 'Safe mode ');
};
toLocationError(errorMessage, errorEvent) {
if (!errorEvent) {
return null;
}
// Do we have any location info?
if (errorEvent.hasOwnProperty('lineNumber') && errorEvent.hasOwnProperty('columnNumber'))
return errorEvent;
// Else try to parse the stack to retrieve location...
var regEx = /\(.+:(\d+):(\d+)\)\n/g;
var match = regEx.exec(errorEvent.stack);
if (match) {
var error = new EvalError(errorMessage);
error.lineNumber = match[1];
error.columnNumber = match[2];
return error;
}
// Not an error with proper location
return null;
}
/**
* Used to show error messages
* @param {String} errorMessage
* @param {String} errorEvent
*/
showError(errorMessage, errorEvent) {
let errorContent = '
';
const locationError = this.toLocationError(errorMessage, errorEvent);
if (locationError == null) {
// use a regular message
errorContent += `${errorMessage}
`;
} else {
// we have location information
errorContent += `Line ${locationError.lineNumber} : ${locationError.columnNumber} - ${errorMessage}`;
}
document.getElementById("errorZone").style.display = 'block';
document.getElementById("errorZone").innerHTML = errorContent;
// Close button error
document.getElementById("errorZone").querySelector('.close').addEventListener('click', function () {
document.getElementById("errorZone").style.display = 'none';
});
// Go To Location
const gotoLocation = document.getElementById("gotoLocation");
const jsEditor = this.parent.monacoCreator.jsEditor;
if (gotoLocation) {
gotoLocation.addEventListener('click', function () {
const position = {
lineNumber: Number(locationError.lineNumber),
column: Number(locationError.columnNumber)
};
jsEditor.revealPositionInCenter(position, monaco.editor.ScrollType.Smooth);
jsEditor.setPosition(position);
});
}
};
/**
* Apply things to the differents menu sizes
*/
setToMultipleID(id, thingToDo, param) {
this.multipleSize.forEach(function (size) {
if (thingToDo == "innerHTML") {
document.getElementById(id + size).innerHTML = param
}
else if (thingToDo == "click") {
if (param.length > 1) {
for (var i = 0; i < param.length; i++) {
document.getElementById(id + size).addEventListener("click", param[i]);
}
}
else
document.getElementById(id + size).addEventListener("click", param);
}
else if (thingToDo == "addClass") {
document.getElementById(id + size).classList.add(param);
}
else if (thingToDo == "removeClass") {
document.getElementById(id + size).classList.remove(param);
}
else if (thingToDo == "display") {
document.getElementById(id + size).style.display = param;
}
});
};
/**
* Function to get the current screen size
*/
getCurrentSize() {
for(var i = 0; i < this.multipleSize.length; i++) {
if(document.getElementById("menuButton" + this.multipleSize[i]).offsetHeight > 0) return this.multipleSize[i];
}
};
debounceAsync(fn, wait = 0, options = {}) {
let lastCallAt
let deferred
let timer
let pendingArgs = []
return function debounced(...args) {
const currentWait = getWait(wait)
const currentTime = new Date().getTime()
const isCold = !lastCallAt || (currentTime - lastCallAt) > currentWait
lastCallAt = currentTime
if (isCold && options.leading) {
return options.accumulate
? Promise.resolve(fn.call(this, [args])).then(result => result[0])
: Promise.resolve(fn.call(this, ...args))
}
if (deferred) {
clearTimeout(timer)
} else {
deferred = defer()
}
pendingArgs.push(args)
timer = setTimeout(flush.bind(this), currentWait)
if (options.accumulate) {
const argsIndex = pendingArgs.length - 1
return deferred.promise.then(results => results[argsIndex])
}
return deferred.promise
}
function getWait(wait) {
return (typeof wait === 'function') ? wait() : wait
}
function defer() {
const deferred = {}
deferred.promise = new Promise((resolve, reject) => {
deferred.resolve = resolve
deferred.reject = reject
})
return deferred
}
function flush() {
const thisDeferred = deferred
clearTimeout(timer)
Promise.resolve(
options.accumulate
? fn.call(this, pendingArgs)
: fn.apply(this, pendingArgs[pendingArgs.length - 1])
)
.then(thisDeferred.resolve, thisDeferred.reject)
pendingArgs = []
deferred = null
}
}
}