From 73a916eac0e883ce40febd9c069fc74c6b129348 Mon Sep 17 00:00:00 2001 From: DenverCoder1 Date: Thu, 20 Oct 2022 23:51:13 +0000 Subject: [PATCH 1/6] Initial gh-pages commit From f1c76102d422f4b9c58343af943175355fc760b2 Mon Sep 17 00:00:00 2001 From: DenverCoder1 Date: Thu, 20 Oct 2022 23:51:13 +0000 Subject: [PATCH 2/6] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20Denv?= =?UTF-8?q?erCoder1/unicode-formatter@3bc74639d774b7b667902493c96af84d7c1d?= =?UTF-8?q?b4ba=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/style.css | 251 ++++++++++++++++++++++++++++++++++++++++++++++++ img/favicon.ico | Bin 0 -> 1150 bytes index.html | 168 ++++++++++++++++++++++++++++++++ js/accordion.js | 112 +++++++++++++++++++++ js/main.js | 199 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 730 insertions(+) create mode 100644 css/style.css create mode 100644 img/favicon.ico create mode 100644 index.html create mode 100644 js/accordion.js create mode 100644 js/main.js diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..d7ecc3c --- /dev/null +++ b/css/style.css @@ -0,0 +1,251 @@ +:root { + --text: black; + --background: #eaeaea; + --highlight: #038c78; + --border: #777777; + --border-hover: #333333; + --textarea: #fafafa; +} + +[data-theme="dark"] { + --text: white; + --background: #0d0f11; +} + +html { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +*, +*:before, +*:after { + -webkit-box-sizing: inherit; + -moz-box-sizing: inherit; + box-sizing: inherit; +} + +body { + background: var(--background); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 95vh; + width: 95vw; + margin: 0 auto; + max-width: 600px; + color: var(--text); +} + +body, +button, +textarea { + font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", + Roboto, Helvetica, Arial, sans-serif; +} + +.CodeMirror { + font-family: inherit; + font-size: 22px; + padding: 18px; + width: 100%; + min-height: 300px; +} + +button:focus, +summary:focus, +a:focus { + outline: none; + box-shadow: 0 0 0 2px var(--highlight); +} + +/* logo */ + +.logo { + display: flex; + justify-content: center; + margin: 1em auto 0.5em auto; + text-decoration: none; + color: var(--text); + font-size: 115%; + transition: color 0.2s ease-out; +} + +.logo:hover { + color: var(--highlight); +} + +a.logo img { + width: 100%; + max-width: 360px; +} + +/* controls */ + +.controls { + padding: 0.5em; + transition: all 0.4s ease-out; + width: 100%; +} + +.control-btns { + display: flex; + flex-wrap: wrap; + margin-top: 0.5em; +} + +.more-fonts summary { + margin: 0 0 12px 6px; + cursor: pointer; + border-radius: 2px; +} + +.controls button { + margin: 0.4em; + width: 30px; + height: 30px; + cursor: pointer; + background: inherit; + border: 1px solid var(--border); + color: var(--text); + border-radius: 2px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + transition: background 0.2s ease-in; +} + +.controls button:hover { + border-color: var(--border-hover); +} + +.more-fonts button { + padding: 0px +} + +/* textarea */ + +textarea { + width: 100%; + height: 294px; + border: none; + outline: none; + background: var(--textarea); + padding: 1em; + font-size: 1.4em; +} + +/* github buttons */ + +div.github { + display: flex; + justify-content: center; + align-items: center; + flex-wrap: wrap; +} + +.github span { + margin: 0 2px; +} + +/* buttons */ +.large-buttons { + display: flex; + justify-content: center; + align-items: center; +} + +.btn { + color: white; + font-size: 1.1em; + padding: 0.8em 1.1em; + border-radius: 28px; + display: flex; + justify-content: center; + align-items: center; + width: 134px; + text-decoration: none; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); + margin: 1.4em 0.5em 0 0.5em; + border: none; + outline: none; + cursor: pointer; +} + +.btn:hover { + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25), 0 6px 6px rgba(0, 0, 0, 0.22); +} + +.btn svg { + margin-right: 0.5em; +} + +.tweet-button { + background: #1da1f2; +} + +.tweet-button:hover { + background: #1a91da; +} + +.copy-to-clipboard-button { + background: #858585; +} + +.copy-to-clipboard-button:hover { + background: #727272; +} + +/* tooltips */ + +/* bubble */ +.controls button:before, +.large-buttons button:before { + content: attr(title); + height: auto; + width: auto; + position: absolute; + background: #4a4a4afa; + border-radius: 4px; + color: white; + line-height: 30px; + font-size: 1.1em; + padding: 0 12px; + transform: translate(0, -38px); + transition: all 0.2s ease-out; + pointer-events: none; + opacity: 0; +} + +/* triangle */ +.controls button:after, +.large-buttons button:after { + content: ""; + position: absolute; + border-style: solid; + border-color: #4a4a4afa transparent transparent transparent; + transform: translate(0, -20px); + transition: all 0.2s ease-out; + pointer-events: none; + opacity: 0; +} + +.large-buttons button:before { + font-size: 1em; + transform: translateY(-52px); +} + +.large-buttons button:after { + transform: translateY(-34px); +} + +.controls button:hover:before, +.large-buttons button:hover:before, +.controls button:hover:after, +.large-buttons button:hover:after { + opacity: 1; +} \ No newline at end of file diff --git a/img/favicon.ico b/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b0a8e0692f9644bc5a95a1eedad03714b30b388f GIT binary patch literal 1150 zcmaizNo*5W7{?zXlq)B$aH7ySb|7(_I0PFz_KcS-q)9TQGl$WAK8sW^HkUEBkb;J2#2BXsW0d<`>$4{&!EeeM#!2%cddw%{SwX}%wfA*L~msr{nc>{SOg52g=<5m=oizB zm5tfME9Ee(m&bTp4)<=C zr$L}^#orqJJ2y+%)?xT~F#&`uljx<|gsC=R@-bwKpXu-^|9S0Gn0RDp_719e^~~t+ zS}!By$U-3tk_d#GQdnOjqNkQPixZ$d`oBG(N)DTX->(~*eZzTNyHqN_oY<`*V9wyx z6C*d=n#CH6h;A!IO%f4%Qf>+6CFfEVH?A6U&i!1%>Cs~O<;t%`wAm#5{m{srIi#S+ znZY{RpAa#^jgzv!Mf;cMHQc`kJSX25&H|gm8eTjFF8)%)u84}HVCWN3U~IpN)~`}n zXG@{CNqpjKFPvWPEx<$J^=RFToG=a<0*h^*1)^-@DszgOu^cqf^3G)0r?OUz=K;r(41C7&WuSv15Lit zh|^bsi!Z@VoM|t7GckzcZB(#hP{UvMfj{p8Te}siOZKR))mx(<70Uv+?C=B2%bX&b zIa&|-;q>(o$3r#t+7<8(QwZAS@fA(EkNyFB05g~RF+yI_4!#H{`EZfmO?nUMIr71~ z)QsP$90@w7KKUm%ca%(?j?(v3mq&biLG-s3#6YX|xTPikLt9Wa8;;-Km3fT4oXyy+ VnT(ChFyejo$pQ~$h?K?-}XI=mR literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..8a822fa --- /dev/null +++ b/index.html @@ -0,0 +1,168 @@ + + + + + + + + + + + Unicode formatter + + + + + + + + + + + + + + + + + + + + +
+ + Sponsor + + View on GitHub + + Star +
+ + +
+ Fonts: +
+ + + + + + +
+
+ + +
+ More fonts +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+ + + \ No newline at end of file diff --git a/js/accordion.js b/js/accordion.js new file mode 100644 index 0000000..5846fd4 --- /dev/null +++ b/js/accordion.js @@ -0,0 +1,112 @@ +// Based on https://css-tricks.com/how-to-animate-the-details-element-using-waapi/ +class Accordion { + constructor(el) { + // Store the
element + this.el = el; + // Store the element + this.summary = el.querySelector("summary"); + // Store the
element + this.content = el.querySelector(".content"); + // Store the animation object (so we can cancel it if needed) + this.animation = null; + // Store if the element is closing + this.isClosing = false; + // Store if the element is expanding + this.isExpanding = false; + // Detect user clicks on the summary element + this.summary.addEventListener("click", (e) => this.onClick(e)); + } + + onClick(e) { + // Stop default behaviour from the browser + e.preventDefault(); + // Add an overflow on the
to avoid content overflowing + this.el.style.overflow = "hidden"; + // Check if the element is being closed or is already closed + if (this.isClosing || !this.el.open) { + this.open(); + // Check if the element is being openned or is already open + } else if (this.isExpanding || this.el.open) { + this.shrink(); + } + } + + shrink() { + // Set the element as "being closed" + this.isClosing = true; + // Store the current height of the element + const startHeight = `${this.el.offsetHeight}px`; + // Calculate the height of the summary + const endHeight = `${this.summary.offsetHeight}px`; + // If there is already an animation running + if (this.animation) { + // Cancel the current animation + this.animation.cancel(); + } + // Start a WAAPI animation + this.animation = this.el.animate({ + // Set the keyframes from the startHeight to endHeight + height: [startHeight, endHeight], + }, { + duration: 400, + easing: "ease-out", + }); + // When the animation is complete, call onAnimationFinish() + this.animation.onfinish = () => this.onAnimationFinish(false); + // If the animation is cancelled, isClosing variable is set to false + this.animation.oncancel = () => (this.isClosing = false); + } + + open() { + // Apply a fixed height on the element + this.el.style.height = `${this.el.offsetHeight}px`; + // Force the [open] attribute on the details element + this.el.open = true; + // Wait for the next frame to call the expand function + window.requestAnimationFrame(() => this.expand()); + } + + expand() { + // Set the element as "being expanding" + this.isExpanding = true; + // Get the current fixed height of the element + const startHeight = `${this.el.offsetHeight}px`; + // Calculate the open height of the element (summary height + content height) + const endHeight = `${ + this.summary.offsetHeight + this.content.offsetHeight + }px`; + // If there is already an animation running + if (this.animation) { + // Cancel the current animation + this.animation.cancel(); + } + // Start a WAAPI animation + this.animation = this.el.animate({ + // Set the keyframes from the startHeight to endHeight + height: [startHeight, endHeight], + }, { + duration: 400, + easing: "ease-out", + }); + // When the animation is complete, call onAnimationFinish() + this.animation.onfinish = () => this.onAnimationFinish(true); + // If the animation is cancelled, isExpanding variable is set to false + this.animation.oncancel = () => (this.isExpanding = false); + } + + onAnimationFinish(open) { + // Set the open attribute based on the parameter + this.el.open = open; + // Clear the stored animation + this.animation = null; + // Reset isClosing & isExpanding + this.isClosing = false; + this.isExpanding = false; + // Remove the overflow hidden and the fixed height + this.el.style.height = this.el.style.overflow = ""; + } +} + +document.querySelectorAll("details").forEach((el) => { + new Accordion(el); +}); \ No newline at end of file diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..9e8281b --- /dev/null +++ b/js/main.js @@ -0,0 +1,199 @@ +let formatter = { + // font maps + fonts: { + normal: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~", + sans: "\"\\ !#$%&'()*+,-./๐Ÿข๐Ÿฃ๐Ÿค๐Ÿฅ๐Ÿฆ๐Ÿง๐Ÿจ๐Ÿฉ๐Ÿช๐Ÿซ:;<=>?@๐– ๐–ก๐–ข๐–ฃ๐–ค๐–ฅ๐–ฆ๐–ง๐–จ๐–ฉ๐–ช๐–ซ๐–ฌ๐–ญ๐–ฎ๐–ฏ๐–ฐ๐–ฑ๐–ฒ๐–ณ๐–ด๐–ต๐–ถ๐–ท๐–ธ๐–น[]^_`๐–บ๐–ป๐–ผ๐–ฝ๐–พ๐–ฟ๐—€๐—๐—‚๐—ƒ๐—„๐—…๐—†๐—‡๐—ˆ๐—‰๐—Š๐—‹๐—Œ๐—๐—Ž๐—๐—๐—‘๐—’๐—“{|}~", + sansBold: "\"\\ !#$%&'()*+,-./๐Ÿฌ๐Ÿญ๐Ÿฎ๐Ÿฏ๐Ÿฐ๐Ÿฑ๐Ÿฒ๐Ÿณ๐Ÿด๐Ÿต:;<=>?@๐—”๐—•๐—–๐——๐—˜๐—™๐—š๐—›๐—œ๐—๐—ž๐—Ÿ๐— ๐—ก๐—ข๐—ฃ๐—ค๐—ฅ๐—ฆ๐—ง๐—จ๐—ฉ๐—ช๐—ซ๐—ฌ๐—ญ[]^_`๐—ฎ๐—ฏ๐—ฐ๐—ฑ๐—ฒ๐—ณ๐—ด๐—ต๐—ถ๐—ท๐—ธ๐—น๐—บ๐—ป๐—ผ๐—ฝ๐—พ๐—ฟ๐˜€๐˜๐˜‚๐˜ƒ๐˜„๐˜…๐˜†๐˜‡{|}~", + sansItalic: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐˜ˆ๐˜‰๐˜Š๐˜‹๐˜Œ๐˜๐˜Ž๐˜๐˜๐˜‘๐˜’๐˜“๐˜”๐˜•๐˜–๐˜—๐˜˜๐˜™๐˜š๐˜›๐˜œ๐˜๐˜ž๐˜Ÿ๐˜ ๐˜ก[]^_`๐˜ข๐˜ฃ๐˜ค๐˜ฅ๐˜ฆ๐˜ง๐˜จ๐˜ฉ๐˜ช๐˜ซ๐˜ฌ๐˜ญ๐˜ฎ๐˜ฏ๐˜ฐ๐˜ฑ๐˜ฒ๐˜ณ๐˜ด๐˜ต๐˜ถ๐˜ท๐˜ธ๐˜น๐˜บ๐˜ป{|}~", + sansBoldItalic: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐˜ผ๐˜ฝ๐˜พ๐˜ฟ๐™€๐™๐™‚๐™ƒ๐™„๐™…๐™†๐™‡๐™ˆ๐™‰๐™Š๐™‹๐™Œ๐™๐™Ž๐™๐™๐™‘๐™’๐™“๐™”๐™•[]^_`๐™–๐™—๐™˜๐™™๐™š๐™›๐™œ๐™๐™ž๐™Ÿ๐™ ๐™ก๐™ข๐™ฃ๐™ค๐™ฅ๐™ฆ๐™ง๐™จ๐™ฉ๐™ช๐™ซ๐™ฌ๐™ญ๐™ฎ๐™ฏ{|}~", + monospace: "\"\\โ€‚!#$%&'()*+,-./๐Ÿถ๐Ÿท๐Ÿธ๐Ÿน๐Ÿบ๐Ÿป๐Ÿผ๐Ÿฝ๐Ÿพ๐Ÿฟ:;<=>?@๐™ฐ๐™ฑ๐™ฒ๐™ณ๐™ด๐™ต๐™ถ๐™ท๐™ธ๐™น๐™บ๐™ป๐™ผ๐™ฝ๐™พ๐™ฟ๐š€๐š๐š‚๐šƒ๐š„๐š…๐š†๐š‡๐šˆ๐š‰[]^_`๐šŠ๐š‹๐šŒ๐š๐šŽ๐š๐š๐š‘๐š’๐š“๐š”๐š•๐š–๐š—๐š˜๐š™๐šš๐š›๐šœ๐š๐šž๐šŸ๐š ๐šก๐šข๐šฃ{|}~", + fullwidth: '"๏ผผใ€€๏ผ๏ผƒ๏ผ„๏ผ…๏ผ†๏ผ‡๏ผˆ๏ผ‰๏ผŠ๏ผ‹๏ผŒ๏ผ๏ผŽ๏ผ๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผš๏ผ›<๏ผ>๏ผŸ๏ผ ๏ผก๏ผข๏ผฃ๏ผค๏ผฅ๏ผฆ๏ผง๏ผจ๏ผฉ๏ผช๏ผซ๏ผฌ๏ผญ๏ผฎ๏ผฏ๏ผฐ๏ผฑ๏ผฒ๏ผณ๏ผด๏ผต๏ผถ๏ผท๏ผธ๏ผน๏ผบ๏ผป๏ผฝ๏ผพ๏ผฟ๏ฝ€๏ฝ๏ฝ‚๏ฝƒ๏ฝ„๏ฝ…๏ฝ†๏ฝ‡๏ฝˆ๏ฝ‰๏ฝŠ๏ฝ‹๏ฝŒ๏ฝ๏ฝŽ๏ฝ๏ฝ๏ฝ‘๏ฝ’๏ฝ“๏ฝ”๏ฝ•๏ฝ–๏ฝ—๏ฝ˜๏ฝ™๏ฝš๏ฝ›๏ฝœ๏ฝ๏ฝž', + fraktur: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐”„๐”…โ„ญ๐”‡๐”ˆ๐”‰๐”Šโ„Œโ„‘๐”๐”Ž๐”๐”๐”‘๐”’๐”“๐””โ„œ๐”–๐”—๐”˜๐”™๐”š๐”›๐”œโ„จ[]^_`๐”ž๐”Ÿ๐” ๐”ก๐”ข๐”ฃ๐”ค๐”ฅ๐”ฆ๐”ง๐”จ๐”ฉ๐”ช๐”ซ๐”ฌ๐”ญ๐”ฎ๐”ฏ๐”ฐ๐”ฑ๐”ฒ๐”ณ๐”ด๐”ต๐”ถ๐”ท{|}~", + boldFraktur: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐•ฌ๐•ญ๐•ฎ๐•ฏ๐•ฐ๐•ฑ๐•ฒ๐•ณ๐•ด๐•ต๐•ถ๐•ท๐•ธ๐•น๐•บ๐•ป๐•ผ๐•ฝ๐•พ๐•ฟ๐–€๐–๐–‚๐–ƒ๐–„๐–…[]^_`๐–†๐–‡๐–ˆ๐–‰๐–Š๐–‹๐–Œ๐–๐–Ž๐–๐–๐–‘๐–’๐–“๐–”๐–•๐––๐–—๐–˜๐–™๐–š๐–›๐–œ๐–๐–ž๐–Ÿ{|}~", + serifBold: "\"\\ !#$%&'()*+,-./๐ŸŽ๐Ÿ๐Ÿ๐Ÿ‘๐Ÿ’๐Ÿ“๐Ÿ”๐Ÿ•๐Ÿ–๐Ÿ—:;<=>?@๐€๐๐‚๐ƒ๐„๐…๐†๐‡๐ˆ๐‰๐Š๐‹๐Œ๐๐Ž๐๐๐‘๐’๐“๐”๐•๐–๐—๐˜๐™[]^_`๐š๐›๐œ๐๐ž๐Ÿ๐ ๐ก๐ข๐ฃ๐ค๐ฅ๐ฆ๐ง๐จ๐ฉ๐ช๐ซ๐ฌ๐ญ๐ฎ๐ฏ๐ฐ๐ฑ๐ฒ๐ณ{|}~", + serifItalic: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐ด๐ต๐ถ๐ท๐ธ๐น๐บ๐ป๐ผ๐ฝ๐พ๐ฟ๐‘€๐‘๐‘‚๐‘ƒ๐‘„๐‘…๐‘†๐‘‡๐‘ˆ๐‘‰๐‘Š๐‘‹๐‘Œ๐‘[]^_`๐‘Ž๐‘๐‘๐‘‘๐‘’๐‘“๐‘”โ„Ž๐‘–๐‘—๐‘˜๐‘™๐‘š๐‘›๐‘œ๐‘๐‘ž๐‘Ÿ๐‘ ๐‘ก๐‘ข๐‘ฃ๐‘ค๐‘ฅ๐‘ฆ๐‘ง{|}~", + serifBoldItalic: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐‘จ๐‘ฉ๐‘ช๐‘ซ๐‘ฌ๐‘ญ๐‘ฎ๐‘ฏ๐‘ฐ๐‘ฑ๐‘ฒ๐‘ณ๐‘ด๐‘ต๐‘ถ๐‘ท๐‘ธ๐‘น๐‘บ๐‘ป๐‘ผ๐‘ฝ๐‘พ๐‘ฟ๐’€๐’[]^_`๐’‚๐’ƒ๐’„๐’…๐’†๐’‡๐’ˆ๐’‰๐’Š๐’‹๐’Œ๐’๐’Ž๐’๐’๐’‘๐’’๐’“๐’”๐’•๐’–๐’—๐’˜๐’™๐’š๐’›{|}~", + doubleStruck: "\"\\ !#$%&'()*+,-./๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›๐Ÿœ๐Ÿ๐Ÿž๐ŸŸ๐Ÿ ๐Ÿก:;<=>?@๐”ธ๐”นโ„‚๐”ป๐”ผ๐”ฝ๐”พโ„๐•€๐•๐•‚๐•ƒ๐•„โ„•๐•†โ„™โ„šโ„๐•Š๐•‹๐•Œ๐•๐•Ž๐•๐•โ„ค[]^_`๐•’๐•“๐•”๐••๐•–๐•—๐•˜๐•™๐•š๐•›๐•œ๐•๐•ž๐•Ÿ๐• ๐•ก๐•ข๐•ฃ๐•ค๐•ฅ๐•ฆ๐•ง๐•จ๐•ฉ๐•ช๐•ซ{|}~", + script: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐’œโ„ฌ๐’ž๐’Ÿโ„ฐโ„ฑ๐’ขโ„‹โ„๐’ฅ๐’ฆโ„’โ„ณ๐’ฉ๐’ช๐’ซ๐’ฌโ„›๐’ฎ๐’ฏ๐’ฐ๐’ฑ๐’ฒ๐’ณ๐’ด๐’ต[]^_`๐’ถ๐’ท๐’ธ๐’นโ„ฏ๐’ปโ„Š๐’ฝ๐’พ๐’ฟ๐“€๐“๐“‚๐“ƒโ„ด๐“…๐“†๐“‡๐“ˆ๐“‰๐“Š๐“‹๐“Œ๐“๐“Ž๐“{|}~", + boldScript: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐“๐“‘๐“’๐““๐“”๐“•๐“–๐“—๐“˜๐“™๐“š๐“›๐“œ๐“๐“ž๐“Ÿ๐“ ๐“ก๐“ข๐“ฃ๐“ค๐“ฅ๐“ฆ๐“ง๐“จ๐“ฉ[]^_`๐“ช๐“ซ๐“ฌ๐“ญ๐“ฎ๐“ฏ๐“ฐ๐“ฑ๐“ฒ๐“ณ๐“ด๐“ต๐“ถ๐“ท๐“ธ๐“น๐“บ๐“ป๐“ผ๐“ฝ๐“พ๐“ฟ๐”€๐”๐”‚๐”ƒ{|}~", + circled: "\"โฆธ !#$%&'()โŠ›โŠ•,โŠ–โจ€โŠ˜โ“ชโ‘ โ‘กโ‘ขโ‘ฃโ‘คโ‘ฅโ‘ฆโ‘งโ‘จ:;โง€โŠœโง?@โ’ถโ’ทโ’ธโ’นโ’บโ’ปโ’ผโ’ฝโ’พโ’ฟโ“€โ“โ“‚โ“ƒโ“„โ“…โ“†โ“‡โ“ˆโ“‰โ“Šโ“‹โ“Œโ“โ“Žโ“[]^_`โ“โ“‘โ“’โ““โ“”โ“•โ“–โ“—โ“˜โ“™โ“šโ“›โ“œโ“โ“žโ“Ÿโ“ โ“กโ“ขโ“ฃโ“คโ“ฅโ“ฆโ“งโ“จโ“ฉ{โฆถ}~", + circledNegative: "\"\\ !#$%&'()*+,-./โ“ฟโถโทโธโนโบโปโผโฝโพ:;<=>?@๐Ÿ…๐Ÿ…‘๐Ÿ…’๐Ÿ…“๐Ÿ…”๐Ÿ…•๐Ÿ…–๐Ÿ…—๐Ÿ…˜๐Ÿ…™๐Ÿ…š๐Ÿ…›๐Ÿ…œ๐Ÿ…๐Ÿ…ž๐Ÿ…Ÿ๐Ÿ… ๐Ÿ…ก๐Ÿ…ข๐Ÿ…ฃ๐Ÿ…ค๐Ÿ…ฅ๐Ÿ…ฆ๐Ÿ…ง๐Ÿ…จ๐Ÿ…ฉ[]^_`๐Ÿ…๐Ÿ…‘๐Ÿ…’๐Ÿ…“๐Ÿ…”๐Ÿ…•๐Ÿ…–๐Ÿ…—๐Ÿ…˜๐Ÿ…™๐Ÿ…š๐Ÿ…›๐Ÿ…œ๐Ÿ…๐Ÿ…ž๐Ÿ…Ÿ๐Ÿ… ๐Ÿ…ก๐Ÿ…ข๐Ÿ…ฃ๐Ÿ…ค๐Ÿ…ฅ๐Ÿ…ฆ๐Ÿ…ง๐Ÿ…จ๐Ÿ…ฉ{|}~", + squared: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐Ÿ„ฐ๐Ÿ„ฑ๐Ÿ„ฒ๐Ÿ„ณ๐Ÿ„ด๐Ÿ„ต๐Ÿ„ถ๐Ÿ„ท๐Ÿ„ธ๐Ÿ„น๐Ÿ„บ๐Ÿ„ป๐Ÿ„ผ๐Ÿ„ฝ๐Ÿ„พ๐Ÿ„ฟ๐Ÿ…€๐Ÿ…๐Ÿ…‚๐Ÿ…ƒ๐Ÿ…„๐Ÿ……๐Ÿ…†๐Ÿ…‡๐Ÿ…ˆ๐Ÿ…‰[]^_`๐Ÿ„ฐ๐Ÿ„ฑ๐Ÿ„ฒ๐Ÿ„ณ๐Ÿ„ด๐Ÿ„ต๐Ÿ„ถ๐Ÿ„ท๐Ÿ„ธ๐Ÿ„น๐Ÿ„บ๐Ÿ„ป๐Ÿ„ผ๐Ÿ„ฝ๐Ÿ„พ๐Ÿ„ฟ๐Ÿ…€๐Ÿ…๐Ÿ…‚๐Ÿ…ƒ๐Ÿ…„๐Ÿ……๐Ÿ…†๐Ÿ…‡๐Ÿ…ˆ๐Ÿ…‰{|}~", + squaredNegative: "\"โง… !#$%&'()โง†โŠž,โŠŸโŠกโง„0123456789:;<=>?@๐Ÿ…ฐ๐Ÿ…ฑ๐Ÿ…ฒ๐Ÿ…ณ๐Ÿ…ด๐Ÿ…ต๐Ÿ…ถ๐Ÿ…ท๐Ÿ…ธ๐Ÿ…น๐Ÿ…บ๐Ÿ…ป๐Ÿ…ผ๐Ÿ…ฝ๐Ÿ…พ๐Ÿ…ฟ๐Ÿ†€๐Ÿ†๐Ÿ†‚๐Ÿ†ƒ๐Ÿ†„๐Ÿ†…๐Ÿ††๐Ÿ†‡๐Ÿ†ˆ๐Ÿ†‰[]^_`๐Ÿ…ฐ๐Ÿ…ฑ๐Ÿ…ฒ๐Ÿ…ณ๐Ÿ…ด๐Ÿ…ต๐Ÿ…ถ๐Ÿ…ท๐Ÿ…ธ๐Ÿ…น๐Ÿ…บ๐Ÿ…ป๐Ÿ…ผ๐Ÿ…ฝ๐Ÿ…พ๐Ÿ…ฟ๐Ÿ†€๐Ÿ†๐Ÿ†‚๐Ÿ†ƒ๐Ÿ†„๐Ÿ†…๐Ÿ††๐Ÿ†‡๐Ÿ†ˆ๐Ÿ†‰{|}~", + parenthesized: "\"\\ !#$%&'()*+,-./0โ‘ดโ‘ตโ‘ถโ‘ทโ‘ธโ‘นโ‘บโ‘ปโ‘ผ:;<=>?@โ’œโ’โ’žโ’Ÿโ’ โ’กโ’ขโ’ฃโ’คโ’ฅโ’ฆโ’งโ’จโ’ฉโ’ชโ’ซโ’ฌโ’ญโ’ฎโ’ฏโ’ฐโ’ฑโ’ฒโ’ณโ’ดโ’ต[]^_`โ’œโ’โ’žโ’Ÿโ’ โ’กโ’ขโ’ฃโ’คโ’ฅโ’ฆโ’งโ’จโ’ฉโ’ชโ’ซโ’ฌโ’ญโ’ฎโ’ฏโ’ฐโ’ฑโ’ฒโ’ณโ’ดโ’ต{|}~", + smallCaps: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`แด€ส™แด„แด…แด‡๊œฐษขสœษชแดŠแด‹สŸแดษดแดแดฉ๊žฏส€๊œฑแด›แดœแด แดกxสแดข{|}~", + subscript: "\"\\ !#$%&'โ‚โ‚Ž*โ‚Š,โ‚‹./โ‚€โ‚โ‚‚โ‚ƒโ‚„โ‚…โ‚†โ‚‡โ‚ˆโ‚‰:;<โ‚Œ>?@แด€ส™แด„แด…แด‡๊œฐษขสœษชแดŠแด‹สŸแดษดแดแด˜๐Ÿ‡ถส€๊œฑแด›แดœแด แดกxสแดข[]^_`โ‚แตฆ๐’ธ๐’นโ‚‘๐’ป๐“ฐโ‚•แตขโฑผโ‚–โ‚—โ‚˜โ‚™โ‚’โ‚šแตฉแตฃโ‚›โ‚œแตคแตฅ๐“Œโ‚“แตง๐“{|}~", + superscript: "\"\\ !#$%&'โฝโพ*โบ,โป./โฐยนยฒยณโดโตโถโทโธโน:;<โผ>?@แดฌแดฎแถœแดฐแดฑแถ แดณแดดแดตแดถแดทแดธแดนแดบแดผแดพแต แดฟหขแต€แตโฑฝแต‚หฃสธแถป[]^_`แตƒแต‡แถœแตˆแต‰แถ แตสฐโฑสฒแตหกแตโฟแต’แต–แต สณหขแต—แต˜แต›สทหฃสธแถป{|}~", + inverted: "โ€ž\\ ยก#$%โ…‹,)(*+โ€˜-ห™/0ฦ–ี‡ฦแ”ญฯ›9๐˜“86:;<=>ยฟ@โˆ€๊“ญโ†ƒ๊“ทฦŽโ„ฒโ…HIลฟ๊“˜โ…‚WNOิ€แฟธ๊“คSโŠฅโˆฉ๊“ฅMXโ…„Z][^โ€พ`ษqษ”pวษŸฦƒษฅฤฑษพสžืŸษฏuodbษนsส‡nสŒสxสŽz}|{~", + mirrored: "\"/ !#$%&')(*+,-.\\0฿ฯ‚ฦ฿‚เคŸแƒ›ูข8เญง:;<=>โธฎ@A๊“ญโ†ƒ๊“ทฦŽ๊Ÿปำ˜HIแ‚ฑ๊“˜โ…ƒMะ˜O๊Ÿผฯ˜ะฏ๊™„TUVWXYZ][^_`ษ’dโ†„bษ˜ส‡ฯฑสœiฤฏสžlmแดŽoqpแด™๊™…ษˆฯ…vwxฮณz}|{~", + }, + + // initialize formatter with CodeMirror + init: function (textarea) { + // no code highlighting and wrap long lines + this.CodeMirror = CodeMirror.fromTextArea(textarea, { + mode: null, + lineWrapping: true, + }); + + // list of font characters for checking if character is formatted + this.allCharacters = new Set(Object.values(this.fonts).join("")); + + // mapping functions + const bold = () => this.formatSelections("sansBold"); + const italic = () => this.formatSelections("sansItalic"); + const monospace = () => this.formatSelections("monospace"); + const strikethrough = () => + this.formatSelections("", { + append: "ฬถ", + }); + const underline = () => + this.formatSelections("", { + append: "อŸ", + }); + const superscript = () => this.formatSelections("superscript"); + const subscript = () => this.formatSelections("subscript"); + + // add keymaps + this.CodeMirror.setOption("extraKeys", { + "Ctrl-B": bold, + "Ctrl-I": italic, + "Ctrl-M": monospace, + "Ctrl-U": underline, + "Alt-K": strikethrough, + "Shift-Alt-5": strikethrough, + "Shift-Ctrl-=": superscript, + "Ctrl-.": superscript, + "Ctrl-=": subscript, + "Ctrl-,": subscript, + }); + }, + + // check if text is already formatted with a certain font + alreadyFormatted: function (text, font) { + const fontCharacters = new Set(this.fonts[font]); + // flag as already formatted if all characters are in font or not in any other font + return Array.from(text).every( + (char) => fontCharacters.has(char) || !this.allCharacters.has(char) + ); + }, + + // check if text is already formatted with a certain font + alreadyAppended: function (text, append) { + // check if at least half the characters are the append character + return Array.from(text).filter((char) => char == append).length >= text.length / 2; + }, + + // format text into selected font + formatText: function (text, font, options) { + // set font to normal if already formatted with selected font + if (this.fonts[font] && this.alreadyFormatted(text, font)) { + font = "normal"; + } + // remove and don't append if character is already appended + if (options?.append) { + options.remove = options.append; + options.append = !this.alreadyAppended(text, options.append) ? options.append : ""; + } + // Array.from() splits the string by symbol and not by code points + let newText = Array.from(text); + // exchange font symbols + if (this.fonts[font]) { + const targetFont = Array.from(this.fonts[font]); + const charLists = Object.values(this.fonts); + // map characters to new font + newText = newText.map((char) => { + let index; + // find the index of the character in some font + const found = charLists.some((charList) => { + index = Array.from(charList).indexOf(char); + return index > -1; + }); + // if found, replace with the corresponding character in the target font + // if not found, keep the character the same + return found ? targetFont[index] : char; + }); + } + // reverse text if reverse option is set + newText = options?.reverse ? newText.reverse() : newText; + // remove appended symbol of specific type from the end + newText = options?.remove + ? newText.map((char) => + char.replace(new RegExp(options.remove + "$", "u"), "") + ) + : newText; + // append symbol (underline, strikethrough, etc.) to end of each character if append is set + newText = options?.append + ? newText.map((char) => char + options.append) + : newText; + // remove appended symbols (underline, strikethrough, etc.) if using eraser + // \u035f = Underline, \u0333 = Double Underline, \u0335 = Short Strikethrough \u0336 = Strikethrough + newText = options?.clear + ? newText.map((char) => char.replace(/\u035f|\u0333|\u0335|\u0336/gu, "")) + : newText; + // set textarea content and select text around the replacement + return newText.join(""); + }, + + // format selected text + formatSelections: function (font, options) { + // for each selection (there can be multiple), format the text + const newTexts = this.CodeMirror.getSelections().map((selection) => + this.formatText(selection, font, options) + ); + // replace all selections with replacements + this.CodeMirror.replaceSelections(newTexts, "around"); + }, + + // open twitter with the text value as the post + tweet: function () { + const text = this.CodeMirror.getValue(); + const encoded = encodeURIComponent(text) + const twitterUrl = `https://twitter.com/intent/tweet?text=${encoded}`; + const win = window.open(twitterUrl, "_blank"); + win.focus(); + }, + + // copy the text to the clipboard + copy: function (el) { + // create dummy textarea with text content + const textarea = document.createElement("textarea"); + textarea.value = this.CodeMirror.getValue(); + document.body.appendChild(textarea); + // select all + textarea.select(); + textarea.setSelectionRange(0, 99999); + // copy + document.execCommand("copy"); + // remove textarea + textarea.parentElement.removeChild(textarea); + // set tooltip text + el.title = "Copied!"; + }, +}; + +let tooltip = { + // put the original title back (eg. "Copied!" => "Copy to clipboard") + resetTooltip: function (el) { + el.title = el.dataset.originalTitle; + }, +}; + +// when the page loads +window.addEventListener("load", function () { + // textarea for initializing CodeMirror + const textarea = document.querySelector("textarea"); + // initialize formatter + formatter.init(textarea); + // add click event listeners to format buttons + document.querySelectorAll(".control-btns button").forEach(function (btn) { + btn.addEventListener("click", function () { + // format highlighted text into selected font + formatter.formatSelections(this.className, { ...this.dataset }); + }, false); + }); + // set dark mode on preference + if (window.matchMedia("(prefers-color-scheme: dark)").matches) { + document.body.setAttribute("data-theme", "dark"); + } +}, false); From 231b7885b78765aa459ecd2ad73928f92d726e85 Mon Sep 17 00:00:00 2001 From: Jonah Lawrence Date: Thu, 20 Oct 2022 17:53:44 -0600 Subject: [PATCH 3/6] Create CNAME --- CNAME | 1 + 1 file changed, 1 insertion(+) create mode 100644 CNAME diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..8d31765 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +unicode-formatter.demolab.com \ No newline at end of file From 4aa9925c59b6d736567deea0544b3d1c1a41e392 Mon Sep 17 00:00:00 2001 From: Jonah Lawrence Date: Thu, 20 Oct 2022 22:07:28 -0600 Subject: [PATCH 4/6] Add /src redirect for old domain to the new domain --- src/index.html | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/index.html diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..b51b321 --- /dev/null +++ b/src/index.html @@ -0,0 +1,18 @@ + + + + + + + Unicode Formatter + + +

+ If you are not redirected automatically, follow this + link + to the new domain. +

+ + From 8e8e5305f1baa5799cc840e72670e8c83b8b8271 Mon Sep 17 00:00:00 2001 From: DenverCoder1 Date: Sun, 30 Oct 2022 21:33:43 +0000 Subject: [PATCH 5/6] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20Denv?= =?UTF-8?q?erCoder1/unicode-formatter@fb25c2de0de864dbf90741ae39a30ee1833a?= =?UTF-8?q?0ac4=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/style.css | 7 +- index.html | 231 +++++++++++++++++++++--------------------------- js/accordion.js | 40 +++++---- js/main.js | 68 +++++++------- src/index.html | 18 ---- 5 files changed, 158 insertions(+), 206 deletions(-) delete mode 100644 src/index.html diff --git a/css/style.css b/css/style.css index d7ecc3c..8274bde 100644 --- a/css/style.css +++ b/css/style.css @@ -42,8 +42,7 @@ body { body, button, textarea { - font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", - Roboto, Helvetica, Arial, sans-serif; + font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; } .CodeMirror { @@ -123,7 +122,7 @@ a.logo img { } .more-fonts button { - padding: 0px + padding: 0px; } /* textarea */ @@ -248,4 +247,4 @@ div.github { .controls button:hover:after, .large-buttons button:hover:after { opacity: 1; -} \ No newline at end of file +} diff --git a/index.html b/index.html index 8a822fa..92d037f 100644 --- a/index.html +++ b/index.html @@ -1,168 +1,137 @@ - - + - - + + Unicode formatter - + - - + + - - + + - + - + - +
- Fonts: -
- - - - - - -
+ Fonts: +
+ + + + + + +
- More fonts -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
+ More fonts +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
- + - +
- - - \ No newline at end of file + + diff --git a/js/accordion.js b/js/accordion.js index 5846fd4..91fa295 100644 --- a/js/accordion.js +++ b/js/accordion.js @@ -44,13 +44,16 @@ class Accordion { this.animation.cancel(); } // Start a WAAPI animation - this.animation = this.el.animate({ - // Set the keyframes from the startHeight to endHeight - height: [startHeight, endHeight], - }, { - duration: 400, - easing: "ease-out", - }); + this.animation = this.el.animate( + { + // Set the keyframes from the startHeight to endHeight + height: [startHeight, endHeight], + }, + { + duration: 400, + easing: "ease-out", + } + ); // When the animation is complete, call onAnimationFinish() this.animation.onfinish = () => this.onAnimationFinish(false); // If the animation is cancelled, isClosing variable is set to false @@ -72,22 +75,23 @@ class Accordion { // Get the current fixed height of the element const startHeight = `${this.el.offsetHeight}px`; // Calculate the open height of the element (summary height + content height) - const endHeight = `${ - this.summary.offsetHeight + this.content.offsetHeight - }px`; + const endHeight = `${this.summary.offsetHeight + this.content.offsetHeight}px`; // If there is already an animation running if (this.animation) { // Cancel the current animation this.animation.cancel(); } // Start a WAAPI animation - this.animation = this.el.animate({ - // Set the keyframes from the startHeight to endHeight - height: [startHeight, endHeight], - }, { - duration: 400, - easing: "ease-out", - }); + this.animation = this.el.animate( + { + // Set the keyframes from the startHeight to endHeight + height: [startHeight, endHeight], + }, + { + duration: 400, + easing: "ease-out", + } + ); // When the animation is complete, call onAnimationFinish() this.animation.onfinish = () => this.onAnimationFinish(true); // If the animation is cancelled, isExpanding variable is set to false @@ -109,4 +113,4 @@ class Accordion { document.querySelectorAll("details").forEach((el) => { new Accordion(el); -}); \ No newline at end of file +}); diff --git a/js/main.js b/js/main.js index 9e8281b..ccd8610 100644 --- a/js/main.js +++ b/js/main.js @@ -1,5 +1,5 @@ let formatter = { - // font maps + // prettier-ignore fonts: { normal: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~", sans: "\"\\ !#$%&'()*+,-./๐Ÿข๐Ÿฃ๐Ÿค๐Ÿฅ๐Ÿฆ๐Ÿง๐Ÿจ๐Ÿฉ๐Ÿช๐Ÿซ:;<=>?@๐– ๐–ก๐–ข๐–ฃ๐–ค๐–ฅ๐–ฆ๐–ง๐–จ๐–ฉ๐–ช๐–ซ๐–ฌ๐–ญ๐–ฎ๐–ฏ๐–ฐ๐–ฑ๐–ฒ๐–ณ๐–ด๐–ต๐–ถ๐–ท๐–ธ๐–น[]^_`๐–บ๐–ป๐–ผ๐–ฝ๐–พ๐–ฟ๐—€๐—๐—‚๐—ƒ๐—„๐—…๐—†๐—‡๐—ˆ๐—‰๐—Š๐—‹๐—Œ๐—๐—Ž๐—๐—๐—‘๐—’๐—“{|}~", @@ -7,7 +7,7 @@ let formatter = { sansItalic: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐˜ˆ๐˜‰๐˜Š๐˜‹๐˜Œ๐˜๐˜Ž๐˜๐˜๐˜‘๐˜’๐˜“๐˜”๐˜•๐˜–๐˜—๐˜˜๐˜™๐˜š๐˜›๐˜œ๐˜๐˜ž๐˜Ÿ๐˜ ๐˜ก[]^_`๐˜ข๐˜ฃ๐˜ค๐˜ฅ๐˜ฆ๐˜ง๐˜จ๐˜ฉ๐˜ช๐˜ซ๐˜ฌ๐˜ญ๐˜ฎ๐˜ฏ๐˜ฐ๐˜ฑ๐˜ฒ๐˜ณ๐˜ด๐˜ต๐˜ถ๐˜ท๐˜ธ๐˜น๐˜บ๐˜ป{|}~", sansBoldItalic: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐˜ผ๐˜ฝ๐˜พ๐˜ฟ๐™€๐™๐™‚๐™ƒ๐™„๐™…๐™†๐™‡๐™ˆ๐™‰๐™Š๐™‹๐™Œ๐™๐™Ž๐™๐™๐™‘๐™’๐™“๐™”๐™•[]^_`๐™–๐™—๐™˜๐™™๐™š๐™›๐™œ๐™๐™ž๐™Ÿ๐™ ๐™ก๐™ข๐™ฃ๐™ค๐™ฅ๐™ฆ๐™ง๐™จ๐™ฉ๐™ช๐™ซ๐™ฌ๐™ญ๐™ฎ๐™ฏ{|}~", monospace: "\"\\โ€‚!#$%&'()*+,-./๐Ÿถ๐Ÿท๐Ÿธ๐Ÿน๐Ÿบ๐Ÿป๐Ÿผ๐Ÿฝ๐Ÿพ๐Ÿฟ:;<=>?@๐™ฐ๐™ฑ๐™ฒ๐™ณ๐™ด๐™ต๐™ถ๐™ท๐™ธ๐™น๐™บ๐™ป๐™ผ๐™ฝ๐™พ๐™ฟ๐š€๐š๐š‚๐šƒ๐š„๐š…๐š†๐š‡๐šˆ๐š‰[]^_`๐šŠ๐š‹๐šŒ๐š๐šŽ๐š๐š๐š‘๐š’๐š“๐š”๐š•๐š–๐š—๐š˜๐š™๐šš๐š›๐šœ๐š๐šž๐šŸ๐š ๐šก๐šข๐šฃ{|}~", - fullwidth: '"๏ผผใ€€๏ผ๏ผƒ๏ผ„๏ผ…๏ผ†๏ผ‡๏ผˆ๏ผ‰๏ผŠ๏ผ‹๏ผŒ๏ผ๏ผŽ๏ผ๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผš๏ผ›<๏ผ>๏ผŸ๏ผ ๏ผก๏ผข๏ผฃ๏ผค๏ผฅ๏ผฆ๏ผง๏ผจ๏ผฉ๏ผช๏ผซ๏ผฌ๏ผญ๏ผฎ๏ผฏ๏ผฐ๏ผฑ๏ผฒ๏ผณ๏ผด๏ผต๏ผถ๏ผท๏ผธ๏ผน๏ผบ๏ผป๏ผฝ๏ผพ๏ผฟ๏ฝ€๏ฝ๏ฝ‚๏ฝƒ๏ฝ„๏ฝ…๏ฝ†๏ฝ‡๏ฝˆ๏ฝ‰๏ฝŠ๏ฝ‹๏ฝŒ๏ฝ๏ฝŽ๏ฝ๏ฝ๏ฝ‘๏ฝ’๏ฝ“๏ฝ”๏ฝ•๏ฝ–๏ฝ—๏ฝ˜๏ฝ™๏ฝš๏ฝ›๏ฝœ๏ฝ๏ฝž', + fullwidth: "\"๏ผผใ€€๏ผ๏ผƒ๏ผ„๏ผ…๏ผ†๏ผ‡๏ผˆ๏ผ‰๏ผŠ๏ผ‹๏ผŒ๏ผ๏ผŽ๏ผ๏ผ๏ผ‘๏ผ’๏ผ“๏ผ”๏ผ•๏ผ–๏ผ—๏ผ˜๏ผ™๏ผš๏ผ›<๏ผ>๏ผŸ๏ผ ๏ผก๏ผข๏ผฃ๏ผค๏ผฅ๏ผฆ๏ผง๏ผจ๏ผฉ๏ผช๏ผซ๏ผฌ๏ผญ๏ผฎ๏ผฏ๏ผฐ๏ผฑ๏ผฒ๏ผณ๏ผด๏ผต๏ผถ๏ผท๏ผธ๏ผน๏ผบ๏ผป๏ผฝ๏ผพ๏ผฟ๏ฝ€๏ฝ๏ฝ‚๏ฝƒ๏ฝ„๏ฝ…๏ฝ†๏ฝ‡๏ฝˆ๏ฝ‰๏ฝŠ๏ฝ‹๏ฝŒ๏ฝ๏ฝŽ๏ฝ๏ฝ๏ฝ‘๏ฝ’๏ฝ“๏ฝ”๏ฝ•๏ฝ–๏ฝ—๏ฝ˜๏ฝ™๏ฝš๏ฝ›๏ฝœ๏ฝ๏ฝž", fraktur: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐”„๐”…โ„ญ๐”‡๐”ˆ๐”‰๐”Šโ„Œโ„‘๐”๐”Ž๐”๐”๐”‘๐”’๐”“๐””โ„œ๐”–๐”—๐”˜๐”™๐”š๐”›๐”œโ„จ[]^_`๐”ž๐”Ÿ๐” ๐”ก๐”ข๐”ฃ๐”ค๐”ฅ๐”ฆ๐”ง๐”จ๐”ฉ๐”ช๐”ซ๐”ฌ๐”ญ๐”ฎ๐”ฏ๐”ฐ๐”ฑ๐”ฒ๐”ณ๐”ด๐”ต๐”ถ๐”ท{|}~", boldFraktur: "\"\\ !#$%&'()*+,-./0123456789:;<=>?@๐•ฌ๐•ญ๐•ฎ๐•ฏ๐•ฐ๐•ฑ๐•ฒ๐•ณ๐•ด๐•ต๐•ถ๐•ท๐•ธ๐•น๐•บ๐•ป๐•ผ๐•ฝ๐•พ๐•ฟ๐–€๐–๐–‚๐–ƒ๐–„๐–…[]^_`๐–†๐–‡๐–ˆ๐–‰๐–Š๐–‹๐–Œ๐–๐–Ž๐–๐–๐–‘๐–’๐–“๐–”๐–•๐––๐–—๐–˜๐–™๐–š๐–›๐–œ๐–๐–ž๐–Ÿ{|}~", serifBold: "\"\\ !#$%&'()*+,-./๐ŸŽ๐Ÿ๐Ÿ๐Ÿ‘๐Ÿ’๐Ÿ“๐Ÿ”๐Ÿ•๐Ÿ–๐Ÿ—:;<=>?@๐€๐๐‚๐ƒ๐„๐…๐†๐‡๐ˆ๐‰๐Š๐‹๐Œ๐๐Ž๐๐๐‘๐’๐“๐”๐•๐–๐—๐˜๐™[]^_`๐š๐›๐œ๐๐ž๐Ÿ๐ ๐ก๐ข๐ฃ๐ค๐ฅ๐ฆ๐ง๐จ๐ฉ๐ช๐ซ๐ฌ๐ญ๐ฎ๐ฏ๐ฐ๐ฑ๐ฒ๐ณ{|}~", @@ -73,9 +73,7 @@ let formatter = { alreadyFormatted: function (text, font) { const fontCharacters = new Set(this.fonts[font]); // flag as already formatted if all characters are in font or not in any other font - return Array.from(text).every( - (char) => fontCharacters.has(char) || !this.allCharacters.has(char) - ); + return Array.from(text).every((char) => fontCharacters.has(char) || !this.allCharacters.has(char)); }, // check if text is already formatted with a certain font @@ -118,19 +116,13 @@ let formatter = { newText = options?.reverse ? newText.reverse() : newText; // remove appended symbol of specific type from the end newText = options?.remove - ? newText.map((char) => - char.replace(new RegExp(options.remove + "$", "u"), "") - ) + ? newText.map((char) => char.replace(new RegExp(options.remove + "$", "u"), "")) : newText; // append symbol (underline, strikethrough, etc.) to end of each character if append is set - newText = options?.append - ? newText.map((char) => char + options.append) - : newText; + newText = options?.append ? newText.map((char) => char + options.append) : newText; // remove appended symbols (underline, strikethrough, etc.) if using eraser // \u035f = Underline, \u0333 = Double Underline, \u0335 = Short Strikethrough \u0336 = Strikethrough - newText = options?.clear - ? newText.map((char) => char.replace(/\u035f|\u0333|\u0335|\u0336/gu, "")) - : newText; + newText = options?.clear ? newText.map((char) => char.replace(/\u035f|\u0333|\u0335|\u0336/gu, "")) : newText; // set textarea content and select text around the replacement return newText.join(""); }, @@ -138,9 +130,7 @@ let formatter = { // format selected text formatSelections: function (font, options) { // for each selection (there can be multiple), format the text - const newTexts = this.CodeMirror.getSelections().map((selection) => - this.formatText(selection, font, options) - ); + const newTexts = this.CodeMirror.getSelections().map((selection) => this.formatText(selection, font, options)); // replace all selections with replacements this.CodeMirror.replaceSelections(newTexts, "around"); }, @@ -148,7 +138,7 @@ let formatter = { // open twitter with the text value as the post tweet: function () { const text = this.CodeMirror.getValue(); - const encoded = encodeURIComponent(text) + const encoded = encodeURIComponent(text); const twitterUrl = `https://twitter.com/intent/tweet?text=${encoded}`; const win = window.open(twitterUrl, "_blank"); win.focus(); @@ -180,20 +170,28 @@ let tooltip = { }; // when the page loads -window.addEventListener("load", function () { - // textarea for initializing CodeMirror - const textarea = document.querySelector("textarea"); - // initialize formatter - formatter.init(textarea); - // add click event listeners to format buttons - document.querySelectorAll(".control-btns button").forEach(function (btn) { - btn.addEventListener("click", function () { - // format highlighted text into selected font - formatter.formatSelections(this.className, { ...this.dataset }); - }, false); - }); - // set dark mode on preference - if (window.matchMedia("(prefers-color-scheme: dark)").matches) { - document.body.setAttribute("data-theme", "dark"); - } -}, false); +window.addEventListener( + "load", + function () { + // textarea for initializing CodeMirror + const textarea = document.querySelector("textarea"); + // initialize formatter + formatter.init(textarea); + // add click event listeners to format buttons + document.querySelectorAll(".control-btns button").forEach(function (btn) { + btn.addEventListener( + "click", + function () { + // format highlighted text into selected font + formatter.formatSelections(this.className, { ...this.dataset }); + }, + false + ); + }); + // set dark mode on preference + if (window.matchMedia("(prefers-color-scheme: dark)").matches) { + document.body.setAttribute("data-theme", "dark"); + } + }, + false +); diff --git a/src/index.html b/src/index.html deleted file mode 100644 index b51b321..0000000 --- a/src/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Unicode Formatter - - -

- If you are not redirected automatically, follow this - link - to the new domain. -

- - From dc4dfbb87f5c995f80d9b8d420c24fb496b326a9 Mon Sep 17 00:00:00 2001 From: DenverCoder1 Date: Tue, 8 Nov 2022 01:38:38 +0000 Subject: [PATCH 6/6] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20Denv?= =?UTF-8?q?erCoder1/unicode-formatter@b4fbde701f0ea9bd50db85437c11bd70f598?= =?UTF-8?q?5892=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 17 +++++++++++++---- js/main.js | 2 ++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 92d037f..b5b22b2 100644 --- a/index.html +++ b/index.html @@ -90,7 +90,15 @@

๐“พ๐“ท๐“ฒ๐“ฌ๐“ธ๐“ญ๐“ฎ ๐™›๐™ค๐™ง๐™ข๐™– + + + - -

diff --git a/js/main.js b/js/main.js index ccd8610..7df5919 100644 --- a/js/main.js +++ b/js/main.js @@ -26,6 +26,8 @@ let formatter = { superscript: "\"\\ !#$%&'โฝโพ*โบ,โป./โฐยนยฒยณโดโตโถโทโธโน:;<โผ>?@แดฌแดฎแถœแดฐแดฑแถ แดณแดดแดตแดถแดทแดธแดนแดบแดผแดพแต แดฟหขแต€แตโฑฝแต‚หฃสธแถป[]^_`แตƒแต‡แถœแตˆแต‰แถ แตสฐโฑสฒแตหกแตโฟแต’แต–แต สณหขแต—แต˜แต›สทหฃสธแถป{|}~", inverted: "โ€ž\\ ยก#$%โ…‹,)(*+โ€˜-ห™/0ฦ–ี‡ฦแ”ญฯ›9๐˜“86:;<=>ยฟ@โˆ€๊“ญโ†ƒ๊“ทฦŽโ„ฒโ…HIลฟ๊“˜โ…‚WNOิ€แฟธ๊“คSโŠฅโˆฉ๊“ฅMXโ…„Z][^โ€พ`ษqษ”pวษŸฦƒษฅฤฑษพสžืŸษฏuodbษนsส‡nสŒสxสŽz}|{~", mirrored: "\"/ !#$%&')(*+,-.\\0฿ฯ‚ฦ฿‚เคŸแƒ›ูข8เญง:;<=>โธฎ@A๊“ญโ†ƒ๊“ทฦŽ๊Ÿปำ˜HIแ‚ฑ๊“˜โ…ƒMะ˜O๊Ÿผฯ˜ะฏ๊™„TUVWXYZ][^_`ษ’dโ†„bษ˜ส‡ฯฑสœiฤฏสžlmแดŽoqpแด™๊™…ษˆฯ…vwxฮณz}|{~", + rotatedLeft: "=/ !#$%&-โโœ*+`ว€โˆ™\\โดฐโ†ฝเดต๐ˆแ“เท„เฎฎฮ“๊แ“‚โ ’;ห…๐„ฅโˆงแฃ‡@แ—‰฿˜๐ˆฑโŒ“ัˆ๐ˆฏแ˜ŽโŒถ๐„ฉโฅŸ๐ˆŽโจผโˆ‘Zโดฐแ“‡โตšแ“šแ”•โŠขโŠƒ๐ˆทแ•’ร—โคš๐‡™โŽตโŽดโ€น|`ฦกแ“„๐ˆฑแ“€ัˆ๐ˆฏแƒ—๐ˆฆ๐„ฉแ“œ๐ˆŽโจผแ—ดโŠ‚โดฐแ“‡แ“‚แ“šแ”•๐€โŠƒ๐ˆทะ—ร—โคš๐‡™โŸ_โžเฒฝ", + rotatedRight: "=/ !#$%&-โœโ*+`ว€โˆ™\\โดฐโ‡€แ˜šฯ‰๐ˆฆเท„ใฎโจผ๊แ“„โ ’;โˆง๐„ฅห…?@แ—†ฯ–แด’แ—œแŒ โ•–แ˜โŒถ๐„ฉแ“šโŒคโŒแ•’Zโดฐแ“€แ“„แ““แ”•โŠฃโŠ‚<แ“ฌร—โค™๐‡™โŽดโŽตโ€บ|`โŒ•แ“‚แด’เฏจแŒ โ•–เฎฎแ“๐„ฉแ“šโŒคโŒแดŸแดโดฐแ“€แ“„แ““แ”•๐€โŠ‚<แ“ฌร—โค™๐‡™โž_โŸเฒฝ", }, // initialize formatter with CodeMirror