From e59ba6d4a92107f28e17b2d723f2f721ab4af2b9 Mon Sep 17 00:00:00 2001 From: jessikitty Date: Tue, 26 May 2026 10:00:40 +1000 Subject: [PATCH] fix: White default bg, paste formatting preservation, text-align + all styles whitelisted --- Views/Slides/Create.cshtml | 48 +++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/Views/Slides/Create.cshtml b/Views/Slides/Create.cshtml index f0a47d5..94fa964 100644 --- a/Views/Slides/Create.cshtml +++ b/Views/Slides/Create.cshtml @@ -51,8 +51,8 @@
- - + +
@@ -105,6 +105,20 @@ selector: '#contentEditor', height: 500, license_key: 'gpl', + paste_data_images: true, + paste_webkit_styles: 'all', + paste_postprocess: function(editor, args) { + args.node.querySelectorAll('*').forEach(function(el) { + var tag = el.tagName.toLowerCase(); + var isTablePart = (tag === 'td' || tag === 'th' || tag === 'table' || tag === 'tr'); + if (el.style.color && !isTablePart) el.style.color = '#000'; + if (el.style.backgroundColor && !isTablePart) el.style.backgroundColor = ''; + }); + }, + valid_styles: { + '*': 'color,background-color,background,font-size,font-family,text-align,text-decoration,font-weight,font-style,border,border-color,border-width,border-style,border-collapse,padding,padding-left,padding-right,padding-top,padding-bottom,margin,margin-left,margin-right,margin-top,margin-bottom,width,height,max-width,max-height,min-width,min-height,vertical-align,white-space,display,float,line-height,letter-spacing,text-indent,text-transform,list-style-type,opacity' + }, + extended_valid_elements: 'table[*],tr[*],td[*],th[*],colgroup[*],col[*],thead[*],tbody[*],tfoot[*],div[*],span[*],p[*],img[*],a[*],h1[*],h2[*],h3[*],h4[*],h5[*],h6[*]', menubar: 'file edit view insert format table', plugins: 'advlist autolink lists link image charmap preview anchor searchreplace visualblocks code fullscreen insertdatetime media table help wordcount', toolbar: 'undo redo | blocks fontsize | bold italic forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | image media table | removeformat code fullscreen', @@ -120,62 +134,42 @@ fetch('/api/listuploads').then(r => r.json()).then(function (files) { var input = document.createElement('input'); input.type = 'file'; input.accept = 'image/*'; - - // If we have existing uploads, show a picker dialog if (files && files.length > 0) { var dialog = document.createElement('div'); dialog.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);z-index:99999;display:flex;align-items:center;justify-content:center;'; var panel = document.createElement('div'); panel.style.cssText = 'background:#fff;border-radius:12px;padding:1.5em;max-width:700px;max-height:80vh;overflow-y:auto;width:90%;'; panel.innerHTML = '

Select Image or Upload New

'; - var grid = document.createElement('div'); grid.style.cssText = 'display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:10px;margin-bottom:1em;'; - files.forEach(function (f) { var thumb = document.createElement('div'); thumb.style.cssText = 'cursor:pointer;border:2px solid #ddd;border-radius:8px;overflow:hidden;aspect-ratio:1;background:#f0f0f0;'; thumb.innerHTML = ''; thumb.title = f.title; - thumb.addEventListener('click', function () { - cb(f.value, { title: f.title }); - document.body.removeChild(dialog); - }); + thumb.addEventListener('click', function () { cb(f.value, { title: f.title }); document.body.removeChild(dialog); }); thumb.addEventListener('mouseenter', function () { this.style.borderColor = '#3b6fd4'; }); thumb.addEventListener('mouseleave', function () { this.style.borderColor = '#ddd'; }); grid.appendChild(thumb); }); - panel.appendChild(grid); - var uploadBtn = document.createElement('button'); uploadBtn.textContent = 'Upload New Image'; uploadBtn.style.cssText = 'background:#3b6fd4;color:#fff;border:none;padding:0.6em 1.5em;border-radius:6px;cursor:pointer;margin-right:0.5em;'; - uploadBtn.addEventListener('click', function () { - document.body.removeChild(dialog); - input.click(); - }); - + uploadBtn.addEventListener('click', function () { document.body.removeChild(dialog); input.click(); }); var cancelBtn = document.createElement('button'); cancelBtn.textContent = 'Cancel'; cancelBtn.style.cssText = 'background:#eee;color:#333;border:none;padding:0.6em 1.5em;border-radius:6px;cursor:pointer;'; cancelBtn.addEventListener('click', function () { document.body.removeChild(dialog); }); - - panel.appendChild(uploadBtn); - panel.appendChild(cancelBtn); + panel.appendChild(uploadBtn); panel.appendChild(cancelBtn); dialog.appendChild(panel); dialog.addEventListener('click', function (e) { if (e.target === dialog) document.body.removeChild(dialog); }); document.body.appendChild(dialog); - } else { - input.click(); - } - + } else { input.click(); } input.addEventListener('change', function () { if (!this.files[0]) return; var fd = new FormData(); fd.append('file', this.files[0]); - fetch('/api/upload', { method: 'POST', body: fd }) - .then(r => r.json()) - .then(d => cb(d.location, { title: this.files[0].name })); + fetch('/api/upload', { method: 'POST', body: fd }).then(r => r.json()).then(d => cb(d.location, { title: this.files[0].name })); }); }).catch(function () { input.click(); }); },