Skip to content

Commit

Permalink
Fix browser (de)serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
ultraq committed Jun 1, 2020
1 parent 62d8933 commit 9b9bf68
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 22 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -28,7 +28,7 @@
"dependencies": {
"@babel/runtime": "^7.7.5",
"@ultraq/array-utils": "^2.0.0",
"@ultraq/dom-utils": "^0.2.0",
"@ultraq/dom-utils": "^0.3.1",
"@ultraq/string-utils": "^2.0.0",
"dumb-query-selector": "^3.3.0",
"jsdom": "^16.2.1"
Expand Down
2 changes: 1 addition & 1 deletion source/Configurations.js
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import StandardDialect from './standard/StandardDialect';
import StandardDialect from './standard/StandardDialect.js';

/**
* Configuration object for the template engine.
Expand Down
31 changes: 15 additions & 16 deletions source/TemplateEngine.js
Expand Up @@ -14,17 +14,13 @@
* limitations under the License.
*/

import {DEFAULT_CONFIGURATION} from './Configurations.js';
import AttributeProcessor from './processors/AttributeProcessor.js';
import ElementProcessor from './processors/ElementProcessor.js';
import Matcher from './processors/Matcher.js';
import StandardDialect from './standard/StandardDialect.js';
import {deserialize} from './utilities/Dom.js';
import {promisify} from './utilities/Functions.js';

import {serialize} from '@ultraq/dom-utils';

const XML_NAMESPACE_ATTRIBUTE = `xmlns:${StandardDialect.DEFAULT_PREFIX}`;
import {DEFAULT_CONFIGURATION} from './Configurations.js';
import AttributeProcessor from './processors/AttributeProcessor.js';
import ElementProcessor from './processors/ElementProcessor.js';
import Matcher from './processors/Matcher.js';
import StandardDialect from './standard/StandardDialect.js';
import {deserialize, serialize} from './utilities/Dom.js';
import {promisify} from './utilities/Functions.js';

/**
* A highly-configurable class responsible for processing the Thymeleaf
Expand All @@ -46,6 +42,9 @@ export default class TemplateEngine {
this.messageResolver = messageResolver;
this.templateResolver = templateResolver;

let standardDialect = dialects.find(dialect => dialect instanceof StandardDialect);
this.xmlNamespaceAttribute = `xmlns:${standardDialect ? standardDialect.prefix : StandardDialect.DEFAULT_PREFIX}`;

// Combine all processors into a unified list
this.processors = dialects.reduce((acc, {processors}) => processors ? [
...acc,
Expand Down Expand Up @@ -80,11 +79,11 @@ export default class TemplateEngine {
templateResolver: this.templateResolver
})
.then(() => {
// TODO: Special case, remove the xmlns:th namespace from the document.
// This should be handled like in main Thymeleaf where it's just
// another processor that runs on the document.
if (rootElement.hasAttribute(XML_NAMESPACE_ATTRIBUTE)) {
rootElement.removeAttribute(XML_NAMESPACE_ATTRIBUTE);
// TODO: Special case, remove the xmlns:thjs namespace from the
// document. This should be handled like in main Thymeleaf where
// it's just another processor that runs on the document.
if (rootElement.hasAttribute(this.xmlNamespaceAttribute)) {
rootElement.removeAttribute(this.xmlNamespaceAttribute);
}
return serialize(document);
});
Expand Down
24 changes: 23 additions & 1 deletion source/utilities/Dom.js
Expand Up @@ -52,12 +52,34 @@ export function getThymeleafAttributeValue(element, prefix, processorName) {
* @return {DocumentFragment}
*/
export function deserialize(htmlString) {
/* istanbul ignore if */
if (ENVIRONMENT === 'browser') {
/* istanbul ignore next */
return require('@ultraq/dom-utils').deserialize(htmlString);
}
else {
const {JSDOM} = require('jsdom');
return new JSDOM(htmlString).window.document;
}
}

/**
* Use either JSDOM or the browser's native DOM serialization to serialize a
* document fragment into an HTML string.
*
* @param {DocumentFragment} documentFragment
* @return {String}
*/
export function serialize(documentFragment) {
/* istanbul ignore if */
if (ENVIRONMENT === 'browser') {
return require('@ultraq/dom-utils').serialize(documentFragment);
}
else {
let result = '';
let {firstChild, firstElementChild} = documentFragment;
if (firstChild.nodeType === Node.DOCUMENT_TYPE_NODE) {
result += `<!DOCTYPE ${firstChild.name}>`;
}
return result + firstElementChild.outerHTML;
}
}

0 comments on commit 9b9bf68

Please sign in to comment.