From 724d633905ccf0434a083c3ccefbea9cc177ffcf Mon Sep 17 00:00:00 2001 From: Glitchii Date: Fri, 1 Apr 2022 14:38:10 +0000 Subject: [PATCH] Update README.md about iframing, detect iframe and work with it --- README.md | 5 ++-- assets/css/index.css | 16 +++++++----- assets/js/script.js | 62 ++++++++++++++++++++++++++++---------------- index.html | 2 +- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 55ad3dc..8f96dab 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,9 @@ https://glitchii.github.io/embedbuilder/?username=Troy&verified&reverse&guitabs= This will only work through iframe or a cloned repo of the builder: Have a JavaScript config file named `builder.config.js`. In this file, define `window.options` to an object containing the params. Note that some param names and cases will be different from the URL ones. An example [builder.config.js](/builder.config.js) file is included in the repo. The config file is loaded before the [main script](/assets/js/script.js) and because it's a JS file, you can do and probably alter anything else. >## 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. -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 should iframe https://glitchii.github.io/embedbuilder into your website with a few of the parameters above if needed instead. +>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. +
+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.

diff --git a/assets/css/index.css b/assets/css/index.css index 1930053..50528b1 100644 --- a/assets/css/index.css +++ b/assets/css/index.css @@ -38,11 +38,6 @@ font-display: swap; } -* { - outline: none; - box-sizing: border-box; -} - :root { --link: #00b0f4; --embedTextColor: #dcddde; @@ -57,6 +52,15 @@ --interactive-muted: #4f545c; } +* { + outline: none; + box-sizing: border-box; +} + +html, body { + height: 100%; +} + body { line-height: 1; margin: 0px; @@ -2142,4 +2146,4 @@ body.emptyEmbed.emptyContent .emptyTxt { .markup>blockquote, .markup pre { max-width: 99%; } -} +} \ No newline at end of file diff --git a/assets/js/script.js b/assets/js/script.js index d6b9988..7728b64 100644 --- a/assets/js/script.js +++ b/assets/js/script.js @@ -3,8 +3,10 @@ // If you found an issue, please report it, make a P.R, or use the discussion page. Thanks 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); -var params = new URL(window.location.href).searchParams, +var params = currentURL().searchParams, hasParam = param => params.get(param) !== null, dataSpecified = options.dataSpecified || params.get('data'), username = params.get('username') || options.username, @@ -26,14 +28,14 @@ var params = new URL(window.location.href).searchParams, localStorage.removeItem(item); return found; }, - jsonToBase64 = (jsonCode, withURL, redirect) => { + jsonToBase64 = (jsonCode, withURL = false, redirect = false) => { data = btoa(escape((JSON.stringify(typeof jsonCode === 'object' ? jsonCode : json)))); if (withURL) { - let currentURL = new URL(window.location); - currentURL.searchParams.append('data', data); - if (redirect) window.location = currentURL; + const url = currentURL(); + url.searchParams.append('data', data); + if (redirect) window.top.location.href = url; // Replace %3D ('=' url encoded) with '=' - data = currentURL.href.replace(/data=\w+(?:%3D)+/g, 'data=' + data); + data = url.href.replace(/data=\w+(?:%3D)+/g, 'data=' + data); } return data; }, @@ -59,11 +61,17 @@ var params = new URL(window.location.href).searchParams, if (autoParams) isReversed ? urlOptions({ set: ['reverse', ''] }) : urlOptions({ remove: 'reverse' }); }, urlOptions = ({ remove, set }) => { - const url = new URL(window.location.href); + const url = currentURL(), href = url.href.replace(/=&|=$/g, x => x === '=' ? '' : '&'); if (remove) url.searchParams.delete(remove); if (set) url.searchParams.set(set[0], set[1]); - // history.replaceState(null, null, url.href); - history.replaceState(null, null, url.href.replace(/=&|=$/g, x => x === '=' ? '' : '&')); + try { + history.replaceState(null, null, href); + } catch (e) { + // Most likely embeded in iframe + console.message(`${e.name}: ${e.message}`, e); + // if (e.name === 'SecurityError') + // window.top.location.href = href; + } }, mainKeys = ["author", "footer", "color", "thumbnail", "image", "fields", "title", "description", "url", "timestamp"], jsonKeys = ["embed", "content", ...mainKeys], @@ -151,6 +159,11 @@ addEventListener('DOMContentLoaded', () => { document.body.classList.add('autoUpdateURL'); 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)')) + e.remove(); + document.querySelectorAll('.clickable > img') .forEach(e => e.parentElement.addEventListener('mouseup', el => window.open(el.target.src))); @@ -709,22 +722,22 @@ addEventListener('DOMContentLoaded', () => { if (data.embed && Object.keys(data.embed).length) { const emb = data.embed; if (!allGood(emb)) return; - + validationError = false; if (emb.title) display(embedTitle, markup(`${emb.url ? '' + encodeHTML(emb.title) + '' : encodeHTML(emb.title)}`, { replaceEmojis: true, inlineBlock: true })); else hide(embedTitle); - + if (emb.description) display(embedDescription, markup(encodeHTML(emb.description), { inEmbed: true, replaceEmojis: true })); else hide(embedDescription); - + if (emb.color) embed.closest('.embed').style.borderColor = (typeof emb.color === 'number' ? '#' + emb.color.toString(16).padStart(6, "0") : emb.color); else embed.closest('.embed').style.removeProperty('border-color'); - + if (emb.author?.name) display(embedAuthor, ` ${emb.author.icon_url ? '' : ''} ${emb.author.url ? '' + encodeHTML(emb.author.name) + '' : '' + encodeHTML(emb.author.name) + ''}`, 'flex'); else hide(embedAuthor); - + const pre = embed.querySelector('.markup pre'); if (emb.thumbnail?.url) { embedThumbnail.src = emb.thumbnail.url, @@ -734,19 +747,19 @@ addEventListener('DOMContentLoaded', () => { hide(embedThumbnail.parentElement); if (pre) pre.style.removeProperty('max-width'); } - + if (emb.image?.url) embedImage.src = emb.image.url, embedImage.parentElement.style.display = 'block'; else hide(embedImage.parentElement); - + if (emb.footer?.text) display(embedFooter, ` ${emb.footer.icon_url ? '' : ''} ${encodeHTML(emb.footer.text)} ${emb.timestamp ? '' + encodeHTML(tstamp(emb.timestamp)) : ''}`, 'flex'); else if (emb.timestamp) display(embedFooter, `${encodeHTML(tstamp(emb.timestamp))}`, 'flex'); else hide(embedFooter); - + if (emb.fields) { innerHTML(embedFields, ''); let index, gridCol; @@ -813,7 +826,7 @@ addEventListener('DOMContentLoaded', () => { twemoji.parse(msgEmbed); } else document.body.classList.add('emptyEmbed'); - + // Make sure that the embed has no text or any visible images such as custom emojis before hiding. if (!embedCont.innerText && !document.querySelector('.messageContent + .container .embedGrid > [style*=display] img')) document.body.classList.add('emptyEmbed'); @@ -822,7 +835,8 @@ addEventListener('DOMContentLoaded', () => { if (autoUpdateURL) urlOptions({ set: ['data', jsonToBase64(json)] }) } catch (e) { - console.log(e); + console.error(e); + console.dir(e); error(e); } } @@ -965,8 +979,6 @@ addEventListener('DOMContentLoaded', () => { if (input.checked) localStorage.setItem('autoParams', true); else localStorage.removeItem('autoParams'); autoParams = input.checked; - - console.log(input?.checked, e.target.closest('.item.auto-params')) } e.target.closest('.top-btn').classList.toggle('active') }) @@ -1031,4 +1043,10 @@ addEventListener('DOMContentLoaded', () => { next(); } }); -}); \ No newline at end of file +}); + +console.__proto__.message = function (title, message, collapse = true) { + collapse && this.groupCollapsed(title) || this.group(title); + this.dir(message); + this.groupEnd(); +} \ No newline at end of file diff --git a/index.html b/index.html index ca02277..cd3d295 100644 --- a/index.html +++ b/index.html @@ -158,7 +158,7 @@
Hide username and avatar
-
+