Skip to content

Commit

Permalink
1. Updated jsdom 2. DOCTYPE detection. (See full commit message). #21
Browse files Browse the repository at this point in the history
1. jQuery.parseHTML on jsdom 3.1.2+ removes doctype, html, head and body tag. As a workaround,
some handling for full HTML document template is done based on an assumption that the first tag
of the document is an <html> tag (excluding doctype) when one wants to parse an entire document.

2. Detects doctype and prepend it to toString() output.
.
  • Loading branch information
Munawwar committed Jun 18, 2016
1 parent 2d6998d commit bca1680
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"version": "1.0.0",
"main": "src/Htmlizer.js",
"dependencies": {
"jsdom": "0.10.3"
"jsdom": "9.2.1"
},
"devDependencies": {
"mocha": "1.18.2"
Expand Down
20 changes: 16 additions & 4 deletions src/Htmlizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
(function (root, factory, saferEval) {
if (typeof exports === 'object') {
var jsdom = require('jsdom').jsdom,
window = jsdom('').parentWindow;
window = jsdom('').defaultView;
module.exports = factory(
saferEval,
require('./jquery')(window),
Expand Down Expand Up @@ -66,6 +66,12 @@
$.extend(this, cfg);
if (typeof template === 'string') {
this.origTplStr = template;
//Detect DOCTYPE
if (template.slice(0, 9).toLowerCase() === '<!doctype') {
var pos = template.indexOf('<', 1);
this.doctype = template.slice(0, pos);
template = template.slice(pos);
}
this.frag = this.moveToNewFragment(this.parseHTML(template));
} else { //assuming DocumentFragment
this.frag = template;
Expand Down Expand Up @@ -485,7 +491,7 @@
html += '<!-- ' + node.data.trim() + ' -->';
}
}, this);
return html;
return (this.doctype || '') + html;
},

/**
Expand Down Expand Up @@ -558,7 +564,13 @@
* @private
*/
parseHTML: function (html) {
return $.parseHTML(html, document, true);
if (html.indexOf('<html') === 0) {
var doc = document.implementation.createHTMLDocument("");
doc.documentElement.innerHTML = html.slice(html.indexOf('>') + 1, html.lastIndexOf('</html>'));
return this.slice(doc.children);
} else {
return $.parseHTML(html, document, true);
}
},

/**
Expand Down Expand Up @@ -698,7 +710,7 @@
if (arguments.length === 4) {
try {
return (new Function('$context', '$data', '$element', 'with($context){with($data){return ' + arguments[0] + '}}'))(arguments[1] || {}, arguments[2] || {}, arguments[3]);
} catch (e) {console.log('Htmlizer expression ' + e);}
} catch (e) {console.warn('Htmlizer expression ' + e);}
} else {
throw new Error('Expression evaluator needs at least 4 arguments.');
}
Expand Down
10 changes: 9 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,14 +365,22 @@ describe('run template binding test', function () {
});
});

describe('run complete document parsing test', function () {
var html = fetch('test/full-document.html'),
outputHtml = (new Htmlizer(html)).toString();
it('markup should be as expected', function () {
assert.equal(outputHtml, '<!DOCTYPE html>\n<html><head></head><body>Test</body></html>');
});
});

/*Utility functions*/
function fetch(pathToTextFile) {
return fs.readFileSync(pathToTextFile, {encoding: 'utf8'});
}

function htmlToDocumentFragment(html) {
var document = jsdom(),
window = document.parentWindow,
window = document.defaultView,
jquery = jqueryFactory(window),
df = document.createDocumentFragment();
jquery.parseHTML(html).forEach(function (node) {
Expand Down

0 comments on commit bca1680

Please sign in to comment.