Skip to content

Commit 3d223d5

Browse files
Claudio ProcidaVilém Jeniš
authored andcommitted
Take over enhancements to render Draft.js in an iframe (facebookarchive#1938)
Summary: **Summary** Takes over and applies requested PR feedback to facebookarchive#1877 by haikyuu. Refer to original PR for context and discussion. **Test Plan** Run some manual smoke tests on the editor running in an iframe as follows: ``` yarn python3 -m http.server 8080 . open http://localhost:8080/examples/draft-0-10-0/iframe/iframe.html ``` Pull Request resolved: facebookarchive#1938 Reviewed By: claudiopro Differential Revision: D13137413 Pulled By: jack-arms fbshipit-source-id: efcdbabc7d8d2aff4fbebc8b06c22d57756ebc12
1 parent ee48b11 commit 3d223d5

35 files changed

+358
-107
lines changed

meta/bundle-size-stats/Draft.js.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

meta/bundle-size-stats/Draft.min.js.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

src/component/base/DraftEditor.react.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const getDefaultKeyBinding = require('getDefaultKeyBinding');
3838
const getScrollPosition = require('getScrollPosition');
3939
const gkx = require('gkx');
4040
const invariant = require('invariant');
41+
const isHTMLElement = require('isHTMLElement');
4142
const nullthrows = require('nullthrows');
4243

4344
const isIE = UserAgent.isBrowser('IE');
@@ -457,7 +458,13 @@ class DraftEditor extends React.Component<DraftEditorProps, State> {
457458
* ie9-beta-minor-change-list.aspx
458459
*/
459460
if (isIE) {
460-
document.execCommand('AutoUrlDetect', false, false);
461+
// editor can be null after mounting
462+
// https://stackoverflow.com/questions/44074747/componentdidmount-called-before-ref-callback
463+
if (!this.editor) {
464+
global.execCommand('AutoUrlDetect', false, false);
465+
} else {
466+
this.editor.ownerDocument.execCommand('AutoUrlDetect', false, false);
467+
}
461468
}
462469
}
463470

@@ -492,10 +499,7 @@ class DraftEditor extends React.Component<DraftEditorProps, State> {
492499
const scrollParent = Style.getScrollParent(editorNode);
493500
const {x, y} = scrollPosition || getScrollPosition(scrollParent);
494501

495-
invariant(
496-
editorNode instanceof HTMLElement,
497-
'editorNode is not an HTMLElement',
498-
);
502+
invariant(isHTMLElement(editorNode), 'editorNode is not an HTMLElement');
499503

500504
editorNode.focus();
501505

@@ -519,10 +523,10 @@ class DraftEditor extends React.Component<DraftEditorProps, State> {
519523

520524
blur: () => void = (): void => {
521525
const editorNode = this.editor;
522-
invariant(
523-
editorNode instanceof HTMLElement,
524-
'editorNode is not an HTMLElement',
525-
);
526+
if (!editorNode) {
527+
return;
528+
}
529+
invariant(isHTMLElement(editorNode), 'editorNode is not an HTMLElement');
526530
editorNode.blur();
527531
};
528532

src/component/contents/DraftEditorBlock.react.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const getElementPosition = require('getElementPosition');
3333
const getScrollPosition = require('getScrollPosition');
3434
const getViewportDimensions = require('getViewportDimensions');
3535
const invariant = require('invariant');
36+
const isHTMLElement = require('isHTMLElement');
3637
const nullthrows = require('nullthrows');
3738

3839
const SCROLL_BUFFER = 10;
@@ -121,10 +122,7 @@ class DraftEditorBlock extends React.Component<Props> {
121122
);
122123
}
123124
} else {
124-
invariant(
125-
blockNode instanceof HTMLElement,
126-
'blockNode is not an HTMLElement',
127-
);
125+
invariant(isHTMLElement(blockNode), 'blockNode is not an HTMLElement');
128126
const blockBottom = blockNode.offsetHeight + blockNode.offsetTop;
129127
const pOffset = scrollParent.offsetTop + scrollParent.offsetHeight;
130128
const scrollBottom = pOffset + scrollPosition.y;

src/component/contents/DraftEditorTextNode.react.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* LICENSE file in the root directory of this source tree.
66
*
77
* @format
8-
* @flow strict-local
8+
* @flow
99
* @emails oncall+draft_js
1010
*/
1111

@@ -15,6 +15,7 @@ const React = require('React');
1515
const UserAgent = require('UserAgent');
1616

1717
const invariant = require('invariant');
18+
const isElement = require('isElement');
1819

1920
// In IE, spans with <br> tags render as two newlines. By rendering a span
2021
// with only a newline character, we can be sure to render a single line.
@@ -81,11 +82,13 @@ class DraftEditorTextNode extends React.Component<Props> {
8182
shouldComponentUpdate(nextProps: Props): boolean {
8283
const node = this._node;
8384
const shouldBeNewline = nextProps.children === '';
84-
invariant(node instanceof Element, 'node is not an Element');
85+
86+
invariant(isElement(node), 'node is not an Element');
87+
const elementNode: Element = (node: any);
8588
if (shouldBeNewline) {
86-
return !isNewline(node);
89+
return !isNewline(elementNode);
8790
}
88-
return node.textContent !== nextProps.children;
91+
return elementNode.textContent !== nextProps.children;
8992
}
9093

9194
componentDidMount(): void {

src/component/contents/exploration/DraftEditorBlockNode.react.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const getScrollPosition = require('getScrollPosition');
3737
const getViewportDimensions = require('getViewportDimensions');
3838
const Immutable = require('immutable');
3939
const invariant = require('invariant');
40+
const isHTMLElement = require('isHTMLElement');
4041

4142
const SCROLL_BUFFER = 10;
4243

@@ -251,11 +252,9 @@ class DraftEditorBlockNode extends React.Component<Props> {
251252
);
252253
}
253254
} else {
254-
invariant(
255-
blockNode instanceof HTMLElement,
256-
'blockNode is not an HTMLElement',
257-
);
258-
const blockBottom = blockNode.offsetHeight + blockNode.offsetTop;
255+
invariant(isHTMLElement(blockNode), 'blockNode is not an HTMLElement');
256+
const htmlBlockNode: HTMLElement = (blockNode: any);
257+
const blockBottom = htmlBlockNode.offsetHeight + htmlBlockNode.offsetTop;
259258
const scrollBottom = scrollParent.offsetHeight + scrollPosition.y;
260259
scrollDelta = blockBottom - scrollBottom;
261260
if (scrollDelta > 0) {

src/component/handlers/composition/DOMObserver.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
const UserAgent = require('UserAgent');
1515

1616
const findAncestorOffsetKey = require('findAncestorOffsetKey');
17+
const getWindowForNode = require('getWindowForNode');
1718
const Immutable = require('immutable');
1819
const invariant = require('invariant');
1920
const nullthrows = require('nullthrows');
@@ -45,8 +46,9 @@ class DOMObserver {
4546
constructor(container: HTMLElement) {
4647
this.container = container;
4748
this.mutations = Map();
48-
if (window.MutationObserver && !USE_CHAR_DATA) {
49-
this.observer = new window.MutationObserver(mutations =>
49+
const containerWindow = getWindowForNode(container);
50+
if (containerWindow.MutationObserver && !USE_CHAR_DATA) {
51+
this.observer = new containerWindow.MutationObserver(mutations =>
5052
this.registerMutations(mutations),
5153
);
5254
} else {

src/component/handlers/drag/DraftEditorDragHandler.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const ReactDOM = require('ReactDOM');
2222
const findAncestorOffsetKey = require('findAncestorOffsetKey');
2323
const getTextContentFromFiles = require('getTextContentFromFiles');
2424
const getUpdatedSelectionState = require('getUpdatedSelectionState');
25+
const getWindowForNode = require('getWindowForNode');
2526
const isEventHandled = require('isEventHandled');
2627
const nullthrows = require('nullthrows');
2728

@@ -38,8 +39,10 @@ function getSelectionForEvent(
3839
/* $FlowFixMe(>=0.68.0 site=www,mobile) This comment suppresses an error
3940
* found when Flow v0.68 was deployed. To see the error delete this comment
4041
* and run Flow. */
41-
if (typeof document.caretRangeFromPoint === 'function') {
42-
const dropRange = document.caretRangeFromPoint(event.x, event.y);
42+
const {ownerDocument} = event.currentTarget;
43+
44+
if (typeof ownerDocument.caretRangeFromPoint === 'function') {
45+
const dropRange = ownerDocument.caretRangeFromPoint(event.x, event.y);
4346
node = dropRange.startContainer;
4447
offset = dropRange.startOffset;
4548
} else if (event.rangeParent) {
@@ -142,7 +145,7 @@ function endDrag(editor) {
142145
const editorNode = ReactDOM.findDOMNode(editor);
143146
if (editorNode) {
144147
const mouseUpEvent = new MouseEvent('mouseup', {
145-
view: window,
148+
view: getWindowForNode(editorNode),
146149
bubbles: true,
147150
cancelable: true,
148151
});

src/component/handlers/edit/__tests__/editOnBeforeInput-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const getEditorState = (text: string = 'Arsenal') => {
5555

5656
const getDraftEditor = (obj): DraftEditor => (obj: any);
5757

58-
const getInputEvent = (data): SyntheticInputEvent<> =>
58+
const getInputEvent = (data): SyntheticInputEvent<HTMLElement> =>
5959
({
6060
data,
6161
preventDefault: jest.fn(),

src/component/handlers/edit/__tests__/editOnBlur-test.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* LICENSE file in the root directory of this source tree.
66
*
77
* @emails oncall+draft_js
8+
* @flow strict-local
89
* @format
910
*/
1011

@@ -29,8 +30,8 @@ const getEditorState = (text: string = 'Arsenal') => {
2930
);
3031
};
3132

32-
const getBlurEvent = data => ({
33-
data,
33+
const getBlurEvent = currentTarget => ({
34+
currentTarget,
3435
});
3536

3637
function withGlobalGetSelectionAs(getSelectionValue = {}, callback) {
@@ -68,7 +69,8 @@ test('editor removes selection on blur (default behaviour)', () => {
6869
editor: editorNode,
6970
};
7071

71-
onBlur(editor, getBlurEvent());
72+
// $FlowExpectedError
73+
onBlur(editor, getBlurEvent(editorNode));
7274

7375
expect(globalSelection.removeAllRanges).toHaveBeenCalledTimes(1);
7476
});
@@ -97,7 +99,8 @@ test('editor preserves selection on blur', () => {
9799
editor: editorNode,
98100
};
99101

100-
onBlur(editor, getBlurEvent());
102+
// $FlowExpectedError
103+
onBlur(editor, getBlurEvent(editorNode));
101104

102105
expect(globalSelection.removeAllRanges).toHaveBeenCalledTimes(0);
103106
});

0 commit comments

Comments
 (0)