Personal tools

Jan 24, 2013

Plone: i bizzarri comportamenti di TinyMCE e Chrome

Una soluzione all'espansione dell'area di testo TinyMCE attraverso le colonne laterali, che si verifica in Chrome

Nelle ultime installazioni di Plone 4 è emerso un bug molto fastidioso. Di tanto in tanto accade che, aprendo un contenuto in modifica, utilizzando il browser Chrome, la pagina si apra sbordando sul lato destro e uscendo completamente dal contenuto principale.

L'effetto è spiacevole, perché parte dei campi di input invadono i riquadri della colonna destra.

Ho potuto riscontrare lo stesso problema in una qualsiasi installazione di Plone 4, con il semplice utilizzo del tema Sunburst e nessun add-on.

Se l'utente ricarica la pagina, il contenuto centrale si ridimensiona tornando al proprio posto.

Il metodo per replicare il problema, con assoluta certezza che riaccada, è quello di aprire una pagina in modifica e spostarsi dal tab "Default" nel tab "Impostazioni" e poi tornare al tab "Default". Tutto questo succede usando Chrome.

Attraverso un serie di test ho potuto osservare che tale comportamento è dovuto alla presenza di almeno un campo con editor di testo TinyMCE.

 

Purtroppo non è servito giocare con le impostazioni di TinyMCE relative al ridimensionamento automatico, come mi aveva gentilmente suggerito Vito Falco nella lista italiana di Plone.

 

Dopo varie ricerche ho trovato il bug ufficiale"Sunburst Theme: Expanding textarea's right portlets bleed through".

Indagando meglio, ho scoperto che il bug è causato dalla toolbar di TinyMCE e molto probabilmente è imputabile al tipo di struttura utilizzata, ovvero una serie di tabelle nidificate. Le icone nella toolbar sono raggruppate in tabelle che si trovano in float left, a loro volta inserite in un elemento HTML td di un'altra tabella. Al caricamento della pagina, queste tabelle ignorano la dimensione del contenuto e si posizionano su una medesima riga, causando lo spiacevole effetto che vi ho descritto.

 

Una soluzione

maartenkling ha proposto un semplice e funzionante workaround: rimuovere il floating sulle tabelle che raggruppano le icone.
span.ploneSkin table.mceToolbar {
     float: none;
}
Purtroppo con questa modifica le icone non occupano tutto lo spazio orizzontale disponibile: gruppi di icone vengono mostrati su più linee anche se esiste lo spazio sufficiente per mostrarle tutte su una singola linea, ad esempio nel caso in cui non vi siano colonne laterali.

La mia soluzione

In attesa che la struttura di TinyMCE venga migliorata, un altro modo per risolvere il problema è quello di specificare la larghezza del contenuto sull'elemento HTML td contenitore delle tabelle di icone, recuperando tale larghezza dalla table principale. In questo modo la larghezza non viene più ignorata e, se non è sufficiente per mostrare tutte le icone su una singola linea, i gruppi si posizionano uno sotto l'altro.

In pratica, all'inizializzazione dell'editor dobbiamo ottenere le dimensioni riguardanti la larghezza dalla tabella che ha la classe "mceLayout", poiché questo è l'elemento HTML padre più prossimo su cui sono definite dimensioni relative all'editor. Presa la larghezza, la dobbiamo impostare sull'elemento HTML td che contiene le varie toolbar.

La funzione da eseguire è questa:
function myCustomInitInstance(inst) {

// tabella contenitore che possiede le dimesioni
var tinytable = $("table.mceLayout");

// elemento td che contiene le toolbar
var tinytoolbar = tinytable.find("tr.mceFirst td.mceToolbar");

// fissiamo le dimensioni sul contenitore delle toolbar
$(tinytoolbar).css("width",$(tinytable).css("width"));
}
Rimane da trovare il punto esatto in cui agganciare questa funzione. Essa deve essere eseguita dopo l'inizializzazione di TinyMCE.

Per questo scopo ho deciso di utilizzare "init_instance_callback", un'opzione di configurazione di TinyMCE. Questa opzione deve contenere il nome di una funzione che verrà eseguita ogni volta che sarà inizializzata un'istanza dell'editor. Essa deve essere specifica nell'inizializzazione di TinyMCE ("tinyMCE.init").
tinyMCE.init({
...
init_instance_callback : "myCustomInitInstance" });
function myCustomInitInstance(inst) {
alert("Editor: " + inst.editorId + " is now initialized.");
}
Il formato della funzione è: InitInstance (inst), dove inst è l'istanza dell'oggetto editor.
Ricapitolando, ho personalizzato il file tiny_mce_init.js, dove viene inizializzato l'oggetto TinyMCE, assegnando all'opzione "init_instance_callback" la mia funzione "myCustomInitInstance".

...
var init_dict = {
...
init_instance_callback : "myCustomInitInstance"
}
...
Quindi "myCustomInitInstance" verrà eseguita all'inizializzazione dell'editor e servirà per impostare la larghezza disponibile alla toolbar, prendendo tale larghezza dall'elemento padre più prossimo.

L'ultima modifica da fare è cambiare la proprietà display del contenitore HTML td, altrimenti la table innestata ignorerà la larghezza dell'elemento padre appena fissata.
td.mceToolbar {
     display:block;
}

Con queste brevi linee di codice possiamo evitare che l'editor invada la colonna laterale destra. Il passo successivo sarà quello di investigare su come questa soluzione diventi definitiva per il bug. Altri suggerimenti per risolvere il problema sono ben accetti!

La foto in testata è di bowenmurphy.

Filed under: , ,
comments powered by Disqus