mirror of https://github.com/artf/grapesjs.git
nocodeframeworkdrag-and-dropsite-buildersite-generatortemplate-builderui-builderweb-builderweb-builder-frameworkwebsite-builderno-codepage-builder
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
33 KiB
140 lines
33 KiB
<!DOCTYPE html>
|
|
<html lang="en-US">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>Replace the built-in Rich Text Editor | GrapesJS</title>
|
|
<meta name="generator" content="VuePress 1.9.10">
|
|
<link rel="icon" href="/docs/logo-icon.png">
|
|
<link rel="stylesheet" href="https://grapesjs.com/stylesheets/grapes.min.css?v0.21.10">
|
|
<script src="https://grapesjs.com/js/grapes.min.js?v0.21.10"></script>
|
|
<meta name="description" content="GrapesJS documentation">
|
|
|
|
<link rel="preload" href="/docs/assets/css/0.styles.2c61df29.css" as="style"><link rel="preload" href="/docs/assets/js/app.424ab1f7.js" as="script"><link rel="preload" href="/docs/assets/js/4.0070552e.js" as="script"><link rel="preload" href="/docs/assets/js/2.6fefd022.js" as="script"><link rel="preload" href="/docs/assets/js/1.d23e9fed.js" as="script"><link rel="preload" href="/docs/assets/js/79.4581c86c.js" as="script"><link rel="prefetch" href="/docs/assets/js/12.fcd6c1b3.js"><link rel="prefetch" href="/docs/assets/js/13.f8ba6288.js"><link rel="prefetch" href="/docs/assets/js/14.37d1e434.js"><link rel="prefetch" href="/docs/assets/js/15.6e77df13.js"><link rel="prefetch" href="/docs/assets/js/16.c5f433ca.js"><link rel="prefetch" href="/docs/assets/js/17.de56d7c2.js"><link rel="prefetch" href="/docs/assets/js/18.bf39ac98.js"><link rel="prefetch" href="/docs/assets/js/19.ca87c57f.js"><link rel="prefetch" href="/docs/assets/js/20.68039d84.js"><link rel="prefetch" href="/docs/assets/js/21.2b429912.js"><link rel="prefetch" href="/docs/assets/js/22.27b0a8c5.js"><link rel="prefetch" href="/docs/assets/js/23.d9e75a94.js"><link rel="prefetch" href="/docs/assets/js/24.96337353.js"><link rel="prefetch" href="/docs/assets/js/25.fe03e194.js"><link rel="prefetch" href="/docs/assets/js/26.33a13a48.js"><link rel="prefetch" href="/docs/assets/js/27.bdeec887.js"><link rel="prefetch" href="/docs/assets/js/28.cf1f128d.js"><link rel="prefetch" href="/docs/assets/js/29.5888c207.js"><link rel="prefetch" href="/docs/assets/js/3.4e94790f.js"><link rel="prefetch" href="/docs/assets/js/30.bace5f23.js"><link rel="prefetch" href="/docs/assets/js/31.2b0fa15d.js"><link rel="prefetch" href="/docs/assets/js/32.fdf463ac.js"><link rel="prefetch" href="/docs/assets/js/33.1b7b6b41.js"><link rel="prefetch" href="/docs/assets/js/34.2a27db4f.js"><link rel="prefetch" href="/docs/assets/js/35.4c1b458d.js"><link rel="prefetch" href="/docs/assets/js/36.80ac7652.js"><link rel="prefetch" href="/docs/assets/js/37.a813e6f1.js"><link rel="prefetch" href="/docs/assets/js/38.b5848cbf.js"><link rel="prefetch" href="/docs/assets/js/39.ac3b74a5.js"><link rel="prefetch" href="/docs/assets/js/40.0fad8f56.js"><link rel="prefetch" href="/docs/assets/js/41.725a5d92.js"><link rel="prefetch" href="/docs/assets/js/42.34d5f071.js"><link rel="prefetch" href="/docs/assets/js/43.49e4b43f.js"><link rel="prefetch" href="/docs/assets/js/44.dcce613b.js"><link rel="prefetch" href="/docs/assets/js/45.851c5425.js"><link rel="prefetch" href="/docs/assets/js/46.61478c36.js"><link rel="prefetch" href="/docs/assets/js/47.3743426b.js"><link rel="prefetch" href="/docs/assets/js/48.f36e3619.js"><link rel="prefetch" href="/docs/assets/js/49.4692ff79.js"><link rel="prefetch" href="/docs/assets/js/5.08dc74a9.js"><link rel="prefetch" href="/docs/assets/js/50.92c87e88.js"><link rel="prefetch" href="/docs/assets/js/51.6c005fbf.js"><link rel="prefetch" href="/docs/assets/js/52.ede5d238.js"><link rel="prefetch" href="/docs/assets/js/53.14d8e525.js"><link rel="prefetch" href="/docs/assets/js/54.e4f036ef.js"><link rel="prefetch" href="/docs/assets/js/55.510d4705.js"><link rel="prefetch" href="/docs/assets/js/56.96abc2ed.js"><link rel="prefetch" href="/docs/assets/js/57.5452e0eb.js"><link rel="prefetch" href="/docs/assets/js/58.659c993f.js"><link rel="prefetch" href="/docs/assets/js/59.34f9eaca.js"><link rel="prefetch" href="/docs/assets/js/6.3a6e1ed3.js"><link rel="prefetch" href="/docs/assets/js/60.2f610937.js"><link rel="prefetch" href="/docs/assets/js/61.f4e5be3d.js"><link rel="prefetch" href="/docs/assets/js/62.c1df51fe.js"><link rel="prefetch" href="/docs/assets/js/63.0486448b.js"><link rel="prefetch" href="/docs/assets/js/64.1b7300e4.js"><link rel="prefetch" href="/docs/assets/js/65.624d0a0a.js"><link rel="prefetch" href="/docs/assets/js/66.7fe4797b.js"><link rel="prefetch" href="/docs/assets/js/67.925c35aa.js"><link rel="prefetch" href="/docs/assets/js/68.31c90117.js"><link rel="prefetch" href="/docs/assets/js/69.5f040bea.js"><link rel="prefetch" href="/docs/assets/js/7.b99a3113.js"><link rel="prefetch" href="/docs/assets/js/70.6f1ee486.js"><link rel="prefetch" href="/docs/assets/js/71.cbc449e7.js"><link rel="prefetch" href="/docs/assets/js/72.e0d79003.js"><link rel="prefetch" href="/docs/assets/js/73.ca348e41.js"><link rel="prefetch" href="/docs/assets/js/74.0f693fad.js"><link rel="prefetch" href="/docs/assets/js/75.435fb2cb.js"><link rel="prefetch" href="/docs/assets/js/76.05d616a1.js"><link rel="prefetch" href="/docs/assets/js/77.9cf43035.js"><link rel="prefetch" href="/docs/assets/js/78.1139cca5.js"><link rel="prefetch" href="/docs/assets/js/8.c0e09a5e.js"><link rel="prefetch" href="/docs/assets/js/80.e8ee32b0.js"><link rel="prefetch" href="/docs/assets/js/81.afcc1145.js"><link rel="prefetch" href="/docs/assets/js/82.3c8f4a16.js"><link rel="prefetch" href="/docs/assets/js/83.4c69a7a0.js"><link rel="prefetch" href="/docs/assets/js/84.76c28d97.js"><link rel="prefetch" href="/docs/assets/js/85.584a0e94.js"><link rel="prefetch" href="/docs/assets/js/86.a3fa56ac.js"><link rel="prefetch" href="/docs/assets/js/87.bced23ab.js"><link rel="prefetch" href="/docs/assets/js/88.b2f8cd57.js"><link rel="prefetch" href="/docs/assets/js/89.12fa0df4.js"><link rel="prefetch" href="/docs/assets/js/9.6121e0b4.js"><link rel="prefetch" href="/docs/assets/js/90.383ffdcc.js"><link rel="prefetch" href="/docs/assets/js/91.b721141c.js"><link rel="prefetch" href="/docs/assets/js/92.7e85069f.js"><link rel="prefetch" href="/docs/assets/js/93.0d4acb59.js"><link rel="prefetch" href="/docs/assets/js/94.036e5ed0.js"><link rel="prefetch" href="/docs/assets/js/vendors~docsearch.0da9b1d4.js">
|
|
<link rel="stylesheet" href="/docs/assets/css/0.styles.2c61df29.css">
|
|
</head>
|
|
<body>
|
|
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/docs/" class="home-link router-link-active"><img src="/docs/logo.png" alt="GrapesJS" class="logo"> <span class="site-name can-hide">GrapesJS</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/docs/" class="nav-link">
|
|
Docs
|
|
</a></div><div class="nav-item"><a href="/docs/api/" class="nav-link">
|
|
API Reference
|
|
</a></div><div class="nav-item"><a href="https://opencollective.com/grapesjs" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
Support Us
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://twitter.com/grapesjs" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
Twitter
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <a href="https://github.com/artf/grapesjs" target="_blank" rel="noopener noreferrer" class="repo-link">
|
|
GitHub
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/docs/" class="nav-link">
|
|
Docs
|
|
</a></div><div class="nav-item"><a href="/docs/api/" class="nav-link">
|
|
API Reference
|
|
</a></div><div class="nav-item"><a href="https://opencollective.com/grapesjs" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
Support Us
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://twitter.com/grapesjs" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
Twitter
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <a href="https://github.com/artf/grapesjs" target="_blank" rel="noopener noreferrer" class="repo-link">
|
|
GitHub
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <div id="native-carbon" class="carbon-ads"></div> <ul class="sidebar-links"><li><a href="/docs/" aria-current="page" class="sidebar-link">Introduction</a></li><li><a href="/docs/getting-started.html" class="sidebar-link">Getting Started</a></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Modules</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/docs/modules/Components.html" class="sidebar-link">Components</a></li><li><a href="/docs/modules/Components-js.html" class="sidebar-link">Components & JS</a></li><li><a href="/docs/modules/Traits.html" class="sidebar-link">Traits</a></li><li><a href="/docs/modules/Blocks.html" class="sidebar-link">Blocks</a></li><li><a href="/docs/modules/Assets.html" class="sidebar-link">Assets</a></li><li><a href="/docs/modules/Commands.html" class="sidebar-link">Commands</a></li><li><a href="/docs/modules/I18n.html" class="sidebar-link">I18n</a></li><li><a href="/docs/modules/Selectors.html" class="sidebar-link">Selectors</a></li><li><a href="/docs/modules/Layers.html" class="sidebar-link">Layers</a></li><li><a href="/docs/modules/Pages.html" class="sidebar-link">Pages</a></li><li><a href="/docs/modules/Style-manager.html" class="sidebar-link">Style Manager</a></li><li><a href="/docs/modules/Storage.html" class="sidebar-link">Storage Manager</a></li><li><a href="/docs/modules/Modal.html" class="sidebar-link">Modal</a></li><li><a href="/docs/modules/Plugins.html" class="sidebar-link">Plugins</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>Guides</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/docs/guides/Replace-Rich-Text-Editor.html" aria-current="page" class="active sidebar-link">Replace Rich Text Editor</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/docs/guides/Replace-Rich-Text-Editor.html#interface" class="sidebar-link">Interface</a></li><li class="sidebar-sub-header"><a href="/docs/guides/Replace-Rich-Text-Editor.html#toolbar-position" class="sidebar-link">Toolbar position</a></li><li class="sidebar-sub-header"><a href="/docs/guides/Replace-Rich-Text-Editor.html#the-built-in-vs-third-party" class="sidebar-link">The built-in vs third-party</a></li><li class="sidebar-sub-header"><a href="/docs/guides/Replace-Rich-Text-Editor.html#plugins" class="sidebar-link">Plugins</a></li></ul></li><li><a href="/docs/guides/Custom-CSS-parser.html" class="sidebar-link">Use Custom CSS Parser</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="replace-the-built-in-rich-text-editor"><a href="#replace-the-built-in-rich-text-editor" class="header-anchor">#</a> Replace the built-in Rich Text Editor</h1> <p>As you might have noticed the default Rich Text Editor (RTE) is really tiny and so doesn't seem like a complete solution as a text editor. Instead of showing how to add new commands inside the default one we'll show how to completely replace it with another one.</p> <p>In the following guide we'll integrate the CKEditor and to accomplish this task we just need to provide few functions to the GrapesJS API method <code>setCustomRte</code> as an interface.</p> <div class="custom-block warning"><p class="custom-block-title">WARNING</p> <p>This guide is referring to GrapesJS v0.21.2 or higher</p></div> <p></p><div class="table-of-contents"><ul><li><a href="#interface">Interface</a><ul><li><a href="#enable">Enable</a></li><li><a href="#disable">Disable</a></li><li><a href="#content">Content</a></li><li><a href="#focus">Focus</a></li></ul></li><li><a href="#toolbar-position">Toolbar position</a></li><li><a href="#the-built-in-vs-third-party">The built-in vs third-party</a><ul><li><a href="#enable-content-parser">Enable content parser</a></li></ul></li><li><a href="#plugins">Plugins</a></li></ul></div><p></p> <h2 id="interface"><a href="#interface" class="header-anchor">#</a> Interface</h2> <h3 id="enable"><a href="#enable" class="header-anchor">#</a> Enable</h3> <p>The first step is to indicate how to enable the third-party library and so for we gonna start with the <code>enable()</code> function. This method should take care of the first initialization of our custom RTE but also for the next time is called on the same element, this is why there is the <code>rte</code> argument.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// IMPORTANT: place the code in a new plugin</span>
|
|
<span class="token keyword">const</span> <span class="token function-variable function">customRTE</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">editor</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
|
|
<span class="token keyword">const</span> <span class="token function-variable function">focus</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> rte</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
|
|
<span class="token comment">// implemented later</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
editor<span class="token punctuation">.</span><span class="token function">setCustomRte</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
|
<span class="token comment">/**
|
|
* Enabling the custom RTE
|
|
* @param {HTMLElement} el This is the HTML node which was selected to be edited
|
|
* @param {Object} rte It's the instance you'd return from the first call of enable().
|
|
* At the first call it'd be undefined. This is useful when you need
|
|
* to check if the RTE is already enabled on the component
|
|
* @return {Object} The return should be the RTE initialized instance
|
|
*/</span>
|
|
<span class="token function">enable</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> rte</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
|
<span class="token comment">// If already exists just focus</span>
|
|
<span class="token keyword">if</span> <span class="token punctuation">(</span>rte<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
|
<span class="token function">focus</span><span class="token punctuation">(</span>el<span class="token punctuation">,</span> rte<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token keyword">return</span> rte<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token comment">// CKEditor initialization</span>
|
|
rte <span class="token operator">=</span> <span class="token constant">CKEDITOR</span><span class="token punctuation">.</span><span class="token function">inline</span><span class="token punctuation">(</span>el<span class="token punctuation">,</span> <span class="token punctuation">{</span>
|
|
<span class="token comment">// Your configurations...</span>
|
|
<span class="token literal-property property">toolbar</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token operator">...</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
|
|
<span class="token comment">// IMPORTANT</span>
|
|
<span class="token comment">// Generally, inline editors are attached exactly at the same position of</span>
|
|
<span class="token comment">// the selected element but in this case it'd work until you start to scroll</span>
|
|
<span class="token comment">// the canvas. For this reason you have to move the RTE's toolbar inside the</span>
|
|
<span class="token comment">// one from GrapesJS. For this purpose we used a plugin which simplify</span>
|
|
<span class="token comment">// this process and move all next CKEditor's toolbars inside our indicated</span>
|
|
<span class="token comment">// element</span>
|
|
<span class="token literal-property property">sharedSpaces</span><span class="token operator">:</span> <span class="token punctuation">{</span>
|
|
<span class="token literal-property property">top</span><span class="token operator">:</span> editor<span class="token punctuation">.</span>RichTextEditor<span class="token punctuation">.</span><span class="token function">getToolbarEl</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
|
|
<span class="token function">focus</span><span class="token punctuation">(</span>el<span class="token punctuation">,</span> rte<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token keyword">return</span> rte<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
<span class="token keyword">const</span> editor <span class="token operator">=</span> grapesjs<span class="token punctuation">.</span><span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
|
<span class="token operator">...</span>
|
|
<span class="token literal-property property">plugins</span><span class="token operator">:</span> <span class="token punctuation">[</span>customRTE<span class="token punctuation">]</span><span class="token punctuation">,</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
</code></pre></div><h3 id="disable"><a href="#disable" class="header-anchor">#</a> Disable</h3> <p>Once we know how to enable the RTE let's implement the method which disable it, so let's create the <code>disable()</code> function.</p> <div class="language-js extra-class"><pre class="language-js"><code>editor<span class="token punctuation">.</span><span class="token function">setCustomRte</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
|
<span class="token comment">// ...</span>
|
|
<span class="token comment">/**
|
|
* The signature of the function is the same of the `enable`
|
|
*/</span>
|
|
<span class="token function">disable</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> rte</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
|
el<span class="token punctuation">.</span>contentEditable <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
|
|
rte<span class="token operator">?.</span>focusManager<span class="token operator">?.</span><span class="token function">blur</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
</code></pre></div><h3 id="content"><a href="#content" class="header-anchor">#</a> Content</h3> <p>Each third-party library could handle the state of the content differently and what is actually rendered as a DOM in the preview might not rapresent the final HTML output. So, by default, GrapesJS takes the <code>innerHTML</code> as the final output directly from the DOM element but is highly recommended to specify the method responsable to return the final state as HTML string (each third-party library might handle it differently).</p> <div class="language-js extra-class"><pre class="language-js"><code>editor<span class="token punctuation">.</span><span class="token function">setCustomRte</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
|
<span class="token comment">// ...</span>
|
|
<span class="token function">getContent</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> rte</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
|
<span class="token keyword">const</span> htmlString <span class="token operator">=</span> rte<span class="token punctuation">.</span><span class="token function">getData</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token keyword">return</span> htmlString<span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
</code></pre></div><h3 id="focus"><a href="#focus" class="header-anchor">#</a> Focus</h3> <p>The <code>focus()</code> method is just a helper used inside <code>enable()</code> and not required by the interface</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token function-variable function">focus</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> rte</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
|
|
<span class="token comment">// Do nothing if already focused</span>
|
|
<span class="token keyword">if</span> <span class="token punctuation">(</span>rte<span class="token operator">?.</span>focusManager<span class="token operator">?.</span>hasFocus<span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
|
<span class="token keyword">return</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
el<span class="token punctuation">.</span>contentEditable <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
|
|
rte<span class="token operator">?.</span><span class="token function">focus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
|
|
editor<span class="token punctuation">.</span><span class="token function">setCustomRte</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
|
<span class="token comment">// ...</span>
|
|
<span class="token function">enable</span><span class="token punctuation">(</span><span class="token parameter">el<span class="token punctuation">,</span> rte</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
|
|
<span class="token comment">// ...</span>
|
|
<span class="token function">focus</span><span class="token punctuation">(</span>el<span class="token punctuation">,</span> rte<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token comment">// ...</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
</code></pre></div><h2 id="toolbar-position"><a href="#toolbar-position" class="header-anchor">#</a> Toolbar position</h2> <p>Sometimes the default top-left position of the toolbar is not always what you need. For example, when you scroll the canvas and the toolbar reaches the top, you'd like to move it down. For this purpose, you can add a listener which applies your logic in this way:</p> <div class="language-js extra-class"><pre class="language-js"><code>editor<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'rteToolbarPosUpdate'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">pos</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
|
|
<span class="token comment">// eg. update `pos.top` and `pos.left` based on additional data passed inside `pos`</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
</code></pre></div><h2 id="the-built-in-vs-third-party"><a href="#the-built-in-vs-third-party" class="header-anchor">#</a> The built-in vs third-party</h2> <p>One thing you have to keep in mind when using a custom RTE is that all the content and its behavior are handled by the library itself, the GrapesJS's component will just store the content as it is.
|
|
For example, when you create a link using the built-in RTE then you'll be able to select it and edit its <code>href</code> via Component Settings. With a custom RTE, it will be its own task to show the proper modal for the link editing.
|
|
Obviously, each third-party library has its own APIs and can present some limitations and drawbacks, so, a minimal knowledge of the library is a plus.</p> <h3 id="enable-content-parser"><a href="#enable-content-parser" class="header-anchor">#</a> Enable content parser</h3> <p>As an experimental feature, now it's possible to tell the editor to parse the returned HTML content from the custom RTE and store the result as components and not as a simple HTML string. This allows GrapesJS to handle the custom RTE more closely to the native implementation and enable features like <a href="https://github.com/GrapesJS/grapesjs/issues/2771#issuecomment-1040486056" target="_blank" rel="noopener noreferrer">textable components<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.</p> <div class="language-js extra-class"><pre class="language-js"><code>editor<span class="token punctuation">.</span><span class="token function">setCustomRte</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
|
|
<span class="token comment">// ...</span>
|
|
<span class="token comment">// Enable content parser</span>
|
|
<span class="token literal-property property">parseContent</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
</code></pre></div><h2 id="plugins"><a href="#plugins" class="header-anchor">#</a> Plugins</h2> <p>For the CKEditor, you can find a complete plugin here <a href="https://github.com/GrapesJS/ckeditor" target="_blank" rel="noopener noreferrer">grapesjs-plugin-ckeditor<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.</p></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/artf/grapesjs/edit/dev/docs/guides/Replace-Rich-Text-Editor.md" target="_blank" rel="noopener noreferrer">Edit this page on GitHub</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <div class="last-updated"><span class="prefix">Last Updated:</span> <span class="time">5/30/2023, 3:01:36 PM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
|
|
←
|
|
<a href="/docs/modules/Plugins.html" class="prev">
|
|
Plugins
|
|
</a></span> <span class="next"><a href="/docs/guides/Custom-CSS-parser.html">
|
|
Use Custom CSS Parser
|
|
</a>
|
|
→
|
|
</span></p></div> </main></div><div class="global-ui"></div></div>
|
|
<script src="/docs/assets/js/app.424ab1f7.js" defer></script><script src="/docs/assets/js/4.0070552e.js" defer></script><script src="/docs/assets/js/2.6fefd022.js" defer></script><script src="/docs/assets/js/1.d23e9fed.js" defer></script><script src="/docs/assets/js/79.4581c86c.js" defer></script>
|
|
</body>
|
|
</html>
|
|
|