Skip to content

Instantly share code, notes, and snippets.

@erika-dike
Last active June 15, 2019 20:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erika-dike/06a97032fa87188ca86a615c274f409e to your computer and use it in GitHub Desktop.
Save erika-dike/06a97032fa87188ca86a615c274f409e to your computer and use it in GitHub Desktop.
const { Component } = wp.element;
import { __, _x } from '@wordpress/i18n';
const { BACKSPACE, DELETE, F10 } = wp.keycodes;
function isTmceEmpty(editor) {
// When tinyMce is empty the content seems to be:
// <p><br data-mce-bogus="1"></p>
// avoid expensive checks for large documents
const body = editor.getBody();
if (body.childNodes.length > 1) {
return false;
} else if (body.childNodes.length === 0) {
return true;
}
if (body.childNodes[0].childNodes.length > 1) {
return false;
}
return /^\n?$/.test(body.innerText || body.textContent);
}
export class ClassicEditor extends Component {
constructor(props) {
super(props);
this.initialize = this.initialize.bind(this);
this.onSetup = this.onSetup.bind(this);
this.focus = this.focus.bind(this);
}
componentDidMount() {
const { baseURL, suffix } = window.wpEditorL10n.tinymce;
window.tinymce.EditorManager.overrideDefaults({
base_url: baseURL,
suffix,
});
if (document.readyState === 'complete') {
this.initialize();
} else {
window.addEventListener('DOMContentLoaded', this.initialize);
}
}
componentWillUnmount() {
window.addEventListener('DOMContentLoaded', this.initialize);
wp.oldEditor.remove(`editor-${this.props.clientId}`);
}
componentDidUpdate(prevProps) {
const { clientId, attributes: { content } } = this.props;
let editor = window.tinymce.get(`editor-${clientId}`);
editor.setContent(content || '');
}
initialize() {
const { clientId } = this.props;
const { settings } = window.wpEditorL10n.tinymce;
wp.oldEditor.initialize(`editor-${clientId}`, {
tinymce: {
...settings,
inline: true,
content_css: false,
fixed_toolbar_container: `#toolbar-${clientId}`,
setup: this.onSetup,
},
});
}
onSetup(editor) {
const { attributes: { content } } = this.props;
let bookmark;
this.editor = editor;
if (content) {
editor.on('loadContent', () => editor.setContent(content));
}
editor.on('blur', () => {
const { setAttributes } = this.props;
bookmark = editor.selection.getBookmark(2, true);
setAttributes({ content: editor.getContent() });
editor.once('focus', () => {
if (bookmark) {
editor.selection.moveToBookmark(bookmark);
}
});
return false;
});
editor.on('mousedown touchstart', () => {
bookmark = null;
});
editor.on('keydown', (event) => {
if ((event.keyCode === BACKSPACE || event.keyCode === DELETE) && isTmceEmpty(editor)) {
// delete the block
this.props.onReplace([]);
event.preventDefault();
event.stopImmediatePropagation();
}
const { altKey } = event;
/*
* Prevent Mousetrap from kicking in: TinyMCE already uses its own
* `alt+f10` shortcut to focus its toolbar.
*/
if (altKey && event.keyCode === F10) {
event.stopPropagation();
}
});
editor.on('init', () => {
const rootNode = this.editor.getBody();
// Create the toolbar by refocussing the editor.
if (document.activeElement === rootNode) {
rootNode.blur();
this.editor.focus();
}
});
}
focus() {
if (this.editor) {
this.editor.focus();
}
}
onToolbarKeyDown(event) {
// Prevent WritingFlow from kicking in and allow arrows navigation on the toolbar.
event.stopPropagation();
// Prevent Mousetrap from moving focus to the top toolbar when pressing `alt+f10` on this block toolbar.
event.nativeEvent.stopImmediatePropagation();
}
render() {
const { clientId } = this.props;
// Disable reasons:
//
// jsx-a11y/no-static-element-interactions
// - the toolbar itself is non-interactive, but must capture events
// from the KeyboardShortcuts component to stop their propagation.
//
// jsx-a11y/no-static-element-interactions
// - Clicking on this visual placeholder should create the
// toolbar, it can also be created by focussing the field below.
/* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
return [
<div
key="toolbar"
id={`toolbar-${clientId}`}
ref={(ref) => this.ref = ref}
className="block-library-classic__toolbar"
onClick={this.focus}
data-placeholder={__('Classic')}
onKeyDown={this.onToolbarKeyDown}
/>,
<div
key="editor"
id={`editor-${clientId}`}
className="wp-block-freeform block-library-rich-text__tinymce"
/>,
];
/* eslint-enable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment