JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html lang="fr">
    <head>
        <meta charset="utf-8"/>
        <title>diff</title>
        <link href="diff.css" rel="stylesheet" type="text/css"/>
    </head>
    <body class="couleur">
        <svg id="svg"></svg>
        <pre id="sortie1"></pre>
        <pre id="sortie2"></pre>
        <div id="inter1"></div>
        <div id="inter2"></div>
        <textarea id="entrée1" placeholder="Écrivez ici un premier texte à comparer"></textarea>
        <textarea id="entrée2" placeholder="Écrivez ici un second texte à comparer"></textarea>
        <script type="text/javascript" src="diff.js"></script>
    </body>
</html>

CSS

.couleur .diff {
  background:#ffff00;
}

.couleur .ajout {
  background:#ff6347;
}
.couleur .diff:hover, .couleur .ajout:hover, .couleur .enAvant {
  background:#d7ffaa;
  border-color:#d7ffaa;
}

.diff {
    //font-style:italic;
}

.ajout {
    //font-weight:bold;
}

html, body, #svg {
    height:100%;
    width:100%;
    margin:0;
    padding:0;
    overflow:hidden;
}    

#inter1, #inter2 {
    display:none;
}

#entrée1, #entrée2, #sortie1, #sortie2 {
    position:fixed;
    background:none;
    //width:calc(50% - 4px);
    //margin:2px;
    //padding:2px;
    width:50%;
    margin:0;
    padding:0;
    font-family:monospace;
    height:100%;
    top:0;
    border:0;
    opacity:1;
    left:0;
    overflow-y:auto;
    resize:none;
}

#entrée2, #sortie2 {
    left:50%;
}

#sortie1, #sortie2 {
    opacity:1;
    color:red;
}    

textarea {
  height:100%;
  width:100%;
}

JavaScript

const entrée1 = document.getElementById("entrée1");
const entrée2 = document.getElementById("entrée2");
const inter1 = document.getElementById("inter1");
const inter2 = document.getElementById("inter2");
const sortie1 = document.getElementById("sortie1");
const sortie2 = document.getElementById("sortie2");
const svg = document.getElementById("svg");
let idDiff = 0;

/**
 * Renvoie la chaîne la plus longue contenue dans 2 chaînes. ("abcdef", "0abcdEf") => ["abcd", 0, 1]
 *
 * @param {chaîne} a
 * @param {chaîne} b
 * @return tableau dont le premier élément est la chaîne la plus longue et les deux suivants sa position dans les chaînes a et b.
 *
function plusLongueChaîneCommune(a, b) {
    "use strict";
    const la = a.length;
    const lb = b.length;
    if (la > lb) {
        const res = plusLongueChaîneCommune(b, a);
        return [res[0], res[2], res[1]];
    }
    let début = 0;
    let chaîneLaPlusLongue = "";
    let positionChaîneLaPlusLongueDansA;
    let positionChaîneLaPlusLongueDansB;
    let longueurChaîneLaPlusLongue = 0;
    let fin = 1;
    // début va parcourir la chaîne a
    while (fin < la) {
        // pour chaque a.substring(début, fin), on regarde si il est contenu dans b
        let appartient = b.indexOf(a.substring(début, fin));
        if (appartient !== -1) {
            let finB = appartient + longueurChaîneLaPlusLongue + 1;
            while (fin < la && finB < lb && a.charAt(fin) === b.charAt(finB)) {
                fin += 1;
                finB += 1;
            }
            if (fin > la || finB > lb) {
                fin -= 1;
            }
            chaîneLaPlusLongue = a.substring(début, fin);
            longueurChaîneLaPlusLongue = chaîneLaPlusLongue.length;
            positionChaîneLaPlusLongueDansA = début;
            positionChaîneLaPlusLongueDansB = appartient;
        }
        début += 1;
        fin = début + longueurChaîneLaPlusLongue + 1;
    }
    return [chaîneLaPlusLongue, positionChaîneLaPlusLongueDansA,...