Skip to content
This repository was archived by the owner on Feb 6, 2023. It is now read-only.
This repository was archived by the owner on Feb 6, 2023. It is now read-only.

Draft.js + Meteor + iframe causes node instanceof Element to return false #1640

Closed
@Minivera

Description

@Minivera

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
When creating a React application using Meteor and DraftJs, trying to render the Editor and make any change will cause the checks for node instanceof Element and node instanceof HTMLElement to return false and prevent the use of draft.js.

Since Meteor compiles scripts and import them in the current window, draft.js Element is the global Element, however, the obtained node by ReactDOM.findNode was created using the iframe's Element constructor. Instanceof implementation suggest using this line rather than accessible Element directly.

myNode instanceof myNode.ownerDocument.defaultView.SVGElement

This can be seen there for example : https://github.com/facebook/draft-js/blob/788595984da7c1e00d1071ea82b063ff87140be4/src/component/contents/DraftEditorTextNode.react.js#L84

This is consistent across the tested browser and is probably caused by the fact that draft.js uses the global Element, which is loaded as the global window Element when the script is first imported, rather than the current window Element.

This was also tested using a standard iFrame with injecting HTML, an iFrame with portals and react-frame-component.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. You can use this jsfiddle to get started: https://jsfiddle.net/stopachka/m6z0xn4r/.

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';

import Frame from 'react-frame-component';
import {
  convertToRaw,
  CompositeDecorator,
  ContentState,
  Entity,
  Editor,
  EditorState,
  EntityInstance,
  RichUtils,
} from 'draft-js';

class PageHome extends Component {
	constructor(props) {
		super(props);
		this.state = {
			editorState: EditorState.createEmpty()
		};
	}
	
	onChange = (editorState) => {
		this.setState({editorState});
	}

    render() {
        return (
           <div className="container" style={{padding:10}}>
        	<Frame>
		    <Editor editorState={this.state.editorState} onChange={this.onChange}/>
		</Frame>
           </div>
        );
    }
}

When doing this, the following error is caused in the console when writing in the editor :

2018-02-06 09_34_39-

What is the expected behavior?

Draft.js should probably not rely on the Element global or the window/document globals for its code. In this case, draft.js should behave like usual when added inside an iframe.

Maybe replace this with an implementation similar to lodash's isElement could also fix this issue, but it has been stated before that iframes are unlikely to be supported in #527. This is also specific to meteor's compiling, but may cause problem for other js compiled and minifiers.

Which versions of Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draft.js?

Tested in version 0.10.5,
Tested with Chrome, Firefox and Microsoft Edge, all latest versions.

I had not tested it with earlier version of draft-js as NPM always install the latest version.

I also tried to implement to solution proposed in PR #765, but it seems the selection is not registered.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions