// ==UserScript==
// @name Show Console Messages
// @namespace Kyan Violentmonkey Scripts
// @match *://*/*
// @grant none
// @license MIT
// @version 1.1.12
// @author Kyan
// @description Show console messages (such as console.log, console.error ...) on screen
// ==/UserScript==
;(function () {
'use strict';
// CSS styles
let console_msg_styles = document.createElement('style');
console_msg_styles.innerHTML = `
.console-message-div {
position: fixed;
z-index: 999;
bottom: 2em;
right: 2em;
background: transparent;
display: flex;
flex-wrap: wrap;
flex-direction: column-reverse;
transition: all 1s ease-out; /* for slide_show() */
overflow: hidden; /* for slide_show() */
pointer-events: none;
}
.console-message-wrapper {
width: 100%;
background: transparent;
transition: all 1s ease-out;
position: relative;
pointer-events: none;
}
.console-message-wrapper-progress-bar {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
border-radius: 5px;
z-index: -1;
overflow: hidden; /* hide border-radius of .console-message-wrapper-progress */
}
.console-message-wrapper-progress {
height: 100%;
background-color: rgba(94, 129, 172, 0.25); /* nord10 Frost (Darkest) */
width: 100%;
transition: all 1s linear;
transform-origin: right;
}
.console-message-text {
float: right;
padding: 5px;
margin: 5px;
border-radius: 5px;
width: fit-content;
font-size: 15px;
transition: all 1s ease-out;
white-space: pre-wrap; /* Preserve whitespace but allow wrapping */
word-break: break-word; /* Break long words */
max-width: 62vw;
pointer-events: auto;
text-shadow: 0px 0px 5px #2e3440; /* nord0 Polar Night (Darkest) */
}
.cursor-pointer {
cursor: pointer;
}
.bg-glass {
backdrop-filter: blur(5px);
}
`;
document.head.appendChild(console_msg_styles);
// create a div to show console log
let console_msg_div = document.createElement('div');
console_msg_div.classList.add('console-message-div');
document.body.appendChild(console_msg_div);
// override the default console.log function
let original_console_log = console.log;
let original_console_error = console.error;
let original_console_warn = console.warn;
let original_console_info = console.info;
let original_console_debug = console.debug;
const exit_to_right = (ele) => {
if (typeof ele !== 'undefined') {
ele.style.opacity = 0;
ele.style.transform = 'translateX(200%)';
setTimeout(() => ele.remove(), 1000);
}
}
const slide_show = (ele) => {
if (typeof ele !== 'undefined') {
let ele_height = window.getComputedStyle(ele).height // Get real height (including padding)
ele.style.height = '0' // Init height with 0px
ele.offsetHeight // Trigger a browser repaint and force reflow to ensure the height of 0px is calculated
ele.style.height = ele_height // Recover element height
}
}
const console_call = (type, original_function, message) => {
original_function(message)
if (message === 'bl') {
return;
}
if (typeof message === 'object' && message !== null) {
message = JSON.stringify(message, null, 4) // No replacing, 4 spaces for indent
}
let msglet_wrapper = document.createElement('div');
msglet_wrapper.classList.add('console-message-wrapper');
let msglet = document.createElement('div');
msglet.classList.add('console-message-text');
msglet.classList.add('bg-glass');
msglet.classList.add('cursor-pointer')
msglet.addEventListener('click', () => exit_to_right(msglet_wrapper))
let flair = ''
let transparency = 0.618
switch (type) {
case 'log':
flair = '💡';
msglet.style.color = 'white'; //
msglet.style.backgroundColor = `rgba(46, 52, 64, ${transparency})`; // nord0 Polar Night (Darkest)
break;
case 'error':
flair = '❌';
msglet.style.color = 'white';
msglet.style.backgroundColor = `rgba(191, 97, 106, ${transparency})`; // nord11 Aurora (Red)
break;
case 'warn':
flair = '⚠️';
msglet.style.color = '#EBCB8B'; // nord13 Aurora (Yellow)
msglet.style.backgroundColor = `rgba(46, 52, 64, ${transparency})`;
break;
case 'info':
flair = 'ℹ️';
msglet.style.color = 'white';
msglet.style.backgroundColor = `rgba(163, 190, 140, ${transparency})`; // nord14 Aurora (Green)
break;
case 'debug':
flair = '🐛';
msglet.style.color = 'white';
msglet.style.backgroundColor = `rgba(180, 142, 173, ${transparency})`; // nord15 Aurora (Purple)
break;
default:
flair = `[${type}]`;
msglet.style.color = '#ECEFF4'; // nord6 Snow Storm (Lightest)
msglet.style.backgroundColor = `rgba(46, 52, 64, ${transparency})`; // nord0 Polar Night (Darkest)
break;
}
if (type == 'error' && typeof message !== "string") {
console.error(message.message)
let err_dom = new DOMParser().parseFromString(message.error, "text/xml")
let err_dom_msg = err_dom.querySelector("Message")
if (err_dom_msg !== null) {
console.error(err_dom_msg.innerHTML)
}
let err_dom_dtl = err_dom.querySelector("Details")
if (err_dom_dtl !== null) {
console.error(err_dom_dtl.innerHTML)
}
} else {
// msglet.innerHTML = flair + ' ' + bionic_reading(message);
msglet.innerHTML = flair + ' ' + message
}
msglet_wrapper.appendChild(msglet);
console_msg_div.prepend(msglet_wrapper);
slide_show(msglet_wrapper)
// Calculate the time left of the message
let lifespan = Math.max(1000 + message.length * 100, 2500)
// Generate a progress bar
let progress_bar = document.createElement('div');
progress_bar.classList.add('console-message-wrapper-progress-bar');
let progress = document.createElement('div');
progress.classList.add('console-message-wrapper-progress');
progress_bar.appendChild(progress);
msglet.appendChild(progress_bar);
progress.style.transitionDuration = lifespan + 'ms';
// Animate the progress bar
setTimeout(() => {
progress.style.transform = 'scaleX(0)'
}, 100);
// Easeout the message after few seconds
progress.addEventListener('transitionend', () => {
if (progress.style.transform === 'scaleX(0)') {
exit_to_right(msglet_wrapper)
}
})
}
// Monkey Patch
console.log = (message) => console_call('log', original_console_log, message)
console.error = (message) => console_call('error', original_console_error, message)
console.warn = (message) => console_call('warn', original_console_warn, message)
console.info = (message) => console_call('info', original_console_info, message)
console.debug = (message) => console_call('debug', original_console_debug, message)
})();
const bionic_reading = (str) => {
let bionified = '';
for (let word of str.split(' ')) {
if (word.length == 2) {
bionified += `<b>${word[0]}</b>${word[1]}`
} else if (word.length > 2) {
bionified += `<b>${word.slice(0, 2)}</b>${word.slice(2)}`
} else {
bionified += word
}
bionified += ' '
}
return bionified.trim()
}