yumaikas gist felülvizsgálása 9 months ago. Revízióhoz ugrás
1 file changed, 1 insertion
contrast-checker.html
| @@ -51,6 +51,7 @@ body { | |||
| 51 | 51 | </div> | |
| 52 | 52 | <button id="btn-share">Copy Link</button> | |
| 53 | 53 | <a id="a-share" href="/">(link if button doesn't work)</a> | |
| 54 | + | </p> | |
| 54 | 55 | </template> | |
| 55 | 56 | ||
| 56 | 57 | <script src="hex.js"></script> | |
yumaikas gist felülvizsgálása 9 months ago. Revízióhoz ugrás
2 files changed, 169 insertions, 14 deletions
contrast-checker.html(fájl létrehozva)
| @@ -0,0 +1,141 @@ | |||
| 1 | + | <!DOCTYPE html> | |
| 2 | + | <html> | |
| 3 | + | <head> | |
| 4 | + | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| 5 | + | <title>Discord Color Role Contrast Checker</title> | |
| 6 | + | </head> | |
| 7 | + | <style> | |
| 8 | + | body { | |
| 9 | + | margin-left: auto; | |
| 10 | + | margin-right: auto; | |
| 11 | + | max-width: 600px; | |
| 12 | + | text-align: center; | |
| 13 | + | color: white; | |
| 14 | + | background: #000; | |
| 15 | + | } | |
| 16 | + | ||
| 17 | + | a:visited { | |
| 18 | + | color: yellow; | |
| 19 | + | } | |
| 20 | + | ||
| 21 | + | .two-grid { | |
| 22 | + | display: grid; | |
| 23 | + | grid-template-columns: 1fr 1fr; | |
| 24 | + | width: 100%; | |
| 25 | + | color: var(--test-color, #476fbf); | |
| 26 | + | } | |
| 27 | + | ||
| 28 | + | .two-grid div { | |
| 29 | + | padding-top: 2rem; | |
| 30 | + | padding-bottom: 2rem; | |
| 31 | + | } | |
| 32 | + | ||
| 33 | + | .bg-white { font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; font-weight: bold; background-color: white; } | |
| 34 | + | .bg-discord { font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; font-weight: bold; background-color: #36393E; } | |
| 35 | + | ||
| 36 | + | </style> | |
| 37 | + | <body class=""> | |
| 38 | + | <h2>Discord Role Color Contrast Checker</h2> | |
| 39 | + | <div id="app"></div> | |
| 40 | + | ||
| 41 | + | <template id="root"> | |
| 42 | + | <input type="color" value="#476fbf" id="color-picker" /> | |
| 43 | + | <p>Contrast of <span id="color-1"/> | |
| 44 | + | <div class="two-grid"> | |
| 45 | + | <div class="bg-white"> | |
| 46 | + | <p>vs. white: <span id="white-contrast"></span>:1</p> | |
| 47 | + | </div> | |
| 48 | + | <div class="bg-discord"> | |
| 49 | + | <p>vs discord dark: <span id="discord-contrast"></span>:1</p> | |
| 50 | + | </div> | |
| 51 | + | </div> | |
| 52 | + | <button id="btn-share">Copy Link</button> | |
| 53 | + | <a id="a-share" href="/">(link if button doesn't work)</a> | |
| 54 | + | </template> | |
| 55 | + | ||
| 56 | + | <script src="hex.js"></script> | |
| 57 | + | <script> | |
| 58 | + | hex.arise(function() { | |
| 59 | + | function relativeLuminanceW3C(R8bit, G8bit, B8bit) { | |
| 60 | + | ||
| 61 | + | const RsRGB = R8bit/255; | |
| 62 | + | const GsRGB = G8bit/255; | |
| 63 | + | const BsRGB = B8bit/255; | |
| 64 | + | ||
| 65 | + | const R = (RsRGB <= 0.03928) ? RsRGB/12.92 : Math.pow((RsRGB+0.055)/1.055, 2.4); | |
| 66 | + | const G = (GsRGB <= 0.03928) ? GsRGB/12.92 : Math.pow((GsRGB+0.055)/1.055, 2.4); | |
| 67 | + | const B = (BsRGB <= 0.03928) ? BsRGB/12.92 : Math.pow((BsRGB+0.055)/1.055, 2.4); | |
| 68 | + | ||
| 69 | + | // For the sRGB colorspace, the relative luminance of a color is defined as: | |
| 70 | + | const L = 0.2126 * R + 0.7152 * G + 0.0722 * B; | |
| 71 | + | return L; | |
| 72 | + | } | |
| 73 | + | ||
| 74 | + | function hexToRGB8(color) { | |
| 75 | + | const r = Number.parseInt(color.slice(1, 3), 16); | |
| 76 | + | const g = Number.parseInt(color.slice(3, 5), 16); | |
| 77 | + | const b = Number.parseInt(color.slice(5, 8), 16) | |
| 78 | + | ||
| 79 | + | return {r,g,b} | |
| 80 | + | } | |
| 81 | + | ||
| 82 | + | function luminanceOfHex(color) { | |
| 83 | + | const {r,g,b} = hexToRGB8(color); | |
| 84 | + | return relativeLuminanceW3C(r,g,b); | |
| 85 | + | } | |
| 86 | + | ||
| 87 | + | const white_lum = luminanceOfHex("#FFFFFF"); | |
| 88 | + | const discord_lum = luminanceOfHex("#36393E"); | |
| 89 | + | ||
| 90 | + | const root = hex.spell("#root", { | |
| 91 | + | init(arg) { | |
| 92 | + | this.setColor(arg.color || "#4764bf"); | |
| 93 | + | this.$doc = document.documentElement; | |
| 94 | + | }, | |
| 95 | + | setColor(color) { | |
| 96 | + | const color_lum = luminanceOfHex(color); | |
| 97 | + | this.$doc.style.setProperty('--test-color', color); | |
| 98 | + | ||
| 99 | + | const white_contrast = (Math.max(white_lum, color_lum)+0.05) / (Math.min(white_lum, color_lum)+0.05); | |
| 100 | + | const discord_contrast = (Math.max(discord_lum, color_lum)+0.05) / (Math.min(discord_lum, color_lum)+0.05); | |
| 101 | + | ||
| 102 | + | this.colorName = color; | |
| 103 | + | this.whiteContrast = white_contrast.toFixed(1); | |
| 104 | + | this.discordContrast = discord_contrast.toFixed(1); | |
| 105 | + | const link = `https://contrast.junglecoder.com/${curr_color}` | |
| 106 | + | this.$toShare.href = link; | |
| 107 | + | } | |
| 108 | + | picker: ["#color-picker", { on: { | |
| 109 | + | change(e) { | |
| 110 | + | this.setColor(e.target.value); | |
| 111 | + | } | |
| 112 | + | }}], | |
| 113 | + | colorName: ["#color-1"], | |
| 114 | + | whiteContrast: ["#white-contrast"], | |
| 115 | + | darkContrast: ["#discord-contrast"], | |
| 116 | + | toShare: ["#a-share"], | |
| 117 | + | shareBtn: ["#btn-share", { | |
| 118 | + | t: 'Copy Link', | |
| 119 | + | on: { | |
| 120 | + | async click() { | |
| 121 | + | const link = `https://contrast.junglecoder.com/${this.colorName}` | |
| 122 | + | try { | |
| 123 | + | await navigator.clipboard.writeText(link) | |
| 124 | + | } finally { | |
| 125 | + | this.toShare = "Manually copy link from here"; | |
| 126 | + | } | |
| 127 | + | } | |
| 128 | + | } | |
| 129 | + | }] | |
| 130 | + | }); | |
| 131 | + | const urlParams = new URLSearchParams(window.location.search); | |
| 132 | + | let firstColor = window.loation.hash || urlParams.get('c') || "#4764bf"; | |
| 133 | + | if (firstColor[0] !== "#") { | |
| 134 | + | firstColor = "#" + firstColor; | |
| 135 | + | } | |
| 136 | + | console.log('FIRST COLOR', firstColor); | |
| 137 | + | hex.become(root, hex.id('app'), { color: firstColor }); | |
| 138 | + | }); | |
| 139 | + | </script> | |
| 140 | + | </body> | |
| 141 | + | </html> | |
hex.js
| @@ -9,11 +9,10 @@ const hex = (function() { | |||
| 9 | 9 | const recall = (k) => JSON.parse(localStorage.getItem(k) || "null"); | |
| 10 | 10 | ||
| 11 | 11 | function setterFor(node) { | |
| 12 | - | switch (node.tagName) { | |
| 13 | - | case "INPUT": | |
| 14 | - | return (val) => node.value = val; | |
| 15 | - | default: | |
| 16 | - | return (val) => { node.innerText = val; }; | |
| 12 | + | if (["INPUT", "TEXTAREA"].indexOf(node.tagName) > -1) { | |
| 13 | + | return (val) => node.value = val; | |
| 14 | + | } else { | |
| 15 | + | return (val) => node.innerText = val; | |
| 17 | 16 | } | |
| 18 | 17 | } | |
| 19 | 18 | ||
| @@ -34,6 +33,13 @@ const hex = (function() { | |||
| 34 | 33 | return toClone.content.cloneNode(true); | |
| 35 | 34 | } | |
| 36 | 35 | ||
| 36 | + | function become(spell, el, config) { | |
| 37 | + | // TODO: Figure out a way for replaceChildren to work | |
| 38 | + | el.replaceChildren(); | |
| 39 | + | spell(el, config); | |
| 40 | + | } | |
| 41 | + | ||
| 42 | + | ||
| 37 | 43 | function spell(template, config) { | |
| 38 | 44 | ||
| 39 | 45 | return function(into, start) { | |
| @@ -60,6 +66,8 @@ const hex = (function() { | |||
| 60 | 66 | const el = q1(basis, v); | |
| 61 | 67 | state.dom[k] = el; | |
| 62 | 68 | makeProp(el, start[k]); | |
| 69 | + | } else if (typeof v === "function") { | |
| 70 | + | interface[k] = v.bind(interface); | |
| 63 | 71 | } else if (Array.isArray(v)) { | |
| 64 | 72 | if (v.length <= 0) { | |
| 65 | 73 | throw new Error("Empty array not valid!"); | |
| @@ -80,6 +88,9 @@ const hex = (function() { | |||
| 80 | 88 | } else if (v.length == 2 && (typeof v[0]) === "string" && isObj(v[1])) { | |
| 81 | 89 | makeProp(el, start[k]); | |
| 82 | 90 | const obj = v[1]; | |
| 91 | + | if (obj.t) { | |
| 92 | + | interface[k] = start[k] || obj.t; | |
| 93 | + | } | |
| 83 | 94 | if (obj.on) { | |
| 84 | 95 | for (const [evt, fn] of Object.entries(obj.on)) { | |
| 85 | 96 | let inner = fn.bind(interface); | |
| @@ -98,17 +109,19 @@ const hex = (function() { | |||
| 98 | 109 | } | |
| 99 | 110 | if (obj.init && typeof obj.init === "function") { | |
| 100 | 111 | obj.init.call(interface, start); | |
| 101 | - | } | |
| 112 | + | } | |
| 102 | 113 | ||
| 103 | - | } else if (v.length === 2 && | |
| 114 | + | } else if (v.length === 3 && | |
| 104 | 115 | (typeof v[0]) === "string" && | |
| 105 | - | (typeof v[1]) === "function" | |
| 116 | + | (typeof v[1]) === "function" && | |
| 117 | + | (typeof v[2]) === "function" | |
| 106 | 118 | && Array.isArray(start[k]) | |
| 107 | 119 | ) { | |
| 108 | - | state.vars[k] = start[k].map((data) => v[1](el, data)); | |
| 120 | + | // TODO: | |
| 121 | + | state.vars[k] = start[k].map((data) => v[1](el, v[2](data))); | |
| 109 | 122 | interface[k] = function(new_data) { | |
| 110 | - | el.innerHTML = ""; | |
| 111 | - | state.vars[k] = new_data.map((data) => v[1](el, data)); | |
| 123 | + | el.replaceChildren(); | |
| 124 | + | state.vars[k] = new_data.map((data) => v[1](el, v[2](data))); | |
| 112 | 125 | } | |
| 113 | 126 | } else { | |
| 114 | 127 | throw new Error(`Invalid config: ${k}`); | |
| @@ -118,13 +131,14 @@ const hex = (function() { | |||
| 118 | 131 | ||
| 119 | 132 | interface._ = state; | |
| 120 | 133 | into.appendChild(basis); | |
| 134 | + | if (typeof interface.init === "function") { | |
| 135 | + | interface.init(start); | |
| 136 | + | } | |
| 121 | 137 | return interface; | |
| 122 | 138 | } | |
| 123 | 139 | } | |
| 124 | 140 | ||
| 125 | - | ||
| 126 | - | ||
| 127 | - | return {q, q1, id, from, arise, scrawl, recall, spell}; | |
| 141 | + | return {q, q1, id, from, arise, scrawl, recall, become, spell}; | |
| 128 | 142 | })(); | |
| 129 | 143 | ||
| 130 | 144 | window.hex = hex; | |
yumaikas gist felülvizsgálása 9 months ago. Revízióhoz ugrás
1 file changed, 115 insertions
affirmations_v2.html(fájl létrehozva)
| @@ -0,0 +1,115 @@ | |||
| 1 | + | <!DOCTYPE html> | |
| 2 | + | <html> | |
| 3 | + | ||
| 4 | + | <div id="app"></div> | |
| 5 | + | <style> | |
| 6 | + | ||
| 7 | + | #app, body { | |
| 8 | + | height: 100%; | |
| 9 | + | } | |
| 10 | + | #edit-affirmations { | |
| 11 | + | display: grid; | |
| 12 | + | grid-template-rows: 80% 20%; | |
| 13 | + | height: 80vh; | |
| 14 | + | } | |
| 15 | + | ||
| 16 | + | .affirmation { | |
| 17 | + | width: 100%; | |
| 18 | + | } | |
| 19 | + | .half-half { | |
| 20 | + | display: grid; | |
| 21 | + | grid-template-columns: 50% 50%; | |
| 22 | + | width: 100%; | |
| 23 | + | } | |
| 24 | + | .right-corner { | |
| 25 | + | width: 25%; | |
| 26 | + | justify-self: end; | |
| 27 | + | } | |
| 28 | + | .w-full { width: 100%; } | |
| 29 | + | .grid { display: grid; } | |
| 30 | + | ||
| 31 | + | #edit-affirmations textarea { | |
| 32 | + | height: 80%; | |
| 33 | + | } | |
| 34 | + | ||
| 35 | + | </style> | |
| 36 | + | ||
| 37 | + | <template id="mode-edit-affirmations"> | |
| 38 | + | <div id="edit-affirmations"> | |
| 39 | + | <textarea class="wide 80-tall" id="affirmation-list"></textarea> | |
| 40 | + | <button id="save-affirmations">Save!</button> | |
| 41 | + | </div> | |
| 42 | + | </template> | |
| 43 | + | <template id="mode-view-affirmations"> | |
| 44 | + | <div class="w-full grid"> | |
| 45 | + | <button id="go-to-edit-mode" class="right-corner"></button> | |
| 46 | + | </div> | |
| 47 | + | <div id="affirmation-list"></div> | |
| 48 | + | <div class="half-half"> | |
| 49 | + | <button id="add-affirmation">another</button> | |
| 50 | + | <button id="clear-affirmations">clear</button> | |
| 51 | + | </div> | |
| 52 | + | </template> | |
| 53 | + | <template id="affirmation"><h3 class="affirmation"></h3></template> | |
| 54 | + | ||
| 55 | + | <script src="hex.js"></script> | |
| 56 | + | <script> | |
| 57 | + | hex.arise(function() { | |
| 58 | + | let affirmation_idx = 0; | |
| 59 | + | ||
| 60 | + | let app = hex.id("app"); | |
| 61 | + | const get_affirmations = () => hex.recall("affirmations") || ["You need to add affirmations!"]; | |
| 62 | + | const next_affirmation = () => { | |
| 63 | + | const affirmations = get_affirmations().filter(x => !(/^\s+$/.test(x))); | |
| 64 | + | const ret = affirmations[affirmation_idx]; | |
| 65 | + | affirmation_idx = (affirmation_idx + 1) % affirmations.length; | |
| 66 | + | return ret; | |
| 67 | + | } | |
| 68 | + | ||
| 69 | + | var affirmHeader = hex.spell("#affirmation", { value: ".affirmation" }); | |
| 70 | + | ||
| 71 | + | var modeRecite = hex.spell("#mode-view-affirmations", { | |
| 72 | + | toEdit: ["#go-to-edit-mode", {t: "edit", on: { | |
| 73 | + | click() { | |
| 74 | + | hex.become(modeEdit, app, {affirmations: get_affirmations()}); | |
| 75 | + | } | |
| 76 | + | } }], | |
| 77 | + | affirmations: ["#affirmation-list", (el, affirmation) => affirmHeader(el, { value: affirmation })], | |
| 78 | + | another: ["#add-affirmation", | |
| 79 | + | { t: "another", | |
| 80 | + | init() { | |
| 81 | + | this._affirmations = []; | |
| 82 | + | this._next = () => { | |
| 83 | + | this._affirmations.push(next_affirmation()); | |
| 84 | + | this.affirmations(this._affirmations) | |
| 85 | + | } | |
| 86 | + | this._next(); | |
| 87 | + | }, | |
| 88 | + | on: { click() { this._next(); } } | |
| 89 | + | } | |
| 90 | + | ], | |
| 91 | + | clear: ["#clear-affirmations", {t: "clear", on: { click() { this._affirmations = []; this.affirmations([]); } } }] | |
| 92 | + | }); | |
| 93 | + | ||
| 94 | + | var modeEdit = hex.spell("#mode-edit-affirmations", { | |
| 95 | + | affirmations: ["#affirmation-list", { | |
| 96 | + | init(arg) { | |
| 97 | + | this.affirmations = arg.affirmations.join("\n"); | |
| 98 | + | this._affirmations = arg.affirmations || get_affirmations(); | |
| 99 | + | }, | |
| 100 | + | on: { input(e) { this._affirmations = e.target.value.split("\n"); } } | |
| 101 | + | }], | |
| 102 | + | ||
| 103 | + | save: ["#save-affirmations", | |
| 104 | + | { t:"save", on: { click() { | |
| 105 | + | console.log(this); | |
| 106 | + | hex.scrawl("affirmations", this._affirmations); | |
| 107 | + | hex.become(modeRecite, app, {affirmations: get_affirmations()}); | |
| 108 | + | }}} | |
| 109 | + | ], | |
| 110 | + | }); | |
| 111 | + | ||
| 112 | + | hex.become(modeRecite, app, {affirmations: get_affirmations()}); | |
| 113 | + | }); | |
| 114 | + | </script> | |
| 115 | + | </html> | |
yumaikas gist felülvizsgálása 9 months ago. Revízióhoz ugrás
1 file changed, 62 deletions
affirmations.html (fájl törölve)
| @@ -1,62 +0,0 @@ | |||
| 1 | - | <!DOCTYPE html> | |
| 2 | - | <html> | |
| 3 | - | ||
| 4 | - | <div id="app"></div> | |
| 5 | - | ||
| 6 | - | <script src="hex.js"></script> | |
| 7 | - | ||
| 8 | - | <template id="job-attr"> | |
| 9 | - | <dt><button class="key"></button></dt> | |
| 10 | - | <dd><pre class="value"></pre></dd> | |
| 11 | - | </template> | |
| 12 | - | ||
| 13 | - | <template id="job-row"> | |
| 14 | - | <dl class="job-content"></dl> | |
| 15 | - | <hr> | |
| 16 | - | </template> | |
| 17 | - | ||
| 18 | - | ||
| 19 | - | <script> | |
| 20 | - | let kvPair = hex.spell("#job-attr", { | |
| 21 | - | key: [".key", { init() { }, on: { click() { | |
| 22 | - | navigator.clipboard.writeText(this.value) | |
| 23 | - | } }}], | |
| 24 | - | value: ".value", // mutable | |
| 25 | - | }); | |
| 26 | - | ||
| 27 | - | let jobRow = hex.spell("#job-row", { | |
| 28 | - | jobFields: [".job-content", (el, [key, value]) => kvPair(el, {key, value})], | |
| 29 | - | }); | |
| 30 | - | ||
| 31 | - | hex.arise(function() { | |
| 32 | - | function job(employerName, city, state, position, startDate, endDate, | |
| 33 | - | contactName, email, phone) { | |
| 34 | - | return { | |
| 35 | - | employerName, city, state, position, startDate, endDate, contactName, email, phone | |
| 36 | - | } | |
| 37 | - | } | |
| 38 | - | let jobs = [ | |
| 39 | - | job("Shift Paradigm", "Austin", "Texas", "Senior Software Developer", "06 - 2021", "04 - 2024 ", | |
| 40 | - | "Michelle Hytry", "michelle.hytry@shiftparadigm.com", "512-717-4097"), | |
| 41 | - | job("Linquest Corporation", "Colorado Springs", "Colorado", "Staff Software Engineer", "08 - 2019", "06 - 2021", | |
| 42 | - | "Susan Kang", "susan.kang@linquest.com", "(719) 884-8400" ), | |
| 43 | - | job("Qdoba Corporation", "Colorado Springs", "Colorado", "Line Cook", "06 - 2019", "08 - 2019", | |
| 44 | - | "N/a", "N/a", "719-592-9701"), | |
| 45 | - | job("Burrito Concepts", "Joplin", "Missouri", "Line Cook", "02 - 2019", "06 - 2019", | |
| 46 | - | "N/a", "N/a", "417-782-5300"), | |
| 47 | - | job("Greenshades Software", "Jacksonville", "Florida", "Software Developer", "11 - 2017", "12 - 2018", | |
| 48 | - | "N/a", "hr@greenshades.com", "904-807-0160"), | |
| 49 | - | job("Genesis Global Technologies", "Ft. Myers", "Florida", "Software Developer", "09 - 2014", "11 - 2017", | |
| 50 | - | "Mona Hilton", "monah@genesisgt.com", "239-337-2667"), | |
| 51 | - | ]; | |
| 52 | - | let app_out = hex.q1("#app"); | |
| 53 | - | app_out.innerHTML = ""; | |
| 54 | - | window.J = []; | |
| 55 | - | for (let j of jobs) { | |
| 56 | - | window.J.push(jobRow(app_out, { | |
| 57 | - | jobFields: Object.entries(j), | |
| 58 | - | })); | |
| 59 | - | } | |
| 60 | - | }); | |
| 61 | - | </script> | |
| 62 | - | </html> | |
yumaikas gist felülvizsgálása 9 months ago. Revízióhoz ugrás
1 file changed, 62 insertions
affirmations.html(fájl létrehozva)
| @@ -0,0 +1,62 @@ | |||
| 1 | + | <!DOCTYPE html> | |
| 2 | + | <html> | |
| 3 | + | ||
| 4 | + | <div id="app"></div> | |
| 5 | + | ||
| 6 | + | <script src="hex.js"></script> | |
| 7 | + | ||
| 8 | + | <template id="job-attr"> | |
| 9 | + | <dt><button class="key"></button></dt> | |
| 10 | + | <dd><pre class="value"></pre></dd> | |
| 11 | + | </template> | |
| 12 | + | ||
| 13 | + | <template id="job-row"> | |
| 14 | + | <dl class="job-content"></dl> | |
| 15 | + | <hr> | |
| 16 | + | </template> | |
| 17 | + | ||
| 18 | + | ||
| 19 | + | <script> | |
| 20 | + | let kvPair = hex.spell("#job-attr", { | |
| 21 | + | key: [".key", { init() { }, on: { click() { | |
| 22 | + | navigator.clipboard.writeText(this.value) | |
| 23 | + | } }}], | |
| 24 | + | value: ".value", // mutable | |
| 25 | + | }); | |
| 26 | + | ||
| 27 | + | let jobRow = hex.spell("#job-row", { | |
| 28 | + | jobFields: [".job-content", (el, [key, value]) => kvPair(el, {key, value})], | |
| 29 | + | }); | |
| 30 | + | ||
| 31 | + | hex.arise(function() { | |
| 32 | + | function job(employerName, city, state, position, startDate, endDate, | |
| 33 | + | contactName, email, phone) { | |
| 34 | + | return { | |
| 35 | + | employerName, city, state, position, startDate, endDate, contactName, email, phone | |
| 36 | + | } | |
| 37 | + | } | |
| 38 | + | let jobs = [ | |
| 39 | + | job("Shift Paradigm", "Austin", "Texas", "Senior Software Developer", "06 - 2021", "04 - 2024 ", | |
| 40 | + | "Michelle Hytry", "michelle.hytry@shiftparadigm.com", "512-717-4097"), | |
| 41 | + | job("Linquest Corporation", "Colorado Springs", "Colorado", "Staff Software Engineer", "08 - 2019", "06 - 2021", | |
| 42 | + | "Susan Kang", "susan.kang@linquest.com", "(719) 884-8400" ), | |
| 43 | + | job("Qdoba Corporation", "Colorado Springs", "Colorado", "Line Cook", "06 - 2019", "08 - 2019", | |
| 44 | + | "N/a", "N/a", "719-592-9701"), | |
| 45 | + | job("Burrito Concepts", "Joplin", "Missouri", "Line Cook", "02 - 2019", "06 - 2019", | |
| 46 | + | "N/a", "N/a", "417-782-5300"), | |
| 47 | + | job("Greenshades Software", "Jacksonville", "Florida", "Software Developer", "11 - 2017", "12 - 2018", | |
| 48 | + | "N/a", "hr@greenshades.com", "904-807-0160"), | |
| 49 | + | job("Genesis Global Technologies", "Ft. Myers", "Florida", "Software Developer", "09 - 2014", "11 - 2017", | |
| 50 | + | "Mona Hilton", "monah@genesisgt.com", "239-337-2667"), | |
| 51 | + | ]; | |
| 52 | + | let app_out = hex.q1("#app"); | |
| 53 | + | app_out.innerHTML = ""; | |
| 54 | + | window.J = []; | |
| 55 | + | for (let j of jobs) { | |
| 56 | + | window.J.push(jobRow(app_out, { | |
| 57 | + | jobFields: Object.entries(j), | |
| 58 | + | })); | |
| 59 | + | } | |
| 60 | + | }); | |
| 61 | + | </script> | |
| 62 | + | </html> | |
yumaikas gist felülvizsgálása 9 months ago. Revízióhoz ugrás
1 file changed, 130 insertions
hex.js(fájl létrehozva)
| @@ -0,0 +1,130 @@ | |||
| 1 | + | const hex = (function() { | |
| 2 | + | const q = (el, sel) => !sel ? document.querySelectorAll(el) : el.querySelectorAll(sel); | |
| 3 | + | const id = (sel) => document.getElementById(sel); | |
| 4 | + | const q1 = (el, sel) => !sel ? document.querySelector(el) : el.querySelector(sel); | |
| 5 | + | const isObj = (obj) => { var type = typeof obj; return type === 'object' && !!obj; }; | |
| 6 | + | const isSimple = (v) => {var type = typeof v; return type=== "number" || type === "string" || type === "boolean"; } | |
| 7 | + | const arise = (fn) => document.addEventListener('DOMContentLoaded', fn, false); | |
| 8 | + | const scrawl = (k, v) => localStorage.setItem(k, JSON.stringify(v)); | |
| 9 | + | const recall = (k) => JSON.parse(localStorage.getItem(k) || "null"); | |
| 10 | + | ||
| 11 | + | function setterFor(node) { | |
| 12 | + | switch (node.tagName) { | |
| 13 | + | case "INPUT": | |
| 14 | + | return (val) => node.value = val; | |
| 15 | + | default: | |
| 16 | + | return (val) => { node.innerText = val; }; | |
| 17 | + | } | |
| 18 | + | } | |
| 19 | + | ||
| 20 | + | let templs = new Map(); | |
| 21 | + | function from(tempSel) { | |
| 22 | + | let toClone; | |
| 23 | + | if (templs.has(tempSel)) { | |
| 24 | + | toClone = templs.get(tempSel); | |
| 25 | + | } else { | |
| 26 | + | let n = q1(tempSel); | |
| 27 | + | if (n) { | |
| 28 | + | templs.set(tempSel, n); | |
| 29 | + | toClone = n; | |
| 30 | + | } else { | |
| 31 | + | throw tempSel + " failed"; | |
| 32 | + | } | |
| 33 | + | } | |
| 34 | + | return toClone.content.cloneNode(true); | |
| 35 | + | } | |
| 36 | + | ||
| 37 | + | function spell(template, config) { | |
| 38 | + | ||
| 39 | + | return function(into, start) { | |
| 40 | + | const basis = from(template) | |
| 41 | + | const state = { vars: {}, dom: {}, setters: {} }; | |
| 42 | + | const interface = Object.create(spell); | |
| 43 | + | const recursionGuard = new Set(); | |
| 44 | + | ||
| 45 | + | for (let [k, v] of Object.entries(config)) { | |
| 46 | + | const makeProp = (el, initialValue) => { | |
| 47 | + | state.setters[k] = setterFor(el); | |
| 48 | + | ||
| 49 | + | Object.defineProperty(interface, k, { | |
| 50 | + | get() { return state.vars[k] }, | |
| 51 | + | set(v) { | |
| 52 | + | state.vars[k] = v; | |
| 53 | + | state.setters[k]((v || "") + ""); | |
| 54 | + | } | |
| 55 | + | }); | |
| 56 | + | ||
| 57 | + | interface[k] = initialValue; | |
| 58 | + | } | |
| 59 | + | if (typeof v === "string" && v) { | |
| 60 | + | const el = q1(basis, v); | |
| 61 | + | state.dom[k] = el; | |
| 62 | + | makeProp(el, start[k]); | |
| 63 | + | } else if (Array.isArray(v)) { | |
| 64 | + | if (v.length <= 0) { | |
| 65 | + | throw new Error("Empty array not valid!"); | |
| 66 | + | } | |
| 67 | + | let el; | |
| 68 | + | if (typeof v[0] === "string") { | |
| 69 | + | el = q1(basis, v[0]); | |
| 70 | + | state.dom[k] = el; | |
| 71 | + | } else { | |
| 72 | + | throw new Error(`Selector for ${k} must be a string!`); | |
| 73 | + | } | |
| 74 | + | ||
| 75 | + | if (v.length == 1 && (typeof v[0]) == "string") { | |
| 76 | + | state.vars[k] = start[k]; | |
| 77 | + | makeProp(el, start[k]); | |
| 78 | + | } else if (v.length == 2 && (typeof v[0]) === "string" && isSimple(v[1])) { | |
| 79 | + | makeProp(el, start[k] || v[1]); | |
| 80 | + | } else if (v.length == 2 && (typeof v[0]) === "string" && isObj(v[1])) { | |
| 81 | + | makeProp(el, start[k]); | |
| 82 | + | const obj = v[1]; | |
| 83 | + | if (obj.on) { | |
| 84 | + | for (const [evt, fn] of Object.entries(obj.on)) { | |
| 85 | + | let inner = fn.bind(interface); | |
| 86 | + | let handler = function() { | |
| 87 | + | if (recursionGuard.has(handler)) { return; } | |
| 88 | + | try { | |
| 89 | + | recursionGuard.add(handler); | |
| 90 | + | inner(...arguments); | |
| 91 | + | } finally { | |
| 92 | + | recursionGuard.delete(handler); | |
| 93 | + | } | |
| 94 | + | }; | |
| 95 | + | ||
| 96 | + | el.addEventListener(evt, handler); | |
| 97 | + | } | |
| 98 | + | } | |
| 99 | + | if (obj.init && typeof obj.init === "function") { | |
| 100 | + | obj.init.call(interface, start); | |
| 101 | + | } | |
| 102 | + | ||
| 103 | + | } else if (v.length === 2 && | |
| 104 | + | (typeof v[0]) === "string" && | |
| 105 | + | (typeof v[1]) === "function" | |
| 106 | + | && Array.isArray(start[k]) | |
| 107 | + | ) { | |
| 108 | + | state.vars[k] = start[k].map((data) => v[1](el, data)); | |
| 109 | + | interface[k] = function(new_data) { | |
| 110 | + | el.innerHTML = ""; | |
| 111 | + | state.vars[k] = new_data.map((data) => v[1](el, data)); | |
| 112 | + | } | |
| 113 | + | } else { | |
| 114 | + | throw new Error(`Invalid config: ${k}`); | |
| 115 | + | } | |
| 116 | + | } | |
| 117 | + | } | |
| 118 | + | ||
| 119 | + | interface._ = state; | |
| 120 | + | into.appendChild(basis); | |
| 121 | + | return interface; | |
| 122 | + | } | |
| 123 | + | } | |
| 124 | + | ||
| 125 | + | ||
| 126 | + | ||
| 127 | + | return {q, q1, id, from, arise, scrawl, recall, spell}; | |
| 128 | + | })(); | |
| 129 | + | ||
| 130 | + | window.hex = hex; | |