Skip to content

Commit

Permalink
Fix multiple editor issue
Browse files Browse the repository at this point in the history
  • Loading branch information
fsbraun committed Dec 18, 2024
1 parent 62d0a5a commit dbf55a2
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
}
}

.cms-editor-inline-wrapper.ck a {
pointer-events: none;
}

.cms-admin.app-djangocms_text.model-text .ck-editor {
border: none;
background: var(--dca-white);
Expand Down
50 changes: 31 additions & 19 deletions private/js/ckeditor5_plugins/cms-link/src/cms.linkfield.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ class LinkField {
this.options = options;
this.urlElement = element;
this.form = element.closest("form");
this.selectElement = this.form.querySelector(`input[name="${this.urlElement.id + '_select'}"]`);
this.selectElement = this.form?.querySelector(`input[name="${this.urlElement.id + '_select'}"]`);
if (this.selectElement) {
this.urlElement.setAttribute('type', 'hidden'); // Two input types?
this.selectElement.setAttribute('type', 'hidden'); // Make hidden and add common input
this.prepareField();
this.createInput();
this.registerEvents();
}
this.populateField();
}

prepareField() {
createInput() {
this.inputElement = document.createElement('input');
this.inputElement.setAttribute('type', 'text');
this.inputElement.setAttribute('autocomplete', 'off');
Expand All @@ -28,21 +29,7 @@ class LinkField {
this.inputElement.setAttribute('placeholder', this.urlElement.getAttribute('placeholder') ||'');
this.inputElement.className = this.urlElement.className;
this.inputElement.classList.add('cms-linkfield-input');
if (this.selectElement.value) {
this.handleChange({target: this.selectElement});
this.inputElement.classList.add('cms-linkfield-selected');
} else if (this.urlElement.value) {
this.inputElement.value = this.urlElement.value;
this.inputElement.classList.remove('cms-linkfield-selected');
}
if (this.selectElement.getAttribute('data-value')) {
this.inputElement.value = this.selectElement.getAttribute('data-value');
this.inputElement.classList.add('cms-linkfield-selected');
}
if (this.selectElement.getAttribute('data-href')) {
this.urlElement.value = this.selectElement.getAttribute('data-href');
this.inputElement.classList.add('cms-linkfield-selected');
}

this.wrapper = document.createElement('div');
this.wrapper.classList.add('cms-linkfield-wrapper');
this.urlElement.insertAdjacentElement('afterend', this.wrapper);
Expand All @@ -54,6 +41,31 @@ class LinkField {
}
this.wrapper.appendChild(this.inputElement);
this.wrapper.appendChild(this.dropdown);

}

populateField() {
if (this.selectElement) {
if (this.selectElement.value) {
this.handleChange();
this.inputElement.classList.add('cms-linkfield-selected');
} else if (this.urlElement.value) {
this.inputElement.value = this.urlElement.value;
this.inputElement.classList.remove('cms-linkfield-selected');
} else {
this.inputElement.value = '';
this.inputElement.classList.remove('cms-linkfield-selected');
}
if (this.selectElement.getAttribute('data-value')) {
this.inputElement.value = this.selectElement.getAttribute('data-value');
this.inputElement.classList.add('cms-linkfield-selected');
}
if (this.selectElement.getAttribute('data-href')) {
this.urlElement.value = this.selectElement.getAttribute('data-href');
this.inputElement.classList.add('cms-linkfield-selected');
}
this.dropdown.innerHTML = ''; // CSS hides dropdown when empty
}
}

registerEvents() {
Expand Down Expand Up @@ -146,7 +158,7 @@ class LinkField {
this.dropdown.innerHTML = ''; // CSS hides dropdown when empty
}

handleChange(event) {
handleChange() {
if (this.selectElement.value) {
fetch(this.options.url + '?g=' + encodeURIComponent(this.selectElement.value))
.then(response => response.json())
Expand Down
102 changes: 96 additions & 6 deletions private/js/ckeditor5_plugins/cms-link/src/cmsLink.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* jshint esversion: 11 */

import {Plugin} from 'ckeditor5/src/core';
import {SwitchButtonView, View, ViewCollection} from 'ckeditor5/src/ui';
import { isLinkElement } from '@ckeditor/ckeditor5-link/src/utils';
import LinkSuggestionsEditing from './linksuggestionediting';
import LinkField from "./cms.linkfield";

Expand All @@ -25,18 +25,105 @@ export default class CmsLink extends Plugin {
this._handleDataLoadingIntoExtraFormField();
}

_defineConverters() {
const editor = this.editor;

// UPCAST: From view (HTML) to the model
editor.conversion.for('upcast').elementToAttribute({
view: {
name: 'a',
attributes: {
'data-cms-href': true
},
},
model: {
key: 'cmsHref',
value: (viewElement) => viewElement.getAttribute('data-cms-href'),
},
});

// DOWNCAST: From model to view (HTML)
editor.conversion.for('downcast').attributeToElement({
model: 'cmsHref',
view: (value, {writer}) => {
const viewAttributes = {};
viewAttributes['data-cms-href'] = value;
const linkViewElement = writer.createAttributeElement(
'a',
viewAttributes,
{priority: 5},
);

// Without it the isLinkElement() will not recognize the link and the UI will not show up
// when the user clicks a link.
writer.setCustomProperty('link', true, linkViewElement);

return linkViewElement;
},
});
}

_handleExtraAttributeValues() {
const editor = this.editor;

// Extend the link command to handle the custom attribute
editor.commands.get('link').on('execute', (evt, data) => {
console.log(data);
if (data.linkHref) {
const model = editor.model;
const selection = model.document.selection;

model.change((writer) => {
editor.execute('link', ...args);

const firstPosition = selection.getFirstPosition();
if (selection.isCollapsed) {
const node = firstPosition.textNode || firstPosition.nodeBefore;
if (data.cmsHref) {
writer.setAttribute('cmsHref', data.cmsHref, writer.createRangeOn(node));
} else {
writer.removeAttribute('cmsHref', writer.createRangeOn(node));
}

writer.removeSelectionAttribute('cmsHref');
} else {
const ranges = model.schema.getValidRanges(
selection.getRanges(),
'cmsHref',
);

// eslint-disable-next-line no-restricted-syntax
for (const range of ranges) {
if (data.cmsHref) {
writer.setAttribute('cmsHref', data.cmsHref, range);
} else {
writer.removeAttribute('cmsHref', range);
}
}
}
});
}
});

}

_enableLinkAutocomplete() {
const {editor} = this;
const linkFormView = editor.plugins.get('LinkUI').formView;
const linkActionsView = editor.plugins.get('LinkUI').actionsView;

let wasAutocompleteAdded = false;
let autoComplete = null;

editor.plugins
.get('ContextualBalloon')
.on('set:visibleView', (evt, propertyName, newValue) => {
if (newValue !== linkFormView && newValue !== linkActionsView) {
return;
}

const selection = editor.model.document.selection;
const cmsHref = selection.getAttribute('cmsHref');
const linkHref = selection.getAttribute('linkHref');

if (newValue === linkActionsView) {
// Add the link target name of a cms link into the action view
Expand All @@ -47,7 +134,7 @@ export default class CmsLink extends Plugin {
const button = linkActionsView.previewButtonView.element;
button.firstElementChild.textContent = data.text;
});
} else {
} else if (linkHref) {
const button = linkActionsView.previewButtonView.element;
button.firstElementChild.textContent = selection.getAttribute('linkHref');
}
Expand All @@ -60,7 +147,11 @@ export default class CmsLink extends Plugin {
* @type {boolean}
*/

if (wasAutocompleteAdded) {
if (autoComplete !== null) {
// Already added, just reset it, if no link exists
autoComplete.selectElement.value = cmsHref || '';
autoComplete.urlElement.value = linkHref || '';
autoComplete.populateField();
return;
}
const hiddenInput = document.createElement('input');
Expand All @@ -72,10 +163,9 @@ export default class CmsLink extends Plugin {
linkFormView.urlInputView.fieldView.element
);
linkFormView.urlInputView.fieldView.element.parentNode.querySelector('label')?.remove();
new LinkField(linkFormView.urlInputView.fieldView.element, {
autoComplete = new LinkField(linkFormView.urlInputView.fieldView.element, {
url: editor.config.get('url_endpoint') || ''
});
wasAutocompleteAdded = true;
});
}

Expand Down
5 changes: 2 additions & 3 deletions private/js/cms.ckeditor5.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

// The editor creator to use.
import ClassicEditorBase from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
import InlineEditorBase from '@ckeditor/ckeditor5-editor-inline/src/inlineeditor';
import BalloonEditorBase from '@ckeditor/ckeditor5-editor-balloon/src/ballooneditor';
import BlockToolbar from '@ckeditor/ckeditor5-ui/src/toolbar/block/blocktoolbar';

Expand Down Expand Up @@ -63,7 +62,6 @@ var builtinPlugins = [
Autoformat,
Autosave,
Alignment,
BlockToolbar,
Bold,
Italic,
Underline,
Expand Down Expand Up @@ -103,8 +101,8 @@ var builtinPlugins = [
];

ClassicEditor.builtinPlugins = builtinPlugins;
// InlineEditor.builtinPlugins = builtinPlugins;
BalloonEditor.builtinPlugins = builtinPlugins;
BalloonEditor.builtinPlugins.push(BlockToolbar);

// Editor configuration.
var defaultConfig = {
Expand Down Expand Up @@ -216,6 +214,7 @@ class CmsCKEditor5Plugin {
editor.model.document.on('change:data', () => el.dataset.changed='true');
editor.ui.focusTracker.on( 'change:isFocused', ( evt, name, isFocused ) => {
el.classList.remove('ck-content'); // remove Ckeditor 5 default styles
console.log('focus', evt, name, isFocused, el);
if ( !isFocused ) {
// change:data event is not reliable, so we need to double-check
if (el.dataset.changed !== 'true' && editor.getData() !== initialContent) {
Expand Down

0 comments on commit dbf55a2

Please sign in to comment.