Colour codes in debug panel

Background

Debug has a couple of special tricks:

  • When it displays a 6 digit hex code eg #7FFF00, it also shows a little colour swatch.
    image
  • When it displays a date or timestamp, clicking on the value cycles through different date representations
    image
    image
    etc

Proposal

  1. Extend debug to recognise different payloads as colors and show the colour swatch - Hex, RGB, HSL [, HWB, etc]
  2. Make the value clickable and cycle between different representations.

Thoughts

Do browsers accept some format properties as either a percentage or a decimal fraction?
Some formats also have a transparency option - HSLA, RGBA HexA. Include or ignore?
Should the string that identifies a payload as a colour require a bracket with no whitespace - try to parse rgb( as a color but not rgb (?
I guess part 1 would be lighter weight than part 2 since it does not require any color conversion code.

1 Like

Do you have specific example strings for these formats that we could easily identify?

There are regular expressions which match color codes. Here is an example flow showing one.
See the function node for notes on my simplified regex.

[{"id":"6ecfad81901dbc79","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"906cdb2aa87e6039","type":"group","z":"6ecfad81901dbc79","name":"Not parsed as colours","style":{"label":true},"nodes":["5cb73ec3fab39b5a","a81d7c7a9a8f8f6f","400cc71f2530b523","175725b77648ab3c","0492e6c47b3ca430","8089f8eb2b0b9e86"],"x":374,"y":19,"w":332,"h":242},{"id":"7b7f11c97f380360","type":"group","z":"6ecfad81901dbc79","name":"Parsed as colours","style":{"label":true},"nodes":["dc6f8a787e93e420","d6b28fa128b48f29","40fef6131f5d9471","0492bee66445e317","a6cf107232169557","45a91610e6686564","ee99094e152ffe8e"],"x":34,"y":19,"w":312,"h":282},{"id":"ee99094e152ffe8e","type":"junction","z":"6ecfad81901dbc79","g":"7b7f11c97f380360","x":320,"y":160,"wires":[["fa7c1e96e06b19c7"]]},{"id":"8089f8eb2b0b9e86","type":"junction","z":"6ecfad81901dbc79","g":"906cdb2aa87e6039","x":680,"y":140,"wires":[["e03caf58f2cdea5d"]]},{"id":"e03caf58f2cdea5d","type":"junction","z":"6ecfad81901dbc79","x":660,"y":280,"wires":[["2e265d180cf68b46"]]},{"id":"fa7c1e96e06b19c7","type":"junction","z":"6ecfad81901dbc79","x":340,"y":320,"wires":[["2e265d180cf68b46"]]},{"id":"2e265d180cf68b46","type":"junction","z":"6ecfad81901dbc79","x":400,"y":320,"wires":[["0cdf049b1b5c436f"]]},{"id":"0cdf049b1b5c436f","type":"function","z":"6ecfad81901dbc79","name":"Apply regex","func":"// First example from khalilgharbaoui contribution to https://gist.github.com/olmokramer/82ccce673f86db7cda5e\n// But ^ and $ added\nconst regex = /^(#(?:[0-9a-fA-F]{2}){2,4}$|(#[0-9a-fA-F]{3}$)|(rgb|hsl)a?\\((-?\\d+%?[,\\s]+){2,3}\\s*[\\d\\.]+%?\\)$|black$|silver$|gray$|whitesmoke$|maroon$|red$|purple$|fuchsia$|green$|lime$|olivedrab$|yellow$|navy$|blue$|teal$|aquamarine$|orange$|aliceblue$|antiquewhite$|aqua$|azure$|beige$|bisque$|blanchedalmond$|blueviolet$|brown$|burlywood$|cadetblue$|chartreuse$|chocolate$|coral$|cornflowerblue$|cornsilk$|crimson$|darkblue$|darkcyan$|darkgoldenrod$|darkgray$|darkgreen$|darkgrey$|darkkhaki$|darkmagenta$|darkolivegreen$|darkorange$|darkorchid$|darkred$|darksalmon$|darkseagreen$|darkslateblue$|darkslategray$|darkslategrey$|darkturquoise$|darkviolet$|deeppink$|deepskyblue$|dimgray$|dimgrey$|dodgerblue$|firebrick$|floralwhite$|forestgreen$|gainsboro$|ghostwhite$|goldenrod$|gold$|greenyellow$|grey$|honeydew$|hotpink$|indianred$|indigo$|ivory$|khaki$|lavenderblush$|lavender$|lawngreen$|lemonchiffon$|lightblue$|lightcoral$|lightcyan$|lightgoldenrodyellow$|lightgray$|lightgreen$|lightgrey$|lightpink$|lightsalmon$|lightseagreen$|lightskyblue$|lightslategray$|lightslategrey$|lightsteelblue$|lightyellow$|limegreen$|linen$|mediumaquamarine$|mediumblue$|mediumorchid$|mediumpurple$|mediumseagreen$|mediumslateblue$|mediumspringgreen$|mediumturquoise$|mediumvioletred$|midnightblue$|mintcream$|mistyrose$|moccasin$|navajowhite$|oldlace$|olive$|orangered$|orchid$|palegoldenrod$|palegreen$|paleturquoise$|palevioletred$|papayawhip$|peachpuff$|peru$|pink$|plum$|powderblue$|rosybrown$|royalblue$|saddlebrown$|salmon$|sandybrown$|seagreen$|seashell$|sienna$|skyblue$|slateblue$|slategray$|slategrey$|snow$|springgreen$|steelblue$|tan$|thistle$|tomato$|transparent$|turquoise$|violet$|wheat$|white$|yellowgreen$|rebeccapurple$)$/i\n\n// Second example (mine) has named colours stripped out\n// Also simplified #[0-9a-fA-F] since whole thing is case insensitive\n//const noNamesRegex = /^(#(?:[0-9a-f]{2}){2,4}$|(#[0-9a-f]{3}$)|(rgb|hsl)a?\\((-?\\d+%?[,\\s]+){2,3}\\s*[\\d\\.]+%?\\)$)$/i\nconst noNamesRegex = /^(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\\((-?\\d+%?[,\\s]+){2,3}\\s*[\\d\\.]+%?\\))$/i\n\nconst payloadString = msg.payload.toString()\nif (payloadString.match(noNamesRegex)) { \n    msg.payload = msg.payload + \" is a colour\"\n}\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":320,"wires":[["6006897f117c106b"]]},{"id":"5cb73ec3fab39b5a","type":"inject","z":"6ecfad81901dbc79","g":"906cdb2aa87e6039","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":480,"y":180,"wires":[["8089f8eb2b0b9e86"]]},{"id":"6006897f117c106b","type":"debug","z":"6ecfad81901dbc79","name":"debug 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":640,"y":320,"wires":[]},{"id":"dc6f8a787e93e420","type":"inject","z":"6ecfad81901dbc79","g":"7b7f11c97f380360","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"#005dff","payloadType":"str","x":130,"y":100,"wires":[["ee99094e152ffe8e"]]},{"id":"d6b28fa128b48f29","type":"inject","z":"6ecfad81901dbc79","g":"7b7f11c97f380360","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"hsl(218, 100%, 50%)","payloadType":"str","x":170,"y":180,"wires":[["ee99094e152ffe8e"]]},{"id":"40fef6131f5d9471","type":"inject","z":"6ecfad81901dbc79","g":"7b7f11c97f380360","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"rgb(0, 93, 255)","payloadType":"str","x":160,"y":220,"wires":[["ee99094e152ffe8e"]]},{"id":"a81d7c7a9a8f8f6f","type":"inject","z":"6ecfad81901dbc79","g":"906cdb2aa87e6039","name":"aliceblue","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"aliceblue","payloadType":"str","x":480,"y":220,"wires":[["8089f8eb2b0b9e86"]]},{"id":"0492bee66445e317","type":"inject","z":"6ecfad81901dbc79","g":"7b7f11c97f380360","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"RGBA(0, 93, 255, 0.5)","payloadType":"str","x":180,"y":260,"wires":[["ee99094e152ffe8e"]]},{"id":"400cc71f2530b523","type":"inject","z":"6ecfad81901dbc79","g":"906cdb2aa87e6039","name":"{\"foo\":\"abc\", \"color\":\"#FFFF\"}","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"foo\":\"abc\", \"color\":\"#FFFF\"}","payloadType":"json","x":540,"y":60,"wires":[["8089f8eb2b0b9e86"]]},{"id":"a6cf107232169557","type":"inject","z":"6ecfad81901dbc79","g":"7b7f11c97f380360","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"#FFF","payloadType":"str","x":130,"y":60,"wires":[["ee99094e152ffe8e"]]},{"id":"175725b77648ab3c","type":"inject","z":"6ecfad81901dbc79","g":"906cdb2aa87e6039","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"#7cffe0AAc9a01f","payloadType":"str","x":500,"y":100,"wires":[["8089f8eb2b0b9e86"]]},{"id":"45a91610e6686564","type":"inject","z":"6ecfad81901dbc79","g":"7b7f11c97f380360","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"#7cffe0AA","payloadType":"str","x":140,"y":140,"wires":[["ee99094e152ffe8e"]]},{"id":"0492e6c47b3ca430","type":"inject","z":"6ecfad81901dbc79","g":"906cdb2aa87e6039","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"rgb (0, 93, 255)","payloadType":"str","x":500,"y":140,"wires":[["8089f8eb2b0b9e86"]]}]

It recognises as a colour (only complete payload, case insensitive)

  • #fff (which the current debug ignores)
  • #0a2b3c
  • rgb(r, g, b)
  • rgba(r, g, b, a)
  • hsl(hue, s%, l%)
  • hsla(h, s%, l%, a)

It does not recognise as a colour

  • Objects
  • Timestamps
  • rgb (r,g,b) ie a space after RGB
  • Named colors
  • #FFFFF ie a bad color definition

Feel free to experiment around here and raise a PR.

1 Like

To get you moving - a head start on the regex listed from easiest to hardest (slowest to fastest)


spec: #RGB[A] or #RRGGBB[AA]
regex: ^#[a-f\d]{3}(?:[a-f\d]?|(?:[a-f\d]{3}(?:[a-f\d]{2})?)?)\b$
try it out


spec: hsl[a](H, S, L[, A]) or hsl[a](H S L[ / A])
regex: ^hsla?\((?:(-?\d+(?:deg|g?rad|turn)?),\s*((?:\d{1,2}|100)%),\s*((?:\d{1,2}|100)%)(?:,\s*((?:\d{1,2}|100)%|0(?:\.\d+)?|1))?|(-?\d+(?:deg|g?rad|turn)?)\s+((?:\d{1,2}|100)%)\s+((?:\d{1,2}|100)%)(?:\s+((?:\d{1,2}|100)%|0(?:\.\d+)?|1))?)\)$
try it out


spec: rgb[a](R, G, B[, A]) or rgb[a](R G B[ / A])
regex: ^rgba?\((?:(25[0-5]|2[0-4]\d|1?\d{1,2}|(?:\d{1,2}|100)%),\s*(25[0-5]|2[0-4]\d|1?\d{1,2}|(?:\d{1,2}|100)%),\s*(25[0-5]|2[0-4]\d|1?\d{1,2}|(?:\d{1,2}|100)%)(?:,\s*((?:\d{1,2}|100)%|0(?:\.\d+)?|1))?|(25[0-5]|2[0-4]\d|1?\d{1,2}|(?:\d{1,2}|100)%)\s+(25[0-5]|2[0-4]\d|1?\d{1,2}|(?:\d{1,2}|100)%)\s+(25[0-5]|2[0-4]\d|1?\d{1,2}|(?:\d{1,2}|100)%)(?:\s+((?:\d{1,2}|100)%|0(?:\.\d+)?|1))?)\)$
try it out


Adapted from this post

3 Likes

Hah regrex as readable as ever !

3 Likes

Makes me yearn for MS basic wildcard matching :smiley:

1 Like

Nice list, Steve -- I'm assuming that these should be evaluated as case-insensitive, right?

Also, it seems that the regex should allow an optional space between the function and argument list, or between arguments -- e.g. rgb ( 10 ,20,30 ) -- since the browser allows this, iirc.

Yes (as per CSS guidelines)

So each regex would be /..regex../i

I thought about that, but decided not to the regex is hefty enough IMO.
Easy enough to retro though.

Which makes me wonder, would pure JS be faster :thinking:

It makes me wonder. Would a specific indicator node be better -see other thread about more debug options.
#theeditorisnotadashboard

1 Like

Well that is true... adding a bunch of optional whitespace \s? syntax everywhere is ugly.
So just a thought -- remove all whitespace before applying the "rbg(...)" and "hsl(...)" regex???

I'm trying to imagine a scenario where that might cause a false-positive, but can't think of one.

wouldn't you have to first test for starting with rgb or hsl - then remove whitespace - then fully test... ? All getting rather OTT IMHO :man_shrugging:

Actually makes me long for IBM's REXX language (was also available on Amiga weirdly) which was always excellent at text manipulation. :grinning:

Those were the days :star_struck:

2 Likes

Don't get me started (Have been quite spammy today)

But I often find my self firing up FS-UAE (OSX equivalent to WinUAE).

1 Like

ahhh still plenty of love out there for Rexx - RexxInfo.org - Free Tutorials, Downloads, Tools, Info, more.
Of course Mike used to work at Hursley and helped me on our early Pageprinter project.

1 Like

And, of course, the forerunner to HTML was IBM's SGML and I was quite the expert at that since that was how we did word processing back in the day. No WSYIWG back then. :grinning:

Unfortunately not. Space is a valid separator:

hsl(123rad 100% 0%)
hsla(123grad, 100%, 0%, 0)
hsla(-123turn 100% 0% 1)
hsla(1 100% 0% 50%)

rgb(0,0,0)
rgb(255,255,255)
rgb(0%, 255, 255)
rgba(0%, 255, 0, 0)
rgb(0 0 0)
rgb(255 255 255)
rgb(0% 255 255)
rgba(0% 25 0 0)
1 Like

Did you miss one?

hsl(204 89% 55% / 70%)
1 Like

If space is valid then convert any , / etc between ( and ) to spaces ?