自定义
Quill 在设计时就考虑到了定制和扩展。这是通过实现一个小型编辑器核心来实现的,该核心由一个精细且定义明确的 API 暴露。核心由 modules 增强,使用你有权访问的相同 APIs。
¥Quill was designed with customization and extension in mind. This is achieved by implementing a small editor core exposed by a granular, well defined API. The core is augmented by modules, using the same APIs you have access to.
通常,常见的自定义功能在 configurations 中处理,用户界面在 主题 和 CSS 中处理,功能在 modules 中处理,编辑器内容在 羊皮纸 中处理。
¥In general, common customizations are handled in configurations, user interfaces by Themes and CSS, functionality by modules, and editor contents by Parchment.
配置
¥Configurations
Quill 更倾向于“代码优先于配置”,但对于非常常见的需求,尤其是在等效代码冗长或复杂的情况下,Quill 提供了 configuration 选项。这将是确定你是否需要实现任何自定义功能的良好起点。
¥Quill favors Code over Configuration™, but for very common needs, especially where the equivalent code would be lengthy or complex, Quill provides configuration options. This would be a good first place to look to determine if you even need to implement any custom functionality.
最强大的两个选项是 modules
和 theme
。你可以通过简单地添加或删除单个 modules 或使用不同的 theme 来彻底改变或扩展 Quill 的功能。
¥Two of the most powerful options is modules
and theme
. You can drastically change or expand what Quill can and does do by simply adding or removing individual modules or using a different theme.
主题
¥Themes
Quill 官方支持标准工具栏主题 雪花 和浮动工具提示主题 气泡。由于 Quill 不像许多旧版编辑器那样局限于 iframe 中,因此许多视觉修改只需使用 CSS 即可完成,并且可以使用现有主题之一。
¥Quill officially supports a standard toolbar theme Snow and a floating tooltip theme Bubble. Since Quill is not confined within an iframe like many legacy editors, many visual modifications can be made with just CSS, using one of the existing themes.
如果你想彻底更改 UI 交互,可以省略 theme
配置选项,这将为你提供一个无样式的 Quill 编辑器。你仍然需要包含一个精简的样式表,例如,确保空格在所有浏览器中都能渲染,并且有序列表的编号正确。
¥If you would like to drastically change UI interactions, you can omit the theme
configuration option, which will give you an unstyled Quill editor. You do still need to include a minimal stylesheet that, for example, makes sure spaces render in all browsers and ordered lists are appropriately numbered.
<link rel="stylesheet" href="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/quill/2.0.0-dev.4/quill.core.css" />
从那里,你可以实现并附加自己的 UI 元素,例如自定义下拉菜单或工具提示。使用 Parchment 克隆 Medium 的最后一部分提供了一个实际示例。
¥From there you can implement and attach your own UI elements like custom dropdowns or tooltips. The last section of Cloning Medium with Parchment provides an example of this in action.
模块
¥Modules
Quill 采用模块化架构设计,由一个小型编辑核心和一些增强其功能的模块组成。其中一些功能对于编辑至关重要,例如 历史记录 模块,它管理撤消和重做。由于所有模块都使用相同的公开给开发者的 API,因此必要时甚至可以交换核心模块。
¥Quill is designed with a modular architecture composed of a small editing core, surrounded by modules that augment its functionality. Some of this functionality is quite integral to editing, such as the History module, which manages undo and redo. Because all modules use the same public API exposed to the developer, even interchanging core modules is possible, when necessary.
与 Quill 的核心本身一样,许多 modules 接口也提供了额外的配置选项和 API。在决定替换模块之前,请查看其文档。通常,你所需的自定义功能已经作为配置或 API 调用实现了。
¥Like Quill's core itself, many modules expose additional configuration options and APIs. Before deciding to replace a module, take a look at its documentation. Often your desired customization is already implemented as a configuration or API call.
此外,如果你想彻底更改现有模块已涵盖的功能,你可以直接不包含它(或者在主题默认包含它时明确排除它),并使用与默认模块相同的 API,在 Quill 外部实现你喜欢的功能。
¥Otherwise, if you would like to drastically change functionality an existing module already covers, you can simply not include it—or explicitly exclude it when a theme includes it by default—and implement the functionality to your liking external to Quill, using the same API the default module uses.
const quill = new Quill('#editor', { modules: { toolbar: false // Snow includes toolbar by default }, theme: 'snow' });
一些模块 - 剪贴板、键盘 和 历史记录 - 需要包含在内,因为核心功能依赖于它们提供的 API。例如,尽管撤消和重做是编辑器的基本功能,但原生浏览器对此行为的处理不一致且不可预测。History 模块通过实现自己的撤消管理器并将 undo()
和 redo()
作为 API 公开来弥补这一缺陷。
¥A few modules—Clipboard, Keyboard, and History—need to be included as core functionality depend on the APIs they provide. For example, even though undo and redo is basic, expected, editor functionality, the native browser behavior handling of this is inconsistent and unpredictable. The History module bridges the gap by implementing its own undo manager and exposing undo()
and redo()
as APIs.
尽管如此,秉承 Quill 模块化设计,你仍然可以通过实现自己的撤消管理器来替换历史记录模块,从而彻底改变撤消和重做(或任何其他核心功能)的工作方式。只要你实现相同的 API 接口,Quill 就会很乐意使用你的替换模块。最简单的方法是继承现有模块,并覆盖要更改的方法。查看 modules 文档,其中有一个非常简单的示例,介绍了如何覆盖核心 剪贴板 模块。
¥Nevertheless, staying true to Quill modular design, you can still drastically change the way undo and redo—or any other core functionality—works by implementing your own undo manager to replace the History module. As long as you implement the same API interface, Quill will happily use your replacement module. This is most easily done by inheriting from the existing module, and overwriting the methods you want to change. Take a look at the modules documentation for a very simple example of overwriting the core Clipboard module.
最后,你可能想要添加现有模块未提供的功能。在这种情况下,将其组织为 Quill 模块可能会更方便,构建自定义模块 指南中对此进行了介绍。当然,将此逻辑与 Quill 分开,放在应用代码中也是可行的。
¥Finally, you may want to add functionality not provided by existing modules. In this case, it may be convenient to organize this as a Quill module, which the Building A Custom Module guide covers. Of course, it is certainly valid to just keep this logic separate from Quill, in your application code instead.
内容和格式
¥Content and Formatting
Quill 允许修改和扩展其通过其文档模型 羊皮纸 理解的内容和格式。内容和格式在 Parchment 中表示为 Blots 或 Attributors,它们大致对应于 DOM 中的节点或属性。
¥Quill allows modification and extension of the contents and formats that it understands through its document model Parchment. Content and formats are represented in Parchment as either Blots or Attributors, which roughly correspond to Nodes or Attributes in the DOM.
类 vs 内联
¥Class vs Inline
Quill 尽可能使用类而不是内联样式属性,但两者都已实现,你可以自行选择。一个实例被实现为 Playground 代码片段。
¥Quill uses classes, instead of inline style attributes, when possible, but both are implemented for you to pick and choose. A live example of this is implemented as a Playground snippet.
const ColorClass = Quill.import('attributors/class/color');const SizeStyle = Quill.import('attributors/style/size');Quill.register(ColorClass, true);Quill.register(SizeStyle, true);
// Initialize as you would normallyconst quill = new Quill('#editor', { modules: { toolbar: true, }, theme: 'snow',});
自定义属性
¥Customizing Attributors
除了选择特定的 Attributor 之外,你还可以自定义现有的 Attributor。以下是用于添加其他字体的字体白名单示例。
¥In addition to choosing the particular Attributor, you can also customize existing ones. Here is an example of the font whitelist to add additional fonts.
const FontAttributor = Quill.import('attributors/class/font');FontAttributor.whitelist = [ 'sofia', 'slabo', 'roboto', 'inconsolata', 'ubuntu',];Quill.register(FontAttributor, true);
请注意,你仍然需要在 CSS 文件中添加这些类的样式。
¥Note you still need to add styling for these classes into your CSS files.
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet" /><style> .ql-font-roboto { font-family: 'Roboto', sans-serif; }</style>
自定义 Blot
¥Customizing Blots
Blot 所表示的格式也可以自定义。以下是如何更改用于表示粗体格式的 DOM 节点。
¥Formats represented by Blots can also be customized. Here is how you would change the DOM Node used to represent bold formatting.
const Bold = Quill.import('formats/bold'); Bold.tagName = 'B'; // Quill uses <strong> by default Quill.register(Bold, true); // Initialize as you would normally const quill = new Quill('#editor', { modules: { toolbar: true }, theme: 'snow' }); const Delta = Quill.import('delta'); quill.setContents( new Delta() .insert('Rendered with <b>!', { bold: true }) .insert('\n') );
扩展 Blot
¥Extending Blots
你还可以扩展现有格式。这是一个快速的 ES6 列表项实现,它不允许格式化其内容。代码块正是以此方式实现的。
¥You can also extend existing formats. Here is a quick ES6 implementation of a list item that does not permit formatting its contents. Code blocks are implemented in exactly this way.
const ListItem = Quill.import('formats/list/item');
class PlainListItem extends ListItem { formatAt(index, length, name, value) { if (name === 'list') { // Allow changing or removing list format super.formatAt(name, value); } // Otherwise ignore }}
Quill.register(PlainListItem, true);
// Initialize as you would normallyconst quill = new Quill('#editor', { modules: { toolbar: true, }, theme: 'snow',});
你可以通过调用 console.log(Quill.imports);
查看可用的 Blots 和 Attributors 列表。不支持直接修改此对象。改用 Quill.register
。
¥You can view a list of Blots and Attributors available by calling console.log(Quill.imports);
. Direct modification of this object is not supported. Use Quill.register
instead.
关于 Parchment、Blots 和 Attributors 的完整参考资料,请参阅 Parchment 自己的 README。有关深入的演示,请查看 使用 Parchment 克隆 Medium,它从 Quill 理解纯文本开始,到添加 中等 支持的所有格式。大多数情况下,你无需从头开始构建格式,因为大多数格式已经在 Quill 中实现,但理解 Quill 更深层次的工作原理仍然很有用。
¥A complete reference on Parchment, Blots and Attributors can be found on Parchment's own README. For an in-depth walkthrough, take a look at Cloning Medium with Parchment, which starts with Quill understanding just plain text, to adding all of the formats Medium supports. Most of the time, you will not have to build formats from scratch since most are already implemented in Quill, but it is still useful to understanding how Quill works at this deeper level.