Project

Profile

Help

Bug #3223

Supplying Document objects to JavaScript global functions

Added by Debbie Lockett over 1 year ago. Updated 7 months ago.

Status:
Closed
Priority:
Normal
Sprint/Milestone:
-
Start date:
2017-05-16
Due date:
% Done:

100%

Applies to JS Branch:
1.0, Trunk
Fix Committed on JS Branch:
1.0, Trunk
Fixed in JS Release:
SEF Generated with:
Company:
-
Contact person:
-
Additional contact persons:
-

Description

Problem arising from working on finding a way to use XMLHttpRequest to make POST requests with XML content. Having encountered difficulties myself while working on the License Tool application, part of the problem is now pinned down with the help of a user support question.

We currently have an issue in Saxon-JS in that we always use DocumentFragment objects (rather than Document, or even XMLDocument, objects) when dealing with chunks of XML (or XHTML). For instance an xsl:document instruction (see newDoc() in Expr.js) will currently always produce a DocumentFragment. So when we want to pass a Document to a JavaScript function (like XMLHttpRequest.send()) we have a problem.

<xsl:template match="button[@id eq 'submit']" mode="ixsl:onclick">
    <xsl:variable name="xmldoc" as="document-node(element(doc))" xmlns="">
      <xsl:document>
        <doc>
...

        </doc>
      </xsl:document>
    </xsl:variable>
    <xsl:sequence select="js:postFn($xmldoc)"/>
  </xsl:template>

In cases such as the above, where the xsl:document is inside an xsl:variable with defined type document-node(), certainly we could be able creating an XMLDocument instead.

(A work around is to do more in the JavaScript function, to copy the content of the DocumentFragment into an XMLDocument; but Saxon-JS should really do this in the first place.)

History

#1 Updated by Michael Kay over 1 year ago

Note, incase it isn't clear: the XDM data model used in XSLT allows a document node to have multiple element and text node children. That means we have to represent it normally using a DOM DocumentFragment rather than Document object. But if the static type of a variable is declared as document-node(element(X)) then we know that it should be possible to represent it as a DOM Document. Of course we need to make sure that there is sanitary error handling if it's declared as document-node(element(X)) and the code then tries to create multiple element or text node children.

#2 Updated by Debbie Lockett 8 months ago

I don't think anything much is going to be changed in the Saxon-JS code on the 1.x branch; but maybe more will be done for 2.0, if we think of anything worthwhile.

It would be good to add a note in the Saxon-JS documentation. In the JS/XDM type conversion section, we currently just say that XDM nodes are converted to DOM nodes. But it may be useful to explain that XDM document nodes are usually converted to DOM DocumentFragment objects rather than DOM Document objects. These can always be converted on the JavaScript side by the user if necessary, using something like:

if (item instanceof DocumentFragment) {
   var docNode = document.implementation.createDocument(null, null, null);
   var n = docNode.importNode(item, true);
   docNode.appendChild(n);
   return docNode;
}

To fix the problem I had with XMLHttpRequests, I think we should update the specification for HTTP request maps supplied to ixsl:schedule-action/@http-request, to clarify that $request?body must be a document node (the documentation currently says any item is allowed); with a check in the JS code to throw a sensible error if it is not (at the moment the XMLHttpRequest may just crash out with an internal error).

#3 Updated by Debbie Lockett 8 months ago

  • Applies to JS Branch 1.0, Trunk added

Re last point: the type of $request?body is just specified as item because of the different content MIME types (text, multipart, and binary, as well as XML and HTML). We should just say that if the MIME type of the content is XML or HTML, then $request?body must be a document node.

#4 Updated by Debbie Lockett 8 months ago

  • Status changed from New to Resolved
  • Fix Committed on JS Branch 1.0, Trunk added

Type check for $request?body added to BrowserPlatform.makeHTTPrequest as described.

Notes added to documentation as suggested.

As Mike suggested in Note 2, we could do more if the static type of a variable is declared as document-node(element(X)), in which case we know that it should be possible to represent it as a DOM Document, rather than just a DocumentFragment. But I don't think we have to (as long as this is documented).

#5 Updated by Debbie Lockett 7 months ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in JS Release set to Saxon-JS 1.1.0

Bug fix applied in the Saxon-JS 1.1.0 maintenance release.

Please register to edit this issue

Also available in: Atom PDF Tracking page