if ((/^localhost/).test(document.location.host)) { | |
var linkChecker = (function() { | |
"use strict"; | |
let links, errors = [], completed = [], errorCounter = 0; | |
function addStyle(styleString) { | |
const style = document.createElement("style"); | |
style.textContent = styleString; | |
document.head.append(style); | |
} | |
function finished(counter) { | |
completed.push(counter); | |
if (completed.length === links.length) { | |
errors = errors.filter(e => typeof e === "object"); | |
if (errors.length > 0) { | |
let errorNav = `${errors.length} Link Errors: <a href="javascript:linkChecker.prevError()">▲</a><a href="javascript:linkChecker.nextError()">▼</a>`; | |
addStyle( | |
` | |
#linkCheckerErrorDialog { | |
background-color: rgba(255,0,0,.9); | |
border-radius: 5px; | |
color: white; | |
display: flex; | |
font-weight: bolder; | |
padding: 5px; | |
position: fixed; | |
left: 5px; | |
top: 5px; | |
z-index: 10000; | |
} | |
#linkCheckerErrorDialog a { | |
background: none; | |
color: white; | |
display: inline-block; | |
padding: 0 .5em; | |
text-decoration: none; | |
} | |
.linkError { | |
border: solid 1px rgba(255,0,0,.6); | |
border-radius: 1em; | |
padding: 0 5px; | |
background: rgba(255,0,0,.02); | |
} | |
.linkError:target { | |
background: rgba(255,0,0,.5); | |
color: #fff; | |
} | |
.linkError:target::after { | |
content: attr(href); | |
color: #fff; | |
position: fixed; | |
bottom: 5px; | |
left: 5px; | |
background: rgba(0,0,0,.5); | |
height: 2em; | |
line-height: 2; | |
padding: 0 5px; | |
border-radius: 5px; | |
} | |
` | |
); | |
let errorDialog = document.createElement("div"); | |
errorDialog.id = "linkCheckerErrorDialog"; | |
errorDialog.innerHTML = errorNav; | |
document.body.appendChild(errorDialog); | |
} | |
} | |
} | |
var linkChecker = { | |
currentError: -1, | |
errors: [], | |
nextError: function() { | |
let err = linkChecker.currentError; | |
if (err >= errors.length - 1) { | |
err = 0; | |
} else { | |
err += 1; | |
} | |
let target = "#" + errors[err][0]; | |
document.location.hash = target; | |
linkChecker.currentError = err; | |
}, | |
prevError: function() { | |
let err = linkChecker.currentError; | |
if (err <= 0) { | |
err = errors.length - 1; | |
} else { | |
err -= 1; | |
} | |
let target = "#" + errors[err][0]; | |
document.location.hash = target; | |
linkChecker.currentError = err; | |
}, | |
check: function() { | |
links = document.querySelectorAll("a[href]"); | |
links.forEach((i, idx) => { | |
var xhr = new XMLHttpRequest(); | |
xhr.onreadystatechange = function() { | |
if (xhr.readyState === 4) { | |
if (xhr.status >= 400) { | |
i.classList += " linkError"; | |
i.id = "error-" + errorCounter; | |
errors[idx] = [i.id, i.href]; | |
errorCounter += 1; | |
} | |
finished(idx); | |
} | |
}; | |
xhr.open("HEAD", i.href); | |
xhr.send(); | |
}); | |
} | |
}; | |
return linkChecker; | |
})(); | |
document.addEventListener("DOMContentLoaded", (event) => { | |
linkChecker.check(); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment