Add codeblocks, emojis from names, and emoticons

This commit is contained in:
Lorem Ipsum 2020-12-16 15:09:45 +00:00
parent 65c437908e
commit 2920ac4652
6 changed files with 142 additions and 99 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
testing/

View file

@ -1,9 +1,11 @@
# An embed visualizer
Visualizes embed or message content from JSON input. This can be used for visualizing bot embed commands.
Displays embed or message content from JSON input. This can be used for visualizing bot embed commands.
This can be used for bot embed commands commands, although I understand that not every one understands JSON thus will add a GUI later.
You can look into the [project boards](https://github.com/Glitchii/embedbuilder/projects/3) if you want to see what I'm currently working on or want to contribute
You can look into the [project boards](https://github.com/Glitchii/embedbuilder/projects/3) if you want to see what is being worked on or want to contribute.
<br>
<br>
![Layout image](https://raw.githubusercontent.com/Glitchii/embedbuilder/master/assets/media/layout.png)
![Layout image](https://raw.githubusercontent.com/Glitchii/embedbuilder/master/assets/media/layout.png)
[To Do](https://github.com/Glitchii/embedbuilder/projects/3) | [Discussions](https://github.com/Glitchii/embedbuilder/discussions/1)

View file

@ -340,10 +340,14 @@ img[alt] {
.emoji {
object-fit: contain;
width: 22px;
height: 22px;
margin: 0 .05em 0 .1em !important;
vertical-align: -.4em;
width: 1.375em;
height: 1.375em;
vertical-align: bottom;
}
.embed .emoji {
width: 18px;
height: 18px;
}
.embedGrid {
@ -471,6 +475,7 @@ img[alt] {
margin-top: 8px;
gap: 8px;
min-width: 0px;
grid-gap: 8px;
}
.embedField {
@ -583,6 +588,26 @@ u {
text-size-adjust: none;
}
.embed blockquote {
max-width: 100%;
}
.blockquote {
display: flex;
}
.blockquote blockquote {
padding: 0 8px 0 12px;
box-sizing: border-box;
text-indent: 0;
}
.blockquote .blockquoteDivider {
width: 4px;
border-radius: 4px;
}
.blockquoteDivider {
background-color: var(--interactive-muted);
}
.container {
display: grid;
grid-auto-flow: row;
@ -620,6 +645,10 @@ u {
white-space: pre-wrap;
}
.markup .markup :is(pre, blockquote) {
max-width: 90%;
}
.markup pre {
max-width: 90%;
border-radius: 4px;
@ -632,11 +661,7 @@ u {
background-clip: border-box;
}
.markup pre.embeded {
max-width: 100%;
}
.markup pre.embeded>code {
.embed code {
border: none;
background: var(--background-tertiary);
}
@ -781,4 +806,17 @@ u {
display: block;
margin-top: 5px;
}
}
@media screen and (max-width: 530px) {
.msgEmbed {
margin: 20px 0px;
padding: 0.125rem 0 20px 65px;
}
.avatar {
left: 10px;
}
.main .side1 {
padding: 10px;
}
}

View file

@ -1,56 +1,58 @@
var emoticons = {
">=-(": "angry",
"=\")": "blush",
"=-\")": "blush",
"<\\3": "broken_heart",
"=-/": "confused",
":'(": "cry",
":'-(": "cry",
":,(": "cry",
":,-(": "cry",
"='(": "cry",
"='-(": "cry",
"=,(": "cry",
"=,-(": "cry",
"=-(": "frowning",
"♡": "heart",
"]=-(": "imp",
"0=-)": "innocent",
":')": "joy",
":'-)": "joy",
":,)": "joy",
":,-)": "joy",
":'D": "joy",
":'-D": "joy",
":,D": "joy",
":,-D": "joy",
"=')": "joy",
"='-)": "joy",
"=,)": "joy",
"=,-)": "joy",
"='D": "joy",
"='-D": "joy",
"=-*": "kissing",
"X-)": "laughing",
"=-|": "neutral_face",
"=-O": "open_mouth",
"=-@": "rage",
"=-D": "smile",
"=-)": "slight_smile",
"]=-)": "smiling_imp",
":,'(": "sob",
":,'-(": "sob",
";(": "sob",
";-(": "sob",
"=,'(": "sob",
"=,'-(": "sob",
"=-P": "stuck_out_tongue",
"B-)": "sunglasses",
",=-(": "sweat",
",=-)": "sweat_smile",
"=-$": "unamused",
";)": "wink",
";-)": "wink"
">=-(": "😠",
"=\")": "😊",
"=-\")": "😊",
"<\\3": "💔",
"=-/": "😕",
":'(": "😢",
":'-(": "😢",
":,(": "😢",
":,-(": "cr😢y",
"='(": "😢",
"='-(": "😢",
"=,(": "😢",
"=,-(": "😢",
"=-(": "😦",
"♡": "heart❤",
"]=-(": "👿",
"0=-)": "😇",
":')": "😂",
":'-)": "😂",
":,)": "😂",
":,-)": "😂",
":'D": "😂",
":'-D": "😂",
":,D": "😂",
":,-D": "😂",
"=')": "😂",
"='-)": "😂",
"=,)": "😂",
"=,-)": "😂",
"='D": "😂",
"='-D": "😂",
"=-*": "😗",
"X-)": "😆",
"=-|": "😐",
"=-O": "😮",
"=-@": "😡",
"=-D": "😄",
":)": "🙂",
":-)": "🙂",
"=-)": "🙂",
"]=-)": "😈",
":,'(": "😭",
":,'-(": "😭",
";(": "😭",
";-(": "😭",
"=,'(": "😭",
"=,'-(": "😭",
"=-P": "😛",
"B-)": "😎",
",=-(": "😓",
",=-)": "😅",
"=-$": "😒",
";)": "😉",
";-)": "😉"
}, emojis = {
"open_hands": "👐",
"open_hands_tone1": "👐🏻",
@ -2968,6 +2970,7 @@ var emoticons = {
"confused": "😕",
"cry": "😢",
"frowning": "😦",
"frowning2": "☹️",
"imp": "👿",
"innocent": "😇",
"joy": "😂",

View file

@ -12,7 +12,6 @@ window.onload = () => {
theme: 'material-darker',
scrollbarStyle: "overlay",
mode: "application/json",
// lineNumbers: true,
foldGutter: true,
gutters: ["CodeMirror-foldgutter", "CodeMirror-lint-markers"],
matchBrackets: true,
@ -30,27 +29,26 @@ window.onload = () => {
if (html) notif.innerHTML = msg;
else notif.innerText = msg;
notif.style.display = 'block';
// err && console.log(err);
}, markup = (txt, isEmbed) => {
}, markup = (txt, opts) => {
txt = txt
// Custom Emojis
.replace(/<a?:[^:]+?:(\d+)>/g, '<img class="emoji" src="https://cdn.discordapp.com/emojis/$1.png"/>') // .replace(/<a?:[^:]+?:(\d+)>/g, '<img class="emoji" src="https://cdn.discordapp.com/emojis/$1.gif" onerror="this.src=\'https://cdn.discordapp.com/emojis/$1.png\'"/>') // This will keep logging failed GET request errors in console
// MD
.replace(/<:[^:]+:(\d+)>/g, '<img class="emoji" src="https://cdn.discordapp.com/emojis/$1.png"/>')
.replace(/<a:[^:]+:(\d+)>/g, '<img class="emoji" src="https://cdn.discordapp.com/emojis/$1.gif"/>')
.replace(/~~(.+?)~~/g, '<s>$1</s>')
.replace(/\`(?!\`)([^\`]+?)\`(?!\`)/g, '<code class="inline">$1</code>')
.replace(/\`\`(?!\`)([^\`]+?)\`\`(?!\`)/g, '<code class="inline">$1</code>')
.replace(/\*\*\*(.+?)\*\*\*/g, '<em><strong>$1</strong></em>')
.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
.replace(/__(.+?)__/g, '<u>$1</u>')
.replace(/\*(.+?)\*/g, '<em>$1</em>')
.replace(/_(.+?)_/g, '<em>$1</em>')
// Block
.replace(/\n/g, '<br>')
.replace(/\`\`\`(\w{1,15})<br>((\n|.)+?)\`\`\`/g, isEmbed ? '<pre class="embeded"><code class="$1">$2</code></pre>' : '<pre><code class="$1">$2</code></pre>')
.replace(/\`\`\`(\w{1,15})<br>((\n|.)+?)\`\`\`/g, isEmbed ? '<pre class="embeded"><code class="$1">$2</code></pre>' : '<pre><code class="$1">$2</code></pre>')
.replace(/\`\`\`(<br>)?((\n|.)+?)\`\`\`/g, isEmbed ? '<pre class="embeded"><code class="hljs nohighlight">$2</code></pre>' : '<pre><code class="hljs nohighlight">$2</code></pre>')
if (isEmbed) txt = txt
.replace(/\[(.+)\]\((.+)\)/g, `<a title="$1" target="_blank" class="anchor" href="$2">$1</a>`);
if (opts.inlineBlock) txt = txt.replace(/\`([^\`]+?)\`|\`\`([^\`]+?)\`\`|\`\`\`((?:\n|.)+?)\`\`\`/g, (m, x, y, z) => x ? `<code class="inline">${x}</code>` : y ? `<code class="inline">${y}</code>` : z ? `<code class="inline">${z}</code>` : m);
else txt = txt.replace(/\`\`\`(\w{1,15})?\n((?:\n|.)+?)\`\`\`|\`\`(.+?)\`\`(?!\`)|\`([^\`]+?)\`/g, (m, w, x, y, z) => w && x ? `<pre><code class="${w}">${x}</code></pre>` : x ? `<pre><code class="hljs nohighlight">${x}</code></pre>` : y || z ? `<code class="inline">${y || z}</code>` : m);
if (opts.inEmbed) txt = txt.replace(/\[([^\[\]]+)\]\((.+?)\)/g, `<a title="$1" target="_blank" class="anchor" href="$2">$1</a>`);
if (opts.replaceEmojis) {
txt = txt.replace(/(?<!code(?: \w+=".+")?>[^>]+)(?<!\/[^\s"]+?):((?!\/)\w+):/g, (match, x) => x && emojis[x] ? emojis[x] : match);
!opts.noEmoticons && Object.keys(emoticons).forEach(e => txt = txt.replace(new RegExp(`(?<=^|\\s)${regEscape(e)}(?=$|\\s)`, 'g'), emoticons[e]));
}
txt = txt
.replace(/(?<=\n|^)\s*>\s+([^\n]+)/g, '<div class="blockquote"><div class="blockquoteDivider"></div><blockquote>$1</blockquote></div>')
.replace(/\n/g, '<br>');
return txt;
},
content = document.querySelector('.messageContent'),
@ -77,15 +75,16 @@ window.onload = () => {
el.style.display = displayType || "unset";
}, hide = el => el.style.removeProperty('display'),
regEscape = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'),
toObj = jsonString => JSON.parse(jsonString.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (x, y) => y ? "" : x)),
update = data => {
try {
content.innerHTML = data.content ? markup(data.content) : '';
content.innerHTML = data.content ? markup(data.content, { replaceEmojis: true }) : '';
if (data.embed) {
let e = data.embed;
if (e.title) display(embedTitle, markup(`${e.url ? '<a class="anchor" target="_blank" href="' + url(e.url) + '">' + e.title + '</a>' : e.title}`));
if (e.title) display(embedTitle, markup(`${e.url ? '<a class="anchor" target="_blank" href="' + url(e.url) + '">' + e.title + '</a>' : e.title}`, { replaceEmojis: true, noEmoticons: true, inlineBlock: true }));
else hide(embedTitle);
if (e.description) display(embedDescription, markup(e.description, true));
if (e.description) display(embedDescription, markup(e.description, { inEmbed: true, replaceEmojis: true }));
else hide(embedDescription);
if (e.color) embed.closest('.embed').style.borderColor = (typeof e.color === 'number' ? '#' + e.color.toString(16) : e.color);
else embed.closest('.embed').style.removeProperty('border-color');
@ -110,15 +109,15 @@ window.onload = () => {
let el = fields.insertBefore(document.createElement('div'), null);
el.outerHTML = `
<div class="embedField" style="grid-column: 1 / 13;">
<div class="embedFieldName">${markup(f.name)}</div>
<div class="embedFieldValue">${markup(f.value)}</div>
<div class="embedFieldName">${markup(f.name, { inEmbed: true, replaceEmojis: true, inlineBlock: true })}</div>
<div class="embedFieldValue">${markup(f.value, { inEmbed: true, replaceEmojis: true })}</div>
</div>`;
} else {
el = fields.insertBefore(document.createElement('div'), null);
el.outerHTML = `
<div class="embedField ${num}" style="grid-column: ${colNum} / ${colNum + 4};">
<div class="embedFieldName">${markup(f.name)}</div>
<div class="embedFieldValue">${markup(f.value)}</div>
<div class="embedFieldName">${markup(f.name, { inEmbed: true, replaceEmojis: true, inlineBlock: true })}</div>
<div class="embedFieldValue">${markup(f.value, { inEmbed: true, replaceEmojis: true })}</div>
</div>`;
colNum = (colNum === 9 ? 1 : colNum + 4);
num++;
@ -127,16 +126,16 @@ window.onload = () => {
colNum = 1;
let len = e.fields.filter(f => f.inline).length;
if (len === 2 || (len > 3 && len % 2 !== 0)) {
let children = Array.from(fields.children),
arr = children.filter(x => x === children[len] || x === children[len - 1]);
let children = Array.from(fields.children), arr = children.filter(x => x === children[len] || x === children[len - 1]);
arr[0].style.gridColumn = '1 / 7', arr[1].style.gridColumn = '7 / 13';
}
display(fields, undefined, 'grid');
} else hide(fields);
embed.classList.remove('empty');
let re = /"((icon_)?url")(: *)("(?!\w+?:\/\/).+?")/g.exec(editor.getValue())
if (re) error(`URLs should have a valid protocol (eg. https://) on this line <span class="inline">${makeShort(re[0], 30, 600)}</span>`, true);
let re = /"((icon_)?url")(: *)("(?!https?:\/\/).+?")/g.exec(editor.getValue())
if (re) error(`URLs should start with <code>https://</code> or <code>http://</code> on this line <span class="inline full">${makeShort(re[0], 30, 600)}</span>`, true);
else notif.animate({ opacity: '0', bottom: '-50px', offset: 1 }, { easing: 'ease', duration: 500 }).onfinish = () => notif.style.removeProperty('display');
twemoji.parse(msgEmbed);
}
} catch (e) {
error(e);
@ -146,16 +145,14 @@ window.onload = () => {
editor.on('change', editor => {
try { update(toObj(editor.getValue())); }
catch (e) {
if (editor.getValue()) return; // error("Couldn't parse JSON; Invalid JSON syntax", e)
if (editor.getValue()) return;
embed.classList.add('empty');
content.innerHTML = '';
}
document.querySelectorAll('.markup pre > code').forEach((block) => hljs.highlightBlock(block));
twemoji.parse(msgEmbed);
});
update(toObj(editor.getValue()));
twemoji.parse(msgEmbed);
document.querySelector('.timeText').innerText = tstamp()
document.querySelectorAll('.markup pre > code').forEach((block) => hljs.highlightBlock(block))
!window.navigator.userAgent.match(/Firefox\/[\d\.]+$/g) && // Firefox pushes the text up a little

View file

@ -23,6 +23,8 @@
<script src="https://unpkg.com/jsonlint@1.6.3/web/jsonlint.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.3/addon/lint/lint.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.3/addon/lint/lint.min.js"></script>
<!-- <script src="https://glitchii.github.io/embedbuilder/assets/js/components.js"></script> -->
<script src="http://localhost:5500/assets/js/components.js"></script>
<script src="./assets/js/index.js"></script>
</head>
<body>
@ -31,10 +33,10 @@
<div class="top item">
<textarea style="display: none;">
{
"content": "You can~~not~~ do `this`.```py\nAnd this.\nprint('Hi')```\n*italics* or _italics_ __*underline italics*__\n**bold** __**underline bold**__\n***bold italics*** __***underline bold italics***__\n__underline__ ~~Strikethrough~~",
"content": "You can~~not~~ do `this`.```\nAnd :laughing:this.\nprint('Hi') :) ```\n*italics* or _italics_ __*underline italics*__\n**bold** __**underline bold**__\n***bold italics*** __***underline bold italics***__\n__underline__ ~~Strikethrough~~\n> Hi",
"embed": {
"title": "Hello ~~people~~ world",
"description": "A description. You can use [links](https://discord.com).\nAnd also emojis 🙂\n```\nAlso code blocks```",
"title": "Hello ~~people~~ world :wave:",
"description": "You can use [links](https://discord.com), emojis 😎 :smile:, emoticons :-)\n```\nAlso code blocks```",
"color": 4321431,
"timestamp": "2020-12-08T13:37:35.401Z",
"url": "https://discord.com",
@ -79,9 +81,9 @@
"inline": true
},
{
"name": "Inline field",
"value": "value",
"inline": true
"name": "Another field",
"value": "> Nope, didn't forget about code blocks",
"inline": false
}
]
}