Piero V.

Contenteditable: un'utopia

Qualche tempo fa avevo cominciato a sviluppare una piccola webapp ad uso interno con Vue.js e, volendo implementare dei tag, mi serviva anche un input per modificarli.

Prima che un mio amico mi consigliasse Vue-Multiselect, avevo provato diversi tag input, di cui alcuni non funzionanti, altri invece che non soddisfacevano tutti i miei requisiti: l’integrazione con Vue, la possibilità di integrarli col design del resto del sito (o quanto meno che sembrassero abbastanza coerenti con Bootstrap, visto che mi sto basando su quello) e che avessero l’autocompletamento.

Non trovandone nessuno che facesse al caso mio, ho deciso di cominciare a scrivere un input tag “universale” con queste caratteristica:

  • indipendenza da qualsiasi libreria, in modo che se altri si fossero trovati nella mia situazione avrebbero potuto usarlo;
  • completa libertà grafica per i designer;
  • possibilità di implementare un auto completamento (scriverne uno che non abbia alcuna dipendenza è un lavoro abbastanza lungo e inutile).

Come soluzione avevo trovato di usare un div con contenteditable="true" (un attributo molto, molto vecchio, disponibile persino su Internet Explorer 6, “il terribile”) e un MutationObserver per individuare le varie modifiche fatte a questo.

Ero quasi pronto a pubblicarlo (avevo fatto anche alcune demo della libreria), quando mi sono reso conto di non aver fatto una cosa essenziale: il test di compatibilità sui vari browser.

Il motivo per cui avevo scelto questa soluzione è che un input realizzato in questo modo è molto simile agli input nativi del browser, tant’è vero che se si applicano le stesse regole CSS a un div editabile e a un input si ottiene un aspetto identico, anche per quanto riguarda i vari modificatori (:focus, in particolare).

Una delle funzionalità che avevo raggiunto e che mi piacevano di più, è che mettendo sui vari figli contenteditable="false", si riesce a cancellare il figlio interamente.

Ma non su Firefox. Da anni esiste un bug aperto sul tracker di Firefox per segnalare questo comportamento, ma ad oggi ancora non si riesce a risolvere. Inoltre Firefox ha bisogno di un break per gestire correttamente l’eventualità del tag vuoto, altrimenti il div assume altezza 0 e si vedono solo i bordi.

Su Edge invece il backspace cancella tutti i tag, che sono realizzati mediante degli span con contenteditable="false" e non hanno alcuno spazio a separarli.

Il comportamento peggiore lo ho riscontrato su Internet Explorer 11: cliccando sui vari tag, venivano fuori gli strumenti di modifica, per esempio per ridimensionare lo span.

Alla fine un mio amico mi ha appunto suggerito una libreria fatta molto bene e che soddisfa tutti i miei requisiti, quindi, visto che comunque avrei dovuto cercare qualcosa per l’autocompletamento, ho deciso di usare questa e lasciare stare il mio progetto.

Ammetto che però, a questo punto, mi sarebbe piaciuto scrivere un articolo di come avevo reso disponibile una libreria per scrivere degli input per i tag con tutte quelle caratteristiche elencate, invece, con un bel po’ di amarezza, mi ritrovo a scrivere di come ancora ci siano tutte queste inconsistenze, per delle funzionalità che esistono da anni.

Riconosco che in primo luogo ho sbagliato io a non controllare subito il comportamento dei vari browser prima di scrivere il javascript, visto che ci ho impiegato anche un bel po’ di tempo.

In ogni caso, non ho cancellato tutto, ma ho pubblicato lo stesso il mio sforzo su GitHub, anche se ormai l’unico scopo che può avere è quello di avvertimento.