diff --git a/dist/langs/ca.min.js b/dist/langs/ca.min.js
new file mode 100644
index 000000000..94717ac68
--- /dev/null
+++ b/dist/langs/ca.min.js
@@ -0,0 +1,11 @@
+/* ===========================================================
+ * ca.js
+ * Catalan translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Àlfons Sánchez (alsanan)
+ * Twitter : @alsanan
+ * Website : about.me/alsanan
+ * Github : https://github.com/alsanan
+ */
+jQuery.trumbowyg.langs.ca={viewHTML:"Veure HTML",formatting:"Formatar",p:"Paragraf",blockquote:"Citació",code:"Codi",header:"Títol",bold:"Negreta",italic:"Itàlica",strikethrough:"Suprimir",underline:"Subratllat",strong:"Forta",em:"Èmfasi",del:"Apagar",unorderedList:"Lista desordenada",orderedList:"Lista ordenada",insertImage:"Inserir imatge",insertVideo:"Inserir vídeo",link:"Enllaç",createLink:"Crear un enllaç",unlink:"Eliminar enllaç",justifyLeft:"Alinear a esquerra",justifyCenter:"Centrar",justifyRight:"Alinear a dreta",justifyFull:"Justificar",horizontalRule:"Inserir separador horitzontal",fullscreen:"Pantalla completa",close:"Tancar",submit:"Enviar",reset:"Reiniciar",invalidUrl:"URL invàlida",required:"Obligatori",description:"Descripció",title:"Títol",text:"Text"};
\ No newline at end of file
diff --git a/dist/langs/de.min.js b/dist/langs/de.min.js
new file mode 100644
index 000000000..1b9e936ae
--- /dev/null
+++ b/dist/langs/de.min.js
@@ -0,0 +1,9 @@
+/* ===========================================================
+ * de.js
+ * German translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Manfred Timm
+ * Github : https://github.com/Manfred62
+ */
+jQuery.trumbowyg.langs.de={viewHTML:"HTML anzeigen",formatting:"Formatieren",p:"Absatz",blockquote:"Zitat",code:"Code",header:"Überschrift",bold:"Fett",italic:"Kursiv",strikethrough:"Durchgestrichen",underline:"Unterstrichen",strong:"Wichtig",em:"Betont",del:"Gelöscht",unorderedList:"Ungeordnete Liste",orderedList:"Geordnete Liste",insertImage:"Bild einfügen",insertVideo:"Video einfügen",link:"Link",createLink:"Link einfügen",unlink:"Link entfernen",justifyLeft:"Links ausrichten",justifyCenter:"Zentrieren",justifyRight:"Rechts ausrichten",justifyFull:"Blocksatz",horizontalRule:"Horizontale Linie einfügen",fullscreen:"Vollbild",close:"Schliessen",submit:"Bestätigen",reset:"Rücksetzen",invalidUrl:"Ungültige URL",required:"Erforderlich",description:"Beschreibung",title:"Titel",text:"Text"};
\ No newline at end of file
diff --git a/dist/langs/es.min.js b/dist/langs/es.min.js
new file mode 100644
index 000000000..b4bcae9f5
--- /dev/null
+++ b/dist/langs/es.min.js
@@ -0,0 +1,9 @@
+/* ===========================================================
+ * es.js
+ * Spanish translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Moisés Márquez
+ * Email : moises.marquez.g@gmail.com
+ */
+jQuery.trumbowyg.langs.es={viewHTML:"Ver HTML",formatting:"Formato",p:"Párrafo",blockquote:"Cita",code:"Código",header:"Título",bold:"Negrita",italic:"Cursiva",strikethrough:"Tachado",underline:"Subrayado",strong:"Negrita",em:"Énfasis",del:"Borrar",unorderedList:"Lista Desordenada",orderedList:"Lista Ordenada",insertImage:"Insertar una imagen",insertVideo:"Insertar un vídeo",link:"Enlace",createLink:"Insertar un enlace",unlink:"Suprimir un enlace",justifyLeft:"Izquierda",justifyCenter:"Centrar",justifyRight:"Derecha",justifyFull:"Justificado",horizontalRule:"Insertar separador horizontal",fullscreen:"Pantalla completa",close:"Cerrar",submit:"Enviar",reset:"Cancelar",invalidUrl:"URL no válida",required:"Obligatorio",description:"Descripción",title:"Título",text:"Texto"};
\ No newline at end of file
diff --git a/dist/langs/es_ar.min.js b/dist/langs/es_ar.min.js
new file mode 100644
index 000000000..826c108be
--- /dev/null
+++ b/dist/langs/es_ar.min.js
@@ -0,0 +1,9 @@
+/* ===========================================================
+ * es_ar.js
+ * Spanish (Argentina) translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Félix Vera
+ * Email : felix.vera@gmail.com
+ */
+jQuery.trumbowyg.langs.es_ar={viewHTML:"Ver HTML",formatting:"Formato",p:"Párrafo",blockquote:"Cita",code:"Código",header:"Título",bold:"Negrita",italic:"Itálica",strikethrough:"Tachado",underline:"Subrayado",strong:"Fuere",em:"Énfasis",del:"Borrar",unorderedList:"Lista Desordenada",orderedList:"Lista Ordenada",insertImage:"Insertar una imagen",insertVideo:"Insertar un video",link:"Vínculo",createLink:"Insertar un vínculo",unlink:"Suprimir un vínculo",justifyLeft:"Alinear a la Izquierda",justifyCenter:"Centrar",justifyRight:"Alinear a la Derecha",justifyFull:"Justificado",horizontalRule:"Insertar separado Horizontal",fullscreen:"Pantalla Completa",close:"Cerrar",submit:"Enviar",reset:"Cancelar",invalidUrl:"URL inválida",required:"Obligatorio",description:"Descripción",title:"Título",text:"Texto"};
\ No newline at end of file
diff --git a/dist/langs/fa.min.js b/dist/langs/fa.min.js
new file mode 100644
index 000000000..efdede4d5
--- /dev/null
+++ b/dist/langs/fa.min.js
@@ -0,0 +1,10 @@
+/* ===========================================================
+ * fa.js
+ * Persian translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Kiarash Soleimanzadeh
+ * Github : https://github.com/kiyarash
+ * Email : kiarash.s@hotmail.com
+ */
+jQuery.trumbowyg.langs.fa={viewHTML:"نمایش کد اچ تی ام ال",formatting:"قالب بندی",p:"پاراگراف",blockquote:"نقل قول",code:"کد",header:"سر تیتر",bold:"ضخیم",italic:"مورب",strikethrough:"میان خط دار",underline:"زیر خط دار",strong:"برجسته",em:"مورب",del:"حذف شده",unorderedList:"لیست نامرتب",orderedList:"لیست مرتب",insertImage:"درج تصویر",insertVideo:"درج ویدئو",link:"لینک",createLink:"درج لینک",unlink:"حذف لینک",justifyLeft:"تراز به چپ",justifyCenter:"تراز به وسط",justifyRight:"تراز به راست",justifyFull:"تراز به چپ و راست",horizontalRule:"درج خط افقی",fullscreen:"تمام صفحه",close:"بستن",submit:"تائید",reset:"انصراف",invalidUrl:"لینک نامعتبر",required:"اجباری",description:"توضیحات",title:"عنوان",text:"متن"};
\ No newline at end of file
diff --git a/dist/langs/fi.min.js b/dist/langs/fi.min.js
new file mode 100644
index 000000000..439e23625
--- /dev/null
+++ b/dist/langs/fi.min.js
@@ -0,0 +1,9 @@
+/* ===========================================================
+ * fi.js
+ * Finnish translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Teppo Koivula (teppokoivula)
+ * Github : https://github.com/teppokoivula
+ */
+jQuery.trumbowyg.langs.fi={viewHTML:"Näytä HTML",formatting:"Muotoilu",p:"Kappale",blockquote:"Lainaus",code:"Koodi",header:"Otsikko",bold:"Lihavointi",italic:"Kursivointi",strikethrough:"Yliviivaus",underline:"Allevivaus",strong:"Vahvennus",em:"Painotus",del:"Poistettu",unorderedList:"Numeroimaton lista",orderedList:"Numeroitu lista",insertImage:"Lisää kuva",insertVideo:"Lisää video",link:"Linkki",createLink:"Luo linkki",unlink:"Poista linkki",justifyLeft:"Asemoi vasemmalle",justifyCenter:"Keskitä",justifyRight:"Asemoi oikealle",justifyFull:"Tasaa",horizontalRule:"Vaakaviiva",fullscreen:"Kokoruutu",close:"Sulje",submit:"Lähetä",reset:"Palauta",invalidUrl:"Viallinen URL-osoite",required:"Pakollinen",description:"Kuvaus",title:"Otsikko",text:"Teksti"};
\ No newline at end of file
diff --git a/dist/langs/fr.min.js b/dist/langs/fr.min.js
new file mode 100644
index 000000000..7f871017f
--- /dev/null
+++ b/dist/langs/fr.min.js
@@ -0,0 +1,10 @@
+/* ===========================================================
+ * fr.js
+ * French translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Alexandre Demode (Alex-D)
+ * Twitter : @AlexandreDemode
+ * Website : alex-d.fr
+ */
+jQuery.trumbowyg.langs.fr={viewHTML:"Voir le HTML",formatting:"Format",p:"Paragraphe",blockquote:"Citation",code:"Code",header:"Titre",bold:"Gras",italic:"Italique",strikethrough:"Rayé",underline:"Souligné",strong:"Fort",em:"Emphase",del:"Supprimé",unorderedList:"Liste à puces",orderedList:"Liste ordonnée",insertImage:"Insérer une image",insertVideo:"Insérer une video",link:"Lien",createLink:"Insérer un lien",unlink:"Supprimer le lien",justifyLeft:"Aligner à gauche",justifyCenter:"Centrer",justifyRight:"Aligner à droite",justifyFull:"Justifier",horizontalRule:"Insérer un séparateur horizontal",fullscreen:"Plein écran",close:"Fermer",submit:"Valider",reset:"Annuler",invalidUrl:"URL invalide",required:"Obligatoire",description:"Description",title:"Titre",text:"Texte"};
\ No newline at end of file
diff --git a/dist/langs/id.min.js b/dist/langs/id.min.js
new file mode 100644
index 000000000..6561511f3
--- /dev/null
+++ b/dist/langs/id.min.js
@@ -0,0 +1,11 @@
+/* ===========================================================
+ * id.js
+ * Indonesian translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Rezha Julio (kimiamania)
+ * Twitter : @kimiamania
+ * Website : http://rezhajulio.web.id
+ * Github : https://github.com/kimiamania
+ */
+jQuery.trumbowyg.langs.id={viewHTML:"Lihat HTML",formatting:"Penyusunan",p:"Paragraf",blockquote:"Kutipan",code:"Kode",header:"Kepala",bold:"Tebal",italic:"Miring",strikethrough:"Coret",underline:"Garis bawah",strong:"Tebal",em:"Miring",del:"Dicoret",unorderedList:"Daftar tak teratur",orderedList:"Daftar teratur",insertImage:"Sisipkan gambar",insertVideo:"Sisipkan video",link:"Tautan",createLink:"Sisipkan Tautan",unlink:"Singkirkan tautan",justifyLeft:"Rata kiri",justifyCenter:"Rata Tengah",justifyRight:"Rata kanan",justifyFull:"Rata kiri dan kanan",horizontalRule:"Sisipkan garis mendatar",fullscreen:"Layar penuh",close:"Tutup",submit:"Setuju",reset:"Batal",invalidUrl:"Tautan salah",required:"Diperlukan",description:"Deskripsi",title:"Judul",text:"Teks"};
\ No newline at end of file
diff --git a/dist/langs/it.min.js b/dist/langs/it.min.js
new file mode 100644
index 000000000..9f5467bee
--- /dev/null
+++ b/dist/langs/it.min.js
@@ -0,0 +1,8 @@
+/* ===========================================================
+ * it.js
+ * Italian translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Mirko Buffoni
+ */
+jQuery.trumbowyg.langs.it={viewHTML:"Mostra HTML",formatting:"Formattazione",p:"Paragrafo",blockquote:"Citazione",code:"Codice",header:"Intestazione",bold:"Grassetto",italic:"Italico",strikethrough:"Barrato",underline:"Sottolineato",strong:"Rafforza",em:"Enfatizza",del:"Cancella",unorderedList:"Elenco puntato",orderedList:"Elenco numerato",insertImage:"Inserisci immagine",insertVideo:"Inserisci video",link:"Collegamento",createLink:"Crea un collegamento",unlink:"Elimina collegamento",justifyLeft:"Allinea a sinistra",justifyCenter:"Centra",justifyRight:"Allinea a destra",justifyFull:"Giustifica",horizontalRule:"Inserisci un separatore orizzontale",fullscreen:"Schermo intero",close:"Chiudi",submit:"Invia",reset:"Annulla",invalidUrl:"URL invalido",required:"Obbligatorio",description:"Descrizione",title:"Titolo",text:"Testo"};
\ No newline at end of file
diff --git a/dist/langs/ko.min.js b/dist/langs/ko.min.js
new file mode 100644
index 000000000..e2afba92b
--- /dev/null
+++ b/dist/langs/ko.min.js
@@ -0,0 +1,10 @@
+/* ===========================================================
+ * ko.js
+ * Korean translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : JoongSeob Vito Kim (dorajistyle)
+ * Blog : http://dorajistyle.pe.kr
+ * Github : https://github.com/dorajistyle
+ */
+jQuery.trumbowyg.langs.ko={viewHTML:"HTML로 보기",formatting:"양식",p:"문단",blockquote:"인용부호",code:"코드",header:"머릿말",bold:"진하게",italic:"기울임",strikethrough:"취소선",underline:"밑줄",strong:"굵게",em:"강조",del:"취소",unorderedList:"순차 목록",orderedList:"비순차 목록",insertImage:"이미지 넣기",insertVideo:"비디오 넣기",link:"링크",createLink:"링크 넣기",unlink:"링크 없애기",justifyLeft:"왼쪽 정렬",justifyCenter:"가운데 정렬",justifyRight:"오른쪽 정렬",justifyFull:"혼합 정렬",horizontalRule:"가로줄 넣기",fullscreen:"전체 화면",close:"닫기",submit:"전송",reset:"초기화",invalidUrl:"올바르지 않은 URL입니다.",required:"꼭 입력해야 합니다.",description:"설명",title:"제목",text:"본문 내용"};
\ No newline at end of file
diff --git a/dist/langs/pl.min.js b/dist/langs/pl.min.js
new file mode 100644
index 000000000..c9fbf4c60
--- /dev/null
+++ b/dist/langs/pl.min.js
@@ -0,0 +1,9 @@
+/* ===========================================================
+ * pl.js
+ * Polish translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Paweł Abramowicz
+ * Github : https://github.com/pawelabrams
+ */
+jQuery.trumbowyg.langs.pl={viewHTML:"Pokaż HTML",formatting:"Format",p:"Akapit",blockquote:"Cytat",code:"Kod",header:"Nagłówek",bold:"Pogrubienie",italic:"Pochylenie",strikethrough:"Przekreślenie",underline:"Podkreślenie",strong:"Wytłuszczenie",em:"Uwydatnienie",del:"Usunięte",unorderedList:"Lista nieuporządkowana",orderedList:"Lista uporządkowana",insertImage:"Wstaw obraz",insertVideo:"Wstaw film",link:"Link",createLink:"Wstaw link",unlink:"Usuń link",justifyLeft:"Wyrównaj do lewej",justifyCenter:"Wyśrodkuj",justifyRight:"Wyrównaj do prawej",justifyFull:"Wyjustuj",horizontalRule:"Odkreśl linią",fullscreen:"Pełny ekran",close:"Zamknij",submit:"Zastosuj",reset:"Przywróć",invalidUrl:"Nieprawidłowy URL",required:"Wymagane",description:"Opis",title:"Tytuł",text:"Tekst"};
\ No newline at end of file
diff --git a/dist/langs/pt.min.js b/dist/langs/pt.min.js
new file mode 100644
index 000000000..9ba374218
--- /dev/null
+++ b/dist/langs/pt.min.js
@@ -0,0 +1,11 @@
+/* ===========================================================
+ * pt.js
+ * Portuguese translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Ramiro Varandas Jr (ramirovjr)
+ * Twitter : @ramirovjnr
+ * Website : about.me/ramirovjnr
+ * Github : https://github.com/ramirovjr
+ */
+jQuery.trumbowyg.langs.pt={viewHTML:"Ver HTML",formatting:"Formatar",p:"Paragráfo",blockquote:"Citação",code:"Código",header:"Título",bold:"Negrito",italic:"Itálico",strikethrough:"Suprimir",underline:"Sublinhado",strong:"Forte",em:"Ênfase",del:"Apagar",unorderedList:"Lista não ordenada",orderedList:"Liste ordenada",insertImage:"Inserir imagem",insertVideo:"Inserir vídeo",link:"Link",createLink:"Criar um link",unlink:"Remover link",justifyLeft:"Alinhar a esquerda",justifyCenter:"Centralizar",justifyRight:"Alinhar a direita",justifyFull:"Justificar",horizontalRule:"Inserir separador horizontal",fullscreen:"Tela cheia",close:"Fechar",submit:"Enviar",reset:"Limpar",invalidUrl:"URL inválida",required:"Obrigatório",description:"Descrição",title:"Título",text:"Texto"};
\ No newline at end of file
diff --git a/dist/langs/ro.min.js b/dist/langs/ro.min.js
new file mode 100644
index 000000000..6141f2e59
--- /dev/null
+++ b/dist/langs/ro.min.js
@@ -0,0 +1,13 @@
+/* ===========================================================
+ * ro.js
+ * Romanian translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Vladut Radulescu (pacMakaveli)
+ *
+ * Email: pacMakaveli90@gmail.com
+ * Twitter : @pacMakaveli90
+ * Website : creative-studio51.co.uk
+ * Github : https://github.com/pacMakaveli
+ */
+jQuery.trumbowyg.langs.pt={viewHTML:"Vizualizare HTML",formatting:"Format",p:"Paragraf",blockquote:"Citație",code:"Cod",header:"Titlu",bold:"Bold",italic:"Italic",strikethrough:"Tăiat",underline:"Subliniat",strong:"Puternic",em:"Accentuat",del:"Sterge",unorderedList:"Lista dezordonată",orderedList:"Liste ordonată",insertImage:"Adăugare Imagine",insertVideo:"Adăugare Video",link:"Link",createLink:"Crează link",unlink:"Remover link",justifyLeft:"Aliniază stânga",justifyCenter:"Aliniază centru",justifyRight:"Aliniază dreapta",justifyFull:"Justificare",horizontalRule:"Linie orizontală",fullscreen:"Tot ecranul",close:"Închide",submit:"Procesează",reset:"Resetează",invalidUrl:"URL invalid",required:"Obligatoriu",description:"Descriere",title:"Titlu",text:"Text"};
\ No newline at end of file
diff --git a/dist/langs/ru.min.js b/dist/langs/ru.min.js
new file mode 100644
index 000000000..a3505ac5d
--- /dev/null
+++ b/dist/langs/ru.min.js
@@ -0,0 +1,8 @@
+/* ===========================================================
+ * ru.js
+ * Russion translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Yuri Lya
+ */
+jQuery.trumbowyg.langs.ru={viewHTML:"Посмотреть HTML",formatting:"Форматирование",p:"Обычный",blockquote:"Цитата",code:"Код",header:"Заголовок",bold:"Полужирный",italic:"Курсив",strikethrough:"Зачеркнутый",underline:"Подчеркнутый",strong:"Полужирный",em:"Курсив",del:"Зачеркнутый",unorderedList:"Обычный список",orderedList:"Нумерованный список",insertImage:"Вставить изображение",insertVideo:"Вставить видео",link:"Ссылка",createLink:"Вставить ссылку",unlink:"Удалить ссылку",justifyLeft:"По левому краю",justifyCenter:"По центру",justifyRight:"По правому краю",justifyFull:"По ширине",horizontalRule:"Горизонтальная линия",fullscreen:"Во весь экран",close:"Закрыть",submit:"Вставить",reset:"Отменить",invalidUrl:"Неверный URL",required:"Обязательное",description:"Описание",title:"Подсказка",text:"Текст"};
\ No newline at end of file
diff --git a/dist/langs/tr.min.js b/dist/langs/tr.min.js
new file mode 100644
index 000000000..902de506c
--- /dev/null
+++ b/dist/langs/tr.min.js
@@ -0,0 +1,10 @@
+/* ===========================================================
+ * tr.js
+ * Turkish translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Emrah Bilbay (munzur)
+ * Github : https://github.com/munzur
+ * Website: http://kafe.in/
+ */
+jQuery.trumbowyg.langs.tr={viewHTML:"HTML Kodu",formatting:"Biçimlendirme",p:"Paragraf",blockquote:"Alıntı",code:"Kod",header:"Başlık",bold:"Kalın",italic:"İtalik",strikethrough:"Orta çizgi",underline:"Alt çigzi",strong:"Koyu",em:"Vurgulu",del:"Üstü çizilmiş",unorderedList:"Numarasız liste",orderedList:"Numaralı liste",insertImage:"Resim yerleştir",insertVideo:"Video yerleştir",link:"Link",createLink:"Link yerleştir",unlink:"Linki sil",justifyLeft:"Sola hizala",justifyCenter:"Ortaya hizala",justifyRight:"Sağa hizala",justifyFull:"Yasla",horizontalRule:"Yatay çizgi ekle",fullscreen:"Tam ekran",close:"Kapat",submit:"Onayla",reset:"Sıfırla",invalidUrl:"Hatalı URL",required:"Gerekli",description:"Açıklama",title:"Başlık",text:"Metin"};
\ No newline at end of file
diff --git a/dist/langs/zh_cn.min.js b/dist/langs/zh_cn.min.js
new file mode 100644
index 000000000..62674fae6
--- /dev/null
+++ b/dist/langs/zh_cn.min.js
@@ -0,0 +1,10 @@
+/* ===========================================================
+ * zh_cn.js
+ * Simplified Chinese translation for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Liu Kai (akai)
+ * Twitter : @akai404
+ * Github : https://github.com/akai
+ */
+jQuery.trumbowyg.langs.zh_cn={viewHTML:"源代码",formatting:"格式",p:"段落",blockquote:"引用",code:"代码",header:"标题",bold:"加粗",italic:"斜体",strikethrough:"删除线",underline:"下划线",strong:"加粗",em:"斜体",del:"删除线",unorderedList:"无序列表",orderedList:"有序列表",insertImage:"插入图片",insertVideo:"插入视频",link:"超链接",createLink:"插入链接",unlink:"取消链接",justifyLeft:"居左对齐",justifyCenter:"居中对齐",justifyRight:"居右对齐",justifyFull:"两端对齐",horizontalRule:"插入分隔线",fullscreen:"全屏",close:"关闭",submit:"确定",reset:"取消",invalidUrl:"无效的 URL",required:"必需的",description:"描述",title:"标题",text:"文字"};
\ No newline at end of file
diff --git a/dist/plugins/base64/trumbowyg.base64.js b/dist/plugins/base64/trumbowyg.base64.js
new file mode 100644
index 000000000..f03591fdb
--- /dev/null
+++ b/dist/plugins/base64/trumbowyg.base64.js
@@ -0,0 +1,74 @@
+/* ===========================================================
+ * trumbowyg.base64.js v1.0
+ * Base64 plugin for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Cyril Biencourt (lizardK)
+ */
+
+(function($){
+ 'use strict';
+
+ $.extend(true, $.trumbowyg, {
+ langs: {
+ en: {
+ base64: "Image as base64",
+ file: "File",
+ errFileReaderNotSupported: "FileReader is not supported by your browser."
+ },
+ fr: {
+ base64: "Image en base64",
+ file: "Fichier"
+ }
+ },
+
+ opts: {
+ btnsDef: {
+ base64: {
+ isSupported: function(){
+ if(typeof FileReader === "undefined"){
+ console.err('[Trumbowyg - Plugin base64] FileReader is not supported by your browser.');
+ return false;
+ }
+ return true;
+ },
+ func: function(params, tbw){
+ var file;
+ tbw.openModalInsert(
+ // Title
+ tbw.lang.base64,
+
+ // Fields
+ {
+ file: {
+ type: 'file',
+ required: true
+ },
+ alt: {
+ label: 'description'
+ }
+ },
+
+ // Callback
+ function(values){
+ var fReader = new FileReader();
+
+ fReader.onloadend = function(){
+ tbw.execCmd('insertImage', fReader.result);
+ $(['img[src="', fReader.result, '"]:not([alt])'].join(''), tbw.$box).attr('alt', values.alt);
+ tbw.closeModal();
+ };
+
+ fReader.readAsDataURL(file);
+ }
+ );
+
+ $('input[type=file]').on('change', function(e){
+ file = e.target.files[0];
+ });
+ }
+ }
+ }
+ }
+ });
+})(jQuery);
diff --git a/dist/plugins/base64/trumbowyg.base64.min.js b/dist/plugins/base64/trumbowyg.base64.min.js
new file mode 100644
index 000000000..645f499b2
--- /dev/null
+++ b/dist/plugins/base64/trumbowyg.base64.min.js
@@ -0,0 +1 @@
+!function(e){"use strict";e.extend(!0,e.trumbowyg,{langs:{en:{base64:"Image as base64",file:"File",errFileReaderNotSupported:"FileReader is not supported by your browser."},fr:{base64:"Image en base64",file:"Fichier"}},opts:{btnsDef:{base64:{isSupported:function(){return"undefined"==typeof FileReader?(console.err("[Trumbowyg - Plugin base64] FileReader is not supported by your browser."),!1):!0},func:function(r,t){var n;t.openModalInsert(t.lang.base64,{file:{type:"file",required:!0},alt:{label:"description"}},function(r){var a=new FileReader;a.onloadend=function(){t.execCmd("insertImage",a.result),e(['img[src="',a.result,'"]:not([alt])'].join(""),t.$box).attr("alt",r.alt),t.closeModal()},a.readAsDataURL(n)}),e("input[type=file]").on("change",function(e){n=e.target.files[0]})}}}}})}(jQuery);
\ No newline at end of file
diff --git a/dist/plugins/upload/trumbowyg.upload.js b/dist/plugins/upload/trumbowyg.upload.js
new file mode 100644
index 000000000..8302f9779
--- /dev/null
+++ b/dist/plugins/upload/trumbowyg.upload.js
@@ -0,0 +1,139 @@
+/* ===========================================================
+ * trumbowyg.upload.js v1.0
+ * Upload plugin for Trumbowyg
+ * http://alex-d.github.com/Trumbowyg
+ * ===========================================================
+ * Author : Alexandre Demode (Alex-D)
+ * Twitter : @AlexandreDemode
+ * Website : alex-d.fr
+ */
+
+(function($){
+ 'use strict';
+
+ addXhrProgressEvent();
+
+ $.extend(true, $.trumbowyg, {
+ langs: {
+ en: {
+ upload: "Upload",
+ file: "File",
+ uploadError: "Error"
+ },
+ fr: {
+ upload: "Envoi",
+ file: "Fichier",
+ uploadError: "Erreur"
+ }
+ },
+
+ upload: {
+ serverPath: './src/plugins/upload/trumbowyg.upload.php'
+ },
+
+ opts: {
+ btnsDef: {
+ upload: {
+ func: function(params, tbw){
+ var file,
+ pfx = tbw.o.prefix;
+
+ var $modal = tbw.openModalInsert(
+ // Title
+ tbw.lang.upload,
+
+ // Fields
+ {
+ file: {
+ type: 'file',
+ required: true
+ },
+ alt: {
+ label: 'description'
+ }
+ },
+
+ // Callback
+ function(){
+ var data = new FormData();
+ data.append('fileToUpload', file);
+
+ if($('.' + pfx +'progress', $modal).length === 0)
+ $('.' + pfx + 'modal-title', $modal)
+ .after(
+ $('
', {
+ 'class': pfx +'progress'
+ })
+ .append(
+ $('', {
+ 'class': pfx +'progress-bar'
+ })
+ )
+ );
+
+ $.ajax({
+ url: $.trumbowyg.upload.serverPath,
+ type: 'POST',
+ data: data,
+ cache: false,
+ dataType: 'json',
+ processData: false,
+ contentType: false,
+
+ progressUpload: function(e){
+ $('.' + pfx + 'progress-bar').stop().animate({
+ width: Math.round(e.loaded * 100 / e.total) + '%'
+ }, 200);
+ },
+
+ success: function(data){
+ if(data.message == "uploadSuccess") {
+ tbw.execCommand('insertImage', data.file);
+ setTimeout(function(){
+ tbw.closeModal();
+ }, 250);
+ } else {
+ tbw.addErrorOnModalField(
+ $('input[type=file]', $modal),
+ tbw.lang[data.message]
+ );
+ }
+ },
+ error: function(){
+ tbw.addErrorOnModalField(
+ $('input[type=file]', $modal),
+ tbw.lang.uploadError
+ );
+ }
+ });
+ }
+ );
+
+ $('input[type=file]').on('change', function(e){
+ file = e.target.files[0];
+ });
+ }
+ }
+ }
+ }
+ });
+
+
+ function addXhrProgressEvent(){
+ var originalXhr = $.ajaxSettings.xhr;
+
+ $.ajaxSetup({
+ xhr: function() {
+ var req = originalXhr(),
+ that = this;
+
+ if(req && typeof req.upload == "object" && that.progressUpload !== undefined)
+ req.upload.addEventListener("progress", function(e){
+ that.progressUpload(e);
+ }, false);
+
+ return req;
+ }
+ });
+ }
+})(jQuery);
\ No newline at end of file
diff --git a/dist/plugins/upload/trumbowyg.upload.min.js b/dist/plugins/upload/trumbowyg.upload.min.js
new file mode 100644
index 000000000..359bc1f90
--- /dev/null
+++ b/dist/plugins/upload/trumbowyg.upload.min.js
@@ -0,0 +1 @@
+!function(e){"use strict";function r(){var r=e.ajaxSettings.xhr;e.ajaxSetup({xhr:function(){var e=r(),o=this;return e&&"object"==typeof e.upload&&void 0!==o.progressUpload&&e.upload.addEventListener("progress",function(e){o.progressUpload(e)},!1),e}})}r(),e.extend(!0,e.trumbowyg,{langs:{en:{upload:"Upload",file:"File",uploadError:"Error"},fr:{upload:"Envoi",file:"Fichier",uploadError:"Erreur"}},upload:{serverPath:"./src/plugins/upload/trumbowyg.upload.php"},opts:{btnsDef:{upload:{func:function(r,o){var a,t=o.o.prefix,n=o.openModalInsert(o.lang.upload,{file:{type:"file",required:!0},alt:{label:"description"}},function(){var r=new FormData;r.append("fileToUpload",a),0===e("."+t+"progress",n).length&&e("."+t+"modal-title",n).after(e("",{"class":t+"progress"}).append(e("",{"class":t+"progress-bar"}))),e.ajax({url:e.trumbowyg.upload.serverPath,type:"POST",data:r,cache:!1,dataType:"json",processData:!1,contentType:!1,progressUpload:function(r){e("."+t+"progress-bar").stop().animate({width:Math.round(100*r.loaded/r.total)+"%"},200)},success:function(r){"uploadSuccess"==r.message?(o.execCommand("insertImage",r.file),setTimeout(function(){o.closeModal()},250)):o.addErrorOnModalField(e("input[type=file]",n),o.lang[r.message])},error:function(){o.addErrorOnModalField(e("input[type=file]",n),o.lang.uploadError)}})});e("input[type=file]").on("change",function(e){a=e.target.files[0]})}}}}})}(jQuery);
\ No newline at end of file
diff --git a/dist/trumbowyg.js b/dist/trumbowyg.js
new file mode 100644
index 000000000..e5b068cb0
--- /dev/null
+++ b/dist/trumbowyg.js
@@ -0,0 +1,1107 @@
+/**
+ * Trumbowyg v1.1.1 - A lightweight WYSIWYG editor
+ * Trumbowyg core file
+ * ------------------------
+ * @link http://alex-d.github.io/Trumbowyg
+ * @license MIT
+ * @author Alexandre Demode (Alex-D)
+ * Twitter : @AlexandreDemode
+ * Website : alex-d.fr
+ */
+
+jQuery.trumbowyg = {
+ langs: {
+ en: {
+ viewHTML: "View HTML",
+
+ formatting: "Formatting",
+ p: "Paragraph",
+ blockquote: "Quote",
+ code: "Code",
+ header: "Header",
+
+ bold: "Bold",
+ italic: "Italic",
+ strikethrough: "Stroke",
+ underline: "Underline",
+
+ strong: "Strong",
+ em: "Emphasis",
+ del: "Deleted",
+
+ unorderedList: "Unordered list",
+ orderedList: "Ordered list",
+
+ insertImage: "Insert Image",
+ insertVideo: "Insert Video",
+ link: "Link",
+ createLink: "Insert link",
+ unlink: "Remove link",
+
+ justifyLeft: "Align Left",
+ justifyCenter: "Align Center",
+ justifyRight: "Align Right",
+ justifyFull: "Align Justify",
+
+ horizontalRule: "Insert horizontal rule",
+
+ fullscreen: "fullscreen",
+
+ close: "Close",
+
+ submit: "Confirm",
+ reset: "Cancel",
+
+ invalidUrl: "Invalid URL",
+ required: "Required",
+ description: "Description",
+ title: "Title",
+ text: "Text"
+ }
+ },
+
+ // User default options
+ opts: {},
+
+ btnsGrps: {
+ design: ['bold', 'italic', 'underline', 'strikethrough'],
+ semantic: ['strong', 'em', 'del'],
+ justify: ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],
+ lists: ['unorderedList', 'orderedList']
+ }
+};
+
+
+
+(function(window, document, $){
+ 'use strict';
+
+ // @param : o are options
+ // @param : p are params
+ $.fn.trumbowyg = function(o, p){
+ if(o === Object(o) || !o){
+ return this.each(function(){
+ if(!$(this).data('trumbowyg'))
+ $(this).data('trumbowyg', new Trumbowyg(this, o));
+ });
+ } else if(this.length === 1){
+ try {
+ var t = $(this).data('trumbowyg');
+ switch(o){
+ // Modal box
+ case 'openModal':
+ return t.openModal(p.title, p.content);
+ case 'closeModal':
+ return t.closeModal();
+ case 'openModalInsert':
+ return t.openModalInsert(p.title, p.fields, p.callback);
+
+ // Selection
+ case 'saveSelection':
+ return t.saveSelection();
+ case 'getSelection':
+ return t.selection;
+ case 'getSelectedText':
+ return t.selection+'';
+ case 'restoreSelection':
+ return t.restoreSelection();
+
+ // Destroy
+ case 'destroy':
+ return t.destroy();
+
+ // Empty
+ case 'empty':
+ return t.empty();
+
+ // Public options
+ case 'lang':
+ return t.lang;
+ case 'duration':
+ return t.o.duration;
+
+ // HTML
+ case 'html':
+ return t.html(p);
+ }
+ } catch(e){}
+ }
+
+ return false;
+ };
+
+
+
+ var Trumbowyg = function(editorElem, opts){
+ var t = this;
+ // jQuery object of the editor
+ t.$e = $(editorElem);
+ t.$creator = $(editorElem);
+
+ // Extend with options
+ opts = $.extend(true, {}, opts, $.trumbowyg.opts);
+
+ // Localization management
+ if(typeof opts.lang === 'undefined' || typeof $.trumbowyg.langs[opts.lang] === 'undefined')
+ t.lang = $.trumbowyg.langs.en;
+ else
+ t.lang = $.extend(true, {}, $.trumbowyg.langs.en, $.trumbowyg.langs[opts.lang]);
+
+ // Defaults Options
+ t.o = $.extend(true, {
+ lang: 'en',
+ dir: 'ltr',
+ duration: 200, // Duration of modal box animations
+
+ mobile: false,
+ tablet: true,
+ closable: false,
+ fullscreenable: true,
+ fixedBtnPane: false,
+ fixedFullWidth: false,
+ semantic: false,
+ resetCss: false,
+ autogrow: false,
+
+ prefix: 'trumbowyg-',
+
+ convertLink: true,
+
+ btns: ['viewHTML',
+ '|', 'formatting',
+ '|', $.trumbowyg.btnsGrps.design,
+ '|', 'link',
+ '|', 'insertImage',
+ '|', $.trumbowyg.btnsGrps.justify,
+ '|', $.trumbowyg.btnsGrps.lists,
+ '|', 'horizontalRule'],
+ btnsAdd: [],
+
+ /**
+ * When the button is associated to a empty object
+ * func and title attributs are defined from the button key value
+ *
+ * For example
+ * foo: {}
+ * is equivalent to :
+ * foo: {
+ * func: 'foo',
+ * title: this.lang.foo
+ * }
+ */
+ btnsDef: {
+ viewHTML: {
+ func: 'toggle'
+ },
+
+ p: {
+ func: 'formatBlock'
+ },
+ blockquote: {
+ func: 'formatBlock'
+ },
+ h1: {
+ func: 'formatBlock',
+ title: t.lang.header + ' 1'
+ },
+ h2: {
+ func: 'formatBlock',
+ title: t.lang.header + ' 2'
+ },
+ h3: {
+ func: 'formatBlock',
+ title: t.lang.header + ' 3'
+ },
+ h4: {
+ func: 'formatBlock',
+ title: t.lang.header + ' 4'
+ },
+
+ bold: {},
+ italic: {},
+ underline: {},
+ strikethrough: {},
+
+ strong: {
+ func: 'bold'
+ },
+ em: {
+ func: 'italic'
+ },
+ del: {
+ func: 'strikethrough'
+ },
+
+ createLink: {},
+ unlink: {},
+
+ insertImage: {},
+
+ justifyLeft: {},
+ justifyCenter: {},
+ justifyRight: {},
+ justifyFull: {},
+
+ unorderedList: {
+ func: 'insertUnorderedList'
+ },
+ orderedList: {
+ func: 'insertOrderedList'
+ },
+
+ horizontalRule: {
+ func: 'insertHorizontalRule'
+ },
+
+ // Dropdowns
+ formatting: {
+ dropdown: ['p', 'blockquote', 'h1', 'h2', 'h3', 'h4']
+ },
+ link: {
+ dropdown: ['createLink', 'unlink']
+ }
+ }
+ }, opts);
+
+ if(t.o.semantic && !opts.btns)
+ t.o.btns = [
+ 'viewHTML',
+ '|', 'formatting',
+ '|', $.trumbowyg.btnsGrps.semantic,
+ '|', 'link',
+ '|', 'insertImage',
+ '|', $.trumbowyg.btnsGrps.justify,
+ '|', $.trumbowyg.btnsGrps.lists,
+ '|', 'horizontalRule'
+ ];
+ else if(opts && opts.btns)
+ t.o.btns = opts.btns;
+
+ t.init();
+ };
+
+ Trumbowyg.prototype = {
+ init: function(){
+ var t = this;
+ t.height = t.$e.css('height');
+
+ if(t.isEnabled()){
+ t.buildEditor(true);
+ return;
+ }
+
+ t.buildEditor();
+ t.buildBtnPane();
+
+ t.fixedBtnPaneEvents();
+
+ t.buildOverlay();
+ },
+
+ buildEditor: function(disable){
+ var t = this;
+ var pfx = t.o.prefix;
+
+
+ if(disable === true){
+ if(!t.$e.is('textarea')){
+ var textarea = t.buildTextarea().val(t.$e.val());
+ t.$e.hide().after(textarea);
+ }
+ return;
+ }
+
+
+ t.$box = $('', {
+ class: pfx + 'box ' + pfx + t.o.lang + ' trumbowyg'
+ });
+
+ t.isTextarea = true;
+ if(t.$e.is('textarea'))
+ t.$editor = $('');
+ else {
+ t.$editor = t.$e;
+ t.$e = t.buildTextarea().val(t.$e.val());
+ t.isTextarea = false;
+ }
+
+ t.$e.hide()
+ .addClass(pfx + 'textarea');
+
+ var html = '';
+ if(t.isTextarea){
+ html = t.$e.val();
+ t.$box.insertAfter(t.$e)
+ .append(t.$editor)
+ .append(t.$e);
+ } else {
+ html = t.$editor.html();
+ t.$box.insertAfter(t.$editor)
+ .append(t.$e)
+ .append(t.$editor);
+ t.syncCode();
+ }
+
+ t.$editor.addClass(pfx + 'editor')
+ .attr('contenteditable', true)
+ .attr('dir', t.o.dir)
+ .html(html);
+
+ if(t.o.resetCss)
+ t.$editor.addClass(pfx + 'reset-css');
+
+ if(!t.o.autogrow){
+ $.each([t.$editor, t.$e], function(i, $el){
+ $el.css({
+ height: t.height,
+ overflow: 'auto'
+ });
+ });
+ }
+
+ if(t.o.semantic){
+ t.$editor.html(
+ t.$editor.html()
+ .replace('
', '')
+ .replace(' ', '')
+ );
+ t.semanticCode();
+ }
+
+
+
+ t.$editor
+ .on('dblclick', 'img', function(){
+ var $img = $(this);
+ t.openModalInsert(t.lang.insertImage, {
+ url: {
+ label: 'URL',
+ value: $img.attr('src'),
+ required: true
+ },
+ alt: {
+ label: 'description',
+ value: $img.attr('alt')
+ }
+ }, function(v){
+ $img.attr('src', v.url);
+ $img.attr('alt', v.alt);
+ });
+ return false;
+ })
+ .on('keyup', function(e){
+ t.semanticCode(false, e.which === 13);
+ })
+ .on('blur', function(){
+ t.syncCode();
+ });
+ },
+
+
+ // Build the Textarea which contain HTML generated code
+ buildTextarea: function(){
+ return $('', {
+ name: this.$e.attr('id'),
+ height: this.height
+ });
+ },
+
+
+ // Build button pane, use o.btns and o.btnsAdd options
+ buildBtnPane: function(){
+ var t = this,
+ pfx = t.o.prefix;
+
+ if(t.o.btns === false)
+ return;
+
+ t.$btnPane = $('
', {
+ class: pfx + 'button-pane'
+ });
+
+ $.each(t.o.btns.concat(t.o.btnsAdd), function(i, btn){
+ // Managment of group of buttons
+ try {
+ var b = btn.split('btnGrp-');
+ if(b[1] !== undefined)
+ btn = $.trumbowyg.btnsGrps[b[1]];
+ } catch(e){}
+
+ if(!$.isArray(btn))
+ btn = [btn];
+
+ $.each(btn, function(i, b){
+ try { // Prevent buildBtn error
+ var $li = $('');
+
+ if(b === '|') // It's a separator
+ $li.addClass(pfx + 'separator');
+ else if(t.isSupportedBtn(b)) // It's a supported button
+ $li.append(t.buildBtn(b));
+
+ t.$btnPane.append($li);
+ } catch(e){}
+ });
+ });
+
+ // Build right li for fullscreen and close buttons
+ var $liRight = $('', {
+ class: pfx + 'not-disable ' + pfx + 'buttons-right'
+ });
+
+ // Add the fullscreen button
+ if(t.o.fullscreenable)
+ $liRight
+ .append(t.buildRightBtn('fullscreen')
+ .on('click', function(){
+ var cssClass = pfx + 'fullscreen';
+ t.$box.toggleClass(cssClass);
+
+ if(t.$box.hasClass(cssClass)){
+ $('body').css('overflow', 'hidden');
+ $.each([t.$editor, t.$e], function(){
+ $(this).css({
+ height: 'calc(100% - 35px)',
+ overflow: 'auto'
+ });
+ });
+ t.$btnPane.css('width', '100%');
+ } else {
+ $('body').css('overflow', 'auto');
+ t.$box.removeAttr('style');
+ if(!t.o.autogrow)
+ $([t.$editor, t.$e]).each(function(i, $el){
+ $el.css('height', t.height);
+ });
+ }
+ $(window).trigger('scroll');
+ }));
+
+ // Build and add close button
+ if(t.o.closable)
+ $liRight
+ .append(
+ t.buildRightBtn('close')
+ .on('click', function(){
+ if(t.$box.hasClass(pfx + 'fullscreen'))
+ $('body').css('overflow', 'auto');
+ t.destroy();
+ })
+ );
+
+
+ // Add right li only if isn't empty
+ if($liRight.not(':empty'))
+ t.$btnPane.append($liRight);
+
+ t.$box.prepend(t.$btnPane);
+ },
+
+
+ // Build a button and his action
+ buildBtn: function(n){ // n is name of the button
+ var t = this,
+ pfx = t.o.prefix,
+ btn = t.o.btnsDef[n],
+ d = btn.dropdown,
+ textDef = t.lang[n] || n,
+
+ $btn = $('', {
+ type: 'button',
+ class: pfx + n +'-button' + (btn.ico ? ' '+ pfx + btn.ico +'-button' : ''),
+ text: btn.text || btn.title || textDef,
+ title: btn.title || btn.text || textDef,
+ mousedown: function(e){
+ if(!d || t.$box.find('.'+n+'-'+pfx + 'dropdown').is(':hidden'))
+ $('body').trigger('mousedown');
+
+ if(t.$btnPane.hasClass(pfx + 'disable') && !$(this).hasClass(pfx + 'active') && !$(this).parent().hasClass(pfx + 'not-disable'))
+ return false;
+
+ t.execCmd((d ? 'dropdown' : false) || btn.func || n,
+ btn.param || n);
+
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ });
+
+
+
+ if(d){
+ $btn.addClass(pfx + 'open-dropdown');
+ var c = pfx + 'dropdown',
+ dd = $('', { // the dropdown
+ class: n + '-' + c + ' ' + c + ' ' + pfx + 'fixed-top'
+ });
+ for(var i = 0, l = d.length; i < l; i++)
+ if(t.o.btnsDef[d[i]] && t.isSupportedBtn(d[i]))
+ dd.append(t.buildSubBtn(d[i]));
+ t.$box.append(dd.hide());
+ }
+
+ return $btn;
+ },
+ // Build a button for dropdown menu
+ // @param n : name of the subbutton
+ buildSubBtn: function(n){
+ var t = this,
+ btnDef = t.o.btnsDef[n];
+ return $('', {
+ type: 'button',
+ text: btnDef.text || btnDef.title || t.lang[n] || n,
+ mousedown: function(e){
+ $('body').trigger('mousedown');
+
+ t.execCmd(btnDef.func || n,
+ btnDef.param || n);
+
+ e.stopPropagation();
+ e.preventDefault();
+ return false;
+ }
+ });
+ },
+ // Build a button for right li
+ // @param n : name of the right button
+ buildRightBtn: function(n){
+ return $('', {
+ type: 'button',
+ class: this.o.prefix + n + '-button',
+ title: this.lang[n],
+ text: this.lang[n]
+ });
+ },
+ // Check if button is supported
+ isSupportedBtn: function(btn){
+ return typeof this.o.btnsDef[btn].isSupported !== 'function' || this.o.btnsDef[btn].isSupported();
+ },
+
+ // Build overlay for modal box
+ buildOverlay: function(){
+ var t = this;
+ t.$overlay = $('', {
+ class: t.o.prefix + 'overlay'
+ }).css({
+ top: t.$btnPane.outerHeight(),
+ height: (parseInt(t.$editor.outerHeight()) + 1) + 'px'
+ }).appendTo(t.$box);
+ return t.$overlay;
+ },
+ showOverlay: function(){
+ var t = this;
+ $(window).trigger('scroll');
+ t.$overlay.fadeIn(t.o.duration);
+ t.$box.addClass(t.o.prefix + 'box-blur');
+ },
+ hideOverlay: function(){
+ var t = this;
+ t.$overlay.fadeOut(t.o.duration/4);
+ t.$box.removeClass(t.o.prefix + 'box-blur');
+ },
+
+ // Management of fixed button pane
+ fixedBtnPaneEvents: function(){
+ var t = this,
+ ffw = t.o.fixedFullWidth;
+ if(!t.o.fixedBtnPane)
+ return;
+
+ t.isFixed = false;
+
+ $(window)
+ .on('scroll resize', function(){
+ if(!t.$box)
+ return;
+
+ t.syncCode();
+
+ var s = $(window).scrollTop(), // s is top scroll
+ o = t.$box.offset().top + 1, // o is offset
+ toFixed = (s - o > 0) && ((s - o - parseInt(t.height)) < 0),
+ bp = t.$btnPane,
+ mt = bp.css('height'),
+ oh = bp.outerHeight();
+
+ if(toFixed){
+ if(!t.isFixed){
+ t.isFixed = true;
+ bp.css({
+ position: 'fixed',
+ top: 0,
+ left: ffw ? '0' : 'auto',
+ zIndex: 7
+ });
+ t.$editor.css({ marginTop: mt });
+ t.$e.css({ marginTop: mt });
+ }
+ bp.css({
+ width: ffw ? '100%' : ((parseInt(t.$box.css('width'))-1) + 'px')
+ });
+
+ $('.' + t.o.prefix + 'fixed-top', t.$box).css({
+ position: ffw ? 'fixed' : 'absolute',
+ top: ffw ? oh : parseInt(oh) + (s - o) + 'px',
+ zIndex: 15
+ });
+ } else if(t.isFixed) {
+ t.isFixed = false;
+ bp.removeAttr('style');
+ t.$editor.css({ marginTop: 0 });
+ t.$e.css({ marginTop: 0 });
+ $('.' + t.o.prefix + 'fixed-top', t.$box).css({
+ position: 'absolute',
+ top: oh
+ });
+ }
+ });
+ },
+
+
+
+ // Destroy the editor
+ destroy: function(){
+ var t = this,
+ pfx = t.o.prefix,
+ h = t.height,
+ html = t.html();
+
+ if(t.isTextarea)
+ t.$box.after(
+ t.$e.css({height: h})
+ .val(html)
+ .removeClass(pfx + 'textarea')
+ .show()
+ );
+ else
+ t.$box.after(
+ t.$editor
+ .css({height: h})
+ .removeClass(pfx + 'editor')
+ .attr('contenteditable', false)
+ .html(html)
+ .show()
+ );
+
+ t.$box.remove();
+ t.$creator.removeData('trumbowyg');
+ },
+
+
+
+ // Empty the editor
+ empty: function(){
+ this.$e.val('');
+ this.syncCode(true);
+ },
+
+
+
+ // Function call when click on viewHTML button
+ toggle: function(){
+ var t = this,
+ pfx = t.o.prefix;
+ t.semanticCode(false, true);
+ t.$editor.toggle();
+ t.$e.toggle();
+ t.$btnPane.toggleClass(pfx + 'disable');
+ t.$btnPane.find('.'+pfx + 'viewHTML-button').toggleClass(pfx + 'active');
+ },
+
+ // Open dropdown when click on a button which open that
+ dropdown: function(name){
+ var t = this,
+ pfx = t.o.prefix,
+ $dropdown = t.$box.find('.'+name+'-'+pfx + 'dropdown'),
+ $btn = t.$btnPane.find('.'+pfx+name+'-button');
+
+ if($dropdown.is(':hidden')){
+ var o = $btn.offset().left;
+ $btn.addClass(pfx + 'active');
+
+ $dropdown.css({
+ position: 'absolute',
+ top: t.$btnPane.outerHeight(),
+ left: (t.o.fixedFullWidth && t.isFixed) ? o+'px' : (o - t.$btnPane.offset().left)+'px'
+ }).show();
+
+ $(window).trigger('scroll');
+
+ $('body').on('mousedown', function(){
+ $('.' + pfx + 'dropdown').hide();
+ $('.' + pfx + 'active').removeClass(pfx + 'active');
+ $('body').off('mousedown');
+ });
+ } else
+ $('body').trigger('mousedown');
+ },
+
+
+
+
+ // HTML Code management
+ html: function(html){
+ var t = this;
+ if(html){
+ t.$e.val(html);
+ t.syncCode(true);
+ return t;
+ } else
+ return t.$e.val();
+ },
+ syncCode: function(force){
+ var t = this;
+ if(!force && t.$editor.is(':visible'))
+ t.$e.val(t.$editor.html());
+ else
+ t.$editor.html(t.$e.val());
+
+ if(t.o.autogrow){
+ t.height = t.$editor.css('height');
+ t.$e.css({ height: t.height });
+ }
+ },
+
+ // Analyse and update to semantic code
+ // @param force : force to sync code from textarea
+ // @param full : wrap text nodes in
+ semanticCode: function(force, full){
+ var t = this;
+ t.syncCode(force);
+
+ if(t.o.semantic){
+ t.semanticTag('b', 'strong');
+ t.semanticTag('i', 'em');
+ t.semanticTag('strike', 'del');
+
+ if(full){
+ // Wrap text nodes in p
+ t.$editor.contents()
+ .filter(function(){
+ // Only non-empty text nodes
+ return this.nodeType === 3 && $.trim(this.nodeValue).length > 0;
+ }).wrap('
').end()
+
+ // Remove all br
+ .filter('br').remove();
+
+ t.saveSelection();
+ t.semanticTag('div', 'p');
+ t.restoreSelection();
+ }
+
+ t.$e.val(t.$editor.html());
+ }
+ },
+ semanticTag: function(oldTag, newTag){
+ $(oldTag, this.$editor).each(function(){
+ $(this).replaceWith(function(){
+ return '<'+newTag+'>' + $(this).html() + ''+newTag+'>';
+ });
+ });
+ },
+
+
+ // Function call when user click on "Insert Link"
+ createLink: function(){
+ var t = this;
+ t.saveSelection();
+ t.openModalInsert(t.lang.createLink, {
+ url: {
+ label: 'URL',
+ value: 'http://',
+ required: true
+ },
+ title: {
+ label: t.lang.title,
+ value: t.selection
+ },
+ text: {
+ label: t.lang.text,
+ value: t.selection
+ }
+ }, function(v){ // v is value
+ t.execCmd('createLink', v.url);
+ var l = $('a[href="'+v.url+'"]:not([title])', t.$box);
+ if(v.text.length > 0)
+ l.text(v.text);
+
+ if(v.title.length > 0)
+ l.attr('title', v.title);
+
+ return true;
+ });
+ },
+ insertImage: function(){
+ var t = this;
+ t.saveSelection();
+ t.openModalInsert(t.lang.insertImage, {
+ url: {
+ label: 'URL',
+ value: 'http://',
+ required: true
+ },
+ alt: {
+ label: t.lang.description,
+ value: t.selection
+ }
+ }, function(v){ // v are values
+ t.execCmd('insertImage', v.url);
+ $('img[src="'+v.url+'"]:not([alt])', t.$box).attr('alt', v.alt);
+ return true;
+ });
+ },
+
+
+ /*
+ * Call method of trumbowyg if exist
+ * else try to call anonymous function
+ * and finaly native execCommand
+ */
+ execCmd: function(cmd, param){
+ var t = this;
+ if(cmd != 'dropdown')
+ t.$editor.focus();
+
+ try {
+ t[cmd](param);
+ } catch(e){
+ try {
+ cmd(param, t);
+ } catch(e2){
+ t.$editor.focus();
+ if(cmd == 'insertHorizontalRule')
+ param = null;
+ else if(cmd == 'formatBlock' && (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0))
+ param = '<' + param + '>';
+
+ document.execCommand(cmd, false, param);
+ }
+ }
+ t.syncCode();
+ },
+
+
+ // Open a modal box
+ openModal: function(title, content){
+ var t = this,
+ pfx = t.o.prefix;
+
+ // No open a modal box when exist other modal box
+ if($('.' + pfx + 'modal-box', t.$box).size() > 0)
+ return false;
+
+ t.saveSelection();
+ t.showOverlay();
+
+ // Disable all btnPane btns
+ t.$btnPane.addClass(pfx + 'disable');
+
+ // Build out of ModalBox, it's the mask for animations
+ var $modal = $('', {
+ class: pfx + 'modal ' + pfx + 'fixed-top'
+ }).css({
+ top: (parseInt(t.$btnPane.css('height')) + 1) + 'px'
+ }).appendTo(t.$box);
+
+ // Click on overflay close modal by cancelling them
+ t.$overlay.one('click', function(e){
+ e.preventDefault();
+ $modal.trigger(pfx + 'cancel');
+ });
+
+ // Build the form
+ var $form = $('', {
+ action: '',
+ html: content
+ })
+ .on('submit', function(e){
+ e.preventDefault();
+ $modal.trigger(pfx + 'confirm');
+ })
+ .on('reset', function(e){
+ e.preventDefault();
+ $modal.trigger(pfx + 'cancel');
+ });
+
+
+ // Build ModalBox and animate to show them
+ var $box = $('', {
+ class: pfx + 'modal-box',
+ html: $form
+ })
+ .css({
+ top: '-' + parseInt(t.$btnPane.outerHeight()) + 'px',
+ opacity: 0
+ })
+ .appendTo($modal)
+ .animate({
+ top: 0,
+ opacity: 1
+ }, t.o.duration / 2);
+
+
+ // Append title
+ $('', {
+ text: title,
+ class: pfx + 'modal-title'
+ }).prependTo($box);
+
+
+ // Focus in modal box
+ $box.find('input:first').focus();
+
+
+ // Append Confirm and Cancel buttons
+ t.buildModalBtn('submit', $box);
+ t.buildModalBtn('reset', $box);
+
+
+ $(window).trigger('scroll');
+
+ return $modal;
+ },
+ // @param n is name of modal
+ buildModalBtn: function(n, modal){
+ var t = this,
+ pfx = t.o.prefix;
+
+ return $('', {
+ class: pfx + 'modal-button ' + pfx + 'modal-' + n,
+ type: n,
+ text: t.lang[n] || n
+ }).appendTo(modal.find('form'));
+ },
+ // close current modal box
+ closeModal: function(){
+ var t = this,
+ pfx = t.o.prefix;
+
+ t.$btnPane.removeClass(pfx + 'disable');
+ t.$overlay.off();
+
+ var $modalBox = $('.' + pfx + 'modal-box', t.$box);
+
+ $modalBox.animate({
+ top: '-' + $modalBox.css('height')
+ }, t.o.duration/2, function(){
+ $(this).parent().remove();
+ t.hideOverlay();
+ });
+ },
+ // Preformated build and management modal
+ openModalInsert: function(title, fields, cmd){
+ var t = this,
+ pfx = t.o.prefix,
+ lg = t.lang,
+ html = '';
+
+ for(var f in fields){
+ var fd = fields[f], // field definition
+ label = (fd.label === undefined) ? (lg[f] ? lg[f] : f) : (lg[fd.label] ? lg[fd.label] : fd.label);
+
+ if(fd.name === undefined)
+ fd.name = f;
+
+ if(!fd.pattern && f === 'url'){
+ fd.pattern = /^(http|https):\/\/([\w~#!:.?+=&%@!\-\/]+)$/;
+ fd.patternError = lg.invalidUrl;
+ }
+
+ html += '';
+ }
+
+ return t.openModal(title, html)
+ .on(pfx + 'confirm', function(){
+ var $form = $(this).find('form'),
+ valid = true,
+ v = {}; // values
+
+ for(var f in fields){
+ var $field = $('input[name="'+f+'"]', $form);
+
+ v[f] = $.trim($field.val());
+
+ // Validate value
+ if(fields[f].required && v[f] === ''){
+ valid = false;
+ t.addErrorOnModalField($field, t.lang.required);
+ } else if(fields[f].pattern && !fields[f].pattern.test(v[f])){
+ valid = false;
+ t.addErrorOnModalField($field, fields[f].patternError);
+ }
+ }
+
+ if(valid){
+ t.restoreSelection();
+
+ if(cmd(v, fields)){
+ t.syncCode();
+ t.closeModal();
+ $(this).off(pfx + 'confirm');
+ }
+ }
+ })
+ .one(pfx + 'cancel', function(){
+ $(this).off(pfx + 'confirm');
+ t.closeModal();
+ t.restoreSelection();
+ });
+ },
+ addErrorOnModalField: function($field, err){
+ var pfx = this.o.prefix,
+ $label = $field.parent();
+
+ $field.on('change keyup', function(){
+ $label.removeClass(pfx + 'input-error');
+ });
+ $label
+ .addClass(pfx + 'input-error')
+ .find('input+span').append(
+ $('', {
+ class: pfx +'msg-error',
+ text: err
+ })
+ );
+ },
+
+
+
+
+ // Selection management
+ saveSelection: function(){
+ var t = this,
+ d = document;
+
+ t.selection = null;
+ if(window.getSelection){
+ var s = window.getSelection();
+ if(s.getRangeAt && s.rangeCount)
+ t.selection = s.getRangeAt(0);
+ } else if(d.selection && d.selection.createRange)
+ t.selection = d.selection.createRange();
+ },
+ restoreSelection: function(){
+ var range = this.selection;
+ if(range){
+ if(window.getSelection){
+ var s = window.getSelection();
+ s.removeAllRanges();
+ s.addRange(range);
+ } else if(document.selection && range.select)
+ range.select();
+ }
+ },
+
+
+
+ // Return true if must enable Trumbowyg on this mobile device
+ isEnabled: function(){
+ var exprTablet = new RegExp("(iPad|webOS)"),
+ exprMobile = new RegExp("(iPhone|iPod|Android|BlackBerry|Windows Phone|ZuneWP7)"),
+ ua = navigator.userAgent;
+
+ return (this.o.tablet === true && exprTablet.test(ua)) || (this.o.mobile === true && exprMobile.test(ua));
+ }
+ };
+})(window, document, jQuery);
\ No newline at end of file
diff --git a/dist/trumbowyg.min.js b/dist/trumbowyg.min.js
new file mode 100644
index 000000000..c2f4b879f
--- /dev/null
+++ b/dist/trumbowyg.min.js
@@ -0,0 +1,2 @@
+/** Trumbowyg v1.1.1 - A lightweight WYSIWYG editor - alex-d.github.io/Trumbowyg - License MIT - Author : Alexandre Demode (Alex-D) / alex-d.fr */
+jQuery.trumbowyg={langs:{en:{viewHTML:"View HTML",formatting:"Formatting",p:"Paragraph",blockquote:"Quote",code:"Code",header:"Header",bold:"Bold",italic:"Italic",strikethrough:"Stroke",underline:"Underline",strong:"Strong",em:"Emphasis",del:"Deleted",unorderedList:"Unordered list",orderedList:"Ordered list",insertImage:"Insert Image",insertVideo:"Insert Video",link:"Link",createLink:"Insert link",unlink:"Remove link",justifyLeft:"Align Left",justifyCenter:"Align Center",justifyRight:"Align Right",justifyFull:"Align Justify",horizontalRule:"Insert horizontal rule",fullscreen:"fullscreen",close:"Close",submit:"Confirm",reset:"Cancel",invalidUrl:"Invalid URL",required:"Required",description:"Description",title:"Title",text:"Text"}},opts:{},btnsGrps:{design:["bold","italic","underline","strikethrough"],semantic:["strong","em","del"],justify:["justifyLeft","justifyCenter","justifyRight","justifyFull"],lists:["unorderedList","orderedList"]}},function(e,t,n){"use strict";n.fn.trumbowyg=function(e,t){if(e===Object(e)||!e)return this.each(function(){n(this).data("trumbowyg")||n(this).data("trumbowyg",new o(this,e))});if(1===this.length)try{var i=n(this).data("trumbowyg");switch(e){case"openModal":return i.openModal(t.title,t.content);case"closeModal":return i.closeModal();case"openModalInsert":return i.openModalInsert(t.title,t.fields,t.callback);case"saveSelection":return i.saveSelection();case"getSelection":return i.selection;case"getSelectedText":return i.selection+"";case"restoreSelection":return i.restoreSelection();case"destroy":return i.destroy();case"empty":return i.empty();case"lang":return i.lang;case"duration":return i.o.duration;case"html":return i.html(t)}}catch(r){}return!1};var o=function(e,t){var o=this;o.$e=n(e),o.$creator=n(e),t=n.extend(!0,{},t,n.trumbowyg.opts),o.lang="undefined"==typeof t.lang||"undefined"==typeof n.trumbowyg.langs[t.lang]?n.trumbowyg.langs.en:n.extend(!0,{},n.trumbowyg.langs.en,n.trumbowyg.langs[t.lang]),o.o=n.extend(!0,{lang:"en",dir:"ltr",duration:200,mobile:!1,tablet:!0,closable:!1,fullscreenable:!0,fixedBtnPane:!1,fixedFullWidth:!1,semantic:!1,resetCss:!1,autogrow:!1,prefix:"trumbowyg-",convertLink:!0,btns:["viewHTML","|","formatting","|",n.trumbowyg.btnsGrps.design,"|","link","|","insertImage","|",n.trumbowyg.btnsGrps.justify,"|",n.trumbowyg.btnsGrps.lists,"|","horizontalRule"],btnsAdd:[],btnsDef:{viewHTML:{func:"toggle"},p:{func:"formatBlock"},blockquote:{func:"formatBlock"},h1:{func:"formatBlock",title:o.lang.header+" 1"},h2:{func:"formatBlock",title:o.lang.header+" 2"},h3:{func:"formatBlock",title:o.lang.header+" 3"},h4:{func:"formatBlock",title:o.lang.header+" 4"},bold:{},italic:{},underline:{},strikethrough:{},strong:{func:"bold"},em:{func:"italic"},del:{func:"strikethrough"},createLink:{},unlink:{},insertImage:{},justifyLeft:{},justifyCenter:{},justifyRight:{},justifyFull:{},unorderedList:{func:"insertUnorderedList"},orderedList:{func:"insertOrderedList"},horizontalRule:{func:"insertHorizontalRule"},formatting:{dropdown:["p","blockquote","h1","h2","h3","h4"]},link:{dropdown:["createLink","unlink"]}}},t),o.o.semantic&&!t.btns?o.o.btns=["viewHTML","|","formatting","|",n.trumbowyg.btnsGrps.semantic,"|","link","|","insertImage","|",n.trumbowyg.btnsGrps.justify,"|",n.trumbowyg.btnsGrps.lists,"|","horizontalRule"]:t&&t.btns&&(o.o.btns=t.btns),o.init()};o.prototype={init:function(){var e=this;return e.height=e.$e.css("height"),e.isEnabled()?void e.buildEditor(!0):(e.buildEditor(),e.buildBtnPane(),e.fixedBtnPaneEvents(),void e.buildOverlay())},buildEditor:function(e){var t=this,o=t.o.prefix;if(e!==!0){t.$box=n("",{"class":o+"box "+o+t.o.lang+" trumbowyg"}),t.isTextarea=!0,t.$e.is("textarea")?t.$editor=n(""):(t.$editor=t.$e,t.$e=t.buildTextarea().val(t.$e.val()),t.isTextarea=!1),t.$e.hide().addClass(o+"textarea");var i="";t.isTextarea?(i=t.$e.val(),t.$box.insertAfter(t.$e).append(t.$editor).append(t.$e)):(i=t.$editor.html(),t.$box.insertAfter(t.$editor).append(t.$e).append(t.$editor),t.syncCode()),t.$editor.addClass(o+"editor").attr("contenteditable",!0).attr("dir",t.o.dir).html(i),t.o.resetCss&&t.$editor.addClass(o+"reset-css"),t.o.autogrow||n.each([t.$editor,t.$e],function(e,n){n.css({height:t.height,overflow:"auto"})}),t.o.semantic&&(t.$editor.html(t.$editor.html().replace("
","").replace(" ","")),t.semanticCode()),t.$editor.on("dblclick","img",function(){var e=n(this);return t.openModalInsert(t.lang.insertImage,{url:{label:"URL",value:e.attr("src"),required:!0},alt:{label:"description",value:e.attr("alt")}},function(t){e.attr("src",t.url),e.attr("alt",t.alt)}),!1}).on("keyup",function(e){t.semanticCode(!1,13===e.which)}).on("blur",function(){t.syncCode()})}else if(!t.$e.is("textarea")){var r=t.buildTextarea().val(t.$e.val());t.$e.hide().after(r)}},buildTextarea:function(){return n("",{name:this.$e.attr("id"),height:this.height})},buildBtnPane:function(){var t=this,o=t.o.prefix;if(t.o.btns!==!1){t.$btnPane=n("
",{"class":o+"button-pane"}),n.each(t.o.btns.concat(t.o.btnsAdd),function(e,i){try{var r=i.split("btnGrp-");void 0!==r[1]&&(i=n.trumbowyg.btnsGrps[r[1]])}catch(a){}n.isArray(i)||(i=[i]),n.each(i,function(e,i){try{var r=n("");"|"===i?r.addClass(o+"separator"):t.isSupportedBtn(i)&&r.append(t.buildBtn(i)),t.$btnPane.append(r)}catch(a){}})});var i=n("",{"class":o+"not-disable "+o+"buttons-right"});t.o.fullscreenable&&i.append(t.buildRightBtn("fullscreen").on("click",function(){var i=o+"fullscreen";t.$box.toggleClass(i),t.$box.hasClass(i)?(n("body").css("overflow","hidden"),n.each([t.$editor,t.$e],function(){n(this).css({height:"calc(100% - 35px)",overflow:"auto"})}),t.$btnPane.css("width","100%")):(n("body").css("overflow","auto"),t.$box.removeAttr("style"),t.o.autogrow||n([t.$editor,t.$e]).each(function(e,n){n.css("height",t.height)})),n(e).trigger("scroll")})),t.o.closable&&i.append(t.buildRightBtn("close").on("click",function(){t.$box.hasClass(o+"fullscreen")&&n("body").css("overflow","auto"),t.destroy()})),i.not(":empty")&&t.$btnPane.append(i),t.$box.prepend(t.$btnPane)}},buildBtn:function(e){var t=this,o=t.o.prefix,i=t.o.btnsDef[e],r=i.dropdown,a=t.lang[e]||e,s=n("",{type:"button","class":o+e+"-button"+(i.ico?" "+o+i.ico+"-button":""),text:i.text||i.title||a,title:i.title||i.text||a,mousedown:function(a){return(!r||t.$box.find("."+e+"-"+o+"dropdown").is(":hidden"))&&n("body").trigger("mousedown"),!t.$btnPane.hasClass(o+"disable")||n(this).hasClass(o+"active")||n(this).parent().hasClass(o+"not-disable")?(t.execCmd((r?"dropdown":!1)||i.func||e,i.param||e),a.stopPropagation(),void a.preventDefault()):!1}});if(r){s.addClass(o+"open-dropdown");for(var l=o+"dropdown",d=n("",{"class":e+"-"+l+" "+l+" "+o+"fixed-top"}),c=0,u=r.length;u>c;c++)t.o.btnsDef[r[c]]&&t.isSupportedBtn(r[c])&&d.append(t.buildSubBtn(r[c]));t.$box.append(d.hide())}return s},buildSubBtn:function(e){var t=this,o=t.o.btnsDef[e];return n("",{type:"button",text:o.text||o.title||t.lang[e]||e,mousedown:function(i){return n("body").trigger("mousedown"),t.execCmd(o.func||e,o.param||e),i.stopPropagation(),i.preventDefault(),!1}})},buildRightBtn:function(e){return n("",{type:"button","class":this.o.prefix+e+"-button",title:this.lang[e],text:this.lang[e]})},isSupportedBtn:function(e){return"function"!=typeof this.o.btnsDef[e].isSupported||this.o.btnsDef[e].isSupported()},buildOverlay:function(){var e=this;return e.$overlay=n("",{"class":e.o.prefix+"overlay"}).css({top:e.$btnPane.outerHeight(),height:parseInt(e.$editor.outerHeight())+1+"px"}).appendTo(e.$box),e.$overlay},showOverlay:function(){var t=this;n(e).trigger("scroll"),t.$overlay.fadeIn(t.o.duration),t.$box.addClass(t.o.prefix+"box-blur")},hideOverlay:function(){var e=this;e.$overlay.fadeOut(e.o.duration/4),e.$box.removeClass(e.o.prefix+"box-blur")},fixedBtnPaneEvents:function(){var t=this,o=t.o.fixedFullWidth;t.o.fixedBtnPane&&(t.isFixed=!1,n(e).on("scroll resize",function(){if(t.$box){t.syncCode();var i=n(e).scrollTop(),r=t.$box.offset().top+1,a=i-r>0&&i-r-parseInt(t.height)<0,s=t.$btnPane,l=s.css("height"),d=s.outerHeight();a?(t.isFixed||(t.isFixed=!0,s.css({position:"fixed",top:0,left:o?"0":"auto",zIndex:7}),t.$editor.css({marginTop:l}),t.$e.css({marginTop:l})),s.css({width:o?"100%":parseInt(t.$box.css("width"))-1+"px"}),n("."+t.o.prefix+"fixed-top",t.$box).css({position:o?"fixed":"absolute",top:o?d:parseInt(d)+(i-r)+"px",zIndex:15})):t.isFixed&&(t.isFixed=!1,s.removeAttr("style"),t.$editor.css({marginTop:0}),t.$e.css({marginTop:0}),n("."+t.o.prefix+"fixed-top",t.$box).css({position:"absolute",top:d}))}}))},destroy:function(){var e=this,t=e.o.prefix,n=e.height,o=e.html();e.$box.after(e.isTextarea?e.$e.css({height:n}).val(o).removeClass(t+"textarea").show():e.$editor.css({height:n}).removeClass(t+"editor").attr("contenteditable",!1).html(o).show()),e.$box.remove(),e.$creator.removeData("trumbowyg")},empty:function(){this.$e.val(""),this.syncCode(!0)},toggle:function(){var e=this,t=e.o.prefix;e.semanticCode(!1,!0),e.$editor.toggle(),e.$e.toggle(),e.$btnPane.toggleClass(t+"disable"),e.$btnPane.find("."+t+"viewHTML-button").toggleClass(t+"active")},dropdown:function(t){var o=this,i=o.o.prefix,r=o.$box.find("."+t+"-"+i+"dropdown"),a=o.$btnPane.find("."+i+t+"-button");if(r.is(":hidden")){var s=a.offset().left;a.addClass(i+"active"),r.css({position:"absolute",top:o.$btnPane.outerHeight(),left:o.o.fixedFullWidth&&o.isFixed?s+"px":s-o.$btnPane.offset().left+"px"}).show(),n(e).trigger("scroll"),n("body").on("mousedown",function(){n("."+i+"dropdown").hide(),n("."+i+"active").removeClass(i+"active"),n("body").off("mousedown")})}else n("body").trigger("mousedown")},html:function(e){var t=this;return e?(t.$e.val(e),t.syncCode(!0),t):t.$e.val()},syncCode:function(e){var t=this;!e&&t.$editor.is(":visible")?t.$e.val(t.$editor.html()):t.$editor.html(t.$e.val()),t.o.autogrow&&(t.height=t.$editor.css("height"),t.$e.css({height:t.height}))},semanticCode:function(e,t){var o=this;o.syncCode(e),o.o.semantic&&(o.semanticTag("b","strong"),o.semanticTag("i","em"),o.semanticTag("strike","del"),t&&(o.$editor.contents().filter(function(){return 3===this.nodeType&&n.trim(this.nodeValue).length>0}).wrap("").end().filter("br").remove(),o.saveSelection(),o.semanticTag("div","p"),o.restoreSelection()),o.$e.val(o.$editor.html()))},semanticTag:function(e,t){n(e,this.$editor).each(function(){n(this).replaceWith(function(){return"<"+t+">"+n(this).html()+""+t+">"})})},createLink:function(){var e=this;e.saveSelection(),e.openModalInsert(e.lang.createLink,{url:{label:"URL",value:"http://",required:!0},title:{label:e.lang.title,value:e.selection},text:{label:e.lang.text,value:e.selection}},function(t){e.execCmd("createLink",t.url);var o=n('a[href="'+t.url+'"]:not([title])',e.$box);return t.text.length>0&&o.text(t.text),t.title.length>0&&o.attr("title",t.title),!0})},insertImage:function(){var e=this;e.saveSelection(),e.openModalInsert(e.lang.insertImage,{url:{label:"URL",value:"http://",required:!0},alt:{label:e.lang.description,value:e.selection}},function(t){return e.execCmd("insertImage",t.url),n('img[src="'+t.url+'"]:not([alt])',e.$box).attr("alt",t.alt),!0})},execCmd:function(e,n){var o=this;"dropdown"!=e&&o.$editor.focus();try{o[e](n)}catch(i){try{e(n,o)}catch(r){o.$editor.focus(),"insertHorizontalRule"==e?n=null:"formatBlock"==e&&(-1!==navigator.userAgent.indexOf("MSIE")||navigator.appVersion.indexOf("Trident/")>0)&&(n="<"+n+">"),t.execCommand(e,!1,n)}}o.syncCode()},openModal:function(t,o){var i=this,r=i.o.prefix;if(n("."+r+"modal-box",i.$box).size()>0)return!1;i.saveSelection(),i.showOverlay(),i.$btnPane.addClass(r+"disable");var a=n("",{"class":r+"modal "+r+"fixed-top"}).css({top:parseInt(i.$btnPane.css("height"))+1+"px"}).appendTo(i.$box);i.$overlay.one("click",function(e){e.preventDefault(),a.trigger(r+"cancel")});var s=n("",{action:"",html:o}).on("submit",function(e){e.preventDefault(),a.trigger(r+"confirm")}).on("reset",function(e){e.preventDefault(),a.trigger(r+"cancel")}),l=n("",{"class":r+"modal-box",html:s}).css({top:"-"+parseInt(i.$btnPane.outerHeight())+"px",opacity:0}).appendTo(a).animate({top:0,opacity:1},i.o.duration/2);return n("",{text:t,"class":r+"modal-title"}).prependTo(l),l.find("input:first").focus(),i.buildModalBtn("submit",l),i.buildModalBtn("reset",l),n(e).trigger("scroll"),a},buildModalBtn:function(e,t){var o=this,i=o.o.prefix;return n("",{"class":i+"modal-button "+i+"modal-"+e,type:e,text:o.lang[e]||e}).appendTo(t.find("form"))},closeModal:function(){var e=this,t=e.o.prefix;e.$btnPane.removeClass(t+"disable"),e.$overlay.off();var o=n("."+t+"modal-box",e.$box);o.animate({top:"-"+o.css("height")},e.o.duration/2,function(){n(this).parent().remove(),e.hideOverlay()})},openModalInsert:function(e,t,o){var i=this,r=i.o.prefix,a=i.lang,s="";for(var l in t){var d=t[l],c=void 0===d.label?a[l]?a[l]:l:a[d.label]?a[d.label]:d.label;void 0===d.name&&(d.name=l),d.pattern||"url"!==l||(d.pattern=/^(http|https):\/\/([\w~#!:.?+=&%@!\-\/]+)$/,d.patternError=a.invalidUrl),s+='"}return i.openModal(e,s).on(r+"confirm",function(){var e=n(this).find("form"),a=!0,s={};for(var l in t){var d=n('input[name="'+l+'"]',e);s[l]=n.trim(d.val()),t[l].required&&""===s[l]?(a=!1,i.addErrorOnModalField(d,i.lang.required)):t[l].pattern&&!t[l].pattern.test(s[l])&&(a=!1,i.addErrorOnModalField(d,t[l].patternError))}a&&(i.restoreSelection(),o(s,t)&&(i.syncCode(),i.closeModal(),n(this).off(r+"confirm")))}).one(r+"cancel",function(){n(this).off(r+"confirm"),i.closeModal(),i.restoreSelection()})},addErrorOnModalField:function(e,t){var o=this.o.prefix,i=e.parent();e.on("change keyup",function(){i.removeClass(o+"input-error")}),i.addClass(o+"input-error").find("input+span").append(n("",{"class":o+"msg-error",text:t}))},saveSelection:function(){var n=this,o=t;if(n.selection=null,e.getSelection){var i=e.getSelection();i.getRangeAt&&i.rangeCount&&(n.selection=i.getRangeAt(0))}else o.selection&&o.selection.createRange&&(n.selection=o.selection.createRange())},restoreSelection:function(){var n=this.selection;if(n)if(e.getSelection){var o=e.getSelection();o.removeAllRanges(),o.addRange(n)}else t.selection&&n.select&&n.select()},isEnabled:function(){var e=new RegExp("(iPad|webOS)"),t=new RegExp("(iPhone|iPod|Android|BlackBerry|Windows Phone|ZuneWP7)"),n=navigator.userAgent;return this.o.tablet===!0&&e.test(n)||this.o.mobile===!0&&t.test(n)}}}(window,document,jQuery);
\ No newline at end of file
diff --git a/dist/ui/images/icons-2x.png b/dist/ui/images/icons-2x.png
new file mode 100644
index 000000000..fba69e609
Binary files /dev/null and b/dist/ui/images/icons-2x.png differ
diff --git a/dist/ui/images/icons.png b/dist/ui/images/icons.png
new file mode 100644
index 000000000..a52643067
Binary files /dev/null and b/dist/ui/images/icons.png differ
diff --git a/dist/ui/trumbowyg.css b/dist/ui/trumbowyg.css
new file mode 100644
index 000000000..6c618e8a3
--- /dev/null
+++ b/dist/ui/trumbowyg.css
@@ -0,0 +1,467 @@
+/**
+ * Trumbowyg v1.1.2 - A lightweight WYSIWYG editor
+ * Default stylesheet for Trumbowyg editor
+ * ------------------------
+ * @link http://alex-d.github.io/Trumbowyg
+ * @license MIT
+ * @author Alexandre Demode (Alex-D)
+ * Twitter : @AlexandreDemode
+ * Website : alex-d.fr
+ */
+
+.trumbowyg-box, .trumbowyg-editor {
+ display: block;
+ position: relative;
+ border: 1px solid #DDD;
+ width: 96%;
+ min-height: 300px;
+ margin: 17px auto; }
+
+.trumbowyg-box .trumbowyg-editor {
+ margin: 0 auto; }
+
+.trumbowyg-box.trumbowyg-fullscreen {
+ background: #FEFEFE; }
+
+.trumbowyg-editor, .trumbowyg-textarea {
+ position: relative;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 1% 2%;
+ min-height: 300px;
+ width: 100%;
+ border-style: none;
+ resize: none;
+ outline: none; }
+
+.trumbowyg-box-blur .trumbowyg-editor * {
+ color: transparent !important;
+ text-shadow: 0 0 7px #333; }
+.trumbowyg-box-blur .trumbowyg-editor img {
+ opacity: 0.2; }
+
+.trumbowyg-textarea {
+ position: relative;
+ display: block;
+ overflow: auto;
+ border: none;
+ white-space: normal; }
+
+.trumbowyg-button-pane {
+ position: relative;
+ width: 100%;
+ background: #ecf0f1;
+ border-bottom: 1px solid #d7e0e2;
+ margin: 0;
+ padding: 0;
+ list-style-type: none;
+ line-height: 10px;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden; }
+ .trumbowyg-button-pane li {
+ display: inline-block;
+ text-align: center;
+ overflow: hidden; }
+ .trumbowyg-button-pane li.trumbowyg-separator {
+ width: 1px;
+ background: #d7e0e2;
+ margin: 0 5px;
+ height: 35px; }
+ .trumbowyg-button-pane.trumbowyg-disable li:not(.trumbowyg-not-disable) button:not(.trumbowyg-active) {
+ opacity: 0.2;
+ cursor: default; }
+ .trumbowyg-button-pane.trumbowyg-disable li.trumbowyg-separator {
+ background: #e3e9eb; }
+ .trumbowyg-button-pane:not(.trumbowyg-disable) li button:hover, .trumbowyg-button-pane:not(.trumbowyg-disable) li button:focus, .trumbowyg-button-pane li button.trumbowyg-active, .trumbowyg-button-pane li.trumbowyg-not-disable button:hover, .trumbowyg-button-pane li.trumbowyg-not-disable button:focus {
+ background-color: #FFF;
+ outline: none; }
+ .trumbowyg-button-pane li .trumbowyg-open-dropdown:after {
+ display: block;
+ content: " ";
+ position: absolute;
+ top: 25px;
+ right: 3px;
+ height: 0;
+ width: 0;
+ border: 3px solid transparent;
+ border-top-color: #555; }
+ .trumbowyg-button-pane .trumbowyg-buttons-right {
+ float: right;
+ width: auto; }
+ .trumbowyg-button-pane .trumbowyg-buttons-right button {
+ float: left; }
+
+.trumbowyg-dropdown {
+ width: 200px;
+ border: 1px solid #ecf0f1;
+ padding: 5px 0;
+ border-top: none;
+ background: #FFF;
+ margin-left: -1px;
+ -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0 2px 3px;
+ box-shadow: rgba(0, 0, 0, 0.1) 0 2px 3px; }
+ .trumbowyg-dropdown button {
+ display: block;
+ width: 100%;
+ height: 35px;
+ line-height: 35px;
+ text-decoration: none;
+ background: #FFF;
+ padding: 0 14px;
+ color: #333;
+ border: none;
+ cursor: pointer;
+ text-align: left;
+ font-size: 15px;
+ -webkit-transition: all 0.15s;
+ -o-transition: all 0.15s;
+ transition: all 0.15s; }
+ .trumbowyg-dropdown button:hover, .trumbowyg-dropdown button:focus {
+ background: #ecf0f1; }
+
+/* Modal box */
+.trumbowyg-modal {
+ position: absolute;
+ top: 0;
+ left: 50%;
+ margin-left: -260px;
+ width: 520px;
+ height: 290px;
+ overflow: hidden; }
+
+.trumbowyg-modal-box {
+ position: absolute;
+ top: 0;
+ left: 50%;
+ margin-left: -250px;
+ width: 500px;
+ height: 275px;
+ z-index: 1;
+ background-color: #FFF;
+ text-align: center;
+ -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 3px;
+ box-shadow: rgba(0, 0, 0, 0.2) 0 2px 3px;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden; }
+ .trumbowyg-modal-box .trumbowyg-modal-title {
+ font-size: 24px;
+ font-weight: bold;
+ margin: 0 0 20px;
+ padding: 15px 0 13px;
+ display: block;
+ border-bottom: 1px solid #EEE;
+ color: #333;
+ background: #fbfcfc; }
+ .trumbowyg-modal-box .trumbowyg-progress {
+ width: 100%;
+ background: #F00;
+ height: 3px;
+ position: absolute;
+ top: 58px; }
+ .trumbowyg-modal-box .trumbowyg-progress .trumbowyg-progress-bar {
+ background: #2BC06A;
+ height: 100%;
+ -webkit-transition: width 0.15s linear;
+ -o-transition: width 0.15s linear;
+ transition: width 0.15s linear; }
+ .trumbowyg-modal-box label {
+ display: block;
+ position: relative;
+ margin: 15px 12px;
+ height: 27px;
+ line-height: 27px;
+ overflow: hidden; }
+ .trumbowyg-modal-box label .trumbowyg-input-infos {
+ display: block;
+ text-align: left;
+ height: 25px;
+ line-height: 25px;
+ -webkit-transition: all 0.15;
+ -o-transition: all 0.15;
+ transition: all 0.15; }
+ .trumbowyg-modal-box label .trumbowyg-input-infos span {
+ display: block;
+ color: #859fa5;
+ background-color: #fbfcfc;
+ border: 1px solid #DEDEDE;
+ padding: 0 2%;
+ width: 19.5%; }
+ .trumbowyg-modal-box label .trumbowyg-input-infos span.trumbowyg-msg-error {
+ color: #e74c3c; }
+ .trumbowyg-modal-box label.trumbowyg-input-error input, .trumbowyg-modal-box label.trumbowyg-input-error textarea {
+ border: 1px solid #e74c3c; }
+ .trumbowyg-modal-box label.trumbowyg-input-error .trumbowyg-input-infos {
+ margin-top: -27px; }
+ .trumbowyg-modal-box label input {
+ position: absolute;
+ top: 0;
+ right: 0;
+ height: 25px;
+ line-height: 25px;
+ border: 1px solid #DEDEDE;
+ background: transparent;
+ width: 72%;
+ padding: 0 2%;
+ margin: 0 0 0 23%;
+ -webkit-transition: all 0.15s;
+ -o-transition: all 0.15s;
+ transition: all 0.15s; }
+ .trumbowyg-modal-box label input:hover, .trumbowyg-modal-box label input:focus {
+ outline: none;
+ border: 1px solid #95a5a6; }
+ .trumbowyg-modal-box label input:focus {
+ background: rgba(230, 230, 255, 0.1); }
+ .trumbowyg-modal-box .error {
+ margin-top: 25px;
+ display: block;
+ color: red; }
+ .trumbowyg-modal-box .trumbowyg-modal-button {
+ position: absolute;
+ bottom: 10px;
+ right: 0;
+ text-decoration: none;
+ color: #FFF;
+ display: block;
+ width: 100px;
+ height: 35px;
+ line-height: 33px;
+ margin: 0 10px;
+ background-color: #333;
+ border: none;
+ border-top: none;
+ cursor: pointer;
+ font-family: "Trebuchet MS", Helvetica, Verdana, sans-serif;
+ font-size: 16px;
+ -webkit-transition: all 0.15s;
+ -o-transition: all 0.15s;
+ transition: all 0.15s; }
+ .trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit {
+ right: 110px;
+ background: #2bc069; }
+ .trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:hover, .trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:focus {
+ background: #40d47d;
+ outline: none; }
+ .trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:active {
+ background: #25a259; }
+ .trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset {
+ color: #555;
+ background: #e6e6e6; }
+ .trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:hover, .trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:focus {
+ background: #fbfbfb;
+ outline: none; }
+ .trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:active {
+ background: #d4d4d4; }
+
+.trumbowyg-overlay {
+ position: absolute;
+ background-color: rgba(255, 255, 255, 0.5);
+ width: 100%;
+ left: 0;
+ display: none; }
+
+/**
+ * Fullscreen
+ */
+.trumbowyg-fullscreen {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ z-index: 99999; }
+ .trumbowyg-fullscreen.trumbowyg-box, .trumbowyg-fullscreen .trumbowyg-editor {
+ border: none; }
+ .trumbowyg-fullscreen .trumbowyg-overlay {
+ height: 100% !important; }
+
+/*
+ * Reset for resetCss option
+ */
+.trumbowyg-editor object, .trumbowyg-editor embed, .trumbowyg-editor video, .trumbowyg-editor img {
+ width: auto;
+ max-width: 100%; }
+.trumbowyg-editor video, .trumbowyg-editor img {
+ height: auto; }
+.trumbowyg-editor img {
+ cursor: move; }
+.trumbowyg-editor.trumbowyg-reset-css {
+ background: #FEFEFE !important;
+ font-family: "Trebuchet MS", Helvetica, Verdana, sans-serif !important;
+ font-size: 14px !important;
+ line-height: 1.45em !important;
+ white-space: normal !important;
+ color: #333; }
+ .trumbowyg-editor.trumbowyg-reset-css a {
+ color: #15c !important;
+ text-decoration: underline !important; }
+ .trumbowyg-editor.trumbowyg-reset-css div, .trumbowyg-editor.trumbowyg-reset-css p, .trumbowyg-editor.trumbowyg-reset-css ul, .trumbowyg-editor.trumbowyg-reset-css ol, .trumbowyg-editor.trumbowyg-reset-css blockquote {
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
+ background: none !important;
+ margin: 0 !important;
+ margin-bottom: 15px !important;
+ line-height: 1.4em !important;
+ font-family: "Trebuchet MS", Helvetica, Verdana, sans-serif !important;
+ font-size: 14px !important;
+ border: none; }
+ .trumbowyg-editor.trumbowyg-reset-css iframe, .trumbowyg-editor.trumbowyg-reset-css object, .trumbowyg-editor.trumbowyg-reset-css hr {
+ margin-bottom: 15px !important; }
+ .trumbowyg-editor.trumbowyg-reset-css blockquote {
+ margin-left: 32px !important;
+ font-style: italic !important;
+ color: #555; }
+ .trumbowyg-editor.trumbowyg-reset-css ul, .trumbowyg-editor.trumbowyg-reset-css ol {
+ padding-left: 20px !important; }
+ .trumbowyg-editor.trumbowyg-reset-css ul ul, .trumbowyg-editor.trumbowyg-reset-css ol ol, .trumbowyg-editor.trumbowyg-reset-css ul ol, .trumbowyg-editor.trumbowyg-reset-css ol ul {
+ border: none;
+ margin: 2px !important;
+ padding: 0 !important;
+ padding-left: 24px !important; }
+ .trumbowyg-editor.trumbowyg-reset-css hr {
+ display: block;
+ height: 1px;
+ border: none;
+ border-top: 1px solid #CCC; }
+ .trumbowyg-editor.trumbowyg-reset-css h1, .trumbowyg-editor.trumbowyg-reset-css h2, .trumbowyg-editor.trumbowyg-reset-css h3, .trumbowyg-editor.trumbowyg-reset-css h4 {
+ color: #111;
+ background: none;
+ margin: 0 !important;
+ padding: 0 !important;
+ font-weight: bold; }
+ .trumbowyg-editor.trumbowyg-reset-css h1 {
+ font-size: 32px !important;
+ line-height: 38px !important;
+ margin-bottom: 20px !important; }
+ .trumbowyg-editor.trumbowyg-reset-css h2 {
+ font-size: 26px !important;
+ line-height: 34px !important;
+ margin-bottom: 15px !important; }
+ .trumbowyg-editor.trumbowyg-reset-css h3 {
+ font-size: 22px !important;
+ line-height: 28px !important;
+ margin-bottom: 7px !important; }
+ .trumbowyg-editor.trumbowyg-reset-css h4 {
+ font-size: 16px !important;
+ line-height: 22px !important;
+ margin-bottom: 7px !important; }
+
+/*
+ * Buttons icons
+ */
+.trumbowyg-button-pane li button {
+ display: block;
+ position: relative;
+ text-indent: -9999px;
+ width: 35px;
+ height: 35px;
+ overflow: hidden;
+ background: transparent url("./images/icons.png") no-repeat;
+ border: none;
+ cursor: pointer;
+ -webkit-transition: background-color 0.15s, background-image 0.15s, opacity 0.15s;
+ -o-transition: background-color 0.15s, background-image 0.15s, opacity 0.15s;
+ transition: background-color 0.15s, background-image 0.15s, opacity 0.15s;
+ /* English and others */ }
+ .trumbowyg-button-pane li button.trumbowyg-viewHTML-button {
+ background-position: 5px -545px; }
+ .trumbowyg-button-pane li button.trumbowyg-formatting-button {
+ background-position: 5px -120px; }
+ .trumbowyg-button-pane li button.trumbowyg-bold-button, .trumbowyg-button-pane li button.trumbowyg-strong-button {
+ background-position: 5px -45px; }
+ .trumbowyg-button-pane li button.trumbowyg-italic-button, .trumbowyg-button-pane li button.trumbowyg-em-button {
+ background-position: 5px 5px; }
+ .trumbowyg-button-pane li button.trumbowyg-underline-button {
+ background-position: 5px -470px; }
+ .trumbowyg-button-pane li button.trumbowyg-strikethrough-button, .trumbowyg-button-pane li button.trumbowyg-del-button {
+ background-position: 5px -445px; }
+ .trumbowyg-button-pane li button.trumbowyg-link-button {
+ background-position: 5px -345px; }
+ .trumbowyg-button-pane li button.trumbowyg-insertImage-button {
+ background-position: 5px -245px; }
+ .trumbowyg-button-pane li button.trumbowyg-justifyLeft-button {
+ background-position: 5px -320px; }
+ .trumbowyg-button-pane li button.trumbowyg-justifyCenter-button {
+ background-position: 5px -70px; }
+ .trumbowyg-button-pane li button.trumbowyg-justifyRight-button {
+ background-position: 5px -395px; }
+ .trumbowyg-button-pane li button.trumbowyg-justifyFull-button {
+ background-position: 5px -295px; }
+ .trumbowyg-button-pane li button.trumbowyg-unorderedList-button {
+ background-position: 5px -495px; }
+ .trumbowyg-button-pane li button.trumbowyg-orderedList-button {
+ background-position: 5px -370px; }
+ .trumbowyg-button-pane li button.trumbowyg-horizontalRule-button {
+ background-position: 5px -220px; }
+ .trumbowyg-button-pane li button.trumbowyg-fullscreen-button {
+ background-position: 5px -170px; }
+ .trumbowyg-button-pane li button.trumbowyg-close-button {
+ background-position: 5px -95px; }
+
+.trumbowyg-fullscreen .trumbowyg-button-pane li button.trumbowyg-fullscreen-button {
+ background-position: 5px -145px; }
+
+.trumbowyg-button-pane li:first-child button {
+ margin-left: 6px; }
+.trumbowyg-button-pane li:last-child button {
+ margin-right: 6px; }
+
+/* French */
+.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-bold-button, .trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strong-button {
+ background-position: 5px -195px; }
+.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-underline-button {
+ background-position: 5px -420px; }
+.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strikethrough-button, .trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-del-button {
+ background-position: 5px -270px; }
+
+@media only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 4/3), only screen and (min-device-pixel-ratio: 1.3), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
+ /* French */
+ .trumbowyg-button-pane li button {
+ -webkit-background-size: 25px 575px !important;
+ background-size: 25px 575px !important;
+ background-image: url("./images/icons-2x.png") !important;
+ /* English and others */ }
+ .trumbowyg-button-pane li button.trumbowyg-viewHTML-button {
+ background-position: 5px -545px; }
+ .trumbowyg-button-pane li button.trumbowyg-formatting-button {
+ background-position: 5px -120px; }
+ .trumbowyg-button-pane li button.trumbowyg-bold-button, .trumbowyg-button-pane li button.trumbowyg-strong-button {
+ background-position: 5px -45px; }
+ .trumbowyg-button-pane li button.trumbowyg-italic-button, .trumbowyg-button-pane li button.trumbowyg-em-button {
+ background-position: 5px 5px; }
+ .trumbowyg-button-pane li button.trumbowyg-underline-button {
+ background-position: 5px -470px; }
+ .trumbowyg-button-pane li button.trumbowyg-strikethrough-button, .trumbowyg-button-pane li button.trumbowyg-del-button {
+ background-position: 5px -445px; }
+ .trumbowyg-button-pane li button.trumbowyg-link-button {
+ background-position: 5px -345px; }
+ .trumbowyg-button-pane li button.trumbowyg-insertImage-button {
+ background-position: 5px -245px; }
+ .trumbowyg-button-pane li button.trumbowyg-justifyLeft-button {
+ background-position: 5px -320px; }
+ .trumbowyg-button-pane li button.trumbowyg-justifyCenter-button {
+ background-position: 5px -70px; }
+ .trumbowyg-button-pane li button.trumbowyg-justifyRight-button {
+ background-position: 5px -395px; }
+ .trumbowyg-button-pane li button.trumbowyg-justifyFull-button {
+ background-position: 5px -295px; }
+ .trumbowyg-button-pane li button.trumbowyg-unorderedList-button {
+ background-position: 5px -495px; }
+ .trumbowyg-button-pane li button.trumbowyg-orderedList-button {
+ background-position: 5px -370px; }
+ .trumbowyg-button-pane li button.trumbowyg-horizontalRule-button {
+ background-position: 5px -220px; }
+ .trumbowyg-button-pane li button.trumbowyg-fullscreen-button {
+ background-position: 5px -170px; }
+ .trumbowyg-button-pane li button.trumbowyg-close-button {
+ background-position: 5px -95px; }
+ .trumbowyg-fullscreen .trumbowyg-button-pane li a.trumbowyg-fullscreen-button {
+ background-position: 5px -145px; }
+ .trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-bold-button, .trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strong-button {
+ background-position: 5px -195px; }
+ .trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-underline-button {
+ background-position: 5px -420px; }
+ .trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strikethrough-button, .trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-del-button {
+ background-position: 5px -270px; } }
diff --git a/dist/ui/trumbowyg.min.css b/dist/ui/trumbowyg.min.css
new file mode 100644
index 000000000..f6bbaabd4
--- /dev/null
+++ b/dist/ui/trumbowyg.min.css
@@ -0,0 +1,2 @@
+/** Trumbowyg v1.1.2 - A lightweight WYSIWYG editor - alex-d.github.io/Trumbowyg - License MIT - Author : Alexandre Demode (Alex-D) / alex-d.fr */
+.trumbowyg-box,.trumbowyg-editor{display:block;position:relative;border:1px solid #DDD;width:96%;min-height:300px;margin:17px auto}.trumbowyg-box .trumbowyg-editor{margin:0 auto}.trumbowyg-box.trumbowyg-fullscreen{background:#FEFEFE}.trumbowyg-editor,.trumbowyg-textarea{position:relative;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1% 2%;min-height:300px;width:100%;border-style:none;resize:none;outline:0}.trumbowyg-box-blur .trumbowyg-editor *{color:transparent!important;text-shadow:0 0 7px #333}.trumbowyg-box-blur .trumbowyg-editor img{opacity:.2}.trumbowyg-textarea{position:relative;display:block;overflow:auto;border:none;white-space:normal}.trumbowyg-button-pane{position:relative;width:100%;background:#ecf0f1;border-bottom:1px solid #d7e0e2;margin:0;padding:0;list-style-type:none;line-height:10px;-webkit-backface-visibility:hidden;backface-visibility:hidden}.trumbowyg-button-pane li{display:inline-block;text-align:center;overflow:hidden}.trumbowyg-button-pane li.trumbowyg-separator{width:1px;background:#d7e0e2;margin:0 5px;height:35px}.trumbowyg-button-pane.trumbowyg-disable li:not(.trumbowyg-not-disable) button:not(.trumbowyg-active){opacity:.2;cursor:default}.trumbowyg-button-pane.trumbowyg-disable li.trumbowyg-separator{background:#e3e9eb}.trumbowyg-button-pane li button.trumbowyg-active,.trumbowyg-button-pane li.trumbowyg-not-disable button:focus,.trumbowyg-button-pane li.trumbowyg-not-disable button:hover,.trumbowyg-button-pane:not(.trumbowyg-disable) li button:focus,.trumbowyg-button-pane:not(.trumbowyg-disable) li button:hover{background-color:#FFF;outline:0}.trumbowyg-button-pane li .trumbowyg-open-dropdown:after{display:block;content:" ";position:absolute;top:25px;right:3px;height:0;width:0;border:3px solid transparent;border-top-color:#555}.trumbowyg-button-pane .trumbowyg-buttons-right{float:right;width:auto}.trumbowyg-button-pane .trumbowyg-buttons-right button{float:left}.trumbowyg-dropdown{width:200px;border:1px solid #ecf0f1;padding:5px 0;border-top:none;background:#FFF;margin-left:-1px;-webkit-box-shadow:rgba(0,0,0,.1) 0 2px 3px;box-shadow:rgba(0,0,0,.1) 0 2px 3px}.trumbowyg-dropdown button{display:block;width:100%;height:35px;line-height:35px;text-decoration:none;background:#FFF;padding:0 14px;color:#333;border:none;cursor:pointer;text-align:left;font-size:15px;-webkit-transition:all .15s;-o-transition:all .15s;transition:all .15s}.trumbowyg-dropdown button:focus,.trumbowyg-dropdown button:hover{background:#ecf0f1}.trumbowyg-modal{position:absolute;top:0;left:50%;margin-left:-260px;width:520px;height:290px;overflow:hidden}.trumbowyg-modal-box{position:absolute;top:0;left:50%;margin-left:-250px;width:500px;height:275px;z-index:1;background-color:#FFF;text-align:center;-webkit-box-shadow:rgba(0,0,0,.2) 0 2px 3px;box-shadow:rgba(0,0,0,.2) 0 2px 3px;-webkit-backface-visibility:hidden;backface-visibility:hidden}.trumbowyg-modal-box .trumbowyg-modal-title{font-size:24px;font-weight:700;margin:0 0 20px;padding:15px 0 13px;display:block;border-bottom:1px solid #EEE;color:#333;background:#fbfcfc}.trumbowyg-modal-box .trumbowyg-progress{width:100%;background:red;height:3px;position:absolute;top:58px}.trumbowyg-modal-box .trumbowyg-progress .trumbowyg-progress-bar{background:#2BC06A;height:100%;-webkit-transition:width .15s linear;-o-transition:width .15s linear;transition:width .15s linear}.trumbowyg-modal-box label{display:block;position:relative;margin:15px 12px;height:27px;line-height:27px;overflow:hidden}.trumbowyg-modal-box label .trumbowyg-input-infos{display:block;text-align:left;height:25px;line-height:25px;-webkit-transition:all .15;-o-transition:all .15;transition:all .15}.trumbowyg-modal-box label .trumbowyg-input-infos span{display:block;color:#859fa5;background-color:#fbfcfc;border:1px solid #DEDEDE;padding:0 2%;width:19.5%}.trumbowyg-modal-box label .trumbowyg-input-infos span.trumbowyg-msg-error{color:#e74c3c}.trumbowyg-modal-box label.trumbowyg-input-error input,.trumbowyg-modal-box label.trumbowyg-input-error textarea{border:1px solid #e74c3c}.trumbowyg-modal-box label.trumbowyg-input-error .trumbowyg-input-infos{margin-top:-27px}.trumbowyg-modal-box label input{position:absolute;top:0;right:0;height:25px;line-height:25px;border:1px solid #DEDEDE;background:0 0;width:72%;padding:0 2%;margin:0 0 0 23%;-webkit-transition:all .15s;-o-transition:all .15s;transition:all .15s}.trumbowyg-modal-box label input:focus,.trumbowyg-modal-box label input:hover{outline:0;border:1px solid #95a5a6}.trumbowyg-modal-box label input:focus{background:rgba(230,230,255,.1)}.trumbowyg-modal-box .error{margin-top:25px;display:block;color:red}.trumbowyg-modal-box .trumbowyg-modal-button{position:absolute;bottom:10px;right:0;text-decoration:none;color:#FFF;display:block;width:100px;height:35px;line-height:33px;margin:0 10px;background-color:#333;border:none;border-top:none;cursor:pointer;font-family:"Trebuchet MS",Helvetica,Verdana,sans-serif;font-size:16px;-webkit-transition:all .15s;-o-transition:all .15s;transition:all .15s}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit{right:110px;background:#2bc069}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:focus,.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:hover{background:#40d47d;outline:0}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:active{background:#25a259}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset{color:#555;background:#e6e6e6}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:focus,.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:hover{background:#fbfbfb;outline:0}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:active{background:#d4d4d4}.trumbowyg-overlay{position:absolute;background-color:rgba(255,255,255,.5);width:100%;left:0;display:none}.trumbowyg-fullscreen{position:fixed;top:0;left:0;width:100%;height:100%;margin:0;padding:0;z-index:99999}.trumbowyg-fullscreen .trumbowyg-editor,.trumbowyg-fullscreen.trumbowyg-box{border:none}.trumbowyg-fullscreen .trumbowyg-overlay{height:100%!important}.trumbowyg-editor embed,.trumbowyg-editor img,.trumbowyg-editor object,.trumbowyg-editor video{width:auto;max-width:100%}.trumbowyg-editor img,.trumbowyg-editor video{height:auto}.trumbowyg-editor img{cursor:move}.trumbowyg-editor.trumbowyg-reset-css{background:#FEFEFE!important;font-family:"Trebuchet MS",Helvetica,Verdana,sans-serif!important;font-size:14px!important;line-height:1.45em!important;white-space:normal!important;color:#333}.trumbowyg-editor.trumbowyg-reset-css a{color:#15c!important;text-decoration:underline!important}.trumbowyg-editor.trumbowyg-reset-css blockquote,.trumbowyg-editor.trumbowyg-reset-css div,.trumbowyg-editor.trumbowyg-reset-css ol,.trumbowyg-editor.trumbowyg-reset-css p,.trumbowyg-editor.trumbowyg-reset-css ul{-webkit-box-shadow:none!important;box-shadow:none!important;background:none!important;margin:0 0 15px!important;line-height:1.4em!important;font-family:"Trebuchet MS",Helvetica,Verdana,sans-serif!important;font-size:14px!important;border:none}.trumbowyg-editor.trumbowyg-reset-css hr,.trumbowyg-editor.trumbowyg-reset-css iframe,.trumbowyg-editor.trumbowyg-reset-css object{margin-bottom:15px!important}.trumbowyg-editor.trumbowyg-reset-css blockquote{margin-left:32px!important;font-style:italic!important;color:#555}.trumbowyg-editor.trumbowyg-reset-css ol,.trumbowyg-editor.trumbowyg-reset-css ul{padding-left:20px!important}.trumbowyg-editor.trumbowyg-reset-css ol ol,.trumbowyg-editor.trumbowyg-reset-css ol ul,.trumbowyg-editor.trumbowyg-reset-css ul ol,.trumbowyg-editor.trumbowyg-reset-css ul ul{border:none;margin:2px!important;padding:0 0 0 24px!important}.trumbowyg-editor.trumbowyg-reset-css hr{display:block;height:1px;border:none;border-top:1px solid #CCC}.trumbowyg-editor.trumbowyg-reset-css h1,.trumbowyg-editor.trumbowyg-reset-css h2,.trumbowyg-editor.trumbowyg-reset-css h3,.trumbowyg-editor.trumbowyg-reset-css h4{color:#111;background:0 0;margin:0!important;padding:0!important;font-weight:700}.trumbowyg-editor.trumbowyg-reset-css h1{font-size:32px!important;line-height:38px!important;margin-bottom:20px!important}.trumbowyg-editor.trumbowyg-reset-css h2{font-size:26px!important;line-height:34px!important;margin-bottom:15px!important}.trumbowyg-editor.trumbowyg-reset-css h3{font-size:22px!important;line-height:28px!important;margin-bottom:7px!important}.trumbowyg-editor.trumbowyg-reset-css h4{font-size:16px!important;line-height:22px!important;margin-bottom:7px!important}.trumbowyg-button-pane li button{display:block;position:relative;text-indent:-9999px;width:35px;height:35px;overflow:hidden;background:url(./images/icons.png) no-repeat;border:none;cursor:pointer;-webkit-transition:background-color .15s,background-image .15s,opacity .15s;-o-transition:background-color .15s,background-image .15s,opacity .15s;transition:background-color .15s,background-image .15s,opacity .15s}.trumbowyg-button-pane li button.trumbowyg-viewHTML-button{background-position:5px -545px}.trumbowyg-button-pane li button.trumbowyg-formatting-button{background-position:5px -120px}.trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-button-pane li button.trumbowyg-strong-button{background-position:5px -45px}.trumbowyg-button-pane li button.trumbowyg-em-button,.trumbowyg-button-pane li button.trumbowyg-italic-button{background-position:5px 5px}.trumbowyg-button-pane li button.trumbowyg-underline-button{background-position:5px -470px}.trumbowyg-button-pane li button.trumbowyg-del-button,.trumbowyg-button-pane li button.trumbowyg-strikethrough-button{background-position:5px -445px}.trumbowyg-button-pane li button.trumbowyg-link-button{background-position:5px -345px}.trumbowyg-button-pane li button.trumbowyg-insertImage-button{background-position:5px -245px}.trumbowyg-button-pane li button.trumbowyg-justifyLeft-button{background-position:5px -320px}.trumbowyg-button-pane li button.trumbowyg-justifyCenter-button{background-position:5px -70px}.trumbowyg-button-pane li button.trumbowyg-justifyRight-button{background-position:5px -395px}.trumbowyg-button-pane li button.trumbowyg-justifyFull-button{background-position:5px -295px}.trumbowyg-button-pane li button.trumbowyg-unorderedList-button{background-position:5px -495px}.trumbowyg-button-pane li button.trumbowyg-orderedList-button{background-position:5px -370px}.trumbowyg-button-pane li button.trumbowyg-horizontalRule-button{background-position:5px -220px}.trumbowyg-button-pane li button.trumbowyg-fullscreen-button{background-position:5px -170px}.trumbowyg-button-pane li button.trumbowyg-close-button{background-position:5px -95px}.trumbowyg-fullscreen .trumbowyg-button-pane li button.trumbowyg-fullscreen-button{background-position:5px -145px}.trumbowyg-button-pane li:first-child button{margin-left:6px}.trumbowyg-button-pane li:last-child button{margin-right:6px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strong-button{background-position:5px -195px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-underline-button{background-position:5px -420px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-del-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strikethrough-button{background-position:5px -270px}@media only screen and (-webkit-min-device-pixel-ratio:1.3),only screen and (min--moz-device-pixel-ratio:1.3),only screen and (-o-min-device-pixel-ratio:4/3),only screen and (min-device-pixel-ratio:1.3),only screen and (min-resolution:192dpi),only screen and (min-resolution:2dppx){.trumbowyg-button-pane li button{-webkit-background-size:25px 575px!important;background-size:25px 575px!important;background-image:url(./images/icons-2x.png)!important}.trumbowyg-button-pane li button.trumbowyg-viewHTML-button{background-position:5px -545px}.trumbowyg-button-pane li button.trumbowyg-formatting-button{background-position:5px -120px}.trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-button-pane li button.trumbowyg-strong-button{background-position:5px -45px}.trumbowyg-button-pane li button.trumbowyg-em-button,.trumbowyg-button-pane li button.trumbowyg-italic-button{background-position:5px 5px}.trumbowyg-button-pane li button.trumbowyg-underline-button{background-position:5px -470px}.trumbowyg-button-pane li button.trumbowyg-del-button,.trumbowyg-button-pane li button.trumbowyg-strikethrough-button{background-position:5px -445px}.trumbowyg-button-pane li button.trumbowyg-link-button{background-position:5px -345px}.trumbowyg-button-pane li button.trumbowyg-insertImage-button{background-position:5px -245px}.trumbowyg-button-pane li button.trumbowyg-justifyLeft-button{background-position:5px -320px}.trumbowyg-button-pane li button.trumbowyg-justifyCenter-button{background-position:5px -70px}.trumbowyg-button-pane li button.trumbowyg-justifyRight-button{background-position:5px -395px}.trumbowyg-button-pane li button.trumbowyg-justifyFull-button{background-position:5px -295px}.trumbowyg-button-pane li button.trumbowyg-unorderedList-button{background-position:5px -495px}.trumbowyg-button-pane li button.trumbowyg-orderedList-button{background-position:5px -370px}.trumbowyg-button-pane li button.trumbowyg-horizontalRule-button{background-position:5px -220px}.trumbowyg-button-pane li button.trumbowyg-fullscreen-button{background-position:5px -170px}.trumbowyg-button-pane li button.trumbowyg-close-button{background-position:5px -95px}.trumbowyg-fullscreen .trumbowyg-button-pane li a.trumbowyg-fullscreen-button{background-position:5px -145px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strong-button{background-position:5px -195px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-underline-button{background-position:5px -420px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-del-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strikethrough-button{background-position:5px -270px}}
\ No newline at end of file