Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Ładowanie bibliotek TinyMCE na żądanie, dynamiczne tworzenie edytorów - problem w Chrome
WebCM
post 11.12.2010, 16:44:17
Post #1





Grupa: Zarejestrowani
Postów: 375
Pomógł: 20
Dołączył: 28.07.2006

Ostrzeżenie: (0%)
-----


Mam problem z dynamicznym tworzeniem edytorów TinyMCE w Google Chrome. Wyświetlą się tylko przy pierwszym wyświetleniu strony, a potem już nie (nie ma błędów w konsoli!) albo na odwrót.

Edytory mogą ładować się na 2 sposoby:
1. Na żądanie - podczas ładowania strony (wywołane w <body>)
2. Na żądanie - po załadowaniu strony (np. po kliknięciu przycisku)

Proces ładowania edytorów:
1. W sekcji <head> dołączam tradycyjnie plik ładujący loader.js
  1. <script type="text/javascript" src="loader.js"></script>

2. Plik loader.js wygląda tak:
[JAVASCRIPT] pobierz, plaintext
  1. function Editor(O)
  2. {
  3. var that = this;
  4.  
  5. //Jeśli nie załadowano tinyMCE, zrób to teraz
  6. if(!Editor.got)
  7. {
  8. include('tiny_mce.js');
  9. Editor.got = true;
  10. }
  11.  
  12. //Funkcja, która dodaje nowy edytor
  13. var init = function()
  14. {
  15. that.o = tinymce.add(new tinymce.Editor(O.id, {
  16.  
  17. //ustawienia wycięte, ale nie mają na to wpływu
  18.  
  19. }));
  20. that.o.render();
  21. };
  22.  
  23. //Jeżeli dokument jest już załadowany
  24. if(Editor.DOM) setTimeout(init,500);
  25.  
  26. //A jeśli nie jest jeszcze załadowany - PATRZ TUTAJ:
  27. else addEvent('load', function() { setTimeout(init,500); Editor.DOM = true })
  28. }
  29.  
  30. Editor.got = Editor.DOM = false;
[JAVASCRIPT] pobierz, plaintext

3. Natomiast instancje obiektu Editor są tworzone w sekcji <body> za formularzem:
  1. <script type="text/javascript">
  2. e = new Editor(formularz.nazwapola);

Bawiłem się w Firebugu do Firefoksa. Jeżeli strona jest już załadowana, dynamiczne wczytanie głównej biblioteki i dodanie nowego edytora nie działa. Czyżby wina TinyMCE? Przykład:
[JAVASCRIPT] pobierz, plaintext
  1. include('tiny_mce.js', function() {
  2. tinyMCE.init({mode:'none'});
  3. var test = new tinymce.Editor('txt', {theme:'advanced'});
  4. tinymce.add(test);
  5. test.render();
  6. });
[JAVASCRIPT] pobierz, plaintext


Funkcja addEvent (chyba) działa prawidłowo, ale gdyby ktoś miał wątpliwości:
[JAVASCRIPT] pobierz, plaintext
  1. function addEvent(type, f, o, capture)
  2. {
  3. if(window.addEventListener)
  4. {
  5. (o||window).addEventListener(type, f, capture||false)
  6. }
  7. else if(window.attachEvent)
  8. {
  9. (o||window).attachEvent('on'+type, f)
  10. }
  11. else if(!o['on'+type])
  12. {
  13. (o||window)[type] = f
  14. }
  15. }
[JAVASCRIPT] pobierz, plaintext

Jedynym wyjściem jest ładowanie głównej biblioteki podczas ładowania strony (przed zdarzeniem window.onload)?

Jak załadować bibliotekę TinyMCE na żądanie, a następnie wyświetlić edytor tak, aby działał w każdej przeglądarce?

Jak sprawdzić, czy wszystkie pliki TinyMCE są załadowane, czyli - czy można już odpalić edytor?

Ten post edytował WebCM 11.12.2010, 16:55:04


--------------------
„Jesteśmy różni, pochodzimy z różnych stron Polski, mamy różne zainteresowania, ale łączy nas jeden cel. Cel ten to Ojczyna, dla której chcemy żyć i pracować.” Roman Dmowski
Go to the top of the page
+Quote Post
erix
post 11.12.2010, 16:58:14
Post #2





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
1. W sekcji <head> dołączam tradycyjnie plik ładujący loader.js

Co to jest? Pierwszy raz na oczy widzę.


--------------------

ZCE :: Pisząc PW załączaj LINK DO TEMATU i TYLKO w sprawach moderacji :: jakiś błąd - a TREŚĆ BŁĘDU? :: nie ponaglaj z odpowiedzią via PW!
Go to the top of the page
+Quote Post
WebCM
post 11.12.2010, 19:43:15
Post #3





Grupa: Zarejestrowani
Postów: 375
Pomógł: 20
Dołączył: 28.07.2006

Ostrzeżenie: (0%)
-----


Cytat
Co to jest? Pierwszy raz na oczy widzę.
To plik na potrzeby skryptu CMS, aby zachować kompatybilność ze standardowym edytorem. Zamieściłem jego zawartość w punkcie nr 2. Jest po to, aby nie modyfikować oryginalnego tiny_mce.js.

Zaproponujcie lepsze rozwiązanie od tego, które przedstawiłem, jeżeli niewiele da się wykombinować tongue.gif


--------------------
„Jesteśmy różni, pochodzimy z różnych stron Polski, mamy różne zainteresowania, ale łączy nas jeden cel. Cel ten to Ojczyna, dla której chcemy żyć i pracować.” Roman Dmowski
Go to the top of the page
+Quote Post
thek
post 11.12.2010, 20:54:11
Post #4





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Zerkni google pod kątem "tinymce dynamic load" ) Zarzucę jednym z wielu wskazywanych wyników smile.gif
http://blog.mirthlab.com/2008/11/13/dynami...nces-to-a-page/


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
WebCM
post 23.12.2010, 12:50:15
Post #5





Grupa: Zarejestrowani
Postów: 375
Pomógł: 20
Dołączył: 28.07.2006

Ostrzeżenie: (0%)
-----


To stary sposób wstawiania i usuwania edytorów. Nowe wersje TinyMCE mają do tego celu API. Szukałem w Google innych sposobów, ale nie ma nic ciekawego. Pobawiłem się w Firebugu i wynika, że...

Po załadowaniu głównej biblioteki tiny_mce.js wystarczy wywołać
[JAVASCRIPT] pobierz, plaintext
  1. include('tiny_mce.js', function() {
  2. var editor = new tinymce.Editor('id_pola', {opcje});
  3. editor.render(); //od tej chwili TinyMCE zacznie ładować pozostałe pliki
  4. tinyMCE.add(editor); //to nie jest konieczne?
  5. });
[JAVASCRIPT] pobierz, plaintext
Występował inny problem opisany tu: http://tinymce.moxiecode.com/punbb/viewtopic.php?pid=83564

Jak widać, 4 dni temu pojawiła się solucja, którą za chwilę przetestuję. W skrócie:
1. Nie ładuj biblioteki tiny_mce.js wielokrotnie!
2. Używaj opcji strict_loading_mode

Przestroga: tinyMCE jest skrótem do obiektu tinymce.EditorManager - to nie to samo co tinymce!

Problem w Chrome powraca. Edytory TinyMCE wyświetlą się tylko po odświeżeniu strony. W przeciwnym przypadku widać, że plik tiny_mce.js ładuje się i nic. Zbadałem przyczynę. Okazuje się, że zdarzenie HTMLScriptElement.onload nie zawsze występuje! Funkcja include() wygląda tak:
[JAVASCRIPT] pobierz, plaintext
  1. function include(file, loaded)
  2. {
  3. var js = document.createElement('script');
  4. js.type = 'text/javascript';
  5. js.src = file;
  6.  
  7. //Wywołaj funkcję, gdy plik zostanie załadowany
  8. if(loaded)
  9. {
  10. //IE, Opera
  11. if(js.readyState)
  12. {
  13. js.onreadystatechange = function()
  14. {
  15. if(js.readyState == 'complete' || js.readyState == 'loaded')
  16. {
  17. loaded(); js.onreadystatechange = null
  18. }
  19. }
  20. }
  21.  
  22. //Firefox, Chrome, Safari, Opera - TU JEST PROBLEM
  23. else js.onload = loaded;
  24. }
  25. document.getElementsByTagName('head')[0].appendChild(js)
  26. }
[JAVASCRIPT] pobierz, plaintext
Dla pewności zbadałem, że WebKit NIE ma własności readyState. Podejrzewam, że nie da się zrobić nic więcej. Sami przetestujcie na własnych skryptach, czy to błąd, czy funkcja (bug or feature) tongue.gif

Na pewno programiści zgłaszali błąd zarówno do Google i do Apple i nic.

AKTUALIZACJA

Moje pierwsze spostrzeżenia były błędne. Zdarzenie HTMLScriptElement.onload wywołuje się zawsze. To ewidentnie wina TinyMCE, tylko dlaczego w innych przeglądarkach problem nie występuje? Mimo wszystko wierzę, że window.onload w Chrome wywołuje się za wcześnie i stąd metoda tinyMCE.init() nie działa.

AKTUALIZACJA 2

Znalazłem przyczynę. Klasa tinymce.dom.EventUtils działa nieprawidłowo na silniku WebKit. Funkcja add:
Kod
if (n == 'init')
{
    if (t.domLoaded)
    {
        console.log('DOM loaded - callback will be called');
        cb();
    }
    else
    {
        console.log('DOM not ready - put callback onto stack');
        t.inits.push(cb);
    }
    return cb;
}
t.inits.push(cb); to ostatnia ważna operacja. Potem nic się nie dzieje. Wywołanie:
Kod
Event.add(document, 'init', function() {

Są tylko 2 miejsca, gdzie własność .domLoaded jest ustawiana na TRUE: _pageInit and _wait. Inny ważny kod:
Kod
else if (doc.addEventListener) {
    t._add(win, 'DOMContentLoaded', function() {
        t._pageInit(win);
    });
}
oraz
Kod
Event = tinymce.dom.Event = new tinymce.dom.EventUtils();

// Dispatch DOM content loaded event for IE and Safari
Event._wait(window);
Oba zdarzenia DOMContentLoaded i onload nie wykonują się, czyli musiały zostać wywołane wcześniej.

Jednak .domLoaded ma wartość TRUE - który fragment kodu go ustawia, jeżeli _pageInit() nie jest wywoływana?

Szukam rozwiązania. Może ktoś już wpadł i nie będę musiał spędzić kolejnego dnia na to cool.gif

Ten post edytował WebCM 23.12.2010, 12:50:51


--------------------
„Jesteśmy różni, pochodzimy z różnych stron Polski, mamy różne zainteresowania, ale łączy nas jeden cel. Cel ten to Ojczyna, dla której chcemy żyć i pracować.” Roman Dmowski
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 13.08.2025 - 22:53