)
}
}
)
(
}
{
)
)
(
)
(
(
{
}
)
(
)
}
)
)
{
(
(
)
)
}
)
(
}

console.log Hijack

  1. const log = console.log;
  2. const consoleUI = document.body.appendChild(
  3.   document.createElement('div')
  4. );
  5. document.body.style.margin = 0;
  6. Object.assign(consoleUI.style, {
  7.   position: 'fixed',
  8.   bottom: 0,
  9.   width: '100%',
  10.   height: '30%',
  11.   maxHeight: '450px',
  12.   minHeight: '200px',
  13.   background: 'rgb(68, 68, 81)',
  14.   overflow: 'scroll'
  15. });
  16. function consoleRow(str) {
  17.   const row = document.createElement('div');
  18.   consoleUI.prepend(row);
  19.   row.innerText = str;
  20.   Object.assign(row.style, {
  21.     padding: '.5em',
  22.     fontFamily: 'sans-serif',
  23.     color: 'white',
  24.     borderBottom: '1px solid rgba(255, 255, 255, .1)',
  25.     whiteSpace: 'pre-wrap'
  26.   });
  27. }
  28.  
  29. console.log = (...args) => {
  30.   const formatted = args.map(val => {
  31.     return typeof val === 'object' ? 
  32.       JSON.stringify(val, null, 2) : val;
  33.   });
  34.   consoleRow(formatted.join(' '));
  35.   log.apply(console, args);
  36. };
  37.  
  38. // test it out
  39.  
  40. console.log(1, 2, 3, 4);
  41. console.log(new Date());
  42.  
  43. const someObject = {
  44.   test: 123,
  45.   testing: { x: 1, y: 2, z: 3 }
  46. };
  47. console.log(someObject);
  48.  
  49. console.log(3, 2, 1, 0);

I’m thinking about adding a little fake console to the Snippet Zone Quick Editor – just whipped this up as a proof of concept – something like this should work…

// css // hacks // javascript // meta // strings // tricks // ui

Range Slider and Progress Bar

  1. const NUM = 8;
  2. const NUM_M_1 = NUM - 1;
  3. const ui = document.createElement('div')
  4. ui.innerHTML = `
  5.   <div class="ui">
  6.     <div class="progress" data-ref>
  7.       <div class="progressFill" data-ref></div>
  8.     </div>
  9.     <div class="text" data-ref>
  10.     0% of 100%
  11.     </div>
  12.  
  13.     <div class="dots" data-ref>
  14.     ${
  15.       `<div></div>`.repeat(NUM)
  16.     }
  17.     </div>
  18.  
  19.     <label>
  20.       drag the slider...
  21.       <input class="slider" type="range" min="0" max="100" step="1" value="0" data-ref/>
  22.     </label>
  23.   </div>
  24.   <style>
  25.     body {
  26.       font-family: sans-serif;
  27.     }
  28.     .progress, .dots {
  29.       position: relative;
  30.       width: 80%;
  31.       margin: 0 auto;
  32.       height: 30px;
  33.       border: 1px solid black;
  34.     }
  35.     .progressFill {
  36.       height: 100%;
  37.       width: 0;
  38.       background: red;
  39.     }
  40.     .text {
  41.       padding: 1em;
  42.       background: #ccc;
  43.       margin: .5em;
  44.       font-weight: bold;
  45.     }
  46.     label {
  47.       display: block;
  48.       margin: 1em;
  49.     }
  50.     .slider {
  51.       cursor: pointer;
  52.     }
  53.     .dots {
  54.       border: none;
  55.     }
  56.     .dots div {
  57.       height: 100%;
  58.       width: ${100 / NUM}%;
  59.       float: left;
  60.       transition: background 400ms ease-out;
  61.       background: transparent;
  62.       border-radius: 500px;
  63.       box-shadow: inset 0 0px 0 3px blue;
  64.     }
  65.     .dots div:nth-child(1) {
  66.       background: red;
  67.     }
  68.  
  69.   </style>
  70. `;
  71. document.body.appendChild(ui);
  72.  
  73. // select everything with a `data-ref`
  74. const els = {};
  75. ;[...document.querySelectorAll('[data-ref]')]
  76.   .forEach(el => {
  77.     els[el.classList[0]] = el;
  78.   });
  79.  
  80. function update(e) {
  81.  
  82.   // normal prog bar
  83.   const val = e.target.value;
  84.   els.progressFill.style.width = `${val}%`;
  85.   els.text.innerHTML = `
  86.     ${val}% of 100%
  87.   `;
  88.  
  89.   // segmented dot prog bar
  90.   const idx = Math.floor(val / (100 / NUM));
  91.   if (idx < NUM) { 
  92.     for (let i = 0; i < NUM; i++) {
  93.       els.dots.children[i]
  94.         .style.background = i <= idx ? 'red' : 'white'
  95.     }
  96.   }
  97. }
  98.  
  99. els.slider.addEventListener('input', update);
  100. els.slider.addEventListener('change', update);

Drag slider and watch two progress bars and a text readout update. There are some interesting vanilla tricks in this one.

This trick and a variety of variations on it is pretty powerful:

  1. const els = {};
  2. [...document.querySelectorAll('[data-ref]')].forEach(el => {
  3.   els[el.classList[0]] = el;
  4. });
// css // dom // graphics // javascript // math // strings // tricks // ui

Replace with “O”

  1. const txt = document.body.appendChild(
  2.   document.createElement('textarea')
  3. );
  4.  
  5. document.body.style.margin = 0;
  6. Object.assign(txt.style, {
  7.   position: 'relative',
  8.   width: '90%',
  9.   fontSize: '1.5em',
  10.   borderRadius: 0,
  11.   padding: '1em',
  12.   outline: 'none'
  13. });
  14. txt.setAttribute('placeholder', 'enter some text');
  15.  
  16. const result = document.body.appendChild(
  17.   document.createElement('div')
  18. );
  19.  
  20. Object.assign(result.style, {
  21.   padding: '1em', 
  22.   fontSize: '2em'
  23. });
  24.  
  25. txt.addEventListener('input', () => { 
  26.   result.innerHTML = txt.value.replace(/[aeiou]/gi, 'o');
  27. });

This snippet takes input into a textfield and replaces all vowels with the letter “o”. I saw a meme that did something like this with musical instruments piano = poono, guitar = gootor etc..

// css // dom // regex // strings

Mini Markdown with Lists

  1.   const isLi = val => val.match(/(^\s+)?- /)
  2.  
  3.   function mark(str) {
  4.     const lines = str.split`\n`;
  5.     let wasLi = false
  6.     let lastDepth = 0;
  7.     let depth;
  8.  
  9.   for (let i = 0; i < lines.length; i++) {
  10.     let curr = lines[i];
  11.     const line = curr.trim();
  12.     const hdr = line.split`#`.length - 1;
  13.  
  14.     if (line === '') {
  15.       lines[i] = '<br>';
  16.     } else if (hdr > 0) {
  17.       lines[i] = `<h${hdr} style="margin-bottom:0">
  18.         ${curr.replace(/#/g, '')}</h${hdr}>`;
  19.     } else if (line === '***') {
  20.       lines[i] = '<hr>';
  21.     } else if (isLi(curr)) {
  22.       depth = curr.split('-')[0].length + 1;
  23.  
  24.       lines[i] = '';
  25.       if (depth < lastDepth) {
  26.         const diff = (lastDepth - depth) / 2
  27.  
  28.         lines[i] += '</ul>'.repeat(diff);
  29.         lastDepth = depth 
  30.       }
  31.  
  32.       lines[i] += `${depth > lastDepth ? '<ul>' : ''}
  33.         <li>${curr.replace(/-\s+/, '')}</li>`;
  34.  
  35.       lastDepth = depth;
  36.  
  37.       wasLi = true;
  38.     } else if (wasLi) {
  39.       lines[i - 1] = '</ul>\n'.repeat(lastDepth)
  40.       wasLi = false
  41.     }
  42.   }
  43.  
  44.   return lines.join`\n`
  45.     .replace(/\*\*(.+)\*\*/gm, '<b>$1</b>')
  46.     .replace(/_(.+)_/gm, '<i>$1</i>')
  47.     .replace(/~~(.+)~~/gm, '<strike>$1</strike>')
  48.     .replace(/`(.+)`/gm, '<code>$1</code>');
  49. }
  50.  
  51. // try it out
  52.  
  53. const md = document.body.appendChild(document.createElement('div'));
  54. md.style.fontFamily = 'sans-serif';
  55. md.innerHTML = `
  56. #Snippet Zone
  57.  
  58. This snippet renders a subset of markdown. 
  59.  
  60. - **bold** and _italic text_
  61. - lists 
  62.   - this particulate
  63.     - snippet can render 
  64.     - nested
  65.   - lists
  66.  
  67. - _**~~strikethrough text~~**_
  68.  
  69. In a real project you will probably want to use
  70. something more complete like the great <a href="https://github.com/markedjs/marked" target="blank" rel="noopener">marked.js</a> library.
  71. `;
  72. md.innerHTML = mark(md.innerHTML);

This snippet renders a small subset of markdown. This is the same as a post from the other day with the addition of support for nested lists.

Mini Markdown Parser

  1. function mark(str) {
  2.   const lines = str.split`\n`;
  3.   let wasLi;
  4.  
  5.   for (let i = 0; i < lines.length; i++) {
  6.     const curr = lines[i];
  7.     const line = curr.trim();
  8.     const hdr = line.split`#`.length - 1;
  9.  
  10.     if (line === '') { 
  11.       lines[i] = '<br>';
  12.     } else if (hdr > 0) {
  13.       lines[i] = `<h${hdr} style="margin-bottom:0">
  14.         ${curr.replace(/#/g, '')}</h${hdr}>`;
  15.     } else if (line === '***') {
  16.       lines[i] = '<hr>';
  17.     } else if (line.startsWith('- ')) {
  18.       lines[i] = `${!wasLi ? '<ul>' : ''}
  19.         <li>${curr.replace(/-\s+/, '')}</li>`;
  20.       wasLi = true;
  21.     } else if (wasLi) {
  22.       lines[i - 1] += '</ul>\n';
  23.       wasLi = false;
  24.     }
  25.   }
  26.  
  27.   return lines.join`\n`
  28.     .replace(/\*\*(.+)\*\*/gm, '<b>$1</b>')
  29.     .replace(/_(.+)_/gm, '<i>$1</i>')
  30.     .replace(/~~(.+)~~/gm, '<strike>$1</strike>')
  31.     .replace(/`(.+)`/gm, '<code>$1</code>');
  32. }
  33.  
  34. // try it out
  35.  
  36. const md = document.body.appendChild(document.createElement('div'));
  37. md.style.fontFamily = 'sans-serif';
  38. md.innerHTML = `# Mini Markdown Subset
  39.  
  40. This is a subset of markdown stuff
  41.  
  42. ## It includes
  43.  
  44. - headers
  45. - **bold styles**
  46. - _italic styles, <br> multiline fine..._
  47. - \`code style\`
  48.  
  49. Other than ~~strikethrough~~ that is pretty much it... oh and **hr** tags
  50. ***
  51. ***
  52. _here is some italic text with some bold text **nested** <br>within it etc..._
  53. `;
  54. md.innerHTML = mark(md.innerHTML);

This code takes a string and formats a few parts of it with markdown syntax. This only handles a small subset of actual markdown.

I was thinking about markdown in code comments last night as I was working on a forthcoming snippet.zone github repo. Anyway, I decided to speed-code the main things I find myself using in markdown so that maybe I can do markdown formatted comments at some point…

snippet.zone ~ 2021-24 /// {s/z}