Skip to content

Commit

Permalink
feat: add spotlight plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
AliKdhim87 committed Nov 24, 2022
1 parent 47f9cd9 commit d61ed86
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/utrecht-editor/src/ckeditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import TextTransformation from "@ckeditor/ckeditor5-typing/src/texttransformatio
import WordCount from "@ckeditor/ckeditor5-word-count/src/wordcount";
import HtmlEmbed from '@ckeditor/ckeditor5-html-embed/src/htmlembed';
import { SimpleBox } from './simplebox'
import { Spotlight } from './spotlight'
import { ProductPreviewEditing } from './ProductPriceWidget/editing';

import { ExtendHTMLSupport } from "./CustomHTMLSupport"
Expand Down Expand Up @@ -94,6 +95,7 @@ Editor.builtinPlugins = [
TextTransformation,
WordCount,
SimpleBox,
Spotlight,
ProductPreviewEditing,
];

Expand Down Expand Up @@ -127,6 +129,7 @@ Editor.defaultConfig = {
"textPartLanguage",
"htmlEmbed",
"simpleBox",
"spotlight"
],
},
language: "en",
Expand Down
33 changes: 33 additions & 0 deletions packages/utrecht-editor/src/spotlight/command.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Command from '@ckeditor/ckeditor5-core/src/command';

export class InsertSpotlightCommand extends Command {
execute() {
this.editor.model.change(writer => {
// Insert <simpleBox>*</simpleBox> at the current selection position
// in a way that will result in creating a valid model structure.
this.editor.model.insertContent(createSpotlight(writer));
});
}

refresh() {
const model = this.editor.model;
const selection = model.document.selection;
const allowedIn = model.schema.findAllowedParent(selection.getFirstPosition(), 'spotlight');
this.isEnabled = allowedIn !== null;
}
}

function createSpotlight(writer) {
const spotlight = writer.createElement('spotlight');
// const spotlightTitle = writer.createElement('spotlightTitle');
const spotlightDescription = writer.createElement('spotlightDescription');

// writer.append(spotlightTitle, spotlight);
writer.append(spotlightDescription, spotlight);

// There must be at least one paragraph for the description to be editable.
// See https://github.com/ckeditor/ckeditor5/issues/1464.
writer.appendElement('paragraph', spotlightDescription);

return spotlight;
}
103 changes: 103 additions & 0 deletions packages/utrecht-editor/src/spotlight/editing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import { toWidget, toWidgetEditable } from '@ckeditor/ckeditor5-widget/src/utils';
import Widget from '@ckeditor/ckeditor5-widget/src/widget';

import { InsertSpotlightCommand } from "./command"

export class SpotlightEditing extends Plugin {
static get requires() {
return [Widget];
}

init() {
this._defineSchema();
this._defineConverters();

this.editor.commands.add('insertSpotlight', new InsertSpotlightCommand(this.editor));
}

_defineSchema() {
const schema = this.editor.model.schema;

schema.register('spotlight', {
// Behaves like a self-contained object (e.g. an image).
isObject: true,

// Allow in places where other blocks are allowed (e.g. directly in the root).
allowWhere: '$block'
});

schema.register('spotlightDescription', {
// Cannot be split or left by the caret.
isLimit: true,

allowIn: 'spotlight',

// Allow content which is allowed in the root (e.g. paragraphs).
allowContentOf: '$root'
});

schema.addChildCheck((context, childDefinition) => {
if (context.endsWith('spotlightDescription') && childDefinition.name == 'spotlight') {
return false;
}
});
}

_defineConverters() {
const conversion = this.editor.conversion;

// <spotlight> converters
conversion.for('upcast').elementToElement({
model: 'spotlight',
view: {
name: 'section',
classes: 'spotlight'
}
});

conversion.for('dataDowncast').elementToElement({
model: 'spotlight',
view: {
name: 'section',
classes: 'spotlight'
}
});

conversion.for('editingDowncast').elementToElement({
model: 'spotlight',
view: (modelElement, { writer: viewWriter }) => {
const section = viewWriter.createContainerElement('section', { class: 'spotlight' });

return toWidget(section, viewWriter, { label: 'simple box widget' });
}
});

// <spotlightDescription> converters
conversion.for('upcast').elementToElement({
model: 'spotlightDescription',
view: {
name: 'div',
classes: ['utrecht-spotlight-section', 'utrecht-spotlight-section--info']
}
});

conversion.for('dataDowncast').elementToElement({
model: 'spotlightDescription',
view: {
name: 'div',
classes: ['utrecht-spotlight-section', 'utrecht-spotlight-section--info']
}
});
conversion.for('editingDowncast').elementToElement({
model: 'spotlightDescription',
view: (modelElement, { writer: viewWriter }) => {
// Note: You use a more specialized createEditableElement() method here.
const div = viewWriter.createEditableElement('div', { class: 'utrecht-spotlight-section utrecht-spotlight-section--info' });

return toWidgetEditable(div, viewWriter);
}
});
}

}
10 changes: 10 additions & 0 deletions packages/utrecht-editor/src/spotlight/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';

import { SpotlightEditing } from './editing';
import { SpotlightUI } from './ui';

export class Spotlight extends Plugin {
static get requires() {
return [SpotlightEditing, SpotlightUI];
}
}
35 changes: 35 additions & 0 deletions packages/utrecht-editor/src/spotlight/ui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
import Plugin from '@ckeditor/ckeditor5-core/src/plugin';

export class SpotlightUI extends Plugin {
init() {
const editor = this.editor
const t = editor.t;

// The "Spotlight" button must be registered among the UI components of the editor
// to be displayed in the toolbar.
editor.ui.componentFactory.add('spotlight', locale => {
// The state of the button will be bound to the widget command.
const command = editor.commands.get('insertSpotlight');

// The button will be an instance of ButtonView.
const buttonView = new ButtonView(locale);

buttonView.set({
// The t() function helps localize the editor. All strings enclosed in t() can be
// translated and change when the language of the editor changes.
label: t('Spotlight'),
withText: true,
tooltip: true
});

// Bind the state of the button to the command.
buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');

// Execute the command when the button is clicked (executed).
this.listenTo(buttonView, 'execute', () => editor.execute('insertSpotlight'));

return buttonView;
});
}
}

0 comments on commit d61ed86

Please sign in to comment.