I spent a lot of time staring at send(), both in reviewing #176 and in implementing this in jsdom. I think the algorithm is too confusing mainly because it doesn't make it clear that the purpose is setting and manipulating the Content-Type header.
Thus, I propose this replacement for the current algorithm. I've written it in pseudo-JS since that was easier for me to rearrange things:
if (body !== null) {
let extractedMIMEType = null;
switch (body) {
case Document:
request.body = body, serialized, converted to unicode, and utf-8 encoded
case BodyInit:
{ extractedBody, extractedMIMEType } = extractBody(body);
request.body = extractedBody;
}
if (authorRequestHeaders.contains("Content-Type")) {
if (body is Document or body is string) {
let originalAuthorContentType = authorRequestHeaders.get("Content-Type");
let contentTypeRecord = MIMEType.parse(contentTypeRecord);
if (contentTypeRecord !== failure && contentTypeRecord.parameters.has("charset")) {
contentTypeRecord.parameters.set("charset", "UTF-8");
let newContentTypeSerialized = contentTypeRecord.serialize();
authorRequestHeaders.set("Content-Type", newContentTypeSerialized);
}
}
} else {
if (body is HTML document) {
authorRequestHeaders.set("Content-Type", "text/html;charset=UTF-8");
}
if (body is XML document) {
authorRequestHeaders.set("Content-Type", "application/xml;charset=UTF-8");
}
if (extractedMIMEType !== null) {
authorRequestHeaders.set("Content-Type", extractedMIMEType);
}
}
}
The main idea of this rewrite is:
Separate out setting the request body from setting the Content-Type. Don't concern ourselves with encodings or content types when setting the request body, except to the extent we're forced to by the extract algorithm.
Make it clear that we're taking different paths depending on whether the author request headers contain Content-Type or not
Make it clear under what conditions we override the author's Content-Type, and how. Each distinct possible result (parse/reserialize; set to HTML; set to XML; set to extracted MIME type) is clearly a peer of each other, instead of setting up all the variables ahead of time then sometimes using them.
WDYT? I can submit a PR after things settle down, if you like this.
I spent a lot of time staring at send(), both in reviewing #176 and in implementing this in jsdom. I think the algorithm is too confusing mainly because it doesn't make it clear that the purpose is setting and manipulating the Content-Type header.
Thus, I propose this replacement for the current algorithm. I've written it in pseudo-JS since that was easier for me to rearrange things:
The main idea of this rewrite is:
WDYT? I can submit a PR after things settle down, if you like this.