instructure-react / react-tinymce Goto Github PK
View Code? Open in Web Editor NEWReact TinyMCE component
React TinyMCE component
shouldComponentUpdate
always returns true for unchanged config
and content
props causes component to rerender every time when parent component rerenders.
config
object comparison happens against customized version of config object which includes selector
and setup
properties that were added after _init
method execution.
config prop need to be cloned before adding any extra properties to it for internal needs..
It is possible to say to tinymce to set the focus on the element just created: https://www.tinymce.com/docs/configure/integration-and-setup/#auto_focus
However, the ID of the textarea must be passed in the config (it's weird, I was expecting just a simple boolean, but whatever.). This ID is generated during the creation of the component, so it can't be pass in the config (since we can't know it before)...
Maybe it needs an additional option to allow user to delegate the autofocus 'config' to the TinyMce
component... (Or maybe there is a more simple implementation using componentDidMount
and then manipulating the TinyMce
ref in the parent but I did not find out)
Thanks for making this.
TinyMCE has a inline mode that is currently not supported. Any chance of this?
Issue when im using a frontend routing service and navigating to a new page and then coming back to the page with the editor. It does not rerender properly.
found this:
http://stackoverflow.com/questions/29169158/react-html-editor-tinymce
Hello,
This repo is awesome that I use it in my project - [ Oi ] an impress.js WYSIWYG editor.
But there's a little problem that when I use redo or undo, the content doesn't re-render (strictly speaking, it doesn't change the property of content, check the demo of this repo).
p.s. I already checked the older issue, but not really well 😞
Consider the following piece of code.
...
const {content, setContent} = this.props
return <div className="field">
<TinyMCE
content={content}
...
TinyMCE will ignore the changes of content
property and will display only it's value on initial render. I managed to get around this limitation by changing the key property on a parent component from a snippet above (which forces it's re-render) but is there any other way to achieve this without hacking my way through?
I am using admin-on-rest and react-tinymce. When I include file_picker_callback
in the tinymce config the editor will reload every time the onchange event fires.
This is an issue because users are not able to continually type (editor loses focus after reloading). I have tried manually setting the focus after it reloads, but it does not focus back to the same place the cursor was previously - so this is not a viable workaround.
If I remove the file_picker_callback
, then everything works as expected.
Here is my code:
import React, { PropTypes, Component } from 'react'
import TinyMCE from 'react-tinymce'
import debounce from 'lodash.debounce';
class Editor extends Component {
self;
componentDidMount() {
const {
id,
disabled,
label,
name,
input: {
value,
onChange
},
config
} = this.props;
self = this;
}
onEditorChange = (content = window.tinyMCE.activeEditor.getContent()) => {
if (self.props.input.value == content)
return;
self.props.input.onChange(content);
}
render() {
return (
<div>
<input type="file" id="image-upload-tinymce" name="single-image" style={{ display: "none" }} accept="image/png, image/gif, image/jpeg, image/jpg, image/svg" />
<TinyMCE
content={this.props.input.value}
config={{
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace wordcount visualblocks code',
'insertdatetime table contextmenu paste code'
],
toolbar: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | code',
file_browser_callback_types: 'image',
file_picker_callback: (callback, value, meta) => {
if (meta.filetype == 'image') {
var input = document.getElementById('image-upload-tinymce');
input.click();
input.onchange = () => {
var file = input.files[0];
var reader = new FileReader();
reader.onload = (e) => {
var img = new Image();
img.src = reader.result;
callback(e.target.result, {
alt: file.name
});
var delay = debounce(self.onEditorChange, 10000);
delay();
};
reader.readAsDataURL(file);
};
}
},
}}
id={this.props.id}
onKeyup={e => {
e.stopPropagation();
e.preventDefault();
var delay = debounce(self.onEditorChange, 500);
delay();
}}
/>
</div>
)
}
}
I have the following in my index.html:
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.5.6/tinymce.min.js"></script>
What I have noticed is that during an onchange event there is a get request issued for:
https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.5.6/skins/lightgray/content.min.css
and the call stack for this request is as follows:
initContentBody @ tinymce.min.js:11
init @ tinymce.min.js:11
(anonymous) @ tinymce.min.js:11
(anonymous) @ tinymce.min.js:4
n @ tinymce.min.js:3
v @ tinymce.min.js:4
loadScripts @ tinymce.min.js:4
loadQueue @ tinymce.min.js:4
t @ tinymce.min.js:11
render @ tinymce.min.js:11
a @ tinymce.min.js:12
(anonymous) @ tinymce.min.js:12
n @ tinymce.min.js:3
d @ tinymce.min.js:12
t.bind @ tinymce.min.js:2
bind @ tinymce.min.js:4
init @ tinymce.min.js:12
_init @ TinyMCE.js:128
TinyMCE_componentWillReceiveProps @ TinyMCE.js:66
(anonymous) @ ReactCompositeComponent.js:611
measureLifeCyclePerf @ ReactCompositeComponent.js:75
updateComponent @ ReactCompositeComponent.js:610
receiveComponent @ ReactCompositeComponent.js:547
receiveComponent @ ReactReconciler.js:125
updateChildren @ ReactChildReconciler.js:109
_reconcilerUpdateChildren @ ReactMultiChild.js:208
_updateChildren @ ReactMultiChild.js:312
updateChildren @ ReactMultiChild.js:299
_updateDOMChildren @ ReactDOMComponent.js:936
updateComponent @ ReactDOMComponent.js:754
receiveComponent @ ReactDOMComponent.js:716
receiveComponent @ ReactReconciler.js:125
_updateRenderedComponent @ ReactCompositeComponent.js:754
_performComponentUpdate @ ReactCompositeComponent.js:724
updateComponent @ ReactCompositeComponent.js:645
receiveComponent @ ReactCompositeComponent.js:547
receiveComponent @ ReactReconciler.js:125
updateChildren @ ReactChildReconciler.js:109
_reconcilerUpdateChildren @ ReactMultiChild.js:208
_updateChildren @ ReactMultiChild.js:312
updateChildren @ ReactMultiChild.js:299
_updateDOMChildren @ ReactDOMComponent.js:936
updateComponent @ ReactDOMComponent.js:754
receiveComponent @ ReactDOMComponent.js:716
receiveComponent @ ReactReconciler.js:125
_updateRenderedComponent @ ReactCompositeComponent.js:754
_performComponentUpdate @ ReactCompositeComponent.js:724
updateComponent @ ReactCompositeComponent.js:645
receiveComponent @ ReactCompositeComponent.js:547
receiveComponent @ ReactReconciler.js:125
_updateRenderedComponent @ ReactCompositeComponent.js:754
_performComponentUpdate @ ReactCompositeComponent.js:724
updateComponent @ ReactCompositeComponent.js:645
receiveComponent @ ReactCompositeComponent.js:547
receiveComponent @ ReactReconciler.js:125
_updateRenderedComponent @ ReactCompositeComponent.js:754
_performComponentUpdate @ ReactCompositeComponent.js:724
updateComponent @ ReactCompositeComponent.js:645
receiveComponent @ ReactCompositeComponent.js:547
receiveComponent @ ReactReconciler.js:125
_updateRenderedComponent @ ReactCompositeComponent.js:754
_performComponentUpdate @ ReactCompositeComponent.js:724
updateComponent @ ReactCompositeComponent.js:645
performUpdateIfNecessary @ ReactCompositeComponent.js:561
performUpdateIfNecessary @ ReactReconciler.js:157
runBatchedUpdates @ ReactUpdates.js:150
perform @ Transaction.js:140
perform @ Transaction.js:140
perform @ ReactUpdates.js:89
flushBatchedUpdates @ ReactUpdates.js:172
closeAll @ Transaction.js:206
perform @ Transaction.js:153
batchedUpdates @ ReactDefaultBatchingStrategy.js:62
enqueueUpdate @ ReactUpdates.js:200
enqueueUpdate @ ReactUpdateQueue.js:24
enqueueSetState @ ReactUpdateQueue.js:219
ReactComponent.setState @ ReactComponent.js:63
handleChange @ connect.js:302
dispatch @ createStore.js:186
(anonymous) @ middleware.js:22
(anonymous) @ middleware.js:80
boundChange @ createFieldProps.js:97
(anonymous) @ createOnChange.js:37
Editor._this.onEditorChange @ editor.js:29
invokeFunc @ index.js:160
trailingEdge @ index.js:207
timerExpired @ index.js:195
From the call stack, line 66 of TinyMCE.js is:
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
if (!(0, _lodashLangIsEqual2['default'])(this.props.config, nextProps.config)) {
this._init(nextProps.config, nextProps.content);//line 66 here
}
line 128 is tinymce.init(config);
I believe this is a bug with react-tinymce (and not admin-on-rest) - but I am not very familiar with react, so I could be wrong.
Any help or insight would be appreciated. I have spent 2 days debugging this and have made no progress
If you're seeing Module not found: Error: Cannot resolve module 'lodash/lang/isEqual'
, and/or Module not found: Error: Cannot resolve module 'lodash/lang/clone
:
See react-tinymce/lib/components/TinyMCE.js
near top of file:
var _lodashLangIsEqual = require('lodash/lang/isEqual');
-> var _lodashLangIsEqual = require('lodash/lang').isEqual;
var _lodashLangClone = require('lodash/lang/clone');
-> var _lodashLangClone = require('lodash/lang').clone;
I have this error below when upgrade react from 14.0.0 to 15.5.4
Uncaught ReferenceError: tinymce is not defined
at Object._init (vendor.js:43)
at Object.componentDidMount
Cant run init function on componentDidMount
i use React 15.5.4, router4, webpack2 last version.
I get the following warning from React v16.0.
Warning: Accessing PropTypes via the main React package is deprecated, and will be removed in React v16.0. Use the latest available v15.* prop-types package from npm instead. For info on usage, compatibility, migration and more, see https://fb.me/prop-types-docs
react-tinymce/lib/components/TinyMCE.js
Lines 35 to 40 in a25b204
I can submit a PR to clean this up if you'd like.
isEqual always says false if object contains functions. Furthermore tinymce adds properties to the single items in the style_formats option.
I had to change the componentWillReceiveProps and shouldComponentUpdate to:
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
if (!(0, _lodashLangIsEqual2['default'])(this.props.config, nextProps.config, function(c1, c2) {
if(typeof c1 === 'function' && typeof c2 === 'function') {
return c1.toString() === c2.toString();
}
if(c1.hasOwnProperty('items') && c2.hasOwnProperty('items')) {
return c1.length == c2.length;
}
})) {
this._init(nextProps.config, nextProps.content);
console.log('TODO: this._init(nextProps.config, nextProps.content);');
}
if (!(0, _lodashLangIsEqual2['default'])(this.props.id, nextProps.id)) {
this.id = nextProps.id;
}
},
shouldComponentUpdate: function shouldComponentUpdate(nextProps) {
return !(0, _lodashLangIsEqual2['default'])(this.props.content, nextProps.content) || !(0, _lodashLangIsEqual2['default'])(this.props.config, nextProps.config, function(c1, c2) {
if(typeof c1 === 'function' && typeof c2 === 'function') {
return c1.toString() === c2.toString();
}
if(c1.hasOwnProperty('items') && c2.hasOwnProperty('items')) {
return c1.length == c2.length;
}
});
},
The component references tinymce
twice, but never requires it in or creates it. I guess it just assumes that there is a global object named tinymce
that exists?
This doesn't play nice if you're using browserify to handle your dependency inclusion. tinymce
appears to exist on npm and there seems to be no reason not to include it: since TinyMCE.js
does use require
, it's not browser-safe on its own anyway.
I am aware that this is a known issue. Can someone tell me which version to roll back to so I will not encounter this error if a fix is not yet available? Also, if it has a specific version requirement on tiny-mce, that would help as well. Thank you for the help.
Hello,
I am using react and I'm using the tinymce component. But the images wont load. Is there a dependency or file I need to see the image icons such as: align left, align right, new document, etc?
I am using react tinymce editor in my project and it's working properly. But when I am doing npm link to some other project, it is causing some issue. Maybe the webpack is not able to bundle it up properly. I am getting an error as "global is undefined" . When I removed the tinymce in the linked project, it works fine, but with tinymce editor the error is coming. IS it webpack or es6 issue?
Hi.
How can I set "name" property to textarea component with <TinyMCE/> component?
I can set "content", "config" and what about the "name"?
Thanks.
When setting the editor to use inline mode in the configuration, the buttons don't work and seem to unselect the selected text.
as subject
the cpu is high when Editor's container state change for render
use antd (ant.design) form validate
<Form.Item label="Content" required={true}> { getFieldDecorator('content', {rules: [{ required: true }]})( <Editor height={300}/> ) } </Form.Item>
Please implement the placeholder attribute of the textarea:
diff --git a/lib/components/TinyMCE.js b/lib/components/TinyMCE.js
index 738b103..fbe49ad 100644
--- a/lib/components/TinyMCE.js
+++ b/lib/components/TinyMCE.js
@@ -37,7 +37,8 @@ const TinyMCE = React.createClass({
content: React.PropTypes.string,
id: React.PropTypes.string,
className: React.PropTypes.string,
- name: React.PropTypes.string
+ name: React.PropTypes.string,
+ placeholder: React.PropTypes.string,
},
getDefaultProps() {
@@ -96,6 +97,7 @@ const TinyMCE = React.createClass({
className={this.props.className}
name={this.props.name}
defaultValue={this.props.content}
+ placeholder={this.props.placeholder}
/>
);
},
First of all, let me say that this lib is awesome!
I'm using react-tinymce on a isomorphic react app, and the thing is that UUID has a global count var, that is incremented for every page load on the server, and on the client side this var starts on zero. This causes a warning on react like this one:
Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
(client) a id="react-tinymce-0" data-reactid="69"
(server) a id="react-tinymce-1" data-reactid="69"
One way to fix this is to have a static method that allow to set count value. (or to reset to zero). And then I can call this on my main component so that way each server and client render starts with zero.
TinyMCE = require('react-tinymce');
TinyMCE.resetUUIDCount();
I can make a PR with this fix, if that's ok
(sorry for my poor english :P)
When trying to utilize the 'setup' function I get the error:
Uncaught TypeError: Cannot set property 'onload' of null
I am using react-tinymce: 0.5.1
If I use a tinymce version <= 4.3.12 then it works fine...but I get the following warning:
'KeyboardEvent.keyIdentifier' is deprecated and will be removed in M54, around October 2016. See https://www.chromestatus.com/features/5316065118650368 for more details.
However, if I use anything > 4.3.12 I get the above mentioned error and tiny mce fails to load.
For reference, here is my code:
<TinyMCE
content={value}
config={{
menubar: false,
statusbar: false,
plugins: 'pplan link image code',
toolbar: 'bold italic | alignleft aligncenter alignright | code save',
setup: function(editor) {
editor.on('blur', function(e) {
console.log('blurred');
});
},
}}
/>
Is this an issue with react-tinymce or tinymce itself. I haven't seen this issue referenced anywhere else.
React.PropTypes
should be replaced by import PropTypes from 'prop-types'
, and React.createClass
by import createClass from 'create-react-class'
.
In case anyone is blocked on this preventing upgrading to React 16, the following webpack config snippet can hack a workaround:
(
{
module: {
rules: [
{
// react-tinymce uses APIs removed from React core, rewrite accesses to them
// with accesses to the modules that provide those APIs
test: /react-tinymce\/lib\/components\/TinyMCE.js$/,
enforce: 'pre',
use: [
{
loader: 'imports-loader',
options: {
'__import_PropTypes': 'prop-types',
'__import_createClass': 'create-react-class'
}
},
{
loader: 'string-replace-loader',
options: {
multiple: [{
search: String.raw`_react2\['default'\].PropTypes`,
replace: '__import_PropTypes',
flags: 'g'
}, {
search: String.raw`_react2\['default'\].createClass`,
replace: '__import_createClass',
flags: 'g'
}]
}
}
]
}
]
}
}
)
I know the docs say that tinymce needs to be globally accessible and they use the example of using a script tag to the cdn
<script src="//tinymce.cachefly.net/4.2/tinymce.min.js"></script>
I wanted to use webpack and the providePlugin in order to accomplish the same thing.
In my webpack config i'll have
plugins: [
new webpack.providePlugin( {'tinymce': 'tinymce/tinymce'} )
]
when i load the page, the console throws an error
tinymce.init() is not a function
if i debug in the console, I can see that tinymce is an object that contains another object called tinymce.
I was under the impression that loading 'tinymce/tinymce' should have resolved that.
Can anyone help advise what I may have missed?
Do you want to request a feature or report a bug?
Bug
What is the current behavior?
After using "setup" or "init_instance_callback" in the tinymce config (together with react) the editor-cursor jumps to the top of the editor. The cursor jumps are happening after every enter. (See gif film here)
Edit: The bug only occurs if the editor is used with inline=true.
Code which works
export default function Editor(props) {
return (
<TinyMCE
config={{
...config.tinymce,
language: getEditorLanguage()
}
}}
content={props.children || props.placeholder}
onChange={props.onChange}
ref={(tiny) => this.tiny = tiny } />
);
}
Code which breaks the editor
The strange behavior starts as soon as we use setup: (editor) => {... }. If I remove the setup with the console.log the editor is back to normal.
export default function Editor(props) {
return (
<TinyMCE
config={{
...config.tinymce,
language: getEditorLanguage(),
setup: (editor) => {
console.log('test');
}
}}
content={props.children || props.placeholder}
onChange={props.onChange}
ref={(tiny) => this.tiny = tiny } />
);
}
The browser console shows also a error after using the enter key:
tinymce.js:41290 Uncaught DOMException: Failed to execute 'setEndAfter' on 'Range': the given Node has no parent.
at handleEnterKey (http://localhost:8000/webpack:/~/tinymce/tinymce.js:41290:1)
at Editor.<anonymous> (http://localhost:8000/webpack:/~/tinymce/tinymce.js:41324:1)
at Dispatcher.fire (http://localhost:8000/webpack:/~/tinymce/tinymce.js:30842:1)
at Editor.fire (http://localhost:8000/webpack:/~/tinymce/tinymce.js:31082:1)
at DOMUtils.delegate (http://localhost:8000/webpack:/~/tinymce/tinymce.js:37928:1)
at executeHandlers (http://localhost:8000/webpack:/~/tinymce/tinymce.js:1181:1)
at HTMLDivElement.defaultNativeHandler (http://localhost:8000/webpack:/~/tinymce/tinymce.js:1208:1)
What is the expected behavior?
Editor should not jump to the top and the buttons should still be shown and working.
We just wanted to add two custom buttons. The Buttons are actually shown and work properly, but as mentioned before the editor-cursor starts to jump around. Is there maybe a workaround for this already?
export default function Editor(props) {
return (
<TinyMCE
config={{
...config.tinymce,
language: getEditorLanguage(),
setup: (editor) => {
editor.addButton('linkfile', {
icon: 'newdocument',
onClick: props.onFileLinkAdd,
tooltip: 'Insert/edit file link'
});
editor.addButton('image', {
icon: 'image',
onclick: props.onImageAdd,
tooltip: 'Insert Image'
});
}
}}
content={props.children || props.placeholder}
onChange={props.onChange}
ref={(tiny) => this.tiny = tiny} />
);
}
Which versions of TinyMCE, and which browser / OS are affected by this issue? Did this work in previous versions of TinyMCE?
react-tinymce: 0.6.0
tinymce: 4.6.4 and 4.6.5 -> Same problem with both versions.
tinymce-i18n: 17.7.8
Google Chrome: Version 59.0.3071.115 (Official Build)
Mozilla Firefox: 55.0.1
Linux: Ubuntu 16.04 LTS
Similar issues:
Has someone seen the same behavior occure? The only other similar problem I found was this one on Stackoverflow:
WIth Angular 2
On change event causes tinymce element to be re-rendered in safari, which seems to cause loss of focus and other errors. Fine in chrome. Problem only seems to appear in Safari or mobile Safari.
Hi there,
The problem I'm facing is activating/deactivating bold/italic and other commands withouyt selecting text.
When doing so, strange things happen:
Is there any posibilities to use tinymce.js (and skin as well) locally on server not via cdn?
Some code example will be great! Thanks
Thanks a lot for your work!
I was checking for the license and found the "MIT" in the package file. It would be great, if you could add LICENSE file as well to make things more clear?
Hey there, the wrapper seems to work well. However for serverside rendering it looks like you are keeping a count:
var count = 0;
module.exports = function uuid() {
return 'react-tinymce-' + count++;
};
Maybe this can be slightly refactored for those working in an isomorphic setup? The above causes a mismatch for isomorphic apps: figure out why the markup being generated is different on the client or server:
(client) a id="react-tinymce-0" data-reactid=".12
(server) a id="react-tinymce-3" data-reactid=".12
As described at
https://stackoverflow.com/questions/19761857/how-to-take-heading-h1-h2-h3-directly-on-toolbar-in-tinymce-4
I would like to add code like that included below so I can add headings buttons to the tinyMCE toolbar. I'm both a React and JavaScript novice so I can't figure out how to accomplish this. I get React errors when I try. Could someone give me some hints on how to proceed?
Many thanks!
tinyMCE.PluginManager.add('stylebuttons', function(editor, url) {
['pre', 'p', 'code', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].forEach(function(name){
editor.addButton("style-" + name, {
tooltip: "Toggle " + name,
text: name.toUpperCase(),
onClick: function() { editor.execCommand('mceToggleFormat', false, name); },
onPostRender: function() {
var self = this, setup = function() {
editor.formatter.formatChanged(name, function(state) {
self.active(state);
});
};
editor.formatter ? setup() : editor.on('init', setup);
}
})
});
});
Im trying to use the tinymce to upload files, but i cannot get access to any files on my system. Once i click the search system button, nothing pops up. Is there somehting im missing?
<TinyMCE
content="<p>This is the initial content of the editor</p>"
config={{
height:600,
paste_data_images: true,
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace wordcount visualblocks code fullscreen',
'insertdatetime media table contextmenu paste code'
],
toolbar: 'undo redo | bold italic | alignleft aligncenter alignright | code',
file_picker_types: 'file image media',
paste_data_images:true,
file_browser_callback_types: 'image',
selector: 'textarea', // change this value according to your HTML
file_picker_callback: function(callback, value, meta) {
if (meta.filetype == 'file') {
//callback('mypage.html', {text: 'My text'});
}
if (meta.filetype == 'image') {
}
if (meta.filetype == 'media') {
//callback('movie.mp4', {source2: 'alt.ogg', poster: 'image.jpg'});
}
}
}}
onChange={this.handleEditorChange}
/>
From official React documentation:
A Controlled component does not maintain its own internal state; the component renders purely based on props.
This is how I expected react-tinymce
to work, but it is not. This is caused a lot of frustration for me and for other people too:
As I understand there is no way to make this component act the same as "controlled component" due to tinyMCE nature, only "hacky" solutions as update state by timeout and so on ?
So I think it is important to highlight this issue in readme to prevent people from making typical mistakes ?
Hi. I have used react-tiny in manner described here https://www.tinymce.com/docs/integrations/react/#7testingtheapplication and got 2 problems:
( tinyMCE.init({ skin: '../../../../Content/css/tiny',) }))
TinyMCE: React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. If you're not yet ready to migrate, create-react-class is available on npm as a drop-in replacement.
Because in TinyMCE.js the render method use defaultValue for the content.
So my solution is add this function to the TinyMCE class:
componentDidUpdate: function componentDidUpdate(prevProps, prevState) {
if(prevProps.content!==this.props.content){
tinymce.EditorManager.get(this.id).setContent(this.props.content);
}
}
Is there a possibility to add Custom Toolbar Buttons with the React-Component?
In TinyMCE it should be possible by passing setup in the config.
https://www.tinymce.com/docs/demo/custom-toolbar-button/
But in the React-Component you are overwriting the setup config before the init of the editor.
config.setup = function (editor) {
EVENTS.forEach(function (event, index) {
var handler = _this.props[HANDLER_NAMES[index]];
if (typeof handler !== 'function') return;
editor.on(event, function (e) {
// native DOM events don't have access to the editor so we pass it here
handler(e, editor);
});
});
// need to set content here because the textarea will still have the
// old `this.props.content`
if (content) {
editor.on('init', function () {
editor.setContent(content);
});
};
};
I think you could just add this to the new config.setup:
if (typeof this.props.config.setup === 'function') {
this.props.config.setup(editor);
}
Many thanks in advance.
Close.
I'm getting the following warnings after adding tinymce and I am not sure what could be the cause.
Failed to decode downloaded font: http://localhost:4000/fonts/OfficeCodePro-Regular.woff
OTS parsing error: invalid version tag
Any help is appreciated
I'm using react-tinymce with create-react-app.
I'm getting the following error when the editor component mounts:
uncaught at handleCall TypeError: Cannot set property 'onload' of null
at p.unbindAllNativeEvents (https://cloud.tinymce.com/stable/tinymce.min.js?apiKey=s057mcau7lzqdzu5tu3vx99qiek91pkj0od7u00dbw6kuk65:18:2293)
at p.remove (https://cloud.tinymce.com/stable/tinymce.min.js?apiKey=s057mcau7lzqdzu5tu3vx99qiek91pkj0od7u00dbw6kuk65:20:9142)
at Object.execCommand (https://cloud.tinymce.com/stable/tinymce.min.js?apiKey=s057mcau7lzqdzu5tu3vx99qiek91pkj0od7u00dbw6kuk65:20:19531)
at Object._remove (http://localhost:3000/static/js/bundle.js:127305:27)
at Object.componentWillUnmount (http://localhost:3000/static/js/bundle.js:127245:10)
The section in question is in tinymce.js
:
unbindAllNativeEvents: function() {
var a, b = this;
if (b.delegates) {
for (a in b.delegates)
b.dom.unbind(d(b, a), a, b.delegates[a]);
delete b.delegates
}
b.inline || (b.getBody().onload = null,
b.dom.unbind(b.getWin()),
b.dom.unbind(b.getDoc())),
b.dom.unbind(b.getBody()),
b.dom.unbind(b.getContainer())
}
b.getBody()
is returning null. This only happens intermittently. Sometimes the editor loads correctly. I should note that I am integrating the editor into react-redux-form, as a custom Control
component.
render(): React.Element<*> {
return (
<div>
<input type="file" id="image-upload-tinymce" name="single-image" style={{ display: "none" }}
accept="image/png, image/gif, image/jpeg, image/jpg, image/svg" />
<UIForm
as={Form}
model={this.props.formModel}
onSubmit={(foo) => this.handleSubmit(foo)}
>
<Control
model={this.props.fieldModel}
component={TinyMCECustom}
mapProps={{
content: (props) => props.viewValue,
}}
updateContent={this.props.updateContent}
validators={{
required: val => val && val.length > 10
}}
/>
</UIForm>
</div>
);
}
I am initializing the value of the form from a reducer that react-redux-form
connects to my redux
state. The reducer has the following structure:
export default function reducer(state = initialState, action) {
switch (action.type) {
case articleModule.GET_SUCCESS:
case articleModule.SAVE_SUCCESS: {
const article = action.payload.data;
return {
...state,
description: article.description || '',
uuid: article.uuid,
}
}
default:
return state;
}
}
Sometimes the editor loads just fine, prepopulating with the description of article from the reducer. This suggests to me that the issue is asynchronous, and is happening when the TinyMCE component attempts to mount before it has received the data from the react-redux-form
reducer. I am setting default values in the reducer, however, so I'm not sure if something else is causing this issue.
This is my implementation of TinyMCECustom:
const filePickerCallback = (callback, value, meta) => {
if (meta.filetype !== 'image') {
return;
}
let input = document.getElementById('image-upload-tinymce');
input.click();
input.onchange = () => {
let file = input.files[0];
let reader = new FileReader();
reader.onload = (e) => {
let img = new Image();
img.src = reader.result;
callback(e.target.result, {
alt: file.name
});
};
reader.readAsDataURL(file);
};
}
const handleEditorChange = (e, props) => {
props.updateContent(e.target.getContent());
};
const handleOnBlur = (e, props) => {
props.updateContent(e.target.getContent());
}
const handleOnKeyup = (e, props) => {
const updateContent = _.debounce(() => props.updateContent(e.target.innerHTML), 300);
updateContent();
}
const TinyMCECustom = (props) => {
return <TinyMCE
content={props.content}
config={{
plugins: ['advlist autolink lists link image charmap print preview hr anchor pagebreak',
'searchreplace wordcount visualblocks visualchars code fullscreen',
'insertdatetime media nonbreaking save table contextmenu directionality',
'emoticons template paste textcolor colorpicker textpattern imagetools codesample toc help'],
toolbar1: 'undo redo | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
toolbar2: 'print preview media | forecolor backcolor emoticons | codesample help',
image_advtab: true,
file_browser_callback_types: 'image',
file_picker_callback: filePickerCallback,
branding: false,
height: 400,
}}
{...props}
onChange={(e) => handleEditorChange(e, props)}
onBlur={(e) => handleOnBlur(e, props)}
onKeyup={(e) => handleOnKeyup(e, props)}
/>
}
I'm trying to use the onKeyUp
event handler, but it doesn't seem to be working. I think it's because your code is looking out for onKeyup
instead.
Im wondering if there is any way to include this in a React-on-Rails app I am creating. I tried copying the react-tinymce.min.js into my vendor/assets/javascripts but I still don't have the TinyMCE component defined.
I am using version 0.14 of the react-rails gem and the tinymce-rails gem so tinymce and ReactDOM are both globally accessible.
Can you assist?
It seems that onChange is only fired when you change the cursor location in the document, not whenever the document content changes (as you type). I expected any changes in the text to receive a callback.
According to docs by redux-form,
content is the fields to be passed... but it turned out redux-form get "undefined" in content...
Thanks in advance~
Here is my code
{ <TinyMCE
config={{
menubar: false,
plugins: 'autolink link image lists print preview',
toolbar: 'styleselect | bold italic | alignleft aligncenter alignright | link ',
height: 150,
width: 450,
statusbar: false,
}} {...content} />}
When adding text to the editor in the demo, I see that the output box only updates after you click. Is there a reason for this, is there a different way to configure the editor to keep the returned content and whatever is entered into the editor the same automatically?
A few deprecation warnings were added in React 15.5.
Can anyone update react-tinymce for being compatible with that?
Whenever the style_formats have been changed in TinyMCE's config, like in this example, the react component of TinyMCE is broken.
Every keypress will cause the component to be rerender and the focus will be lost.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.