我想知道如何将 CKeditor 5 设置为 RTL? 我在他们的网站上找不到这个。
如果不可能,什么是好的 rtl 编辑器?
谢谢!
最佳答案
我面对这个问题两周了,最后,根据我的经验,我通过在 ckeditor.js 中编码解决了它,添加 CKEditor 5 组件的最佳方法是,首先,你应该去 https://ckeditor.com/ckeditor-5/online-builder/并通过 5 个简单步骤。 那么你应该将它添加到你的项目中。此外,还可以向此构建组件添加 RTL 方向。然而,主要问题是它只是将 rtl 方向添加为默认值,并且无法根据您的需要在文本中更改它。因此你必须自己做一些编码。我做到了,并且在 Angular 8 中完美运行
如果您仔细按照以下步骤操作,方向选择将轻松添加到您的项目中。
转到@ckeditor/ckeditor5-build-classic/build并打开ckeditor.js文件
然后尝试从 min js 文件中提取它 - 你可以通过谷歌搜索找到太多在线工具。
那么首先你需要找到下面的 block 代码
class Ak extends ok {
static get requires() {
return [pk, xk];
}
static get pluginName() {
return "Alignment";
}
}
- 现在,在此 block 代码之后,您应该添加以下代码(只需将其从此处复制到您的文件中)
// Removes the direction attribute from blocks.
// @private
function removeDirectionFromSelection(blocks, writer) {
for (const block of blocks) {
writer.removeAttribute(DIRECTION, block);
}
}
// Sets the direction attribute on blocks.
// @private
function setDirectionOnSelection(blocks, writer, direction) {
for (const block of blocks) {
writer.setAttribute(DIRECTION, direction, block);
}
}
const DIRECTION = 'direction';
class DirectionCommand extends sk {
refresh() {
const firstBlock = ck(this.editor.model.document.selection.getSelectedBlocks());
// As first check whether to enable or disable the command as the value will always be false if the command cannot be enabled.
this.isEnabled = !!firstBlock && this._canBeAligned(firstBlock);
this.value = (this.isEnabled && firstBlock.hasAttribute('direction')) ? firstBlock.getAttribute('direction') : 'rtl';
}
execute(options = {}) {
const editor = this.editor;
const model = editor.model;
const doc = model.document;
const value = options.value;
model.change(writer => {
// Get only those blocks from selected that can have direction set
const blocks = Array.from(doc.selection.getSelectedBlocks()).filter(block => this._canBeAligned(block));
const currentDirection = blocks[0].getAttribute('direction');
// Remove direction attribute if current direction is:
// - default (should not be stored in model as it will bloat model data)
// - equal to currently set
// - or no value is passed - denotes default direction.
const removeDirection = isDefault(value) || currentDirection === value || !value;
if (removeDirection) {
removeDirectionFromSelection(blocks, writer);
} else {
setDirectionOnSelection(blocks, writer, value);
}
});
}
_canBeAligned(block) {
return this.editor.model.schema.checkAttribute(block, DIRECTION);
}
}
const supportedOptions = ['ltr', 'rtl'];
class DirectionEditing extends ok {
constructor(editor) {
super(editor);
editor.config.define('direction', {
options: [...supportedOptions]
});
}
init() {
const editor = this.editor;
const schema = editor.model.schema;
// Filter out unsupported options.
const enabledOptions = editor.config.get('direction.options').filter(isSupported);
// Allow direction attribute on all blocks.
schema.extend('$block', { allowAttributes: 'direction' });
editor.model.schema.setAttributeProperties('direction', { isFormatting: true });
const definition = _buildDefinition(enabledOptions.filter(option => !isDefault(option)));
editor.conversion.attributeToAttribute(definition);
editor.commands.add('direction', new DirectionCommand(editor));
}
}
function isSupported(option) {
return supportedOptions.includes(option);
}
function _buildDefinition(options) {
const definition = {
model: {
key: 'direction',
values: options.slice()
},
view: {}
};
for (const option of options) {
definition.view[option] = {
key: 'style',
value: {
'direction': option
}
};
}
return definition;
}
function isDefault(direction) {
// Right now only LTR is supported so the 'ltr' value is always the default one.
return direction === 'rtl';
}
class DirectionUI extends ok {
get localizedOptionTitles() {
const t = this.editor.t;
return {
'ltr': t('چپ چین کردن متن'),
'rtl': t('راست چین کردن متن'),
};
}
static get pluginName() {
return 'DirectionUI';
}
init() {
const editor = this.editor;
const componentFactory = editor.ui.componentFactory;
const t = editor.t;
const options = editor.config.get('direction.options');
options
.filter(isSupported)
.forEach(option => this._addButton(option));
componentFactory.add('direction', locale => {
const dropdownView = jw(locale);
// Add existing direction buttons to dropdown's toolbar.
const buttons = options.map(option => componentFactory.create(`direction:${option}`));
Fw(dropdownView, buttons);
// Configure dropdown properties an behavior.
dropdownView.buttonView.set({
label: t('چپ چین راست چین'),
tooltip: true
});
dropdownView.toolbarView.isVertical = true;
dropdownView.extendTemplate({
attributes: {
class: 'ck-direction-dropdown'
}
});
// The default icon is align left as we do not support RTL yet (see #3).
const defaultIcon = alignLeftIcon;
// Change icon to reflect current selection's direction.
dropdownView.buttonView.bind('icon').toMany(buttons, 'isOn', (...areActive) => {
// Get the index of an active button.
const index = areActive.findIndex(value => value);
// If none of the commands is active, display either defaultIcon or the first button's icon.
if (index < 0) {
return defaultIcon;
}
// Return active button's icon.
return buttons[index].icon;
});
// Enable button if any of the buttons is enabled.
dropdownView.bind('isEnabled').toMany(buttons, 'isEnabled', (...areEnabled) => areEnabled.some(isEnabled => isEnabled));
return dropdownView;
});
}
_addButton(option) {
const editor = this.editor;
editor.ui.componentFactory.add(`direction:${option}`, locale => {
const command = editor.commands.get('direction');
const buttonView = new Ew(locale);
buttonView.set({
label: this.localizedOptionTitles[option],
icon: icons.get(option),
tooltip: true
});
// Bind button model to command.
buttonView.bind('isEnabled').to(command);
buttonView.bind('isOn').to(command, 'value', value => value === option);
// Execute command.
this.listenTo(buttonView, 'execute', () => {
editor.execute('direction', { value: option });
editor.editing.view.focus();
});
return buttonView;
});
}
}
const alignLeftIcon = '<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M 10 0.199219 C 7.292969 0.199219 5.101562 2.394531 5.101562 5.101562 C 5.101562 7.804688 7.292969 10 10 10 L 10 19.800781 L 12.449219 19.800781 L 12.449219 2.648438 L 14.898438 2.648438 L 14.898438 19.800781 L 17.351562 19.800781 L 17.351562 2.648438 L 19.800781 2.648438 L 19.800781 0.199219 Z M 0.199219 13.675781 L 5.101562 8.777344 L 0.199219 3.875 Z M 0.199219 13.675781"/></svg>';
const alignRightIcon = '<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M 5.101562 0.199219 C 2.394531 0.199219 0.199219 2.394531 0.199219 5.101562 C 0.199219 7.804688 2.394531 10 5.101562 10 L 5.101562 19.800781 L 7.550781 19.800781 L 7.550781 2.648438 L 10 2.648438 L 10 19.800781 L 12.449219 19.800781 L 12.449219 2.648438 L 14.898438 2.648438 L 14.898438 0.199219 Z M 19.800781 3.875 L 14.898438 8.777344 L 19.800781 13.675781 Z M 19.800781 3.875"/></svg>';
const icons = new Map([
['ltr', alignLeftIcon],
['rtl', alignRightIcon],
]);
class Direction extends ok {
static get requires() {
return [DirectionEditing, DirectionUI];
}
static get pluginName() {
return 'Direction';
}
}
- 现在您需要找到“EL.builtinPlugins[....]”代码块,然后您应该将“Direction”添加到其数组中。
- 在您的 ckeditor 配置中添加工具栏项目的组件中,您需要在项目中添加“方向”(请注意其单词大小写敏感性)。
恭喜。您现在将在工具栏中看到方向按钮。 享受
关于javascript - 将 CKeditor 5 与 rtl 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47238886/