O
G
botemiungbamilafont-size: max(1.6em, calc(16px + (22 - 16) * ((100vw - 500px) / (790 - 500))))^_^, For web devs
font-size: max(1.6em, calc(16px + (22 - 16) * ((100vw - 500px) / (790 - 500))))^_^, For web devs
Both individual svg files and svg sprites are supported
spritesfolder.Draft 1#
Draft 2#
Draft 3#
Draft 4#
The core of the algorithm uses the dynamic rgx object below. The result of
FileList[i++].text().then(text=>{
arr = text.split(rgx.tag(<input>.value||'symbol'))
})
is an array that gets looped over via
requestAnimationFrame((id, el)=>{
(el = arr.shift())?el.replace(rgx[attr](<input>.value)||rgx['all attributes'], attr=>/**/):cancelAnimationFrame(id)
})
let rgx = {
'all attributes': /[^,>]+/,
attr: _=>new RegExp(`\\s${_}\\s*=\\s*("|')[^,("|')]+("|')`),
tag: _=>new RegExp(`<${_}`)
}
web development skills used in the previous section
React, it has become an industry default to use these "frameworks" for large projects. However, novel bugs require novel solutions and slapping on a feature that is foreign to the core of the framework of choice will only lead to more added features masked as updates with, of course, backwards incompatibilities
with codes written in earlier versions.TailwindCSSframework sparingly for rapid prototyping only. The problem of increase in markup due to the atomic CSS approach is solved by fetching both the markup and/or its contents using AJAXCSS class on this site - tooltip, has all its declarations written by "hand" because custom designs require custom styles. Any CSS framework hoping to augument such custom styling to its existing codebase may as well become a CSS library instead, the only catch being that they are uncommon and needless with good reason.npm -v && node -v: 9.5.1 && v16.15.1
<div class="scroller"> <section class="card settings">
<form class="settings-form" action="/set" method="POST">
<h1>Connection to server</h1>
<div class="warning">
<p>You browser doesn't support the fetch API, so this won't work. Try Chrome or Firefox.</p>
</div>
{{#each connectionTypes}}
<div>
<label class="material-radio">
<input type="radio" name="connectionType" value="{{value}}" {{#if checked}}checked{{/if}}>
<span class="material-radio-btn"></span>
<span class="material-radio-text">{{title}}</span>
</label>
</div>
{{/each}}
</form>
</section>
<section class="card settings tester">
<form class="test-form">
<h1>Test results</h1>
<p>During the course you'll be able to come here and run tests to verify everything
is working as expected.</p>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input test-id" type="text" id="testId" name="testId" />
<label class="mdl-textfield__label" for="testId">Test ID</label>
</div>
<div class="feedback-text"></div>
<div class="meme-container"><div class="meme-img-container"></div></div>
</form></section> </div> <script>
var config = {
appPort: {{appPort}}}; </script>
index.jsfile as followslet Handlebars = require('handlebars'),
settings = Handlebars
.compile(fs
.readFileSync('./templates/settings.hbs',
'utf-8'));
settingsTemplate({/**/});
console.time('alternate'),
settings({/**/}),
console.timeEnd('alternate')
module.exports = function(arg) { return `<div class="scroller"> <section class="card settings"> <form class="settings-form" action="/set" method="POST"> <h1>Connection to server</h1> <div class="warning"> <p>You browser doesn't support the fetch API, so this won't work. Try Chrome or Firefox.</p> </div>` + arg.connectionTypes.map(conType=>`<div> <label class="material-radio"> <input type="radio" name="connectionType" value="${conType.value}" ${conType.checked && 'checked' || ''}> <span class="material-radio-btn"></span> <span class="material-radio-text">${conType.title}</span> </label> </div>`).join('\n') + ` </form> </section> <section class="card settings tester"> <form class="test-form"> <h1>Test results</h1> <p> During the course you'll be able to come here and run tests to verify everything is working as expected. </p> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <input class="mdl-textfield__input test-id" type="text" id="testId" name="testId" /> <label class="mdl-textfield__label" for="testId">Test ID</label> </div> <div class="feedback-text"></div> <div class="meme-container"><div class="meme-img-container"></div></div> </form> </section> </div> <script> var config = { appPort: ${arg.appPort} }; </script>` }
//require'd as a module or package
let settings = require('./templates/settings');
settings({/**/})
console.time('alternate'), settings({/**/}),
console.timeEnd('alternate')
1
2of1msServing HTML templates in Nodejs
npm -v && node -v: 9.5.1 && v16.15.1
const all = ['link', 'script', 'title', 'body_attrs', 'html_attrs', 'title', 'meta', 'page', 'style', 'headScript', 'bodyScript'], place = {}; all.forEach(e=>place[e] = `__::${e}::__`); /* Usage: let wrapper = wrapInHTML({}); wrapper.place['script'] places <script __::script::__></script> for a value to be slotted in via wrapInHTML.slotIn({script:["src=... integrity=... async"]}) */ function wrapInHTML(settings/*, other parameters: link, script, ...*/) { /* link = settings.link||['__::link::__'], script = settings.script||['__::script::__'], html_attrs = ' '+(settings.html_attrs||'__::html_attrs::__'), title = settings.title||'__::title::__' meta = settings.meta||'__::meta::__', page = settings.page||'__::page::__', body_attrs = ' '+(settings.body_attrs||'__::body_attrs::__'), style = settings.style||['__::style::__'], headScript = settings.headScript||'__::headScript::__', bodyScript = settings.bodyScript||'__::bodyScript::__'; */ result = `<!DOCTYPE HTML> \t<html${html_attrs}> \t\t<head> \t\t\t<title>${title}</title> \t\t\t${meta.replace(/\n/g, '\n\t\t\t')} `; link.forEach(e=>{ result += `\t\t\t<link${(' '+e).replace(/^\s+/, ' ')}> `}) /* ... and so on. The value of result is retained in this function for use by the helper functions below until changed by calling wrapInHTML({/**/}) */ wrapInHTML.slotIn =(obj, str)=> { /* obj is similar to settings above and it is used to slot in custom fields to the value of result gotten by the most recent call of wrapInHTML({/**/}). Does not modify the internal value of result */ } wrapInHTML.cleanse = function(str) { str ||=result; /* modifies unused attributes such as <script __::script::__></script> into <script></script>. Does not modify the internal value of result */ return str; } return result; } module.exports = {wrapInHTML, place};
const wrapper = require('./utils/wrap-in-html'), wrapInHTML = wrapper.wrapInHTML; let home, about, template = wrapInHTML({ link:['rel="shortcut icon" href="../favicon.ico"', 'rel="stylesheet" href="css/build.css" preload="true"', 'rel="stylesheet" href="css/tailwind.min.css"', 'rel="stylesheet" href="css/all.min.css"'], script: ['src="js/ripples.js" defer=true', 'src="js/utils.js"', wrapper.place['script']], meta:`<meta charset="utf-8"> <!-- <meta http-equiv="refresh" content="3"> --> <meta name="theme-color" content="#ff056"> <meta name="color-scheme" content="light"> <meta name="viewport" content="width=device-width, initial-scale=1.0">`, }); home = wrapInHTML.slotIn({ script: ['src="js/optimized.js"', 'src="js/deferred.js" defer=true'], link:['rel="stylesheet" href="css/glitch-hero-image.css"'], title: '<Website name> | <keywords>, page: '<body.innerHTML>', style:[`* {box-sizing:border-box}`], headScript: 'let w = window;', bodyScript: 'w.onload=function(){/**/}', }), about = wrapInHTML.slotIn({ script: ['src="js/deferred_2.js" defer=true'], title: '<Website name> | <keywords>, page: partial, style:[`* {box-sizing:border-box}`], headScript: 'let w = window;', bodyScript: 'w.onload=function(){/**/}', html_attrs: 'data-scroll="0"' })
Manipulating DOMStrings in Node.js
${window.location.href}
pageData to store key nodes, Nodelists and functions as properties or as nested objects. Other needed nodes are then accessed via their parent, sibling, child relationships with these key nodes.pageData.article_1.nav,the code to collapse or expand it onclick or (body > main).onscroll uses pageData.article_1.nav_arrwhich gets defined when the collapse button on nav gets clicked the very first time as followsHTMLButtonElement.onclick = function() {
let pN=this.parentNode;
(pageData.article_1.nav_arr||=
slice(pN.children, 0, 2))
/* other scripts */
}
pageDate.article_1.nav_arr is defined, the expanded state of nav at the beginning of the page and during scrolling become defaults with no JavaScriptobjWalk is defined with abbreviations set through objWalk.setDict(['classList', 'previousSibling', 'nextSibling', 'lastChild', 'firstChild', 'nextElementSibling', 'previousElementSibling', 'parentNode', 'lastElementChild', 'childNodes', 'firstElementChild'])
which defines objWalk.dictas{ "fEC":"firstElementChild", "cN":"childNodes","pN":"parentNode", "lEC":"lastElementChild", "pES":"previousElementSibling", "nES":"nextElementSibling", "fC":"firstChild","lC":"lastChild", "nS":"nextSibling", "pS":"previousSibling","cL":"classList" }
objWalkis used as followsobjWalk(<HTMLElement>, [{2:'pN'}, {2:'nES'}, 'cL'])
to access the classList of the two nextElementSiblings of the parent of the parent of <HTMLElement>### style.sh
#!/usr/bin/env bash
cat ./src/styles/*.scss | sass > ./public/dist.css
### script.sh
#!/usr/bin/env bash
cat ./src/scripts/*.js > ./public/dist.js
### build.sh
#!/usr/bin/env bash
./style.sh
./script.sh
It may be used in lieu of the more common task runners; gulp, grunt, jest, with or without Node.js
sourceblog.logrocket article on Node.js task runners vs. module bundlers