diff --git a/comp.js b/comp.js
deleted file mode 100644
index a57cac6..0000000
--- a/comp.js
+++ /dev/null
@@ -1,675 +0,0 @@
-
-// Want to use or contribute to this? https://github.com/Glitchii/embedbuilder
-// If you found an issue, please report it, make a P.R, or use the discussion page. Thanks
-
-var activeFields, colNum = 1, num = 0,
- toRGB = (hex, reversed, integer) => {
- if (reversed) return '#' + hex.match(/[\d]+/g).map(x => parseInt(x).toString(16).padStart(2, '0')).join('');
- if (integer) return parseInt(hex.match(/[\d]+/g).map(x => parseInt(x).toString(16).padStart(2, '0')).join(''), 16);
- if (hex.includes(',')) return hex.match(/[\d]+/g);
- hex = hex.replace('#', '').match(/.{1,2}/g)
- return [parseInt(hex[0], 16), parseInt(hex[1], 16), parseInt(hex[2], 16), 1];
- }, json = {
- 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~~",
- embed: {
- title: "Hello ~~people~~ world :wave:",
- description: "You can use [links](https://discord.com) or emojis :smile: 😎\n```\nAnd also code blocks\n```",
- color: 4321431,
- timestamp: new Date().toISOString(),
- url: "https://discord.com",
- author: {
- name: "Author name",
- url: "https://discord.com",
- icon_url: "https://unsplash.it/100"
- },
- thumbnail: {
- url: "https://unsplash.it/200"
- },
- image: {
- url: "https://unsplash.it/380/200"
- },
- footer: {
- text: "Footer text",
- icon_url: "https://unsplash.it/100"
- },
- fields: [
- {
- name: "Field 1, *lorem* **ipsum**, ~~dolor~~",
- value: "Field value"
- },
- {
- name: "Field 2",
- value: "You can use custom emojis <:Kekwlaugh:722088222766923847>. <:GangstaBlob:742256196295065661>",
- inline: false
- },
- {
- name: "Inline field",
- value: "Fields can be inline",
- inline: true
- },
- {
- name: "Inline field",
- value: "*Lorem ipsum*",
- inline: true
- },
- {
- name: "Inline field",
- value: "value",
- inline: true
- },
- {
- name: "Another field",
- value: "> Nope, didn't forget about code blocks",
- inline: false
- }
- ]
- }
- };
-
-window.onload = () => {
- document.querySelectorAll('img.clickable')
- .forEach(e => e.addEventListener('click', el => window.open(el.target.src)));
- let editorHolder = document.querySelector('.editorHolder'),
- guiParent = document.querySelector('.top'),
- embedContent = document.querySelector('.messageContent'),
- embedCont = document.querySelector('.messageContent + .container'),
- gui = guiParent.querySelector('.gui:first-of-type');
- window.editor = CodeMirror(elt => editorHolder.parentNode.replaceChild(elt, editorHolder), {
- value: JSON.stringify(json, null, 4),
- extraKeys: { Tab: cm => cm.replaceSelection(" ", "end") },
- gutters: ["CodeMirror-foldgutter", "CodeMirror-lint-markers"],
- scrollbarStyle: "overlay",
- mode: "application/json",
- theme: 'material-darker',
- matchBrackets: true,
- foldGutter: true,
- lint: true,
- });
-
- editor.focus();
- let notif = document.querySelector('.notification'),
- url = (url) => /^(https?:)?\/\//g.exec(url) ? url : '//' + url,
- makeShort = (txt, length, mediaWidth) => {
- if (mediaWidth && window.matchMedia(`(max-width:${mediaWidth}px)`).matches)
- return txt.length > (length - 3) ? txt.substring(0, length - 3) + '...' : txt;
- return txt;
- }, error = (msg, time) => {
- notif.innerHTML = msg, notif.style.display = 'block';
- time && setTimeout(() => notif.animate({ opacity: '0', bottom: '-50px', offset: 1 }, { easing: 'ease', duration: 500 })
- .onfinish = () => notif.style.removeProperty('display'), time);
- return false;
- }, allGood = e => {
- let str = JSON.stringify(e, null, 4), re = /("(?:icon_)?url": *")((?!\w+?:\/\/).+)"/g.exec(str);
- if (e.timestamp && new Date(e.timestamp).toString() === "Invalid Date") return error('Timestamp is invalid');
- if (re) { // If a URL is found without a protocol
- if (!/\w+:|\/\/|^\//g.exec(re[2]) && re[2].includes('.')) {
- let activeInput = document.querySelector('input[class$="link" i]:focus')
- if (activeInput) {
- lastPos = activeInput.selectionStart + 7;
- authorLink.value = `http://${re[2]}`;
- update(JSON.parse(str.replace(re[0], `${re[1]}http://${re[2]}"`)));
- activeInput.setSelectionRange(lastPos, lastPos)
- return true;
- }
- }
- return error(`URL should have a protocol. Did you mean http://${makeShort(re[2], 30, 600).replace(' ', '')}?`);
- }
- return true;
- }, markup = (txt, opts) => {
- txt = txt
- .replace(/\<:[^:]+:(\d+)\>/g, '
')
- .replace(/\<a:[^:]+:(\d+)\>/g, '
')
- .replace(/~~(.+?)~~/g, '$1')
- .replace(/\*\*\*(.+?)\*\*\*/g, '$1')
- .replace(/\*\*(.+?)\*\*/g, '$1')
- .replace(/__(.+?)__/g, '$1')
- .replace(/\*(.+?)\*/g, '$1')
- .replace(/_(.+?)_/g, '$1')
- if (opts.inlineBlock) txt = txt.replace(/\`([^\`]+?)\`|\`\`([^\`]+?)\`\`|\`\`\`((?:\n|.)+?)\`\`\`/g, (m, x, y, z) => x ? `${x}
` : y ? `${y}
` : z ? `${z}
` : m);
- else txt = txt.replace(/\`\`\`(\w{1,15})?\n((?:\n|.)+?)\`\`\`|\`\`(.+?)\`\`(?!\`)|\`([^\`]+?)\`/g, (m, w, x, y, z) => w && x ? `
${x}
` : x ? `${x}
` : y || z ? `${y || z}
` : m);
- if (opts.inEmbed) txt = txt.replace(/\[([^\[\]]+)\]\((.+?)\)/g, `$1`);
- if (opts.replaceEmojis) txt = txt.replace(/(?[^>]+)(? x && emojis[x] ? emojis[x] : match);
- txt = txt
- .replace(/(?<=\n|^)\s*>\s+([^\n]+)/g, '')
- .replace(/\n/g, '
');
- return txt;
- },
- embed = document.querySelector('.embedGrid'),
- msgEmbed = document.querySelector('.msgEmbed'),
- embedTitle = document.querySelector('.embedTitle'),
- embedDescription = document.querySelector('.embedDescription'),
- embedAuthor = document.querySelector('.embedAuthor'),
- embedFooter = document.querySelector('.embedFooter'),
- embedImage = document.querySelector('.embedImage'),
- embedThumbnail = document.querySelector('.embedThumbnail'),
- embedFields = embed.querySelector('.embedFields'),
- encodeHTML = str => str.replace(/[\u00A0-\u9999<>\&]/g, i => '' + i.charCodeAt(0) + ';'),
- tstamp = stringISO => {
- let date = stringISO ? new Date(stringISO) : new Date(),
- dateArray = date.toLocaleString('en-US', { hour: 'numeric', hour12: true, minute: 'numeric' }),
- today = new Date(),
- yesterday = new Date(new Date().setDate(today.getDate() - 1));
- return today.toDateString() === date.toDateString() ? `Today at ${dateArray}` :
- yesterday.toDateString() === date.toDateString() ? `Yesterday at ${dateArray}` :
- `${String(date.getMonth() + 1).padStart(2, '0')}/${String(date.getDate()).padStart(2, '0')}/${date.getFullYear()}`;
- }, display = (el, data, displayType) => {
- if (data) el.innerHTML = data;
- el.style.display = displayType || "unset";
- }, hide = el => el.style.removeProperty('display'),
- imgSrc = (elm, src, remove) => remove ? elm.style.removeProperty('content') : elm.style.content = `url(${src})`,
- toObj = jsonString => JSON.parse(jsonString.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (x, y) => y ? "" : x));
- buildGui = (object, opts) => {
- gui.innerHTML = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `;
-
- let fieldsEditor = gui.querySelector('.fields ~ .edit'), addField = `
-
-
New Field
-
-
`;
- if (object.embed?.fields) fieldsEditor.innerHTML = object.embed.fields.filter(f => f && typeof f === 'object').map(f => `
-
-
-
-
-
-
-
-
`).join('\n') + addField;
- else fieldsEditor.innerHTML = addField;
-
- gui.querySelectorAll('.removeBtn').forEach(e => {
- e.addEventListener('click', el => {
- fields = gui.querySelector('.fields ~ .edit');
- let field = el.target.closest('.field');
- if (field) {
- let i = Array.from(fields.children).indexOf(field), jsonField = object.embed.fields[i];
- if (jsonField) {
- object.embed.fields.splice(i, 1);
- field.remove();
- update(object);
- }
- }
- })
- })
-
- document.querySelectorAll('.gui > .item').forEach(e => {
- e.addEventListener('click', el => {
- let elm = (el.target.closest('.top>.gui>.item') || el.target);
- if (elm.classList.contains('active')) window.getSelection().anchorNode !== elm && elm.classList.remove('active');
- else {
- let inlineField = elm.closest('.inlineField'),
- input = elm.nextElementSibling.querySelector('input[type="text"]'),
- txt = elm.nextElementSibling.querySelector('textarea');
- elm.classList.add('active');
- if (inlineField) inlineField.querySelector('.ttle~input').focus();
- else if (input) {
- input.focus();
- input.selectionStart = input.selectionEnd = input.value.length;
- } else if (txt) txt.focus();
- elm.classList.contains('fields') && elm.scrollIntoView({ behavior: "smooth", block: "center" });
- }
- })
- })
-
- content = gui.querySelector('.editContent');
- title = gui.querySelector('.editTitle');
- authorName = gui.querySelector('.editAuthorName');
- authorLink = gui.querySelector('.editAuthorLink');
- desc = gui.querySelector('.editDescription');
- thumbLink = gui.querySelector('.editThumbnailLink');
- imgLink = gui.querySelector('.editImageLink');
- footerText = gui.querySelector('.editFooterText');
- footerLink = gui.querySelector('.editFooterLink');
- fields = gui.querySelector('.fields ~ .edit');
-
- document.querySelector('.addField').addEventListener('click', () => {
- !json.embed && (json.embed = {});
- let arr = json.embed.fields || [];
- if (arr.length >= 25) return error('Cannot have more than 25 fields', 5000);
- arr.push({ name: "Field name", value: "Field value", inline: false });
- json.embed.fields = arr;
- update(json);
- buildGui(json, { newField: true, activate: document.querySelectorAll('.gui > .item.active') });
- })
-
- gui.querySelectorAll('textarea, input').forEach(e => e.addEventListener('input', el => {
- let value = el.target.value, field = el.target.closest('.field');
- if (field) {
- let jsonField = json.embed.fields[Array.from(fields.children).indexOf(field)];
- if (jsonField) {
- if (el.target.type === 'text') jsonField.name = value;
- else if (el.target.type === 'textarea') jsonField.value = value;
- else jsonField.inline = el.target.checked;
- } else {
- let obj = {}
- if (el.target.type === 'text') obj.name = value;
- else if (el.target.type === 'textarea') obj.value = value;
- else obj.inline = el.target.checked;
- json.embed.fields.push(obj);
- }
- } else {
- json.embed ??= {};
- switch (el.target) {
- case content: json.content = value; break;
- case title: json.embed.title = value; break;
- case authorName: json.embed.author ??= {}, json.embed.author.name = value; break;
- case authorLink: json.embed.author ??= {}, json.embed.author.icon_url = value, imgSrc(el.target.previousElementSibling, value); break;
- case desc: json.embed.description = value; break;
- case thumbLink: json.embed.thumbnail ??= {}, json.embed.thumbnail.url = value, imgSrc(el.target.closest('.editIcon').querySelector('.imgParent'), value); break;
- case imgLink: json.embed.image ??= {}, json.embed.image.url = value, imgSrc(el.target.closest('.editIcon').querySelector('.imgParent'), value); break;
- case footerText: json.embed.footer ??= {}, json.embed.footer.text = value; break;
- case footerLink: json.embed.footer ??= {}, json.embed.footer.icon_url = value, imgSrc(el.target.previousElementSibling, value); break;
- }
- }
- update(json);
- }))
-
- if (opts?.activate) {
- let elements = opts.activate;
- Array.from(elements).map(el => el.className).map(clss => '.' + clss.split(' ').slice(0, 2).join('.'))
- .forEach(clss => document.querySelectorAll(clss)
- .forEach(e => e.classList.add('active')))
- } else['.item.author', '.item.description'].forEach(clss => document.querySelector(clss).classList.add('active'));
-
- if (opts?.newField) {
- let last = fields.children[fields.childElementCount - 2], el = last.querySelector('.designerFieldName > input');
- el.setSelectionRange(el.value.length, el.value.length); el.focus();
- last.scrollIntoView({ behavior: "smooth", block: "center" });
- }
-
- let files = document.querySelectorAll('input[type="file"]');
- files.forEach(f => f.addEventListener('change', e => {
- if (f.files) {
- e.target.nextElementSibling.click();
- e.target.closest('.edit').querySelector('.browse').classList.add('loading');
- }
- }))
-
- document.querySelectorAll('form').forEach(form => form.addEventListener('submit', e => {
- e.preventDefault();
- let formData = new FormData(e.target);
- formData.append('file', files.files);
- formData.append('datetime', '10m');
- fetch('https://tempfile.site/api/files', {
- method: 'POST',
- body: formData,
- })
- .then(res => res.json())
- .then(res => {
- let browse = e.target.closest('.edit').querySelector('.browse');
- browse.classList.remove('loading');
- if (!res.ok) {
- console.log(res.error);
- browse.classList.add('error');
- return setTimeout(() => browse.classList.remove('error'), 5000)
- }
- imgSrc(e.target.previousElementSibling.querySelector('.editIcon > .imgParent') || e.target.closest('.editIcon').querySelector('.imgParent'), res.link);
- let input = e.target.previousElementSibling.querySelector('.editIcon > input') || e.target.previousElementSibling;
- input.value = res.link;
- if (input === authorLink) ((json.embed ??= {}).author ??= {}).icon_url = res.link;
- else if (input === thumbLink) ((json.embed ??= {}).thumbnail ??= {}).url = res.link;
- else if (input === imgLink) ((json.embed ??= {}).image ??= {}).url = res.link;
- else ((json.embed ??= {}).footer ??= {}).url = res.link;
- update(json);
- console.info(`Image (${res.link}) will be deleted in 10 minutes. To delete it now, go to ${res.link.replace('/files', '/del')} and enter this code: ${res.authkey}`);
- }).catch(err => error(`Request to tempfile.site failed with error: ${err}`, 5000))
- }))
- }
-
- buildGui(json);
- fields = gui.querySelector('.fields ~ .edit');
- update = data => {
- try {
- if (!data.content) embedContent.classList.add('empty');
- else {
- embedContent.innerHTML = markup(encodeHTML(data.content), { replaceEmojis: true });
- embedContent.classList.remove('empty');
- }
- if (data.embed && Object.keys(data.embed).length) {
- let e = data.embed;
- if (!allGood(e)) return;
- if (e.title) display(embedTitle, markup(`${e.url ? '' + encodeHTML(e.title) + '' : encodeHTML(e.title)}`, { replaceEmojis: true, inlineBlock: true }));
- else hide(embedTitle);
- if (e.description) display(embedDescription, markup(encodeHTML(e.description), { inEmbed: true, replaceEmojis: true }));
- else hide(embedDescription);
- if (e.color) embed.closest('.embed').style.borderColor = encodeHTML(typeof e.color === 'number' ? '#' + e.color.toString(16).padStart(6, "0") : e.color);
- else embed.closest('.embed').style.removeProperty('border-color');
- if (e.author && e.author.name) display(embedAuthor, `
- ${e.author.icon_url ? '
' : ''}
- ${e.author.url ? '' + encodeHTML(e.author.name) + '' : '' + encodeHTML(e.author.name) + ''}`, 'flex');
- else hide(embedAuthor);
- if (e.thumbnail && e.thumbnail.url) embedThumbnail.src = encodeHTML(e.thumbnail.url), embedThumbnail.style.display = 'block';
- else hide(embedThumbnail);
- if (e.image && e.image.url) embedImage.src = encodeHTML(e.image.url), embedImage.style.display = 'block';
- else hide(embedImage);
- if (e.footer && e.footer.text) display(embedFooter, `
- ${e.footer.icon_url ? '' : ''}`, 'flex');
- else if (e.timestamp) display(embedFooter, ``, 'flex');
- else hide(embedFooter);
- if (e.fields) {
- embedFields.innerHTML = '';
- e.fields.forEach(f => {
- if (f.name && f.value) {
- if (!f.inline) {
- let el = embedFields.insertBefore(document.createElement('div'), null);
- el.outerHTML = `
-
-
${markup(encodeHTML(f.name), { inEmbed: true, replaceEmojis: true, inlineBlock: true })}
-
${markup(encodeHTML(f.value), { inEmbed: true, replaceEmojis: true })}
-
`;
- } else {
- el = embedFields.insertBefore(document.createElement('div'), null);
- el.outerHTML = `
-
-
${markup(encodeHTML(f.name), { inEmbed: true, replaceEmojis: true, inlineBlock: true })}
-
${markup(encodeHTML(f.value), { inEmbed: true, replaceEmojis: true })}
-
`;
- colNum = (colNum === 9 ? 1 : colNum + 4);
- num++;
- }
- }
- });
- colNum = 1;
- let len = e.fields.filter(f => f.inline).length;
- if (len === 2 || (len > 3 && len % 2 !== 0)) {
- let children = Array.from(embedFields.children), arr = children.filter(x => x === children[len] || x === children[len - 1]);
- arr[0] && (arr[0].style.gridColumn = '1 / 7');
- arr[1] && (arr[1].style.gridColumn = '7 / 13');
- }
- display(embedFields, undefined, 'grid');
- } else hide(embedFields);
- embedCont.classList.remove('empty');
- document.querySelectorAll('.markup pre > code').forEach((block) => hljs.highlightBlock(block));
- notif.animate({ opacity: '0', bottom: '-50px', offset: 1 }, { easing: 'ease', duration: 500 }).onfinish = () => notif.style.removeProperty('display');
- twemoji.parse(msgEmbed);
- } else embedCont.classList.add('empty');
- } catch (e) {
- error(e);
- }
- }
-
- editor.on('change', editor => {
- try { update(toObj(editor.getValue())); }
- catch (e) {
- if (editor.getValue()) return;
- embedCont.classList.add('empty');
- embedContent.innerHTML = '';
- }
- });
-
- let picker = new CP(document.querySelector('.picker'), state = { parent: document.querySelector('.cTop') });
- picker.fire('change', toRGB('#41f097'));
-
- let colRight = document.querySelector('.colRight'), removePicker = () => colRight.classList.remove('picking');
- document.querySelector('.colBack').addEventListener('click', e => {
- picker.self.remove(); removePicker();
- })
- picker.on('enter', () => colRight.classList.add('picking'))
- picker.on('exit', removePicker);
-
- document.querySelectorAll('.colr').forEach(e => e.addEventListener('click', el => {
- el = el.target.closest('.colr') || el.target;
- embed.closest('.embed').style.borderColor = el.style.backgroundColor;
- json.embed && (json.embed.color = toRGB(el.style.backgroundColor, false, true));
- picker.source.style.removeProperty('background');
- }))
-
- setTimeout(() => {
- picker.on('change', function (r, g, b, a) {
- embed.closest('.embed').style.borderColor = this.color(r, g, b);
- json.embed && (json.embed.color = parseInt(this.color(r, g, b).slice(1), 16));
- picker.source.style.background = this.color(r, g, b);
- })
- }, 1000)
-
- 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
- document.querySelector('.botText').style.removeProperty('top');
-
- document.querySelector('.opt.gui').addEventListener('click', () => {
- json = toObj(editor.getValue() || '{}');
- buildGui(json, { activate: activeFields });
- document.body.classList.add('gui');
- activeFields = null;
- })
-
- document.querySelector('.opt.json').addEventListener('click', () => {
- editor.setValue(JSON.stringify(json, null, 4));
- editor.refresh();
- document.body.classList.remove('gui');
- editor.focus();
- activeFields = document.querySelectorAll('.gui > .item.active');
- })
-
- document.querySelector('.clear').addEventListener('click', () => {
- json = {};
- embed.style.removeProperty('border-color');
- picker.source.style.removeProperty('background');
- update(json); buildGui(json); editor.setValue(JSON.stringify(json, null, 4));
- document.querySelectorAll('.gui>.item').forEach(e => e.classList.add('active'));
- content.focus();
- })
-
- let colrs = document.querySelector('.colrs');
- document.querySelector('.pickerToggle').addEventListener('click', () => colrs.classList.toggle('display'));
- update(json);
-};