Shadow DOM
让编辑器在 shadow root 中运行,例如在您自己的 Web 组件或微前端中。页面样式表不会作用到 shadow root 内部,因此如果没有辅助,其中的编辑器将没有样式;这个插件会把编辑器自己的样式表复制到包含它的 shadow root 中,并持续复制插件之后添加的样式表。

启用
该功能由 shadowdom.js 插件提供(也包含在 plugins/all_plugins.js 中)。像平常一样在页面中加载编辑器的样式表,然后在 shadow root 内的某个元素上创建编辑器;其余的由插件完成。它没有按钮。
<link rel="stylesheet" href="/richtexteditor/rte_theme_default.css">
<script src="/richtexteditor/rte.js"></script>
<script src="/richtexteditor/plugins/all_plugins.js"></script>
<note-editor id="host"></note-editor>
<script>
class NoteEditor extends HTMLElement {
connectedCallback() {
const root = this.attachShadow({ mode: "open" });
root.innerHTML = '<div class="box"><p>Text inside a <b>shadow root</b>.</p></div>';
this.editor = new RichTextEditor(root.querySelector(".box"), { toolbar: "basic", height: "220px" });
}
}
customElements.define("note-editor", NoteEditor);
</script>
rte-webcomponent.js 中现成的 <rich-text-editor> 元素使用的也是这个插件:添加 shadow 属性,它就会把编辑器挂载到自己的 shadow root 中。
<script src="/richtexteditor/rte-webcomponent.js"></script>
<rich-text-editor shadow toolbar="basic" height="220px"><p>Hello</p></rich-text-editor>
如果没有加载 shadowdom.js,该元素会在控制台中输出一条警告,并留在 light DOM 中,而不会以无样式的状态渲染。
选项
| 选项 | 默认值 | 作用 |
|---|---|---|
shadowStyleAdoption | true | 把编辑器的样式表复制到 shadow root 中。false 会关闭复制。 |
shadowStyleSources | null | 要添加到 shadow root 中的额外样式表 URL,可以是字符串或数组,用于您自己的皮肤覆盖样式。 |
复制哪些内容
- 从加载
rte.js的文件夹提供的<link rel="stylesheet">元素,或者文件名属于编辑器的元素(rte_theme、rte_mobile、richtexteditor_content、richtexteditor_preview、aitoolkit)。它们会以相同的 URL 重新创建为新的<link>元素,因此会从浏览器缓存中加载。 - id 以
rte-或__rte开头的<style>元素(插件的样式),以及没有 id、但 CSS 中提到编辑器选择器的<style>元素——Vite 等打包工具就是以这种方式注入导入的主题的。 - 页面通过
document.adoptedStyleSheets采用的样式表。
页面中的其他内容都不会被复制,因此您的组件仍然保持封装。每个副本都带有 data-rte-adopted="1"。在上面的测试页面中,复制了 9 个样式表(主题、AI Toolkit 样式表以及插件的 <style> 元素),工具栏高度为 41 像素。设置 shadowStyleAdoption: false 时,工具栏高度为 7,561 像素,变成了一列没有样式的按钮。
插件会监视页面的 <head>,因此启动之后、插件面板首次打开时才添加的插件样式也会被复制。对话框和菜单在编辑器的元素内部创建,因此它们位于 shadow root 中,并使用复制过来的样式。
API
editor.isInShadowDom()——编辑器位于 shadow root 中时为true。editor.getShadowRoot()——该 shadow root,或者null。editor.getAdoptedStyleCount()——已复制的样式表数量(上例中为 9)。editor.adoptEditorStyles(target)——把编辑器的样式表复制到另一个根中,例如用于显示预览的第二个 shadow root。不带参数时,使用编辑器自己的 shadow root。
注意事项
- 编辑区域是一个 iframe,因此文档自身的 CSS 会照常加载到其中(
contentCssUrl);这个插件只与编辑器的工具栏、菜单和对话框有关。 - 在 shadow root 之外,插件不做任何事,也不会创建观察器。
- 写在页面样式表中、用于覆盖编辑器外观的样式,不会作用到 shadow root 内部。请把它们列在
shadowStyleSources中,或者自己把它们放进 shadow root。 - 保存的 HTML 不受影响;
getHTMLCode()返回了<p>Text inside a <b>shadow root</b>.</p>。