[英]Manipulate innerText of a CKEditor ViewElement
我正在為#neoscms 的CKEditor5 創建一個小自定義插件。 Neos 正在使用#ckeditor5,但具有自定義視圖。
該插件或多或少是一個占位符插件。 用戶可以為項目(標識符和標簽)配置具有鍵值存儲的數據源。 CKEditor 中的下拉列表中填充了項目,當用戶從下拉列表中選擇項目時,它會創建一個占位符元素,該元素應以帶有一些數據屬性的 span 元素結尾。
主要思想是有一個空元素,只有數據屬性來識別元素並能夠分配實時數據。 但事實證明,實時數據的事情很棘手。 當我在網站上使用額外的 JS 片段操作跨度時,CKEditor 無法處理此問題。
是否可以在 DOM 中操作視圖元素並且仍然有工作的編輯器? 如果我只是在 downCasting 中添加內部文本並且不替換某些內容,則插件可以正常工作。 但是實時數據會很好。
也許該代碼給出了包的概念。 它還沒有准備好,因為這或多或少是主要功能;)
import {Plugin, toWidget, viewToModelPositionOutsideModelElement, Widget,} from "ckeditor5-exports";
import PlaceholderCommand from "./placeHolderCommand";
export default class PlaceholderEditing extends Plugin {
static get requires() {
return [Widget];
}
init() {
this._defineSchema();
this._defineConverters();
this.editor.commands.add(
"placeholder",
new PlaceholderCommand(this.editor)
);
this.editor.editing.mapper.on(
"viewToModelPosition",
viewToModelPositionOutsideModelElement(this.editor.model, (viewElement) =>
viewElement.hasClass("internezzo-placeholder")
)
);
this.editor.config.define("placeholderProps", {
types: ["name", "node", "nodePath"],
});
this.editor.config.define("placeholderBrackets", {
open: "[",
close: "]",
});
}
_defineSchema() {
const schema = this.editor.model.schema;
schema.register("placeholder", {
allowWhere: "$text",
isInline: true,
isObject: true,
allowAttributes: [
"name",
"node",
"nodePath",
"data-placeholder-identifier",
"data-node-identifier",
"data-node-path",
],
});
}
_defineConverters() {
const conversion = this.editor.conversion;
const config = this.editor.config;
conversion.for("upcast").elementToElement({
view: {
name: "span",
classes: ["foobar-placeholder"],
},
model: (viewElement, writer) => {
const name = viewElement.getAttribute('data-placeholder-identifier');
const node = viewElement.getAttribute('data-node-identifier');
const nodePath = viewElement.getAttribute('data-node-path');
const modelWriter = writer.writer || writer;
return modelWriter.createElement("placeholder", {name, node, nodePath, editable: false});
},
});
conversion.for("editingDowncast").elementToElement({
model: "placeholder",
view: (modelItem, writer) => {
const viewWriter = writer.writer || writer;
const widgetElement = createPlaceholderView(modelItem, viewWriter);
return toWidget(widgetElement, viewWriter);
},
});
conversion.for("dataDowncast").elementToElement({
model: "placeholder",
view: (modelItem, writer) => {
const viewWriter = writer.writer || writer;
return createPlaceholderView(modelItem, viewWriter);
},
});
// Helper method for downcast converters.
function createPlaceholderView(modelItem, viewWriter) {
const name = modelItem.getAttribute("name");
const node = modelItem.getAttribute("node");
const nodePath = modelItem.getAttribute("nodePath");
const placeholderView = viewWriter.createContainerElement("span", {
class: "foobar-placeholder",
"data-placeholder-identifier": name,
"data-node-identifier": node,
"data-node-path": nodePath,
});
// Would be nice to remove that and have just empty spans that get dynamic data
let innerText = config.get("placeholderBrackets.open") + name;
innerText += config.get("placeholderBrackets.close");
viewWriter.insert(
viewWriter.createPositionAt(placeholderView, 0),
viewWriter.createText(innerText)
);
return placeholderView;
}
}
}
因此,網站使用的額外 JS 片段正在搜索具有類foobar-placeholder
的跨度,並將一個帶有實時數據的值寫入跨度。 當然,這在前端有效,但使用 CKEditor 的 CMS 的后端在不斷變化的數據方面存在問題。
我找不到 CKEditor 文檔的解決方案,也許我以某種方式濫用了 API,但我現在找到了適合我的解決方案。
我的網站片段現在通過廣播消息與插件通信。 然后我搜索占位符元素並檢查是否需要更改屬性。
const broadcastChannel = new BroadcastChannel('placeholder:changeData');
broadcastChannel.postMessage({identifier: name, value});
並且在插件中
// Receive new values for placeholder via broadcast
const broadcastChannel = new BroadcastChannel('placeholder:changeData');
broadcastChannel.onmessage = (message) => {
const identifier = get('data.identifier', message);
const newValue = get('data.value', message);
this.editor.model.change( writer => {
if (identifier) {
this._replaceAttribute(writer, identifier, newValue);
}
});
};
現在唯一的缺點是我需要重新加載頁面,但已經讀到這可能是由於我的元素向下轉換並且我更改了屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.