Edits with VE in PageForms doesn't save to the page.
It saves just fine if you switch to source code mode.
The problem is in lack of textarea content update after VE chagnes (for example, you add something in VE, but textarea remains same).
Looks like pageforms use textarea as a source of it's content.
I resolved it temporarily changing resources/VEForAll.js :
/** * Being called by PageForms on textareas with 'visualeditor' class present * * @return {boolean} */ jQuery.fn.applyVisualEditor = function () { console.log(this); var config = mw.config.get( 'VEForAll' ); if ( !config.VisualEditorEnable ) { return false; } return this.each( function () { var textarea = this, veEditor = new mw.veForAll.Editor( this, $( this ).val() ); veEditor.initCallbacks.push( function () { }); veEditor.initCallbacks.push( function () { veEditor.target.on( 'editor-ready', function () { //Catch any changes in Visual Editor. var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; var myObserver = new MutationObserver (mutationHandler); var obsConfig = { childList: true, characterData: true, attributes: true, subtree: true }; var nodeToObserve = $( textarea ).parent().find('.ve-init-sa-target-surfaceWrapper').slice(-1)[0]; myObserver.observe (nodeToObserve, obsConfig); function mutationHandler (mutationRecords) { veEditor.target.updateContent().then( function () { $( textarea ).trigger( 'change' ); console.log('changed!'); }); } // Catch keyup events on raw textarea to use changes warning on page reload veEditor.target.$node.on( 'keyup', function () { $( textarea ).trigger( 'change' ); } ); } ); } ); // Add textarea updates for the case when textarea appared after page load. // It is possible with multiple-instance templates in pageforms if ( typeof veEditor.target !== 'undefined' ){ veEditor.target.on( 'editor-ready', function () { console.log('editor-ready'); //Catch any changes in Visual Editor. var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; var myObserver = new MutationObserver (mutationHandler); var obsConfig = { childList: true, characterData: true, attributes: true, subtree: true }; var nodeToObserve = $( textarea ).parent().find('.ve-init-sa-target-surfaceWrapper').slice(-1)[0]; myObserver.observe (nodeToObserve, obsConfig); function mutationHandler (mutationRecords) { veEditor.target.updateContent().then( function () { $( textarea ).trigger( 'change' ); console.log('changed!'); }); } // Catch keyup events on raw textarea to use changes warning on page reload veEditor.target.$node.on( 'keyup', function () { $( textarea ).trigger( 'change' ); } ); } ); } veInstances.push( veEditor ); } ); };
There are a lot of problems with such solution but the main are:
- Probably using MutationObserver is a bad idea. But I don't know how to subscribe to VE content changes. Using
veEditor.target.getSurface().getView().on('keyup'
is a bad idea because that event does not cover if user just clicked on a toolbar button (to make text bold, for example).
- I've added the same code twice to resolve multiple-instances templates. Probably there is more suitable callback instead of that solution.