Add custom classes select control to blocks menu
gitea/godo.js/pipeline/head There was a failure building this commit
Details
gitea/godo.js/pipeline/head There was a failure building this commit
Details
This commit is contained in:
parent
b8f8eb2a08
commit
7874ebb0bc
|
@ -22,6 +22,20 @@
|
|||
max-width: 60em;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.red {
|
||||
padding: 1rem;
|
||||
border: 1px solid red;
|
||||
border-radius: 10px;
|
||||
background: #FFCCCB;
|
||||
}
|
||||
|
||||
.green {
|
||||
padding: 1rem;
|
||||
border: 1px solid green;
|
||||
border-radius: 10px;
|
||||
background: #90EE90;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
@ -60,10 +74,14 @@
|
|||
<h2>Full Godo</h2>
|
||||
<p>p, h1 -> h3, strong, em, ul</p>
|
||||
<form action="">
|
||||
<textarea class="textarea-for-godo-2" data-godo-schema="full">
|
||||
<textarea
|
||||
class="textarea-for-godo-2"
|
||||
data-godo-schema="full"
|
||||
data-godo-custom-classes='{"red": { "allowOn": "paragraph", "label": "Erreur"}, "green": { "allowOn": "paragraph", "label": "Info" } }'
|
||||
>
|
||||
<h1>titre</h1>
|
||||
<h2>Sous-titre</h2>
|
||||
<p>Paragraphe.</p>
|
||||
<p>Paragraphe. <a href="http://sacripant.fr" class="pk-button">My website</a></p>
|
||||
<ul>
|
||||
<li>First Item</li>
|
||||
<li>Second Item</li>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,8 +18,10 @@ export default {
|
|||
},
|
||||
],
|
||||
plugins: [nodeResolve(), buble({
|
||||
objectAssign: 'Object.assign',
|
||||
transforms: {
|
||||
forOf: false,
|
||||
generator: false,
|
||||
},
|
||||
})],
|
||||
}
|
||||
|
|
|
@ -1,15 +1,93 @@
|
|||
import {DOMSerializer} from 'prosemirror-model'
|
||||
|
||||
export default (options) => ({
|
||||
patchSchema (schemaSpec) {
|
||||
addCustomClassesSupport(options, schemaSpec.nodes)
|
||||
addCustomClassesSupport(options, schemaSpec.marks)
|
||||
},
|
||||
})
|
||||
export default (options) => {
|
||||
const customClasses = JSON.parse(options.customClasses || '{}')
|
||||
|
||||
function addCustomClassesSupport (options, specs) {
|
||||
const customClasses = options.customClasses || {}
|
||||
return {
|
||||
patchSchema (schemaSpec) {
|
||||
addCustomClassesSupport(customClasses, schemaSpec.nodes)
|
||||
addCustomClassesSupport(customClasses, schemaSpec.marks)
|
||||
},
|
||||
blocksMenu () {
|
||||
return {
|
||||
selectClass: customClassMenu(customClasses),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function customClassMenu (customClasses) {
|
||||
function filterAllowedClasses (classes, nodeOrMark) {
|
||||
const result = []
|
||||
for (const className of classes) {
|
||||
const classSettings = customClasses[className]
|
||||
const allowOn = classSettings['allowOn'] || []
|
||||
if (allowOn.includes(nodeOrMark.type.name)) {
|
||||
result.push(className)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
return function (view) {
|
||||
let classSelect = document.createElement('select')
|
||||
|
||||
classSelect.addEventListener('change', e => {
|
||||
e.preventDefault()
|
||||
const cursor = view.state.selection.$cursor
|
||||
const currentNode = cursor.parent
|
||||
|
||||
let selectedClasses = []
|
||||
|
||||
// First option is default style
|
||||
if (classSelect.selectedIndex !== 0) {
|
||||
selectedClasses = Array.from(classSelect.selectedOptions)
|
||||
.map(option => option.value)
|
||||
.filter(className => className !== undefined)
|
||||
}
|
||||
|
||||
const newClasses = filterAllowedClasses(selectedClasses, currentNode)
|
||||
const newAttrs = {...currentNode.attrs, classes: newClasses}
|
||||
view.dispatch(
|
||||
view.state.tr.setNodeMarkup(cursor.pos - cursor.parentOffset - 1, null, newAttrs, currentNode.marks),
|
||||
)
|
||||
})
|
||||
|
||||
return {
|
||||
dom: classSelect,
|
||||
update () {
|
||||
classSelect.innerHTML = ''
|
||||
classSelect.style.display = 'none'
|
||||
|
||||
const cursor = view.state.selection.$cursor
|
||||
if (!cursor) {
|
||||
return
|
||||
}
|
||||
|
||||
const currentNode = cursor.parent
|
||||
const currentNodeClasses = currentNode.attrs.classes || []
|
||||
|
||||
const defaultOption = document.createElement('option')
|
||||
defaultOption.value = 0
|
||||
defaultOption.text = 'Defaut'
|
||||
defaultOption.selected = currentNodeClasses.length === 0
|
||||
classSelect.add(defaultOption)
|
||||
|
||||
for (const className of filterAllowedClasses(Object.keys(customClasses), currentNode)) {
|
||||
const classSettings = customClasses[className]
|
||||
classSelect.style.display = null
|
||||
const option = document.createElement('option')
|
||||
option.value = className
|
||||
option.text = classSettings['label'] || className
|
||||
option.selected = currentNodeClasses.includes(className)
|
||||
classSelect.add(option)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addCustomClassesSupport (customClasses, specs) {
|
||||
for (const specName in specs) {
|
||||
const allowedClasses = Object.keys(customClasses).filter(className => {
|
||||
const classSettings = customClasses[className]
|
||||
|
|
|
@ -13,6 +13,7 @@ import fontMarks from './components/font-marks.mjs'
|
|||
import heading from './components/heading.mjs'
|
||||
import link from './components/link.mjs'
|
||||
import list from './components/list.mjs'
|
||||
import customClasses from './components/custom-classes.mjs'
|
||||
|
||||
function menuPlugin (menu) {
|
||||
return new Plugin({
|
||||
|
@ -55,7 +56,7 @@ export default class Godo {
|
|||
|
||||
this.options = Object.assign(this.defaultOptions, options)
|
||||
|
||||
const componentsDefinitions = [base, fontMarks, link]
|
||||
const componentsDefinitions = [base, fontMarks, link, customClasses]
|
||||
if (this.options.schema === 'full') {
|
||||
componentsDefinitions.push(heading, list)
|
||||
}
|
||||
|
@ -129,6 +130,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||
if (textarea.dataset.godoHeadingLevels) {
|
||||
options.headingLevels = textarea.dataset.godoHeadingLevels
|
||||
}
|
||||
options.customClasses = textarea.dataset.godoCustomClasses
|
||||
new Godo(textarea, options) // eslint-disable-line no-new
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue