diff --git a/src/bundle/Resources/public/js/CKEditor/anchor/anchor-editing.js b/src/bundle/Resources/public/js/CKEditor/anchor/anchor-editing.js index ab928de6..0806b736 100644 --- a/src/bundle/Resources/public/js/CKEditor/anchor/anchor-editing.js +++ b/src/bundle/Resources/public/js/CKEditor/anchor/anchor-editing.js @@ -17,6 +17,67 @@ class IbexaAnchorEditing extends Plugin { key: 'id', }, }); + + this.editor.conversion.for('dataDowncast').add((dispatcher) => { + dispatcher.on('attribute:anchor:listItem', (event, data, conversionApi) => { + if (data.attributeKey !== 'anchor') { + return; + } + + const viewItem = conversionApi.mapper.toViewElement(data.item); + const previousElement = viewItem.parent.previousSibling; + + if (data.attributeNewValue) { + conversionApi.writer.setAttribute('id', data.attributeNewValue, viewItem.parent); + } else { + conversionApi.writer.removeAttribute('id', viewItem.parent); + } + + conversionApi.writer.removeAttribute('id', viewItem); + + if (previousElement?.name === viewItem.parent.name) { + conversionApi.writer.mergeContainers(conversionApi.writer.createPositionAfter(previousElement)); + } + }); + }); + + this.editor.conversion.for('editingDowncast').add((dispatcher) => { + dispatcher.on('attribute:anchor:listItem', (event, data, conversionApi) => { + if (data.attributeKey !== 'anchor') { + return; + } + + const viewItem = conversionApi.mapper.toViewElement(data.item); + const previousElement = viewItem.parent.previousSibling; + const nextElement = viewItem.parent.nextSibling; + + if (data.attributeNewValue) { + conversionApi.writer.setAttribute('id', data.attributeNewValue, viewItem.parent); + } else { + conversionApi.writer.removeAttribute('id', viewItem.parent); + } + + conversionApi.writer.removeAttribute('id', viewItem); + + if (previousElement?.name === viewItem.parent.name) { + conversionApi.writer.mergeContainers(conversionApi.writer.createPositionAfter(previousElement)); + } + + if (nextElement?.name === viewItem.parent.name) { + conversionApi.writer.mergeContainers(conversionApi.writer.createPositionBefore(nextElement)); + } + }); + }); + + this.editor.conversion.for('upcast').add((dispatcher) => { + dispatcher.on('element:li', (event, data, conversionApi) => { + const listParent = data.viewItem.parent; + const listItem = data.modelRange.start.nodeAfter ?? data.modelRange.end.nodeBefore; + const id = listParent.getAttribute('id'); + + conversionApi.writer.setAttribute('anchor', id, listItem); + }); + }); } init() { diff --git a/src/bundle/Resources/public/js/CKEditor/anchor/anchor-ui.js b/src/bundle/Resources/public/js/CKEditor/anchor/anchor-ui.js index 341a770b..e09c90bd 100644 --- a/src/bundle/Resources/public/js/CKEditor/anchor/anchor-ui.js +++ b/src/bundle/Resources/public/js/CKEditor/anchor/anchor-ui.js @@ -21,6 +21,22 @@ class IbexaAnchorUI extends Plugin { return this.editor.model.document.selection.getSelectedElement() || this.editor.model.document.selection.anchor.parent; } + removeAnchorFromSiblings(modelElement, writer) { + let { previousSibling, nextSibling } = modelElement; + + while (previousSibling?.name === 'listItem') { + writer.removeAttribute('anchor', previousSibling); + + previousSibling = previousSibling.previousSibling; + } + + while (nextSibling?.name === 'listItem') { + writer.removeAttribute('anchor', nextSibling); + + nextSibling = nextSibling.nextSibling; + } + } + createFormView() { const formView = new IbexaAnchorFormView({ locale: this.editor.locale }); @@ -56,9 +72,14 @@ class IbexaAnchorUI extends Plugin { this.listenTo(formView, 'remove-anchor', () => { const modelElement = this.getModelElement(); + const isListItem = modelElement.name === 'listItem'; this.editor.model.change((writer) => { writer.removeAttribute('anchor', modelElement); + + if (isListItem) { + this.removeAnchorFromSiblings(modelElement, writer); + } }); this.hideForm(); diff --git a/src/bundle/Resources/public/scss/_general.scss b/src/bundle/Resources/public/scss/_general.scss index ff1980f4..f3b78f3f 100644 --- a/src/bundle/Resources/public/scss/_general.scss +++ b/src/bundle/Resources/public/scss/_general.scss @@ -3,7 +3,7 @@ border: calculateRem(1px) solid $ibexa-color-dark-200; border-radius: $ibexa-border-radius; - .ck-content { + .ck.ck-content { min-height: calculateRem(100px); padding: 0 calculateRem(24px); }