From 7adcb81e4f83f98c468889aaa5a85558ba88c770 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= ' +
+ 'CKEditor ' + CKEDITOR.version + ' (revision ' + CKEDITOR.revision + ') ' +
+ lang.help.replace( '$1', '' + lang.userGuide + '' ) +
+ ' ' +
+ lang.moreInfo + ' ' +
+ lang.copy.replace( '$1', 'CKSource - Frederico Knabben' ) +
+ '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Content content content. Styled by Test internal D&D in the editor, dropping content from an external source (helpers, MS Word) and D&D between editors. Keep in mind that internal D&D is the most complex operation because editor have to handle two ranges at the same time. Apollo 11 was the spaceflight that landed the first humans, Americans Neil Armstrong and Buzz Aldrin, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC. Armstrong spent about Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as: One small step for [a] man, one giant leap for mankind. Apollo 11 effectively ended the Space Race and fulfilled a national goal proposed in 1961 by the late U.S. President John F. Kennedy in a speech before the United States Congress: [...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth. Launched by a Saturn V rocket from Kennedy Space Center in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of NASA's Apollo program. The Apollo spacecraft had three parts: After being sent to the Moon by the Saturn V's upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the Sea of Tranquility. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the Pacific Ocean on July 24. Source: Wikipedia.org -> (br.cke-pasted-remove will be removed later)
+ data = data.replace( /^ (?: |\r\n)?<(\w+)/g, function( match, elementName ) {
+ if ( elementName.toLowerCase() in blockElements ) {
+ evt.data.preSniffing = 'html'; // Mark as not a text.
+ return '<' + elementName;
+ }
+ return match;
+ } );
+ } else if ( CKEDITOR.env.webkit ) {
+ // %1
%2
',
+ itemTpl = '
' +
+ 'http://ckeditor.com' +
+ '
' +
+ 'http://ckeditor.com/about/license' +
+ '
保留所有权利。',
+ dlgTitle: '关于 CKEditor',
+ help: '访问 $1 以获取帮助。',
+ moreInfo: '相关授权许可信息请访问我们的网站:',
+ title: '关于 CKEditor',
+ userGuide: 'CKEditor 用户向导'
+} );
diff --git a/sources/plugins/about/lang/zh.js b/sources/plugins/about/lang/zh.js
new file mode 100644
index 00000000..955546d9
--- /dev/null
+++ b/sources/plugins/about/lang/zh.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'about', 'zh', {
+ copy: 'Copyright © $1. All rights reserved.',
+ dlgTitle: '關於 CKEditor',
+ help: '檢閱 $1 尋求幫助。',
+ moreInfo: '關於授權資訊,請參閱我們的網站:',
+ title: '關於 CKEditor',
+ userGuide: 'CKEditor 使用者手冊'
+} );
diff --git a/sources/plugins/about/plugin.js b/sources/plugins/about/plugin.js
new file mode 100644
index 00000000..09dd4bc7
--- /dev/null
+++ b/sources/plugins/about/plugin.js
@@ -0,0 +1,27 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.add( 'about', {
+ requires: 'dialog',
+ // jscs:disable maximumLineLength
+ lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
+ // jscs:enable maximumLineLength
+ icons: 'about', // %REMOVE_LINE_CORE%
+ hidpi: true, // %REMOVE_LINE_CORE%
+ init: function( editor ) {
+ var command = editor.addCommand( 'about', new CKEDITOR.dialogCommand( 'about' ) );
+ command.modes = { wysiwyg: 1, source: 1 };
+ command.canUndo = false;
+ command.readOnly = 1;
+
+ editor.ui.addButton && editor.ui.addButton( 'About', {
+ label: editor.lang.about.title,
+ command: 'about',
+ toolbar: 'about'
+ } );
+
+ CKEDITOR.dialog.add( 'about', this.path + 'dialogs/about.js' );
+ }
+} );
diff --git a/sources/plugins/basicstyles/icons/bold.png b/sources/plugins/basicstyles/icons/bold.png
new file mode 100644
index 00000000..5ff84fec
Binary files /dev/null and b/sources/plugins/basicstyles/icons/bold.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/bold.png b/sources/plugins/basicstyles/icons/hidpi/bold.png
new file mode 100644
index 00000000..65acb293
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/bold.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/italic.png b/sources/plugins/basicstyles/icons/hidpi/italic.png
new file mode 100644
index 00000000..2b0f44e7
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/italic.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/strike.png b/sources/plugins/basicstyles/icons/hidpi/strike.png
new file mode 100644
index 00000000..ef045c84
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/strike.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/subscript.png b/sources/plugins/basicstyles/icons/hidpi/subscript.png
new file mode 100644
index 00000000..f12f4be2
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/subscript.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/superscript.png b/sources/plugins/basicstyles/icons/hidpi/superscript.png
new file mode 100644
index 00000000..4f7b762f
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/superscript.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/underline.png b/sources/plugins/basicstyles/icons/hidpi/underline.png
new file mode 100644
index 00000000..79702f69
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/underline.png differ
diff --git a/sources/plugins/basicstyles/icons/italic.png b/sources/plugins/basicstyles/icons/italic.png
new file mode 100644
index 00000000..64d1332c
Binary files /dev/null and b/sources/plugins/basicstyles/icons/italic.png differ
diff --git a/sources/plugins/basicstyles/icons/strike.png b/sources/plugins/basicstyles/icons/strike.png
new file mode 100644
index 00000000..31ea47a1
Binary files /dev/null and b/sources/plugins/basicstyles/icons/strike.png differ
diff --git a/sources/plugins/basicstyles/icons/subscript.png b/sources/plugins/basicstyles/icons/subscript.png
new file mode 100644
index 00000000..bfe5420e
Binary files /dev/null and b/sources/plugins/basicstyles/icons/subscript.png differ
diff --git a/sources/plugins/basicstyles/icons/superscript.png b/sources/plugins/basicstyles/icons/superscript.png
new file mode 100644
index 00000000..a1eb2f1e
Binary files /dev/null and b/sources/plugins/basicstyles/icons/superscript.png differ
diff --git a/sources/plugins/basicstyles/icons/underline.png b/sources/plugins/basicstyles/icons/underline.png
new file mode 100644
index 00000000..1dd0c593
Binary files /dev/null and b/sources/plugins/basicstyles/icons/underline.png differ
diff --git a/sources/plugins/basicstyles/lang/af.js b/sources/plugins/basicstyles/lang/af.js
new file mode 100644
index 00000000..bc781641
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/af.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'af', {
+ bold: 'Vet',
+ italic: 'Skuins',
+ strike: 'Deurgestreep',
+ subscript: 'Onderskrif',
+ superscript: 'Bo-skrif',
+ underline: 'Onderstreep'
+} );
diff --git a/sources/plugins/basicstyles/lang/ar.js b/sources/plugins/basicstyles/lang/ar.js
new file mode 100644
index 00000000..cb975e34
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/ar.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'ar', {
+ bold: 'عريض',
+ italic: 'مائل',
+ strike: 'يتوسطه خط',
+ subscript: 'منخفض',
+ superscript: 'مرتفع',
+ underline: 'تسطير'
+} );
diff --git a/sources/plugins/basicstyles/lang/bg.js b/sources/plugins/basicstyles/lang/bg.js
new file mode 100644
index 00000000..da72e4a5
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/bg.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'bg', {
+ bold: 'Удебелен',
+ italic: 'Наклонен',
+ strike: 'Зачертан текст',
+ subscript: 'Индексиран текст',
+ superscript: 'Суперскрипт',
+ underline: 'Подчертан'
+} );
diff --git a/sources/plugins/basicstyles/lang/bn.js b/sources/plugins/basicstyles/lang/bn.js
new file mode 100644
index 00000000..85992c3b
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/bn.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'bn', {
+ bold: 'বোল্ড',
+ italic: 'ইটালিক',
+ strike: 'স্ট্রাইক থ্রু',
+ subscript: 'অধোলেখ',
+ superscript: 'অভিলেখ',
+ underline: 'আন্ডারলাইন'
+} );
diff --git a/sources/plugins/basicstyles/lang/bs.js b/sources/plugins/basicstyles/lang/bs.js
new file mode 100644
index 00000000..5e1c7f24
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/bs.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'bs', {
+ bold: 'Boldiraj',
+ italic: 'Ukosi',
+ strike: 'Precrtaj',
+ subscript: 'Subscript',
+ superscript: 'Superscript',
+ underline: 'Podvuci'
+} );
diff --git a/sources/plugins/basicstyles/lang/ca.js b/sources/plugins/basicstyles/lang/ca.js
new file mode 100644
index 00000000..3c81cc11
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/ca.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'ca', {
+ bold: 'Negreta',
+ italic: 'Cursiva',
+ strike: 'Ratllat',
+ subscript: 'Subíndex',
+ superscript: 'Superíndex',
+ underline: 'Subratllat'
+} );
diff --git a/sources/plugins/basicstyles/lang/cs.js b/sources/plugins/basicstyles/lang/cs.js
new file mode 100644
index 00000000..73b1267c
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/cs.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'cs', {
+ bold: 'Tučné',
+ italic: 'Kurzíva',
+ strike: 'Přeškrtnuté',
+ subscript: 'Dolní index',
+ superscript: 'Horní index',
+ underline: 'Podtržené'
+} );
diff --git a/sources/plugins/basicstyles/lang/cy.js b/sources/plugins/basicstyles/lang/cy.js
new file mode 100644
index 00000000..e0ac3af3
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/cy.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'cy', {
+ bold: 'Bras',
+ italic: 'Italig',
+ strike: 'Llinell Trwyddo',
+ subscript: 'Is-sgript',
+ superscript: 'Uwchsgript',
+ underline: 'Tanlinellu'
+} );
diff --git a/sources/plugins/basicstyles/lang/da.js b/sources/plugins/basicstyles/lang/da.js
new file mode 100644
index 00000000..e9721830
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/da.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'da', {
+ bold: 'Fed',
+ italic: 'Kursiv',
+ strike: 'Gennemstreget',
+ subscript: 'Sænket skrift',
+ superscript: 'Hævet skrift',
+ underline: 'Understreget'
+} );
diff --git a/sources/plugins/basicstyles/lang/de.js b/sources/plugins/basicstyles/lang/de.js
new file mode 100644
index 00000000..c86554d7
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/de.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'de', {
+ bold: 'Fett',
+ italic: 'Kursiv',
+ strike: 'Durchgestrichen',
+ subscript: 'Tiefgestellt',
+ superscript: 'Hochgestellt',
+ underline: 'Unterstrichen'
+} );
diff --git a/sources/plugins/basicstyles/lang/el.js b/sources/plugins/basicstyles/lang/el.js
new file mode 100644
index 00000000..8cc2faec
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/el.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'el', {
+ bold: 'Έντονη',
+ italic: 'Πλάγια',
+ strike: 'Διακριτή Διαγραφή',
+ subscript: 'Δείκτης',
+ superscript: 'Εκθέτης',
+ underline: 'Υπογράμμιση'
+} );
diff --git a/sources/plugins/basicstyles/lang/en-au.js b/sources/plugins/basicstyles/lang/en-au.js
new file mode 100644
index 00000000..a989ed0f
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/en-au.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'en-au', {
+ bold: 'Bold',
+ italic: 'Italic',
+ strike: 'Strike Through',
+ subscript: 'Subscript',
+ superscript: 'Superscript',
+ underline: 'Underline'
+} );
diff --git a/sources/plugins/basicstyles/lang/en-ca.js b/sources/plugins/basicstyles/lang/en-ca.js
new file mode 100644
index 00000000..ae09008b
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/en-ca.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'en-ca', {
+ bold: 'Bold',
+ italic: 'Italic',
+ strike: 'Strike Through',
+ subscript: 'Subscript',
+ superscript: 'Superscript',
+ underline: 'Underline'
+} );
diff --git a/sources/plugins/basicstyles/lang/en-gb.js b/sources/plugins/basicstyles/lang/en-gb.js
new file mode 100644
index 00000000..c3df8993
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/en-gb.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'en-gb', {
+ bold: 'Bold',
+ italic: 'Italic',
+ strike: 'Strike Through',
+ subscript: 'Subscript',
+ superscript: 'Superscript',
+ underline: 'Underline'
+} );
diff --git a/sources/plugins/basicstyles/lang/en.js b/sources/plugins/basicstyles/lang/en.js
new file mode 100644
index 00000000..1ccbfb88
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/en.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'en', {
+ bold: 'Bold',
+ italic: 'Italic',
+ strike: 'Strikethrough',
+ subscript: 'Subscript',
+ superscript: 'Superscript',
+ underline: 'Underline'
+} );
diff --git a/sources/plugins/basicstyles/lang/eo.js b/sources/plugins/basicstyles/lang/eo.js
new file mode 100644
index 00000000..41b8570d
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/eo.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'eo', {
+ bold: 'Grasa',
+ italic: 'Kursiva',
+ strike: 'Trastreko',
+ subscript: 'Suba indico',
+ superscript: 'Supra indico',
+ underline: 'Substreko'
+} );
diff --git a/sources/plugins/basicstyles/lang/es.js b/sources/plugins/basicstyles/lang/es.js
new file mode 100644
index 00000000..196f1d04
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/es.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'es', {
+ bold: 'Negrita',
+ italic: 'Cursiva',
+ strike: 'Tachado',
+ subscript: 'Subíndice',
+ superscript: 'Superíndice',
+ underline: 'Subrayado'
+} );
diff --git a/sources/plugins/basicstyles/lang/et.js b/sources/plugins/basicstyles/lang/et.js
new file mode 100644
index 00000000..9cd8c7a0
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/et.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'et', {
+ bold: 'Paks',
+ italic: 'Kursiiv',
+ strike: 'Läbijoonitud',
+ subscript: 'Allindeks',
+ superscript: 'Ülaindeks',
+ underline: 'Allajoonitud'
+} );
diff --git a/sources/plugins/basicstyles/lang/eu.js b/sources/plugins/basicstyles/lang/eu.js
new file mode 100644
index 00000000..84a2d4e2
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/eu.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'eu', {
+ bold: 'Lodia',
+ italic: 'Etzana',
+ strike: 'Marratua',
+ subscript: 'Azpi-indizea',
+ superscript: 'Goi-indizea',
+ underline: 'Azpimarratu'
+} );
diff --git a/sources/plugins/basicstyles/lang/fa.js b/sources/plugins/basicstyles/lang/fa.js
new file mode 100644
index 00000000..8cea19a5
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/fa.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'fa', {
+ bold: 'درشت',
+ italic: 'خمیده',
+ strike: 'خطخورده',
+ subscript: 'زیرنویس',
+ superscript: 'بالانویس',
+ underline: 'زیرخطدار'
+} );
diff --git a/sources/plugins/basicstyles/lang/fi.js b/sources/plugins/basicstyles/lang/fi.js
new file mode 100644
index 00000000..b011b41f
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/fi.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'fi', {
+ bold: 'Lihavoitu',
+ italic: 'Kursivoitu',
+ strike: 'Yliviivattu',
+ subscript: 'Alaindeksi',
+ superscript: 'Yläindeksi',
+ underline: 'Alleviivattu'
+} );
diff --git a/sources/plugins/basicstyles/lang/fo.js b/sources/plugins/basicstyles/lang/fo.js
new file mode 100644
index 00000000..7d293076
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/fo.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'fo', {
+ bold: 'Feit skrift',
+ italic: 'Skráskrift',
+ strike: 'Yvirstrikað',
+ subscript: 'Lækkað skrift',
+ superscript: 'Hækkað skrift',
+ underline: 'Undirstrikað'
+} );
diff --git a/sources/plugins/basicstyles/lang/fr-ca.js b/sources/plugins/basicstyles/lang/fr-ca.js
new file mode 100644
index 00000000..3f82c9af
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/fr-ca.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'fr-ca', {
+ bold: 'Gras',
+ italic: 'Italique',
+ strike: 'Barré',
+ subscript: 'Indice',
+ superscript: 'Exposant',
+ underline: 'Souligné'
+} );
diff --git a/sources/plugins/basicstyles/lang/fr.js b/sources/plugins/basicstyles/lang/fr.js
new file mode 100644
index 00000000..44349e34
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/fr.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'fr', {
+ bold: 'Gras',
+ italic: 'Italique',
+ strike: 'Barré',
+ subscript: 'Indice',
+ superscript: 'Exposant',
+ underline: 'Souligné'
+} );
diff --git a/sources/plugins/basicstyles/lang/gl.js b/sources/plugins/basicstyles/lang/gl.js
new file mode 100644
index 00000000..7e7379a2
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/gl.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'gl', {
+ bold: 'Negra',
+ italic: 'Cursiva',
+ strike: 'Riscado',
+ subscript: 'Subíndice',
+ superscript: 'Superíndice',
+ underline: 'Subliñado'
+} );
diff --git a/sources/plugins/basicstyles/lang/gu.js b/sources/plugins/basicstyles/lang/gu.js
new file mode 100644
index 00000000..90619039
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/gu.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'gu', {
+ bold: 'બોલ્ડ/સ્પષ્ટ',
+ italic: 'ઇટેલિક, ત્રાંસા',
+ strike: 'છેકી નાખવું',
+ subscript: 'એક ચિહ્નની નીચે કરેલું બીજું ચિહ્ન',
+ superscript: 'એક ચિહ્ન ઉપર કરેલું બીજું ચિહ્ન.',
+ underline: 'અન્ડર્લાઇન, નીચે લીટી'
+} );
diff --git a/sources/plugins/basicstyles/lang/he.js b/sources/plugins/basicstyles/lang/he.js
new file mode 100644
index 00000000..e5279b6e
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/he.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'he', {
+ bold: 'מודגש',
+ italic: 'נטוי',
+ strike: 'כתיב מחוק',
+ subscript: 'כתיב תחתון',
+ superscript: 'כתיב עליון',
+ underline: 'קו תחתון'
+} );
diff --git a/sources/plugins/basicstyles/lang/hi.js b/sources/plugins/basicstyles/lang/hi.js
new file mode 100644
index 00000000..daacb67d
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/hi.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'hi', {
+ bold: 'बोल्ड',
+ italic: 'इटैलिक',
+ strike: 'स्ट्राइक थ्रू',
+ subscript: 'अधोलेख',
+ superscript: 'अभिलेख',
+ underline: 'रेखांकण'
+} );
diff --git a/sources/plugins/basicstyles/lang/hr.js b/sources/plugins/basicstyles/lang/hr.js
new file mode 100644
index 00000000..d3f16468
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/hr.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'hr', {
+ bold: 'Podebljaj',
+ italic: 'Ukosi',
+ strike: 'Precrtano',
+ subscript: 'Subscript',
+ superscript: 'Superscript',
+ underline: 'Potcrtano'
+} );
diff --git a/sources/plugins/basicstyles/lang/hu.js b/sources/plugins/basicstyles/lang/hu.js
new file mode 100644
index 00000000..9d18d3b4
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/hu.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'hu', {
+ bold: 'Félkövér',
+ italic: 'Dőlt',
+ strike: 'Áthúzott',
+ subscript: 'Alsó index',
+ superscript: 'Felső index',
+ underline: 'Aláhúzott'
+} );
diff --git a/sources/plugins/basicstyles/lang/id.js b/sources/plugins/basicstyles/lang/id.js
new file mode 100644
index 00000000..146b1a78
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/id.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'id', {
+ bold: 'Huruf Tebal',
+ italic: 'Huruf Miring',
+ strike: 'Strikethrough', // MISSING
+ subscript: 'Subscript', // MISSING
+ superscript: 'Superscript', // MISSING
+ underline: 'Garis Bawah'
+} );
diff --git a/sources/plugins/basicstyles/lang/is.js b/sources/plugins/basicstyles/lang/is.js
new file mode 100644
index 00000000..ccef9cd3
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/is.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'is', {
+ bold: 'Feitletrað',
+ italic: 'Skáletrað',
+ strike: 'Yfirstrikað',
+ subscript: 'Niðurskrifað',
+ superscript: 'Uppskrifað',
+ underline: 'Undirstrikað'
+} );
diff --git a/sources/plugins/basicstyles/lang/it.js b/sources/plugins/basicstyles/lang/it.js
new file mode 100644
index 00000000..d3f02488
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/it.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'it', {
+ bold: 'Grassetto',
+ italic: 'Corsivo',
+ strike: 'Barrato',
+ subscript: 'Pedice',
+ superscript: 'Apice',
+ underline: 'Sottolineato'
+} );
diff --git a/sources/plugins/basicstyles/lang/ja.js b/sources/plugins/basicstyles/lang/ja.js
new file mode 100644
index 00000000..38c0a0a4
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/ja.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'ja', {
+ bold: '太字',
+ italic: '斜体',
+ strike: '打ち消し線',
+ subscript: '下付き',
+ superscript: '上付き',
+ underline: '下線'
+} );
diff --git a/sources/plugins/basicstyles/lang/ka.js b/sources/plugins/basicstyles/lang/ka.js
new file mode 100644
index 00000000..70c1bc38
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/ka.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'ka', {
+ bold: 'მსხვილი',
+ italic: 'დახრილი',
+ strike: 'გადახაზული',
+ subscript: 'ინდექსი',
+ superscript: 'ხარისხი',
+ underline: 'გახაზული'
+} );
diff --git a/sources/plugins/basicstyles/lang/km.js b/sources/plugins/basicstyles/lang/km.js
new file mode 100644
index 00000000..29d87369
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/km.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'km', {
+ bold: 'ដិត',
+ italic: 'ទ្រេត',
+ strike: 'គូសបន្ទាត់ចំកណ្ដាល',
+ subscript: 'អក្សរតូចក្រោម',
+ superscript: 'អក្សរតូចលើ',
+ underline: 'គូសបន្ទាត់ក្រោម'
+} );
diff --git a/sources/plugins/basicstyles/lang/ko.js b/sources/plugins/basicstyles/lang/ko.js
new file mode 100644
index 00000000..53c2be18
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/ko.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'ko', {
+ bold: '굵게',
+ italic: '기울임꼴',
+ strike: '취소선',
+ subscript: '아래 첨자',
+ superscript: '위 첨자',
+ underline: '밑줄'
+} );
diff --git a/sources/plugins/basicstyles/lang/ku.js b/sources/plugins/basicstyles/lang/ku.js
new file mode 100644
index 00000000..6dc67666
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/ku.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'ku', {
+ bold: 'قەڵەو',
+ italic: 'لار',
+ strike: 'لێدان',
+ subscript: 'ژێرنووس',
+ superscript: 'سەرنووس',
+ underline: 'ژێرهێڵ'
+} );
diff --git a/sources/plugins/basicstyles/lang/lt.js b/sources/plugins/basicstyles/lang/lt.js
new file mode 100644
index 00000000..c42a74aa
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/lt.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'lt', {
+ bold: 'Pusjuodis',
+ italic: 'Kursyvas',
+ strike: 'Perbrauktas',
+ subscript: 'Apatinis indeksas',
+ superscript: 'Viršutinis indeksas',
+ underline: 'Pabrauktas'
+} );
diff --git a/sources/plugins/basicstyles/lang/lv.js b/sources/plugins/basicstyles/lang/lv.js
new file mode 100644
index 00000000..227953ae
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/lv.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'lv', {
+ bold: 'Treknināts',
+ italic: 'Kursīvs',
+ strike: 'Pārsvītrots',
+ subscript: 'Apakšrakstā',
+ superscript: 'Augšrakstā',
+ underline: 'Pasvītrots'
+} );
diff --git a/sources/plugins/basicstyles/lang/mk.js b/sources/plugins/basicstyles/lang/mk.js
new file mode 100644
index 00000000..a70ec268
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/mk.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'mk', {
+ bold: 'Bold', // MISSING
+ italic: 'Italic', // MISSING
+ strike: 'Strikethrough', // MISSING
+ subscript: 'Subscript', // MISSING
+ superscript: 'Superscript', // MISSING
+ underline: 'Underline' // MISSING
+} );
diff --git a/sources/plugins/basicstyles/lang/mn.js b/sources/plugins/basicstyles/lang/mn.js
new file mode 100644
index 00000000..262cf104
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/mn.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'mn', {
+ bold: 'Тод бүдүүн',
+ italic: 'Налуу',
+ strike: 'Дундуур нь зураастай болгох',
+ subscript: 'Суурь болгох',
+ superscript: 'Зэрэг болгох',
+ underline: 'Доогуур нь зураастай болгох'
+} );
diff --git a/sources/plugins/basicstyles/lang/ms.js b/sources/plugins/basicstyles/lang/ms.js
new file mode 100644
index 00000000..114b8e55
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/ms.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'ms', {
+ bold: 'Bold',
+ italic: 'Italic',
+ strike: 'Strike Through',
+ subscript: 'Subscript',
+ superscript: 'Superscript',
+ underline: 'Underline'
+} );
diff --git a/sources/plugins/basicstyles/lang/nb.js b/sources/plugins/basicstyles/lang/nb.js
new file mode 100644
index 00000000..460de348
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/nb.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'nb', {
+ bold: 'Fet',
+ italic: 'Kursiv',
+ strike: 'Gjennomstreking',
+ subscript: 'Senket skrift',
+ superscript: 'Hevet skrift',
+ underline: 'Understreking'
+} );
diff --git a/sources/plugins/basicstyles/lang/nl.js b/sources/plugins/basicstyles/lang/nl.js
new file mode 100644
index 00000000..43a6aa69
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/nl.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'nl', {
+ bold: 'Vet',
+ italic: 'Cursief',
+ strike: 'Doorhalen',
+ subscript: 'Subscript',
+ superscript: 'Superscript',
+ underline: 'Onderstrepen'
+} );
diff --git a/sources/plugins/basicstyles/lang/no.js b/sources/plugins/basicstyles/lang/no.js
new file mode 100644
index 00000000..753d90a3
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/no.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'no', {
+ bold: 'Fet',
+ italic: 'Kursiv',
+ strike: 'Gjennomstreking',
+ subscript: 'Senket skrift',
+ superscript: 'Hevet skrift',
+ underline: 'Understreking'
+} );
diff --git a/sources/plugins/basicstyles/lang/pl.js b/sources/plugins/basicstyles/lang/pl.js
new file mode 100644
index 00000000..256630d5
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/pl.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'pl', {
+ bold: 'Pogrubienie',
+ italic: 'Kursywa',
+ strike: 'Przekreślenie',
+ subscript: 'Indeks dolny',
+ superscript: 'Indeks górny',
+ underline: 'Podkreślenie'
+} );
diff --git a/sources/plugins/basicstyles/lang/pt-br.js b/sources/plugins/basicstyles/lang/pt-br.js
new file mode 100644
index 00000000..655c5971
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/pt-br.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'pt-br', {
+ bold: 'Negrito',
+ italic: 'Itálico',
+ strike: 'Tachado',
+ subscript: 'Subscrito',
+ superscript: 'Sobrescrito',
+ underline: 'Sublinhado'
+} );
diff --git a/sources/plugins/basicstyles/lang/pt.js b/sources/plugins/basicstyles/lang/pt.js
new file mode 100644
index 00000000..c25ceb2e
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/pt.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'pt', {
+ bold: 'Negrito',
+ italic: 'Itálico',
+ strike: 'Rasurado',
+ subscript: 'Superior à linha',
+ superscript: 'Inferior à Linha',
+ underline: 'Sublinhado'
+} );
diff --git a/sources/plugins/basicstyles/lang/ro.js b/sources/plugins/basicstyles/lang/ro.js
new file mode 100644
index 00000000..59c2483d
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/ro.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'ro', {
+ bold: 'Îngroşat (bold)',
+ italic: 'Înclinat (italic)',
+ strike: 'Tăiat (strike through)',
+ subscript: 'Indice (subscript)',
+ superscript: 'Putere (superscript)',
+ underline: 'Subliniat (underline)'
+} );
diff --git a/sources/plugins/basicstyles/lang/ru.js b/sources/plugins/basicstyles/lang/ru.js
new file mode 100644
index 00000000..f87bea18
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/ru.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'ru', {
+ bold: 'Полужирный',
+ italic: 'Курсив',
+ strike: 'Зачеркнутый',
+ subscript: 'Подстрочный индекс',
+ superscript: 'Надстрочный индекс',
+ underline: 'Подчеркнутый'
+} );
diff --git a/sources/plugins/basicstyles/lang/si.js b/sources/plugins/basicstyles/lang/si.js
new file mode 100644
index 00000000..8f7db5da
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/si.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'si', {
+ bold: 'තද අකුරින් ලියනලද',
+ italic: 'බැධීඅකුරින් ලියන ලද',
+ strike: 'Strikethrough', // MISSING
+ subscript: 'Subscript', // MISSING
+ superscript: 'Superscript', // MISSING
+ underline: 'යටින් ඉරි අදින ලද'
+} );
diff --git a/sources/plugins/basicstyles/lang/sk.js b/sources/plugins/basicstyles/lang/sk.js
new file mode 100644
index 00000000..5d038c6d
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/sk.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'sk', {
+ bold: 'Tučné',
+ italic: 'Kurzíva',
+ strike: 'Prečiarknuté',
+ subscript: 'Dolný index',
+ superscript: 'Horný index',
+ underline: 'Podčiarknuté'
+} );
diff --git a/sources/plugins/basicstyles/lang/sl.js b/sources/plugins/basicstyles/lang/sl.js
new file mode 100644
index 00000000..1397a700
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/sl.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'sl', {
+ bold: 'Krepko',
+ italic: 'Ležeče',
+ strike: 'Prečrtano',
+ subscript: 'Podpisano',
+ superscript: 'Nadpisano',
+ underline: 'Podčrtano'
+} );
diff --git a/sources/plugins/basicstyles/lang/sq.js b/sources/plugins/basicstyles/lang/sq.js
new file mode 100644
index 00000000..82242b26
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/sq.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'sq', {
+ bold: 'Trash',
+ italic: 'Pjerrët',
+ strike: 'Nëpërmes',
+ subscript: 'Nën-skriptë',
+ superscript: 'Super-skriptë',
+ underline: 'Nënvijëzuar'
+} );
diff --git a/sources/plugins/basicstyles/lang/sr-latn.js b/sources/plugins/basicstyles/lang/sr-latn.js
new file mode 100644
index 00000000..62f51edd
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/sr-latn.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'sr-latn', {
+ bold: 'Podebljano',
+ italic: 'Kurziv',
+ strike: 'Precrtano',
+ subscript: 'Indeks',
+ superscript: 'Stepen',
+ underline: 'Podvučeno'
+} );
diff --git a/sources/plugins/basicstyles/lang/sr.js b/sources/plugins/basicstyles/lang/sr.js
new file mode 100644
index 00000000..59e6105b
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/sr.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'sr', {
+ bold: 'Подебљано',
+ italic: 'Курзив',
+ strike: 'Прецртано',
+ subscript: 'Индекс',
+ superscript: 'Степен',
+ underline: 'Подвучено'
+} );
diff --git a/sources/plugins/basicstyles/lang/sv.js b/sources/plugins/basicstyles/lang/sv.js
new file mode 100644
index 00000000..afcbf3ff
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/sv.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'sv', {
+ bold: 'Fet',
+ italic: 'Kursiv',
+ strike: 'Genomstruken',
+ subscript: 'Nedsänkta tecken',
+ superscript: 'Upphöjda tecken',
+ underline: 'Understruken'
+} );
diff --git a/sources/plugins/basicstyles/lang/th.js b/sources/plugins/basicstyles/lang/th.js
new file mode 100644
index 00000000..61700f54
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/th.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'th', {
+ bold: 'ตัวหนา',
+ italic: 'ตัวเอียง',
+ strike: 'ตัวขีดเส้นทับ',
+ subscript: 'ตัวห้อย',
+ superscript: 'ตัวยก',
+ underline: 'ตัวขีดเส้นใต้'
+} );
diff --git a/sources/plugins/basicstyles/lang/tr.js b/sources/plugins/basicstyles/lang/tr.js
new file mode 100644
index 00000000..0e226b89
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/tr.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'tr', {
+ bold: 'Kalın',
+ italic: 'İtalik',
+ strike: 'Üstü Çizgili',
+ subscript: 'Alt Simge',
+ superscript: 'Üst Simge',
+ underline: 'Altı Çizgili'
+} );
diff --git a/sources/plugins/basicstyles/lang/tt.js b/sources/plugins/basicstyles/lang/tt.js
new file mode 100644
index 00000000..6c4eb03f
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/tt.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'tt', {
+ bold: 'Калын',
+ italic: 'Курсив',
+ strike: 'Сызылган',
+ subscript: 'Аскы индекс',
+ superscript: 'Өске индекс',
+ underline: 'Астына сызылган'
+} );
diff --git a/sources/plugins/basicstyles/lang/ug.js b/sources/plugins/basicstyles/lang/ug.js
new file mode 100644
index 00000000..10d42cdd
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/ug.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'ug', {
+ bold: 'توم',
+ italic: 'يانتۇ',
+ strike: 'ئۆچۈرۈش سىزىقى',
+ subscript: 'تۆۋەن ئىندېكس',
+ superscript: 'يۇقىرى ئىندېكس',
+ underline: 'ئاستى سىزىق'
+} );
diff --git a/sources/plugins/basicstyles/lang/uk.js b/sources/plugins/basicstyles/lang/uk.js
new file mode 100644
index 00000000..7d5d84d9
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/uk.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'uk', {
+ bold: 'Жирний',
+ italic: 'Курсив',
+ strike: 'Закреслений',
+ subscript: 'Нижній індекс',
+ superscript: 'Верхній індекс',
+ underline: 'Підкреслений'
+} );
diff --git a/sources/plugins/basicstyles/lang/vi.js b/sources/plugins/basicstyles/lang/vi.js
new file mode 100644
index 00000000..cc1dfaac
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/vi.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'vi', {
+ bold: 'Đậm',
+ italic: 'Nghiêng',
+ strike: 'Gạch xuyên ngang',
+ subscript: 'Chỉ số dưới',
+ superscript: 'Chỉ số trên',
+ underline: 'Gạch chân'
+} );
diff --git a/sources/plugins/basicstyles/lang/zh-cn.js b/sources/plugins/basicstyles/lang/zh-cn.js
new file mode 100644
index 00000000..538c36d2
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/zh-cn.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'zh-cn', {
+ bold: '加粗',
+ italic: '倾斜',
+ strike: '删除线',
+ subscript: '下标',
+ superscript: '上标',
+ underline: '下划线'
+} );
diff --git a/sources/plugins/basicstyles/lang/zh.js b/sources/plugins/basicstyles/lang/zh.js
new file mode 100644
index 00000000..c73c4d3f
--- /dev/null
+++ b/sources/plugins/basicstyles/lang/zh.js
@@ -0,0 +1,12 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'basicstyles', 'zh', {
+ bold: '粗體',
+ italic: '斜體',
+ strike: '刪除線',
+ subscript: '下標',
+ superscript: '上標',
+ underline: '底線'
+} );
diff --git a/sources/plugins/basicstyles/plugin.js b/sources/plugins/basicstyles/plugin.js
new file mode 100644
index 00000000..3fa96373
--- /dev/null
+++ b/sources/plugins/basicstyles/plugin.js
@@ -0,0 +1,209 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.add( 'basicstyles', {
+ // jscs:disable maximumLineLength
+ lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
+ // jscs:enable maximumLineLength
+ icons: 'bold,italic,underline,strike,subscript,superscript', // %REMOVE_LINE_CORE%
+ hidpi: true, // %REMOVE_LINE_CORE%
+ init: function( editor ) {
+ var order = 0;
+ // All buttons use the same code to register. So, to avoid
+ // duplications, let's use this tool function.
+ var addButtonCommand = function( buttonName, buttonLabel, commandName, styleDefiniton ) {
+ // Disable the command if no definition is configured.
+ if ( !styleDefiniton )
+ return;
+
+ var style = new CKEDITOR.style( styleDefiniton ),
+ forms = contentForms[ commandName ];
+
+ // Put the style as the most important form.
+ forms.unshift( style );
+
+ // Listen to contextual style activation.
+ editor.attachStyleStateChange( style, function( state ) {
+ !editor.readOnly && editor.getCommand( commandName ).setState( state );
+ } );
+
+ // Create the command that can be used to apply the style.
+ editor.addCommand( commandName, new CKEDITOR.styleCommand( style, {
+ contentForms: forms
+ } ) );
+
+ // Register the button, if the button plugin is loaded.
+ if ( editor.ui.addButton ) {
+ editor.ui.addButton( buttonName, {
+ label: buttonLabel,
+ command: commandName,
+ toolbar: 'basicstyles,' + ( order += 10 )
+ } );
+ }
+ };
+
+ var contentForms = {
+ bold: [
+ 'strong',
+ 'b',
+ [ 'span', function( el ) {
+ var fw = el.styles[ 'font-weight' ];
+ return fw == 'bold' || +fw >= 700;
+ } ]
+ ],
+
+ italic: [
+ 'em',
+ 'i',
+ [ 'span', function( el ) {
+ return el.styles[ 'font-style' ] == 'italic';
+ } ]
+ ],
+
+ underline: [
+ 'u',
+ [ 'span', function( el ) {
+ return el.styles[ 'text-decoration' ] == 'underline';
+ } ]
+ ],
+
+ strike: [
+ 's',
+ 'strike',
+ [ 'span', function( el ) {
+ return el.styles[ 'text-decoration' ] == 'line-through';
+ } ]
+ ],
+
+ subscript: [
+ 'sub'
+ ],
+
+ superscript: [
+ 'sup'
+ ]
+ },
+ config = editor.config,
+ lang = editor.lang.basicstyles;
+
+ addButtonCommand( 'Bold', lang.bold, 'bold', config.coreStyles_bold );
+ addButtonCommand( 'Italic', lang.italic, 'italic', config.coreStyles_italic );
+ addButtonCommand( 'Underline', lang.underline, 'underline', config.coreStyles_underline );
+ addButtonCommand( 'Strike', lang.strike, 'strike', config.coreStyles_strike );
+ addButtonCommand( 'Subscript', lang.subscript, 'subscript', config.coreStyles_subscript );
+ addButtonCommand( 'Superscript', lang.superscript, 'superscript', config.coreStyles_superscript );
+
+ editor.setKeystroke( [
+ [ CKEDITOR.CTRL + 66 /*B*/, 'bold' ],
+ [ CKEDITOR.CTRL + 73 /*I*/, 'italic' ],
+ [ CKEDITOR.CTRL + 85 /*U*/, 'underline' ]
+ ] );
+ }
+} );
+
+// Basic Inline Styles.
+
+/**
+ * The style definition that applies the **bold** style to the text.
+ *
+ * Read more in the [documentation](#!/guide/dev_basicstyles)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).
+ *
+ * config.coreStyles_bold = { element: 'b', overrides: 'strong' };
+ *
+ * config.coreStyles_bold = {
+ * element: 'span',
+ * attributes: { 'class': 'Bold' }
+ * };
+ *
+ * @cfg
+ * @member CKEDITOR.config
+ */
+CKEDITOR.config.coreStyles_bold = { element: 'strong', overrides: 'b' };
+
+/**
+ * The style definition that applies the *italics* style to the text.
+ *
+ * Read more in the [documentation](#!/guide/dev_basicstyles)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).
+ *
+ * config.coreStyles_italic = { element: 'i', overrides: 'em' };
+ *
+ * CKEDITOR.config.coreStyles_italic = {
+ * element: 'span',
+ * attributes: { 'class': 'Italic' }
+ * };
+ *
+ * @cfg
+ * @member CKEDITOR.config
+ */
+CKEDITOR.config.coreStyles_italic = { element: 'em', overrides: 'i' };
+
+/**
+ * The style definition that applies the underline style to the text.
+ *
+ * Read more in the [documentation](#!/guide/dev_basicstyles)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).
+ *
+ * CKEDITOR.config.coreStyles_underline = {
+ * element: 'span',
+ * attributes: { 'class': 'Underline' }
+ * };
+ *
+ * @cfg
+ * @member CKEDITOR.config
+ */
+CKEDITOR.config.coreStyles_underline = { element: 'u' };
+
+/**
+ * The style definition that applies the strikethrough style to the text.
+ *
+ * Read more in the [documentation](#!/guide/dev_basicstyles)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).
+ *
+ * CKEDITOR.config.coreStyles_strike = {
+ * element: 'span',
+ * attributes: { 'class': 'Strikethrough' },
+ * overrides: 'strike'
+ * };
+ *
+ * @cfg
+ * @member CKEDITOR.config
+ */
+CKEDITOR.config.coreStyles_strike = { element: 's', overrides: 'strike' };
+
+/**
+ * The style definition that applies the subscript style to the text.
+ *
+ * Read more in the [documentation](#!/guide/dev_basicstyles)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).
+ *
+ * CKEDITOR.config.coreStyles_subscript = {
+ * element: 'span',
+ * attributes: { 'class': 'Subscript' },
+ * overrides: 'sub'
+ * };
+ *
+ * @cfg
+ * @member CKEDITOR.config
+ */
+CKEDITOR.config.coreStyles_subscript = { element: 'sub' };
+
+/**
+ * The style definition that applies the superscript style to the text.
+ *
+ * Read more in the [documentation](#!/guide/dev_basicstyles)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).
+ *
+ * CKEDITOR.config.coreStyles_superscript = {
+ * element: 'span',
+ * attributes: { 'class': 'Superscript' },
+ * overrides: 'sup'
+ * };
+ *
+ * @cfg
+ * @member CKEDITOR.config
+ */
+CKEDITOR.config.coreStyles_superscript = { element: 'sup' };
diff --git a/sources/plugins/bidi/icons/bidiltr.png b/sources/plugins/bidi/icons/bidiltr.png
new file mode 100644
index 00000000..a909c010
Binary files /dev/null and b/sources/plugins/bidi/icons/bidiltr.png differ
diff --git a/sources/plugins/bidi/icons/bidirtl.png b/sources/plugins/bidi/icons/bidirtl.png
new file mode 100644
index 00000000..7dbad48c
Binary files /dev/null and b/sources/plugins/bidi/icons/bidirtl.png differ
diff --git a/sources/plugins/bidi/icons/hidpi/bidiltr.png b/sources/plugins/bidi/icons/hidpi/bidiltr.png
new file mode 100644
index 00000000..c5998e00
Binary files /dev/null and b/sources/plugins/bidi/icons/hidpi/bidiltr.png differ
diff --git a/sources/plugins/bidi/icons/hidpi/bidirtl.png b/sources/plugins/bidi/icons/hidpi/bidirtl.png
new file mode 100644
index 00000000..8aa2adc8
Binary files /dev/null and b/sources/plugins/bidi/icons/hidpi/bidirtl.png differ
diff --git a/sources/plugins/bidi/lang/af.js b/sources/plugins/bidi/lang/af.js
new file mode 100644
index 00000000..048140a1
--- /dev/null
+++ b/sources/plugins/bidi/lang/af.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'af', {
+ ltr: 'Skryfrigting van links na regs',
+ rtl: 'Skryfrigting van regs na links'
+} );
diff --git a/sources/plugins/bidi/lang/ar.js b/sources/plugins/bidi/lang/ar.js
new file mode 100644
index 00000000..78297ecb
--- /dev/null
+++ b/sources/plugins/bidi/lang/ar.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'ar', {
+ ltr: 'إتجاه النص من اليسار إلى اليمين',
+ rtl: 'إتجاه النص من اليمين إلى اليسار'
+} );
diff --git a/sources/plugins/bidi/lang/bg.js b/sources/plugins/bidi/lang/bg.js
new file mode 100644
index 00000000..b81ab861
--- /dev/null
+++ b/sources/plugins/bidi/lang/bg.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'bg', {
+ ltr: 'Посока на текста от ляво на дясно',
+ rtl: 'Посока на текста от дясно на ляво'
+} );
diff --git a/sources/plugins/bidi/lang/bn.js b/sources/plugins/bidi/lang/bn.js
new file mode 100644
index 00000000..2c35288e
--- /dev/null
+++ b/sources/plugins/bidi/lang/bn.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'bn', {
+ ltr: 'Text direction from left to right', // MISSING
+ rtl: 'Text direction from right to left' // MISSING
+} );
diff --git a/sources/plugins/bidi/lang/bs.js b/sources/plugins/bidi/lang/bs.js
new file mode 100644
index 00000000..13f8ac49
--- /dev/null
+++ b/sources/plugins/bidi/lang/bs.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'bs', {
+ ltr: 'Text direction from left to right', // MISSING
+ rtl: 'Text direction from right to left' // MISSING
+} );
diff --git a/sources/plugins/bidi/lang/ca.js b/sources/plugins/bidi/lang/ca.js
new file mode 100644
index 00000000..801a18f4
--- /dev/null
+++ b/sources/plugins/bidi/lang/ca.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'ca', {
+ ltr: 'Direcció del text d\'esquerra a dreta',
+ rtl: 'Direcció del text de dreta a esquerra'
+} );
diff --git a/sources/plugins/bidi/lang/cs.js b/sources/plugins/bidi/lang/cs.js
new file mode 100644
index 00000000..b0852c0a
--- /dev/null
+++ b/sources/plugins/bidi/lang/cs.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'cs', {
+ ltr: 'Směr textu zleva doprava',
+ rtl: 'Směr textu zprava doleva'
+} );
diff --git a/sources/plugins/bidi/lang/cy.js b/sources/plugins/bidi/lang/cy.js
new file mode 100644
index 00000000..17e9d3bb
--- /dev/null
+++ b/sources/plugins/bidi/lang/cy.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'cy', {
+ ltr: 'Cyfeiriad testun o\'r chwith i\'r dde',
+ rtl: 'Cyfeiriad testun o\'r dde i\'r chwith'
+} );
diff --git a/sources/plugins/bidi/lang/da.js b/sources/plugins/bidi/lang/da.js
new file mode 100644
index 00000000..a53fbf7b
--- /dev/null
+++ b/sources/plugins/bidi/lang/da.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'da', {
+ ltr: 'Tekstretning fra venstre til højre',
+ rtl: 'Tekstretning fra højre til venstre'
+} );
diff --git a/sources/plugins/bidi/lang/de.js b/sources/plugins/bidi/lang/de.js
new file mode 100644
index 00000000..043fbc8b
--- /dev/null
+++ b/sources/plugins/bidi/lang/de.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'de', {
+ ltr: 'Leserichtung von Links nach Rechts',
+ rtl: 'Leserichtung von Rechts nach Links'
+} );
diff --git a/sources/plugins/bidi/lang/el.js b/sources/plugins/bidi/lang/el.js
new file mode 100644
index 00000000..7c38e8d7
--- /dev/null
+++ b/sources/plugins/bidi/lang/el.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'el', {
+ ltr: 'Διεύθυνση κειμένου από αριστερά στα δεξιά',
+ rtl: 'Διεύθυνση κειμένου από δεξιά στα αριστερά'
+} );
diff --git a/sources/plugins/bidi/lang/en-au.js b/sources/plugins/bidi/lang/en-au.js
new file mode 100644
index 00000000..a5fe457e
--- /dev/null
+++ b/sources/plugins/bidi/lang/en-au.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'en-au', {
+ ltr: 'Text direction from left to right', // MISSING
+ rtl: 'Text direction from right to left' // MISSING
+} );
diff --git a/sources/plugins/bidi/lang/en-ca.js b/sources/plugins/bidi/lang/en-ca.js
new file mode 100644
index 00000000..8424bf67
--- /dev/null
+++ b/sources/plugins/bidi/lang/en-ca.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'en-ca', {
+ ltr: 'Text direction from left to right', // MISSING
+ rtl: 'Text direction from right to left' // MISSING
+} );
diff --git a/sources/plugins/bidi/lang/en-gb.js b/sources/plugins/bidi/lang/en-gb.js
new file mode 100644
index 00000000..60c192fb
--- /dev/null
+++ b/sources/plugins/bidi/lang/en-gb.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'en-gb', {
+ ltr: 'Text direction from left to right',
+ rtl: 'Text direction from right to left'
+} );
diff --git a/sources/plugins/bidi/lang/en.js b/sources/plugins/bidi/lang/en.js
new file mode 100644
index 00000000..a685a87d
--- /dev/null
+++ b/sources/plugins/bidi/lang/en.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'en', {
+ ltr: 'Text direction from left to right',
+ rtl: 'Text direction from right to left'
+} );
diff --git a/sources/plugins/bidi/lang/eo.js b/sources/plugins/bidi/lang/eo.js
new file mode 100644
index 00000000..c63e15bb
--- /dev/null
+++ b/sources/plugins/bidi/lang/eo.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'eo', {
+ ltr: 'Tekstdirekto de maldekstre dekstren',
+ rtl: 'Tekstdirekto de dekstre maldekstren'
+} );
diff --git a/sources/plugins/bidi/lang/es.js b/sources/plugins/bidi/lang/es.js
new file mode 100644
index 00000000..6ea13209
--- /dev/null
+++ b/sources/plugins/bidi/lang/es.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'es', {
+ ltr: 'Dirección del texto de izquierda a derecha',
+ rtl: 'Dirección del texto de derecha a izquierda'
+} );
diff --git a/sources/plugins/bidi/lang/et.js b/sources/plugins/bidi/lang/et.js
new file mode 100644
index 00000000..4f8517d6
--- /dev/null
+++ b/sources/plugins/bidi/lang/et.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'et', {
+ ltr: 'Teksti suund vasakult paremale',
+ rtl: 'Teksti suund paremalt vasakule'
+} );
diff --git a/sources/plugins/bidi/lang/eu.js b/sources/plugins/bidi/lang/eu.js
new file mode 100644
index 00000000..8b46a9c4
--- /dev/null
+++ b/sources/plugins/bidi/lang/eu.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'eu', {
+ ltr: 'Testuaren norantza ezkerretik eskuinera',
+ rtl: 'Testuaren norantza eskuinetik ezkerrera'
+} );
diff --git a/sources/plugins/bidi/lang/fa.js b/sources/plugins/bidi/lang/fa.js
new file mode 100644
index 00000000..5d9a6eac
--- /dev/null
+++ b/sources/plugins/bidi/lang/fa.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'fa', {
+ ltr: 'جهت متن از چپ به راست',
+ rtl: 'جهت متن از راست به چپ'
+} );
diff --git a/sources/plugins/bidi/lang/fi.js b/sources/plugins/bidi/lang/fi.js
new file mode 100644
index 00000000..805f5b10
--- /dev/null
+++ b/sources/plugins/bidi/lang/fi.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'fi', {
+ ltr: 'Tekstin suunta vasemmalta oikealle',
+ rtl: 'Tekstin suunta oikealta vasemmalle'
+} );
diff --git a/sources/plugins/bidi/lang/fo.js b/sources/plugins/bidi/lang/fo.js
new file mode 100644
index 00000000..4e1c9408
--- /dev/null
+++ b/sources/plugins/bidi/lang/fo.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'fo', {
+ ltr: 'Tekstkós frá vinstru til høgru',
+ rtl: 'Tekstkós frá høgru til vinstru'
+} );
diff --git a/sources/plugins/bidi/lang/fr-ca.js b/sources/plugins/bidi/lang/fr-ca.js
new file mode 100644
index 00000000..184ed8ef
--- /dev/null
+++ b/sources/plugins/bidi/lang/fr-ca.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'fr-ca', {
+ ltr: 'Direction du texte de gauche à droite',
+ rtl: 'Direction du texte de droite à gauche'
+} );
diff --git a/sources/plugins/bidi/lang/fr.js b/sources/plugins/bidi/lang/fr.js
new file mode 100644
index 00000000..549a465d
--- /dev/null
+++ b/sources/plugins/bidi/lang/fr.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'fr', {
+ ltr: 'Direction du texte de la gauche vers la droite',
+ rtl: 'Direction du texte de la droite vers la gauche'
+} );
diff --git a/sources/plugins/bidi/lang/gl.js b/sources/plugins/bidi/lang/gl.js
new file mode 100644
index 00000000..cb753e3f
--- /dev/null
+++ b/sources/plugins/bidi/lang/gl.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'gl', {
+ ltr: 'Dirección do texto de esquerda a dereita',
+ rtl: 'Dirección do texto de dereita a esquerda'
+} );
diff --git a/sources/plugins/bidi/lang/gu.js b/sources/plugins/bidi/lang/gu.js
new file mode 100644
index 00000000..a75d98a8
--- /dev/null
+++ b/sources/plugins/bidi/lang/gu.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'gu', {
+ ltr: 'ટેક્ષ્ત્ ની દિશા ડાબે થી જમણે',
+ rtl: 'ટેક્ષ્ત્ ની દિશા જમણે થી ડાબે'
+} );
diff --git a/sources/plugins/bidi/lang/he.js b/sources/plugins/bidi/lang/he.js
new file mode 100644
index 00000000..89840cd9
--- /dev/null
+++ b/sources/plugins/bidi/lang/he.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'he', {
+ ltr: 'כיוון טקסט משמאל לימין (LTR)',
+ rtl: 'כיוון טקסט מימין לשמאל (RTL)'
+} );
diff --git a/sources/plugins/bidi/lang/hi.js b/sources/plugins/bidi/lang/hi.js
new file mode 100644
index 00000000..66697cc8
--- /dev/null
+++ b/sources/plugins/bidi/lang/hi.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'hi', {
+ ltr: 'Text direction from left to right', // MISSING
+ rtl: 'Text direction from right to left' // MISSING
+} );
diff --git a/sources/plugins/bidi/lang/hr.js b/sources/plugins/bidi/lang/hr.js
new file mode 100644
index 00000000..0be7b34c
--- /dev/null
+++ b/sources/plugins/bidi/lang/hr.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'hr', {
+ ltr: 'Smjer teksta s lijeva na desno',
+ rtl: 'Smjer teksta s desna na lijevo'
+} );
diff --git a/sources/plugins/bidi/lang/hu.js b/sources/plugins/bidi/lang/hu.js
new file mode 100644
index 00000000..58797e5d
--- /dev/null
+++ b/sources/plugins/bidi/lang/hu.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'hu', {
+ ltr: 'Szöveg iránya balról jobbra',
+ rtl: 'Szöveg iránya jobbról balra'
+} );
diff --git a/sources/plugins/bidi/lang/id.js b/sources/plugins/bidi/lang/id.js
new file mode 100644
index 00000000..2be45ac8
--- /dev/null
+++ b/sources/plugins/bidi/lang/id.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'id', {
+ ltr: 'Arah penulisan dari kiri ke kanan.',
+ rtl: 'Arah penulisan dari kanan ke kiri.'
+} );
diff --git a/sources/plugins/bidi/lang/is.js b/sources/plugins/bidi/lang/is.js
new file mode 100644
index 00000000..cd41df26
--- /dev/null
+++ b/sources/plugins/bidi/lang/is.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'is', {
+ ltr: 'Text direction from left to right', // MISSING
+ rtl: 'Text direction from right to left' // MISSING
+} );
diff --git a/sources/plugins/bidi/lang/it.js b/sources/plugins/bidi/lang/it.js
new file mode 100644
index 00000000..d4e9de6a
--- /dev/null
+++ b/sources/plugins/bidi/lang/it.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'it', {
+ ltr: 'Direzione del testo da sinistra verso destra',
+ rtl: 'Direzione del testo da destra verso sinistra'
+} );
diff --git a/sources/plugins/bidi/lang/ja.js b/sources/plugins/bidi/lang/ja.js
new file mode 100644
index 00000000..c79e1b64
--- /dev/null
+++ b/sources/plugins/bidi/lang/ja.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'ja', {
+ ltr: 'テキストの向き : 左から右へ',
+ rtl: 'テキストの向き : 右から左へ'
+} );
diff --git a/sources/plugins/bidi/lang/ka.js b/sources/plugins/bidi/lang/ka.js
new file mode 100644
index 00000000..cf731816
--- /dev/null
+++ b/sources/plugins/bidi/lang/ka.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'ka', {
+ ltr: 'ტექსტის მიმართულება მარცხნიდან მარჯვნივ',
+ rtl: 'ტექსტის მიმართულება მარჯვნიდან მარცხნივ'
+} );
diff --git a/sources/plugins/bidi/lang/km.js b/sources/plugins/bidi/lang/km.js
new file mode 100644
index 00000000..b28d330a
--- /dev/null
+++ b/sources/plugins/bidi/lang/km.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'km', {
+ ltr: 'ទិសដៅអក្សរពីឆ្វេងទៅស្ដាំ',
+ rtl: 'ទិសដៅអក្សរពីស្ដាំទៅឆ្វេង'
+} );
diff --git a/sources/plugins/bidi/lang/ko.js b/sources/plugins/bidi/lang/ko.js
new file mode 100644
index 00000000..923f70ce
--- /dev/null
+++ b/sources/plugins/bidi/lang/ko.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'ko', {
+ ltr: '텍스트 방향이 왼쪽에서 오른쪽으로 ',
+ rtl: '텍스트 방향이 오른쪽에서 왼쪽으로'
+} );
diff --git a/sources/plugins/bidi/lang/ku.js b/sources/plugins/bidi/lang/ku.js
new file mode 100644
index 00000000..0d563c76
--- /dev/null
+++ b/sources/plugins/bidi/lang/ku.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'ku', {
+ ltr: 'ئاراستەی نووسە لە چەپ بۆ ڕاست',
+ rtl: 'ئاراستەی نووسە لە ڕاست بۆ چەپ'
+} );
diff --git a/sources/plugins/bidi/lang/lt.js b/sources/plugins/bidi/lang/lt.js
new file mode 100644
index 00000000..e455b52b
--- /dev/null
+++ b/sources/plugins/bidi/lang/lt.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'lt', {
+ ltr: 'Tekstas iš kairės į dešinę',
+ rtl: 'Tekstas iš dešinės į kairę'
+} );
diff --git a/sources/plugins/bidi/lang/lv.js b/sources/plugins/bidi/lang/lv.js
new file mode 100644
index 00000000..b9e7d130
--- /dev/null
+++ b/sources/plugins/bidi/lang/lv.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'lv', {
+ ltr: 'Teksta virziens no kreisās uz labo',
+ rtl: 'Teksta virziens no labās uz kreiso'
+} );
diff --git a/sources/plugins/bidi/lang/mk.js b/sources/plugins/bidi/lang/mk.js
new file mode 100644
index 00000000..f7771932
--- /dev/null
+++ b/sources/plugins/bidi/lang/mk.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'mk', {
+ ltr: 'Text direction from left to right', // MISSING
+ rtl: 'Text direction from right to left' // MISSING
+} );
diff --git a/sources/plugins/bidi/lang/mn.js b/sources/plugins/bidi/lang/mn.js
new file mode 100644
index 00000000..acade9af
--- /dev/null
+++ b/sources/plugins/bidi/lang/mn.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'mn', {
+ ltr: 'Зүүнээс баруун тийш бичлэг',
+ rtl: 'Баруунаас зүүн тийш бичлэг'
+} );
diff --git a/sources/plugins/bidi/lang/ms.js b/sources/plugins/bidi/lang/ms.js
new file mode 100644
index 00000000..a86971b6
--- /dev/null
+++ b/sources/plugins/bidi/lang/ms.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'ms', {
+ ltr: 'Text direction from left to right', // MISSING
+ rtl: 'Text direction from right to left' // MISSING
+} );
diff --git a/sources/plugins/bidi/lang/nb.js b/sources/plugins/bidi/lang/nb.js
new file mode 100644
index 00000000..3a1225b9
--- /dev/null
+++ b/sources/plugins/bidi/lang/nb.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'nb', {
+ ltr: 'Tekstretning fra venstre til høyre',
+ rtl: 'Tekstretning fra høyre til venstre'
+} );
diff --git a/sources/plugins/bidi/lang/nl.js b/sources/plugins/bidi/lang/nl.js
new file mode 100644
index 00000000..d9cf8f7c
--- /dev/null
+++ b/sources/plugins/bidi/lang/nl.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'nl', {
+ ltr: 'Schrijfrichting van links naar rechts',
+ rtl: 'Schrijfrichting van rechts naar links'
+} );
diff --git a/sources/plugins/bidi/lang/no.js b/sources/plugins/bidi/lang/no.js
new file mode 100644
index 00000000..309a7474
--- /dev/null
+++ b/sources/plugins/bidi/lang/no.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'no', {
+ ltr: 'Tekstretning fra venstre til høyre',
+ rtl: 'Tekstretning fra høyre til venstre'
+} );
diff --git a/sources/plugins/bidi/lang/pl.js b/sources/plugins/bidi/lang/pl.js
new file mode 100644
index 00000000..b9ad7eb9
--- /dev/null
+++ b/sources/plugins/bidi/lang/pl.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'pl', {
+ ltr: 'Kierunek tekstu od lewej strony do prawej',
+ rtl: 'Kierunek tekstu od prawej strony do lewej'
+} );
diff --git a/sources/plugins/bidi/lang/pt-br.js b/sources/plugins/bidi/lang/pt-br.js
new file mode 100644
index 00000000..f97f3db1
--- /dev/null
+++ b/sources/plugins/bidi/lang/pt-br.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'pt-br', {
+ ltr: 'Direção do texto da esquerda para a direita',
+ rtl: 'Direção do texto da direita para a esquerda'
+} );
diff --git a/sources/plugins/bidi/lang/pt.js b/sources/plugins/bidi/lang/pt.js
new file mode 100644
index 00000000..5dd99b3a
--- /dev/null
+++ b/sources/plugins/bidi/lang/pt.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'pt', {
+ ltr: 'Direção do texto da esquerda para a direita',
+ rtl: 'Direção do texto da direita para a esquerda'
+} );
diff --git a/sources/plugins/bidi/lang/ro.js b/sources/plugins/bidi/lang/ro.js
new file mode 100644
index 00000000..13a560b0
--- /dev/null
+++ b/sources/plugins/bidi/lang/ro.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'ro', {
+ ltr: 'Direcția textului de la stânga la dreapta',
+ rtl: 'Direcția textului de la dreapta la stânga'
+} );
diff --git a/sources/plugins/bidi/lang/ru.js b/sources/plugins/bidi/lang/ru.js
new file mode 100644
index 00000000..e3dc391b
--- /dev/null
+++ b/sources/plugins/bidi/lang/ru.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'ru', {
+ ltr: 'Направление текста слева направо',
+ rtl: 'Направление текста справа налево'
+} );
diff --git a/sources/plugins/bidi/lang/si.js b/sources/plugins/bidi/lang/si.js
new file mode 100644
index 00000000..5260df1a
--- /dev/null
+++ b/sources/plugins/bidi/lang/si.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'si', {
+ ltr: 'වගන්ති දිශාව වමේ සිට දකුණට',
+ rtl: 'වගන්ති දිශාව දකුණේ සිට වමට'
+} );
diff --git a/sources/plugins/bidi/lang/sk.js b/sources/plugins/bidi/lang/sk.js
new file mode 100644
index 00000000..8f4a3587
--- /dev/null
+++ b/sources/plugins/bidi/lang/sk.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'sk', {
+ ltr: 'Smer textu zľava doprava',
+ rtl: 'Smer textu sprava doľava'
+} );
diff --git a/sources/plugins/bidi/lang/sl.js b/sources/plugins/bidi/lang/sl.js
new file mode 100644
index 00000000..972d355c
--- /dev/null
+++ b/sources/plugins/bidi/lang/sl.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'sl', {
+ ltr: 'Smer besedila od leve proti desni',
+ rtl: 'Smer besedila od desne proti levi'
+} );
diff --git a/sources/plugins/bidi/lang/sq.js b/sources/plugins/bidi/lang/sq.js
new file mode 100644
index 00000000..55a2152b
--- /dev/null
+++ b/sources/plugins/bidi/lang/sq.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'sq', {
+ ltr: 'Drejtimi i tekstit nga e majta në të djathtë',
+ rtl: 'Drejtimi i tekstit nga e djathta në të majtë'
+} );
diff --git a/sources/plugins/bidi/lang/sr-latn.js b/sources/plugins/bidi/lang/sr-latn.js
new file mode 100644
index 00000000..bf349403
--- /dev/null
+++ b/sources/plugins/bidi/lang/sr-latn.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'sr-latn', {
+ ltr: 'Text direction from left to right', // MISSING
+ rtl: 'Text direction from right to left' // MISSING
+} );
diff --git a/sources/plugins/bidi/lang/sr.js b/sources/plugins/bidi/lang/sr.js
new file mode 100644
index 00000000..c8cff445
--- /dev/null
+++ b/sources/plugins/bidi/lang/sr.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'sr', {
+ ltr: 'Text direction from left to right', // MISSING
+ rtl: 'Text direction from right to left' // MISSING
+} );
diff --git a/sources/plugins/bidi/lang/sv.js b/sources/plugins/bidi/lang/sv.js
new file mode 100644
index 00000000..b2056407
--- /dev/null
+++ b/sources/plugins/bidi/lang/sv.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'sv', {
+ ltr: 'Text riktning från vänster till höger',
+ rtl: 'Text riktning från höger till vänster'
+} );
diff --git a/sources/plugins/bidi/lang/th.js b/sources/plugins/bidi/lang/th.js
new file mode 100644
index 00000000..fefb49c7
--- /dev/null
+++ b/sources/plugins/bidi/lang/th.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'th', {
+ ltr: 'Text direction from left to right', // MISSING
+ rtl: 'Text direction from right to left' // MISSING
+} );
diff --git a/sources/plugins/bidi/lang/tr.js b/sources/plugins/bidi/lang/tr.js
new file mode 100644
index 00000000..11cde918
--- /dev/null
+++ b/sources/plugins/bidi/lang/tr.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'tr', {
+ ltr: 'Metin yönü soldan sağa',
+ rtl: 'Metin yönü sağdan sola'
+} );
diff --git a/sources/plugins/bidi/lang/tt.js b/sources/plugins/bidi/lang/tt.js
new file mode 100644
index 00000000..b60b3b28
--- /dev/null
+++ b/sources/plugins/bidi/lang/tt.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'tt', {
+ ltr: 'Сулдан уңга язылыш',
+ rtl: 'Уңнан сулга язылыш'
+} );
diff --git a/sources/plugins/bidi/lang/ug.js b/sources/plugins/bidi/lang/ug.js
new file mode 100644
index 00000000..b17d36cc
--- /dev/null
+++ b/sources/plugins/bidi/lang/ug.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'ug', {
+ ltr: 'تېكىست يۆنىلىشى سولدىن ئوڭغا',
+ rtl: 'تېكىست يۆنىلىشى ئوڭدىن سولغا'
+} );
diff --git a/sources/plugins/bidi/lang/uk.js b/sources/plugins/bidi/lang/uk.js
new file mode 100644
index 00000000..a74f09fc
--- /dev/null
+++ b/sources/plugins/bidi/lang/uk.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'uk', {
+ ltr: 'Напрямок тексту зліва направо',
+ rtl: 'Напрямок тексту справа наліво'
+} );
diff --git a/sources/plugins/bidi/lang/vi.js b/sources/plugins/bidi/lang/vi.js
new file mode 100644
index 00000000..cc6fd7b0
--- /dev/null
+++ b/sources/plugins/bidi/lang/vi.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'vi', {
+ ltr: 'Văn bản hướng từ trái sang phải',
+ rtl: 'Văn bản hướng từ phải sang trái'
+} );
diff --git a/sources/plugins/bidi/lang/zh-cn.js b/sources/plugins/bidi/lang/zh-cn.js
new file mode 100644
index 00000000..d56019e2
--- /dev/null
+++ b/sources/plugins/bidi/lang/zh-cn.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'zh-cn', {
+ ltr: '文字方向为从左至右',
+ rtl: '文字方向为从右至左'
+} );
diff --git a/sources/plugins/bidi/lang/zh.js b/sources/plugins/bidi/lang/zh.js
new file mode 100644
index 00000000..ff5db4f9
--- /dev/null
+++ b/sources/plugins/bidi/lang/zh.js
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'bidi', 'zh', {
+ ltr: '文字方向從左至右',
+ rtl: '文字方向從右至左'
+} );
diff --git a/sources/plugins/bidi/plugin.js b/sources/plugins/bidi/plugin.js
new file mode 100644
index 00000000..bfe3ffcb
--- /dev/null
+++ b/sources/plugins/bidi/plugin.js
@@ -0,0 +1,320 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+ var guardElements = { table: 1, ul: 1, ol: 1, blockquote: 1, div: 1 },
+ directSelectionGuardElements = {},
+ // All guard elements which can have a direction applied on them.
+ allGuardElements = {};
+ CKEDITOR.tools.extend( directSelectionGuardElements, guardElements, { tr: 1, p: 1, div: 1, li: 1 } );
+ CKEDITOR.tools.extend( allGuardElements, directSelectionGuardElements, { td: 1 } );
+
+ function setToolbarStates( editor, path ) {
+ var useComputedState = editor.config.useComputedState,
+ selectedElement;
+
+ useComputedState = useComputedState === undefined || useComputedState;
+
+ // We can use computedState provided by the browser or traverse parents manually.
+ if ( !useComputedState )
+ selectedElement = getElementForDirection( path.lastElement, editor.editable() );
+
+ selectedElement = selectedElement || path.block || path.blockLimit;
+
+ // If we're having BODY here, user probably done CTRL+A, let's try to get the enclosed node, if any.
+ if ( selectedElement.equals( editor.editable() ) ) {
+ var enclosedNode = editor.getSelection().getRanges()[ 0 ].getEnclosedNode();
+ enclosedNode && enclosedNode.type == CKEDITOR.NODE_ELEMENT && ( selectedElement = enclosedNode );
+ }
+
+ if ( !selectedElement )
+ return;
+
+ var selectionDir = useComputedState ? selectedElement.getComputedStyle( 'direction' ) : selectedElement.getStyle( 'direction' ) || selectedElement.getAttribute( 'dir' );
+
+ editor.getCommand( 'bidirtl' ).setState( selectionDir == 'rtl' ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );
+ editor.getCommand( 'bidiltr' ).setState( selectionDir == 'ltr' ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );
+ }
+
+ function handleMixedDirContent( editor, path ) {
+ var directionNode = path.block || path.blockLimit || editor.editable();
+ var pathDir = directionNode.getDirection( 1 );
+ if ( pathDir != ( editor._.selDir || editor.lang.dir ) ) {
+ editor._.selDir = pathDir;
+ editor.fire( 'contentDirChanged', pathDir );
+ }
+ }
+
+ // Returns element with possibility of applying the direction.
+ // @param node
+ function getElementForDirection( node, root ) {
+ while ( node && !( node.getName() in allGuardElements || node.equals( root ) ) ) {
+ var parent = node.getParent();
+ if ( !parent )
+ break;
+
+ node = parent;
+ }
+
+ return node;
+ }
+
+ function switchDir( element, dir, editor, database ) {
+ if ( element.isReadOnly() || element.equals( editor.editable() ) )
+ return;
+
+ // Mark this element as processed by switchDir.
+ CKEDITOR.dom.element.setMarker( database, element, 'bidi_processed', 1 );
+
+ // Check whether one of the ancestors has already been styled.
+ var parent = element,
+ editable = editor.editable();
+ while ( ( parent = parent.getParent() ) && !parent.equals( editable ) ) {
+ if ( parent.getCustomData( 'bidi_processed' ) ) {
+ // Ancestor style must dominate.
+ element.removeStyle( 'direction' );
+ element.removeAttribute( 'dir' );
+ return;
+ }
+ }
+
+ var useComputedState = ( 'useComputedState' in editor.config ) ? editor.config.useComputedState : 1;
+
+ var elementDir = useComputedState ? element.getComputedStyle( 'direction' ) : element.getStyle( 'direction' ) || element.hasAttribute( 'dir' );
+
+ // Stop if direction is same as present.
+ if ( elementDir == dir )
+ return;
+
+ // Clear direction on this element.
+ element.removeStyle( 'direction' );
+
+ // Do the second check when computed state is ON, to check
+ // if we need to apply explicit direction on this element.
+ if ( useComputedState ) {
+ element.removeAttribute( 'dir' );
+ if ( dir != element.getComputedStyle( 'direction' ) ) {
+ element.setAttribute( 'dir', dir );
+ }
+ } else {
+ // Set new direction for this element.
+ element.setAttribute( 'dir', dir );
+ }
+
+ editor.forceNextSelectionCheck();
+
+ return;
+ }
+
+ function getFullySelected( range, elements, enterMode ) {
+ var ancestor = range.getCommonAncestor( false, true );
+
+ range = range.clone();
+ range.enlarge( enterMode == CKEDITOR.ENTER_BR ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
+
+ if ( range.checkBoundaryOfElement( ancestor, CKEDITOR.START ) && range.checkBoundaryOfElement( ancestor, CKEDITOR.END ) ) {
+ var parent;
+ while ( ancestor && ancestor.type == CKEDITOR.NODE_ELEMENT && ( parent = ancestor.getParent() ) && parent.getChildCount() == 1 && !( ancestor.getName() in elements ) )
+ ancestor = parent;
+
+ return ancestor.type == CKEDITOR.NODE_ELEMENT && ( ancestor.getName() in elements ) && ancestor;
+ }
+ }
+
+ function bidiCommand( dir ) {
+ return {
+ // It applies to a "block-like" context.
+ context: 'p',
+ allowedContent: {
+ 'h1 h2 h3 h4 h5 h6 table ul ol blockquote div tr p div li td': {
+ propertiesOnly: true,
+ attributes: 'dir'
+ }
+ },
+ requiredContent: 'p[dir]',
+ refresh: function( editor, path ) {
+ setToolbarStates( editor, path );
+ handleMixedDirContent( editor, path );
+ },
+ exec: function( editor ) {
+ var selection = editor.getSelection(),
+ enterMode = editor.config.enterMode,
+ ranges = selection.getRanges();
+
+ if ( ranges && ranges.length ) {
+ var database = {};
+
+ // Creates bookmarks for selection, as we may split some blocks.
+ var bookmarks = selection.createBookmarks();
+
+ var rangeIterator = ranges.createIterator(),
+ range,
+ i = 0;
+
+ while ( ( range = rangeIterator.getNextRange( 1 ) ) ) {
+ // Apply do directly selected elements from guardElements.
+ var selectedElement = range.getEnclosedNode();
+
+ // If this is not our element of interest, apply to fully selected elements from guardElements.
+ if ( !selectedElement || selectedElement && !( selectedElement.type == CKEDITOR.NODE_ELEMENT && selectedElement.getName() in directSelectionGuardElements ) )
+ selectedElement = getFullySelected( range, guardElements, enterMode );
+
+ selectedElement && switchDir( selectedElement, dir, editor, database );
+
+ var iterator, block;
+
+ // Walker searching for guardElements.
+ var walker = new CKEDITOR.dom.walker( range );
+
+ var start = bookmarks[ i ].startNode,
+ end = bookmarks[ i++ ].endNode;
+
+ walker.evaluator = function( node ) {
+ var enterTagName = ( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' );
+
+ function isNodeElement( node ) {
+ return node ? ( node.type == CKEDITOR.NODE_ELEMENT ) : false;
+ }
+
+ function isGuard( node ) {
+ return node.getName() in guardElements;
+ }
+
+ return !!( isNodeElement( node ) && isGuard( node ) && !( node.is( enterTagName ) && isNodeElement( node.getParent() ) && node.getParent().is( 'blockquote' ) ) &&
+ // Element must be fully included in the range as well. (#6485).
+ node.getPosition( start ) & CKEDITOR.POSITION_FOLLOWING &&
+ ( ( node.getPosition( end ) & CKEDITOR.POSITION_PRECEDING + CKEDITOR.POSITION_CONTAINS ) == CKEDITOR.POSITION_PRECEDING ) );
+ };
+
+ while ( ( block = walker.next() ) )
+ switchDir( block, dir, editor, database );
+
+ iterator = range.createIterator();
+ iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
+
+ while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) )
+ switchDir( block, dir, editor, database );
+ }
+
+ CKEDITOR.dom.element.clearAllMarkers( database );
+
+ editor.forceNextSelectionCheck();
+ // Restore selection position.
+ selection.selectBookmarks( bookmarks );
+
+ editor.focus();
+ }
+ }
+ };
+ }
+
+ CKEDITOR.plugins.add( 'bidi', {
+ // jscs:disable maximumLineLength
+ lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
+ // jscs:enable maximumLineLength
+ icons: 'bidiltr,bidirtl', // %REMOVE_LINE_CORE%
+ hidpi: true, // %REMOVE_LINE_CORE%
+ init: function( editor ) {
+ if ( editor.blockless )
+ return;
+
+ // All buttons use the same code to register. So, to avoid
+ // duplications, let's use this tool function.
+ function addButtonCommand( buttonName, buttonLabel, commandName, commandDef, order ) {
+ editor.addCommand( commandName, new CKEDITOR.command( editor, commandDef ) );
+
+ if ( editor.ui.addButton ) {
+ editor.ui.addButton( buttonName, {
+ label: buttonLabel,
+ command: commandName,
+ toolbar: 'bidi,' + order
+ } );
+ }
+ }
+
+ var lang = editor.lang.bidi;
+
+ addButtonCommand( 'BidiLtr', lang.ltr, 'bidiltr', bidiCommand( 'ltr' ), 10 );
+ addButtonCommand( 'BidiRtl', lang.rtl, 'bidirtl', bidiCommand( 'rtl' ), 20 );
+
+ editor.on( 'contentDom', function() {
+ editor.document.on( 'dirChanged', function( evt ) {
+ editor.fire( 'dirChanged', {
+ node: evt.data,
+ dir: evt.data.getDirection( 1 )
+ } );
+ } );
+ } );
+
+ // Indicate that the current selection is in different direction than the UI.
+ editor.on( 'contentDirChanged', function( evt ) {
+ var func = ( editor.lang.dir != evt.data ? 'add' : 'remove' ) + 'Class';
+ var toolbar = editor.ui.space( editor.config.toolbarLocation );
+ if ( toolbar )
+ toolbar[ func ]( 'cke_mixed_dir_content' );
+ } );
+ }
+ } );
+
+ // If the element direction changed, we need to switch the margins of
+ // the element and all its children, so it will get really reflected
+ // like a mirror. (#5910)
+ function isOffline( el ) {
+ var html = el.getDocument().getBody().getParent();
+ while ( el ) {
+ if ( el.equals( html ) )
+ return false;
+ el = el.getParent();
+ }
+ return true;
+ }
+
+ function dirChangeNotifier( org ) {
+ var isAttribute = org == elementProto.setAttribute,
+ isRemoveAttribute = org == elementProto.removeAttribute,
+ dirStyleRegexp = /\bdirection\s*:\s*(.*?)\s*(:?$|;)/;
+
+ return function( name, val ) {
+ if ( !this.isReadOnly() ) {
+ var orgDir;
+ if ( ( name == ( isAttribute || isRemoveAttribute ? 'dir' : 'direction' ) || name == 'style' && ( isRemoveAttribute || dirStyleRegexp.test( val ) ) ) && !isOffline( this ) ) {
+ orgDir = this.getDirection( 1 );
+ var retval = org.apply( this, arguments );
+ if ( orgDir != this.getDirection( 1 ) ) {
+ this.getDocument().fire( 'dirChanged', this );
+ return retval;
+ }
+ }
+ }
+
+ return org.apply( this, arguments );
+ };
+ }
+
+ var elementProto = CKEDITOR.dom.element.prototype,
+ methods = [ 'setStyle', 'removeStyle', 'setAttribute', 'removeAttribute' ];
+ for ( var i = 0; i < methods.length; i++ )
+ elementProto[ methods[ i ] ] = CKEDITOR.tools.override( elementProto[ methods[ i ] ], dirChangeNotifier );
+} )();
+
+/**
+ * Fired when the language direction of an element is changed.
+ *
+ * @event dirChanged
+ * @member CKEDITOR.editor
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {CKEDITOR.dom.node} data.node The element that is being changed.
+ * @param {String} data.dir The new direction.
+ */
+
+/**
+ * Fired when the language direction in the specific cursor position is changed
+ *
+ * @event contentDirChanged
+ * @member CKEDITOR.editor
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param {String} data The direction in the current position.
+ */
diff --git a/sources/plugins/blockquote/icons/blockquote.png b/sources/plugins/blockquote/icons/blockquote.png
new file mode 100644
index 00000000..95293e25
Binary files /dev/null and b/sources/plugins/blockquote/icons/blockquote.png differ
diff --git a/sources/plugins/blockquote/icons/hidpi/blockquote.png b/sources/plugins/blockquote/icons/hidpi/blockquote.png
new file mode 100644
index 00000000..50c23b9f
Binary files /dev/null and b/sources/plugins/blockquote/icons/hidpi/blockquote.png differ
diff --git a/sources/plugins/blockquote/lang/af.js b/sources/plugins/blockquote/lang/af.js
new file mode 100644
index 00000000..e615381f
--- /dev/null
+++ b/sources/plugins/blockquote/lang/af.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'af', {
+ toolbar: 'Sitaatblok'
+} );
diff --git a/sources/plugins/blockquote/lang/ar.js b/sources/plugins/blockquote/lang/ar.js
new file mode 100644
index 00000000..eb22b93e
--- /dev/null
+++ b/sources/plugins/blockquote/lang/ar.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'ar', {
+ toolbar: 'اقتباس'
+} );
diff --git a/sources/plugins/blockquote/lang/bg.js b/sources/plugins/blockquote/lang/bg.js
new file mode 100644
index 00000000..97e6f126
--- /dev/null
+++ b/sources/plugins/blockquote/lang/bg.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'bg', {
+ toolbar: 'Блок за цитат'
+} );
diff --git a/sources/plugins/blockquote/lang/bn.js b/sources/plugins/blockquote/lang/bn.js
new file mode 100644
index 00000000..02ab2002
--- /dev/null
+++ b/sources/plugins/blockquote/lang/bn.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'bn', {
+ toolbar: 'Block Quote' // MISSING
+} );
diff --git a/sources/plugins/blockquote/lang/bs.js b/sources/plugins/blockquote/lang/bs.js
new file mode 100644
index 00000000..3a4d3f38
--- /dev/null
+++ b/sources/plugins/blockquote/lang/bs.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'bs', {
+ toolbar: 'Block Quote' // MISSING
+} );
diff --git a/sources/plugins/blockquote/lang/ca.js b/sources/plugins/blockquote/lang/ca.js
new file mode 100644
index 00000000..41bfbc73
--- /dev/null
+++ b/sources/plugins/blockquote/lang/ca.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'ca', {
+ toolbar: 'Bloc de cita'
+} );
diff --git a/sources/plugins/blockquote/lang/cs.js b/sources/plugins/blockquote/lang/cs.js
new file mode 100644
index 00000000..7c63ff53
--- /dev/null
+++ b/sources/plugins/blockquote/lang/cs.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'cs', {
+ toolbar: 'Citace'
+} );
diff --git a/sources/plugins/blockquote/lang/cy.js b/sources/plugins/blockquote/lang/cy.js
new file mode 100644
index 00000000..a47b50ab
--- /dev/null
+++ b/sources/plugins/blockquote/lang/cy.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'cy', {
+ toolbar: 'Dyfyniad bloc'
+} );
diff --git a/sources/plugins/blockquote/lang/da.js b/sources/plugins/blockquote/lang/da.js
new file mode 100644
index 00000000..e1f8de13
--- /dev/null
+++ b/sources/plugins/blockquote/lang/da.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'da', {
+ toolbar: 'Blokcitat'
+} );
diff --git a/sources/plugins/blockquote/lang/de.js b/sources/plugins/blockquote/lang/de.js
new file mode 100644
index 00000000..e5c47e5f
--- /dev/null
+++ b/sources/plugins/blockquote/lang/de.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'de', {
+ toolbar: 'Zitatblock'
+} );
diff --git a/sources/plugins/blockquote/lang/el.js b/sources/plugins/blockquote/lang/el.js
new file mode 100644
index 00000000..af7cde55
--- /dev/null
+++ b/sources/plugins/blockquote/lang/el.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'el', {
+ toolbar: 'Περιοχή Παράθεσης'
+} );
diff --git a/sources/plugins/blockquote/lang/en-au.js b/sources/plugins/blockquote/lang/en-au.js
new file mode 100644
index 00000000..9f70e6ce
--- /dev/null
+++ b/sources/plugins/blockquote/lang/en-au.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'en-au', {
+ toolbar: 'Block Quote'
+} );
diff --git a/sources/plugins/blockquote/lang/en-ca.js b/sources/plugins/blockquote/lang/en-ca.js
new file mode 100644
index 00000000..7caafa22
--- /dev/null
+++ b/sources/plugins/blockquote/lang/en-ca.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'en-ca', {
+ toolbar: 'Block Quote'
+} );
diff --git a/sources/plugins/blockquote/lang/en-gb.js b/sources/plugins/blockquote/lang/en-gb.js
new file mode 100644
index 00000000..f894911a
--- /dev/null
+++ b/sources/plugins/blockquote/lang/en-gb.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'en-gb', {
+ toolbar: 'Block Quote'
+} );
diff --git a/sources/plugins/blockquote/lang/en.js b/sources/plugins/blockquote/lang/en.js
new file mode 100644
index 00000000..33c50694
--- /dev/null
+++ b/sources/plugins/blockquote/lang/en.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'en', {
+ toolbar: 'Block Quote'
+} );
diff --git a/sources/plugins/blockquote/lang/eo.js b/sources/plugins/blockquote/lang/eo.js
new file mode 100644
index 00000000..b33c6f18
--- /dev/null
+++ b/sources/plugins/blockquote/lang/eo.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'eo', {
+ toolbar: 'Citaĵo'
+} );
diff --git a/sources/plugins/blockquote/lang/es.js b/sources/plugins/blockquote/lang/es.js
new file mode 100644
index 00000000..fb4e834e
--- /dev/null
+++ b/sources/plugins/blockquote/lang/es.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'es', {
+ toolbar: 'Cita'
+} );
diff --git a/sources/plugins/blockquote/lang/et.js b/sources/plugins/blockquote/lang/et.js
new file mode 100644
index 00000000..eb9eaa55
--- /dev/null
+++ b/sources/plugins/blockquote/lang/et.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'et', {
+ toolbar: 'Blokktsitaat'
+} );
diff --git a/sources/plugins/blockquote/lang/eu.js b/sources/plugins/blockquote/lang/eu.js
new file mode 100644
index 00000000..6320397b
--- /dev/null
+++ b/sources/plugins/blockquote/lang/eu.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'eu', {
+ toolbar: 'Aipamen blokea'
+} );
diff --git a/sources/plugins/blockquote/lang/fa.js b/sources/plugins/blockquote/lang/fa.js
new file mode 100644
index 00000000..2f12a50e
--- /dev/null
+++ b/sources/plugins/blockquote/lang/fa.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'fa', {
+ toolbar: 'بلوک نقل قول'
+} );
diff --git a/sources/plugins/blockquote/lang/fi.js b/sources/plugins/blockquote/lang/fi.js
new file mode 100644
index 00000000..44924d0a
--- /dev/null
+++ b/sources/plugins/blockquote/lang/fi.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'fi', {
+ toolbar: 'Lainaus'
+} );
diff --git a/sources/plugins/blockquote/lang/fo.js b/sources/plugins/blockquote/lang/fo.js
new file mode 100644
index 00000000..0557b99c
--- /dev/null
+++ b/sources/plugins/blockquote/lang/fo.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'fo', {
+ toolbar: 'Blockquote'
+} );
diff --git a/sources/plugins/blockquote/lang/fr-ca.js b/sources/plugins/blockquote/lang/fr-ca.js
new file mode 100644
index 00000000..0ae3f2b2
--- /dev/null
+++ b/sources/plugins/blockquote/lang/fr-ca.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'fr-ca', {
+ toolbar: 'Citation'
+} );
diff --git a/sources/plugins/blockquote/lang/fr.js b/sources/plugins/blockquote/lang/fr.js
new file mode 100644
index 00000000..21710d24
--- /dev/null
+++ b/sources/plugins/blockquote/lang/fr.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'fr', {
+ toolbar: 'Citation'
+} );
diff --git a/sources/plugins/blockquote/lang/gl.js b/sources/plugins/blockquote/lang/gl.js
new file mode 100644
index 00000000..0ace64eb
--- /dev/null
+++ b/sources/plugins/blockquote/lang/gl.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'gl', {
+ toolbar: 'Cita'
+} );
diff --git a/sources/plugins/blockquote/lang/gu.js b/sources/plugins/blockquote/lang/gu.js
new file mode 100644
index 00000000..9fc65baa
--- /dev/null
+++ b/sources/plugins/blockquote/lang/gu.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'gu', {
+ toolbar: 'બ્લૉક-કોટ, અવતરણચિહ્નો'
+} );
diff --git a/sources/plugins/blockquote/lang/he.js b/sources/plugins/blockquote/lang/he.js
new file mode 100644
index 00000000..a10d7e40
--- /dev/null
+++ b/sources/plugins/blockquote/lang/he.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'he', {
+ toolbar: 'בלוק ציטוט'
+} );
diff --git a/sources/plugins/blockquote/lang/hi.js b/sources/plugins/blockquote/lang/hi.js
new file mode 100644
index 00000000..b7481e24
--- /dev/null
+++ b/sources/plugins/blockquote/lang/hi.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'hi', {
+ toolbar: 'ब्लॉक-कोट'
+} );
diff --git a/sources/plugins/blockquote/lang/hr.js b/sources/plugins/blockquote/lang/hr.js
new file mode 100644
index 00000000..421ffd57
--- /dev/null
+++ b/sources/plugins/blockquote/lang/hr.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'hr', {
+ toolbar: 'Blockquote'
+} );
diff --git a/sources/plugins/blockquote/lang/hu.js b/sources/plugins/blockquote/lang/hu.js
new file mode 100644
index 00000000..5bf22703
--- /dev/null
+++ b/sources/plugins/blockquote/lang/hu.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'hu', {
+ toolbar: 'Idézet blokk'
+} );
diff --git a/sources/plugins/blockquote/lang/id.js b/sources/plugins/blockquote/lang/id.js
new file mode 100644
index 00000000..3cab0ac3
--- /dev/null
+++ b/sources/plugins/blockquote/lang/id.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'id', {
+ toolbar: 'Kutipan Blok'
+} );
diff --git a/sources/plugins/blockquote/lang/is.js b/sources/plugins/blockquote/lang/is.js
new file mode 100644
index 00000000..04f13a9b
--- /dev/null
+++ b/sources/plugins/blockquote/lang/is.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'is', {
+ toolbar: 'Inndráttur'
+} );
diff --git a/sources/plugins/blockquote/lang/it.js b/sources/plugins/blockquote/lang/it.js
new file mode 100644
index 00000000..77de24eb
--- /dev/null
+++ b/sources/plugins/blockquote/lang/it.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'it', {
+ toolbar: 'Citazione'
+} );
diff --git a/sources/plugins/blockquote/lang/ja.js b/sources/plugins/blockquote/lang/ja.js
new file mode 100644
index 00000000..d6155ea0
--- /dev/null
+++ b/sources/plugins/blockquote/lang/ja.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'ja', {
+ toolbar: 'ブロック引用文'
+} );
diff --git a/sources/plugins/blockquote/lang/ka.js b/sources/plugins/blockquote/lang/ka.js
new file mode 100644
index 00000000..826113bb
--- /dev/null
+++ b/sources/plugins/blockquote/lang/ka.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'ka', {
+ toolbar: 'ციტატა'
+} );
diff --git a/sources/plugins/blockquote/lang/km.js b/sources/plugins/blockquote/lang/km.js
new file mode 100644
index 00000000..a29f072c
--- /dev/null
+++ b/sources/plugins/blockquote/lang/km.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'km', {
+ toolbar: 'ប្លក់ពាក្យសម្រង់'
+} );
diff --git a/sources/plugins/blockquote/lang/ko.js b/sources/plugins/blockquote/lang/ko.js
new file mode 100644
index 00000000..f27c777d
--- /dev/null
+++ b/sources/plugins/blockquote/lang/ko.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'ko', {
+ toolbar: '인용 단락'
+} );
diff --git a/sources/plugins/blockquote/lang/ku.js b/sources/plugins/blockquote/lang/ku.js
new file mode 100644
index 00000000..c6e22aa6
--- /dev/null
+++ b/sources/plugins/blockquote/lang/ku.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'ku', {
+ toolbar: 'بەربەستکردنی ووتەی وەرگیراو'
+} );
diff --git a/sources/plugins/blockquote/lang/lt.js b/sources/plugins/blockquote/lang/lt.js
new file mode 100644
index 00000000..775232a0
--- /dev/null
+++ b/sources/plugins/blockquote/lang/lt.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'lt', {
+ toolbar: 'Citata'
+} );
diff --git a/sources/plugins/blockquote/lang/lv.js b/sources/plugins/blockquote/lang/lv.js
new file mode 100644
index 00000000..006ec477
--- /dev/null
+++ b/sources/plugins/blockquote/lang/lv.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'lv', {
+ toolbar: 'Bloka citāts'
+} );
diff --git a/sources/plugins/blockquote/lang/mk.js b/sources/plugins/blockquote/lang/mk.js
new file mode 100644
index 00000000..87167bae
--- /dev/null
+++ b/sources/plugins/blockquote/lang/mk.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'mk', {
+ toolbar: 'Block Quote' // MISSING
+} );
diff --git a/sources/plugins/blockquote/lang/mn.js b/sources/plugins/blockquote/lang/mn.js
new file mode 100644
index 00000000..a18eb38c
--- /dev/null
+++ b/sources/plugins/blockquote/lang/mn.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'mn', {
+ toolbar: 'Ишлэл хэсэг'
+} );
diff --git a/sources/plugins/blockquote/lang/ms.js b/sources/plugins/blockquote/lang/ms.js
new file mode 100644
index 00000000..4c7e7b47
--- /dev/null
+++ b/sources/plugins/blockquote/lang/ms.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'ms', {
+ toolbar: 'Block Quote' // MISSING
+} );
diff --git a/sources/plugins/blockquote/lang/nb.js b/sources/plugins/blockquote/lang/nb.js
new file mode 100644
index 00000000..154c2609
--- /dev/null
+++ b/sources/plugins/blockquote/lang/nb.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'nb', {
+ toolbar: 'Blokksitat'
+} );
diff --git a/sources/plugins/blockquote/lang/nl.js b/sources/plugins/blockquote/lang/nl.js
new file mode 100644
index 00000000..ef45be9a
--- /dev/null
+++ b/sources/plugins/blockquote/lang/nl.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'nl', {
+ toolbar: 'Citaatblok'
+} );
diff --git a/sources/plugins/blockquote/lang/no.js b/sources/plugins/blockquote/lang/no.js
new file mode 100644
index 00000000..79388492
--- /dev/null
+++ b/sources/plugins/blockquote/lang/no.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'no', {
+ toolbar: 'Blokksitat'
+} );
diff --git a/sources/plugins/blockquote/lang/pl.js b/sources/plugins/blockquote/lang/pl.js
new file mode 100644
index 00000000..ebaab5db
--- /dev/null
+++ b/sources/plugins/blockquote/lang/pl.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'pl', {
+ toolbar: 'Cytat'
+} );
diff --git a/sources/plugins/blockquote/lang/pt-br.js b/sources/plugins/blockquote/lang/pt-br.js
new file mode 100644
index 00000000..8fbe5004
--- /dev/null
+++ b/sources/plugins/blockquote/lang/pt-br.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'pt-br', {
+ toolbar: 'Citação'
+} );
diff --git a/sources/plugins/blockquote/lang/pt.js b/sources/plugins/blockquote/lang/pt.js
new file mode 100644
index 00000000..98c65b03
--- /dev/null
+++ b/sources/plugins/blockquote/lang/pt.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'pt', {
+ toolbar: 'Bloco de citação'
+} );
diff --git a/sources/plugins/blockquote/lang/ro.js b/sources/plugins/blockquote/lang/ro.js
new file mode 100644
index 00000000..699ee2cd
--- /dev/null
+++ b/sources/plugins/blockquote/lang/ro.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'ro', {
+ toolbar: 'Citat'
+} );
diff --git a/sources/plugins/blockquote/lang/ru.js b/sources/plugins/blockquote/lang/ru.js
new file mode 100644
index 00000000..b7ddbb46
--- /dev/null
+++ b/sources/plugins/blockquote/lang/ru.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'ru', {
+ toolbar: 'Цитата'
+} );
diff --git a/sources/plugins/blockquote/lang/si.js b/sources/plugins/blockquote/lang/si.js
new file mode 100644
index 00000000..0cf851aa
--- /dev/null
+++ b/sources/plugins/blockquote/lang/si.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'si', {
+ toolbar: 'උද්ධෘත කොටස'
+} );
diff --git a/sources/plugins/blockquote/lang/sk.js b/sources/plugins/blockquote/lang/sk.js
new file mode 100644
index 00000000..3ee34ea8
--- /dev/null
+++ b/sources/plugins/blockquote/lang/sk.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'sk', {
+ toolbar: 'Citácia'
+} );
diff --git a/sources/plugins/blockquote/lang/sl.js b/sources/plugins/blockquote/lang/sl.js
new file mode 100644
index 00000000..50201069
--- /dev/null
+++ b/sources/plugins/blockquote/lang/sl.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'sl', {
+ toolbar: 'Citat'
+} );
diff --git a/sources/plugins/blockquote/lang/sq.js b/sources/plugins/blockquote/lang/sq.js
new file mode 100644
index 00000000..3e99a148
--- /dev/null
+++ b/sources/plugins/blockquote/lang/sq.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'sq', {
+ toolbar: 'Citatet'
+} );
diff --git a/sources/plugins/blockquote/lang/sr-latn.js b/sources/plugins/blockquote/lang/sr-latn.js
new file mode 100644
index 00000000..8372a930
--- /dev/null
+++ b/sources/plugins/blockquote/lang/sr-latn.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'sr-latn', {
+ toolbar: 'Block Quote' // MISSING
+} );
diff --git a/sources/plugins/blockquote/lang/sr.js b/sources/plugins/blockquote/lang/sr.js
new file mode 100644
index 00000000..afbb2b6a
--- /dev/null
+++ b/sources/plugins/blockquote/lang/sr.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'sr', {
+ toolbar: 'Block Quote' // MISSING
+} );
diff --git a/sources/plugins/blockquote/lang/sv.js b/sources/plugins/blockquote/lang/sv.js
new file mode 100644
index 00000000..6002c515
--- /dev/null
+++ b/sources/plugins/blockquote/lang/sv.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'sv', {
+ toolbar: 'Blockcitat'
+} );
diff --git a/sources/plugins/blockquote/lang/th.js b/sources/plugins/blockquote/lang/th.js
new file mode 100644
index 00000000..dbda0a53
--- /dev/null
+++ b/sources/plugins/blockquote/lang/th.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'th', {
+ toolbar: 'Block Quote'
+} );
diff --git a/sources/plugins/blockquote/lang/tr.js b/sources/plugins/blockquote/lang/tr.js
new file mode 100644
index 00000000..db22c313
--- /dev/null
+++ b/sources/plugins/blockquote/lang/tr.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'tr', {
+ toolbar: 'Blok Oluştur'
+} );
diff --git a/sources/plugins/blockquote/lang/tt.js b/sources/plugins/blockquote/lang/tt.js
new file mode 100644
index 00000000..4dc271e3
--- /dev/null
+++ b/sources/plugins/blockquote/lang/tt.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'tt', {
+ toolbar: 'Өземтә блогы'
+} );
diff --git a/sources/plugins/blockquote/lang/ug.js b/sources/plugins/blockquote/lang/ug.js
new file mode 100644
index 00000000..5be430bf
--- /dev/null
+++ b/sources/plugins/blockquote/lang/ug.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'ug', {
+ toolbar: 'بۆلەك نەقىل'
+} );
diff --git a/sources/plugins/blockquote/lang/uk.js b/sources/plugins/blockquote/lang/uk.js
new file mode 100644
index 00000000..b425fdaa
--- /dev/null
+++ b/sources/plugins/blockquote/lang/uk.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'uk', {
+ toolbar: 'Цитата'
+} );
diff --git a/sources/plugins/blockquote/lang/vi.js b/sources/plugins/blockquote/lang/vi.js
new file mode 100644
index 00000000..e4eb496b
--- /dev/null
+++ b/sources/plugins/blockquote/lang/vi.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'vi', {
+ toolbar: 'Khối trích dẫn'
+} );
diff --git a/sources/plugins/blockquote/lang/zh-cn.js b/sources/plugins/blockquote/lang/zh-cn.js
new file mode 100644
index 00000000..76a92636
--- /dev/null
+++ b/sources/plugins/blockquote/lang/zh-cn.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'zh-cn', {
+ toolbar: '块引用'
+} );
diff --git a/sources/plugins/blockquote/lang/zh.js b/sources/plugins/blockquote/lang/zh.js
new file mode 100644
index 00000000..7f892984
--- /dev/null
+++ b/sources/plugins/blockquote/lang/zh.js
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'blockquote', 'zh', {
+ toolbar: '引用段落'
+} );
diff --git a/sources/plugins/blockquote/plugin.js b/sources/plugins/blockquote/plugin.js
new file mode 100644
index 00000000..0b2bf332
--- /dev/null
+++ b/sources/plugins/blockquote/plugin.js
@@ -0,0 +1,251 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+ function noBlockLeft( bqBlock ) {
+ for ( var i = 0, length = bqBlock.getChildCount(), child; i < length && ( child = bqBlock.getChild( i ) ); i++ ) {
+ if ( child.type == CKEDITOR.NODE_ELEMENT && child.isBlockBoundary() )
+ return false;
+ }
+ return true;
+ }
+
+ var commandObject = {
+ exec: function( editor ) {
+ var state = editor.getCommand( 'blockquote' ).state,
+ selection = editor.getSelection(),
+ range = selection && selection.getRanges()[ 0 ];
+
+ if ( !range )
+ return;
+
+ var bookmarks = selection.createBookmarks();
+
+ // Kludge for #1592: if the bookmark nodes are in the beginning of
+ // blockquote, then move them to the nearest block element in the
+ // blockquote.
+ if ( CKEDITOR.env.ie ) {
+ var bookmarkStart = bookmarks[ 0 ].startNode,
+ bookmarkEnd = bookmarks[ 0 ].endNode,
+ cursor;
+
+ if ( bookmarkStart && bookmarkStart.getParent().getName() == 'blockquote' ) {
+ cursor = bookmarkStart;
+ while ( ( cursor = cursor.getNext() ) ) {
+ if ( cursor.type == CKEDITOR.NODE_ELEMENT && cursor.isBlockBoundary() ) {
+ bookmarkStart.move( cursor, true );
+ break;
+ }
+ }
+ }
+
+ if ( bookmarkEnd && bookmarkEnd.getParent().getName() == 'blockquote' ) {
+ cursor = bookmarkEnd;
+ while ( ( cursor = cursor.getPrevious() ) ) {
+ if ( cursor.type == CKEDITOR.NODE_ELEMENT && cursor.isBlockBoundary() ) {
+ bookmarkEnd.move( cursor );
+ break;
+ }
+ }
+ }
+ }
+
+ var iterator = range.createIterator(),
+ block;
+ iterator.enlargeBr = editor.config.enterMode != CKEDITOR.ENTER_BR;
+
+ if ( state == CKEDITOR.TRISTATE_OFF ) {
+ var paragraphs = [];
+ while ( ( block = iterator.getNextParagraph() ) )
+ paragraphs.push( block );
+
+ // If no paragraphs, create one from the current selection position.
+ if ( paragraphs.length < 1 ) {
+ var para = editor.document.createElement( editor.config.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ),
+ firstBookmark = bookmarks.shift();
+ range.insertNode( para );
+ para.append( new CKEDITOR.dom.text( '\ufeff', editor.document ) );
+ range.moveToBookmark( firstBookmark );
+ range.selectNodeContents( para );
+ range.collapse( true );
+ firstBookmark = range.createBookmark();
+ paragraphs.push( para );
+ bookmarks.unshift( firstBookmark );
+ }
+
+ // Make sure all paragraphs have the same parent.
+ var commonParent = paragraphs[ 0 ].getParent(),
+ tmp = [];
+ for ( var i = 0; i < paragraphs.length; i++ ) {
+ block = paragraphs[ i ];
+ commonParent = commonParent.getCommonAncestor( block.getParent() );
+ }
+
+ // The common parent must not be the following tags: table, tbody, tr, ol, ul.
+ var denyTags = { table: 1, tbody: 1, tr: 1, ol: 1, ul: 1 };
+ while ( denyTags[ commonParent.getName() ] )
+ commonParent = commonParent.getParent();
+
+ // Reconstruct the block list to be processed such that all resulting blocks
+ // satisfy parentNode.equals( commonParent ).
+ var lastBlock = null;
+ while ( paragraphs.length > 0 ) {
+ block = paragraphs.shift();
+ while ( !block.getParent().equals( commonParent ) )
+ block = block.getParent();
+ if ( !block.equals( lastBlock ) )
+ tmp.push( block );
+ lastBlock = block;
+ }
+
+ // If any of the selected blocks is a blockquote, remove it to prevent
+ // nested blockquotes.
+ while ( tmp.length > 0 ) {
+ block = tmp.shift();
+ if ( block.getName() == 'blockquote' ) {
+ var docFrag = new CKEDITOR.dom.documentFragment( editor.document );
+ while ( block.getFirst() ) {
+ docFrag.append( block.getFirst().remove() );
+ paragraphs.push( docFrag.getLast() );
+ }
+
+ docFrag.replace( block );
+ } else {
+ paragraphs.push( block );
+ }
+ }
+
+ // Now we have all the blocks to be included in a new blockquote node.
+ var bqBlock = editor.document.createElement( 'blockquote' );
+ bqBlock.insertBefore( paragraphs[ 0 ] );
+ while ( paragraphs.length > 0 ) {
+ block = paragraphs.shift();
+ bqBlock.append( block );
+ }
+ } else if ( state == CKEDITOR.TRISTATE_ON ) {
+ var moveOutNodes = [],
+ database = {};
+
+ while ( ( block = iterator.getNextParagraph() ) ) {
+ var bqParent = null,
+ bqChild = null;
+ while ( block.getParent() ) {
+ if ( block.getParent().getName() == 'blockquote' ) {
+ bqParent = block.getParent();
+ bqChild = block;
+ break;
+ }
+ block = block.getParent();
+ }
+
+ // Remember the blocks that were recorded down in the moveOutNodes array
+ // to prevent duplicates.
+ if ( bqParent && bqChild && !bqChild.getCustomData( 'blockquote_moveout' ) ) {
+ moveOutNodes.push( bqChild );
+ CKEDITOR.dom.element.setMarker( database, bqChild, 'blockquote_moveout', true );
+ }
+ }
+
+ CKEDITOR.dom.element.clearAllMarkers( database );
+
+ var movedNodes = [],
+ processedBlockquoteBlocks = [];
+
+ database = {};
+ while ( moveOutNodes.length > 0 ) {
+ var node = moveOutNodes.shift();
+ bqBlock = node.getParent();
+
+ // If the node is located at the beginning or the end, just take it out
+ // without splitting. Otherwise, split the blockquote node and move the
+ // paragraph in between the two blockquote nodes.
+ if ( !node.getPrevious() )
+ node.remove().insertBefore( bqBlock );
+ else if ( !node.getNext() )
+ node.remove().insertAfter( bqBlock );
+ else {
+ node.breakParent( node.getParent() );
+ processedBlockquoteBlocks.push( node.getNext() );
+ }
+
+ // Remember the blockquote node so we can clear it later (if it becomes empty).
+ if ( !bqBlock.getCustomData( 'blockquote_processed' ) ) {
+ processedBlockquoteBlocks.push( bqBlock );
+ CKEDITOR.dom.element.setMarker( database, bqBlock, 'blockquote_processed', true );
+ }
+
+ movedNodes.push( node );
+ }
+
+ CKEDITOR.dom.element.clearAllMarkers( database );
+
+ // Clear blockquote nodes that have become empty.
+ for ( i = processedBlockquoteBlocks.length - 1; i >= 0; i-- ) {
+ bqBlock = processedBlockquoteBlocks[ i ];
+ if ( noBlockLeft( bqBlock ) )
+ bqBlock.remove();
+ }
+
+ if ( editor.config.enterMode == CKEDITOR.ENTER_BR ) {
+ var firstTime = true;
+ while ( movedNodes.length ) {
+ node = movedNodes.shift();
+
+ if ( node.getName() == 'div' ) {
+ docFrag = new CKEDITOR.dom.documentFragment( editor.document );
+ var needBeginBr = firstTime && node.getPrevious() && !( node.getPrevious().type == CKEDITOR.NODE_ELEMENT && node.getPrevious().isBlockBoundary() );
+ if ( needBeginBr )
+ docFrag.append( editor.document.createElement( 'br' ) );
+
+ var needEndBr = node.getNext() && !( node.getNext().type == CKEDITOR.NODE_ELEMENT && node.getNext().isBlockBoundary() );
+ while ( node.getFirst() )
+ node.getFirst().remove().appendTo( docFrag );
+
+ if ( needEndBr )
+ docFrag.append( editor.document.createElement( 'br' ) );
+
+ docFrag.replace( node );
+ firstTime = false;
+ }
+ }
+ }
+ }
+
+ selection.selectBookmarks( bookmarks );
+ editor.focus();
+ },
+
+ refresh: function( editor, path ) {
+ // Check if inside of blockquote.
+ var firstBlock = path.block || path.blockLimit;
+ this.setState( editor.elementPath( firstBlock ).contains( 'blockquote', 1 ) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );
+ },
+
+ context: 'blockquote',
+
+ allowedContent: 'blockquote',
+ requiredContent: 'blockquote'
+ };
+
+ CKEDITOR.plugins.add( 'blockquote', {
+ // jscs:disable maximumLineLength
+ lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
+ // jscs:enable maximumLineLength
+ icons: 'blockquote', // %REMOVE_LINE_CORE%
+ hidpi: true, // %REMOVE_LINE_CORE%
+ init: function( editor ) {
+ if ( editor.blockless )
+ return;
+
+ editor.addCommand( 'blockquote', commandObject );
+
+ editor.ui.addButton && editor.ui.addButton( 'Blockquote', {
+ label: editor.lang.blockquote.toolbar,
+ command: 'blockquote',
+ toolbar: 'blocks,10'
+ } );
+ }
+ } );
+} )();
diff --git a/sources/plugins/button/lang/af.js b/sources/plugins/button/lang/af.js
new file mode 100644
index 00000000..03c8ec2c
--- /dev/null
+++ b/sources/plugins/button/lang/af.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'af', {
+ selectedLabel: '%1 uitgekies'
+} );
diff --git a/sources/plugins/button/lang/ar.js b/sources/plugins/button/lang/ar.js
new file mode 100644
index 00000000..06ac9de3
--- /dev/null
+++ b/sources/plugins/button/lang/ar.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'ar', {
+ selectedLabel: '%1 (محدد)'
+} );
diff --git a/sources/plugins/button/lang/bg.js b/sources/plugins/button/lang/bg.js
new file mode 100644
index 00000000..11b356ee
--- /dev/null
+++ b/sources/plugins/button/lang/bg.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'bg', {
+ selectedLabel: '%1 (Избрано)'
+} );
diff --git a/sources/plugins/button/lang/ca.js b/sources/plugins/button/lang/ca.js
new file mode 100644
index 00000000..9b0aadac
--- /dev/null
+++ b/sources/plugins/button/lang/ca.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'ca', {
+ selectedLabel: '%1 (Seleccionat)'
+} );
diff --git a/sources/plugins/button/lang/cs.js b/sources/plugins/button/lang/cs.js
new file mode 100644
index 00000000..172f712a
--- /dev/null
+++ b/sources/plugins/button/lang/cs.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'cs', {
+ selectedLabel: '%1 (Vybráno)'
+} );
diff --git a/sources/plugins/button/lang/da.js b/sources/plugins/button/lang/da.js
new file mode 100644
index 00000000..16f2f6bf
--- /dev/null
+++ b/sources/plugins/button/lang/da.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'da', {
+ selectedLabel: '%1 (Valgt)'
+} );
diff --git a/sources/plugins/button/lang/de.js b/sources/plugins/button/lang/de.js
new file mode 100644
index 00000000..a1c07a0b
--- /dev/null
+++ b/sources/plugins/button/lang/de.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'de', {
+ selectedLabel: '%1 (Ausgewählt)'
+} );
diff --git a/sources/plugins/button/lang/el.js b/sources/plugins/button/lang/el.js
new file mode 100644
index 00000000..37aa384d
--- /dev/null
+++ b/sources/plugins/button/lang/el.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'el', {
+ selectedLabel: '%1 (Επιλεγμένο)'
+} );
diff --git a/sources/plugins/button/lang/en-gb.js b/sources/plugins/button/lang/en-gb.js
new file mode 100644
index 00000000..cd7c4a19
--- /dev/null
+++ b/sources/plugins/button/lang/en-gb.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'en-gb', {
+ selectedLabel: '%1 (Selected)'
+} );
diff --git a/sources/plugins/button/lang/en.js b/sources/plugins/button/lang/en.js
new file mode 100644
index 00000000..cb07e4fc
--- /dev/null
+++ b/sources/plugins/button/lang/en.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'en', {
+ selectedLabel: '%1 (Selected)'
+} );
diff --git a/sources/plugins/button/lang/eo.js b/sources/plugins/button/lang/eo.js
new file mode 100644
index 00000000..ef12a0b6
--- /dev/null
+++ b/sources/plugins/button/lang/eo.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'eo', {
+ selectedLabel: '%1 (Selektita)'
+} );
diff --git a/sources/plugins/button/lang/es.js b/sources/plugins/button/lang/es.js
new file mode 100644
index 00000000..0a272085
--- /dev/null
+++ b/sources/plugins/button/lang/es.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'es', {
+ selectedLabel: '%1 (Seleccionado)'
+} );
diff --git a/sources/plugins/button/lang/eu.js b/sources/plugins/button/lang/eu.js
new file mode 100644
index 00000000..d932a7d8
--- /dev/null
+++ b/sources/plugins/button/lang/eu.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'eu', {
+ selectedLabel: '%1 (hautatuta)'
+} );
diff --git a/sources/plugins/button/lang/fa.js b/sources/plugins/button/lang/fa.js
new file mode 100644
index 00000000..73d37e66
--- /dev/null
+++ b/sources/plugins/button/lang/fa.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'fa', {
+ selectedLabel: '%1 (انتخاب شده)'
+} );
diff --git a/sources/plugins/button/lang/fi.js b/sources/plugins/button/lang/fi.js
new file mode 100644
index 00000000..dd706fa1
--- /dev/null
+++ b/sources/plugins/button/lang/fi.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'fi', {
+ selectedLabel: '%1 (Valittu)'
+} );
diff --git a/sources/plugins/button/lang/fr.js b/sources/plugins/button/lang/fr.js
new file mode 100644
index 00000000..86dd735d
--- /dev/null
+++ b/sources/plugins/button/lang/fr.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'fr', {
+ selectedLabel: '%1 (Sélectionné)'
+} );
diff --git a/sources/plugins/button/lang/gl.js b/sources/plugins/button/lang/gl.js
new file mode 100644
index 00000000..f34d2f3f
--- /dev/null
+++ b/sources/plugins/button/lang/gl.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'gl', {
+ selectedLabel: '%1 (seleccionado)'
+} );
diff --git a/sources/plugins/button/lang/he.js b/sources/plugins/button/lang/he.js
new file mode 100644
index 00000000..5911f30f
--- /dev/null
+++ b/sources/plugins/button/lang/he.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'he', {
+ selectedLabel: '1% (סומן)'
+} );
diff --git a/sources/plugins/button/lang/hu.js b/sources/plugins/button/lang/hu.js
new file mode 100644
index 00000000..ecfbf0ae
--- /dev/null
+++ b/sources/plugins/button/lang/hu.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'hu', {
+ selectedLabel: '%1 (Kiválasztva)'
+} );
diff --git a/sources/plugins/button/lang/id.js b/sources/plugins/button/lang/id.js
new file mode 100644
index 00000000..29d04a0a
--- /dev/null
+++ b/sources/plugins/button/lang/id.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'id', {
+ selectedLabel: '%1(Dipilih)'
+} );
diff --git a/sources/plugins/button/lang/it.js b/sources/plugins/button/lang/it.js
new file mode 100644
index 00000000..e563591e
--- /dev/null
+++ b/sources/plugins/button/lang/it.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'it', {
+ selectedLabel: '%1 (selezionato)'
+} );
diff --git a/sources/plugins/button/lang/ja.js b/sources/plugins/button/lang/ja.js
new file mode 100644
index 00000000..fdac0604
--- /dev/null
+++ b/sources/plugins/button/lang/ja.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'ja', {
+ selectedLabel: '%1 (選択中)'
+} );
diff --git a/sources/plugins/button/lang/km.js b/sources/plugins/button/lang/km.js
new file mode 100644
index 00000000..830061fb
--- /dev/null
+++ b/sources/plugins/button/lang/km.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'km', {
+ selectedLabel: '%1 (បានជ្រើសរើស)'
+} );
diff --git a/sources/plugins/button/lang/ko.js b/sources/plugins/button/lang/ko.js
new file mode 100644
index 00000000..ed1ecc2e
--- /dev/null
+++ b/sources/plugins/button/lang/ko.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'ko', {
+ selectedLabel: '%1 (선택됨)'
+} );
diff --git a/sources/plugins/button/lang/ku.js b/sources/plugins/button/lang/ku.js
new file mode 100644
index 00000000..9920be19
--- /dev/null
+++ b/sources/plugins/button/lang/ku.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'ku', {
+ selectedLabel: '%1 (هەڵبژێردراو)'
+} );
diff --git a/sources/plugins/button/lang/lt.js b/sources/plugins/button/lang/lt.js
new file mode 100644
index 00000000..1f30aa94
--- /dev/null
+++ b/sources/plugins/button/lang/lt.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'lt', {
+ selectedLabel: '%1 (Pasirinkta)'
+} );
diff --git a/sources/plugins/button/lang/nb.js b/sources/plugins/button/lang/nb.js
new file mode 100644
index 00000000..2d866303
--- /dev/null
+++ b/sources/plugins/button/lang/nb.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'nb', {
+ selectedLabel: '%1 (Valgt)'
+} );
diff --git a/sources/plugins/button/lang/nl.js b/sources/plugins/button/lang/nl.js
new file mode 100644
index 00000000..c750f638
--- /dev/null
+++ b/sources/plugins/button/lang/nl.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'nl', {
+ selectedLabel: '%1 (Geselecteerd)'
+} );
diff --git a/sources/plugins/button/lang/pl.js b/sources/plugins/button/lang/pl.js
new file mode 100644
index 00000000..661f372a
--- /dev/null
+++ b/sources/plugins/button/lang/pl.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'pl', {
+ selectedLabel: '%1 (Wybrany)'
+} );
diff --git a/sources/plugins/button/lang/pt-br.js b/sources/plugins/button/lang/pt-br.js
new file mode 100644
index 00000000..18c09381
--- /dev/null
+++ b/sources/plugins/button/lang/pt-br.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'pt-br', {
+ selectedLabel: '%1 (Selecionado)'
+} );
diff --git a/sources/plugins/button/lang/pt.js b/sources/plugins/button/lang/pt.js
new file mode 100644
index 00000000..af7e673d
--- /dev/null
+++ b/sources/plugins/button/lang/pt.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'pt', {
+ selectedLabel: '%1 (Selecionado)'
+} );
diff --git a/sources/plugins/button/lang/ro.js b/sources/plugins/button/lang/ro.js
new file mode 100644
index 00000000..44dee158
--- /dev/null
+++ b/sources/plugins/button/lang/ro.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'ro', {
+ selectedLabel: '%1 (Selectat)'
+} );
diff --git a/sources/plugins/button/lang/ru.js b/sources/plugins/button/lang/ru.js
new file mode 100644
index 00000000..bbfa42be
--- /dev/null
+++ b/sources/plugins/button/lang/ru.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'ru', {
+ selectedLabel: '%1 (Выбрано)'
+} );
diff --git a/sources/plugins/button/lang/sk.js b/sources/plugins/button/lang/sk.js
new file mode 100644
index 00000000..b4f35aa8
--- /dev/null
+++ b/sources/plugins/button/lang/sk.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'sk', {
+ selectedLabel: '%1 (Vybrané)'
+} );
diff --git a/sources/plugins/button/lang/sl.js b/sources/plugins/button/lang/sl.js
new file mode 100644
index 00000000..4faf3c55
--- /dev/null
+++ b/sources/plugins/button/lang/sl.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'sl', {
+ selectedLabel: '%1 (Izbrano)'
+} );
diff --git a/sources/plugins/button/lang/sq.js b/sources/plugins/button/lang/sq.js
new file mode 100644
index 00000000..e67b12ad
--- /dev/null
+++ b/sources/plugins/button/lang/sq.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'sq', {
+ selectedLabel: '%1 (Përzgjedhur)'
+} );
diff --git a/sources/plugins/button/lang/sv.js b/sources/plugins/button/lang/sv.js
new file mode 100644
index 00000000..9e714be3
--- /dev/null
+++ b/sources/plugins/button/lang/sv.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'sv', {
+ selectedLabel: '%1 (Vald)'
+} );
diff --git a/sources/plugins/button/lang/tr.js b/sources/plugins/button/lang/tr.js
new file mode 100644
index 00000000..06ad32b0
--- /dev/null
+++ b/sources/plugins/button/lang/tr.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'tr', {
+ selectedLabel: '%1 (Seçilmiş)'
+} );
diff --git a/sources/plugins/button/lang/tt.js b/sources/plugins/button/lang/tt.js
new file mode 100644
index 00000000..5572afac
--- /dev/null
+++ b/sources/plugins/button/lang/tt.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'tt', {
+ selectedLabel: '%1 (Сайланган)'
+} );
diff --git a/sources/plugins/button/lang/ug.js b/sources/plugins/button/lang/ug.js
new file mode 100644
index 00000000..a2ceef5b
--- /dev/null
+++ b/sources/plugins/button/lang/ug.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'ug', {
+ selectedLabel: '%1 (تاللاندى)'
+} );
diff --git a/sources/plugins/button/lang/uk.js b/sources/plugins/button/lang/uk.js
new file mode 100644
index 00000000..ddec74ae
--- /dev/null
+++ b/sources/plugins/button/lang/uk.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'uk', {
+ selectedLabel: '%1 (Вибрано)'
+} );
diff --git a/sources/plugins/button/lang/vi.js b/sources/plugins/button/lang/vi.js
new file mode 100644
index 00000000..7a7adc01
--- /dev/null
+++ b/sources/plugins/button/lang/vi.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'vi', {
+ selectedLabel: '%1 (Đã chọn)'
+} );
diff --git a/sources/plugins/button/lang/zh-cn.js b/sources/plugins/button/lang/zh-cn.js
new file mode 100644
index 00000000..726a3dc7
--- /dev/null
+++ b/sources/plugins/button/lang/zh-cn.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'zh-cn', {
+ selectedLabel: '已选中 %1 项'
+} );
diff --git a/sources/plugins/button/lang/zh.js b/sources/plugins/button/lang/zh.js
new file mode 100644
index 00000000..95949474
--- /dev/null
+++ b/sources/plugins/button/lang/zh.js
@@ -0,0 +1,8 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.plugins.setLang( 'button', 'zh', {
+ selectedLabel: '%1 (已選取)'
+} );
diff --git a/sources/plugins/button/plugin.js b/sources/plugins/button/plugin.js
new file mode 100644
index 00000000..2338229c
--- /dev/null
+++ b/sources/plugins/button/plugin.js
@@ -0,0 +1,377 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+ var template = '' +
+ '{label}' +
+ '{arrowHtml}' +
+ '';
+
+ var templateArrow = ' ' +
+ ' ';
+
+ var btnArrowTpl = CKEDITOR.addTemplate( 'buttonArrow', templateArrow ),
+ btnTpl = CKEDITOR.addTemplate( 'button', template );
+
+ CKEDITOR.plugins.add( 'button', {
+ lang: 'af,ar,bg,ca,cs,da,de,el,en,en-gb,eo,es,eu,fa,fi,fr,gl,he,hu,id,it,ja,km,ko,ku,lt,nb,nl,pl,pt,pt-br,ro,ru,sk,sl,sq,sv,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
+ beforeInit: function( editor ) {
+ editor.ui.addHandler( CKEDITOR.UI_BUTTON, CKEDITOR.ui.button.handler );
+ }
+ } );
+
+ /**
+ * Button UI element.
+ *
+ * @readonly
+ * @property {String} [='button']
+ * @member CKEDITOR
+ */
+ CKEDITOR.UI_BUTTON = 'button';
+
+ /**
+ * Represents a button UI element. This class should not be called directly. To
+ * create new buttons use {@link CKEDITOR.ui#addButton} instead.
+ *
+ * @class
+ * @constructor Creates a button class instance.
+ * @param {Object} definition The button definition.
+ */
+ CKEDITOR.ui.button = function( definition ) {
+ CKEDITOR.tools.extend( this, definition,
+ // Set defaults.
+ {
+ title: definition.label,
+ click: definition.click ||
+ function( editor ) {
+ editor.execCommand( definition.command );
+ }
+ } );
+
+ this._ = {};
+ };
+
+ /**
+ * Represents the button handler object.
+ *
+ * @class
+ * @singleton
+ * @extends CKEDITOR.ui.handlerDefinition
+ */
+ CKEDITOR.ui.button.handler = {
+ /**
+ * Transforms a button definition in a {@link CKEDITOR.ui.button} instance.
+ *
+ * @member CKEDITOR.ui.button.handler
+ * @param {Object} definition
+ * @returns {CKEDITOR.ui.button}
+ */
+ create: function( definition ) {
+ return new CKEDITOR.ui.button( definition );
+ }
+ };
+
+ /** @class CKEDITOR.ui.button */
+ CKEDITOR.ui.button.prototype = {
+ /**
+ * Renders the button.
+ *
+ * @param {CKEDITOR.editor} editor The editor instance which this button is
+ * to be used by.
+ * @param {Array} output The output array to which the HTML code related to
+ * this button should be appended.
+ */
+ render: function( editor, output ) {
+ function updateState() {
+ // "this" is a CKEDITOR.ui.button instance.
+ var mode = editor.mode;
+
+ if ( mode ) {
+ // Restore saved button state.
+ var state = this.modes[ mode ] ? modeStates[ mode ] !== undefined ? modeStates[ mode ] : CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;
+
+ state = editor.readOnly && !this.readOnly ? CKEDITOR.TRISTATE_DISABLED : state;
+
+ this.setState( state );
+
+ // Let plugin to disable button.
+ if ( this.refresh )
+ this.refresh();
+ }
+ }
+
+ var env = CKEDITOR.env,
+ id = this._.id = CKEDITOR.tools.getNextId(),
+ stateName = '',
+ command = this.command,
+ // Get the command name.
+ clickFn;
+
+ this._.editor = editor;
+
+ var instance = {
+ id: id,
+ button: this,
+ editor: editor,
+ focus: function() {
+ var element = CKEDITOR.document.getById( id );
+ element.focus();
+ },
+ execute: function() {
+ this.button.click( editor );
+ },
+ attach: function( editor ) {
+ this.button.attach( editor );
+ }
+ };
+
+ var keydownFn = CKEDITOR.tools.addFunction( function( ev ) {
+ if ( instance.onkey ) {
+ ev = new CKEDITOR.dom.event( ev );
+ return ( instance.onkey( instance, ev.getKeystroke() ) !== false );
+ }
+ } );
+
+ var focusFn = CKEDITOR.tools.addFunction( function( ev ) {
+ var retVal;
+
+ if ( instance.onfocus )
+ retVal = ( instance.onfocus( instance, new CKEDITOR.dom.event( ev ) ) !== false );
+
+ return retVal;
+ } );
+
+ var selLocked = 0;
+
+ instance.clickFn = clickFn = CKEDITOR.tools.addFunction( function() {
+
+ // Restore locked selection in Opera.
+ if ( selLocked ) {
+ editor.unlockSelection( 1 );
+ selLocked = 0;
+ }
+ instance.execute();
+
+ // Fixed iOS focus issue when your press disabled button (#12381).
+ if ( env.iOS ) {
+ editor.focus();
+ }
+ } );
+
+
+ // Indicate a mode sensitive button.
+ if ( this.modes ) {
+ var modeStates = {};
+
+ editor.on( 'beforeModeUnload', function() {
+ if ( editor.mode && this._.state != CKEDITOR.TRISTATE_DISABLED )
+ modeStates[ editor.mode ] = this._.state;
+ }, this );
+
+ // Update status when activeFilter, mode or readOnly changes.
+ editor.on( 'activeFilterChange', updateState, this );
+ editor.on( 'mode', updateState, this );
+ // If this button is sensitive to readOnly state, update it accordingly.
+ !this.readOnly && editor.on( 'readOnly', updateState, this );
+
+ } else if ( command ) {
+ // Get the command instance.
+ command = editor.getCommand( command );
+
+ if ( command ) {
+ command.on( 'state', function() {
+ this.setState( command.state );
+ }, this );
+
+ stateName += ( command.state == CKEDITOR.TRISTATE_ON ? 'on' : command.state == CKEDITOR.TRISTATE_DISABLED ? 'disabled' : 'off' );
+ }
+ }
+
+ // For button that has text-direction awareness on selection path.
+ if ( this.directional ) {
+ editor.on( 'contentDirChanged', function( evt ) {
+ var el = CKEDITOR.document.getById( this._.id ),
+ icon = el.getFirst();
+
+ var pathDir = evt.data;
+
+ // Make a minor direction change to become style-able for the skin icon.
+ if ( pathDir != editor.lang.dir )
+ el.addClass( 'cke_' + pathDir );
+ else
+ el.removeClass( 'cke_ltr' ).removeClass( 'cke_rtl' );
+
+ // Inline style update for the plugin icon.
+ icon.setAttribute( 'style', CKEDITOR.skin.getIconStyle( iconName, pathDir == 'rtl', this.icon, this.iconOffset ) );
+ }, this );
+ }
+
+ if ( !command )
+ stateName += 'off';
+
+ var name = this.name || this.command,
+ iconName = name;
+
+ // Check if we're pointing to an icon defined by another command. (#9555)
+ if ( this.icon && !( /\./ ).test( this.icon ) ) {
+ iconName = this.icon;
+ this.icon = null;
+ }
+
+ var params = {
+ id: id,
+ name: name,
+ iconName: iconName,
+ label: this.label,
+ cls: this.className || '',
+ state: stateName,
+ ariaDisabled: stateName == 'disabled' ? 'true' : 'false',
+ title: this.title,
+ titleJs: env.gecko && !env.hc ? '' : ( this.title || '' ).replace( "'", '' ),
+ hasArrow: this.hasArrow ? 'true' : 'false',
+ keydownFn: keydownFn,
+ focusFn: focusFn,
+ clickFn: clickFn,
+ style: CKEDITOR.skin.getIconStyle( iconName, ( editor.lang.dir == 'rtl' ), this.icon, this.iconOffset ),
+ arrowHtml: this.hasArrow ? btnArrowTpl.output() : ''
+ };
+
+ btnTpl.output( params, output );
+
+ if ( this.onRender )
+ this.onRender();
+
+ return instance;
+ },
+
+ /**
+ * Sets the button state.
+ *
+ * @param {Number} state Indicates the button state. One of {@link CKEDITOR#TRISTATE_ON},
+ * {@link CKEDITOR#TRISTATE_OFF}, or {@link CKEDITOR#TRISTATE_DISABLED}.
+ */
+ setState: function( state ) {
+ if ( this._.state == state )
+ return false;
+
+ this._.state = state;
+
+ var element = CKEDITOR.document.getById( this._.id );
+
+ if ( element ) {
+ element.setState( state, 'cke_button' );
+
+ state == CKEDITOR.TRISTATE_DISABLED ?
+ element.setAttribute( 'aria-disabled', true ) :
+ element.removeAttribute( 'aria-disabled' );
+
+ if ( !this.hasArrow ) {
+ // Note: aria-pressed attribute should not be added to menuButton instances. (#11331)
+ state == CKEDITOR.TRISTATE_ON ?
+ element.setAttribute( 'aria-pressed', true ) :
+ element.removeAttribute( 'aria-pressed' );
+ } else {
+ var newLabel = state == CKEDITOR.TRISTATE_ON ?
+ this._.editor.lang.button.selectedLabel.replace( /%1/g, this.label ) : this.label;
+ CKEDITOR.document.getById( this._.id + '_label' ).setText( newLabel );
+ }
+
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ /**
+ * Gets the button state.
+ *
+ * @returns {Number} The button state. One of {@link CKEDITOR#TRISTATE_ON},
+ * {@link CKEDITOR#TRISTATE_OFF}, or {@link CKEDITOR#TRISTATE_DISABLED}.
+ */
+ getState: function() {
+ return this._.state;
+ },
+
+ /**
+ * Returns this button's {@link CKEDITOR.feature} instance.
+ *
+ * It may be this button instance if it has at least one of
+ * `allowedContent` and `requiredContent` properties. Otherwise,
+ * if a command is bound to this button by the `command` property, then
+ * that command will be returned.
+ *
+ * This method implements the {@link CKEDITOR.feature#toFeature} interface method.
+ *
+ * @since 4.1
+ * @param {CKEDITOR.editor} Editor instance.
+ * @returns {CKEDITOR.feature} The feature.
+ */
+ toFeature: function( editor ) {
+ if ( this._.feature )
+ return this._.feature;
+
+ var feature = this;
+
+ // If button isn't a feature, return command if is bound.
+ if ( !this.allowedContent && !this.requiredContent && this.command )
+ feature = editor.getCommand( this.command ) || feature;
+
+ return this._.feature = feature;
+ }
+ };
+
+ /**
+ * Adds a button definition to the UI elements list.
+ *
+ * editorInstance.ui.addButton( 'MyBold', {
+ * label: 'My Bold',
+ * command: 'bold',
+ * toolbar: 'basicstyles,1'
+ * } );
+ *
+ * @member CKEDITOR.ui
+ * @param {String} name The button name.
+ * @param {Object} definition The button definition.
+ * @param {String} definition.label The textual part of the button (if visible) and its tooltip.
+ * @param {String} definition.command The command to be executed once the button is activated.
+ * @param {String} definition.toolbar The {@link CKEDITOR.config#toolbarGroups toolbar group} into which
+ * the button will be added. An optional index value (separated by a comma) determines the button position within the group.
+ */
+ CKEDITOR.ui.prototype.addButton = function( name, definition ) {
+ this.add( name, CKEDITOR.UI_BUTTON, definition );
+ };
+
+} )();
diff --git a/sources/plugins/clipboard/dev/clipboard.html b/sources/plugins/clipboard/dev/clipboard.html
new file mode 100644
index 00000000..00a073f8
--- /dev/null
+++ b/sources/plugins/clipboard/dev/clipboard.html
@@ -0,0 +1,190 @@
+
+
+
+
+
+
+ CKEditor Sample — clipboard plugin playground
+
+ Editor 6
+ .someClass
.' +
+ '
',
+
+ refresh: function() {
+ return {
+ header: 'Paste',
+ type: pasteType,
+ value: pasteValue
+ };
+ },
+
+ refreshOn: function( editor, refresh ) {
+ editor.on( 'paste', function( evt ) {
+ pasteType = evt.data.type;
+ pasteValue = CKEDITOR.tools.htmlEncode( evt.data.dataValue );
+ refresh();
+ } );
+ }
+ },
+ {
+ type: 'log',
+ on: function( editor, log, logFn ) {
+ editor.on( 'paste', function( evt ) {
+ logFn( 'paste; type:' + evt.data.type )();
+ } );
+ }
+ }
+ ]
+ } );
+} )();
diff --git a/sources/plugins/clipboard/dev/dnd.html b/sources/plugins/clipboard/dev/dnd.html
new file mode 100644
index 00000000..3a1845d1
--- /dev/null
+++ b/sources/plugins/clipboard/dev/dnd.html
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+ Manual test for #11460
+
+ Description (hide/show)
+ Expected behavior:
+
+
+ Drag scenarios:
+
+
+ Drop scenarios:
+
+
+ Known issues (not part of this ticket):
+
+
+ Helpers (hide/show)
+
+Aenean cursus egestas ipsum.
+
+ Classic editor (hide/show)
+ Inline editor (hide/show)
+
+
+ Apollo 11
three and a half two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5 kg) of lunar material for return to Earth. A third member of the mission, Michael Collins, piloted the command spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.Broadcasting and quotes
+
+
+
+
+
+
+
+ Technical details
+
+
+
+
+
+
+
+
+ Position
+ Astronaut
+
+
+ Commander
+ Neil A. Armstrong
+
+
+ Command Module Pilot
+ Michael Collins
+
+
+
+ Lunar Module Pilot
+ Edwin "Buzz" E. Aldrin, Jr.
+
+
+
+
+
Brug i stedet tastaturet til at kopiere teksten (Ctrl/Cmd+C).',
+ cut: 'Klip',
+ cutError: 'Din browsers sikkerhedsindstillinger tillader ikke editoren at få automatisk adgang til udklipsholderen.
Brug i stedet tastaturet til at klippe teksten (Ctrl/Cmd+X).',
+ paste: 'Indsæt',
+ pasteArea: 'Indsæt område',
+ pasteMsg: 'Indsæt i feltet herunder (Ctrl/Cmd+V) og klik på OK.',
+ securityMsg: 'Din browsers sikkerhedsindstillinger tillader ikke editoren at få automatisk adgang til udklipsholderen.
Du skal indsætte udklipsholderens indhold i dette vindue igen.',
+ title: 'Indsæt'
+} );
diff --git a/sources/plugins/clipboard/lang/de.js b/sources/plugins/clipboard/lang/de.js
new file mode 100644
index 00000000..baeb6528
--- /dev/null
+++ b/sources/plugins/clipboard/lang/de.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'de', {
+ copy: 'Kopieren',
+ copyError: 'Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch kopieren. Bitte benutzen Sie die System-Zwischenablage über STRG-C (kopieren).',
+ cut: 'Ausschneiden',
+ cutError: 'Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch auszuschneiden. Bitte benutzen Sie die System-Zwischenablage über STRG-X (ausschneiden) und STRG-V (einfügen).',
+ paste: 'Einfügen',
+ pasteArea: 'Einfügebereich',
+ pasteMsg: 'Bitte fügen Sie den Text in der folgenden Box über die Tastatur (mit Strg+V) ein und bestätigen Sie mit OK.',
+ securityMsg: 'Aufgrund von Sicherheitsbeschränkungen Ihres Browsers kann der Editor nicht direkt auf die Zwischenablage zugreifen. Bitte fügen Sie den Inhalt erneut in diesem Fenster ein.',
+ title: 'Einfügen'
+} );
diff --git a/sources/plugins/clipboard/lang/el.js b/sources/plugins/clipboard/lang/el.js
new file mode 100644
index 00000000..57158663
--- /dev/null
+++ b/sources/plugins/clipboard/lang/el.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'el', {
+ copy: 'Αντιγραφή',
+ copyError: 'Οι ρυθμίσεις ασφαλείας του περιηγητή σας δεν επιτρέπουν την επιλεγμένη εργασία αντιγραφής. Παρακαλώ χρησιμοποιείστε το πληκτρολόγιο (Ctrl/Cmd+C).',
+ cut: 'Αποκοπή',
+ cutError: 'Οι ρυθμίσεις ασφαλείας του περιηγητή σας δεν επιτρέπουν την επιλεγμένη εργασία αποκοπής. Παρακαλώ χρησιμοποιείστε το πληκτρολόγιο (Ctrl/Cmd+X).',
+ paste: 'Επικόλληση',
+ pasteArea: 'Περιοχή Επικόλλησης',
+ pasteMsg: 'Παρακαλώ επικολλήστε στο ακόλουθο κουτί χρησιμοποιώντας το πληκτρολόγιο (Ctrl/Cmd+V) και πατήστε OK.',
+ securityMsg: 'Λόγων των ρυθμίσεων ασφάλειας του περιηγητή σας, ο επεξεργαστής δεν μπορεί να έχει πρόσβαση στην μνήμη επικόλλησης. Χρειάζεται να επικολλήσετε ξανά σε αυτό το παράθυρο.',
+ title: 'Επικόλληση'
+} );
diff --git a/sources/plugins/clipboard/lang/en-au.js b/sources/plugins/clipboard/lang/en-au.js
new file mode 100644
index 00000000..6c895f82
--- /dev/null
+++ b/sources/plugins/clipboard/lang/en-au.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'en-au', {
+ copy: 'Copy',
+ copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).',
+ cut: 'Cut',
+ cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).',
+ paste: 'Paste',
+ pasteArea: 'Paste Area', // MISSING
+ pasteMsg: 'Please paste inside the following box using the keyboard (Ctrl/Cmd+V) and hit OK',
+ securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.',
+ title: 'Paste'
+} );
diff --git a/sources/plugins/clipboard/lang/en-ca.js b/sources/plugins/clipboard/lang/en-ca.js
new file mode 100644
index 00000000..4f1220e0
--- /dev/null
+++ b/sources/plugins/clipboard/lang/en-ca.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'en-ca', {
+ copy: 'Copy',
+ copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).',
+ cut: 'Cut',
+ cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).',
+ paste: 'Paste',
+ pasteArea: 'Paste Area', // MISSING
+ pasteMsg: 'Please paste inside the following box using the keyboard (Ctrl/Cmd+V) and hit OK',
+ securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.',
+ title: 'Paste'
+} );
diff --git a/sources/plugins/clipboard/lang/en-gb.js b/sources/plugins/clipboard/lang/en-gb.js
new file mode 100644
index 00000000..a460489e
--- /dev/null
+++ b/sources/plugins/clipboard/lang/en-gb.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'en-gb', {
+ copy: 'Copy',
+ copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).',
+ cut: 'Cut',
+ cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).',
+ paste: 'Paste',
+ pasteArea: 'Paste Area',
+ pasteMsg: 'Please paste inside the following box using the keyboard (Ctrl/Cmd+V) and hit OK',
+ securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.',
+ title: 'Paste'
+} );
diff --git a/sources/plugins/clipboard/lang/en.js b/sources/plugins/clipboard/lang/en.js
new file mode 100644
index 00000000..db5dd596
--- /dev/null
+++ b/sources/plugins/clipboard/lang/en.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'en', {
+ copy: 'Copy',
+ copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).',
+ cut: 'Cut',
+ cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).',
+ paste: 'Paste',
+ pasteArea: 'Paste Area',
+ pasteMsg: 'Please paste inside the following box using the keyboard (Ctrl/Cmd+V) and hit OK',
+ securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.',
+ title: 'Paste'
+} );
diff --git a/sources/plugins/clipboard/lang/eo.js b/sources/plugins/clipboard/lang/eo.js
new file mode 100644
index 00000000..55a62ef3
--- /dev/null
+++ b/sources/plugins/clipboard/lang/eo.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'eo', {
+ copy: 'Kopii',
+ copyError: 'La sekurecagordo de via TTT-legilo ne permesas, ke la redaktilo faras kopiajn operaciojn. Bonvolu uzi la klavaron por tio (Ctrl/Cmd-C).',
+ cut: 'Eltondi',
+ cutError: 'La sekurecagordo de via TTT-legilo ne permesas, ke la redaktilo faras eltondajn operaciojn. Bonvolu uzi la klavaron por tio (Ctrl/Cmd-X).',
+ paste: 'Interglui',
+ pasteArea: 'Intergluoareo',
+ pasteMsg: 'Bonvolu glui la tekston en la jenan areon per uzado de la klavaro (Ctrl/Cmd+V) kaj premu OK',
+ securityMsg: 'Pro la sekurecagordo de via TTT-legilo, la redaktilo ne povas rekte atingi viajn datenojn en la poŝo. Bonvolu denove interglui la datenojn en tiun fenestron.',
+ title: 'Interglui'
+} );
diff --git a/sources/plugins/clipboard/lang/es.js b/sources/plugins/clipboard/lang/es.js
new file mode 100644
index 00000000..346265af
--- /dev/null
+++ b/sources/plugins/clipboard/lang/es.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'es', {
+ copy: 'Copiar',
+ copyError: 'La configuración de seguridad de este navegador no permite la ejecución automática de operaciones de copiado.\r\nPor favor use el teclado (Ctrl/Cmd+C).',
+ cut: 'Cortar',
+ cutError: 'La configuración de seguridad de este navegador no permite la ejecución automática de operaciones de cortado.\r\nPor favor use el teclado (Ctrl/Cmd+X).',
+ paste: 'Pegar',
+ pasteArea: 'Zona de pegado',
+ pasteMsg: 'Por favor pegue dentro del cuadro utilizando el teclado (Ctrl/Cmd+V);\r\nluego presione Aceptar.',
+ securityMsg: 'Debido a la configuración de seguridad de su navegador, el editor no tiene acceso al portapapeles.\r\nEs necesario que lo pegue de nuevo en esta ventana.',
+ title: 'Pegar'
+} );
diff --git a/sources/plugins/clipboard/lang/et.js b/sources/plugins/clipboard/lang/et.js
new file mode 100644
index 00000000..34dc3bc7
--- /dev/null
+++ b/sources/plugins/clipboard/lang/et.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'et', {
+ copy: 'Kopeeri',
+ copyError: 'Sinu veebisirvija turvaseaded ei luba redaktoril automaatselt kopeerida. Palun kasutage selleks klaviatuuri klahvikombinatsiooni (Ctrl/Cmd+C).',
+ cut: 'Lõika',
+ cutError: 'Sinu veebisirvija turvaseaded ei luba redaktoril automaatselt lõigata. Palun kasutage selleks klaviatuuri klahvikombinatsiooni (Ctrl/Cmd+X).',
+ paste: 'Aseta',
+ pasteArea: 'Asetamise ala',
+ pasteMsg: 'Palun aseta tekst järgnevasse kasti kasutades klaviatuuri klahvikombinatsiooni (Ctrl/Cmd+V) ja vajuta seejärel OK.',
+ securityMsg: 'Sinu veebisirvija turvaseadete tõttu ei oma redaktor otsest ligipääsu lõikelaua andmetele. Sa pead asetama need uuesti siia aknasse.',
+ title: 'Asetamine'
+} );
diff --git a/sources/plugins/clipboard/lang/eu.js b/sources/plugins/clipboard/lang/eu.js
new file mode 100644
index 00000000..6683130a
--- /dev/null
+++ b/sources/plugins/clipboard/lang/eu.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'eu', {
+ copy: 'Kopiatu',
+ copyError: 'Zure web nabigatzailearen segurtasun ezarpenek ez dute baimentzen testuak automatikoki kopiatzea. Mesedez teklatua erabil ezazu (Ctrl/Cmd+C).',
+ cut: 'Ebaki',
+ cutError: 'Zure web nabigatzailearen segurtasun ezarpenek ez dute baimentzen testuak automatikoki moztea. Mesedez teklatua erabil ezazu (Ctrl/Cmd+X).',
+ paste: 'Itsatsi',
+ pasteArea: 'Itsasteko area',
+ pasteMsg: 'Mesedez teklatua erabiliz (Ctrl/Cmd+V) ondorengo eremuan testua itsatsi eta sakatu Ados.',
+ securityMsg: 'Nabigatzailearen segurtasun ezarpenak direla eta, editoreak ezin du arbela zuzenean erabili. Leiho honetan berriro itsatsi behar duzu.',
+ title: 'Itsatsi'
+} );
diff --git a/sources/plugins/clipboard/lang/fa.js b/sources/plugins/clipboard/lang/fa.js
new file mode 100644
index 00000000..2bf8ae48
--- /dev/null
+++ b/sources/plugins/clipboard/lang/fa.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'fa', {
+ copy: 'رونوشت',
+ copyError: 'تنظیمات امنیتی مرورگر شما اجازه نمیدهد که ویرایشگر به طور خودکار عملکردهای کپی کردن را انجام دهد. لطفا با دکمههای صفحه کلید این کار را انجام دهید (Ctrl/Cmd+C).',
+ cut: 'برش',
+ cutError: 'تنظیمات امنیتی مرورگر شما اجازه نمیدهد که ویرایشگر به طور خودکار عملکردهای برش را انجام دهد. لطفا با دکمههای صفحه کلید این کار را انجام دهید (Ctrl/Cmd+X).',
+ paste: 'چسباندن',
+ pasteArea: 'محل چسباندن',
+ pasteMsg: 'لطفا متن را با کلیدهای (Ctrl/Cmd+V) در این جعبهٴ متنی بچسبانید و پذیرش را بزنید.',
+ securityMsg: 'به خاطر تنظیمات امنیتی مرورگر شما، ویرایشگر نمیتواند دسترسی مستقیم به دادههای clipboard داشته باشد. شما باید دوباره آنرا در این پنجره بچسبانید.',
+ title: 'چسباندن'
+} );
diff --git a/sources/plugins/clipboard/lang/fi.js b/sources/plugins/clipboard/lang/fi.js
new file mode 100644
index 00000000..60f63956
--- /dev/null
+++ b/sources/plugins/clipboard/lang/fi.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'fi', {
+ copy: 'Kopioi',
+ copyError: 'Selaimesi turva-asetukset eivät salli editorin toteuttaa kopioimista. Käytä näppäimistöä kopioimiseen (Ctrl+C).',
+ cut: 'Leikkaa',
+ cutError: 'Selaimesi turva-asetukset eivät salli editorin toteuttaa leikkaamista. Käytä näppäimistöä leikkaamiseen (Ctrl+X).',
+ paste: 'Liitä',
+ pasteArea: 'Leikealue',
+ pasteMsg: 'Liitä painamalla (Ctrl+V) ja painamalla OK.',
+ securityMsg: 'Selaimesi turva-asetukset eivät salli editorin käyttää leikepöytää suoraan. Sinun pitää suorittaa liittäminen tässä ikkunassa.',
+ title: 'Liitä'
+} );
diff --git a/sources/plugins/clipboard/lang/fo.js b/sources/plugins/clipboard/lang/fo.js
new file mode 100644
index 00000000..1298d096
--- /dev/null
+++ b/sources/plugins/clipboard/lang/fo.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'fo', {
+ copy: 'Avrita',
+ copyError: 'Trygdaruppseting alnótskagans forðar tekstviðgeranum í at avrita tekstin. Vinarliga nýt knappaborðið til at avrita tekstin (Ctrl/Cmd+C).',
+ cut: 'Kvett',
+ cutError: 'Trygdaruppseting alnótskagans forðar tekstviðgeranum í at kvetta tekstin. Vinarliga nýt knappaborðið til at kvetta tekstin (Ctrl/Cmd+X).',
+ paste: 'Innrita',
+ pasteArea: 'Avritingarumráði',
+ pasteMsg: 'Vinarliga koyr tekstin í hendan rútin við knappaborðinum (Ctrl/Cmd+V) og klikk á Góðtak.',
+ securityMsg: 'Trygdaruppseting alnótskagans forðar tekstviðgeranum í beinleiðis atgongd til avritingarminnið. Tygum mugu royna aftur í hesum rútinum.',
+ title: 'Innrita'
+} );
diff --git a/sources/plugins/clipboard/lang/fr-ca.js b/sources/plugins/clipboard/lang/fr-ca.js
new file mode 100644
index 00000000..2c01ed4e
--- /dev/null
+++ b/sources/plugins/clipboard/lang/fr-ca.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'fr-ca', {
+ copy: 'Copier',
+ copyError: 'Les paramètres de sécurité de votre navigateur empêchent l\'éditeur de copier automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl/Cmd+C).',
+ cut: 'Couper',
+ cutError: 'Les paramètres de sécurité de votre navigateur empêchent l\'éditeur de couper automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl/Cmd+X).',
+ paste: 'Coller',
+ pasteArea: 'Coller la zone',
+ pasteMsg: 'Veuillez coller dans la zone ci-dessous en utilisant le clavier (Ctrl/Cmd+V) et appuyer sur OK.',
+ securityMsg: 'A cause des paramètres de sécurité de votre navigateur, l\'éditeur ne peut accéder au presse-papier directement. Vous devez coller à nouveau le contenu dans cette fenêtre.',
+ title: 'Coller'
+} );
diff --git a/sources/plugins/clipboard/lang/fr.js b/sources/plugins/clipboard/lang/fr.js
new file mode 100644
index 00000000..a8dc5f9e
--- /dev/null
+++ b/sources/plugins/clipboard/lang/fr.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'fr', {
+ copy: 'Copier',
+ copyError: 'Les paramètres de sécurité de votre navigateur ne permettent pas à l\'éditeur d\'exécuter automatiquement des opérations de copie. Veuillez utiliser le raccourci clavier (Ctrl/Cmd+C).',
+ cut: 'Couper',
+ cutError: 'Les paramètres de sécurité de votre navigateur ne permettent pas à l\'éditeur d\'exécuter automatiquement l\'opération "couper". Veuillez utiliser le raccourci clavier (Ctrl/Cmd+X).',
+ paste: 'Coller',
+ pasteArea: 'Coller la zone',
+ pasteMsg: 'Veuillez coller le texte dans la zone suivante en utilisant le raccourci clavier (Ctrl/Cmd+V) et cliquez sur OK.',
+ securityMsg: 'A cause des paramètres de sécurité de votre navigateur, l\'éditeur n\'est pas en mesure d\'accéder directement à vos données contenues dans le presse-papier. Vous devriez réessayer de coller les données dans la fenêtre.',
+ title: 'Coller'
+} );
diff --git a/sources/plugins/clipboard/lang/gl.js b/sources/plugins/clipboard/lang/gl.js
new file mode 100644
index 00000000..7fc6b465
--- /dev/null
+++ b/sources/plugins/clipboard/lang/gl.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'gl', {
+ copy: 'Copiar',
+ copyError: 'Os axustes de seguranza do seu navegador non permiten que o editor realice automaticamente as tarefas de copia. Use o teclado para iso (Ctrl/Cmd+C).',
+ cut: 'Cortar',
+ cutError: 'Os axustes de seguranza do seu navegador non permiten que o editor realice automaticamente as tarefas de corte. Use o teclado para iso (Ctrl/Cmd+X).',
+ paste: 'Pegar',
+ pasteArea: 'Zona de pegado',
+ pasteMsg: 'Pegue dentro do seguinte cadro usando o teclado (Ctrl/Cmd+V) e prema en Aceptar',
+ securityMsg: 'Por mor da configuración de seguranza do seu navegador, o editor non ten acceso ao portapapeis. É necesario pegalo novamente nesta xanela.',
+ title: 'Pegar'
+} );
diff --git a/sources/plugins/clipboard/lang/gu.js b/sources/plugins/clipboard/lang/gu.js
new file mode 100644
index 00000000..a513482f
--- /dev/null
+++ b/sources/plugins/clipboard/lang/gu.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'gu', {
+ copy: 'નકલ',
+ copyError: 'તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસ કોપી કરવાની પરવાનગી નથી આપતી. (Ctrl/Cmd+C) का प्रयोग करें।',
+ cut: 'કાપવું',
+ cutError: 'તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસ કટ કરવાની પરવાનગી નથી આપતી. (Ctrl/Cmd+X) નો ઉપયોગ કરો.',
+ paste: 'પેસ્ટ',
+ pasteArea: 'પેસ્ટ કરવાની જગ્યા',
+ pasteMsg: 'Ctrl/Cmd+V નો પ્રયોગ કરી પેસ્ટ કરો',
+ securityMsg: 'તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસના કારણે,એડિટર તમારા કિલ્પબોર્ડ ડેટા ને કોપી નથી કરી શકતો. તમારે આ વિન્ડોમાં ફરીથી પેસ્ટ કરવું પડશે.',
+ title: 'પેસ્ટ'
+} );
diff --git a/sources/plugins/clipboard/lang/he.js b/sources/plugins/clipboard/lang/he.js
new file mode 100644
index 00000000..d91fee0d
--- /dev/null
+++ b/sources/plugins/clipboard/lang/he.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'he', {
+ copy: 'העתקה',
+ copyError: 'הגדרות האבטחה בדפדפן שלך לא מאפשרות לעורך לבצע פעולות העתקה אוטומטיות. יש להשתמש במקלדת לשם כך (Ctrl/Cmd+C).',
+ cut: 'גזירה',
+ cutError: 'הגדרות האבטחה בדפדפן שלך לא מאפשרות לעורך לבצע פעולות גזירה אוטומטיות. יש להשתמש במקלדת לשם כך (Ctrl/Cmd+X).',
+ paste: 'הדבקה',
+ pasteArea: 'איזור הדבקה',
+ pasteMsg: 'נא להדביק בתוך הקופסה באמצעות (Ctrl/Cmd+V) וללחוץ על אישור.',
+ securityMsg: 'עקב הגדרות אבטחה בדפדפן, לא ניתן לגשת אל לוח הגזירים (Clipboard) בצורה ישירה. נא להדביק שוב בחלון זה.',
+ title: 'הדבקה'
+} );
diff --git a/sources/plugins/clipboard/lang/hi.js b/sources/plugins/clipboard/lang/hi.js
new file mode 100644
index 00000000..3660fb19
--- /dev/null
+++ b/sources/plugins/clipboard/lang/hi.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'hi', {
+ copy: 'कॉपी',
+ copyError: 'आपके ब्राआउज़र की सुरक्षा सॅटिन्ग्स ने कॉपी करने की अनुमति नहीं प्रदान की है। (Ctrl/Cmd+C) का प्रयोग करें।',
+ cut: 'कट',
+ cutError: 'आपके ब्राउज़र की सुरक्षा सॅटिन्ग्स ने कट करने की अनुमति नहीं प्रदान की है। (Ctrl/Cmd+X) का प्रयोग करें।',
+ paste: 'पेस्ट',
+ pasteArea: 'Paste Area', // MISSING
+ pasteMsg: 'Ctrl/Cmd+V का प्रयोग करके पेस्ट करें और ठीक है करें.',
+ securityMsg: 'आपके ब्राउज़र की सुरक्षा आपके ब्राउज़र की सुरKश सैटिंग के कारण, एडिटर आपके क्लिपबोर्ड डेटा को नहीं पा सकता है. आपको उसे इस विन्डो में दोबारा पेस्ट करना होगा.',
+ title: 'पेस्ट'
+} );
diff --git a/sources/plugins/clipboard/lang/hr.js b/sources/plugins/clipboard/lang/hr.js
new file mode 100644
index 00000000..b820eb9e
--- /dev/null
+++ b/sources/plugins/clipboard/lang/hr.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'hr', {
+ copy: 'Kopiraj',
+ copyError: 'Sigurnosne postavke Vašeg pretraživača ne dozvoljavaju operacije automatskog kopiranja. Molimo koristite kraticu na tipkovnici (Ctrl/Cmd+C).',
+ cut: 'Izreži',
+ cutError: 'Sigurnosne postavke Vašeg pretraživača ne dozvoljavaju operacije automatskog izrezivanja. Molimo koristite kraticu na tipkovnici (Ctrl/Cmd+X).',
+ paste: 'Zalijepi',
+ pasteArea: 'Prostor za ljepljenje',
+ pasteMsg: 'Molimo zaljepite unutar doljnjeg okvira koristeći tipkovnicu (Ctrl/Cmd+V) i kliknite OK.',
+ securityMsg: 'Zbog sigurnosnih postavki Vašeg pretraživača, editor nema direktan pristup Vašem međuspremniku. Potrebno je ponovno zalijepiti tekst u ovaj prozor.',
+ title: 'Zalijepi'
+} );
diff --git a/sources/plugins/clipboard/lang/hu.js b/sources/plugins/clipboard/lang/hu.js
new file mode 100644
index 00000000..61829ca9
--- /dev/null
+++ b/sources/plugins/clipboard/lang/hu.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'hu', {
+ copy: 'Másolás',
+ copyError: 'A böngésző biztonsági beállításai nem engedélyezik a szerkesztőnek, hogy végrehajtsa a másolás műveletet. Használja az alábbi billentyűkombinációt (Ctrl/Cmd+X).',
+ cut: 'Kivágás',
+ cutError: 'A böngésző biztonsági beállításai nem engedélyezik a szerkesztőnek, hogy végrehajtsa a kivágás műveletet. Használja az alábbi billentyűkombinációt (Ctrl/Cmd+X).',
+ paste: 'Beillesztés',
+ pasteArea: 'Beszúrás mező',
+ pasteMsg: 'Másolja be az alábbi mezőbe a Ctrl/Cmd+V billentyűk lenyomásával, majd nyomjon Rendben-t.',
+ securityMsg: 'A böngésző biztonsági beállításai miatt a szerkesztő nem képes hozzáférni a vágólap adataihoz. Illeszd be újra ebben az ablakban.',
+ title: 'Beillesztés'
+} );
diff --git a/sources/plugins/clipboard/lang/id.js b/sources/plugins/clipboard/lang/id.js
new file mode 100644
index 00000000..eca3852a
--- /dev/null
+++ b/sources/plugins/clipboard/lang/id.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'id', {
+ copy: 'Salin',
+ copyError: 'Pengaturan keamanan peramban anda tidak mengizinkan editor untuk mengeksekusi operasi menyalin secara otomatis. Mohon gunakan papan tuts (Ctrl/Cmd+C)',
+ cut: 'Potong',
+ cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).', // MISSING
+ paste: 'Tempel',
+ pasteArea: 'Area Tempel',
+ pasteMsg: 'Please paste inside the following box using the keyboard (Ctrl/Cmd+V) and hit OK', // MISSING
+ securityMsg: 'Karena pengaturan keamanan peramban anda, editor tida dapat mengakses data clipboard anda secara langsung. Anda harus mem-paste kembali pada halaman ini',
+ title: 'Tempel'
+} );
diff --git a/sources/plugins/clipboard/lang/is.js b/sources/plugins/clipboard/lang/is.js
new file mode 100644
index 00000000..bdf5862f
--- /dev/null
+++ b/sources/plugins/clipboard/lang/is.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'is', {
+ copy: 'Afrita',
+ copyError: 'Öryggisstillingar vafrans þíns leyfa ekki afritun texta með músaraðgerð. Notaðu lyklaborðið í afrita (Ctrl/Cmd+C).',
+ cut: 'Klippa',
+ cutError: 'Öryggisstillingar vafrans þíns leyfa ekki klippingu texta með músaraðgerð. Notaðu lyklaborðið í klippa (Ctrl/Cmd+X).',
+ paste: 'Líma',
+ pasteArea: 'Paste Area', // MISSING
+ pasteMsg: 'Límdu í svæðið hér að neðan og (Ctrl/Cmd+V) og smelltu á OK.',
+ securityMsg: 'Vegna öryggisstillinga í vafranum þínum fær ritillinn ekki beinan aðgang að klippuborðinu. Þú verður að líma innihaldið aftur inn í þennan glugga.',
+ title: 'Líma'
+} );
diff --git a/sources/plugins/clipboard/lang/it.js b/sources/plugins/clipboard/lang/it.js
new file mode 100644
index 00000000..443fdf2e
--- /dev/null
+++ b/sources/plugins/clipboard/lang/it.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'it', {
+ copy: 'Copia',
+ copyError: 'Le impostazioni di sicurezza del browser non permettono di copiare automaticamente il testo. Usa la tastiera (Ctrl/Cmd+C).',
+ cut: 'Taglia',
+ cutError: 'Le impostazioni di sicurezza del browser non permettono di tagliare automaticamente il testo. Usa la tastiera (Ctrl/Cmd+X).',
+ paste: 'Incolla',
+ pasteArea: 'Incolla',
+ pasteMsg: 'Incolla il testo all\'interno dell\'area sottostante usando la scorciatoia di tastiere (Ctrl/Cmd+V) e premi OK.',
+ securityMsg: 'A causa delle impostazioni di sicurezza del browser,l\'editor non è in grado di accedere direttamente agli appunti. E\' pertanto necessario incollarli di nuovo in questa finestra.',
+ title: 'Incolla'
+} );
diff --git a/sources/plugins/clipboard/lang/ja.js b/sources/plugins/clipboard/lang/ja.js
new file mode 100644
index 00000000..5697cbb7
--- /dev/null
+++ b/sources/plugins/clipboard/lang/ja.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'ja', {
+ copy: 'コピー',
+ copyError: 'ブラウザーのセキュリティ設定によりエディタのコピー操作を自動で実行することができません。実行するには手動でキーボードの(Ctrl/Cmd+C)を使用してください。',
+ cut: '切り取り',
+ cutError: 'ブラウザーのセキュリティ設定によりエディタの切り取り操作を自動で実行することができません。実行するには手動でキーボードの(Ctrl/Cmd+X)を使用してください。',
+ paste: '貼り付け',
+ pasteArea: '貼り付け場所',
+ pasteMsg: 'キーボード(Ctrl/Cmd+V)を使用して、次の入力エリア内で貼り付けて、OKを押してください。',
+ securityMsg: 'ブラウザのセキュリティ設定により、エディタはクリップボードデータに直接アクセスすることができません。このウィンドウは貼り付け操作を行う度に表示されます。',
+ title: '貼り付け'
+} );
diff --git a/sources/plugins/clipboard/lang/ka.js b/sources/plugins/clipboard/lang/ka.js
new file mode 100644
index 00000000..021fe08e
--- /dev/null
+++ b/sources/plugins/clipboard/lang/ka.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'ka', {
+ copy: 'ასლი',
+ copyError: 'თქვენი ბროუზერის უსაფრთხოების პარამეტრები არ იძლევა ასლის ოპერაციის ავტომატურად განხორციელების საშუალებას. გამოიყენეთ კლავიატურა ამისთვის (Ctrl/Cmd+C).',
+ cut: 'ამოჭრა',
+ cutError: 'თქვენი ბროუზერის უსაფრთხოების პარამეტრები არ იძლევა ამოჭრის ოპერაციის ავტომატურად განხორციელების საშუალებას. გამოიყენეთ კლავიატურა ამისთვის (Ctrl/Cmd+X).',
+ paste: 'ჩასმა',
+ pasteArea: 'ჩასმის არე',
+ pasteMsg: 'ჩასვით ამ არის შიგნით კლავიატურის გამოყენებით (Ctrl/Cmd+V) და დააჭირეთ OK-ს',
+ securityMsg: 'თქვენი ბროუზერის უსაფრთხოების პარამეტრები არ იძლევა clipboard-ის მონაცემების წვდომის უფლებას. კიდევ უნდა ჩასვათ ტექსტი ამ ფანჯარაში.',
+ title: 'ჩასმა'
+} );
diff --git a/sources/plugins/clipboard/lang/km.js b/sources/plugins/clipboard/lang/km.js
new file mode 100644
index 00000000..0baa9d8b
--- /dev/null
+++ b/sources/plugins/clipboard/lang/km.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'km', {
+ copy: 'ចម្លង',
+ copyError: 'ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះមិនអាចធ្វើកម្មវិធីតាក់តែងអត្ថបទ ចំលងអត្ថបទយកដោយស្វ័យប្រវត្តបានឡើយ ។ សូមប្រើប្រាស់បន្សំ ឃីដូចនេះ (Ctrl/Cmd+C)។',
+ cut: 'កាត់យក',
+ cutError: 'ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះមិនអាចធ្វើកម្មវិធីតាក់តែងអត្ថបទ កាត់អត្ថបទយកដោយស្វ័យប្រវត្តបានឡើយ ។ សូមប្រើប្រាស់បន្សំ ឃីដូចនេះ (Ctrl/Cmd+X) ។',
+ paste: 'បិទភ្ជាប់',
+ pasteArea: 'តំបន់បិទភ្ជាប់',
+ pasteMsg: 'សូមចំលងអត្ថបទទៅដាក់ក្នុងប្រអប់ដូចខាងក្រោមដោយប្រើប្រាស់ ឃី (Ctrl/Cmd+V) ហើយចុច OK ។',
+ securityMsg: 'ព្រោះតែការកំណត់សុវត្ថិភាព ប្រអប់សរសេរមិនអាចចាប់យកទិន្នន័យពីក្តារតម្បៀតខ្ទាស់អ្នកដោយផ្ទាល់បានទេ។ អ្នកត្រូវចំលងដាក់វាម្តងទៀត ក្នុងផ្ទាំងនេះ។',
+ title: 'បិទភ្ជាប់'
+} );
diff --git a/sources/plugins/clipboard/lang/ko.js b/sources/plugins/clipboard/lang/ko.js
new file mode 100644
index 00000000..6db8caba
--- /dev/null
+++ b/sources/plugins/clipboard/lang/ko.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'ko', {
+ copy: '복사',
+ copyError: '브라우저의 보안설정 때문에 복사할 수 없습니다. 키보드(Ctrl/Cmd+C)를 이용해서 복사하십시오.',
+ cut: '잘라내기',
+ cutError: '브라우저의 보안설정 때문에 잘라내기 기능을 실행할 수 없습니다. 키보드(Ctrl/Cmd+X)를 이용해서 잘라내기 하십시오',
+ paste: '붙여넣기',
+ pasteArea: '붙여넣기 범위',
+ pasteMsg: '키보드(Ctrl/Cmd+V)를 이용해서 상자안에 붙여넣고 확인 를 누르세요.',
+ securityMsg: '브라우저 보안 설정으로 인해, 클립보드에 직접 접근할 수 없습니다. 이 창에 다시 붙여넣기 하십시오.',
+ title: '붙여넣기'
+} );
diff --git a/sources/plugins/clipboard/lang/ku.js b/sources/plugins/clipboard/lang/ku.js
new file mode 100644
index 00000000..91b77671
--- /dev/null
+++ b/sources/plugins/clipboard/lang/ku.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'ku', {
+ copy: 'لەبەرگرتنەوە',
+ copyError: 'پارێزی وێبگەڕەکەت ڕێگەنادات بەسەرنووسەکە لە لکاندنی دەقی خۆکارارنە. تکایە لەبری ئەمە ئەم فەرمانە بەکاربهێنە بەداگرتنی کلیلی (Ctrl/Cmd+C).',
+ cut: 'بڕین',
+ cutError: 'پارێزی وێبگەڕەکەت ڕێگەنادات بە سەرنووسەکە لەبڕینی خۆکارانە. تکایە لەبری ئەمە ئەم فەرمانە بەکاربهێنە بەداگرتنی کلیلی (Ctrl/Cmd+X).',
+ paste: 'لکاندن',
+ pasteArea: 'ناوچەی لکاندن',
+ pasteMsg: 'تکایە بیلکێنە لەناوەوەی ئەم سنوقە لەڕێی تەختەکلیلەکەت بە بەکارهێنانی کلیلی (Ctrl/Cmd+V) دووای کلیکی باشە بکە.',
+ securityMsg: 'بەهۆی شێوەپێدانی پارێزی وێبگەڕەکەت، سەرنووسەکه ناتوانێت دەستبگەیەنێت بەهەڵگیراوەکە ڕاستەوخۆ. بۆیه پێویسته دووباره بیلکێنیت لەم پەنجەرەیه.',
+ title: 'لکاندن'
+} );
diff --git a/sources/plugins/clipboard/lang/lt.js b/sources/plugins/clipboard/lang/lt.js
new file mode 100644
index 00000000..ef57ed48
--- /dev/null
+++ b/sources/plugins/clipboard/lang/lt.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'lt', {
+ copy: 'Kopijuoti',
+ copyError: 'Jūsų naršyklės saugumo nustatymai neleidžia redaktoriui automatiškai įvykdyti kopijavimo operacijų. Tam prašome naudoti klaviatūrą (Ctrl/Cmd+C).',
+ cut: 'Iškirpti',
+ cutError: 'Jūsų naršyklės saugumo nustatymai neleidžia redaktoriui automatiškai įvykdyti iškirpimo operacijų. Tam prašome naudoti klaviatūrą (Ctrl/Cmd+X).',
+ paste: 'Įdėti',
+ pasteArea: 'Įkelti dalį',
+ pasteMsg: 'Žemiau esančiame įvedimo lauke įdėkite tekstą, naudodami klaviatūrą (Ctrl/Cmd+V) ir paspauskite mygtuką OK.',
+ securityMsg: 'Dėl jūsų naršyklės saugumo nustatymų, redaktorius negali tiesiogiai pasiekti laikinosios atminties. Jums reikia nukopijuoti dar kartą į šį langą.',
+ title: 'Įdėti'
+} );
diff --git a/sources/plugins/clipboard/lang/lv.js b/sources/plugins/clipboard/lang/lv.js
new file mode 100644
index 00000000..f347cc4f
--- /dev/null
+++ b/sources/plugins/clipboard/lang/lv.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'lv', {
+ copy: 'Kopēt',
+ copyError: 'Jūsu pārlūkprogrammas drošības iestatījumi nepieļauj redaktoram automātiski veikt kopēšanas darbību. Lūdzu, izmantojiet (Ctrl/Cmd+C), lai veiktu šo darbību.',
+ cut: 'Izgriezt',
+ cutError: 'Jūsu pārlūkprogrammas drošības iestatījumi nepieļauj redaktoram automātiski veikt izgriezšanas darbību. Lūdzu, izmantojiet (Ctrl/Cmd+X), lai veiktu šo darbību.',
+ paste: 'Ielīmēt',
+ pasteArea: 'Ielīmēšanas zona',
+ pasteMsg: 'Lūdzu, ievietojiet tekstu šajā laukumā, izmantojot klaviatūru (Ctrl/Cmd+V) un apstipriniet ar Darīts!.',
+ securityMsg: 'Jūsu pārlūka drošības uzstādījumu dēļ, nav iespējams tieši piekļūt jūsu starpliktuvei. Jums jāielīmē atkārtoti šajā logā.',
+ title: 'Ievietot'
+} );
diff --git a/sources/plugins/clipboard/lang/mk.js b/sources/plugins/clipboard/lang/mk.js
new file mode 100644
index 00000000..3fbb5718
--- /dev/null
+++ b/sources/plugins/clipboard/lang/mk.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'mk', {
+ copy: 'Copy', // MISSING
+ copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).', // MISSING
+ cut: 'Cut', // MISSING
+ cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).', // MISSING
+ paste: 'Paste', // MISSING
+ pasteArea: 'Paste Area', // MISSING
+ pasteMsg: 'Please paste inside the following box using the keyboard (Ctrl/Cmd+V) and hit OK', // MISSING
+ securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', // MISSING
+ title: 'Paste' // MISSING
+} );
diff --git a/sources/plugins/clipboard/lang/mn.js b/sources/plugins/clipboard/lang/mn.js
new file mode 100644
index 00000000..68c3f77e
--- /dev/null
+++ b/sources/plugins/clipboard/lang/mn.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'mn', {
+ copy: 'Хуулах',
+ copyError: 'Таны browser-ын хамгаалалтын тохиргоо editor-д автоматаар хуулах үйлдэлийг зөвшөөрөхгүй байна. (Ctrl/Cmd+C) товчны хослолыг ашиглана уу.',
+ cut: 'Хайчлах',
+ cutError: 'Таны browser-ын хамгаалалтын тохиргоо editor-д автоматаар хайчлах үйлдэлийг зөвшөөрөхгүй байна. (Ctrl/Cmd+X) товчны хослолыг ашиглана уу.',
+ paste: 'Буулгах',
+ pasteArea: 'Paste Area', // MISSING
+ pasteMsg: '(Ctrl/Cmd+V) товчийг ашиглан paste хийнэ үү. Мөн OK дар.',
+ securityMsg: 'Таны үзүүлэгч/browser/-н хамгаалалтын тохиргооноос болоод editor clipboard өгөгдөлрүү шууд хандах боломжгүй. Энэ цонход дахин paste хийхийг оролд.',
+ title: 'Буулгах'
+} );
diff --git a/sources/plugins/clipboard/lang/ms.js b/sources/plugins/clipboard/lang/ms.js
new file mode 100644
index 00000000..4381f047
--- /dev/null
+++ b/sources/plugins/clipboard/lang/ms.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'ms', {
+ copy: 'Salin',
+ copyError: 'Keselamatan perisian browser anda tidak membenarkan operasi salinan text/imej. Sila gunakan papan kekunci (Ctrl/Cmd+C).',
+ cut: 'Potong',
+ cutError: 'Keselamatan perisian browser anda tidak membenarkan operasi suntingan text/imej. Sila gunakan papan kekunci (Ctrl/Cmd+X).',
+ paste: 'Tampal',
+ pasteArea: 'Paste Area', // MISSING
+ pasteMsg: 'Please paste inside the following box using the keyboard (Ctrl/Cmd+V) and hit OK', // MISSING
+ securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', // MISSING
+ title: 'Tampal'
+} );
diff --git a/sources/plugins/clipboard/lang/nb.js b/sources/plugins/clipboard/lang/nb.js
new file mode 100644
index 00000000..d2dedbfc
--- /dev/null
+++ b/sources/plugins/clipboard/lang/nb.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'nb', {
+ copy: 'Kopier',
+ copyError: 'Din nettlesers sikkerhetsinstillinger tillater ikke automatisk kopiering av tekst. Vennligst bruk tastatursnarveien (Ctrl/Cmd+C).',
+ cut: 'Klipp ut',
+ cutError: 'Din nettlesers sikkerhetsinstillinger tillater ikke automatisk utklipping av tekst. Vennligst bruk tastatursnarveien (Ctrl/Cmd+X).',
+ paste: 'Lim inn',
+ pasteArea: 'Innlimingsområde',
+ pasteMsg: 'Vennligst lim inn i følgende boks med tastaturet (Ctrl/Cmd+V) og trykk OK.',
+ securityMsg: 'Din nettlesers sikkerhetsinstillinger gir ikke redigeringsverktøyet direkte tilgang til utklippstavlen. Du må derfor lime det inn på nytt i dette vinduet.',
+ title: 'Lim inn'
+} );
diff --git a/sources/plugins/clipboard/lang/nl.js b/sources/plugins/clipboard/lang/nl.js
new file mode 100644
index 00000000..b9829c53
--- /dev/null
+++ b/sources/plugins/clipboard/lang/nl.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'nl', {
+ copy: 'Kopiëren',
+ copyError: 'De beveiligingsinstelling van de browser verhinderen het automatisch kopiëren. Gebruik de sneltoets Ctrl/Cmd+C van het toetsenbord.',
+ cut: 'Knippen',
+ cutError: 'De beveiligingsinstelling van de browser verhinderen het automatisch knippen. Gebruik de sneltoets Ctrl/Cmd+X van het toetsenbord.',
+ paste: 'Plakken',
+ pasteArea: 'Plakgebied',
+ pasteMsg: 'Plak de tekst in het volgende vak gebruikmakend van uw toetsenbord (Ctrl/Cmd+V) en klik op OK.',
+ securityMsg: 'Door de beveiligingsinstellingen van uw browser is het niet mogelijk om direct vanuit het klembord in de editor te plakken. Middels opnieuw plakken in dit venster kunt u de tekst alsnog plakken in de editor.',
+ title: 'Plakken'
+} );
diff --git a/sources/plugins/clipboard/lang/no.js b/sources/plugins/clipboard/lang/no.js
new file mode 100644
index 00000000..d883f6c2
--- /dev/null
+++ b/sources/plugins/clipboard/lang/no.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'no', {
+ copy: 'Kopier',
+ copyError: 'Din nettlesers sikkerhetsinstillinger tillater ikke automatisk kopiering av tekst. Vennligst bruk snarveien (Ctrl/Cmd+C).',
+ cut: 'Klipp ut',
+ cutError: 'Din nettlesers sikkerhetsinstillinger tillater ikke automatisk utklipping av tekst. Vennligst bruk snarveien (Ctrl/Cmd+X).',
+ paste: 'Lim inn',
+ pasteArea: 'Innlimingsområde',
+ pasteMsg: 'Vennligst lim inn i følgende boks med tastaturet (Ctrl/Cmd+V) og trykk OK.',
+ securityMsg: 'Din nettlesers sikkerhetsinstillinger gir ikke redigeringsverktøyet direkte tilgang til utklippstavlen. Du må derfor lime det inn på nytt i dette vinduet.',
+ title: 'Lim inn'
+} );
diff --git a/sources/plugins/clipboard/lang/pl.js b/sources/plugins/clipboard/lang/pl.js
new file mode 100644
index 00000000..ca45bd03
--- /dev/null
+++ b/sources/plugins/clipboard/lang/pl.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'pl', {
+ copy: 'Kopiuj',
+ copyError: 'Ustawienia bezpieczeństwa Twojej przeglądarki nie pozwalają na automatyczne kopiowanie tekstu. Użyj skrótu klawiszowego Ctrl/Cmd+C.',
+ cut: 'Wytnij',
+ cutError: 'Ustawienia bezpieczeństwa Twojej przeglądarki nie pozwalają na automatyczne wycinanie tekstu. Użyj skrótu klawiszowego Ctrl/Cmd+X.',
+ paste: 'Wklej',
+ pasteArea: 'Obszar wklejania',
+ pasteMsg: 'Wklej tekst w poniższym polu, używając skrótu klawiaturowego (Ctrl/Cmd+V), i kliknij OK.',
+ securityMsg: 'Zabezpieczenia przeglądarki uniemożliwiają wklejenie danych bezpośrednio do edytora. Proszę ponownie wkleić dane w tym oknie.',
+ title: 'Wklej'
+} );
diff --git a/sources/plugins/clipboard/lang/pt-br.js b/sources/plugins/clipboard/lang/pt-br.js
new file mode 100644
index 00000000..895ff3db
--- /dev/null
+++ b/sources/plugins/clipboard/lang/pt-br.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'pt-br', {
+ copy: 'Copiar',
+ copyError: 'As configurações de segurança do seu navegador não permitem que o editor execute operações de copiar automaticamente. Por favor, utilize o teclado para copiar (Ctrl/Cmd+C).',
+ cut: 'Recortar',
+ cutError: 'As configurações de segurança do seu navegador não permitem que o editor execute operações de recortar automaticamente. Por favor, utilize o teclado para recortar (Ctrl/Cmd+X).',
+ paste: 'Colar',
+ pasteArea: 'Área para Colar',
+ pasteMsg: 'Transfira o link usado na caixa usando o teclado com (Ctrl/Cmd+V) e OK.',
+ securityMsg: 'As configurações de segurança do seu navegador não permitem que o editor acesse os dados da área de transferência diretamente. Por favor cole o conteúdo manualmente nesta janela.',
+ title: 'Colar'
+} );
diff --git a/sources/plugins/clipboard/lang/pt.js b/sources/plugins/clipboard/lang/pt.js
new file mode 100644
index 00000000..40bf99bd
--- /dev/null
+++ b/sources/plugins/clipboard/lang/pt.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'pt', {
+ copy: 'Copiar',
+ copyError: 'A configuração de segurança do navegador não permite a execução automática de operações de copiar. Por favor use o teclado (Ctrl/Cmd+C).',
+ cut: 'Cortar',
+ cutError: 'A configuração de segurança do navegador não permite a execução automática de operações de cortar. Por favor use o teclado (Ctrl/Cmd+X).',
+ paste: 'Colar',
+ pasteArea: 'Colar área',
+ pasteMsg: 'Por favor, cole dentro da seguinte caixa usando o teclado (Ctrl/Cmd+V) e prima OK.',
+ securityMsg: 'Devido ás definições de segurança do teu browser, o editor não pode aceder ao clipboard diretamente. É necessário que voltes a colar as informações nesta janela.',
+ title: 'Colar'
+} );
diff --git a/sources/plugins/clipboard/lang/ro.js b/sources/plugins/clipboard/lang/ro.js
new file mode 100644
index 00000000..2b34ef74
--- /dev/null
+++ b/sources/plugins/clipboard/lang/ro.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'ro', {
+ copy: 'Copiază',
+ copyError: 'Setările de securitate ale navigatorului (browser) pe care îl folosiţi nu permit editorului să execute automat operaţiunea de copiere. Vă rugăm folosiţi tastatura (Ctrl/Cmd+C).',
+ cut: 'Taie',
+ cutError: 'Setările de securitate ale navigatorului (browser) pe care îl folosiţi nu permit editorului să execute automat operaţiunea de tăiere. Vă rugăm folosiţi tastatura (Ctrl/Cmd+X).',
+ paste: 'Adaugă',
+ pasteArea: 'Suprafața de adăugare',
+ pasteMsg: 'Vă rugăm adăugaţi în căsuţa următoare folosind tastatura (Ctrl/Cmd+V) şi apăsaţi OK',
+ securityMsg: 'Din cauza setărilor de securitate ale programului dvs. cu care navigaţi pe internet (browser), editorul nu poate accesa direct datele din clipboard. Va trebui să adăugaţi din nou datele în această fereastră.',
+ title: 'Adaugă'
+} );
diff --git a/sources/plugins/clipboard/lang/ru.js b/sources/plugins/clipboard/lang/ru.js
new file mode 100644
index 00000000..9790f01d
--- /dev/null
+++ b/sources/plugins/clipboard/lang/ru.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'ru', {
+ copy: 'Копировать',
+ copyError: 'Настройки безопасности вашего браузера не разрешают редактору выполнять операции по копированию текста. Пожалуйста, используйте для этого клавиатуру (Ctrl/Cmd+C).',
+ cut: 'Вырезать',
+ cutError: 'Настройки безопасности вашего браузера не разрешают редактору выполнять операции по вырезке текста. Пожалуйста, используйте для этого клавиатуру (Ctrl/Cmd+X).',
+ paste: 'Вставить',
+ pasteArea: 'Зона для вставки',
+ pasteMsg: 'Пожалуйста, вставьте текст в зону ниже, используя клавиатуру (Ctrl/Cmd+V) и нажмите кнопку "OK".',
+ securityMsg: 'Настройки безопасности вашего браузера не разрешают редактору напрямую обращаться к буферу обмена. Вы должны вставить текст снова в это окно.',
+ title: 'Вставить'
+} );
diff --git a/sources/plugins/clipboard/lang/si.js b/sources/plugins/clipboard/lang/si.js
new file mode 100644
index 00000000..37dd1248
--- /dev/null
+++ b/sources/plugins/clipboard/lang/si.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'si', {
+ copy: 'පිටපත් කරන්න',
+ copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).', // MISSING
+ cut: 'කපාගන්න',
+ cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).', // MISSING
+ paste: 'අලවන්න',
+ pasteArea: 'අලවන ප්රදේශ',
+ pasteMsg: 'Please paste inside the following box using the keyboard (Ctrl/Cmd+V) and hit OK', // MISSING
+ securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', // MISSING
+ title: 'අලවන්න'
+} );
diff --git a/sources/plugins/clipboard/lang/sk.js b/sources/plugins/clipboard/lang/sk.js
new file mode 100644
index 00000000..4f9e97a7
--- /dev/null
+++ b/sources/plugins/clipboard/lang/sk.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'sk', {
+ copy: 'Kopírovať',
+ copyError: 'Bezpečnostné nastavenia Vášho prehliadača nedovoľujú editoru automaticky spustiť operáciu kopírovania. Prosím, použite na to klávesnicu (Ctrl/Cmd+C).',
+ cut: 'Vystrihnúť',
+ cutError: 'Bezpečnostné nastavenia Vášho prehliadača nedovoľujú editoru automaticky spustiť operáciu vystrihnutia. Prosím, použite na to klávesnicu (Ctrl/Cmd+X).',
+ paste: 'Vložiť',
+ pasteArea: 'Miesto pre vloženie',
+ pasteMsg: 'Prosím, vložte nasledovný rámček použitím klávesnice (Ctrl/Cmd+V) a stlačte OK.',
+ securityMsg: 'Kvôli vašim bezpečnostným nastaveniam prehliadača editor nie je schopný pristupovať k vašej schránke na kopírovanie priamo. Vložte to preto do tohto okna.',
+ title: 'Vložiť'
+} );
diff --git a/sources/plugins/clipboard/lang/sl.js b/sources/plugins/clipboard/lang/sl.js
new file mode 100644
index 00000000..4bb3b6c8
--- /dev/null
+++ b/sources/plugins/clipboard/lang/sl.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'sl', {
+ copy: 'Kopiraj',
+ copyError: 'Varnostne nastavitve brskalnika ne dopuščajo samodejnega kopiranja. Uporabite kombinacijo tipk na tipkovnici (Ctrl/Cmd+C).',
+ cut: 'Izreži',
+ cutError: 'Varnostne nastavitve brskalnika ne dopuščajo samodejnega izrezovanja. Uporabite kombinacijo tipk na tipkovnici (Ctrl/Cmd+X).',
+ paste: 'Prilepi',
+ pasteArea: 'Prilepi Prostor',
+ pasteMsg: 'Prosim prilepite v sleči okvir s pomočjo tipkovnice (Ctrl/Cmd+V) in pritisnite V redu.',
+ securityMsg: 'Zaradi varnostnih nastavitev vašega brskalnika urejevalnik ne more neposredno dostopati do odložišča. Vsebino odložišča ponovno prilepite v to okno.',
+ title: 'Prilepi'
+} );
diff --git a/sources/plugins/clipboard/lang/sq.js b/sources/plugins/clipboard/lang/sq.js
new file mode 100644
index 00000000..e5be3c6c
--- /dev/null
+++ b/sources/plugins/clipboard/lang/sq.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'sq', {
+ copy: 'Kopjo',
+ copyError: 'Të dhënat e sigurisë së shfletuesit tuaj nuk lejojnë që redaktuesi automatikisht të kryej veprimin e kopjimit. Ju lutemi shfrytëzoni tastierën për këtë veprim (Ctrl/Cmd+C).',
+ cut: 'Preje',
+ cutError: 'Të dhënat e sigurisë së shfletuesit tuaj nuk lejojnë që redaktuesi automatikisht të kryej veprimin e prerjes. Ju lutemi shfrytëzoni tastierën për këtë veprim (Ctrl/Cmd+X).',
+ paste: 'Hidhe',
+ pasteArea: 'Hapësira Hedhëse',
+ pasteMsg: 'Ju lutemi hidhni brenda kutizës në vijim duke shfrytëzuar tastierën (Ctrl/Cmd+V) dhe shtypni Mirë.',
+ securityMsg: 'Për shkak të dhënave të sigurisë së shfletuesit tuaj, redaktuesi nuk është në gjendje të i qaset drejtpërdrejtë të dhanve të tabelës suaj të punës. Ju duhet të hidhni atë përsëri në këtë dritare.',
+ title: 'Hidhe'
+} );
diff --git a/sources/plugins/clipboard/lang/sr-latn.js b/sources/plugins/clipboard/lang/sr-latn.js
new file mode 100644
index 00000000..02a2fbe5
--- /dev/null
+++ b/sources/plugins/clipboard/lang/sr-latn.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'sr-latn', {
+ copy: 'Kopiraj',
+ copyError: 'Sigurnosna podešavanja Vašeg pretraživača ne dozvoljavaju operacije automatskog kopiranja teksta. Molimo Vas da koristite prečicu sa tastature (Ctrl/Cmd+C).',
+ cut: 'Iseci',
+ cutError: 'Sigurnosna podešavanja Vašeg pretraživača ne dozvoljavaju operacije automatskog isecanja teksta. Molimo Vas da koristite prečicu sa tastature (Ctrl/Cmd+X).',
+ paste: 'Zalepi',
+ pasteArea: 'Prostor za lepljenje',
+ pasteMsg: 'Molimo Vas da zalepite unutar donje povrine koristeći tastaturnu prečicu (Ctrl/Cmd+V) i da pritisnete OK.',
+ securityMsg: 'Zbog sigurnosnih postavki vašeg pregledača, editor nije u mogućnosti da direktno pristupi podacima u klipbordu. Potrebno je da zalepite još jednom u ovom prozoru.',
+ title: 'Zalepi'
+} );
diff --git a/sources/plugins/clipboard/lang/sr.js b/sources/plugins/clipboard/lang/sr.js
new file mode 100644
index 00000000..51055eb2
--- /dev/null
+++ b/sources/plugins/clipboard/lang/sr.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'sr', {
+ copy: 'Копирај',
+ copyError: 'Сигурносна подешавања Вашег претраживача не дозвољавају операције аутоматског копирања текста. Молимо Вас да користите пречицу са тастатуре (Ctrl/Cmd+C).',
+ cut: 'Исеци',
+ cutError: 'Сигурносна подешавања Вашег претраживача не дозвољавају операције аутоматског исецања текста. Молимо Вас да користите пречицу са тастатуре (Ctrl/Cmd+X).',
+ paste: 'Залепи',
+ pasteArea: 'Залепи зону',
+ pasteMsg: 'Молимо Вас да залепите унутар доње површине користећи тастатурну пречицу (Ctrl/Cmd+V) и да притиснете OK.',
+ securityMsg: 'Због сигурносних подешавања претраживача, едитор не може да приступи оставу. Требате да га поново залепите у овом прозору.',
+ title: 'Залепи'
+} );
diff --git a/sources/plugins/clipboard/lang/sv.js b/sources/plugins/clipboard/lang/sv.js
new file mode 100644
index 00000000..747a1cb2
--- /dev/null
+++ b/sources/plugins/clipboard/lang/sv.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'sv', {
+ copy: 'Kopiera',
+ copyError: 'Säkerhetsinställningar i Er webbläsare tillåter inte åtgärden kopiera. Använd (Ctrl/Cmd+C) istället.',
+ cut: 'Klipp ut',
+ cutError: 'Säkerhetsinställningar i Er webbläsare tillåter inte åtgärden klipp ut. Använd (Ctrl/Cmd+X) istället.',
+ paste: 'Klistra in',
+ pasteArea: 'Paste Area',
+ pasteMsg: 'Var god och klistra in Er text i rutan nedan genom att använda (Ctrl/Cmd+V) klicka sen på OK.',
+ securityMsg: 'På grund av din webbläsares säkerhetsinställningar kan verktyget inte få åtkomst till urklippsdatan. Var god och använd detta fönster istället.',
+ title: 'Klistra in'
+} );
diff --git a/sources/plugins/clipboard/lang/th.js b/sources/plugins/clipboard/lang/th.js
new file mode 100644
index 00000000..2ece4685
--- /dev/null
+++ b/sources/plugins/clipboard/lang/th.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'th', {
+ copy: 'สำเนา',
+ copyError: 'ไม่สามารถสำเนาข้อความที่เลือกไว้ได้เนื่องจากการกำหนดค่าระดับความปลอดภัย. กรุณาใช้ปุ่มลัดเพื่อวางข้อความแทน (กดปุ่ม Ctrl/Cmd และตัว C พร้อมกัน).',
+ cut: 'ตัด',
+ cutError: 'ไม่สามารถตัดข้อความที่เลือกไว้ได้เนื่องจากการกำหนดค่าระดับความปลอดภัย. กรุณาใช้ปุ่มลัดเพื่อวางข้อความแทน (กดปุ่ม Ctrl/Cmd และตัว X พร้อมกัน).',
+ paste: 'วาง',
+ pasteArea: 'Paste Area', // MISSING
+ pasteMsg: 'กรุณาใช้คีย์บอร์ดเท่านั้น โดยกดปุ๋ม (Ctrl/Cmd และ V)พร้อมๆกัน และกด OK.',
+ securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', // MISSING
+ title: 'วาง'
+} );
diff --git a/sources/plugins/clipboard/lang/tr.js b/sources/plugins/clipboard/lang/tr.js
new file mode 100644
index 00000000..a960cbfe
--- /dev/null
+++ b/sources/plugins/clipboard/lang/tr.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'tr', {
+ copy: 'Kopyala',
+ copyError: 'Gezgin yazılımınızın güvenlik ayarları düzenleyicinin otomatik kopyalama işlemine izin vermiyor. İşlem için (Ctrl/Cmd+C) tuşlarını kullanın.',
+ cut: 'Kes',
+ cutError: 'Gezgin yazılımınızın güvenlik ayarları düzenleyicinin otomatik kesme işlemine izin vermiyor. İşlem için (Ctrl/Cmd+X) tuşlarını kullanın.',
+ paste: 'Yapıştır',
+ pasteArea: 'Yapıştırma Alanı',
+ pasteMsg: 'Lütfen aşağıdaki kutunun içine yapıştırın. (Ctrl/Cmd+V) ve Tamam butonunu tıklayın.',
+ securityMsg: 'Gezgin yazılımınızın güvenlik ayarları düzenleyicinin direkt olarak panoya erişimine izin vermiyor. Bu pencere içine tekrar yapıştırmalısınız..',
+ title: 'Yapıştır'
+} );
diff --git a/sources/plugins/clipboard/lang/tt.js b/sources/plugins/clipboard/lang/tt.js
new file mode 100644
index 00000000..3921b895
--- /dev/null
+++ b/sources/plugins/clipboard/lang/tt.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'tt', {
+ copy: 'Күчермәләү',
+ copyError: 'Браузерыгызның иминлек үзлекләре автоматик рәвештә күчермәләү үтәүне тыя. Тиз төймәләрне (Ctrl/Cmd+C) кулланыгыз.',
+ cut: 'Кисеп алу',
+ cutError: 'Браузерыгызның иминлек үзлекләре автоматик рәвештә күчермәләү үтәүне тыя. Тиз төймәләрне (Ctrl/Cmd+C) кулланыгыз.',
+ paste: 'Өстәү',
+ pasteArea: 'Өстәү мәйданы',
+ pasteMsg: 'Please paste inside the following box using the keyboard (Ctrl/Cmd+V) and hit OK', // MISSING
+ securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', // MISSING
+ title: 'Өстәү'
+} );
diff --git a/sources/plugins/clipboard/lang/ug.js b/sources/plugins/clipboard/lang/ug.js
new file mode 100644
index 00000000..6b0f0851
--- /dev/null
+++ b/sources/plugins/clipboard/lang/ug.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'ug', {
+ copy: 'نەشر ھوقۇقىغا ئىگە بەلگىسى',
+ copyError: 'تور كۆرگۈڭىزنىڭ بىخەتەرلىك تەڭشىكى تەھرىرلىگۈچنىڭ كۆچۈر مەشغۇلاتىنى ئۆزلۈكىدىن ئىجرا قىلىشىغا يول قويمايدۇ، ھەرپتاختا تېز كۇنۇپكا (Ctrl/Cmd+C) ئارقىلىق تاماملاڭ',
+ cut: 'كەس',
+ cutError: 'تور كۆرگۈڭىزنىڭ بىخەتەرلىك تەڭشىكى تەھرىرلىگۈچنىڭ كەس مەشغۇلاتىنى ئۆزلۈكىدىن ئىجرا قىلىشىغا يول قويمايدۇ، ھەرپتاختا تېز كۇنۇپكا (Ctrl/Cmd+X) ئارقىلىق تاماملاڭ',
+ paste: 'چاپلا',
+ pasteArea: 'چاپلاش دائىرىسى',
+ pasteMsg: 'ھەرپتاختا تېز كۇنۇپكا (Ctrl/Cmd+V) نى ئىشلىتىپ مەزمۇننى تۆۋەندىكى رامكىغا كۆچۈرۈڭ، ئاندىن جەزملەنى بېسىڭ',
+ securityMsg: 'توركۆرگۈڭىزنىڭ بىخەتەرلىك تەڭشىكى سەۋەبىدىن بۇ تەھرىرلىگۈچ چاپلاش تاختىسىدىكى مەزمۇننى بىۋاستە زىيارەت قىلالمايدۇ، بۇ كۆزنەكتە قايتا بىر قېتىم چاپلىشىڭىز كېرەك.',
+ title: 'چاپلا'
+} );
diff --git a/sources/plugins/clipboard/lang/uk.js b/sources/plugins/clipboard/lang/uk.js
new file mode 100644
index 00000000..666be54c
--- /dev/null
+++ b/sources/plugins/clipboard/lang/uk.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'uk', {
+ copy: 'Копіювати',
+ copyError: 'Налаштування безпеки Вашого браузера не дозволяють редактору автоматично виконувати операції копіювання. Будь ласка, використовуйте клавіатуру для цього (Ctrl/Cmd+C).',
+ cut: 'Вирізати',
+ cutError: 'Налаштування безпеки Вашого браузера не дозволяють редактору автоматично виконувати операції вирізування. Будь ласка, використовуйте клавіатуру для цього (Ctrl/Cmd+X)',
+ paste: 'Вставити',
+ pasteArea: 'Область вставки',
+ pasteMsg: 'Будь ласка, вставте інформацію з буфера обміну в цю область, користуючись комбінацією клавіш (Ctrl/Cmd+V), та натисніть OK.',
+ securityMsg: 'Редактор не може отримати прямий доступ до буферу обміну у зв\'язку з налаштуваннями Вашого браузера. Вам потрібно вставити інформацію в це вікно.',
+ title: 'Вставити'
+} );
diff --git a/sources/plugins/clipboard/lang/vi.js b/sources/plugins/clipboard/lang/vi.js
new file mode 100644
index 00000000..dfbc8210
--- /dev/null
+++ b/sources/plugins/clipboard/lang/vi.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'vi', {
+ copy: 'Sao chép',
+ copyError: 'Các thiết lập bảo mật của trình duyệt không cho phép trình biên tập tự động thực thi lệnh sao chép. Hãy sử dụng bàn phím cho lệnh này (Ctrl/Cmd+C).',
+ cut: 'Cắt',
+ cutError: 'Các thiết lập bảo mật của trình duyệt không cho phép trình biên tập tự động thực thi lệnh cắt. Hãy sử dụng bàn phím cho lệnh này (Ctrl/Cmd+X).',
+ paste: 'Dán',
+ pasteArea: 'Khu vực dán',
+ pasteMsg: 'Hãy dán nội dung vào trong khung bên dưới, sử dụng tổ hợp phím (Ctrl/Cmd+V) và nhấn vào nút Đồng ý.',
+ securityMsg: 'Do thiết lập bảo mật của trình duyệt nên trình biên tập không thể truy cập trực tiếp vào nội dung đã sao chép. Bạn cần phải dán lại nội dung vào cửa sổ này.',
+ title: 'Dán'
+} );
diff --git a/sources/plugins/clipboard/lang/zh-cn.js b/sources/plugins/clipboard/lang/zh-cn.js
new file mode 100644
index 00000000..426e4072
--- /dev/null
+++ b/sources/plugins/clipboard/lang/zh-cn.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'zh-cn', {
+ copy: '复制',
+ copyError: '您的浏览器安全设置不允许编辑器自动执行复制操作,请使用键盘快捷键(Ctrl/Cmd+C)来完成。',
+ cut: '剪切',
+ cutError: '您的浏览器安全设置不允许编辑器自动执行剪切操作,请使用键盘快捷键(Ctrl/Cmd+X)来完成。',
+ paste: '粘贴',
+ pasteArea: '粘贴区域',
+ pasteMsg: '请使用键盘快捷键(Ctrl/Cmd+V)把内容粘贴到下面的方框里,再按 确定',
+ securityMsg: '因为您的浏览器的安全设置原因,本编辑器不能直接访问您的剪贴板内容,你需要在本窗口重新粘贴一次。',
+ title: '粘贴'
+} );
diff --git a/sources/plugins/clipboard/lang/zh.js b/sources/plugins/clipboard/lang/zh.js
new file mode 100644
index 00000000..116ab664
--- /dev/null
+++ b/sources/plugins/clipboard/lang/zh.js
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang( 'clipboard', 'zh', {
+ copy: '複製',
+ copyError: '瀏覽器的安全性設定不允許編輯器自動執行複製動作。請使用鍵盤快捷鍵 (Ctrl/Cmd+C) 複製。',
+ cut: '剪下',
+ cutError: '瀏覽器的安全性設定不允許編輯器自動執行剪下動作。請使用鏐盤快捷鍵 (Ctrl/Cmd+X) 剪下。',
+ paste: '貼上',
+ pasteArea: '貼上區',
+ pasteMsg: '請使用鍵盤快捷鍵 (Ctrl/Cmd+V) 貼到下方區域中並按下「確定」。',
+ securityMsg: '因為瀏覽器的安全性設定,本編輯器無法直接存取您的剪貼簿資料,請您自行在本視窗進行貼上動作。',
+ title: '貼上'
+} );
diff --git a/sources/plugins/clipboard/plugin.js b/sources/plugins/clipboard/plugin.js
new file mode 100644
index 00000000..e3bc5f09
--- /dev/null
+++ b/sources/plugins/clipboard/plugin.js
@@ -0,0 +1,2723 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @ignore
+ * File overview: Clipboard support.
+ */
+
+//
+// COPY & PASTE EXECUTION FLOWS:
+// -- CTRL+C
+// * if ( isCustomCopyCutSupported )
+// * dataTransfer.setData( 'text/html', getSelectedHtml )
+// * else
+// * browser's default behavior
+// -- CTRL+X
+// * listen onKey (onkeydown)
+// * fire 'saveSnapshot' on editor
+// * if ( isCustomCopyCutSupported )
+// * dataTransfer.setData( 'text/html', getSelectedHtml )
+// * extractSelectedHtml // remove selected contents
+// * else
+// * browser's default behavior
+// * deferred second 'saveSnapshot' event
+// -- CTRL+V
+// * listen onKey (onkeydown)
+// * simulate 'beforepaste' for non-IEs on editable
+// * listen 'onpaste' on editable ('onbeforepaste' for IE)
+// * fire 'beforePaste' on editor
+// * if ( !canceled && ( htmlInDataTransfer || !external paste) && dataTransfer is not empty ) getClipboardDataByPastebin
+// * fire 'paste' on editor
+// * !canceled && fire 'afterPaste' on editor
+// -- Copy command
+// * tryToCutCopy
+// * execCommand
+// * !success && notification
+// -- Cut command
+// * fixCut
+// * tryToCutCopy
+// * execCommand
+// * !success && notification
+// -- Paste command
+// * fire 'paste' on editable ('beforepaste' for IE)
+// * !canceled && execCommand 'paste'
+// * !success && fire 'pasteDialog' on editor
+// -- Paste from native context menu & menubar
+// (Fx & Webkits are handled in 'paste' default listener.
+// Opera cannot be handled at all because it doesn't fire any events
+// Special treatment is needed for IE, for which is this part of doc)
+// * listen 'onpaste'
+// * cancel native event
+// * fire 'beforePaste' on editor
+// * if ( !canceled && ( htmlInDataTransfer || !external paste) && dataTransfer is not empty ) getClipboardDataByPastebin
+// * execIECommand( 'paste' ) -> this fires another 'paste' event, so cancel it
+// * fire 'paste' on editor
+// * !canceled && fire 'afterPaste' on editor
+//
+//
+// PASTE EVENT - PREPROCESSING:
+// -- Possible dataValue types: auto, text, html.
+// -- Possible dataValue contents:
+// * text (possible \n\r)
+// * htmlified text (text + br,div,p - no presentational markup & attrs - depends on browser)
+// * html
+// -- Possible flags:
+// * htmlified - if true then content is a HTML even if no markup inside. This flag is set
+// for content from editable pastebins, because they 'htmlify' pasted content.
+//
+// -- Type: auto:
+// * content: htmlified text -> filter, unify text markup (brs, ps, divs), set type: text
+// * content: html -> filter, set type: html
+// -- Type: text:
+// * content: htmlified text -> filter, unify text markup
+// * content: html -> filter, strip presentational markup, unify text markup
+// -- Type: html:
+// * content: htmlified text -> filter, unify text markup
+// * content: html -> filter
+//
+// -- Phases:
+// * if dataValue is empty copy data from dataTransfer to dataValue (priority 1)
+// * filtering (priorities 3-5) - e.g. pastefromword filters
+// * content type sniffing (priority 6)
+// * markup transformations for text (priority 6)
+//
+// DRAG & DROP EXECUTION FLOWS:
+// -- Drag
+// * save to the global object:
+// * drag timestamp (with 'cke-' prefix),
+// * selected html,
+// * drag range,
+// * editor instance.
+// * put drag timestamp into event.dataTransfer.text
+// -- Drop
+// * if events text == saved timestamp && editor == saved editor
+// internal drag & drop occurred
+// * getRangeAtDropPosition
+// * create bookmarks for drag and drop ranges starting from the end of the document
+// * dragRange.deleteContents()
+// * fire 'paste' with saved html and drop range
+// * if events text == saved timestamp && editor != saved editor
+// cross editor drag & drop occurred
+// * getRangeAtDropPosition
+// * fire 'paste' with saved html
+// * dragRange.deleteContents()
+// * FF: refreshCursor on afterPaste
+// * if events text != saved timestamp
+// drop form external source occurred
+// * getRangeAtDropPosition
+// * if event contains html data then fire 'paste' with html
+// * else if event contains text data then fire 'paste' with encoded text
+// * FF: refreshCursor on afterPaste
+
+'use strict';
+
+( function() {
+ // Register the plugin.
+ CKEDITOR.plugins.add( 'clipboard', {
+ requires: 'dialog',
+ // jscs:disable maximumLineLength
+ lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
+ // jscs:enable maximumLineLength
+ icons: 'copy,copy-rtl,cut,cut-rtl,paste,paste-rtl', // %REMOVE_LINE_CORE%
+ hidpi: true, // %REMOVE_LINE_CORE%
+ init: function( editor ) {
+ var filterType,
+ filtersFactory = filtersFactoryFactory();
+
+ if ( editor.config.forcePasteAsPlainText ) {
+ filterType = 'plain-text';
+ } else if ( editor.config.pasteFilter ) {
+ filterType = editor.config.pasteFilter;
+ }
+ // On Webkit the pasteFilter defaults 'semantic-content' because pasted data is so terrible
+ // that it must be always filtered.
+ else if ( CKEDITOR.env.webkit && !( 'pasteFilter' in editor.config ) ) {
+ filterType = 'semantic-content';
+ }
+
+ editor.pasteFilter = filtersFactory.get( filterType );
+
+ initPasteClipboard( editor );
+ initDragDrop( editor );
+
+ CKEDITOR.dialog.add( 'paste', CKEDITOR.getUrl( this.path + 'dialogs/paste.js' ) );
+
+ editor.on( 'paste', function( evt ) {
+ // Init `dataTransfer` if `paste` event was fired without it, so it will be always available.
+ if ( !evt.data.dataTransfer ) {
+ evt.data.dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer();
+ }
+
+ // If dataValue is already set (manually or by paste bin), so do not override it.
+ if ( evt.data.dataValue ) {
+ return;
+ }
+
+ var dataTransfer = evt.data.dataTransfer,
+ // IE support only text data and throws exception if we try to get html data.
+ // This html data object may also be empty if we drag content of the textarea.
+ value = dataTransfer.getData( 'text/html' );
+
+ if ( value ) {
+ evt.data.dataValue = value;
+ evt.data.type = 'html';
+ } else {
+ // Try to get text data otherwise.
+ value = dataTransfer.getData( 'text/plain' );
+
+ if ( value ) {
+ evt.data.dataValue = editor.editable().transformPlainTextToHtml( value );
+ evt.data.type = 'text';
+ }
+ }
+ }, null, null, 1 );
+
+ editor.on( 'paste', function( evt ) {
+ var data = evt.data.dataValue,
+ blockElements = CKEDITOR.dtd.$block;
+
+ // Filter webkit garbage.
+ if ( data.indexOf( 'Apple-' ) > -1 ) {
+ // Replace special webkit's with simple space, because webkit
+ // produces them even for normal spaces.
+ data = data.replace( / <\/span>/gi, ' ' );
+
+ // Strip around white-spaces when not in forced 'html' content type.
+ // This spans are created only when pasting plain text into Webkit,
+ // but for safety reasons remove them always.
+ if ( evt.data.type != 'html' ) {
+ data = data.replace( /]*>([^<]*)<\/span>/gi, function( all, spaces ) {
+ // Replace tabs with 4 spaces like Fx does.
+ return spaces.replace( /\t/g, ' ' );
+ } );
+ }
+
+ // This br is produced only when copying & pasting HTML content.
+ if ( data.indexOf( '
' ) > -1 ) {
+ evt.data.startsWithEOL = 1;
+ evt.data.preSniffing = 'html'; // Mark as not text.
+ data = data.replace( /
/, '' );
+ }
+
+ // Remove all other classes.
+ data = data.replace( /(<[^>]+) class="Apple-[^"]*"/gi, '$1' );
+ }
+
+ // Strip editable that was copied from inside. (#9534)
+ if ( data.match( /^<[^<]+cke_(editable|contents)/i ) ) {
+ var tmp,
+ editable_wrapper,
+ wrapper = new CKEDITOR.dom.element( 'div' );
+
+ wrapper.setHtml( data );
+ // Verify for sure and check for nested editor UI parts. (#9675)
+ while ( wrapper.getChildCount() == 1 &&
+ ( tmp = wrapper.getFirst() ) &&
+ tmp.type == CKEDITOR.NODE_ELEMENT && // Make sure first-child is element.
+ ( tmp.hasClass( 'cke_editable' ) || tmp.hasClass( 'cke_contents' ) ) ) {
+ wrapper = editable_wrapper = tmp;
+ }
+
+ // If editable wrapper was found strip it and bogus
(added on FF).
+ if ( editable_wrapper )
+ data = editable_wrapper.getHtml().replace( /
$/i, '' );
+ }
+
+ if ( CKEDITOR.env.ie ) {
+ //
- paragraphs can be separated by new \r\n ).
+ if ( !data.match( /^([^<]|
)*$/gi ) && !data.match( /^(
([^<]|
)*<\/p>|(\r\n))*$/gi ) )
+ return 'html';
+ } else if ( CKEDITOR.env.gecko ) {
+ // Text or
.
+ if ( !data.match( /^([^<]|
)*$/gi ) )
+ return 'html';
+ } else {
+ return 'html';
+ }
+
+ return 'htmlifiedtext';
+ }
+
+ // This function transforms what browsers produce when
+ // pasting plain text into editable element (see clipboard/paste.html TCs
+ // for more info) into correct HTML (similar to that produced by text2Html).
+ function htmlifiedTextHtmlification( config, data ) {
+ function repeatParagraphs( repeats ) {
+ // Repeat blocks floor((n+1)/2) times.
+ // Even number of repeats - add
at the beginning of last
. + return CKEDITOR.tools.repeat( '
', ~~( repeats / 2 ) ) + ( repeats % 2 == 1 ? '
' : '' );
+ }
+
+ // Replace adjacent white-spaces (EOLs too - Fx sometimes keeps them) with one space.
+ data = data.replace( /\s+/g, ' ' )
+ // Remove spaces from between tags.
+ .replace( /> +<' )
+ // Normalize XHTML syntax and upper cased
tags.
+ .replace( /
/gi, '
' );
+
+ // IE - lower cased tags.
+ data = data.replace( /<\/?[A-Z]+>/g, function( match ) {
+ return match.toLowerCase();
+ } );
+
+ // Don't touch single lines (no
) - nothing to do here.
+ if ( data.match( /^[^<]$/ ) )
+ return data;
+
+ // Webkit.
+ if ( CKEDITOR.env.webkit && data.indexOf( '
' + data.replace( /(
' + data.replace( /(
){2,}/g, function( match ) {
+ return repeatParagraphs( match.length / 4 );
+ } ) + '
element completely, because it's a basic structural element, + // so it tries to replace it with an element created based on the active enter mode, eventually doing nothing. + // + // Now you can sleep well. + return filters.plainText || ( filters.plainText = new CKEDITOR.filter( 'br' ) ); + } else if ( type == 'semantic-content' ) { + return filters.semanticContent || ( filters.semanticContent = createSemanticContentFilter() ); + } else if ( type ) { + // Create filter based on rules (string or object). + return new CKEDITOR.filter( type ); + } + + return null; + } + }; + } + + function filterContent( editor, data, filter ) { + var fragment = CKEDITOR.htmlParser.fragment.fromHtml( data ), + writer = new CKEDITOR.htmlParser.basicWriter(); + + filter.applyTo( fragment, true, false, editor.activeEnterMode ); + fragment.writeHtml( writer ); + + return writer.getHtml(); + } + + function switchEnterMode( config, data ) { + if ( config.enterMode == CKEDITOR.ENTER_BR ) { + data = data.replace( /(<\/p>
)+/g, function( match ) {
+ return CKEDITOR.tools.repeat( ' This is some sample HTML content.
+ This sample shows how to use the
+ CKEditor Dialog API
+ to customize CKEditor dialog windows without changing the original editor code.
+ The following customizations are being done in the example below:
+
+ For details on how to create this setup check the source code of this sample page.
+ A custom dialog is added to the editors using the The below editor modify the dialog definition of the above added dialog using the
', match.length / 7 * 2 );
+ } ).replace( /<\/?p>/g, '' );
+ } else if ( config.enterMode == CKEDITOR.ENTER_DIV ) {
+ data = data.replace( /<(\/)?p>/g, '<$1div>' );
+ }
+
+ return data;
+ }
+
+ function preventDefaultSetDropEffectToNone( evt ) {
+ evt.data.preventDefault();
+ evt.data.$.dataTransfer.dropEffect = 'none';
+ }
+
+ function initDragDrop( editor ) {
+ var clipboard = CKEDITOR.plugins.clipboard;
+
+ editor.on( 'contentDom', function() {
+ var editable = editor.editable(),
+ dropTarget = CKEDITOR.plugins.clipboard.getDropTarget( editor ),
+ top = editor.ui.space( 'top' ),
+ bottom = editor.ui.space( 'bottom' );
+
+ // -------------- DRAGOVER TOP & BOTTOM --------------
+
+ // Not allowing dragging on toolbar and bottom (#12613).
+ clipboard.preventDefaultDropOnElement( top );
+ clipboard.preventDefaultDropOnElement( bottom );
+
+ // -------------- DRAGSTART --------------
+ // Listed on dragstart to mark internal and cross-editor drag & drop
+ // and save range and selected HTML.
+
+ editable.attachListener( dropTarget, 'dragstart', fireDragEvent );
+
+ // Make sure to reset data transfer (in case dragend was not called or was canceled).
+ editable.attachListener( editor, 'dragstart', clipboard.resetDragDataTransfer, clipboard, null, 1 );
+
+ // Create a dataTransfer object and save it globally.
+ editable.attachListener( editor, 'dragstart', function( evt ) {
+ clipboard.initDragDataTransfer( evt, editor );
+ }, null, null, 2 );
+
+ editable.attachListener( editor, 'dragstart', function() {
+ // Save drag range globally for cross editor D&D.
+ var dragRange = clipboard.dragRange = editor.getSelection().getRanges()[ 0 ];
+
+ // Store number of children, so we can later tell if any text node was split on drop. (#13011, #13447)
+ if ( CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) {
+ clipboard.dragStartContainerChildCount = dragRange ? getContainerChildCount( dragRange.startContainer ) : null;
+ clipboard.dragEndContainerChildCount = dragRange ? getContainerChildCount( dragRange.endContainer ) : null;
+ }
+ }, null, null, 100 );
+
+ // -------------- DRAGEND --------------
+ // Clean up on dragend.
+
+ editable.attachListener( dropTarget, 'dragend', fireDragEvent );
+
+ // Init data transfer if someone wants to use it in dragend.
+ editable.attachListener( editor, 'dragend', clipboard.initDragDataTransfer, clipboard, null, 1 );
+
+ // When drag & drop is done we need to reset dataTransfer so the future
+ // external drop will be not recognize as internal.
+ editable.attachListener( editor, 'dragend', clipboard.resetDragDataTransfer, clipboard, null, 100 );
+
+ // -------------- DRAGOVER --------------
+ // We need to call preventDefault on dragover because otherwise if
+ // we drop image it will overwrite document.
+
+ editable.attachListener( dropTarget, 'dragover', function( evt ) {
+ var target = evt.data.getTarget();
+
+ // Prevent reloading page when dragging image on empty document (#12619).
+ if ( target && target.is && target.is( 'html' ) ) {
+ evt.data.preventDefault();
+ return;
+ }
+
+ // If we do not prevent default dragover on IE the file path
+ // will be loaded and we will lose content. On the other hand
+ // if we prevent it the cursor will not we shown, so we prevent
+ // dragover only on IE, on versions which support file API and only
+ // if the event contains files.
+ if ( CKEDITOR.env.ie &&
+ CKEDITOR.plugins.clipboard.isFileApiSupported &&
+ evt.data.$.dataTransfer.types.contains( 'Files' ) ) {
+ evt.data.preventDefault();
+ }
+ } );
+
+ // -------------- DROP --------------
+
+ editable.attachListener( dropTarget, 'drop', function( evt ) {
+ // Do nothing if event was already prevented. (#13879)
+ if ( evt.data.$.defaultPrevented ) {
+ return;
+ }
+
+ // Cancel native drop.
+ evt.data.preventDefault();
+
+ var target = evt.data.getTarget(),
+ readOnly = target.isReadOnly();
+
+ // Do nothing if drop on non editable element (#13015).
+ // The tag isn't editable (body is), but we want to allow drop on it
+ // (so it is possible to drop below editor contents).
+ if ( readOnly && !( target.type == CKEDITOR.NODE_ELEMENT && target.is( 'html' ) ) ) {
+ return;
+ }
+
+ // Getting drop position is one of the most complex parts.
+ var dropRange = clipboard.getRangeAtDropPosition( evt, editor ),
+ dragRange = clipboard.dragRange;
+
+ // Do nothing if it was not possible to get drop range.
+ if ( !dropRange ) {
+ return;
+ }
+
+ // Fire drop.
+ fireDragEvent( evt, dragRange, dropRange );
+ }, null, null, 9999 );
+
+ // Create dataTransfer or get it, if it was created before.
+ editable.attachListener( editor, 'drop', clipboard.initDragDataTransfer, clipboard, null, 1 );
+
+ // Execute drop action, fire paste.
+ editable.attachListener( editor, 'drop', function( evt ) {
+ var data = evt.data;
+
+ if ( !data ) {
+ return;
+ }
+
+ // Let user modify drag and drop range.
+ var dropRange = data.dropRange,
+ dragRange = data.dragRange,
+ dataTransfer = data.dataTransfer;
+
+ if ( dataTransfer.getTransferType( editor ) == CKEDITOR.DATA_TRANSFER_INTERNAL ) {
+ // Execute drop with a timeout because otherwise selection, after drop,
+ // on IE is in the drag position, instead of drop position.
+ setTimeout( function() {
+ clipboard.internalDrop( dragRange, dropRange, dataTransfer, editor );
+ }, 0 );
+ } else if ( dataTransfer.getTransferType( editor ) == CKEDITOR.DATA_TRANSFER_CROSS_EDITORS ) {
+ crossEditorDrop( dragRange, dropRange, dataTransfer );
+ } else {
+ externalDrop( dropRange, dataTransfer );
+ }
+ }, null, null, 9999 );
+
+ // Cross editor drag and drop (drag in one Editor and drop in the other).
+ function crossEditorDrop( dragRange, dropRange, dataTransfer ) {
+ // Paste event should be fired before delete contents because otherwise
+ // Chrome have a problem with drop range (Chrome split the drop
+ // range container so the offset is bigger then container length).
+ dropRange.select();
+ firePasteEvents( editor, { dataTransfer: dataTransfer, method: 'drop' }, 1 );
+
+ // Remove dragged content and make a snapshot.
+ dataTransfer.sourceEditor.fire( 'saveSnapshot' );
+
+ dataTransfer.sourceEditor.editable().extractHtmlFromRange( dragRange );
+
+ // Make some selection before saving snapshot, otherwise error will be thrown, because
+ // there will be no valid selection after content is removed.
+ dataTransfer.sourceEditor.getSelection().selectRanges( [ dragRange ] );
+ dataTransfer.sourceEditor.fire( 'saveSnapshot' );
+ }
+
+ // Drop from external source.
+ function externalDrop( dropRange, dataTransfer ) {
+ // Paste content into the drop position.
+ dropRange.select();
+
+ firePasteEvents( editor, { dataTransfer: dataTransfer, method: 'drop' }, 1 );
+
+ // Usually we reset DataTranfer on dragend,
+ // but dragend is called on the same element as dragstart
+ // so it will not be called on on external drop.
+ clipboard.resetDragDataTransfer();
+ }
+
+ // Fire drag/drop events (dragstart, dragend, drop).
+ function fireDragEvent( evt, dragRange, dropRange ) {
+ var eventData = {
+ $: evt.data.$,
+ target: evt.data.getTarget()
+ };
+
+ if ( dragRange ) {
+ eventData.dragRange = dragRange;
+ }
+ if ( dropRange ) {
+ eventData.dropRange = dropRange;
+ }
+
+ if ( editor.fire( evt.name, eventData ) === false ) {
+ evt.data.preventDefault();
+ }
+ }
+
+ function getContainerChildCount( container ) {
+ if ( container.type != CKEDITOR.NODE_ELEMENT ) {
+ container = container.getParent();
+ }
+
+ return container.getChildCount();
+ }
+ } );
+ }
+
+ /**
+ * @singleton
+ * @class CKEDITOR.plugins.clipboard
+ */
+ CKEDITOR.plugins.clipboard = {
+ /**
+ * True if the environment allows to set data on copy or cut manually. This value is false in IE, because this browser
+ * shows the security dialog window when the script tries to set clipboard data and on iOS, because custom data is
+ * not saved to clipboard there.
+ *
+ * @since 4.5
+ * @readonly
+ * @property {Boolean}
+ */
+ isCustomCopyCutSupported: !CKEDITOR.env.ie && !CKEDITOR.env.iOS,
+
+ /**
+ * True if the environment supports MIME types and custom data types in dataTransfer/cliboardData getData/setData methods.
+ *
+ * @since 4.5
+ * @readonly
+ * @property {Boolean}
+ */
+ isCustomDataTypesSupported: !CKEDITOR.env.ie,
+
+ /**
+ * True if the environment supports File API.
+ *
+ * @since 4.5
+ * @readonly
+ * @property {Boolean}
+ */
+ isFileApiSupported: !CKEDITOR.env.ie || CKEDITOR.env.version > 9,
+
+ /**
+ * Main native paste event editable should listen to.
+ *
+ * **Note:** Safari does not like the {@link CKEDITOR.editor#beforePaste} event — it sometimes does not
+ * handle Ctrl+C properly. This is probably caused by some race condition between events.
+ * Chrome, Firefox and Edge work well with both events, so it is better to use {@link CKEDITOR.editor#paste}
+ * which will handle pasting from e.g. browsers' menu bars.
+ * IE7/8 does not like the {@link CKEDITOR.editor#paste} event for which it is throwing random errors.
+ *
+ * @since 4.5
+ * @readonly
+ * @property {String}
+ */
+ mainPasteEvent: ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) ? 'beforepaste' : 'paste',
+
+ /**
+ * Returns `true` if it is expected that a browser provides HTML data through the Clipboard API.
+ * If not, this method returns `false` and as a result CKEditor will use the paste bin. Read more in
+ * the [Clipboard Integration](http://docs.ckeditor.com/#!/guide/dev_clipboard-section-clipboard-api) guide.
+ *
+ * @since 4.5.2
+ * @returns {Boolean}
+ */
+ canClipboardApiBeTrusted: function( dataTransfer, editor ) {
+ // If it's an internal or cross-editor data transfer, then it means that custom cut/copy/paste support works
+ // and that the data were put manually on the data transfer so we can be sure that it's available.
+ if ( dataTransfer.getTransferType( editor ) != CKEDITOR.DATA_TRANSFER_EXTERNAL ) {
+ return true;
+ }
+
+ // In Chrome we can trust Clipboard API, with the exception of Chrome on Android (in both - mobile and desktop modes), where
+ // clipboard API is not available so we need to check it (#13187).
+ if ( CKEDITOR.env.chrome && !dataTransfer.isEmpty() ) {
+ return true;
+ }
+
+ // Because of a Firefox bug HTML data are not available in some cases (e.g. paste from Word), in such cases we
+ // need to use the pastebin (#13528, https://bugzilla.mozilla.org/show_bug.cgi?id=1183686).
+ if ( CKEDITOR.env.gecko && ( dataTransfer.getData( 'text/html' ) || dataTransfer.getFilesCount() ) ) {
+ return true;
+ }
+
+ // In Safari and IE HTML data is not available though the Clipboard API.
+ // In Edge things are a bit messy at the moment -
+ // https://connect.microsoft.com/IE/feedback/details/1572456/edge-clipboard-api-text-html-content-messed-up-in-event-clipboarddata
+ // It is safer to use the paste bin in unknown cases.
+ return false;
+ },
+
+ /**
+ * Returns the element that should be used as the target for the drop event.
+ *
+ * @since 4.5
+ * @param {CKEDITOR.editor} editor The editor instance.
+ * @returns {CKEDITOR.dom.domObject} the element that should be used as the target for the drop event.
+ */
+ getDropTarget: function( editor ) {
+ var editable = editor.editable();
+
+ // #11123 Firefox needs to listen on document, because otherwise event won't be fired.
+ // #11086 IE8 cannot listen on document.
+ if ( ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) || editable.isInline() ) {
+ return editable;
+ } else {
+ return editor.document;
+ }
+ },
+
+ /**
+ * IE 8 & 9 split text node on drop so the first node contains the
+ * text before the drop position and the second contains the rest. If you
+ * drag the content from the same node you will be not be able to get
+ * it (the range becomes invalid), so you need to join them back.
+ *
+ * Note that the first node in IE 8 & 9 is the original node object
+ * but with shortened content.
+ *
+ * Before:
+ * --- Text Node A ----------------------------------
+ * /\
+ * Drag position
+ *
+ * After (IE 8 & 9):
+ * --- Text Node A ----- --- Text Node B -----------
+ * /\ /\
+ * Drop position Drag position
+ * (invalid)
+ *
+ * After (other browsers):
+ * --- Text Node A ----------------------------------
+ * /\ /\
+ * Drop position Drag position
+ *
+ * **Note:** This function is in the public scope for tests usage only.
+ *
+ * @since 4.5
+ * @private
+ * @param {CKEDITOR.dom.range} dragRange The drag range.
+ * @param {CKEDITOR.dom.range} dropRange The drop range.
+ * @param {Number} preDragStartContainerChildCount The number of children of the drag range start container before the drop.
+ * @param {Number} preDragEndContainerChildCount The number of children of the drag range end container before the drop.
+ */
+ fixSplitNodesAfterDrop: function( dragRange, dropRange, preDragStartContainerChildCount, preDragEndContainerChildCount ) {
+ var dropContainer = dropRange.startContainer;
+
+ if (
+ typeof preDragEndContainerChildCount != 'number' ||
+ typeof preDragStartContainerChildCount != 'number'
+ ) {
+ return;
+ }
+
+ // We are only concerned about ranges anchored in elements.
+ if ( dropContainer.type != CKEDITOR.NODE_ELEMENT ) {
+ return;
+ }
+
+ if ( handleContainer( dragRange.startContainer, dropContainer, preDragStartContainerChildCount ) ) {
+ return;
+ }
+
+ if ( handleContainer( dragRange.endContainer, dropContainer, preDragEndContainerChildCount ) ) {
+ return;
+ }
+
+ function handleContainer( dragContainer, dropContainer, preChildCount ) {
+ var dragElement = dragContainer;
+ if ( dragElement.type == CKEDITOR.NODE_TEXT ) {
+ dragElement = dragContainer.getParent();
+ }
+
+ if ( dragElement.equals( dropContainer ) && preChildCount != dropContainer.getChildCount() ) {
+ applyFix( dropRange );
+ return true;
+ }
+ }
+
+ function applyFix( dropRange ) {
+ var nodeBefore = dropRange.startContainer.getChild( dropRange.startOffset - 1 ),
+ nodeAfter = dropRange.startContainer.getChild( dropRange.startOffset );
+
+ if (
+ nodeBefore && nodeBefore.type == CKEDITOR.NODE_TEXT &&
+ nodeAfter && nodeAfter.type == CKEDITOR.NODE_TEXT
+ ) {
+ var offset = nodeBefore.getLength();
+
+ nodeBefore.setText( nodeBefore.getText() + nodeAfter.getText() );
+ nodeAfter.remove();
+
+ dropRange.setStart( nodeBefore, offset );
+ dropRange.collapse( true );
+ }
+ }
+ },
+
+ /**
+ * Checks whether turning the drag range into bookmarks will invalidate the drop range.
+ * This usually happens when the drop range shares the container with the drag range and is
+ * located after the drag range, but there are countless edge cases.
+ *
+ * This function is stricly related to {@link #internalDrop} which toggles
+ * order in which it creates bookmarks for both ranges based on a value returned
+ * by this method. In some cases this method returns a value which is not necessarily
+ * true in terms of what it was meant to check, but it is convenient, because
+ * we know how it is interpreted in {@link #internalDrop}, so the correct
+ * behavior of the entire algorithm is assured.
+ *
+ * **Note:** This function is in the public scope for tests usage only.
+ *
+ * @since 4.5
+ * @private
+ * @param {CKEDITOR.dom.range} dragRange The first range to compare.
+ * @param {CKEDITOR.dom.range} dropRange The second range to compare.
+ * @returns {Boolean} `true` if the first range is before the second range.
+ */
+ isDropRangeAffectedByDragRange: function( dragRange, dropRange ) {
+ var dropContainer = dropRange.startContainer,
+ dropOffset = dropRange.endOffset;
+
+ // Both containers are the same and drop offset is at the same position or later.
+ // " A L] A " " M A "
+ // ^ ^
+ if ( dragRange.endContainer.equals( dropContainer ) && dragRange.endOffset <= dropOffset ) {
+ return true;
+ }
+
+ // Bookmark for drag start container will mess up with offsets.
+ // " O [L A " " M A "
+ // ^ ^
+ if (
+ dragRange.startContainer.getParent().equals( dropContainer ) &&
+ dragRange.startContainer.getIndex() < dropOffset
+ ) {
+ return true;
+ }
+
+ // Bookmark for drag end container will mess up with offsets.
+ // " O] L A " " M A "
+ // ^ ^
+ if (
+ dragRange.endContainer.getParent().equals( dropContainer ) &&
+ dragRange.endContainer.getIndex() < dropOffset
+ ) {
+ return true;
+ }
+
+ return false;
+ },
+
+ /**
+ * Internal drag and drop (drag and drop in the same editor instance).
+ *
+ * **Note:** This function is in the public scope for tests usage only.
+ *
+ * @since 4.5
+ * @private
+ * @param {CKEDITOR.dom.range} dragRange The first range to compare.
+ * @param {CKEDITOR.dom.range} dropRange The second range to compare.
+ * @param {CKEDITOR.plugins.clipboard.dataTransfer} dataTransfer
+ * @param {CKEDITOR.editor} editor
+ */
+ internalDrop: function( dragRange, dropRange, dataTransfer, editor ) {
+ var clipboard = CKEDITOR.plugins.clipboard,
+ editable = editor.editable(),
+ dragBookmark, dropBookmark, isDropRangeAffected;
+
+ // Save and lock snapshot so there will be only
+ // one snapshot for both remove and insert content.
+ editor.fire( 'saveSnapshot' );
+ editor.fire( 'lockSnapshot', { dontUpdate: 1 } );
+
+ if ( CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) {
+ this.fixSplitNodesAfterDrop(
+ dragRange,
+ dropRange,
+ clipboard.dragStartContainerChildCount,
+ clipboard.dragEndContainerChildCount
+ );
+ }
+
+ // Because we manipulate multiple ranges we need to do it carefully,
+ // changing one range (event creating a bookmark) may make other invalid.
+ // We need to change ranges into bookmarks so we can manipulate them easily in the future.
+ // We can change the range which is later in the text before we change the preceding range.
+ // We call isDropRangeAffectedByDragRange to test the order of ranges.
+ isDropRangeAffected = this.isDropRangeAffectedByDragRange( dragRange, dropRange );
+ if ( !isDropRangeAffected ) {
+ dragBookmark = dragRange.createBookmark( false );
+ }
+ dropBookmark = dropRange.clone().createBookmark( false );
+ if ( isDropRangeAffected ) {
+ dragBookmark = dragRange.createBookmark( false );
+ }
+
+ // Check if drop range is inside range.
+ // This is an edge case when we drop something on editable's margin/padding.
+ // That space is not treated as a part of the range we drag, so it is possible to drop there.
+ // When we drop, browser tries to find closest drop position and it finds it inside drag range. (#13453)
+ var startNode = dragBookmark.startNode,
+ endNode = dragBookmark.endNode,
+ dropNode = dropBookmark.startNode,
+ dropInsideDragRange =
+ // Must check endNode because dragRange could be collapsed in some edge cases (simulated DnD).
+ endNode &&
+ ( startNode.getPosition( dropNode ) & CKEDITOR.POSITION_PRECEDING ) &&
+ ( endNode.getPosition( dropNode ) & CKEDITOR.POSITION_FOLLOWING );
+
+ // If the drop range happens to be inside drag range change it's position to the beginning of the drag range.
+ if ( dropInsideDragRange ) {
+ // We only change position of bookmark span that is connected with dropBookmark.
+ // dropRange will be overwritten and set to the dropBookmark later.
+ dropNode.insertBefore( startNode );
+ }
+
+ // No we can safely delete content for the drag range...
+ dragRange = editor.createRange();
+ dragRange.moveToBookmark( dragBookmark );
+ editable.extractHtmlFromRange( dragRange, 1 );
+
+ // ...and paste content into the drop position.
+ dropRange = editor.createRange();
+ dropRange.moveToBookmark( dropBookmark );
+
+ // We do not select drop range, because of may be in the place we can not set the selection
+ // (e.g. between blocks, in case of block widget D&D). We put range to the paste event instead.
+ firePasteEvents( editor, { dataTransfer: dataTransfer, method: 'drop', range: dropRange }, 1 );
+
+ editor.fire( 'unlockSnapshot' );
+ },
+
+ /**
+ * Gets the range from the `drop` event.
+ *
+ * @since 4.5
+ * @param {Object} domEvent A native DOM drop event object.
+ * @param {CKEDITOR.editor} editor The source editor instance.
+ * @returns {CKEDITOR.dom.range} range at drop position.
+ */
+ getRangeAtDropPosition: function( dropEvt, editor ) {
+ var $evt = dropEvt.data.$,
+ x = $evt.clientX,
+ y = $evt.clientY,
+ $range,
+ defaultRange = editor.getSelection( true ).getRanges()[ 0 ],
+ range = editor.createRange();
+
+ // Make testing possible.
+ if ( dropEvt.data.testRange )
+ return dropEvt.data.testRange;
+
+ // Webkits.
+ if ( document.caretRangeFromPoint ) {
+ $range = editor.document.$.caretRangeFromPoint( x, y );
+ range.setStart( CKEDITOR.dom.node( $range.startContainer ), $range.startOffset );
+ range.collapse( true );
+ }
+ // FF.
+ else if ( $evt.rangeParent ) {
+ range.setStart( CKEDITOR.dom.node( $evt.rangeParent ), $evt.rangeOffset );
+ range.collapse( true );
+ }
+ // IEs 9+.
+ // We check if editable is focused to make sure that it's an internal DnD. External DnD must use the second
+ // mechanism because of http://dev.ckeditor.com/ticket/13472#comment:6.
+ else if ( CKEDITOR.env.ie && CKEDITOR.env.version > 8 && defaultRange && editor.editable().hasFocus ) {
+ // On IE 9+ range by default is where we expected it.
+ // defaultRange may be undefined if dragover was canceled (file drop).
+ return defaultRange;
+ }
+ // IE 8 and all IEs if !defaultRange or external DnD.
+ else if ( document.body.createTextRange ) {
+ // To use this method we need a focus (which may be somewhere else in case of external drop).
+ editor.focus();
+
+ $range = editor.document.getBody().$.createTextRange();
+ try {
+ var sucess = false;
+
+ // If user drop between text line IEs moveToPoint throws exception:
+ //
+ // Lorem ipsum pulvinar purus et euismod
+ //
+ // dolor sit amet,| consectetur adipiscing
+ // *
+ // vestibulum tincidunt augue eget tempus.
+ //
+ // * - drop position
+ // | - expected cursor position
+ //
+ // So we try to call moveToPoint with +-1px up to +-20px above or
+ // below original drop position to find nearest good drop position.
+ for ( var i = 0; i < 20 && !sucess; i++ ) {
+ if ( !sucess ) {
+ try {
+ $range.moveToPoint( x, y - i );
+ sucess = true;
+ } catch ( err ) {
+ }
+ }
+ if ( !sucess ) {
+ try {
+ $range.moveToPoint( x, y + i );
+ sucess = true;
+ } catch ( err ) {
+ }
+ }
+ }
+
+ if ( sucess ) {
+ var id = 'cke-temp-' + ( new Date() ).getTime();
+ $range.pasteHTML( '\u200b' );
+
+ var span = editor.document.getById( id );
+ range.moveToPosition( span, CKEDITOR.POSITION_BEFORE_START );
+ span.remove();
+ } else {
+ // If the fist method does not succeed we might be next to
+ // the short element (like header):
+ //
+ // Lorem ipsum pulvinar purus et euismod.
+ //
+ //
+ // SOME HEADER| *
+ //
+ //
+ // vestibulum tincidunt augue eget tempus.
+ //
+ // * - drop position
+ // | - expected cursor position
+ //
+ // In such situation elementFromPoint returns proper element. Using getClientRect
+ // it is possible to check if the cursor should be at the beginning or at the end
+ // of paragraph.
+ var $element = editor.document.$.elementFromPoint( x, y ),
+ element = new CKEDITOR.dom.element( $element ),
+ rect;
+
+ if ( !element.equals( editor.editable() ) && element.getName() != 'html' ) {
+ rect = element.getClientRect();
+
+ if ( x < rect.left ) {
+ range.setStartAt( element, CKEDITOR.POSITION_AFTER_START );
+ range.collapse( true );
+ } else {
+ range.setStartAt( element, CKEDITOR.POSITION_BEFORE_END );
+ range.collapse( true );
+ }
+ }
+ // If drop happens on no element elementFromPoint returns html or body.
+ //
+ // * |Lorem ipsum pulvinar purus et euismod.
+ //
+ // vestibulum tincidunt augue eget tempus.
+ //
+ // * - drop position
+ // | - expected cursor position
+ //
+ // In such case we can try to use default selection. If startContainer is not
+ // 'editable' element it is probably proper selection.
+ else if ( defaultRange && defaultRange.startContainer &&
+ !defaultRange.startContainer.equals( editor.editable() ) ) {
+ return defaultRange;
+
+ // Otherwise we can not find any drop position and we have to return null
+ // and cancel drop event.
+ } else {
+ return null;
+ }
+
+ }
+ } catch ( err ) {
+ return null;
+ }
+ } else {
+ return null;
+ }
+
+ return range;
+ },
+
+ /**
+ * This function tries to link the `evt.data.dataTransfer` property of the {@link CKEDITOR.editor#dragstart},
+ * {@link CKEDITOR.editor#dragend} and {@link CKEDITOR.editor#drop} events to a single
+ * {@link CKEDITOR.plugins.clipboard.dataTransfer} object.
+ *
+ * This method is automatically used by the core of the drag and drop functionality and
+ * usually does not have to be called manually when using the drag and drop events.
+ *
+ * This method behaves differently depending on whether the drag and drop events were fired
+ * artificially (to represent a non-native drag and drop) or whether they were caused by the native drag and drop.
+ *
+ * If the native event is not available, then it will create a new {@link CKEDITOR.plugins.clipboard.dataTransfer}
+ * instance (if it does not exist already) and will link it to this and all following event objects until
+ * the {@link #resetDragDataTransfer} method is called. It means that all three drag and drop events must be fired
+ * in order to ensure that the data transfer is bound correctly.
+ *
+ * If the native event is available, then the {@link CKEDITOR.plugins.clipboard.dataTransfer} is identified
+ * by its ID and a new instance is assigned to the `evt.data.dataTransfer` only if the ID changed or
+ * the {@link #resetDragDataTransfer} method was called.
+ *
+ * @since 4.5
+ * @param {CKEDITOR.dom.event} [evt] A drop event object.
+ * @param {CKEDITOR.editor} [sourceEditor] The source editor instance.
+ */
+ initDragDataTransfer: function( evt, sourceEditor ) {
+ // Create a new dataTransfer object based on the drop event.
+ // If this event was used on dragstart to create dataTransfer
+ // both dataTransfer objects will have the same id.
+ var nativeDataTransfer = evt.data.$ ? evt.data.$.dataTransfer : null,
+ dataTransfer = new this.dataTransfer( nativeDataTransfer, sourceEditor );
+
+ if ( !nativeDataTransfer ) {
+ // No native event.
+ if ( this.dragData ) {
+ dataTransfer = this.dragData;
+ } else {
+ this.dragData = dataTransfer;
+ }
+ } else {
+ // Native event. If there is the same id we will replace dataTransfer with the one
+ // created on drag, because it contains drag editor, drag content and so on.
+ // Otherwise (in case of drag from external source) we save new object to
+ // the global clipboard.dragData.
+ if ( this.dragData && dataTransfer.id == this.dragData.id ) {
+ dataTransfer = this.dragData;
+ } else {
+ this.dragData = dataTransfer;
+ }
+ }
+
+ evt.data.dataTransfer = dataTransfer;
+ },
+
+ /**
+ * Removes the global {@link #dragData} so the next call to {@link #initDragDataTransfer}
+ * always creates a new instance of {@link CKEDITOR.plugins.clipboard.dataTransfer}.
+ *
+ * @since 4.5
+ */
+ resetDragDataTransfer: function() {
+ this.dragData = null;
+ },
+
+ /**
+ * Global object storing the data transfer of the current drag and drop operation.
+ * Do not use it directly, use {@link #initDragDataTransfer} and {@link #resetDragDataTransfer}.
+ *
+ * Note: This object is global (meaning that it is not related to a single editor instance)
+ * in order to handle drag and drop from one editor into another.
+ *
+ * @since 4.5
+ * @private
+ * @property {CKEDITOR.plugins.clipboard.dataTransfer} dragData
+ */
+
+ /**
+ * Range object to save the drag range and remove its content after the drop.
+ *
+ * @since 4.5
+ * @private
+ * @property {CKEDITOR.dom.range} dragRange
+ */
+
+ /**
+ * Initializes and links data transfer objects based on the paste event. If the data
+ * transfer object was already initialized on this event, the function will
+ * return that object. In IE it is not possible to link copy/cut and paste events
+ * so the method always returns a new object. The same happens if there is no paste event
+ * passed to the method.
+ *
+ * @since 4.5
+ * @param {CKEDITOR.dom.event} [evt] A paste event object.
+ * @param {CKEDITOR.editor} [sourceEditor] The source editor instance.
+ * @returns {CKEDITOR.plugins.clipboard.dataTransfer} The data transfer object.
+ */
+ initPasteDataTransfer: function( evt, sourceEditor ) {
+ if ( !this.isCustomCopyCutSupported ) {
+ return new this.dataTransfer( null, sourceEditor );
+ } else if ( evt && evt.data && evt.data.$ ) {
+ var dataTransfer = new this.dataTransfer( evt.data.$.clipboardData, sourceEditor );
+
+ if ( this.copyCutData && dataTransfer.id == this.copyCutData.id ) {
+ dataTransfer = this.copyCutData;
+ dataTransfer.$ = evt.data.$.clipboardData;
+ } else {
+ this.copyCutData = dataTransfer;
+ }
+
+ return dataTransfer;
+ } else {
+ return new this.dataTransfer( null, sourceEditor );
+ }
+ },
+
+ /**
+ * Prevents dropping on the specified element.
+ *
+ * @since 4.5
+ * @param {CKEDITOR.dom.element} element The element on which dropping should be disabled.
+ */
+ preventDefaultDropOnElement: function( element ) {
+ element && element.on( 'dragover', preventDefaultSetDropEffectToNone );
+ }
+ };
+
+ // Data type used to link drag and drop events.
+ //
+ // In IE URL data type is buggie and there is no way to mark drag & drop without
+ // modifying text data (which would be displayed if user drop content to the textarea)
+ // so we just read dragged text.
+ //
+ // In Chrome and Firefox we can use custom data types.
+ var clipboardIdDataType = CKEDITOR.plugins.clipboard.isCustomDataTypesSupported ? 'cke/id' : 'Text';
+ /**
+ * Facade for the native `dataTransfer`/`clipboadData` object to hide all differences
+ * between browsers.
+ *
+ * @since 4.5
+ * @class CKEDITOR.plugins.clipboard.dataTransfer
+ * @constructor Creates a class instance.
+ * @param {Object} [nativeDataTransfer] A native data transfer object.
+ * @param {CKEDITOR.editor} [editor] The source editor instance. If the editor is defined, dataValue will
+ * be created based on the editor content and the type will be 'html'.
+ */
+ CKEDITOR.plugins.clipboard.dataTransfer = function( nativeDataTransfer, editor ) {
+ if ( nativeDataTransfer ) {
+ this.$ = nativeDataTransfer;
+ }
+
+ this._ = {
+ metaRegExp: /^' +
+ '
' +
+ '' +
+ '' +
+ ' ' +
+ '' +
+ '' +
+ ' ' +
+ '', lang.auto, ' ' +
+ '' );
+
+ // Render the color boxes.
+ for ( var i = 0; i < colors.length; i++ ) {
+ if ( ( i % 8 ) === 0 )
+ output.push( '
' );
+
+ return output.join( '' );
+ }
+
+ function isUnstylable( ele ) {
+ return ( ele.getAttribute( 'contentEditable' ) == 'false' ) || ele.getAttribute( 'data-nostyle' );
+ }
+ }
+} );
+
+/**
+ * Whether to enable the **More Colors*** button in the color selectors.
+ *
+ * Read more in the [documentation](#!/guide/dev_colorbutton)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/colorbutton.html).
+ *
+ * config.colorButton_enableMore = false;
+ *
+ * @cfg {Boolean} [colorButton_enableMore=true]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * Defines the colors to be displayed in the color selectors. This is a string
+ * containing hexadecimal notation for HTML colors, without the `'#'` prefix.
+ *
+ * **Since 3.3:** A color name may optionally be defined by prefixing the entries with
+ * a name and the slash character. For example, `'FontColor1/FF9900'` will be
+ * displayed as the color `#FF9900` in the selector, but will be output as `'FontColor1'`.
+ *
+ * Read more in the [documentation](#!/guide/dev_colorbutton)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/colorbutton.html).
+ *
+ * // Brazil colors only.
+ * config.colorButton_colors = '00923E,F8C100,28166F';
+ *
+ * config.colorButton_colors = 'FontColor1/FF9900,FontColor2/0066CC,FontColor3/F00';
+ *
+ * @cfg {String} [colorButton_colors=see source]
+ * @member CKEDITOR.config
+ */
+CKEDITOR.config.colorButton_colors = '000,800000,8B4513,2F4F4F,008080,000080,4B0082,696969,' +
+ 'B22222,A52A2A,DAA520,006400,40E0D0,0000CD,800080,808080,' +
+ 'F00,FF8C00,FFD700,008000,0FF,00F,EE82EE,A9A9A9,' +
+ 'FFA07A,FFA500,FFFF00,00FF00,AFEEEE,ADD8E6,DDA0DD,D3D3D3,' +
+ 'FFF0F5,FAEBD7,FFFFE0,F0FFF0,F0FFFF,F0F8FF,E6E6FA,FFF';
+
+/**
+ * Stores the style definition that applies the text foreground color.
+ *
+ * Read more in the [documentation](#!/guide/dev_colorbutton)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/colorbutton.html).
+ *
+ * // This is actually the default value.
+ * config.colorButton_foreStyle = {
+ * element: 'span',
+ * styles: { color: '#(color)' }
+ * };
+ *
+ * @cfg [colorButton_foreStyle=see source]
+ * @member CKEDITOR.config
+ */
+CKEDITOR.config.colorButton_foreStyle = {
+ element: 'span',
+ styles: { 'color': '#(color)' },
+ overrides: [ {
+ element: 'font', attributes: { 'color': null }
+ } ]
+};
+
+/**
+ * Stores the style definition that applies the text background color.
+ *
+ * Read more in the [documentation](#!/guide/dev_colorbutton)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/colorbutton.html).
+ *
+ * // This is actually the default value.
+ * config.colorButton_backStyle = {
+ * element: 'span',
+ * styles: { 'background-color': '#(color)' }
+ * };
+ *
+ * @cfg [colorButton_backStyle=see source]
+ * @member CKEDITOR.config
+ */
+CKEDITOR.config.colorButton_backStyle = {
+ element: 'span',
+ styles: { 'background-color': '#(color)' }
+};
diff --git a/sources/plugins/colordialog/dialogs/colordialog.js b/sources/plugins/colordialog/dialogs/colordialog.js
new file mode 100644
index 00000000..f5ecd483
--- /dev/null
+++ b/sources/plugins/colordialog/dialogs/colordialog.js
@@ -0,0 +1,327 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.dialog.add( 'colordialog', function( editor ) {
+ // Define some shorthands.
+ var $el = CKEDITOR.dom.element,
+ $doc = CKEDITOR.document,
+ lang = editor.lang.colordialog;
+
+ // Reference the dialog.
+ var dialog;
+
+ var spacer = {
+ type: 'html',
+ html: ' '
+ };
+
+ var selected;
+
+ function clearSelected() {
+ $doc.getById( selHiColorId ).removeStyle( 'background-color' );
+ dialog.getContentElement( 'picker', 'selectedColor' ).setValue( '' );
+ selected && selected.removeAttribute( 'aria-selected' );
+ selected = null;
+ }
+
+ function updateSelected( evt ) {
+ var target = evt.data.getTarget(),
+ color;
+
+ if ( target.getName() == 'td' && ( color = target.getChild( 0 ).getHtml() ) ) {
+ selected = target;
+ selected.setAttribute( 'aria-selected', true );
+ dialog.getContentElement( 'picker', 'selectedColor' ).setValue( color );
+ }
+ }
+
+ // Basing black-white decision off of luma scheme using the Rec. 709 version
+ function whiteOrBlack( color ) {
+ color = color.replace( /^#/, '' );
+ for ( var i = 0, rgb = []; i <= 2; i++ )
+ rgb[ i ] = parseInt( color.substr( i * 2, 2 ), 16 );
+ var luma = ( 0.2126 * rgb[ 0 ] ) + ( 0.7152 * rgb[ 1 ] ) + ( 0.0722 * rgb[ 2 ] );
+ return '#' + ( luma >= 165 ? '000' : 'fff' );
+ }
+
+ // Distinguish focused and hover states.
+ var focused, hovered;
+
+ // Apply highlight style.
+ function updateHighlight( event ) {
+ // Convert to event.
+ !event.name && ( event = new CKEDITOR.event( event ) );
+
+ var isFocus = !( /mouse/ ).test( event.name ),
+ target = event.data.getTarget(),
+ color;
+
+ if ( target.getName() == 'td' && ( color = target.getChild( 0 ).getHtml() ) ) {
+ removeHighlight( event );
+
+ isFocus ? focused = target : hovered = target;
+
+ // Apply outline style to show focus.
+ if ( isFocus ) {
+ target.setStyle( 'border-color', whiteOrBlack( color ) );
+ target.setStyle( 'border-style', 'dotted' );
+ }
+
+ $doc.getById( hicolorId ).setStyle( 'background-color', color );
+ $doc.getById( hicolorTextId ).setHtml( color );
+ }
+ }
+
+ function clearHighlight() {
+ var color = focused.getChild( 0 ).getHtml();
+ focused.setStyle( 'border-color', color );
+ focused.setStyle( 'border-style', 'solid' );
+ $doc.getById( hicolorId ).removeStyle( 'background-color' );
+ $doc.getById( hicolorTextId ).setHtml( ' ' );
+ focused = null;
+ }
+
+ // Remove previously focused style.
+ function removeHighlight( event ) {
+ var isFocus = !( /mouse/ ).test( event.name ),
+ target = isFocus && focused;
+
+ if ( target ) {
+ var color = target.getChild( 0 ).getHtml();
+ target.setStyle( 'border-color', color );
+ target.setStyle( 'border-style', 'solid' );
+ }
+
+ if ( !( focused || hovered ) ) {
+ $doc.getById( hicolorId ).removeStyle( 'background-color' );
+ $doc.getById( hicolorTextId ).setHtml( ' ' );
+ }
+ }
+
+ function onKeyStrokes( evt ) {
+ var domEvt = evt.data;
+
+ var element = domEvt.getTarget();
+ var relative, nodeToMove;
+ var keystroke = domEvt.getKeystroke(),
+ rtl = editor.lang.dir == 'rtl';
+
+ switch ( keystroke ) {
+ // UP-ARROW
+ case 38:
+ // relative is TR
+ if ( ( relative = element.getParent().getPrevious() ) ) {
+ nodeToMove = relative.getChild( [ element.getIndex() ] );
+ nodeToMove.focus();
+ }
+ domEvt.preventDefault();
+ break;
+ // DOWN-ARROW
+ case 40:
+ // relative is TR
+ if ( ( relative = element.getParent().getNext() ) ) {
+ nodeToMove = relative.getChild( [ element.getIndex() ] );
+ if ( nodeToMove && nodeToMove.type == 1 )
+ nodeToMove.focus();
+
+ }
+ domEvt.preventDefault();
+ break;
+
+ // SPACE
+ // ENTER
+ case 32:
+ case 13:
+ updateSelected( evt );
+ domEvt.preventDefault();
+ break;
+
+ // RIGHT-ARROW
+ case rtl ? 37 : 39:
+ // relative is TD
+ if ( ( nodeToMove = element.getNext() ) ) {
+ if ( nodeToMove.type == 1 ) {
+ nodeToMove.focus();
+ domEvt.preventDefault( true );
+ }
+ }
+ // relative is TR
+ else if ( ( relative = element.getParent().getNext() ) ) {
+ nodeToMove = relative.getChild( [ 0 ] );
+ if ( nodeToMove && nodeToMove.type == 1 ) {
+ nodeToMove.focus();
+ domEvt.preventDefault( true );
+ }
+ }
+ break;
+
+ // LEFT-ARROW
+ case rtl ? 39 : 37:
+ // relative is TD
+ if ( ( nodeToMove = element.getPrevious() ) ) {
+ nodeToMove.focus();
+ domEvt.preventDefault( true );
+ }
+ // relative is TR
+ else if ( ( relative = element.getParent().getPrevious() ) ) {
+ nodeToMove = relative.getLast();
+ nodeToMove.focus();
+ domEvt.preventDefault( true );
+ }
+ break;
+ default:
+ // Do not stop not handled events.
+ return;
+ }
+ }
+
+ function createColorTable() {
+ table = CKEDITOR.dom.element.createFromHtml( '' );
+
+ var parts = colors[ i ].split( '/' ),
+ colorName = parts[ 0 ],
+ colorCode = parts[ 1 ] || colorName;
+
+ // The data can be only a color code (without #) or colorName + color code
+ // If only a color code is provided, then the colorName is the color with the hash
+ // Convert the color from RGB to RRGGBB for better compatibility with IE and . See #5676
+ if ( !parts[ 1 ] )
+ colorName = '#' + colorName.replace( /^(.)(.)(.)$/, '$1$1$2$2$3$3' );
+
+ var colorLabel = editor.lang.colorbutton.colors[ colorCode ] || colorCode;
+ output.push( ' ' +
+ '' +
+ '' +
+ '' +
+ '' +
+ ' ' );
+ }
+
+ // Render the "More Colors" button.
+ if ( moreColorsEnabled ) {
+ output.push( '' +
+ ' ' +
+ '', lang.more, '' +
+ ' ' ); // tr is later in the code.
+ }
+
+ output.push( '' +
+ '
' );
+
+ table.on( 'mouseover', updateHighlight );
+ table.on( 'mouseout', removeHighlight );
+
+ // Create the base colors array.
+ var aColors = [ '00', '33', '66', '99', 'cc', 'ff' ];
+
+ // This function combines two ranges of three values from the color array into a row.
+ function appendColorRow( rangeA, rangeB ) {
+ for ( var i = rangeA; i < rangeA + 3; i++ ) {
+ var row = new $el( table.$.insertRow( -1 ) );
+ row.setAttribute( 'role', 'row' );
+
+ for ( var j = rangeB; j < rangeB + 3; j++ ) {
+ for ( var n = 0; n < 6; n++ ) {
+ appendColorCell( row.$, '#' + aColors[ j ] + aColors[ n ] + aColors[ i ] );
+ }
+ }
+ }
+ }
+
+ // This function create a single color cell in the color table.
+ function appendColorCell( targetRow, color ) {
+ var cell = new $el( targetRow.insertCell( -1 ) );
+ cell.setAttribute( 'class', 'ColorCell' );
+ cell.setAttribute( 'tabIndex', -1 );
+ cell.setAttribute( 'role', 'gridcell' );
+
+ cell.on( 'keydown', onKeyStrokes );
+ cell.on( 'click', updateSelected );
+ cell.on( 'focus', updateHighlight );
+ cell.on( 'blur', removeHighlight );
+
+ cell.setStyle( 'background-color', color );
+ cell.setStyle( 'border', '1px solid ' + color );
+
+ cell.setStyle( 'width', '14px' );
+ cell.setStyle( 'height', '14px' );
+
+ var colorLabel = numbering( 'color_table_cell' );
+ cell.setAttribute( 'aria-labelledby', colorLabel );
+ cell.append( CKEDITOR.dom.element.createFromHtml( '' + color + '', CKEDITOR.document ) );
+ }
+
+ appendColorRow( 0, 0 );
+ appendColorRow( 3, 0 );
+ appendColorRow( 0, 3 );
+ appendColorRow( 3, 3 );
+
+ // Create the last row.
+ var oRow = new $el( table.$.insertRow( -1 ) );
+ oRow.setAttribute( 'role', 'row' );
+
+ // Create the gray scale colors cells.
+ appendColorCell( oRow.$, '#000000' );
+ for ( var n = 0; n < 16; n++ ) {
+ var c = n.toString( 16 );
+ appendColorCell( oRow.$, '#' + c + c + c + c + c + c );
+ }
+ appendColorCell( oRow.$, '#ffffff' );
+ }
+
+ var numbering = function( id ) {
+ return CKEDITOR.tools.getNextId() + '_' + id;
+ },
+ hicolorId = numbering( 'hicolor' ),
+ hicolorTextId = numbering( 'hicolortext' ),
+ selHiColorId = numbering( 'selhicolor' ),
+ table;
+
+ createColorTable();
+
+ return {
+ title: lang.title,
+ minWidth: 360,
+ minHeight: 220,
+ onLoad: function() {
+ // Update reference.
+ dialog = this;
+ },
+ onHide: function() {
+ clearSelected();
+ clearHighlight();
+ },
+ contents: [ {
+ id: 'picker',
+ label: lang.title,
+ accessKey: 'I',
+ elements: [ {
+ type: 'hbox',
+ padding: 0,
+ widths: [ '70%', '10%', '30%' ],
+ children: [ {
+ type: 'html',
+ html: '',
+ onLoad: function() {
+ CKEDITOR.document.getById( this.domId ).append( table );
+ },
+ focus: function() {
+ // Restore the previously focused cell,
+ // otherwise put the initial focus on the first table cell.
+ ( focused || this.getElement().getElementsByTag( 'td' ).getItem( 0 ) ).focus();
+ }
+ },
+ spacer,
+ {
+ type: 'vbox',
+ padding: 0,
+ widths: [ '70%', '5%', '25%' ],
+ children: [ {
+ type: 'html',
+ html: '' + lang.highlight + '' +
+ '' +
+ 'This is some sample HTML content.
'
+ * }
+ *
+ * // Example 2:
+ * // Complete sample with document.getById() call when the "Ok" button is clicked.
+ * var dialogDefinition = {
+ * title: 'Sample dialog',
+ * minWidth: 300,
+ * minHeight: 200,
+ * onOk: function() {
+ * // "this" is now a CKEDITOR.dialog object.
+ * var document = this.getElement().getDocument();
+ * // document = CKEDITOR.dom.document
+ * var element = document.getById( 'myDiv' );
+ * if ( element )
+ * alert( element.getHtml() );
+ * },
+ * contents: [
+ * {
+ * id: 'tab1',
+ * label: '',
+ * title: '',
+ * elements: [
+ * {
+ * type: 'html',
+ * html: '' +
+ '
' +
+ ' ' +
+ '' +
+ ' ' +
+ '
' +
+ '' +
+ ' ' +
+ '' +
+ ' ' +
+ ' ' +
+ '' +
+ ' ' ];
+ for ( i = 0; i < childHtmlList.length; i++ ) {
+ var className = 'cke_dialog_ui_hbox_child',
+ styles = [];
+ if ( i === 0 ) {
+ className = 'cke_dialog_ui_hbox_first';
+ }
+ if ( i == childHtmlList.length - 1 ) {
+ className = 'cke_dialog_ui_hbox_last';
+ }
+
+ html.push( ' ' );
+ return html.join( '' );
+ };
+
+ var attribs = { role: 'presentation' };
+ elementDefinition && elementDefinition.align && ( attribs.align = elementDefinition.align );
+
+ CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type: 'hbox' }, htmlList, 'table', styles, attribs, innerHTML );
+ },
+
+ /**
+ * Vertical layout box for dialog UI elements.
+ *
+ * @class CKEDITOR.ui.dialog.vbox
+ * @extends CKEDITOR.ui.dialog.hbox
+ * @constructor Creates a vbox class instance.
+ * @param {CKEDITOR.dialog} dialog Parent dialog object.
+ * @param {Array} childObjList
+ * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container.
+ * @param {Array} childHtmlList
+ * Array of HTML code that correspond to the HTML output of all the
+ * objects in childObjList.
+ * @param {Array} htmlList Array of HTML code that this element will output to.
+ * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
+ * The element definition. Accepted fields:
+ *
+ * * `width` (Optional) The width of the layout.
+ * * `heights` (Optional) The heights of individual cells.
+ * * `align` (Optional) The alignment of the layout.
+ * * `padding` (Optional) The padding width inside child cells.
+ * * `expand` (Optional) Whether the layout should expand
+ * vertically to fill its container.
+ */
+ vbox: function( dialog, childObjList, childHtmlList, htmlList, elementDefinition ) {
+ if ( arguments.length < 3 )
+ return;
+
+ this._ || ( this._ = {} );
+
+ var children = this._.children = childObjList,
+ width = elementDefinition && elementDefinition.width || null,
+ heights = elementDefinition && elementDefinition.heights || null;
+ /** @ignore */
+ var innerHTML = function() {
+ var html = [ ' 0 ) {
+ html.push( 'style="' + styles.join( '; ' ) + '" ' );
+ }
+ html.push( '>', childHtmlList[ i ], ' ' );
+ }
+ html.push( '' );
+ for ( var i = 0; i < childHtmlList.length; i++ ) {
+ var styles = [];
+ html.push( '
' );
+ return html.join( '' );
+ };
+ CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type: 'vbox' }, htmlList, 'div', null, { role: 'presentation' }, innerHTML );
+ }
+ };
+ } )();
+
+ /** @class CKEDITOR.ui.dialog.uiElement */
+ CKEDITOR.ui.dialog.uiElement.prototype = {
+ /**
+ * Gets the root DOM element of this dialog UI object.
+ *
+ * uiElement.getElement().hide();
+ *
+ * @returns {CKEDITOR.dom.element} Root DOM element of UI object.
+ */
+ getElement: function() {
+ return CKEDITOR.document.getById( this.domId );
+ },
+
+ /**
+ * Gets the DOM element that the user inputs values.
+ *
+ * This function is used by {@link #setValue}, {@link #getValue} and {@link #focus}. It should
+ * be overrided in child classes where the input element isn't the root
+ * element.
+ *
+ * var rawValue = textInput.getInputElement().$.value;
+ *
+ * @returns {CKEDITOR.dom.element} The element where the user input values.
+ */
+ getInputElement: function() {
+ return this.getElement();
+ },
+
+ /**
+ * Gets the parent dialog object containing this UI element.
+ *
+ * var dialog = uiElement.getDialog();
+ *
+ * @returns {CKEDITOR.dialog} Parent dialog object.
+ */
+ getDialog: function() {
+ return this._.dialog;
+ },
+
+ /**
+ * Sets the value of this dialog UI object.
+ *
+ * uiElement.setValue( 'Dingo' );
+ *
+ * @chainable
+ * @param {Object} value The new value.
+ * @param {Boolean} noChangeEvent Internal commit, to supress `change` event on this element.
+ */
+ setValue: function( value, noChangeEvent ) {
+ this.getInputElement().setValue( value );
+ !noChangeEvent && this.fire( 'change', { value: value } );
+ return this;
+ },
+
+ /**
+ * Gets the current value of this dialog UI object.
+ *
+ * var myValue = uiElement.getValue();
+ *
+ * @returns {Object} The current value.
+ */
+ getValue: function() {
+ return this.getInputElement().getValue();
+ },
+
+ /**
+ * Tells whether the UI object's value has changed.
+ *
+ * if ( uiElement.isChanged() )
+ * confirm( 'Value changed! Continue?' );
+ *
+ * @returns {Boolean} `true` if changed, `false` if not changed.
+ */
+ isChanged: function() {
+ // Override in input classes.
+ return false;
+ },
+
+ /**
+ * Selects the parent tab of this element. Usually called by focus() or overridden focus() methods.
+ *
+ * focus : function() {
+ * this.selectParentTab();
+ * // do something else.
+ * }
+ *
+ * @chainable
+ */
+ selectParentTab: function() {
+ var element = this.getInputElement(),
+ cursor = element,
+ tabId;
+ while ( ( cursor = cursor.getParent() ) && cursor.$.className.search( 'cke_dialog_page_contents' ) == -1 ) {
+
+ }
+
+ // Some widgets don't have parent tabs (e.g. OK and Cancel buttons).
+ if ( !cursor )
+ return this;
+
+ tabId = cursor.getAttribute( 'name' );
+ // Avoid duplicate select.
+ if ( this._.dialog._.currentTabId != tabId )
+ this._.dialog.selectPage( tabId );
+ return this;
+ },
+
+ /**
+ * Puts the focus to the UI object. Switches tabs if the UI object isn't in the active tab page.
+ *
+ * uiElement.focus();
+ *
+ * @chainable
+ */
+ focus: function() {
+ this.selectParentTab().getInputElement().focus();
+ return this;
+ },
+
+ /**
+ * Registers the `on*` event handlers defined in the element definition.
+ *
+ * The default behavior of this function is:
+ *
+ * 1. If the on* event is defined in the class's eventProcesors list,
+ * then the registration is delegated to the corresponding function
+ * in the eventProcessors list.
+ * 2. If the on* event is not defined in the eventProcessors list, then
+ * register the event handler under the corresponding DOM event of
+ * the UI element's input DOM element (as defined by the return value
+ * of {@link #getInputElement}).
+ *
+ * This function is only called at UI element instantiation, but can
+ * be overridded in child classes if they require more flexibility.
+ *
+ * @chainable
+ * @param {CKEDITOR.dialog.definition.uiElement} definition The UI element
+ * definition.
+ */
+ registerEvents: function( definition ) {
+ var regex = /^on([A-Z]\w+)/,
+ match;
+
+ var registerDomEvent = function( uiElement, dialog, eventName, func ) {
+ dialog.on( 'load', function() {
+ uiElement.getInputElement().on( eventName, func, uiElement );
+ } );
+ };
+
+ for ( var i in definition ) {
+ if ( !( match = i.match( regex ) ) )
+ continue;
+ if ( this.eventProcessors[ i ] )
+ this.eventProcessors[ i ].call( this, this._.dialog, definition[ i ] );
+ else
+ registerDomEvent( this, this._.dialog, match[ 1 ].toLowerCase(), definition[ i ] );
+ }
+
+ return this;
+ },
+
+ /**
+ * The event processor list used by
+ * {@link CKEDITOR.ui.dialog.uiElement#getInputElement} at UI element
+ * instantiation. The default list defines three `on*` events:
+ *
+ * 1. `onLoad` - Called when the element's parent dialog opens for the
+ * first time.
+ * 2. `onShow` - Called whenever the element's parent dialog opens.
+ * 3. `onHide` - Called whenever the element's parent dialog closes.
+ *
+ * // This connects the 'click' event in CKEDITOR.ui.dialog.button to onClick
+ * // handlers in the UI element's definitions.
+ * CKEDITOR.ui.dialog.button.eventProcessors = CKEDITOR.tools.extend( {},
+ * CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors,
+ * { onClick : function( dialog, func ) { this.on( 'click', func ); } },
+ * true
+ * );
+ *
+ * @property {Object}
+ */
+ eventProcessors: {
+ onLoad: function( dialog, func ) {
+ dialog.on( 'load', func, this );
+ },
+
+ onShow: function( dialog, func ) {
+ dialog.on( 'show', func, this );
+ },
+
+ onHide: function( dialog, func ) {
+ dialog.on( 'hide', func, this );
+ }
+ },
+
+ /**
+ * The default handler for a UI element's access key down event, which
+ * tries to put focus to the UI element.
+ *
+ * Can be overridded in child classes for more sophisticaed behavior.
+ *
+ * @param {CKEDITOR.dialog} dialog The parent dialog object.
+ * @param {String} key The key combination pressed. Since access keys
+ * are defined to always include the `CTRL` key, its value should always
+ * include a `'CTRL+'` prefix.
+ */
+ accessKeyDown: function() {
+ this.focus();
+ },
+
+ /**
+ * The default handler for a UI element's access key up event, which
+ * does nothing.
+ *
+ * Can be overridded in child classes for more sophisticated behavior.
+ *
+ * @param {CKEDITOR.dialog} dialog The parent dialog object.
+ * @param {String} key The key combination pressed. Since access keys
+ * are defined to always include the `CTRL` key, its value should always
+ * include a `'CTRL+'` prefix.
+ */
+ accessKeyUp: function() {},
+
+ /**
+ * Disables a UI element.
+ */
+ disable: function() {
+ var element = this.getElement(),
+ input = this.getInputElement();
+ input.setAttribute( 'disabled', 'true' );
+ element.addClass( 'cke_disabled' );
+ },
+
+ /**
+ * Enables a UI element.
+ */
+ enable: function() {
+ var element = this.getElement(),
+ input = this.getInputElement();
+ input.removeAttribute( 'disabled' );
+ element.removeClass( 'cke_disabled' );
+ },
+
+ /**
+ * Determines whether an UI element is enabled or not.
+ *
+ * @returns {Boolean} Whether the UI element is enabled.
+ */
+ isEnabled: function() {
+ return !this.getElement().hasClass( 'cke_disabled' );
+ },
+
+ /**
+ * Determines whether an UI element is visible or not.
+ *
+ * @returns {Boolean} Whether the UI element is visible.
+ */
+ isVisible: function() {
+ return this.getInputElement().isVisible();
+ },
+
+ /**
+ * Determines whether an UI element is focus-able or not.
+ * Focus-able is defined as being both visible and enabled.
+ *
+ * @returns {Boolean} Whether the UI element can be focused.
+ */
+ isFocusable: function() {
+ if ( !this.isEnabled() || !this.isVisible() )
+ return false;
+ return true;
+ }
+ };
+
+ /** @class CKEDITOR.ui.dialog.hbox */
+ CKEDITOR.ui.dialog.hbox.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement(), {
+ /**
+ * Gets a child UI element inside this container.
+ *
+ * var checkbox = hbox.getChild( [0,1] );
+ * checkbox.setValue( true );
+ *
+ * @param {Array/Number} indices An array or a single number to indicate the child's
+ * position in the container's descendant tree. Omit to get all the children in an array.
+ * @returns {Array/CKEDITOR.ui.dialog.uiElement} Array of all UI elements in the container
+ * if no argument given, or the specified UI element if indices is given.
+ */
+ getChild: function( indices ) {
+ // If no arguments, return a clone of the children array.
+ if ( arguments.length < 1 )
+ return this._.children.concat();
+
+ // If indices isn't array, make it one.
+ if ( !indices.splice )
+ indices = [ indices ];
+
+ // Retrieve the child element according to tree position.
+ if ( indices.length < 2 )
+ return this._.children[ indices[ 0 ] ];
+ else
+ return ( this._.children[ indices[ 0 ] ] && this._.children[ indices[ 0 ] ].getChild ) ? this._.children[ indices[ 0 ] ].getChild( indices.slice( 1, indices.length ) ) : null;
+ }
+ }, true );
+
+ CKEDITOR.ui.dialog.vbox.prototype = new CKEDITOR.ui.dialog.hbox();
+
+ ( function() {
+ var commonBuilder = {
+ build: function( dialog, elementDefinition, output ) {
+ var children = elementDefinition.children,
+ child,
+ childHtmlList = [],
+ childObjList = [];
+ for ( var i = 0;
+ ( i < children.length && ( child = children[ i ] ) ); i++ ) {
+ var childHtml = [];
+ childHtmlList.push( childHtml );
+ childObjList.push( CKEDITOR.dialog._.uiElementBuilders[ child.type ].build( dialog, child, childHtml ) );
+ }
+ return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, childObjList, childHtmlList, output, elementDefinition );
+ }
+ };
+
+ CKEDITOR.dialog.addUIElement( 'hbox', commonBuilder );
+ CKEDITOR.dialog.addUIElement( 'vbox', commonBuilder );
+ } )();
+
+ /**
+ * Generic dialog command. It opens a specific dialog when executed.
+ *
+ * // Register the "link" command, which opens the "link" dialog.
+ * editor.addCommand( 'link', new CKEDITOR.dialogCommand( 'link' ) );
+ *
+ * @class
+ * @constructor Creates a dialogCommand class instance.
+ * @extends CKEDITOR.commandDefinition
+ * @param {String} dialogName The name of the dialog to open when executing
+ * this command.
+ * @param {Object} [ext] Additional command definition's properties.
+ */
+ CKEDITOR.dialogCommand = function( dialogName, ext ) {
+ this.dialogName = dialogName;
+ CKEDITOR.tools.extend( this, ext, true );
+ };
+
+ CKEDITOR.dialogCommand.prototype = {
+ exec: function( editor ) {
+ editor.openDialog( this.dialogName );
+ },
+
+ // Dialog commands just open a dialog ui, thus require no undo logic,
+ // undo support should dedicate to specific dialog implementation.
+ canUndo: false,
+
+ editorFocus: 1
+ };
+
+ ( function() {
+ var notEmptyRegex = /^([a]|[^a])+$/,
+ integerRegex = /^\d*$/,
+ numberRegex = /^\d*(?:\.\d+)?$/,
+ htmlLengthRegex = /^(((\d*(\.\d+))|(\d*))(px|\%)?)?$/,
+ cssLengthRegex = /^(((\d*(\.\d+))|(\d*))(px|em|ex|in|cm|mm|pt|pc|\%)?)?$/i,
+ inlineStyleRegex = /^(\s*[\w-]+\s*:\s*[^:;]+(?:;|$))*$/;
+
+ CKEDITOR.VALIDATE_OR = 1;
+ CKEDITOR.VALIDATE_AND = 2;
+
+ CKEDITOR.dialog.validate = {
+ functions: function() {
+ var args = arguments;
+ return function() {
+ /**
+ * It's important for validate functions to be able to accept the value
+ * as argument in addition to this.getValue(), so that it is possible to
+ * combine validate functions together to make more sophisticated
+ * validators.
+ */
+ var value = this && this.getValue ? this.getValue() : args[ 0 ];
+
+ var msg,
+ relation = CKEDITOR.VALIDATE_AND,
+ functions = [],
+ i;
+
+ for ( i = 0; i < args.length; i++ ) {
+ if ( typeof args[ i ] == 'function' )
+ functions.push( args[ i ] );
+ else
+ break;
+ }
+
+ if ( i < args.length && typeof args[ i ] == 'string' ) {
+ msg = args[ i ];
+ i++;
+ }
+
+ if ( i < args.length && typeof args[ i ] == 'number' )
+ relation = args[ i ];
+
+ var passed = ( relation == CKEDITOR.VALIDATE_AND ? true : false );
+ for ( i = 0; i < functions.length; i++ ) {
+ if ( relation == CKEDITOR.VALIDATE_AND )
+ passed = passed && functions[ i ]( value );
+ else
+ passed = passed || functions[ i ]( value );
+ }
+
+ return !passed ? msg : true;
+ };
+ },
+
+ regex: function( regex, msg ) {
+ /*
+ * Can be greatly shortened by deriving from functions validator if code size
+ * turns out to be more important than performance.
+ */
+ return function() {
+ var value = this && this.getValue ? this.getValue() : arguments[ 0 ];
+ return !regex.test( value ) ? msg : true;
+ };
+ },
+
+ notEmpty: function( msg ) {
+ return this.regex( notEmptyRegex, msg );
+ },
+
+ integer: function( msg ) {
+ return this.regex( integerRegex, msg );
+ },
+
+ 'number': function( msg ) {
+ return this.regex( numberRegex, msg );
+ },
+
+ 'cssLength': function( msg ) {
+ return this.functions( function( val ) {
+ return cssLengthRegex.test( CKEDITOR.tools.trim( val ) );
+ }, msg );
+ },
+
+ 'htmlLength': function( msg ) {
+ return this.functions( function( val ) {
+ return htmlLengthRegex.test( CKEDITOR.tools.trim( val ) );
+ }, msg );
+ },
+
+ 'inlineStyle': function( msg ) {
+ return this.functions( function( val ) {
+ return inlineStyleRegex.test( CKEDITOR.tools.trim( val ) );
+ }, msg );
+ },
+
+ equals: function( value, msg ) {
+ return this.functions( function( val ) {
+ return val == value;
+ }, msg );
+ },
+
+ notEqual: function( value, msg ) {
+ return this.functions( function( val ) {
+ return val != value;
+ }, msg );
+ }
+ };
+
+ CKEDITOR.on( 'instanceDestroyed', function( evt ) {
+ // Remove dialog cover on last instance destroy.
+ if ( CKEDITOR.tools.isEmpty( CKEDITOR.instances ) ) {
+ var currentTopDialog;
+ while ( ( currentTopDialog = CKEDITOR.dialog._.currentTop ) )
+ currentTopDialog.hide();
+ removeCovers();
+ }
+
+ var dialogs = evt.editor._.storedDialogs;
+ for ( var name in dialogs )
+ dialogs[ name ].destroy();
+
+ } );
+
+ } )();
+
+ // Extend the CKEDITOR.editor class with dialog specific functions.
+ CKEDITOR.tools.extend( CKEDITOR.editor.prototype, {
+ /**
+ * Loads and opens a registered dialog.
+ *
+ * CKEDITOR.instances.editor1.openDialog( 'smiley' );
+ *
+ * @member CKEDITOR.editor
+ * @param {String} dialogName The registered name of the dialog.
+ * @param {Function} callback The function to be invoked after dialog instance created.
+ * @returns {CKEDITOR.dialog} The dialog object corresponding to the dialog displayed.
+ * `null` if the dialog name is not registered.
+ * @see CKEDITOR.dialog#add
+ */
+ openDialog: function( dialogName, callback ) {
+ var dialog = null, dialogDefinitions = CKEDITOR.dialog._.dialogDefinitions[ dialogName ];
+
+ if ( CKEDITOR.dialog._.currentTop === null )
+ showCover( this );
+
+ // If the dialogDefinition is already loaded, open it immediately.
+ if ( typeof dialogDefinitions == 'function' ) {
+ var storedDialogs = this._.storedDialogs || ( this._.storedDialogs = {} );
+
+ dialog = storedDialogs[ dialogName ] || ( storedDialogs[ dialogName ] = new CKEDITOR.dialog( this, dialogName ) );
+
+ callback && callback.call( dialog, dialog );
+ dialog.show();
+
+ } else if ( dialogDefinitions == 'failed' ) {
+ hideCover( this );
+ throw new Error( '[CKEDITOR.dialog.openDialog] Dialog "' + dialogName + '" failed when loading definition.' );
+ } else if ( typeof dialogDefinitions == 'string' ) {
+
+ CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( dialogDefinitions ),
+ function() {
+ var dialogDefinition = CKEDITOR.dialog._.dialogDefinitions[ dialogName ];
+ // In case of plugin error, mark it as loading failed.
+ if ( typeof dialogDefinition != 'function' )
+ CKEDITOR.dialog._.dialogDefinitions[ dialogName ] = 'failed';
+
+ this.openDialog( dialogName, callback );
+ }, this, 0, 1 );
+ }
+
+ CKEDITOR.skin.loadPart( 'dialog' );
+
+ return dialog;
+ }
+ } );
+} )();
+
+CKEDITOR.plugins.add( 'dialog', {
+ requires: 'dialogui',
+ init: function( editor ) {
+ editor.on( 'doubleclick', function( evt ) {
+ if ( evt.data.dialog )
+ editor.openDialog( evt.data.dialog );
+ }, null, null, 999 );
+ }
+} );
+
+// Dialog related configurations.
+
+/**
+ * The color of the dialog background cover. It should be a valid CSS color string.
+ *
+ * config.dialog_backgroundCoverColor = 'rgb(255, 254, 253)';
+ *
+ * @cfg {String} [dialog_backgroundCoverColor='white']
+ * @member CKEDITOR.config
+ */
+
+/**
+ * The opacity of the dialog background cover. It should be a number within the
+ * range `[0.0, 1.0]`.
+ *
+ * config.dialog_backgroundCoverOpacity = 0.7;
+ *
+ * @cfg {Number} [dialog_backgroundCoverOpacity=0.5]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * If the dialog has more than one tab, put focus into the first tab as soon as dialog is opened.
+ *
+ * config.dialog_startupFocusTab = true;
+ *
+ * @cfg {Boolean} [dialog_startupFocusTab=false]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * The distance of magnetic borders used in moving and resizing dialogs,
+ * measured in pixels.
+ *
+ * config.dialog_magnetDistance = 30;
+ *
+ * @cfg {Number} [dialog_magnetDistance=20]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * The guideline to follow when generating the dialog buttons. There are 3 possible options:
+ *
+ * * `'OS'` - the buttons will be displayed in the default order of the user's OS;
+ * * `'ltr'` - for Left-To-Right order;
+ * * `'rtl'` - for Right-To-Left order.
+ *
+ * Example:
+ *
+ * config.dialog_buttonsOrder = 'rtl';
+ *
+ * @since 3.5
+ * @cfg {String} [dialog_buttonsOrder='OS']
+ * @member CKEDITOR.config
+ */
+
+/**
+ * The dialog contents to removed. It's a string composed by dialog name and tab name with a colon between them.
+ *
+ * Separate each pair with semicolon (see example).
+ *
+ * **Note:** All names are case-sensitive.
+ *
+ * **Note:** Be cautious when specifying dialog tabs that are mandatory,
+ * like `'info'`, dialog functionality might be broken because of this!
+ *
+ * config.removeDialogTabs = 'flash:advanced;image:Link';
+ *
+ * @since 3.5
+ * @cfg {String} [removeDialogTabs='']
+ * @member CKEDITOR.config
+ */
+
+/**
+ * Tells if user should not be asked to confirm close, if any dialog field was modified.
+ * By default it is set to `false` meaning that the confirmation dialog will be shown.
+ *
+ * config.dialog_noConfirmCancel = true;
+ *
+ * @since 4.3
+ * @cfg {Boolean} [dialog_noConfirmCancel=false]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * Event fired when a dialog definition is about to be used to create a dialog into
+ * an editor instance. This event makes it possible to customize the definition
+ * before creating it.
+ *
+ * Note that this event is called only the first time a specific dialog is
+ * opened. Successive openings will use the cached dialog, and this event will
+ * not get fired.
+ *
+ * @event dialogDefinition
+ * @member CKEDITOR
+ * @param {CKEDITOR.dialog.definition} data The dialog defination that
+ * is being loaded.
+ * @param {CKEDITOR.editor} editor The editor instance that will use the dialog.
+ */
+
+/**
+ * Event fired when a tab is going to be selected in a dialog.
+ *
+ * @event selectPage
+ * @member CKEDITOR.dialog
+ * @param data
+ * @param {String} data.page The id of the page that it's gonna be selected.
+ * @param {String} data.currentPage The id of the current page.
+ */
+
+/**
+ * Event fired when the user tries to dismiss a dialog.
+ *
+ * @event cancel
+ * @member CKEDITOR.dialog
+ * @param data
+ * @param {Boolean} data.hide Whether the event should proceed or not.
+ */
+
+/**
+ * Event fired when the user tries to confirm a dialog.
+ *
+ * @event ok
+ * @member CKEDITOR.dialog
+ * @param data
+ * @param {Boolean} data.hide Whether the event should proceed or not.
+ */
+
+/**
+ * Event fired when a dialog is shown.
+ *
+ * @event show
+ * @member CKEDITOR.dialog
+ */
+
+/**
+ * Event fired when a dialog is shown.
+ *
+ * @event dialogShow
+ * @member CKEDITOR.editor
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param {CKEDITOR.dialog} data The opened dialog instance.
+ */
+
+/**
+ * Event fired when a dialog is hidden.
+ *
+ * @event hide
+ * @member CKEDITOR.dialog
+ */
+
+/**
+ * Event fired when a dialog is hidden.
+ *
+ * @event dialogHide
+ * @member CKEDITOR.editor
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param {CKEDITOR.dialog} data The hidden dialog instance.
+ */
+
+/**
+ * Event fired when a dialog is being resized. The event is fired on
+ * both the {@link CKEDITOR.dialog} object and the dialog instance
+ * since 3.5.3, previously it was only available in the global object.
+ *
+ * @static
+ * @event resize
+ * @member CKEDITOR.dialog
+ * @param data
+ * @param {CKEDITOR.dialog} data.dialog The dialog being resized (if
+ * it is fired on the dialog itself, this parameter is not sent).
+ * @param {String} data.skin The skin name.
+ * @param {Number} data.width The new width.
+ * @param {Number} data.height The new height.
+ */
+
+/**
+ * Event fired when a dialog is being resized. The event is fired on
+ * both the {@link CKEDITOR.dialog} object and the dialog instance
+ * since 3.5.3, previously it was only available in the global object.
+ *
+ * @since 3.5
+ * @event resize
+ * @member CKEDITOR.dialog
+ * @param data
+ * @param {Number} data.width The new width.
+ * @param {Number} data.height The new height.
+ */
+
+/**
+ * Event fired when the dialog state changes, usually by {@link CKEDITOR.dialog#setState}.
+ *
+ * @since 4.5
+ * @event state
+ * @member CKEDITOR.dialog
+ * @param data
+ * @param {Number} data The new state. Either {@link CKEDITOR#DIALOG_STATE_IDLE} or {@link CKEDITOR#DIALOG_STATE_BUSY}.
+ */
diff --git a/sources/plugins/dialog/samples/assets/my_dialog.js b/sources/plugins/dialog/samples/assets/my_dialog.js
new file mode 100644
index 00000000..6ee1a201
--- /dev/null
+++ b/sources/plugins/dialog/samples/assets/my_dialog.js
@@ -0,0 +1,49 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.dialog.add( 'myDialog', function() {
+ return {
+ title: 'My Dialog',
+ minWidth: 400,
+ minHeight: 200,
+ contents: [
+ {
+ id: 'tab1',
+ label: 'First Tab',
+ title: 'First Tab',
+ elements: [
+ {
+ id: 'input1',
+ type: 'text',
+ label: 'Text Field'
+ },
+ {
+ id: 'select1',
+ type: 'select',
+ label: 'Select Field',
+ items: [
+ [ 'option1', 'value1' ],
+ [ 'option2', 'value2' ]
+ ]
+ }
+ ]
+ },
+ {
+ id: 'tab2',
+ label: 'Second Tab',
+ title: 'Second Tab',
+ elements: [
+ {
+ id: 'button1',
+ type: 'button',
+ label: 'Button Field'
+ }
+ ]
+ }
+ ]
+ };
+} );
+
+// %LEAVE_UNMINIFIED% %REMOVE_LINE%
diff --git a/sources/plugins/dialog/samples/dialog.html b/sources/plugins/dialog/samples/dialog.html
new file mode 100644
index 00000000..df43657e
--- /dev/null
+++ b/sources/plugins/dialog/samples/dialog.html
@@ -0,0 +1,190 @@
+
+
+
+
+
+ ' );
+ }
+ html.push( ' 0 )
+ html.push( 'style="', styles.join( '; ' ), '" ' );
+ html.push( ' class="cke_dialog_ui_vbox_child">', childHtmlList[ i ], '
+ CKEditor Samples » Using CKEditor Dialog API
+
+ pluginsLoaded
event, from an external dialog definition file:
+
+
+
+ dialogDefinition
event:
+
+
+
+
+
+
diff --git a/sources/plugins/dialogadvtab/plugin.js b/sources/plugins/dialogadvtab/plugin.js
new file mode 100644
index 00000000..f57f604b
--- /dev/null
+++ b/sources/plugins/dialogadvtab/plugin.js
@@ -0,0 +1,196 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+
+ function setupAdvParams( element ) {
+ var attrName = this.att;
+
+ var value = element && element.hasAttribute( attrName ) && element.getAttribute( attrName ) || '';
+
+ if ( value !== undefined )
+ this.setValue( value );
+ }
+
+ function commitAdvParams() {
+ // Dialogs may use different parameters in the commit list, so, by
+ // definition, we take the first CKEDITOR.dom.element available.
+ var element;
+
+ for ( var i = 0; i < arguments.length; i++ ) {
+ if ( arguments[ i ] instanceof CKEDITOR.dom.element ) {
+ element = arguments[ i ];
+ break;
+ }
+ }
+
+ if ( element ) {
+ var attrName = this.att,
+ value = this.getValue();
+
+ if ( value )
+ element.setAttribute( attrName, value );
+ else
+ element.removeAttribute( attrName, value );
+ }
+ }
+
+ var defaultTabConfig = { id: 1, dir: 1, classes: 1, styles: 1 };
+
+ CKEDITOR.plugins.add( 'dialogadvtab', {
+ requires: 'dialog',
+
+ // Returns allowed content rule for the content created by this plugin.
+ allowedContent: function( tabConfig ) {
+ if ( !tabConfig )
+ tabConfig = defaultTabConfig;
+
+ var allowedAttrs = [];
+ if ( tabConfig.id )
+ allowedAttrs.push( 'id' );
+ if ( tabConfig.dir )
+ allowedAttrs.push( 'dir' );
+
+ var allowed = '';
+
+ if ( allowedAttrs.length )
+ allowed += '[' + allowedAttrs.join( ',' ) + ']';
+
+ if ( tabConfig.classes )
+ allowed += '(*)';
+ if ( tabConfig.styles )
+ allowed += '{*}';
+
+ return allowed;
+ },
+
+ // @param tabConfig
+ // id, dir, classes, styles
+ createAdvancedTab: function( editor, tabConfig, element ) {
+ if ( !tabConfig )
+ tabConfig = defaultTabConfig;
+
+ var lang = editor.lang.common;
+
+ var result = {
+ id: 'advanced',
+ label: lang.advancedTab,
+ title: lang.advancedTab,
+ elements: [ {
+ type: 'vbox',
+ padding: 1,
+ children: []
+ } ]
+ };
+
+ var contents = [];
+
+ if ( tabConfig.id || tabConfig.dir ) {
+ if ( tabConfig.id ) {
+ contents.push( {
+ id: 'advId',
+ att: 'id',
+ type: 'text',
+ requiredContent: element ? element + '[id]' : null,
+ label: lang.id,
+ setup: setupAdvParams,
+ commit: commitAdvParams
+ } );
+ }
+
+ if ( tabConfig.dir ) {
+ contents.push( {
+ id: 'advLangDir',
+ att: 'dir',
+ type: 'select',
+ requiredContent: element ? element + '[dir]' : null,
+ label: lang.langDir,
+ 'default': '',
+ style: 'width:100%',
+ items: [
+ [ lang.notSet, '' ],
+ [ lang.langDirLTR, 'ltr' ],
+ [ lang.langDirRTL, 'rtl' ]
+ ],
+ setup: setupAdvParams,
+ commit: commitAdvParams
+ } );
+ }
+
+ result.elements[ 0 ].children.push( {
+ type: 'hbox',
+ widths: [ '50%', '50%' ],
+ children: [].concat( contents )
+ } );
+ }
+
+ if ( tabConfig.styles || tabConfig.classes ) {
+ contents = [];
+
+ if ( tabConfig.styles ) {
+ contents.push( {
+ id: 'advStyles',
+ att: 'style',
+ type: 'text',
+ requiredContent: element ? element + '{cke-xyz}' : null,
+ label: lang.styles,
+ 'default': '',
+
+ validate: CKEDITOR.dialog.validate.inlineStyle( lang.invalidInlineStyle ),
+ onChange: function() {},
+
+ getStyle: function( name, defaultValue ) {
+ var match = this.getValue().match( new RegExp( '(?:^|;)\\s*' + name + '\\s*:\\s*([^;]*)', 'i' ) );
+ return match ? match[ 1 ] : defaultValue;
+ },
+
+ updateStyle: function( name, value ) {
+ var styles = this.getValue();
+
+ var tmp = editor.document.createElement( 'span' );
+ tmp.setAttribute( 'style', styles );
+ tmp.setStyle( name, value );
+ styles = CKEDITOR.tools.normalizeCssText( tmp.getAttribute( 'style' ) );
+
+ this.setValue( styles, 1 );
+ },
+
+ setup: setupAdvParams,
+
+ commit: commitAdvParams
+
+ } );
+ }
+
+ if ( tabConfig.classes ) {
+ contents.push( {
+ type: 'hbox',
+ widths: [ '45%', '55%' ],
+ children: [ {
+ id: 'advCSSClasses',
+ att: 'class',
+ type: 'text',
+ requiredContent: element ? element + '(cke-xyz)' : null,
+ label: lang.cssClasses,
+ 'default': '',
+ setup: setupAdvParams,
+ commit: commitAdvParams
+
+ } ]
+ } );
+ }
+
+ result.elements[ 0 ].children.push( {
+ type: 'hbox',
+ widths: [ '50%', '50%' ],
+ children: [].concat( contents )
+ } );
+ }
+
+ return result;
+ }
+ } );
+
+} )();
diff --git a/sources/plugins/dialogui/plugin.js b/sources/plugins/dialogui/plugin.js
new file mode 100644
index 00000000..3b3f1e22
--- /dev/null
+++ b/sources/plugins/dialogui/plugin.js
@@ -0,0 +1,1530 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview The Dialog User Interface plugin.
+ */
+
+CKEDITOR.plugins.add( 'dialogui', {
+ onLoad: function() {
+
+ var initPrivateObject = function( elementDefinition ) {
+ this._ || ( this._ = {} );
+ this._[ 'default' ] = this._.initValue = elementDefinition[ 'default' ] || '';
+ this._.required = elementDefinition.required || false;
+ var args = [ this._ ];
+ for ( var i = 1; i < arguments.length; i++ )
+ args.push( arguments[ i ] );
+ args.push( true );
+ CKEDITOR.tools.extend.apply( CKEDITOR.tools, args );
+ return this._;
+ },
+ textBuilder = {
+ build: function( dialog, elementDefinition, output ) {
+ return new CKEDITOR.ui.dialog.textInput( dialog, elementDefinition, output );
+ }
+ },
+ commonBuilder = {
+ build: function( dialog, elementDefinition, output ) {
+ return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, elementDefinition, output );
+ }
+ },
+ containerBuilder = {
+ build: function( dialog, elementDefinition, output ) {
+ var children = elementDefinition.children,
+ child,
+ childHtmlList = [],
+ childObjList = [];
+ for ( var i = 0;
+ ( i < children.length && ( child = children[ i ] ) ); i++ ) {
+ var childHtml = [];
+ childHtmlList.push( childHtml );
+ childObjList.push( CKEDITOR.dialog._.uiElementBuilders[ child.type ].build( dialog, child, childHtml ) );
+ }
+ return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, childObjList, childHtmlList, output, elementDefinition );
+ }
+ },
+ commonPrototype = {
+ isChanged: function() {
+ return this.getValue() != this.getInitValue();
+ },
+
+ reset: function( noChangeEvent ) {
+ this.setValue( this.getInitValue(), noChangeEvent );
+ },
+
+ setInitValue: function() {
+ this._.initValue = this.getValue();
+ },
+
+ resetInitValue: function() {
+ this._.initValue = this._[ 'default' ];
+ },
+
+ getInitValue: function() {
+ return this._.initValue;
+ }
+ },
+ commonEventProcessors = CKEDITOR.tools.extend( {}, CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors, {
+ onChange: function( dialog, func ) {
+ if ( !this._.domOnChangeRegistered ) {
+ dialog.on( 'load', function() {
+ this.getInputElement().on( 'change', function() {
+ // Make sure 'onchange' doesn't get fired after dialog closed. (#5719)
+ if ( !dialog.parts.dialog.isVisible() )
+ return;
+
+ this.fire( 'change', { value: this.getValue() } );
+ }, this );
+ }, this );
+ this._.domOnChangeRegistered = true;
+ }
+
+ this.on( 'change', func );
+ }
+ }, true ),
+ eventRegex = /^on([A-Z]\w+)/,
+ cleanInnerDefinition = function( def ) {
+ // An inner UI element should not have the parent's type, title or events.
+ for ( var i in def ) {
+ if ( eventRegex.test( i ) || i == 'title' || i == 'type' )
+ delete def[ i ];
+ }
+ return def;
+ },
+ // @context {CKEDITOR.dialog.uiElement} UI element (textarea or textInput)
+ // @param {CKEDITOR.dom.event} evt
+ toggleBidiKeyUpHandler = function( evt ) {
+ var keystroke = evt.data.getKeystroke();
+
+ // ALT + SHIFT + Home for LTR direction.
+ if ( keystroke == CKEDITOR.SHIFT + CKEDITOR.ALT + 36 )
+ this.setDirectionMarker( 'ltr' );
+
+ // ALT + SHIFT + End for RTL direction.
+ else if ( keystroke == CKEDITOR.SHIFT + CKEDITOR.ALT + 35 )
+ this.setDirectionMarker( 'rtl' );
+ };
+
+ CKEDITOR.tools.extend( CKEDITOR.ui.dialog, {
+ /**
+ * Base class for all dialog window elements with a textual label on the left.
+ *
+ * @class CKEDITOR.ui.dialog.labeledElement
+ * @extends CKEDITOR.ui.dialog.uiElement
+ * @constructor Creates a labeledElement class instance.
+ * @param {CKEDITOR.dialog} dialog Parent dialog window object.
+ * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition
+ * The element definition. Accepted fields:
+ *
+ * * `label` (Required) The label string.
+ * * `labelLayout` (Optional) Put 'horizontal' here if the
+ * label element is to be laid out horizontally. Otherwise a vertical
+ * layout will be used.
+ * * `widths` (Optional) This applies only to horizontal
+ * layouts — a two-element array of lengths to specify the widths of the
+ * label and the content element.
+ * * `role` (Optional) Value for the `role` attribute.
+ * * `includeLabel` (Optional) If set to `true`, the `aria-labelledby` attribute
+ * will be included.
+ *
+ * @param {Array} htmlList The list of HTML code to output to.
+ * @param {Function} contentHtml
+ * A function returning the HTML code string to be added inside the content
+ * cell.
+ */
+ labeledElement: function( dialog, elementDefinition, htmlList, contentHtml ) {
+ if ( arguments.length < 4 )
+ return;
+
+ var _ = initPrivateObject.call( this, elementDefinition );
+ _.labelId = CKEDITOR.tools.getNextId() + '_label';
+ this._.children = [];
+
+ var innerHTML = function() {
+ var html = [],
+ requiredClass = elementDefinition.required ? ' cke_required' : '';
+ if ( elementDefinition.labelLayout != 'horizontal' ) {
+ html.push(
+ '',
+ ' or inline
+ // container's width, so need to wrap it inside a