W poprzednich wpisach pokazałem jak dodawać własne przyciski do edytora TinyMCE oraz wstawić własny kod do edytora. Pora na zagadnienie bardziej złożone – dodawanie własnego formatowania i sprawienie by zachowywało się ono tak jak podstawowe przyciski formatowania dostępne w TinyMCE.
Pełny kod wtyczki opisywanej w poniższym wpisie znajduje się na Githubie.
Standardowe przyciski formatowania działają tak, że gdy kursor wprowadzania tekstu znajduje się w sformatowanym ciągu znaków są one aktywne. Dodanie takiego zachowania jest dostępne również dla naszych własnych przycisków.
Zacznijmy od podstaw skryptu dodającego przycisk – stworzymy przycisk, który tworzy duży tekst:
(function() { tinymce.PluginManager.add('dziudek_bigtext_button', function( editor, url ) { editor.addButton("dziudek_bigtext_button", { title: 'Big text', tooltip: "Toggle big text", icon: 'icon dashicons-arrow-up-alt2' }) }); })();
Aby stworzyć formatowanie tekstu dla którego można zarządzać stanami przycisków musimy skorzystać z obiektu odpowiadającego za formatowanie tekstu i stworzyć funkcję, która odpowiednio go skonfiguruje:
var editorFormatterSetup = function(self) { editor.formatter.register('bigtext', { inline: 'strong', styles: {fontSize : '32px'} }); editor.formatter.formatChanged('bigtext', function(state) { self.active(state); }); };
Powyższa funkcja tworzy nowy styl formatowania – bigtext, który korzysta ze znacznika strong oraz nadaje mu atrybut style z rozmiarem tekstu ustawionym na 32 piksele. Funkcja ta jako argument przyjmuje uchwyt do przycisku, który obsługuje dane formatowanie.
Kolejnym krokiem jest obsłużenie akcji zmiany stylu formatowania – służy do tego zdarzenie formatChanged, które jako pierwszy argument przyjmuje nazwę sposobu formatowania tekstu dla którego jest wywoływana funkcja podana jako drugi argument – w naszym wypadku będzie ona zmieniać stan przycisku pomiędzy stanami: aktywny i nieaktywny. Nie musimy tych stanów dodatkowo stylować, gdyż są one domyślnie ostylowane w edytorze.
Pora wykorzystać naszą funkcję – umieszczamy ją wewnątrz funkcji wywoływanej przy dodawaniu przycisku a dodatkowo definiujemy dwie akcje: onclick oraz onpostrender:
(function() { tinymce.PluginManager.add('dziudek_bigtext_button', function( editor, url ) { var editorFormatterSetup = function(self) { editor.formatter.register('bigtext', { inline: 'strong', styles: {fontSize : '32px'} }); editor.formatter.formatChanged('bigtext', function(state) { self.active(state); }); }; editor.addButton("dziudek_bigtext_button", { title: 'Big text', tooltip: "Toggle big text", icon: 'icon dashicons-arrow-up-alt2', onclick: function() { editor.formatter.toggle('bigtext'); }, onpostrender: function() { var self = this; if(editor.formatter) { editorFormatterSetup(self); } else { editor.on('init', function() { editorFormatterSetup(self); }); } } }); }); })();
Akcja onclick jest już nam znana – w tym wypadku po prostu wywołujemy zmianę formatowania dla zaznaczonego tekstu z użyciem funkcji, która automatycznie włącza lub wyłącza formatowanie w zależności od tego czy było ono uprzednio zaaplikowane dla danego tekstu czy też nie. Jak widać dzięki funkcji toggle obiektu formatującego tekst w TinyMCE nie musimy się w ogóle martwić o wyodrębnienie zaznaczonego tekstu i sprawdzenie czy ma on zaaplikowane konkretne stylowanie czy też nie – a wszystko to dzięki temu, że skorzystaliśmy uprzednio ze stworzenia własnego stylu formatowania tekstu.
W akcji onpostrender definujemy kod, który wykona się przy renderowaniu posta w edytorze. W naszym wypadku tworzymy uchwyt do przycisku w postaci zmiennej self. Następnie w zależności od tego czy obiekt formatujący tekst w edytorze już istnieje czy też nie wywołujemy naszą funkcję konfigurującą nasz styl formatowania. W wypadku gdy obiekt ten nie jest zdefiniowany w momencie tworzenia naszego przycisku, nasza funkcja zostanie wywołana podczas inicjalizacji edytora.
W tym momencie mamy już działające zarządzanie stanami naszego przycisku:
Pozwolę sobie opisać jeszcze jedno udogodnienie, które wymaga dodanie dodatkowego kodu przy zmianie stanu przycisku:
(function() { tinymce.PluginManager.add('dziudek_bigtext_button', function( editor, url ) { var editorFormatterSetup = function(self) { editor.formatter.register('bigtext', { inline: 'strong', styles: {fontSize : '32px'} }); editor.formatter.formatChanged('bigtext', function(state) { self.active(state); if(state) { document.querySelector('#' + self._id + ' i').setAttribute('class', 'mce-ico mce-i-icon dashicons-arrow-down-alt2'); } else { document.querySelector('#' + self._id + ' i').setAttribute('class', 'mce-ico mce-i-icon dashicons-arrow-up-alt2'); } }); }; editor.addButton("dziudek_bigtext_button", { title: 'Big text', tooltip: "Toggle big text", icon: 'icon dashicons-arrow-up-alt2', onclick: function() { editor.formatter.toggle('bigtext'); }, onpostrender: function() { var self = this; if(editor.formatter) { editorFormatterSetup(self); } else { editor.on('init', function() { editorFormatterSetup(self); }); } } }); }); })();
W tym momencie poza stanem przycisku zmienią się też klasy CSS przypisane do naszego przycisku a jego wygląd będzie zależny od jego stanu:
Na koniec mała wskazówka dla tych, którzy niekoniecznie chcą korzystać z atrybutów <strong>style</strong> do stylowania tekstu – oczywiście można też użyć klas CSS:
editor.formatter.register('bigtext', { inline: 'strong', classes: 'big-text' });
Powyższy kod doda klasę big-text do elementu strong – oczywiście warto pamiętać by plik editor.css w wykorzystywanym motywie zawierał odpowiedni kod stylujący tą klasę CSS.
Więcej o atrybutach obiektów konfigurujących sposoby formatowania tekstu można przeczytać w tym artykule.