From d7c9bb7f8aac5eabafcf7f7331867f82b9944bd7 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Mon, 27 Mar 2017 11:36:13 +0100 Subject: [PATCH] TinyMCE: V1 of the Editable Component initializing TinyMCE --- .eslintrc.json | 3 +- blocks/components/editable/index.js | 95 ++++++++++++++++++++++++++++- editor/blocks/text-block/index.js | 4 +- element/index.js | 7 ++- index.php | 3 +- 5 files changed, 105 insertions(+), 7 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 902f6cb6acbbb..2cb6635e3c133 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -18,7 +18,8 @@ } }, "globals": { - "wp": true + "wp": true, + "tinymce": true }, "plugins": [ "react", diff --git a/blocks/components/editable/index.js b/blocks/components/editable/index.js index 59fe33dcba1d7..cfd7b04471e00 100644 --- a/blocks/components/editable/index.js +++ b/blocks/components/editable/index.js @@ -1,3 +1,94 @@ -export default function Editable( { value } ) { - return

{ value }

; +let editorInstance = 1; + +export default class Editable extends wp.element.Component { + constructor( ...args ) { + super( ...args ); + this.onInit = this.onInit.bind( this ); + this.onSetup = this.onSetup.bind( this ); + this.onChange = this.onChange.bind( this ); + this.onFocusIn = this.onFocusIn.bind( this ); + this.onFocusOut = this.onFocusOut.bind( this ); + this.id = `tinymce-instance-${ editorInstance }`; + editorInstance++; + } + + componentDidMount() { + this.initialize(); + if ( this.props.focusConfig ) { + this.focus(); + } + } + + initialize() { + const config = { + mode: 'exact', + elements: this.id, + theme: false, + inline: true, + toolbar: false, + entity_encoding: 'raw', + setup: this.onSetup, + formats: { + strikethrough: { inline: 'del' } + } + }; + + tinymce.init( config ); + } + + onSetup( editor ) { + this.editor = editor; + editor.on( 'init', this.onInit ); + editor.on( 'focusIn', this.onFocusIn ); + editor.on( 'focusout', this.onFocusOut ); + } + + onInit() { + this.editor.setContent( this.props.value ); + } + + onChange() { + const value = this.editor.getContent(); + if ( value === this.props.value ) { + return; + } + + this.props.onChange( value ); + } + + onFocusIn() { + this.isFocused = true; + } + + onFocusOut() { + this.isFocused = false; + this.onChange(); + } + + updateContent() { + let bookmark; + if ( this.isFocused ) { + bookmark = this.editor.selection.getBookmark( 2, true ); + } + this.editor.setContent( this.props.value ); + if ( this.isFocused ) { + this.editor.selection.moveToBookmark( bookmark ); + } + } + + componentWillUnmount() { + if ( this.editor ) { + this.editor.destroy(); + } + } + + componentDidUpdate( prevProps ) { + if ( this.props.value !== prevProps.value ) { + this.updateContent( !! prevProps.focusConfig ); + } + } + + render() { + return
; + } } diff --git a/editor/blocks/text-block/index.js b/editor/blocks/text-block/index.js index 45f5ee45d722f..812f67ec73f9a 100644 --- a/editor/blocks/text-block/index.js +++ b/editor/blocks/text-block/index.js @@ -1,4 +1,4 @@ -const { query, html } = wp.blocks.query; +const { html } = wp.blocks.query; const Editable = wp.blocks.Editable; wp.blocks.registerBlock( 'core/text', { @@ -6,7 +6,7 @@ wp.blocks.registerBlock( 'core/text', { icon: 'text', attributes: { - value: query( 'p', html() ) + value: html() }, edit( attributes, onChange ) { diff --git a/element/index.js b/element/index.js index 3be0186c4c297..c6734e11eb2f1 100644 --- a/element/index.js +++ b/element/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { createElement as reactCreateElement } from 'react'; +import { createElement as reactCreateElement, Component as ReactComponent } from 'react'; import { render as reactRender } from 'react-dom'; /** @@ -28,3 +28,8 @@ export function createElement( type, props, ...children ) { export function render( element, target ) { reactRender( element, target ); } + +/** + * A base class to create WordPress Components (Refs, state and lifecycle hooks) + */ +export const Component = ReactComponent; diff --git a/index.php b/index.php index 8e62cf3f3db0f..e8565ee2050df 100644 --- a/index.php +++ b/index.php @@ -40,8 +40,9 @@ function gutenberg_register_scripts() { wp_register_script( 'react-dom', 'https://unpkg.com/react-dom@15/dist/react-dom' . $suffix . '.js', array( 'react' ) ); // Editor + wp_register_script( 'tinymce_js', includes_url( 'js/tinymce/' ) . 'wp-tinymce.php', array( 'jquery' ) ); wp_register_script( 'wp-element', plugins_url( 'element/build/index.js', __FILE__ ), array( 'react', 'react-dom' ) ); - wp_register_script( 'wp-blocks', plugins_url( 'blocks/build/index.js', __FILE__ ), array( 'wp-element' ) ); + wp_register_script( 'wp-blocks', plugins_url( 'blocks/build/index.js', __FILE__ ), array( 'wp-element', 'tinymce_js' ) ); } add_action( 'init', 'gutenberg_register_scripts' );