Skip to content

Instantly share code, notes, and snippets.

@LukeChannings
Last active July 19, 2018 16:23
Show Gist options
  • Save LukeChannings/e7c2eec3163cd182f0dca9d2183ef286 to your computer and use it in GitHub Desktop.
Save LukeChannings/e7c2eec3163cd182f0dca9d2183ef286 to your computer and use it in GitHub Desktop.
HTML Validator snippet
;(function validateHtml() {
const getErrorExampleSnippet = (html, start, end) => {
const lines = html.split('\n')
const linesWeCareAbout = lines.slice(start.line - 1, end.line)
const region = linesWeCareAbout.map((l, i, ls) => {
const isFirstLine = i === 0
const isLastLine = ls.length - 1 === i
if (isFirstLine && isLastLine) {
return l.slice(start.col - 1, end.col - 1)
} else if (isFirstLine) {
return l.slice(start.col - 1)
} else if (isLastLine) {
return l.slice(-(end.col - 1))
} else {
return l
}
})
return region.join('\n')
}
const logItem = (li, html, type) => {
const text = li.querySelector('p > span').textContent
const line = Number(li.querySelector('.first-line').textContent)
const col = Number(li.querySelector('.first-col').textContent)
const lastLine = Number(li.querySelector('.last-line').textContent)
const lastCol = Number(li.querySelector('.last-col').textContent)
const snippet = getErrorExampleSnippet(
html,
{ line, col },
{ line: lastLine, col: lastCol }
)
console.log(
`%c%s%c (Line %d, Column: %d to Line %d, Column %d)`,
`color: ${type === 'error' ? 'red' : 'yellow'}`,
text,
'',
line,
col,
lastLine,
lastCol
)
console.log(
'| %c%s',
'background: white; font-family: monospace; color: black',
snippet
)
}
async function validate() {
const form = new FormData()
const html = `${new XMLSerializer().serializeToString(document.doctype)}
${document.documentElement.outerHTML}`
form.append('content', html)
const response = await fetch('https://validator.w3.org/nu/', {
method: 'POST',
body: form
})
if (!response.ok)
throw new Error(`HTML Validation request failed with ${response.status}.`)
const text = await response.text()
console.group('HTML Validator')
try {
const doc = new DOMParser().parseFromString(text, 'text/html')
const results = doc.getElementById('results')
if (!results)
throw new Error('There were no results in the validation response 🤔')
const successMessage = results.querySelector('.success')
const failureMessage = results.querySelector('.failure')
const isValid = successMessage && !failureMessage
if (isValid) {
console.log('%c✅ %s', 'color: green', successMessage.innerText)
} else {
const warnings = results.querySelectorAll('ol .warning')
const errors = results.querySelectorAll('ol .error')
console.log('%c❌ %s', 'color: red', failureMessage.innerText)
console.group('Errors')
Array.from(errors).forEach(li => logItem(li, html, 'error'))
console.groupEnd()
console.group('Warnings')
Array.from(warnings).forEach(li => logItem(li, html, 'warning'))
console.groupEnd()
}
} catch (error) {
throw new Error(
`Failed to parse the results of the validator. (${error.message})`
)
}
console.groupEnd()
}
validate()
const observer = new MutationObserver(validate)
observer.observe(document.documentElement, {
attributes: true,
subtree: true
})
})()
@LukeChannings
Copy link
Author

Paste into the JavaScript console and get page HTML validation as you go through a journey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment