Last active
November 17, 2016 10:05
-
-
Save lucamug/0eb113b62bbf1ff820841d79cead4cfb to your computer and use it in GitHub Desktop.
See https://coding-and-design.blogspot.de/2016/11/are-all-element-tags-closed-testing-it.html for more info
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// See https://coding-and-design.blogspot.de/2016/11/are-all-element-tags-closed-testing-it.html for more info | |
var 凸 = typeof global === 'undefined' ? 凸 : global.tmp; | |
var 凸 = (function (凸) { | |
凸.buildGetPageFunction = function buildGetPageFunction() { | |
if (typeof global === 'undefined') { | |
// Browser | |
return function (url, callback) { | |
var xhr = new XMLHttpRequest(); | |
xhr.onreadystatechange = function () { | |
if (xhr.readyState === XMLHttpRequest.DONE) { | |
return callback(xhr.responseText); | |
} | |
}; | |
xhr.open('GET', url, true); | |
xhr.send(null); | |
}; | |
} else { | |
// Node | |
return function (url, callback) { | |
var request = require("request"); | |
request({ url: url }, function (err, response, responseText) { | |
if (!err && response.statusCode === 200) { | |
return callback(responseText); | |
} else { | |
throw err; | |
} | |
}); | |
}; | |
} | |
}; | |
return 凸; | |
}(凸 || {})); | |
var 凸 = (function (凸) { | |
function isSelfClosingTag(tagName) { | |
return tagName.match(/area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr|script/i); | |
} | |
function displayLine(line, array) { | |
return ('Line #' + line + ': ' + array[line - 1]); | |
} | |
凸.checkHtml = function checkHtml(p) { | |
// Based on http://jona.ca/blog/unclosed-tag-finder | |
var | |
array1 = p.constructor === Array ? p : p.split('\n'), | |
tags = [], | |
tag, | |
openTags = [], | |
openTag, | |
i, | |
j, | |
line, | |
array2, | |
matches, | |
closingTag; | |
for (i = 0; i < array1.length; i++) { | |
line = array1[i]; | |
array2 = line.match(/<[^>]*[^/]>/g) || []; | |
for (j = 0; j < array2.length; j++) { | |
tag = array2[j]; | |
matches = tag.match(/<\/?([a-z0-9]+)/i); | |
if (matches) { | |
tags.push({ tag: tag, name: matches[1], line: i + 1, closing: tag[1] === '/' }); | |
} | |
} | |
} | |
if (tags.length === 0) { | |
return 'No tags found.'; | |
} | |
for (i = 0; i < tags.length; i++) { | |
tag = tags[i]; | |
if (tag.closing) { | |
closingTag = tag; | |
if (isSelfClosingTag(closingTag.name)) { | |
continue; | |
} | |
if (openTags.length === 0) { | |
return [ | |
'Closing tag ' + closingTag.tag + ' on line ' + closingTag.line + ' does not have corresponding open tag.', | |
displayLine(closingTag.line, array1), | |
].join('\n'); | |
} | |
openTag = openTags[openTags.length - 1]; | |
if (closingTag.name !== openTag.name) { | |
return [ | |
'Closing tag ' + closingTag.tag + ' on line ' + closingTag.line + ' does not match open tag ' + openTag.tag + ' on line ' + openTag.line + '.', | |
displayLine(openTag.line, array1), | |
displayLine(closingTag.line, array1) | |
].join('\n'); | |
} else { | |
openTags.pop(); | |
} | |
} else { | |
openTag = tag; | |
if (isSelfClosingTag(openTag.name)) { | |
continue; | |
} | |
openTags.push(openTag); | |
} | |
} | |
if (openTags.length > 0) { | |
openTag = openTags[openTags.length - 1]; | |
return [ | |
'Open tag ' + openTag.tag + ' on line ' + openTag.line + ' does not have a corresponding closing tag.', | |
displayLine(openTag.line, array1), | |
].join('\n'); | |
} | |
return 'Success: No unclosed tags found.'; | |
}; | |
return 凸; | |
}(凸 || {})); | |
(function () { | |
var url = (typeof global === 'undefined') ? document.location.href : "http://example.com"; | |
凸.buildGetPageFunction()(url, function (page) { | |
console.log("### Checking " + url + "\n\n" + 凸.checkHtml(page) + "\n\n"); | |
}); | |
console.log("### Checking <div>\n\n" + 凸.checkHtml("<div>") + "\n\n"); | |
console.log("### Checking ['<div>']\n\n" + 凸.checkHtml(["<div>"]) + "\n\n"); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment