Parsoid relies on the data-parsoid mapping when performing html to wikitext conversion. For this purpose, the data-parsoid mapping is stashed when Visual Editor loads the HTML to edit. When the edit is about to be saved, the modified HTML coming from the Visual Editor client needs to be converted to wikitext, with the help of the stashed data-parsoid mapping (identified by the edtag returned by the original request for editable HTML).
This functionality is currently implemented in the transform endpoint RESTbase, which loads the stashed mapping, injected it into the HTML, and sends the result to the parsoid extension's transform endpoint.
In the future, this functionality should be covered by the new transform endpoint in MW core. Ideally, this functionality would be implemented in a service or helper class, so it can be used by ApiVisualEditorEdit directly, bypassing the REST framework (T310377). The stashing backend is already implemented in the ParsoidOutputStash class, and is already populated when claling the page/html endpoint with stash=true.
Further information:
* The code in RESTbase that attaches the stashed data to the request that is then sent to parsoid lives in `transformRevision` in `sys/parsoid.js`.
* RESTbase currently takes the etag from the If-Match header if present, and tries to extract it from an HTML meta-tag with property=mw:TimeUuid" eitherwise. We may want to support it as part of JSON payload as well. Using If-Modified is problematic, see T233320, T238849, 310710, ...
* stashed data-parsoid can be injected back into a DOM of the original HTML using the following code: `PageBundle::apply( $oldBody->ownerDocument, $origPb );` This is currently in html2wt() on the ParsoidHandler base class.
* The endpoint most relevant for VE is: /transform/pagebundle/to/wikitext/
* Relevant e2e test in the parsoid extension: `tests/api-testing/Parsoid.js`, around line 1760
* The process of selectively serializing HTML to Wikitext using a data-parsoid mapping is referred to as "SelSer". See ContentModelHandler::fromDOM().