@@ -65,6 +65,60 @@ type State = {
65
65
66
66
let didInitODS = false ;
67
67
68
+ class UpdateEditorState extends React . Component < {
69
+ editor : DraftEditor ,
70
+ editorState : EditorState ,
71
+ } > {
72
+ render ( ) {
73
+ return null ;
74
+ }
75
+ componentDidMount ( ) {
76
+ this . _update ( ) ;
77
+ }
78
+ componentDidUpdate ( ) {
79
+ this . _update ( ) ;
80
+ }
81
+ _update ( ) {
82
+ if ( gkx ( 'draft_js_remove_componentwillupdate' ) ) {
83
+ /**
84
+ * Sometimes a render triggers a 'focus' or other event, and that will
85
+ * schedule a second render pass.
86
+ * In order to make sure the second render pass gets the latest editor
87
+ * state, we update it here.
88
+ * Example:
89
+ * render #1
90
+ * +
91
+ * |
92
+ * | cWU -> Nothing ... latestEditorState = STALE_STATE :(
93
+ * |
94
+ * | render -> this.props.editorState = FRESH_STATE
95
+ * | + *and* set latestEditorState = FRESH_STATE
96
+ * |
97
+ * | |
98
+ * | +--> triggers 'focus' event, calling 'handleFocus' with latestEditorState
99
+ * | +
100
+ * | |
101
+ * +>cdU -> latestEditorState = FRESH_STATE | the 'handleFocus' call schedules render #2
102
+ * | with latestEditorState, which is FRESH_STATE
103
+ * |
104
+ * render #2 <--------------------------------------+
105
+ * +
106
+ * |
107
+ * | cwU -> nothing updates
108
+ * |
109
+ * | render -> this.props.editorState = FRESH_STATE which was passed in above
110
+ * |
111
+ * +>cdU fires and resets latestEditorState = FRESH_STATE
112
+ * ---
113
+ * Note that if we don't set latestEditorState in 'render' in the above
114
+ * diagram, then STALE_STATE gets passed to render #2.
115
+ */
116
+ const editor = this . props . editor ;
117
+ editor . _latestEditorState = this . props . editorState ;
118
+ }
119
+ }
120
+ }
121
+
68
122
/**
69
123
* `DraftEditor` is the root editor component. It composes a `contentEditable`
70
124
* div, and provides a wide variety of useful function props for managing the
@@ -237,43 +291,6 @@ class DraftEditor extends React.Component<DraftEditorProps, State> {
237
291
}
238
292
239
293
render ( ) : React . Node {
240
- if ( gkx ( 'draft_js_remove_componentwillupdate' ) ) {
241
- /**
242
- * Sometimes a render triggers a 'focus' or other event, and that will
243
- * schedule a second render pass.
244
- * In order to make sure the second render pass gets the latest editor
245
- * state, we update it here.
246
- * Example:
247
- * render #1
248
- * +
249
- * |
250
- * | cWU -> Nothing ... latestEditorState = STALE_STATE :(
251
- * |
252
- * | render -> this.props.editorState = FRESH_STATE
253
- * | + *and* set latestEditorState = FRESH_STATE
254
- * |
255
- * | |
256
- * | +--> triggers 'focus' event, calling 'handleFocus' with latestEditorState
257
- * | +
258
- * | |
259
- * +>cdU -> latestEditorState = FRESH_STATE | the 'handleFocus' call schedules render #2
260
- * | with latestEditorState, which is FRESH_STATE
261
- * |
262
- * render #2 <--------------------------------------+
263
- * +
264
- * |
265
- * | cwU -> nothing updates
266
- * |
267
- * | render -> this.props.editorState = FRESH_STATE which was passed in above
268
- * |
269
- * +>cdU fires and resets latestEditorState = FRESH_STATE
270
- * ---
271
- * Note that if we don't set latestEditorState in 'render' in the above
272
- * diagram, then STALE_STATE gets passed to render #2.
273
- */
274
-
275
- this . _latestEditorState = this . props . editorState ;
276
- }
277
294
const {
278
295
blockRenderMap,
279
296
blockRendererFn,
@@ -381,6 +398,11 @@ class DraftEditor extends React.Component<DraftEditorProps, State> {
381
398
style = { contentStyle }
382
399
suppressContentEditableWarning
383
400
tabIndex = { this . props . tabIndex } >
401
+ { /*
402
+ Needs to come earlier in the tree as a sibling (not ancestor) of
403
+ all DraftEditorLeaf nodes so it's first in postorder traversal.
404
+ */ }
405
+ < UpdateEditorState editor = { this } editorState = { editorState } />
384
406
< DraftEditorContents { ...editorContentsProps } />
385
407
</ div >
386
408
</ div >
0 commit comments