1 |
|
2 |
|
3 |
|
4 | import { Component } from '@wordpress/element';
|
5 | import { __, _x } from '@wordpress/i18n';
|
6 | import { BACKSPACE, DELETE, F10 } from '@wordpress/keycodes';
|
7 |
|
8 | const { wp } = window;
|
9 |
|
10 | function isTmceEmpty( editor ) {
|
11 |
|
12 |
|
13 |
|
14 | const body = editor.getBody();
|
15 | if ( body.childNodes.length > 1 ) {
|
16 | return false;
|
17 | } else if ( body.childNodes.length === 0 ) {
|
18 | return true;
|
19 | }
|
20 | if ( body.childNodes[ 0 ].childNodes.length > 1 ) {
|
21 | return false;
|
22 | }
|
23 | return /^\n?$/.test( body.innerText || body.textContent );
|
24 | }
|
25 |
|
26 | export default class ClassicEdit extends Component {
|
27 | constructor( props ) {
|
28 | super( props );
|
29 | this.initialize = this.initialize.bind( this );
|
30 | this.onSetup = this.onSetup.bind( this );
|
31 | this.focus = this.focus.bind( this );
|
32 | }
|
33 |
|
34 | componentDidMount() {
|
35 | const { baseURL, suffix } = window.wpEditorL10n.tinymce;
|
36 |
|
37 | window.tinymce.EditorManager.overrideDefaults( {
|
38 | base_url: baseURL,
|
39 | suffix,
|
40 | } );
|
41 |
|
42 | if ( document.readyState === 'complete' ) {
|
43 | this.initialize();
|
44 | } else {
|
45 | window.addEventListener( 'DOMContentLoaded', this.initialize );
|
46 | }
|
47 | }
|
48 |
|
49 | componentWillUnmount() {
|
50 | window.addEventListener( 'DOMContentLoaded', this.initialize );
|
51 | wp.oldEditor.remove( `editor-${ this.props.clientId }` );
|
52 | }
|
53 |
|
54 | componentDidUpdate( prevProps ) {
|
55 | const { clientId, attributes: { content } } = this.props;
|
56 |
|
57 | const editor = window.tinymce.get( `editor-${ clientId }` );
|
58 |
|
59 | if ( prevProps.attributes.content !== content ) {
|
60 | editor.setContent( content || '' );
|
61 | }
|
62 | }
|
63 |
|
64 | initialize() {
|
65 | const { clientId } = this.props;
|
66 | const { settings } = window.wpEditorL10n.tinymce;
|
67 | wp.oldEditor.initialize( `editor-${ clientId }`, {
|
68 | tinymce: {
|
69 | ...settings,
|
70 | inline: true,
|
71 | content_css: false,
|
72 | fixed_toolbar_container: `#toolbar-${ clientId }`,
|
73 | setup: this.onSetup,
|
74 | },
|
75 | } );
|
76 | }
|
77 |
|
78 | onSetup( editor ) {
|
79 | const { attributes: { content }, setAttributes } = this.props;
|
80 | const { ref } = this;
|
81 | let bookmark;
|
82 |
|
83 | this.editor = editor;
|
84 |
|
85 | if ( content ) {
|
86 | editor.on( 'loadContent', () => editor.setContent( content ) );
|
87 | }
|
88 |
|
89 | editor.on( 'blur', () => {
|
90 | bookmark = editor.selection.getBookmark( 2, true );
|
91 |
|
92 | setAttributes( {
|
93 | content: editor.getContent(),
|
94 | } );
|
95 |
|
96 | editor.once( 'focus', () => {
|
97 | if ( bookmark ) {
|
98 | editor.selection.moveToBookmark( bookmark );
|
99 | }
|
100 | } );
|
101 |
|
102 | return false;
|
103 | } );
|
104 |
|
105 | editor.on( 'mousedown touchstart', () => {
|
106 | bookmark = null;
|
107 | } );
|
108 |
|
109 | editor.on( 'keydown', ( event ) => {
|
110 | if ( ( event.keyCode === BACKSPACE || event.keyCode === DELETE ) && isTmceEmpty( editor ) ) {
|
111 |
|
112 | this.props.onReplace( [] );
|
113 | event.preventDefault();
|
114 | event.stopImmediatePropagation();
|
115 | }
|
116 |
|
117 | const { altKey } = event;
|
118 | |
119 |
|
120 |
|
121 |
|
122 | if ( altKey && event.keyCode === F10 ) {
|
123 | event.stopPropagation();
|
124 | }
|
125 | } );
|
126 |
|
127 |
|
128 | editor.addButton( 'kitchensink', {
|
129 | tooltip: _x( 'More', 'button to expand options' ),
|
130 | icon: 'dashicon dashicons-editor-kitchensink',
|
131 | onClick() {
|
132 | const button = this;
|
133 | const active = ! button.active();
|
134 |
|
135 | button.active( active );
|
136 | editor.dom.toggleClass( ref, 'has-advanced-toolbar', active );
|
137 | },
|
138 | } );
|
139 |
|
140 |
|
141 | editor.on( 'init', function() {
|
142 | if ( editor.settings.toolbar1 && editor.settings.toolbar1.indexOf( 'kitchensink' ) === -1 ) {
|
143 | editor.dom.addClass( ref, 'has-advanced-toolbar' );
|
144 | }
|
145 | } );
|
146 |
|
147 | editor.addButton( 'wp_add_media', {
|
148 | tooltip: __( 'Insert Media' ),
|
149 | icon: 'dashicon dashicons-admin-media',
|
150 | cmd: 'WP_Medialib',
|
151 | } );
|
152 |
|
153 |
|
154 | editor.on( 'init', () => {
|
155 | const rootNode = this.editor.getBody();
|
156 |
|
157 |
|
158 | if ( document.activeElement === rootNode ) {
|
159 | rootNode.blur();
|
160 | this.editor.focus();
|
161 | }
|
162 | } );
|
163 | }
|
164 |
|
165 | focus() {
|
166 | if ( this.editor ) {
|
167 | this.editor.focus();
|
168 | }
|
169 | }
|
170 |
|
171 | onToolbarKeyDown( event ) {
|
172 |
|
173 | event.stopPropagation();
|
174 |
|
175 | event.nativeEvent.stopImmediatePropagation();
|
176 | }
|
177 |
|
178 | render() {
|
179 | const { clientId } = this.props;
|
180 |
|
181 |
|
182 |
|
183 |
|
184 | return [
|
185 |
|
186 |
|
187 |
|
188 | <div
|
189 | key="toolbar"
|
190 | id={ `toolbar-${ clientId }` }
|
191 | ref={ ( ref ) => this.ref = ref }
|
192 | className="block-library-classic__toolbar"
|
193 | onClick={ this.focus }
|
194 | data-placeholder={ __( 'Classic' ) }
|
195 | onKeyDown={ this.onToolbarKeyDown }
|
196 | />,
|
197 | <div
|
198 | key="editor"
|
199 | id={ `editor-${ clientId }` }
|
200 | className="wp-block-freeform block-library-rich-text__tinymce"
|
201 | />,
|
202 | ];
|
203 |
|
204 | }
|
205 | }
|