Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/4.6'
Browse files Browse the repository at this point in the history
  • Loading branch information
dew326 committed Mar 19, 2024
2 parents 6c49bc4 + 5c9ae83 commit 0b295e5
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,10 @@ const VIEWPORT_TOP_OFFSET_DISTRACTION_FREE_MODE = 0;
IbexaElementsPath,
IbexaEmbed,
IbexaCustomTags,
IbexaFormatted,
IbexaCustomStylesInline,
IbexaCustomAttributes,
IbexaLink,
IbexaFormatted,
IbexaAnchor,
IbexaMove,
IbexaRemoveElement,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import Command from '@ckeditor/ckeditor5-core/src/command';

import { getCustomAttributesConfig, getCustomClassesConfig } from './helpers/config-helper';
import {
getCustomAttributesConfig,
getCustomClassesConfig,
getCustomAttributesElementConfig,
getCustomClassesElementConfig,
findConfigName,
} from './helpers/config-helper';

class IbexaCustomAttributesCommand extends Command {
cleanAttributes(modelElement, attributes) {
Object.entries(attributes).forEach(([elementName, config]) => {
if (elementName === modelElement.name) {
const configName = findConfigName(modelElement.name);

if (elementName === configName) {
return;
}

this.editor.model.change((writer) => {
Object.keys(config).forEach((name) => {
if (attributes[modelElement.name]?.[name]) {
if (attributes[configName]?.[name]) {
return;
}

Expand All @@ -23,15 +31,16 @@ class IbexaCustomAttributesCommand extends Command {

cleanClasses(modelElement, classes) {
Object.keys(classes).forEach((elementName) => {
const configName = findConfigName(modelElement.name);
const selectedCustomClasses = modelElement.getAttribute('custom-classes') ?? '';
const elementCustomClassesConfig = classes[modelElement.name];
const elementCustomClassesConfig = classes[configName];
const hasOwnCustomClasses =
elementCustomClassesConfig &&
selectedCustomClasses
.split(' ')
.every((selectedCustomClass) => elementCustomClassesConfig.choices.includes(selectedCustomClass));

if (elementName === modelElement.name || hasOwnCustomClasses) {
if (elementName === configName || hasOwnCustomClasses) {
return;
}

Expand All @@ -41,6 +50,24 @@ class IbexaCustomAttributesCommand extends Command {
});
}

isTableColumnSelected(parentElementName) {
const selectedBlocks = [...this.editor.model.document.selection.getSelectedBlocks()];
const isTableRow = parentElementName === 'tableRow';
const areBlocksInSameRow = selectedBlocks.every((selectedBlock, index) => {
const nextBlock = selectedBlocks[index + 1];

if (!nextBlock) {
return true;
}

const commonAncestor = selectedBlock.getCommonAncestor(nextBlock);

return commonAncestor.name === 'tableRow';
});

return !areBlocksInSameRow && isTableRow;
}

refresh() {
const { selection } = this.editor.model.document;
const parentElement = selection.getSelectedElement() ?? selection.getFirstPosition().parent;
Expand All @@ -60,9 +87,9 @@ class IbexaCustomAttributesCommand extends Command {

const customAttributesConfig = getCustomAttributesConfig();
const customClassesConfig = getCustomClassesConfig();
const parentElementAttributesConfig = customAttributesConfig[parentElementName];
const parentElementClassesConfig = customClassesConfig[parentElementName];
const isEnabled = parentElementAttributesConfig || parentElementClassesConfig;
const parentElementAttributesConfig = getCustomAttributesElementConfig(parentElementName);
const parentElementClassesConfig = getCustomClassesElementConfig(parentElementName);
const isEnabled = !this.isTableColumnSelected(parentElementName) && (parentElementAttributesConfig || parentElementClassesConfig);

this.isEnabled = !!isEnabled;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import Widget from '@ckeditor/ckeditor5-widget/src/widget';
import IbexaCustomAttributesCommand from './custom-attributes-command';
import { getCustomAttributesConfig, getCustomClassesConfig } from './helpers/config-helper';

const configElementsMapping = {
li: 'listItem',
tr: 'tableRow',
td: 'tableCell',
};

class IbexaCustomAttributesEditing extends Plugin {
static get requires() {
return [Widget];
Expand Down Expand Up @@ -126,8 +132,10 @@ class IbexaCustomAttributesEditing extends Plugin {
}

extendSchema(schema, element, definition) {
if (schema.getDefinition(element)) {
schema.extend(element, definition);
const resolvedElement = configElementsMapping[element] ?? element;

if (schema.getDefinition(resolvedElement)) {
schema.extend(resolvedElement, definition);
} else {
console.warn(`Schema does not have '${element}' element`);
}
Expand Down Expand Up @@ -202,4 +210,4 @@ class IbexaCustomAttributesEditing extends Plugin {
}
}

export default IbexaCustomAttributesEditing;
export { IbexaCustomAttributesEditing as default, configElementsMapping };
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import clickOutsideHandler from '@ckeditor/ckeditor5-ui/src/bindings/clickoutsid
import IbexaCustomAttributesFormView from './ui/custom-attributes-form-view';
import IbexaButtonView from '../common/button-view/button-view';

import { getCustomAttributesConfig, getCustomClassesConfig } from './helpers/config-helper';
import { getCustomAttributesElementConfig, getCustomClassesElementConfig } from './helpers/config-helper';

const { Translator } = window;

Expand Down Expand Up @@ -40,6 +40,10 @@ class IbexaAttributesUI extends Plugin {
const prefix = this.getAttributePrefix();

modelElements.forEach((modelElement) => {
if (this.editor.isListSelected && this.editor.listIndent !== modelElement.getAttribute('listIndent')) {
return;
}

writer.setAttribute(`${prefix}${name}`, value, modelElement);
});
});
Expand All @@ -59,6 +63,10 @@ class IbexaAttributesUI extends Plugin {
const prefix = this.getAttributePrefix();

modelElements.forEach((modelElement) => {
if (this.editor.isListSelected && this.editor.listIndent !== modelElement.getAttribute('listIndent')) {
return;
}

writer.removeAttribute(`${prefix}${name}`, modelElement);
});
});
Expand All @@ -81,8 +89,6 @@ class IbexaAttributesUI extends Plugin {

showForm() {
const parentElement = this.getModelElement();
const customAttributesConfig = getCustomAttributesConfig();
const customClassesConfig = getCustomClassesConfig();
const prefix = this.getAttributePrefix();
let parentElementName = parentElement.name;

Expand All @@ -98,8 +104,8 @@ class IbexaAttributesUI extends Plugin {
}
}

const customAttributes = customAttributesConfig[parentElementName] ?? {};
const customClasses = customClassesConfig[parentElementName];
const customAttributes = getCustomAttributesElementConfig(parentElementName) ?? {};
const customClasses = getCustomClassesElementConfig(parentElementName);
const areCustomAttributesSet =
parentElement.hasAttribute(`${prefix}custom-classes`) ||
Object.keys(customAttributes).some((customAttributeName) => parentElement.hasAttribute(`${prefix}${customAttributeName}`));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { configElementsMapping } from '../custom-attributes-editing';

const headingsList = ['heading1', 'heading2', 'heading3', 'heading4', 'heading5', 'heading6'];
const findConfigName = (elementName) => {
const configName = Object.entries(configElementsMapping).find(([, value]) => value === elementName);

return configName?.[0] ?? elementName;
};
const getCustomAttributesConfig = () => {
const attributes = { ...window.ibexa.richText.alloyEditor.attributes };

Expand All @@ -17,7 +23,12 @@ const getCustomAttributesConfig = () => {

return attributes;
};
const getCustomAttributesElementConfig = (elementName) => {
const config = getCustomAttributesConfig();
const configName = findConfigName(elementName);

return config[configName];
};
const getCustomClassesConfig = () => {
const classes = { ...window.ibexa.richText.alloyEditor.classes };

Expand All @@ -35,5 +46,17 @@ const getCustomClassesConfig = () => {

return classes;
};
const getCustomClassesElementConfig = (elementName) => {
const config = getCustomClassesConfig();
const configName = findConfigName(elementName);

export { getCustomAttributesConfig, getCustomClassesConfig };
return config[configName];
};

export {
getCustomAttributesConfig,
getCustomClassesConfig,
getCustomAttributesElementConfig,
getCustomClassesElementConfig,
findConfigName,
};
59 changes: 46 additions & 13 deletions src/bundle/Resources/public/js/CKEditor/plugins/elements-path.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,33 @@ class IbexaElementsPath extends Plugin {
super(props);

this.elementsPathWrapper = null;
this.isTableCellSelected = false;

this.updatePath = this.updatePath.bind(this);
}

addListItem(element) {
findElementSiblings(element, siblingsName) {
let iterator = element;
const elementSiblings = [element];

while (iterator?.previousSibling?.name === siblingsName) {
elementSiblings.unshift(iterator.previousSibling);

iterator = iterator.previousSibling;
}

iterator = element;

while (iterator?.nextSibling?.name === siblingsName) {
elementSiblings.push(iterator.nextSibling);

iterator = iterator.nextSibling;
}

return elementSiblings;
}

addListItem(element, index) {
const label = Translator.trans(/*@Desc("list")*/ 'elements_path.list.label', {}, 'ck_editor');
const pathItem = `<li class="ibexa-elements-path__item">${label}</li>`;
const container = document.createElement('ul');
Expand All @@ -22,28 +44,25 @@ class IbexaElementsPath extends Plugin {
listItemNode.addEventListener(
'click',
() => {
let firstElement = element;
let lastElement = element;

while (firstElement?.previousSibling?.name === 'listItem') {
firstElement = firstElement.previousSibling;
}

while (lastElement?.nextSibling?.name === 'listItem') {
lastElement = lastElement.nextSibling;
}
const elementSiblings = this.findElementSiblings(element, 'listItem');
const firstElement = elementSiblings.find((elementSibling) => elementSibling.getAttribute('listIndent') === index);
const lastElement = elementSiblings.findLast((elementSibling) => elementSibling.getAttribute('listIndent') === index);

const range = this.editor.model.createRange(
this.editor.model.createPositionBefore(firstElement),
this.editor.model.createPositionAfter(lastElement),
);

this.editor.isListSelected = true;
this.editor.listIndent = index;

this.editor.model.change((writer) => writer.setSelection(range));
this.editor.focus();

this.editor.model.document.selection.once('change', () => {
this.editor.isListSelected = false;

delete this.editor.listIndent;
});
},
false,
Expand All @@ -58,7 +77,11 @@ class IbexaElementsPath extends Plugin {
}

if (element.name === 'listItem') {
this.addListItem(element);
const listIndent = element.getAttribute('listIndent');

for (let i = 0; i <= listIndent; i++) {
this.addListItem(element, i);
}
}

const pathItem = `<li class="ibexa-elements-path__item">${element.name}</li>`;
Expand All @@ -71,7 +94,11 @@ class IbexaElementsPath extends Plugin {
listItemNode.addEventListener(
'click',
() => {
this.editor.model.change((writer) => writer.setSelection(element, 'in'));
this.isTableCellSelected = element.name === 'tableCell';

const placement = this.isTableCellSelected ? 'on' : 'in';

this.editor.model.change((writer) => writer.setSelection(element, placement));
this.editor.focus();
},
false,
Expand All @@ -87,6 +114,12 @@ class IbexaElementsPath extends Plugin {
this.elementsPathWrapper.innerHTML = '';

this.editor.model.document.selection.getFirstPosition().getAncestors().forEach(this.updatePath);

if (this.isTableCellSelected) {
this.updatePath(this.editor.model.document.selection.getSelectedElement());

this.isTableCellSelected = false;
}
});
}
}
Expand Down

0 comments on commit 0b295e5

Please sign in to comment.