/** __ ( ) _____ ___ ___ ____ ____ )( ( _ )/ __) / __)( ___)( _ \ )(__ )(_)(( (_-.( (_-. )__) ) / (____)(_____)\___/ \___/(____)(_)\_) By Mike & Nike This file is part of Sparc by Mike & Nike. Widgets is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Widgets is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Get your copy of the GNU General Public License at . * @category Core * @subcategory Libraries * @class * @todo extract from app (this is just a hook for window.console) * @param {object} nativeConsole a reference to the native browser console (Typically window.console ) * @param {object} config */ app.logger = function(oldCons, config){ const appendErr = (data) => { data['errId'] = crypto.randomUUID() app.latestErrors.push(data) let maxentries = config.latestErrsMax || 10; while(app.latestErrors.length > maxentries) app.latestErrors.shift() } const getCircularReplacer = () => { const seen = new WeakSet(); return (key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) { return; } seen.add(value); } return value; }; }; const formater = function(err, args, color){ var splitter = function(stkLine, mode){ if(mode=='chrome'){ var buf = stkLine.substr(0,stkLine.indexOf(' (')); var funcName = buf.substr(buf.lastIndexOf('.')+1); var buf = stkLine.substr(stkLine.lastIndexOf('/')+1); var scriptname = buf.substr(0,buf.indexOf('.js')+3); var lincol = buf.substr(buf.indexOf(':')+1).split(':'); } else { var funcName = stkLine.substr(0,stkLine.indexOf('@')); if(funcName.indexOf('/')>-1) funcName = funcName.substr(0,funcName.indexOf('/')); var buf = stkLine.substr(stkLine.lastIndexOf('/')+1); var scriptname = buf.substr(0,buf.indexOf('.js')+3); var lincol = buf.substr(buf.indexOf(':')+1).split(':'); } return([funcName, scriptname, lincol]); } var lines = err.stack.split('\n'); var nice_stack=[]; var funcName, scriptname, lincol; if(lines[0].toLowerCase()=='error'){ // Chrome & Edge style [funcName, scriptname, lincol] = splitter(lines[2], 'chrome'); lines.shift();lines.shift(); for(var line of lines) nice_stack.push(splitter(line, 'chrome')); } else { // Firefox style [funcName, scriptname, lincol] = splitter(lines[1], 'ff'); lines.shift(); for(var line of lines) nice_stack.push(splitter(line, 'ff')); } var msg = args[0]; args[0] = `${args[0]} %c${funcName} @ ${scriptname} : ${lincol}`; args.splice(1,0,'background-color:'+color+';color:#FFF;font-weight:bold;float:right;padding:2px 5px 2px 5px;border-radius:4px;'); return([args, msg, nice_stack]); } return { nativeConsoleAPI:'', //noooo, the console is NOT changed... or is it ;-) trace: oldCons.trace, log: function(...args){ if(typeof(args[0])!='string') args.unshift(''); var nice_stack, msg; var err = new Error(); [args, msg, nice_stack] = formater(err, args, '#070'); oldCons.log(...args); }, info: function (...args) { if(typeof(args[0])!='string') args.unshift(''); var nice_stack, msg; var err = new Error(); [args, msg, nice_stack] = formater(err, args, '#070'); oldCons.info(...args); }, warn: function (...args) { if(typeof(args[0])!='string') args.unshift(''); var nice_stack, msg; var err = new Error(); var msgData = (args.length>1) ? args.slice(1) : ''; [args, msg, nice_stack] = formater(err, args, '#C90'); oldCons.warn(...args); if(config.levels.indexOf('warn')<0) return; let data = {'level':'WARNING', 'message': msg, 'messageData' : msgData, 'user': app.User, 'timestamp':(new Date).toISOString().replace(/[A-Z]/g,' ').trim() , 'url': document.location.toString(), 'stacktrace' : nice_stack, }; if(config.postUrl.startsWith('https://')){ fetch(config.postUrl, { 'method': 'POST', 'body' : JSON.stringify(data, getCircularReplacer()), 'headers': {'Content-type': 'application/json; charset=UTF-8'} }) } appendErr(data); }, error: function (...args) { if(typeof(args[0])!='string') args.unshift(''); var nice_stack, msg; var err = new Error(); var msgData = (args.length>1) ? args.slice(1) : ''; [args, msg, nice_stack] = formater(err, args, '#900'); oldCons.error(...args); if(config.levels.indexOf('err')<0) return; let data = {'level':'ERROR', 'message': msg, 'messageData' : msgData, 'user': app.User, 'timestamp':(new Date).toISOString().replace(/[A-Z]/g,' ').trim() , 'url': document.location.toString(), 'stacktrace' : nice_stack, }; if(config.postUrl.startsWith('https://')){ fetch(config.postUrl, { 'method': 'POST', 'body' : JSON.stringify(data, getCircularReplacer()), 'headers': {'Content-type': 'application/json; charset=UTF-8'} }) } appendErr(data); } }; };