Add option to toggle between editor & preview

This commit is contained in:
Glitchii 2022-04-01 18:51:02 +00:00
parent 724d633905
commit 455a039efb
5 changed files with 200 additions and 20 deletions

View file

@ -41,7 +41,9 @@ placeholders Silences some warrnings, e.g. warrnings about missing ur
This param is useful when your bot allows having placeholders in place of a URL eg. `{ server.url }`
placeholders=errors This also disables automatic insertion of 'http' for urls without a protocol.
Except, warnings won't be silenced. The user will still see a warning that a url or timestamp (etc.) is incorrect for 5 seconds.
hideditor Hides the editor.
hidepreview Hides the preview.
hidemenu Hides the three dotted menu.
```
<small>Case matters, all parameters should be lowercase.</small>
### Example URL with all* the above parameters:
@ -53,7 +55,7 @@ This will only work through iframe or a cloned repo of the builder: Have a JavaS
>## Intergretting into your website
>You are free to use this in your website. Intergretting into your websites allows sending the embed to Discord with a few changes, and using 'formatters' eg. '{ server.name }' or '{ user.name }' etc. A (not so bad) downside would be that you'd probably have to keep up with fixes and updates.
<br>
To over come that, and if all you want is to have an embed builder in your website with no additional features and maybe using your own bot name and avatar, etc., then you might iframe https://glitchii.github.io/embedbuilder into your website with a few of the parameters above if needed instead. The downside to this is that due to security reasons, browsers won't allow features like updating URL parameter to work through iframes, whoever URL options will still be read from the top holder of the iframe, those are probably the only features that won't work and thus are removed from the GUI menu when embeded in iframe.
To over come that, and if all you want is to have an embed builder in your website with no additional features and maybe using your own bot name and avatar, etc., then you might iframe https://glitchii.github.io/embedbuilder into your website with a few of the parameters above if needed instead. The downside to this is that due to security reasons, browsers won't allow features like updating URL parameter to work through iframes, whoever URL options will still be read from the top holder of the iframe, those are probably the only features that won't work and thus are removed from the GUI menu when embeded in iframe. `builder.config.js` also won't be seen in iframe
<br><br>

View file

@ -79,6 +79,10 @@ body.no-user .msgEmbed>.contents {
display: none;
}
.pointer {
cursor: pointer;
}
.main {
position: absolute;
width: 100%;
@ -86,7 +90,7 @@ body.no-user .msgEmbed>.contents {
display: grid;
}
body:not(.only-embed) .main {
body:not(.no-preview):not(.no-editor) .main {
grid-template-columns: 45% 55%;
}
@ -1143,7 +1147,7 @@ body:not(.gui) .chooser>.back {
.bottom .colrs {
z-index: 5;
animation: colrsAn .5s ease-out;
animation: colrsAn .25s ease-out;
background: #212226;
border-radius: 10px;
width: 250px;
@ -1801,7 +1805,6 @@ body {
--bgc: #27282e;
left: 140px;
position: absolute;
cursor: pointer;
z-index: 5;
transform: translate(0, -5px);
padding: 8.5px;
@ -1812,6 +1815,10 @@ body {
transition: .5s ease;
}
.top-btn:not(.active) {
cursor: pointer;
}
.top-btn.copy {
left: 190px;
}
@ -1881,8 +1888,9 @@ body {
align-content: center;
}
.top-btn.menu>.box .item:hover {
.top-btn.menu>.box .item.normal:hover {
background: #35373f;
cursor: pointer;
}
.vs {
@ -1895,13 +1903,42 @@ body {
transform: translateX(-50%);
}
.top-btn.menu>.box .item> :is(*, *>svg) {
.top-btn.menu>.box .item.normal> :is(*, *>svg) {
display: flex;
align-self: flex-end;
margin: 0;
}
.top-btn.menu>.box .item>input {
.item.toggle {
display: block;
}
.item.toggle .inner .toggles {
display: flex;
gap: 2em;
}
.item.toggle .inner .toggles .item {
align-items: center;
background: #35363e;
padding: 5px 10px;
}
.item.toggle .inner .toggles .item * {
pointer-events: none;
}
.item.toggle .inner .title {
text-align: left;
margin: 10px 0;
opacity: .5;
text-transform: uppercase;
font-size: 79%;
font-weight: bold;
pointer-events: none;
}
.item.toggle .item.toggle .item.toggle .item.toggle .top-btn.menu>.box .item>input {
pointer-events: none;
}
@ -1995,6 +2032,96 @@ body.emptyEmbed.emptyContent .emptyTxt {
top: 800%;
}
body.no-editor.no-preview .side1 .chooser {
background: transparent;
}
body.no-editor .side1 :not(.needed):not(.needed *) {
display: none !important;
}
body.no-editor .main .side1,
body.no-preview .main .side2 {
height: auto;
padding-bottom: 5px;
background: transparent;
}
body:is(.no-preview, .no-editor) .main {
display: flex;
flex-direction: column;
}
body.no-editor .side1 .chooser :is(.back, .opt) {
/* display: none; */
opacity: .25;
pointer-events: none;
}
body.no-editor .side1 .chooser.needed> :not(.menu) {
display: none !important;
}
body.no-editor .side1 {
position: absolute;
}
/* body.no-editor .side1 .chooser {
background: transparent;
} */
/* body.no-editor .side1 {
display: none !important;
} */
body.no-preview .side2 {
display: none !important;
}
/* body.no-editor .bottom .colrs {
left: 20px;
top: 90px;
bottom: 0;
} */
body.no-editor .bottom .colrs {
left: 20px;
top: 90px;
bottom: 0;
display: none;
}
body.no-editor .pickerToggle {
display: block;
position: absolute;
cursor: pointer;
z-index: 5;
left: 226px;
border-left: 2px solid #4c5057;
padding-left: 15px;
bottom: auto;
margin-left: 15px;
}
body.no-editor .pickerToggle>svg {
width: 17px;
transform: translateY(2px);
}
body.no-editor .main .side1 {
border-right: none;
}
body.no-editor .side1 .item.top {
padding-top: 10px;
transform: translateY(10px);
}
body.no-editor .bottom .colrs.display {
display: grid;
}
::-webkit-scrollbar {
width: 7px;
background: #292b2f00;
@ -2049,7 +2176,8 @@ body.emptyEmbed.emptyContent .emptyTxt {
.bottom .colrs {
bottom: 40px;
top: 100px;
left: 10px;
top: 90px;
left: 20px;
display: none;
animation: colrsAn .1s ease-out;
box-shadow: 0px 5px 15px 0px #0000004f;
@ -2066,7 +2194,7 @@ body.emptyEmbed.emptyContent .emptyTxt {
width: 100%;
}
.bottom {
body:not(.no-editor) .bottom {
margin: 40px 0 0 0 !important;
}

View file

@ -4,7 +4,7 @@
options = window.options || {};
inIframe = window.inIframe || top !== self;
currentURL = () => new URL(inIframe ? /(https?:\/\/(?:[\d\w]+\.)?[\d\w\.]+(?::\d+)?)/g.exec(document.referrer)[0] : location.href);
currentURL = () => new URL(inIframe ? /(https?:\/\/(?:[\d\w]+\.)?[\d\w\.]+(?::\d+)?)/g.exec(document.referrer)?.[0] || location.href : location.href);
var params = currentURL().searchParams,
hasParam = param => params.get(param) !== null,
@ -20,6 +20,9 @@ var params = currentURL().searchParams,
allowPlaceholders = hasParam('placeholders') || options.allowPlaceholders,
autoUpdateURL = localStorage.getItem('autoUpdateURL') || options.autoUpdateURL,
autoParams = localStorage.getItem('autoParams') || hasParam('autoparams') || options.autoParams,
hideEditor = localStorage.getItem('hideeditor') || hasParam('hideeditor') || options.hideEditor,
hidePreview = localStorage.getItem('hidepreview') || hasParam('hidepreview') || options.hidePreview,
hideMenu = localStorage.getItem('hideMenu') || hasParam('hidemenu') || options.hideMenu,
activeFields, colNum = 1, num = 0, validationError,
toggleStored = item => {
const found = localStorage.getItem(item);
@ -75,7 +78,7 @@ var params = currentURL().searchParams,
},
mainKeys = ["author", "footer", "color", "thumbnail", "image", "fields", "title", "description", "url", "timestamp"],
jsonKeys = ["embed", "content", ...mainKeys],
json = {
json = window.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:",
@ -160,9 +163,19 @@ addEventListener('DOMContentLoaded', () => {
if (autoParams)
document.querySelector('.auto-params > input').checked = true;
if (inIframe)
// Remove menu options that that don't work in iframe.
for (const e of document.querySelectorAll('.top-btn.menu :is(.item.auto, .item.auto-params, .vs.auto-url)'))
// Remove menu options that don't work in iframe.
for (const e of document.querySelectorAll('.no-frame'))
e.remove();
if (hideMenu)
document.querySelector('.top-btn.menu').remove();
if (hideEditor) {
document.body.classList.add('no-editor');
document.querySelector('.toggle .toggles .editor input').checked = false;
}
if (hidePreview) {
document.body.classList.add('no-preview');
document.querySelector('.toggle .toggles .preview input').checked = false;
}
document.querySelectorAll('.clickable > img')
.forEach(e => e.parentElement.addEventListener('mouseup', el => window.open(el.target.src)));
@ -955,7 +968,7 @@ addEventListener('DOMContentLoaded', () => {
content.focus();
})
document.querySelector('.top-btn.menu').addEventListener('click', e => {
document.querySelector('.top-btn.menu')?.addEventListener('click', e => {
if (e.target.closest('.item.dataLink'))
return prompt('Here\'s the current URL with base64 embed data:', jsonToBase64(json, true));
@ -979,6 +992,15 @@ addEventListener('DOMContentLoaded', () => {
if (input.checked) localStorage.setItem('autoParams', true);
else localStorage.removeItem('autoParams');
autoParams = input.checked;
} else if (e.target.closest('.toggles>.item')) {
const win = input.closest('.item').classList[2];
if (input.checked) {
document.body.classList.remove(`no-${win}`);
localStorage.removeItem(`hide${win}`);
} else {
document.body.classList.add(`no-${win}`);
localStorage.setItem(`hide${win}`, true);
}
}
e.target.closest('.top-btn').classList.toggle('active')
})

View file

@ -13,8 +13,20 @@ options = {
allowPlaceholders: false,
autoUpdateURL: false,
autoParams: false,
hideEditor: false,
hidePreview: false,
hideMenu: false,
}
// // Default JSON object
// json = {
// content: "Hello world",
// embed: {
// title: "A title",
// description: "A description",
// }
// }
onload = () => {
// console.log('Salut 👋');
}

View file

@ -40,7 +40,7 @@
<body class="gui emptyEmbed">
<div class="main">
<section class="side1 noDisplay">
<div class="chooser">
<div class="chooser needed">
<div class="back"></div>
<div class="gui opt">
<p>GUI</p>
@ -121,7 +121,7 @@
</div>
<div>Get data link</div>
</div>
<div class="item normal auto">
<div class="item normal auto no-frame">
<!-- <input type="checkbox" id="auto" name="auto" autocomplete="off" class="hidden"> -->
<div class="icon">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" x="0" y="0" viewBox="0 0 48 48" xml:space="preserve" width="16" height="16">
@ -158,8 +158,8 @@
</div>
<div>Hide username and avatar</div>
</div>
<div class="vs auto-url"></div>
<div class="item auto-params">
<div class="vs no-frame"></div>
<div class="item normal auto-params no-frame">
<input id="auto" name="auto" autocomplete="off" type="checkbox">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" x="0" y="0" viewBox="0 0 512 512" xml:space="preserve" width="16" height="16" fill="currentColor" style="display: none;">
<g>
@ -168,6 +168,22 @@
</svg>
<div>Auto-update URL options</div>
</div>
<div class="vs no-frame"></div>
<div class="item toggle">
<div class="inner">
<div class="title">Toggle on or off</div>
<div class="toggles">
<div class="item pointer editor">
<input autocomplete="off" type="checkbox" checked>
<span>Editor</span>
</div>
<div class="item pointer preview">
<input autocomplete="off" type="checkbox" checked>
<span>Preview</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@ -175,7 +191,7 @@
<div class="gui"></div>
<div class="editorHolder"></div>
</div>
<div class="bottom item">
<div class="bottom item needed">
<div class="colrs high">
<div class="hex">
<div>