JavaScript TinyMCE / jQuery race condition on Firefox

I have a website with a form that uses TinyMCE; Regardless, I use jQuery. When I download a form from an intermediate server on Firefox 3 (MacOS X, Linux), TinyMCE does not finish the download. There is an error in the Firefox console stating that t.getBody() returned null . t.getBody() , as I understand it from TinyMCE docs, is a function that returns a document body element for checking some functions. The problem does not occur when I use Safari, and also when I use Firefox with the same site that works with localhost.

The original, JavaScript-related code failure looked like this:

 <script type="text/javascript" src="http://static.alfa.foo.pl/json2.js"></script> <script type="text/javascript" src="http://static.alfa.foo.pl/jquery.js"></script> <script type="text/javascript" src="http://static.alfa.foo.pl/jquery.ui.js"></script> <script type="text/javascript" src="http://static.alfa.foo.pl/tiny_mce/tiny_mce.js"></script> <script type="text/javascript"> tinyMCE.init({ mode:"specific_textareas", editor_selector:"mce", theme:"simple", language:"pl" }); </script> <script type="text/javascript" src="http://static.alfa.foo.pl/jquery.jeditable.js"></script> <script type="text/javascript" src="http://static.alfa.foo.pl/jquery.tinymce.js"></script> <script type="text/javascript" charset="utf-8" src="http://static.alfa.foo.pl/foo.js"></script> <script type="text/javascript"> $(document).ready(function(){ /* jQuery initialization */ }); </script> 

I tried changing the loading order of the script by moving the tinyMCE.init() call to the <script/> , $(document).ready() call-before, after . . tinyMCE.init() $(document).ready() , - , init. tinyMCE.init() call to the <script/> , $(document).ready() call-before, after . . tinyMCE.init() $(document).ready() , - , init.

Then, after working a bit on using TinyMCE with jQuery, I changed the call to tinyMCE.init() to:

 tinyMCE.init({ mode:"none", theme:"simple", language:"pl" }); 

and the following jQuery call was added to the $(document).ready() handler:

 $(".mce").each( function(i) { tinyMCE.execCommand("mceAddControl",true,this.id); }); 

Still the same error. But here, when things begin to look like real voodoo, when I added alert (i); before calling tinyMCE.execCommand (), warnings were given and the TinyMCE text fields were correctly initialized. I figured it might be a delay caused by the user waiting for the warning to be rejected, so I entered a second delay, changing the call, still in the $ (document) .ready () handler, as follows:

  setTimeout ('$ (". mce"). each (function (i) {tinyMCE.execCommand ("mceAddControl", true, this.id);});', 1000);

When the timeout occurs, the TinyMCE text fields will be correctly initialized, but this will concern the real problem. The problem looks like an obvious race condition (especially when I consider that in the same browser, but when the server is on the local host, the problem does not occur). But is JavaScript not executing once? Can someone please enlighten me about what is happening here, where is the real problem, and what can I do to really fix this?

+7
javascript jquery firefox tinymce
source share
3 answers

The browser executes the scripts in the order in which they are loaded, not written. Immediate scripts - tinyMCE.init(...) and $(document.ready(...)); - may be executed before the file upload is completed.

So the problem is probably related to network latency - especially with 6 separate scenarios (each of which requires a different HTTP conversation between the browser and the server). Thus, the browser is probably trying to execute tinyMCE.init() before tiny_mce.js finishes the analysis and tinyMCE is fully defined.

If you do not have Firebug, get it .;)
It has a Network tab that will show you how long it takes to load all your scripts.


While you can assume that setTimeout is a channel tape, this is a really decent solution. The only problem I see is that it assumes that 1 second will always be fixed. Quick connection, and they could see a pause. The connection is slow and it does not wait long enough - you still get an error.

Alternatively, you can use window.onload - if jQuery doesn't use it yet. (Can anyone else check?)

 window.onload = function () { tinyMCE.init(...); $(document).ready(...); }; 

Also, was there a direct copy?

 <script type="text/javascript"> $(document).ready(function(){ /* jQuery initialization */ } </script> 

No completion ) ready :

 <script type="text/javascript"> $(document).ready(function(){ /* jQuery initialization */ }) </script> 

Lack of punctuation can do a lot of damage. The parser is just about to read until it finds it - it will mix something up.

+5
source share

Since this is the first page that appeared on google when I asked myself the same question, here is what I found about this problem.

a source

There is a callback function in tinyMCE that starts when the component is loaded and ready. you can use it as follows:

 tinyMCE.init({ ... setup : function(ed) { ed.onInit.add(function(ed) { console.log('Editor is loaded: ' + ed.id); }); } }); 
+2
source share

If you use jquery.tinymce.js , you do not need tiny_mce.js because TinyMCE will try to load it using an ajax request. If you find that window.tinymce (or just tinymce ) is undefined , then that means ajax is not complete yet (which might explain why using setTimeout worked for you). This is a typical order of events:

  • Download jquery.js with a script tag (or by downloading Google).
  • Download the TinyMCE jQuery plugin, jquery.tinymce.js , with a script tag.
  • Ready events of document readiness; here you call .tinymce(settings) on textarea s. For example. $('textarea').tinymce({ script_url: '/tiny_mce/tiny_mce.js' })

  • Download tiny_mce.js , this step is done for you by the TinyMCE jQuery plugin, but this can happen after the document ready event is triggered.

Sometimes you really need to access window.tinymce , here is the safest way to do this:

$ (Document) .tinymce ({'script_url': '/tiny_mce/tiny_mce.js' 'setup': function () {notifications (TinyMCE);}});

TinyMCE will go so far as to create a tinymce.Editor object and perform a setup callback. None of the editor events are fired, and the editor object created for the document is not added to tinymce.editors .

I also found that calling tinyMCE ajax interfered with my .ajaxStop functions, so I also used setTimeout :

$ (Document) .tinymce ({'script_url': '/tiny_mce/tiny_mce.js' 'setup': function () {setTimeout (function () {$ (document) .ajaxStart (function (e) {/ * stuff / }); $ (document) .ajaxStop (function (e) {/ stuff * /});}, 0);}});

+1
source share

All Articles