diff --git a/app/assets/javascripts/01-types.js b/app/assets/javascripts/01-types.js index ba053dec..8a23a46f 100644 --- a/app/assets/javascripts/01-types.js +++ b/app/assets/javascripts/01-types.js @@ -146,32 +146,49 @@ const typesWithProperties = { img: { checkFn: blocks.img.checkFn, updateInput (el, editorEl) { - const imgSrcEl = editorEl.querySelector("*[data-prop=\"img-src\"]") - imgSrcEl.disabled = false - imgSrcEl.value = el.src + const imgFileEl = editorEl.querySelector(`*[data-prop="img-file"]`) + imgFileEl.disabled = false + // XXX: No se puede cambiar el texto, ¡esto puede ser confuso! - const imgAltEl = editorEl.querySelector("*[data-prop=\"img-alt\"]") + const imgAltEl = editorEl.querySelector(`*[data-prop="img-alt"]`) imgAltEl.disabled = false imgAltEl.value = el.alt }, disableInput (editorEl) { - const imgSrcEl = editorEl.querySelector("*[data-prop=\"img-src\"]") - imgSrcEl.disabled = true - imgSrcEl.value = "" + const imgFileEl = editorEl.querySelector(`*[data-prop="img-file"]`) + imgFileEl.disabled = true - const imgAltEl = editorEl.querySelector("*[data-prop=\"img-alt\"]") + const imgAltEl = editorEl.querySelector(`*[data-prop="img-alt"]`) imgAltEl.disabled = true imgAltEl.value = "" }, setupInput (editorEl, contentEl) { - const imgSrcEl = editorEl.querySelector("*[data-prop=\"img-src\"]") - imgSrcEl.addEventListener("input", event => { + const imgFileEl = editorEl.querySelector(`*[data-prop="img-file"]`) + imgFileEl.addEventListener("input", event => { // const imgEl = findRecursiveChild(blocks.img.checkFn, contentEl) const imgEl = getSelected(contentEl) - if (imgEl) imgEl.src = imgSrcEl.value + if (!imgEl) return + + const file = imgFileEl.files[0] + + imgEl.src = URL.createObjectURL(file) + imgEl.dataset.editorLoading = true + uploadFile(file) + .then(url => { + imgEl.src = url + delete imgEl.dataset.editorError + }) + .catch(err => { + // TODO: mostrar error + console.error(err) + imgEl.dataset.editorError = true + }) + .finally(() => { + delete imgEl.dataset.editorLoading + }) }, false) - const imgAltEl = editorEl.querySelector("*[data-prop=\"img-alt\"]") + const imgAltEl = editorEl.querySelector(`*[data-prop="img-alt"]`) imgAltEl.addEventListener("input", event => { // const imgEl = findRecursiveChild(blocks.img.checkFn, contentEl) const imgEl = getSelected(contentEl) diff --git a/app/assets/stylesheets/editor.scss b/app/assets/stylesheets/editor.scss index 27d0b8ca..1692237c 100644 --- a/app/assets/stylesheets/editor.scss +++ b/app/assets/stylesheets/editor.scss @@ -30,4 +30,11 @@ div[data-align="center"] { text-align: center; } div[data-align="right"] { text-align: right; } } + + *[data-editor-loading] { + opacity: 0.5; + } + *[data-editor-error] { + filter: grayscale(100%); + } } diff --git a/app/views/application/markdown.haml b/app/views/application/markdown.haml index 3f499ea7..71a1336d 100644 --- a/app/views/application/markdown.haml +++ b/app/views/application/markdown.haml @@ -17,17 +17,21 @@ %button{:data => {:button => "center"}} Center %button{:data => {:button => "right"}} Right %br/ + // TODO: generar IDs para labels + %label{:for => "mark-color"} Color de resaltado: %input{:type => "color", :data => {:prop => "mark-color"}}/ %br/ - %label{:for => "img-src"} URL de imágen: - %input{:placeholder => "https://radio.sutty.nl/public/placeholder_992x992.png", :type => "url", :data => {:prop => "img-src"}}/ + + %label{:for => "img-file"} Archivo de la imágen: + %input{:type => "file", :data => {:prop => "img-file"}}/ %label{:for => "img-alt"} Descripción de imágen: %input{:placeholder => "Un álbum", :type => "text", :data => {:prop => "img-alt"}}/ %button{:data => {:button => "img"}} Insertar imágen %br/ %label{:for => "link-href"} URL de link: %input{:type => "url", :data => {:prop => "link-href"}}/ + .editor-content{:contenteditable => "true"} %h1 Hola diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 05997ddc..ec2c50c1 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -14,7 +14,7 @@ Rails.application.config.content_security_policy do |policy| policy.script_src :self policy.font_src :self # XXX: Los íconos de Trix se cargan vía data: - policy.img_src :self, :data, :https + policy.img_src :self, :data, :https, :blob # Ya no usamos applets! policy.object_src :none if Rails.env.development?