2021-04-07 20:45:27 +00:00
|
|
|
import * as ActiveStorage from '@rails/activestorage'
|
2021-02-14 16:01:41 +00:00
|
|
|
import { Editor } from 'editor/editor'
|
2021-03-27 18:44:24 +00:00
|
|
|
import { EditorNode, getValidParentInSelection } from 'editor/types'
|
2021-02-14 16:01:41 +00:00
|
|
|
import {
|
|
|
|
safeGetSelection, safeGetRangeAt,
|
|
|
|
markNames, parentBlockNames,
|
2021-03-22 20:54:26 +00:00
|
|
|
setAuxiliaryToolbar, clearSelected,
|
2021-02-14 16:01:41 +00:00
|
|
|
} from 'editor/utils'
|
|
|
|
|
|
|
|
function uploadFile (file: File): Promise<string> {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
const upload = new ActiveStorage.DirectUpload(
|
|
|
|
file,
|
|
|
|
origin + '/rails/active_storage/direct_uploads',
|
|
|
|
)
|
|
|
|
|
|
|
|
upload.create((error: any, blob: any) => {
|
|
|
|
if (error) {
|
|
|
|
reject(error)
|
|
|
|
} else {
|
|
|
|
const url = `${origin}/rails/active_storage/blobs/${blob.signed_id}/${blob.filename}`
|
|
|
|
resolve(url)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
function getAlt (multimediaInnerEl: HTMLElement): string | null {
|
|
|
|
switch (multimediaInnerEl.tagName) {
|
|
|
|
case 'VIDEO':
|
|
|
|
case 'AUDIO':
|
|
|
|
return multimediaInnerEl.getAttribute('aria-label')
|
|
|
|
case 'IMG':
|
|
|
|
return (multimediaInnerEl as HTMLImageElement).alt
|
|
|
|
case 'IFRAME':
|
|
|
|
return multimediaInnerEl.title
|
|
|
|
default:
|
|
|
|
throw new Error('no pude conseguir el alt')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function setAlt (multimediaInnerEl: HTMLElement, value: string): void {
|
|
|
|
switch (multimediaInnerEl.tagName) {
|
|
|
|
case 'VIDEO':
|
|
|
|
case 'AUDIO':
|
|
|
|
multimediaInnerEl.setAttribute('aria-label', value)
|
|
|
|
break
|
|
|
|
case 'IMG':
|
|
|
|
(multimediaInnerEl as HTMLImageElement).alt = value
|
|
|
|
break
|
|
|
|
case 'IFRAME':
|
|
|
|
multimediaInnerEl.title = value
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
throw new Error('no pude setear el alt')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-22 20:54:26 +00:00
|
|
|
function select (editor: Editor, el: HTMLElement): void {
|
|
|
|
clearSelected(editor)
|
|
|
|
el.dataset.editorSelected = ''
|
|
|
|
|
|
|
|
const innerEl = el.querySelector<HTMLElement>('[data-multimedia-inner]')
|
|
|
|
if (!innerEl) throw new Error('No hay multimedia válida')
|
2021-04-10 22:20:13 +00:00
|
|
|
if (innerEl.tagName === "P") {
|
|
|
|
editor.toolbar.auxiliary.multimedia.altEl.value = "";
|
|
|
|
editor.toolbar.auxiliary.multimedia.altEl.disabled = true;
|
|
|
|
} else {
|
|
|
|
editor.toolbar.auxiliary.multimedia.altEl.value = getAlt(innerEl) || "";
|
|
|
|
editor.toolbar.auxiliary.multimedia.altEl.disabled = false;
|
|
|
|
}
|
2021-03-22 20:54:26 +00:00
|
|
|
|
|
|
|
setAuxiliaryToolbar(editor, editor.toolbar.auxiliary.multimedia.parentEl)
|
|
|
|
}
|
|
|
|
|
2021-02-14 16:01:41 +00:00
|
|
|
export const multimedia: EditorNode = {
|
|
|
|
selector: 'figure[data-multimedia]',
|
|
|
|
allowedChildren: 'ignore-children',
|
|
|
|
handleEmpty: 'remove',
|
|
|
|
create: () => {
|
|
|
|
const figureEl = document.createElement('figure')
|
|
|
|
figureEl.dataset.multimedia = ''
|
|
|
|
figureEl.contentEditable = 'false'
|
|
|
|
|
|
|
|
const placeholderEl = document.createElement('p')
|
|
|
|
placeholderEl.dataset.multimediaInner = ''
|
|
|
|
// TODO i18n
|
|
|
|
placeholderEl.append('¡Clickeame para subir un archivo!')
|
|
|
|
figureEl.appendChild(placeholderEl)
|
|
|
|
|
|
|
|
const descriptionEl = document.createElement('figcaption')
|
|
|
|
descriptionEl.contentEditable = 'true'
|
|
|
|
// TODO i18n
|
|
|
|
descriptionEl.append('Escribí acá la descripción del archivo.')
|
|
|
|
figureEl.appendChild(descriptionEl)
|
|
|
|
|
|
|
|
return figureEl
|
|
|
|
},
|
|
|
|
onClick (editor, el) {
|
|
|
|
if (!(el instanceof HTMLElement))
|
|
|
|
throw new Error('oh no')
|
2021-03-22 20:54:26 +00:00
|
|
|
select(editor, el)
|
2021-02-14 16:01:41 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
function createElementWithFile (url: string, type: string): HTMLElement {
|
|
|
|
if (type.match(/^image\/.+$/)) {
|
|
|
|
const el = document.createElement('img')
|
|
|
|
el.dataset.multimediaInner = ''
|
|
|
|
el.src = url
|
|
|
|
return el
|
|
|
|
} else if (type.match(/^video\/.+$/)) {
|
|
|
|
const el = document.createElement('video')
|
|
|
|
el.controls = true
|
|
|
|
el.dataset.multimediaInner = ''
|
|
|
|
el.src = url
|
|
|
|
return el
|
|
|
|
} else if (type.match(/^audio\/.+$/)) {
|
|
|
|
const el = document.createElement('audio')
|
|
|
|
el.controls = true
|
|
|
|
el.dataset.multimediaInner = ''
|
|
|
|
el.src = url
|
|
|
|
return el
|
|
|
|
} else if (type.match(/^application\/pdf$/)) {
|
|
|
|
const el = document.createElement('iframe')
|
|
|
|
el.dataset.multimediaInner = ''
|
|
|
|
el.src = url
|
|
|
|
return el
|
|
|
|
} else {
|
|
|
|
// TODO: chequear si el archivo es válido antes de subir
|
|
|
|
throw new Error('Tipo de archivo no reconocido')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function setupAuxiliaryToolbar (editor: Editor): void {
|
|
|
|
editor.toolbar.auxiliary.multimedia.uploadEl.addEventListener('click', event => {
|
|
|
|
const files = editor.toolbar.auxiliary.multimedia.fileEl.files
|
2021-02-18 21:42:53 +00:00
|
|
|
if (!files || !files.length) throw new Error('no hay archivos para subir')
|
2021-02-14 16:01:41 +00:00
|
|
|
const file = files[0]
|
|
|
|
|
|
|
|
const selectedEl = editor.contentEl
|
|
|
|
.querySelector<HTMLElement>('figure[data-editor-selected]')
|
|
|
|
if (!selectedEl)
|
|
|
|
throw new Error('No pude encontrar el elemento para setear el archivo')
|
|
|
|
|
|
|
|
selectedEl.dataset.editorLoading = ''
|
|
|
|
uploadFile(file)
|
|
|
|
.then(url => {
|
|
|
|
const innerEl = selectedEl.querySelector('[data-multimedia-inner]')
|
|
|
|
if (!innerEl) throw new Error('No hay multimedia a reemplazar')
|
|
|
|
|
|
|
|
const el = createElementWithFile(url, file.type)
|
|
|
|
setAlt(el, editor.toolbar.auxiliary.multimedia.altEl.value)
|
|
|
|
selectedEl.replaceChild(el, innerEl)
|
|
|
|
|
2021-04-10 22:20:13 +00:00
|
|
|
select(editor, selectedEl)
|
|
|
|
|
2021-02-14 16:01:41 +00:00
|
|
|
delete selectedEl.dataset.editorError
|
|
|
|
})
|
|
|
|
.catch(err => {
|
|
|
|
console.error(err)
|
|
|
|
// TODO: mostrar error
|
|
|
|
selectedEl.dataset.editorError = ''
|
|
|
|
})
|
|
|
|
.finally(() => { delete selectedEl.dataset.editorLoading })
|
|
|
|
})
|
|
|
|
|
|
|
|
editor.toolbar.auxiliary.multimedia.removeEl.addEventListener('click', event => {
|
|
|
|
const selectedEl = editor.contentEl
|
|
|
|
.querySelector<HTMLElement>('figure[data-editor-selected]')
|
|
|
|
if (!selectedEl)
|
|
|
|
throw new Error('No pude encontrar el elemento para borrar')
|
|
|
|
|
|
|
|
selectedEl.parentElement?.removeChild(selectedEl)
|
|
|
|
setAuxiliaryToolbar(editor, null)
|
|
|
|
})
|
|
|
|
|
|
|
|
editor.toolbar.auxiliary.multimedia.altEl.addEventListener('input', event => {
|
|
|
|
const selectedEl = editor.contentEl
|
|
|
|
.querySelector<HTMLAnchorElement>('figure[data-editor-selected]')
|
|
|
|
if (!selectedEl)
|
|
|
|
throw new Error('No pude encontrar el multimedia para setear el alt')
|
|
|
|
|
|
|
|
const innerEl = selectedEl.querySelector<HTMLElement>('[data-multimedia-inner]')
|
|
|
|
if (!innerEl) throw new Error('No hay multimedia a para setear el alt')
|
|
|
|
|
|
|
|
setAlt(innerEl, editor.toolbar.auxiliary.multimedia.altEl.value)
|
|
|
|
})
|
|
|
|
editor.toolbar.auxiliary.multimedia.altEl.addEventListener('keydown', event => {
|
|
|
|
if (event.keyCode == 13) event.preventDefault()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
export function setupButtons (editor: Editor): void {
|
|
|
|
const buttonEl = editor.toolbarEl.querySelector('[data-editor-button="multimedia"]')
|
|
|
|
if (!buttonEl) throw new Error('No encontre el botón de multimedia')
|
|
|
|
buttonEl.addEventListener('click', event => {
|
|
|
|
event.preventDefault()
|
|
|
|
|
2021-03-27 18:44:24 +00:00
|
|
|
const list = getValidParentInSelection({ editor, type: 'multimedia' })
|
2021-02-14 16:01:41 +00:00
|
|
|
|
|
|
|
const el = multimedia.create(editor)
|
2021-03-27 18:44:24 +00:00
|
|
|
list[0].insertBefore(el, list[1].nextElementSibling)
|
|
|
|
select(editor, el)
|
2021-02-14 16:01:41 +00:00
|
|
|
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
}
|