I ended up using the tinyMCE.Editor.save() function before serializing the form.
Using jQuery, I code looks like this:
// Unified form serialization, also serializes tinyMCE textarea contents
$.fn.saveState = function() {
var $form = $(this);
$form.find('textarea').each(function() {
tinyMCE.get($(this).attr('name')).save();
});
$form.data('original_value', $form.serialize());
};
// Unified form change check, also detects tinyMCE textarea changes
$.fn.formChanged= function() {
var $form = $(this);
$form.find('textarea').each(function() {
tinyMCE.get($(this).attr('name')).save();
});
return ($form.data('original_value') !== $form.serialize());
};
Upon document.ready, I call the saveState() function on each form element in the document. Then I set up a timer, that'll call the formChanged() function to see if there were any changes. If yes, I'll trigger my action (in my case - autosave the current state of the form on the server), and call on saveState() again.
This will not work if you have mixed textareas on your page, some of them having tinyMCE attached and some of them not. In that case you could go with a class based identification - like $form.find('textarea.tinyMCEAttached')...
Kevin Peno's suggestion to use the onChange() was not going to work for me. onChange fires only on blur, and I needed to detect form changes even if the user doesn't leave the editor area. However, it pointed me to the right direction, thanks Kevin!