mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-23 00:16:23 +00:00
toolbar auxiliar
This commit is contained in:
parent
5f8c368541
commit
ef66f6ad5a
4 changed files with 100 additions and 43 deletions
|
@ -1,3 +1,15 @@
|
||||||
|
function setAuxiliaryToolbar (editorEl, toolbarName) {
|
||||||
|
const toolbarEl = editorEl.querySelector(`*[data-editor-auxiliary-toolbar]`)
|
||||||
|
for (const otherEl of toolbarEl.childNodes) {
|
||||||
|
if (otherEl.nodeType !== Node.ELEMENT_NODE) continue
|
||||||
|
otherEl.classList.remove("editor-auxiliary-tool-active")
|
||||||
|
}
|
||||||
|
if (toolbarName) {
|
||||||
|
const auxEl = editorEl.querySelector(`*[data-editor-auxiliary="${toolbarName}"]`)
|
||||||
|
auxEl.classList.add("editor-auxiliary-tool-active")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const marks = {
|
const marks = {
|
||||||
bold: {
|
bold: {
|
||||||
selector: "strong",
|
selector: "strong",
|
||||||
|
@ -146,6 +158,8 @@ const typesWithProperties = {
|
||||||
mark: {
|
mark: {
|
||||||
selector: marks.mark.selector,
|
selector: marks.mark.selector,
|
||||||
updateInput (el, editorEl) {
|
updateInput (el, editorEl) {
|
||||||
|
setAuxiliaryToolbar(editorEl, "mark")
|
||||||
|
|
||||||
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"
|
||||||
|
@ -166,6 +180,8 @@ const typesWithProperties = {
|
||||||
img: {
|
img: {
|
||||||
selector: blocks.img.selector,
|
selector: blocks.img.selector,
|
||||||
updateInput (el, editorEl) {
|
updateInput (el, editorEl) {
|
||||||
|
setAuxiliaryToolbar(editorEl, "img")
|
||||||
|
|
||||||
const imgFileEl = editorEl.querySelector(`*[data-prop="img-file"]`)
|
const imgFileEl = editorEl.querySelector(`*[data-prop="img-file"]`)
|
||||||
imgFileEl.disabled = false
|
imgFileEl.disabled = false
|
||||||
// XXX: No se puede cambiar el texto, ¡esto puede ser confuso!
|
// XXX: No se puede cambiar el texto, ¡esto puede ser confuso!
|
||||||
|
@ -217,6 +233,8 @@ const typesWithProperties = {
|
||||||
audio: {
|
audio: {
|
||||||
selector: blocks.audio.selector,
|
selector: blocks.audio.selector,
|
||||||
updateInput (el, editorEl) {
|
updateInput (el, editorEl) {
|
||||||
|
setAuxiliaryToolbar(editorEl, "audio")
|
||||||
|
|
||||||
const audioFileEl = editorEl.querySelector(`*[data-prop="audio-file"]`)
|
const audioFileEl = editorEl.querySelector(`*[data-prop="audio-file"]`)
|
||||||
audioFileEl.disabled = false
|
audioFileEl.disabled = false
|
||||||
// XXX: No se puede cambiar el texto, ¡esto puede ser confuso!
|
// XXX: No se puede cambiar el texto, ¡esto puede ser confuso!
|
||||||
|
@ -254,6 +272,8 @@ const typesWithProperties = {
|
||||||
video: {
|
video: {
|
||||||
selector: blocks.video.selector,
|
selector: blocks.video.selector,
|
||||||
updateInput (el, editorEl) {
|
updateInput (el, editorEl) {
|
||||||
|
setAuxiliaryToolbar(editorEl, "video")
|
||||||
|
|
||||||
const videoFileEl = editorEl.querySelector(`*[data-prop="video-file"]`)
|
const videoFileEl = editorEl.querySelector(`*[data-prop="video-file"]`)
|
||||||
videoFileEl.disabled = false
|
videoFileEl.disabled = false
|
||||||
// XXX: No se puede cambiar el texto, ¡esto puede ser confuso!
|
// XXX: No se puede cambiar el texto, ¡esto puede ser confuso!
|
||||||
|
@ -291,6 +311,8 @@ const typesWithProperties = {
|
||||||
pdf: {
|
pdf: {
|
||||||
selector: blocks.pdf.selector,
|
selector: blocks.pdf.selector,
|
||||||
updateInput (el, editorEl) {
|
updateInput (el, editorEl) {
|
||||||
|
setAuxiliaryToolbar(editorEl, "pdf")
|
||||||
|
|
||||||
const pdfFileEl = editorEl.querySelector(`*[data-prop="pdf-file"]`)
|
const pdfFileEl = editorEl.querySelector(`*[data-prop="pdf-file"]`)
|
||||||
pdfFileEl.disabled = false
|
pdfFileEl.disabled = false
|
||||||
// XXX: No se puede cambiar el texto, ¡esto puede ser confuso!
|
// XXX: No se puede cambiar el texto, ¡esto puede ser confuso!
|
||||||
|
|
|
@ -346,6 +346,11 @@ function setupEditor (editorEl) {
|
||||||
const sel = window.getSelection()
|
const sel = window.getSelection()
|
||||||
const range = sel.getRangeAt(0)
|
const range = sel.getRangeAt(0)
|
||||||
|
|
||||||
|
let parentEl = range.commonAncestorContainer
|
||||||
|
if (parentEl.nodeType !== Node.ELEMENT_NODE) parentEl = parentEl.parentElement
|
||||||
|
|
||||||
|
if (!contentEl.contains(parentEl)) return
|
||||||
|
|
||||||
// Borrar todas las selecciones
|
// Borrar todas las selecciones
|
||||||
for (const el of contentEl.querySelectorAll(".selected")) {
|
for (const el of contentEl.querySelectorAll(".selected")) {
|
||||||
el.classList.remove("selected")
|
el.classList.remove("selected")
|
||||||
|
@ -354,8 +359,7 @@ function setupEditor (editorEl) {
|
||||||
el.classList.remove("selected-unactive")
|
el.classList.remove("selected-unactive")
|
||||||
}
|
}
|
||||||
|
|
||||||
let parentEl = range.commonAncestorContainer
|
setAuxiliaryToolbar(editorEl)
|
||||||
if (parentEl.nodeType !== Node.ELEMENT_TYPE) parentEl = parentEl.parentElement
|
|
||||||
|
|
||||||
for (const [name, type] of Object.entries(typesWithProperties)) {
|
for (const [name, type] of Object.entries(typesWithProperties)) {
|
||||||
let i = 0
|
let i = 0
|
||||||
|
@ -420,6 +424,12 @@ function setupEditor (editorEl) {
|
||||||
type.setupInput(editorEl, contentEl)
|
type.setupInput(editorEl, contentEl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.addEventListener(editorBtn("mark"), () => setAuxiliaryToolbar(editorEl, "mark"))
|
||||||
|
document.addEventListener(editorBtn("img"), () => setAuxiliaryToolbar(editorEl, "img"))
|
||||||
|
document.addEventListener(editorBtn("audio"), () => setAuxiliaryToolbar(editorEl, "audio"))
|
||||||
|
document.addEventListener(editorBtn("video"), () => setAuxiliaryToolbar(editorEl, "video"))
|
||||||
|
document.addEventListener(editorBtn("pdf"), () => setAuxiliaryToolbar(editorEl, "pdf"))
|
||||||
|
|
||||||
cleanContent(contentEl)
|
cleanContent(contentEl)
|
||||||
htmlEl.value = contentEl.innerHTML
|
htmlEl.value = contentEl.innerHTML
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,27 @@
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.editor-toolbar {
|
||||||
|
position: sticky;
|
||||||
|
top: 0px;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-primary-toolbar, .editor-auxiliary-toolbar {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-auxiliary-toolbar {
|
||||||
|
& > * {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.editor-auxiliary-tool-active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ol, ul { margin: 0; }
|
ol, ul { margin: 0; }
|
||||||
|
|
||||||
.editor-content {
|
.editor-content {
|
||||||
|
|
|
@ -1,50 +1,54 @@
|
||||||
= form_with do
|
= form_with do
|
||||||
.editor
|
.editor
|
||||||
%button{:data => {:button => "bold"}} Bold
|
.editor-toolbar
|
||||||
%button{:data => {:button => "italic"}} Italic
|
.editor-primary-toolbar
|
||||||
%button{:data => {:button => "deleted"}} Deleted
|
%button.btn{:data => {:button => "bold"}} Bold
|
||||||
%button{:data => {:button => "underline"}} Underline
|
%button.btn{:data => {:button => "italic"}} Italic
|
||||||
%button{:data => {:button => "mark"}} Mark
|
%button.btn{:data => {:button => "deleted"}} Deleted
|
||||||
%button{:data => {:button => "h1"}} H1
|
%button.btn{:data => {:button => "underline"}} Underline
|
||||||
%button{:data => {:button => "h2"}} H2
|
%button.btn{:data => {:button => "mark"}} Subrayar
|
||||||
%button{:data => {:button => "h3"}} H3
|
%button.btn{:data => {:button => "h1"}} H1
|
||||||
%button{:data => {:button => "h4"}} H4
|
%button.btn{:data => {:button => "h2"}} H2
|
||||||
%button{:data => {:button => "h5"}} H5
|
%button.btn{:data => {:button => "h3"}} H3
|
||||||
%button{:data => {:button => "h6"}} H6
|
%button.btn{:data => {:button => "h4"}} H4
|
||||||
%button{:data => {:button => "ul"}} Lista desordenada
|
%button.btn{:data => {:button => "h5"}} H5
|
||||||
%button{:data => {:button => "ol"}} Lista ordenada
|
%button.btn{:data => {:button => "h6"}} H6
|
||||||
%button{:data => {:button => "left"}} Left
|
%button.btn{:data => {:button => "ul"}} Lista desordenada
|
||||||
%button{:data => {:button => "center"}} Center
|
%button.btn{:data => {:button => "ol"}} Lista ordenada
|
||||||
%button{:data => {:button => "right"}} Right
|
%button.btn{:data => {:button => "left"}} Left
|
||||||
%br/
|
%button.btn{:data => {:button => "center"}} Center
|
||||||
|
%button.btn{:data => {:button => "right"}} Right
|
||||||
|
%button.btn{:data => {:button => "img"}} Imágen
|
||||||
|
%button.btn{:data => {:button => "video"}} Video
|
||||||
|
%button.btn{:data => {:button => "audio"}} Audio
|
||||||
|
%button.btn{:data => {:button => "pdf"}} PDF
|
||||||
// TODO: generar IDs para labels
|
// TODO: generar IDs para labels
|
||||||
|
|
||||||
|
// HAML cringe
|
||||||
|
.editor-auxiliary-toolbar{:data => {:editor => {:auxiliary => {:toolbar => ""}}}}
|
||||||
|
%div{:data => {:editor => {:auxiliary => "mark"}}}
|
||||||
%label{:for => "mark-color"} Color de resaltado:
|
%label{:for => "mark-color"} Color de resaltado:
|
||||||
%input{:type => "color", :data => {:prop => "mark-color"}}/
|
%input{:type => "color", :data => {:prop => "mark-color"}}/
|
||||||
%br/
|
|
||||||
|
|
||||||
|
%div{:data => {:editor => {:auxiliary => "img"}}}
|
||||||
%label{:for => "img-file"} Archivo de la imágen:
|
%label{:for => "img-file"} Archivo de la imágen:
|
||||||
%input{:type => "file", :data => {:prop => "img-file"}}/
|
%input{:type => "file", :data => {:prop => "img-file"}}/
|
||||||
%label{:for => "img-alt"} Descripción de imágen:
|
%label{:for => "img-alt"} Descripción de imágen:
|
||||||
%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
|
|
||||||
%br/
|
|
||||||
|
|
||||||
|
%div{:data => {:editor => {:auxiliary => "audio"}}}
|
||||||
%label{:for => "audio-file"} Archivo de la audio:
|
%label{:for => "audio-file"} Archivo de la audio:
|
||||||
%input{:type => "file", :data => {:prop => "audio-file"}}/
|
%input{:type => "file", :data => {:prop => "audio-file"}}/
|
||||||
%button{:data => {:button => "audio"}} Insertar audio
|
|
||||||
%br/
|
|
||||||
|
|
||||||
|
%div{:data => {:editor => {:auxiliary => "video"}}}
|
||||||
%label{:for => "video-file"} Archivo de la video:
|
%label{:for => "video-file"} Archivo de la video:
|
||||||
%input{:type => "file", :data => {:prop => "video-file"}}/
|
%input{:type => "file", :data => {:prop => "video-file"}}/
|
||||||
%button{:data => {:button => "video"}} Insertar video
|
|
||||||
%br/
|
|
||||||
|
|
||||||
|
%div{:data => {:editor => {:auxiliary => "pdf"}}}
|
||||||
%label{:for => "pdf-file"} Archivo de la PDF:
|
%label{:for => "pdf-file"} Archivo de la PDF:
|
||||||
%input{:type => "file", :data => {:prop => "pdf-file"}}/
|
%input{:type => "file", :data => {:prop => "pdf-file"}}/
|
||||||
%button{:data => {:button => "pdf"}} Insertar PDF
|
|
||||||
%br/
|
|
||||||
|
|
||||||
|
%div{:data => {:editor => {:auxiliary => "link"}}}
|
||||||
%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"}}/
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue