subida de PDFs, videos y audios y limpieza

This commit is contained in:
void 2020-11-05 19:19:37 -03:00
parent fdb8584dcb
commit 0382be3351
4 changed files with 164 additions and 10 deletions

View file

@ -72,10 +72,34 @@ const blocks = {
img: { img: {
checkFn: el => el.tagName == "IMG", checkFn: el => el.tagName == "IMG",
createFn: editorEl => { createFn: editorEl => {
const imgEl = document.createElement("IMG") const el = document.createElement("IMG")
imgEl.src = "https://radio.sutty.nl/public/placeholder_992x992.png" el.src = "https://radio.sutty.nl/public/placeholder_992x992.png"
imgEl.alt = "Un hermoso álbum" el.alt = "Un hermoso álbum"
return imgEl return el
},
},
audio: {
checkFn: el => el.tagName == "AUDIO",
createFn: editorEl => {
const el = document.createElement("AUDIO")
el.controls = true
return el
},
},
video: {
checkFn: el => el.tagName == "VIDEO",
createFn: editorEl => {
const el = document.createElement("VIDEO")
el.controls = true
return el
},
},
// PDF
pdf: {
checkFn: el => el.tagName == "IFRAME",
createFn: editorEl => {
const el = document.createElement("IFRAME")
return el
}, },
}, },
} }
@ -126,17 +150,17 @@ const typesWithProperties = {
mark: { mark: {
checkFn: marks.mark.checkFn, checkFn: marks.mark.checkFn,
updateInput (el, editorEl) { updateInput (el, editorEl) {
const markColorInputEl = editorEl.querySelector("*[data-prop=\"mark-color\"]") const markColorInputEl = editorEl.querySelector(`*[data-prop="mark-color"]`)
markColorInputEl.disabled = false markColorInputEl.disabled = false
markColorInputEl.value = el.style.backgroundColor ? rgb2hex(el.style.backgroundColor) : "#f206f9" markColorInputEl.value = el.style.backgroundColor ? rgb2hex(el.style.backgroundColor) : "#f206f9"
}, },
disableInput (editorEl) { disableInput (editorEl) {
const markColorInputEl = editorEl.querySelector("*[data-prop=\"mark-color\"]") const markColorInputEl = editorEl.querySelector(`*[data-prop="mark-color"]`)
markColorInputEl.disabled = true markColorInputEl.disabled = true
markColorInputEl.value = "#000000" markColorInputEl.value = "#000000"
}, },
setupInput (editorEl, contentEl) { setupInput (editorEl, contentEl) {
const markColorInputEl = editorEl.querySelector("*[data-prop=\"mark-color\"]") const markColorInputEl = editorEl.querySelector(`*[data-prop="mark-color"]`)
markColorInputEl.addEventListener("change", event => { markColorInputEl.addEventListener("change", event => {
const markEl = findRecursiveChild(marks.mark.checkFn, contentEl) const markEl = findRecursiveChild(marks.mark.checkFn, contentEl)
if (markEl) markEl.style.backgroundColor = markColorInputEl.value if (markEl) markEl.style.backgroundColor = markColorInputEl.value
@ -196,4 +220,115 @@ const typesWithProperties = {
}, false) }, false)
}, },
}, },
audio: {
checkFn: blocks.audio.checkFn,
updateInput (el, editorEl) {
const audioFileEl = editorEl.querySelector(`*[data-prop="audio-file"]`)
audioFileEl.disabled = false
// XXX: No se puede cambiar el texto, ¡esto puede ser confuso!
},
disableInput (editorEl) {
const audioFileEl = editorEl.querySelector(`*[data-prop="audio-file"]`)
audioFileEl.disabled = true
},
setupInput (editorEl, contentEl) {
const audioFileEl = editorEl.querySelector(`*[data-prop="audio-file"]`)
audioFileEl.addEventListener("input", event => {
const audioEl = getSelected(contentEl)
if (!audioEl) return
const file = audioFileEl.files[0]
audioEl.src = URL.createObjectURL(file)
audioEl.dataset.editorLoading = true
uploadFile(file)
.then(url => {
audioEl.src = url
delete audioEl.dataset.editorError
})
.catch(err => {
// TODO: mostrar error
console.error(err)
audioEl.dataset.editorError = true
})
.finally(() => {
delete audioEl.dataset.editorLoading
})
}, false)
},
},
video: {
checkFn: blocks.video.checkFn,
updateInput (el, editorEl) {
const videoFileEl = editorEl.querySelector(`*[data-prop="video-file"]`)
videoFileEl.disabled = false
// XXX: No se puede cambiar el texto, ¡esto puede ser confuso!
},
disableInput (editorEl) {
const videoFileEl = editorEl.querySelector(`*[data-prop="video-file"]`)
videoFileEl.disabled = true
},
setupInput (editorEl, contentEl) {
const videoFileEl = editorEl.querySelector(`*[data-prop="video-file"]`)
videoFileEl.addEventListener("input", event => {
const videoEl = getSelected(contentEl)
if (!videoEl) return
const file = videoFileEl.files[0]
videoEl.src = URL.createObjectURL(file)
videoEl.dataset.editorLoading = true
uploadFile(file)
.then(url => {
videoEl.src = url
delete videoEl.dataset.editorError
})
.catch(err => {
// TODO: mostrar error
console.error(err)
videoEl.dataset.editorError = true
})
.finally(() => {
delete videoEl.dataset.editorLoading
})
}, false)
},
},
pdf: {
checkFn: blocks.pdf.checkFn,
updateInput (el, editorEl) {
const pdfFileEl = editorEl.querySelector(`*[data-prop="pdf-file"]`)
pdfFileEl.disabled = false
// XXX: No se puede cambiar el texto, ¡esto puede ser confuso!
},
disableInput (editorEl) {
const pdfFileEl = editorEl.querySelector(`*[data-prop="pdf-file"]`)
pdfFileEl.disabled = true
},
setupInput (editorEl, contentEl) {
const pdfFileEl = editorEl.querySelector(`*[data-prop="pdf-file"]`)
pdfFileEl.addEventListener("input", event => {
const pdfEl = getSelected(contentEl)
if (!pdfEl) return
const file = pdfFileEl.files[0]
pdfEl.src = URL.createObjectURL(file)
pdfEl.dataset.editorLoading = true
uploadFile(file)
.then(url => {
pdfEl.src = url
delete pdfEl.dataset.editorError
})
.catch(err => {
// TODO: mostrar error
console.error(err)
pdfEl.dataset.editorError = true
})
.finally(() => {
delete pdfEl.dataset.editorLoading
})
}, false)
},
},
} }

View file

@ -208,8 +208,11 @@ function hasContent (element) {
if (child.nodeType === Node.TEXT_NODE && child.data.length > 0) return true if (child.nodeType === Node.TEXT_NODE && child.data.length > 0) return true
else if (child.hasChildNodes() && hasContent(child)) return true else if (child.hasChildNodes() && hasContent(child)) return true
} }
// TODO: verificar que la imágen tiene contenido // TODO: verificar que los elementos tiene contenido
if (element.tagName === "IMG") return true if (element.tagName === "IMG"
|| element.tagName === "AUDIO"
|| element.tagName === "VIDEO"
|| element.tagName === "IFRAME") return true
return false return false
} }

View file

@ -18,7 +18,7 @@
outline-offset: 1pt; outline-offset: 1pt;
} }
img { img, video, iframe {
width: 100%; width: 100%;
max-width: 600px; max-width: 600px;
display: block; display: block;

View file

@ -29,6 +29,22 @@
%input{:placeholder => "Un álbum", :type => "text", :data => {:prop => "img-alt"}}/ %input{:placeholder => "Un álbum", :type => "text", :data => {:prop => "img-alt"}}/
%button{:data => {:button => "img"}} Insertar imágen %button{:data => {:button => "img"}} Insertar imágen
%br/ %br/
%label{:for => "audio-file"} Archivo de la audio:
%input{:type => "file", :data => {:prop => "audio-file"}}/
%button{:data => {:button => "audio"}} Insertar audio
%br/
%label{:for => "video-file"} Archivo de la video:
%input{:type => "file", :data => {:prop => "video-file"}}/
%button{:data => {:button => "video"}} Insertar video
%br/
%label{:for => "pdf-file"} Archivo de la PDF:
%input{:type => "file", :data => {:prop => "pdf-file"}}/
%button{:data => {:button => "pdf"}} Insertar PDF
%br/
%label{:for => "link-href"} URL de link: %label{:for => "link-href"} URL de link:
%input{:type => "url", :data => {:prop => "link-href"}}/ %input{:type => "url", :data => {:prop => "link-href"}}/