Instead of attempting to update the ixsl:source() as changes are made, I've taken Michael's suggestion and implemented logic which keeps the working data in the HTML and when the Save button is pressed, it walks the HTML DOM and re-constitutes the XML document.

<xsl:template match="input[@value='Save']" mode="ixsl:onclick">
        <xsl:variable name="doc">
            <xsl:apply-templates select="ixsl:page()/html/body/div/div[@class='element']" mode="save"/>
        </xsl:variable>
        <xsl:message><xsl:value-of select="$doc"/></xsl:message>
        <xsl:value-of select="ixsl:call(ixsl:window(),'saveDocument',$doc)"/>
</xsl:template>

The trace message appears in the console as expected, however the ixsl:call() throws an "Out of stack space" exception. The saveDocument() function wants to perform a JQuery AJAX 'put' of the document to a BaseX server, but it is not invoked because of the exception.   If I replace $doc with a dummy string 'here', the saveDocument() function is invoked OK.   The size of the document is 52KB.  

I guess what I should try next is to write the document to a hidden <div> in the document and then fetch the contents of this div in the javascript.