TinyMCE – zarządzanie stanami przycisków

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:

[js](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′
})
});
})();[/js]

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:

[js]var editorFormatterSetup = function(self) {
editor.formatter.register(’bigtext’, {
inline: 'strong’,
styles: {fontSize : ’32px’}
});

editor.formatter.formatChanged(’bigtext’, function(state) {
self.active(state);
});
};[/js]

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:

[js highlight=”3-12,18-32″](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);
});
}
}
});
});
})();[/js]

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:

btn_state_1

Pozwolę sobie opisać jeszcze jedno udogodnienie, które wymaga dodanie dodatkowego kodu przy zmianie stanu przycisku:

[js highlight=”12,13,14,15,16″](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);
});
}
}
});
});
})();[/js]

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:

btn_state_2

btn_state_3

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:

[js highlight=”3″]editor.formatter.register(’bigtext’, {
inline: 'strong’,
classes: 'big-text’
});[/js]

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.