Ce bookmarklet permet de nettoyer le code HTML copié d’une page web pour pouvoir le coller dans un document LibreOffice Writer
Le nettoyage du code HTML est effectué avec les caractéristiques suivantes :
Cette extension se présente sous la format d’un bookmarklet. Pour pouvoir l’installer, glissez-déposer le lien ci-dessous dans la barre des favoris de votre navigateur
Une fois installé, allez sur une page, sélectionnez le texte et cliquez sur le lien dans votre barre de favoris.
(function () {
const usefulAttributes = ["href", "src", "alt"]
function isUsefulAttribute(attribute) {
return (usefulAttributes.indexOf(attribute.name.toLowerCase()) != -1)
}
const badTags = ["script", "noscript"]
function isBadTag(element) {
return (element.nodeType == Node.ELEMENT_NODE)
&& (badTags.indexOf(element.nodeName.toLowerCase()) != -1)
}
const usefulTags = [
"p", "h1", "h2", "h3", "h4", "h5", "h6", "strong", "em", "ul", "ol", "li",
"sup", "sub", "a", "img", "pre"
]
function isUsefulTag(element) {
return (element.nodeType == Node.ELEMENT_NODE)
&& (usefulTags.indexOf(element.nodeName.toLowerCase()) != -1)
}
function isALink(element) {
return (element.nodeType == Node.ELEMENT_NODE)
&& (element.nodeName.toLowerCase() == "a")
&& (element.hasAttribute("href"))
}
function isAnImage(element) {
return (element.nodeType == Node.ELEMENT_NODE)
&& (element.nodeName.toLowerCase() == "img")
}
function convertImage(src, callback) {
const image = new Image()
image.crossOrigin = "Anonymous"
image.onload = function () {
const canvas = document.createElement("canvas")
const context = canvas.getContext("2d")
canvas.height = this.naturalHeight
canvas.width = this.naturalWidth
context.drawImage(this, 0, 0)
const dataURL = canvas.toDataURL("image/png")
callback(dataURL)
}
image.src = src
}
const typographicRules = [
[/ +/g, " "],
[/'/g, "’"],
[/ ([?!%€$»:;])/g, " $1"],
[/« /g, "« "],
[/\.\.\./g, "…"],
[/([0-9]) ?([%€$£])/g, "$1 $2"],
[/([0-9]{1,3})[ .]([0-9]{3})[ .]([0-9]{3})/g, "$1$2$3"],
[/([0-9]{1,3})[ .]([0-9]{3})/g, "$1$2"],
]
function applyTypography(str) {
for ([regex, replacement] of typographicRules) {
str = str.replace(regex, replacement)
}
return str
}
function cleanTags(fragment) {
let cleaned
if (isBadTag(fragment)) return document.createDocumentFragment()
if (isUsefulTag(fragment)) {
cleaned = document.createElement(fragment.nodeName)
for (const attribute of fragment.attributes) {
if (!isUsefulAttribute(attribute)) continue
cleaned.setAttributeNode(attribute.cloneNode())
}
if (isAnImage(fragment)) {
convertImage(
fragment.getAttribute("src"),
(src) => { cleaned.setAttribute("src", src) }
)
} else if (isALink(fragment)) {
const absoluteLink = new URL(
fragment.getAttribute("href"),
fragment.baseURI
).href
cleaned.setAttribute("href", absoluteLink)
}
} else if (fragment.nodeType == Node.TEXT_NODE) {
cleaned = document.createTextNode(applyTypography(fragment.data))
} else {
cleaned = document.createDocumentFragment()
}
for (const child of fragment.childNodes) {
cleaned.appendChild(cleanTags(child))
}
return cleaned
}
function createPopup(fragment) {
const copyTab = window.open("", "_blank", "popup").document
copyTab.title = "CleanHTML"
copyTab.body.appendChild(fragment)
copyTab.close()
}
const selection = window.getSelection()
if (selection.rangeCount < 1) { return }
const elements = document.createDocumentFragment()
for (let i = 0; i < selection.rangeCount; i++) {
elements.appendChild(window.getSelection().getRangeAt(i).cloneContents())
}
createPopup(cleanTags(elements))
})()