Created
October 30, 2022 13:05
-
-
Save lydell/20bb50d84addac671fe0985d17cc4a26 to your computer and use it in GitHub Desktop.
Patch for Elm’s Debug.log that gives you an interactive value in the console
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var _Debug_log = F2(function(tag, value) | |
{ | |
console.log(tag + ': ' + _Debug_toString(value)); | |
return value; | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////// START Debug.log replacement ////////////////////////// | |
var _Debug_log = F2(function(tag, value) | |
{ | |
const js = _Debug_toJs(value); | |
console.log(tag + ':', typeof js === 'string' ? new String_(js) : js); | |
return value; | |
}); | |
// Firefox does not print the name of user-defined classes in the console. | |
// Instead, it prints the name of the "native" object it (eventually) inherits from, | |
// like Object, Array or Error. This means that: | |
// - Char is displayed as string. | |
// - Tuple, List and Array are all displayed as arrays. | |
// - Unit is displayed as an empty array. | |
// - Dict is displayed as Map. | |
// - Custom type constructor names are shown as the first array element. | |
// Note: We can't use the user agent to detect Firefox, because this needs to work | |
// even when the responsive design mode is enabled (which also swaps the user agent). | |
const IS_FIREFOX = 'MozAppearance' in document.documentElement.style; | |
class Array_ extends Array {} | |
class Char extends Array {} | |
class Dict extends Map {} | |
class Internals {} | |
class List extends Array {} | |
class String_ extends Array {} | |
class Tuple extends Array {} | |
class Unit extends Array {} | |
class WeirdConstructor extends Array {} | |
const _DEBUG_UPPER_NAME = /^\p{Lu}\p{ID_Continue}*$/u; | |
// Originally based on _Debug_toAnsiString. | |
function _Debug_toJs(value) { | |
if (typeof value !== 'object' || value === null) { | |
return value; | |
} | |
if (value instanceof String) { | |
return IS_FIREFOX ? value.toString() : new Char(value.toString()); | |
} | |
if (value.constructor.name !== 'Object') { | |
return value; | |
} | |
if ('$' in value) { | |
// It can be a number for internals (like Json and Html). | |
const tag = value.$.toString(); | |
if (tag === '#0') { | |
return new Unit(); | |
} | |
if (tag[0] === '#') { | |
const output = new Tuple(); | |
for (const key in value) { | |
if (key === '$') continue; | |
output.push(_Debug_toJs(value[key])); | |
} | |
return output; | |
} | |
if (tag === 'Set_elm_builtin') { | |
return new Set(_Debug_toJsArray($elm$core$Set$toList(value), [])); | |
} | |
if (tag === 'RBNode_elm_builtin' || tag === 'RBEmpty_elm_builtin') { | |
return new Dict(_Debug_toJsArray($elm$core$Dict$toList(value), [])); | |
} | |
if (tag === 'Array_elm_builtin') { | |
return _Debug_toJsArray($elm$core$Array$toList(value), new Array_()); | |
} | |
if (tag === '::' || tag === '[]') { | |
return _Debug_toJsArray(value, new List()); | |
} | |
if (!_DEBUG_UPPER_NAME.test(tag)) { | |
const output = new Internals(); | |
for (const key in value) { | |
output[key] = value[key]; | |
} | |
return output; | |
} | |
let output; | |
if (IS_FIREFOX) { | |
output = [tag]; | |
} else { | |
try { | |
const constructor = new Function('return class ' + tag + ' extends Array {}')(); | |
output = new constructor(); | |
} catch (error) { | |
output = new WeirdConstructor(tag); | |
output.push(tag); | |
output.error = error; | |
} | |
} | |
for (const key in value) { | |
if (key === '$') continue; | |
output.push(_Debug_toJs(value[key])); | |
} | |
return output; | |
} | |
const output = {}; | |
for (const key in value) { | |
const field = key[0] === '_' ? key.slice(1) : key; | |
output[field] = _Debug_toJs(value[key]); | |
} | |
return output; | |
} | |
function _Debug_toJsArray(value, output) { | |
for (; value.b; value = value.b) { | |
output.push(_Debug_toJs(value.a)); | |
} | |
return output; | |
} | |
////////////////////////// END Debug.log replacement ////////////////////////// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment