Hlavní navigace

TinyMCE popup okna vs. JQuery

29. 1. 2009 12:22 (aktualizováno) Martin Jonáš

Konečně jsem si našel trochu času na to, abych zase něco napsal. Poslední týdny byly trochu hektické (zkouškové + práce). Takže tento příspěvek bude o problému na který jsme nedávno narazili u nás v práci při vývoji systému Ariadne3.0.

V našem systému používáme jako WYSIWYG editor TinyMCE s několika vlastnímy pluginy. Nedávo jsme v rámci optimalizací odezvy začali určité části systému předělávat pomocí AJAXu a JQuery tak, aby k jejich načítání docházelo postupně v průběhu práce se stránkou. Hlavní optimalizace se týkala stromového menu systému, které na některých zakázkách bylo již poměrně rozsáhlé. Tím jsme odezvu systému v některých případech zlepšili až 10×. Pak ovšem přišel problém.

Naše pluginy pro TinyMCE používají popup okna, ve kterých uživatel zadává parametry vkládaných systémových tagů. V několika případech je tímto parametrem i výběr položky ze stromového menu. Problém byl v tom, že kód, který bez problému fungoval všude v systému v popup oknech TinyMCE pracovat přestal. Největší záhadou, ale bylo, že chybová konzole nenahlásila sebemenší chybu. Kód prostě nefungoval.

Po nějaké době hledání se nám podařilo určit, že důvodem je vložení scriptu tiny_mce_popup.js, který v popup oknech slouží jako helper pro práci s TinyMCE. Konkrétně problém způsobil tento kód:

...
h = document.body.innerHTML;
...
document.body.innerHTML = t.editor.translate(h);
...

Funkce editor.translate má následující obsah:

translate : function(s) {
  var c = this.settings.language, i18n = EditorManager.i18n;
  if (!s) return '';
  return i18n[c + '.' + s] || s.replace(/{\#([^}]+)\}/g, function(a, b) {
    return i18n[c + '.' + b] || '{#' + b + '}';
  });
},

Jde tedy o překlad jazykových hodnot v popup okně. TinyMCE prostě vezme HTML kód popup okna a nahradí všechny výskyty {#id} za text příslušející danému id. Problém je v tom, že poté provede nahrazení kódu popup okna novým HTML. To také znamená, že prohlížeč musí sestavit nový DOM strom. A zde je ten problém. Pokud měl jQuery v DOM stromu nějaké vlastní modifikace (např. přižazené callbacky) po sestavení nového DOM se tyto modifikace ztratí.

Problém jsme vyřešili tak, že jsme v našich pluginech vypnuli překlady od TinyMCE, které naštěstí nepotřebujeme, protože obsah popup okna je generován na serveru systémeme ariadne3.0, který má vlastní nástroje pro lokalizaci. Protože ale v ostatních pluginech je potřeba aby překlad stále probíhal přidali jsme k vynutí překladu podmínku, které se řídí příznakem, který nastavujeme pouze v našich popup oknech.

if (typeof(tiny_mce_disable_translate)=='undefined'){
  document.body.innerHTML = t.editor.translate(h);
}

Není to řešení nejelegantnější, ale funguje.

Pokud máte někdo návrh jak tento problém vyřešit lépe rád si ho přeštu v komentářích pod tímto příspěvkem.