Browse Source

Merge branch 'dolibarr-php7' of https://github.com/GPCsolutions/dolibarr
into GPCsolutions-dolibarr-php7

Conflicts:
.gitignore

Laurent Destailleur 9 năm trước cách đây
mục cha
commit
327d764284
100 tập tin đã thay đổi với 133 bổ sung31961 xóa
  1. 5 1
      .gitignore
  2. 2 2
      COPYRIGHT
  3. 3 3
      composer.json
  4. 13 14
      composer.lock
  5. 1 1
      dev/dolibarr_changes.txt
  6. 2 2
      dev/test/testtcpdf.php
  7. 2 2
      dev/test/testutf.php
  8. 1 1
      htdocs/filefunc.inc.php
  9. 42 10
      htdocs/includes/adodbtime/adodb-time.inc.php
  10. 62 19
      htdocs/includes/ckeditor/ckeditor/README.md
  11. 0 442
      htdocs/includes/ckeditor/ckeditor/_source/CHANGES.md
  12. 0 1274
      htdocs/includes/ckeditor/ckeditor/_source/LICENSE.md
  13. 0 39
      htdocs/includes/ckeditor/ckeditor/_source/README.md
  14. 0 165
      htdocs/includes/ckeditor/ckeditor/_source/build-config.js
  15. 0 42
      htdocs/includes/ckeditor/ckeditor/_source/ckeditor.js
  16. 0 17
      htdocs/includes/ckeditor/ckeditor/_source/config.js
  17. 0 123
      htdocs/includes/ckeditor/ckeditor/_source/contents.css
  18. 0 74
      htdocs/includes/ckeditor/ckeditor/_source/core/_bootstrap.js
  19. 0 204
      htdocs/includes/ckeditor/ckeditor/_source/core/ckeditor.js
  20. 0 315
      htdocs/includes/ckeditor/ckeditor/_source/core/ckeditor_base.js
  21. 0 94
      htdocs/includes/ckeditor/ckeditor/_source/core/ckeditor_basic.js
  22. 0 271
      htdocs/includes/ckeditor/ckeditor/_source/core/command.js
  23. 0 139
      htdocs/includes/ckeditor/ckeditor/_source/core/commanddefinition.js
  24. 0 383
      htdocs/includes/ckeditor/ckeditor/_source/core/config.js
  25. 0 153
      htdocs/includes/ckeditor/ckeditor/_source/core/creators/inline.js
  26. 0 457
      htdocs/includes/ckeditor/ckeditor/_source/core/creators/themedui.js
  27. 0 70
      htdocs/includes/ckeditor/ckeditor/_source/core/dataprocessor.js
  28. 0 13
      htdocs/includes/ckeditor/ckeditor/_source/core/dom.js
  29. 0 53
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/comment.js
  30. 0 316
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/document.js
  31. 0 45
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/documentfragment.js
  32. 0 262
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/domobject.js
  33. 0 2007
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/element.js
  34. 0 251
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/elementpath.js
  35. 0 208
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/event.js
  36. 0 500
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/iterator.js
  37. 0 748
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/node.js
  38. 0 43
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/nodelist.js
  39. 0 2391
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/range.js
  40. 0 201
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/rangelist.js
  41. 0 139
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/text.js
  42. 0 616
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/walker.js
  43. 0 95
      htdocs/includes/ckeditor/ckeditor/_source/core/dom/window.js
  44. 0 328
      htdocs/includes/ckeditor/ckeditor/_source/core/dtd.js
  45. 0 1968
      htdocs/includes/ckeditor/ckeditor/_source/core/editable.js
  46. 0 1775
      htdocs/includes/ckeditor/ckeditor/_source/core/editor.js
  47. 0 36
      htdocs/includes/ckeditor/ckeditor/_source/core/editor_basic.js
  48. 0 359
      htdocs/includes/ckeditor/ckeditor/_source/core/env.js
  49. 0 387
      htdocs/includes/ckeditor/ckeditor/_source/core/event.js
  50. 0 115
      htdocs/includes/ckeditor/ckeditor/_source/core/eventInfo.js
  51. 0 2072
      htdocs/includes/ckeditor/ckeditor/_source/core/filter.js
  52. 0 271
      htdocs/includes/ckeditor/ckeditor/_source/core/focusmanager.js
  53. 0 989
      htdocs/includes/ckeditor/ckeditor/_source/core/htmldataprocessor.js
  54. 0 207
      htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser.js
  55. 0 152
      htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/basicwriter.js
  56. 0 48
      htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/cdata.js
  57. 0 80
      htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/comment.js
  58. 0 519
      htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/element.js
  59. 0 407
      htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/filter.js
  60. 0 631
      htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/fragment.js
  61. 0 150
      htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/node.js
  62. 0 70
      htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/text.js
  63. 0 153
      htdocs/includes/ckeditor/ckeditor/_source/core/keystrokehandler.js
  64. 0 100
      htdocs/includes/ckeditor/ckeditor/_source/core/lang.js
  65. 0 247
      htdocs/includes/ckeditor/ckeditor/_source/core/loader.js
  66. 0 96
      htdocs/includes/ckeditor/ckeditor/_source/core/plugindefinition.js
  67. 0 119
      htdocs/includes/ckeditor/ckeditor/_source/core/plugins.js
  68. 0 227
      htdocs/includes/ckeditor/ckeditor/_source/core/resourcemanager.js
  69. 0 202
      htdocs/includes/ckeditor/ckeditor/_source/core/scriptloader.js
  70. 0 2224
      htdocs/includes/ckeditor/ckeditor/_source/core/selection.js
  71. 0 335
      htdocs/includes/ckeditor/ckeditor/_source/core/skin.js
  72. 0 1714
      htdocs/includes/ckeditor/ckeditor/_source/core/style.js
  73. 0 69
      htdocs/includes/ckeditor/ckeditor/_source/core/template.js
  74. 0 1123
      htdocs/includes/ckeditor/ckeditor/_source/core/tools.js
  75. 0 168
      htdocs/includes/ckeditor/ckeditor/_source/core/ui.js
  76. 0 63
      htdocs/includes/ckeditor/ckeditor/_source/lang/_translationstatus.txt
  77. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/af.js
  78. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/ar.js
  79. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/bg.js
  80. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/bn.js
  81. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/bs.js
  82. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/ca.js
  83. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/cs.js
  84. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/cy.js
  85. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/da.js
  86. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/de.js
  87. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/el.js
  88. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/en-au.js
  89. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/en-ca.js
  90. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/en-gb.js
  91. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/en.js
  92. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/eo.js
  93. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/es.js
  94. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/et.js
  95. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/eu.js
  96. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/fa.js
  97. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/fi.js
  98. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/fo.js
  99. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/fr-ca.js
  100. 0 98
      htdocs/includes/ckeditor/ckeditor/_source/lang/fr.js

+ 5 - 1
.gitignore

@@ -19,4 +19,8 @@ Thumbs.db
 # Vagrant generated files
 .vagrant
 # Composer installed repositories
-/htdocs/includes/**/.git
+/htdocs/includes/**/.git
+# Composer autoloader and unwanted files
+htdocs/includes/autoload.php
+htdocs/includes/bin/
+htdocs/includes/composer/

+ 2 - 2
COPYRIGHT

@@ -12,7 +12,7 @@ Dolibarr uses some external libraries released under different licenses. This is
 Component              Version       License                     GPL Compatible  Usage
 -------------------------------------------------------------------------------------
 PHP libraries:
-AdoDb-Date             0.33          Modified BSD License        Yes             Date convertion (not into rpm package)
+AdoDb-Date             0.36          Modified BSD License        Yes             Date convertion (not into rpm package)
 ChromePHP              4.1.0         Apache Software License 2.0 Yes             Return server log to chrome browser console
 CKEditor               4.3.3         LGPL-2.1+                   Yes             Editor WYSIWYG
 EvalMath               1.0           BSD                         Yes             Safe math expressions evaluation
@@ -24,7 +24,7 @@ Mobiledetect           2.8.3         MIT License                 Yes
 NuSoap                 0.9.5         LGPL 2.1+                   Yes             Library to develop SOAP Web services (not into rpm and deb package)
 PEAR Mail_MIME         1.8.9         BSD                         Yes             NuSoap dependency
 odtPHP                 1.0.1         GPL-2+  b                   Yes             Library to build/edit ODT files
-PHPExcel               1.8.0         LGPL-2.1+                   Yes             Read/Write XLS files, read ODS files
+PHPExcel               1.8.1         LGPL-2.1+                   Yes             Read/Write XLS files, read ODS files
 php-iban               1.4.7         LGPL-3+                     Yes             Parse and validate IBAN (and IIBAN) bank account information in PHP
 PHPoAuthLib            0.8.2         MIT License                 Yes             Library to provide oauth1 and oauth2 to different service
 PHPPrintIPP            1.3           GPL-2+                      Yes             Library to send print IPP requests

+ 3 - 3
composer.json

@@ -16,12 +16,12 @@
         "php": ">=5.3.0",
         "ext-curl": "*",
         "ccampbell/chromephp": "^4.1",
-        "ckeditor/ckeditor": "4.3.3",
+        "ckeditor/ckeditor": "dev-full/4.3.x#0b7c3f1",
         "mike42/escpos-php": "dev-master",
         "mobiledetect/mobiledetectlib": "2.8.3",
-        "phpoffice/phpexcel": "1.8.0",
+        "phpoffice/phpexcel": "1.8.1",
         "restler/framework": "^3.0",
-        "tecnick.com/tcpdf": "6.2.6",
+        "tecnickcom/tcpdf": "6.2.6",
         "raven/raven": "^0.12.0",
         "firephp/firephp-core": "^0.4.0"
     },

+ 13 - 14
composer.lock

@@ -4,8 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "d88b5c84a9ea1af354d867ba2e2ab251",
-    "content-hash": "85e60ec7f8ab593387c7bd10d8db860d",
+    "hash": "335eb7bd5c2eb116fd2da80b4f48e857",
     "packages": [
         {
             "name": "ccampbell/chromephp",
@@ -52,16 +51,16 @@
         },
         {
             "name": "ckeditor/ckeditor",
-            "version": "4.3.3",
+            "version": "dev-full/4.3.x",
             "source": {
                 "type": "git",
                 "url": "https://github.com/ckeditor/ckeditor-releases.git",
-                "reference": "0068dd540ce8bf1815abb7b5455c55354bc56334"
+                "reference": "0b7c3f1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/ckeditor/ckeditor-releases/zipball/0068dd540ce8bf1815abb7b5455c55354bc56334",
-                "reference": "0068dd540ce8bf1815abb7b5455c55354bc56334",
+                "url": "https://api.github.com/repos/ckeditor/ckeditor-releases/zipball/252e512e911f21d880ea542fe162c4643885b317",
+                "reference": "0b7c3f1",
                 "shasum": ""
             },
             "type": "library",
@@ -89,7 +88,7 @@
                 "text",
                 "wysiwyg"
             ],
-            "time": "2014-02-26 15:34:37"
+            "time": "2014-02-26 15:43:10"
         },
         {
             "name": "firephp/firephp-core",
@@ -239,16 +238,16 @@
         },
         {
             "name": "phpoffice/phpexcel",
-            "version": "1.8.0",
+            "version": "1.8.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/PHPOffice/PHPExcel.git",
-                "reference": "e69a5e4d0ffa7fb6f171859e0a04346e580df30b"
+                "reference": "372c7cbb695a6f6f1e62649381aeaa37e7e70b32"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/PHPOffice/PHPExcel/zipball/e69a5e4d0ffa7fb6f171859e0a04346e580df30b",
-                "reference": "e69a5e4d0ffa7fb6f171859e0a04346e580df30b",
+                "url": "https://api.github.com/repos/PHPOffice/PHPExcel/zipball/372c7cbb695a6f6f1e62649381aeaa37e7e70b32",
+                "reference": "372c7cbb695a6f6f1e62649381aeaa37e7e70b32",
                 "shasum": ""
             },
             "require": {
@@ -292,7 +291,7 @@
                 "xls",
                 "xlsx"
             ],
-            "time": "2014-03-02 15:22:49"
+            "time": "2015-05-01 07:00:55"
         },
         {
             "name": "raven/raven",
@@ -423,7 +422,7 @@
             "time": "2015-08-04 07:52:49"
         },
         {
-            "name": "tecnick.com/tcpdf",
+            "name": "tecnickcom/tcpdf",
             "version": "6.2.6",
             "source": {
                 "type": "git",
@@ -483,7 +482,6 @@
                 "pdf417",
                 "qrcode"
             ],
-            "abandoned": "tecnickcom/tcpdf",
             "time": "2015-01-28 18:51:40"
         }
     ],
@@ -491,6 +489,7 @@
     "aliases": [],
     "minimum-stability": "stable",
     "stability-flags": {
+        "ckeditor/ckeditor": 20,
         "mike42/escpos-php": 20
     },
     "prefer-stable": false,

+ 1 - 1
dev/dolibarr_changes.txt

@@ -69,7 +69,7 @@ Add tcpdi.php
 Add tcpdi_parser.php and replace:
 require_once(dirname(__FILE__).'/include/tcpdf_filters.php');
 with:
-require_once(dirname(__FILE__).'/../tecnick.com/tcpdf/include/tcpdf_filters.php');
+require_once(dirname(__FILE__).'/../tecnickcom/tcpdf/include/tcpdf_filters.php');
 
 
 

+ 2 - 2
dev/test/testtcpdf.php

@@ -27,8 +27,8 @@
  * @since 2008-03-04
  */
 
-require_once('../../htdocs/includes/tecnick.com/tcpdf/config/tcpdf_config.php');
-require_once('../../htdocs/includes/tecnick.com/tcpdf/tcpdf.php');
+require_once('../../htdocs/includes/tecnickcom/tcpdf/config/tcpdf_config.php');
+require_once('../../htdocs/includes/tecnickcom/tcpdf/tcpdf.php');
 
 // create new PDF document
 $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

+ 2 - 2
dev/test/testutf.php

@@ -47,8 +47,8 @@ print 'Files has been created. Check its name from your explorer'."\n";
  * @since 2008-09-15
  */
 
-require_once('../../htdocs/includes/tecnick.com/tcpdf/config/tcpdf_config.php');
-require_once('../../htdocs/includes/tecnick.com/tcpdf/tcpdf.php');
+require_once('../../htdocs/includes/tecnickcom/tcpdf/config/tcpdf_config.php');
+require_once('../../htdocs/includes/tecnickcom/tcpdf/tcpdf.php');
 
 // create new PDF document
 $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

+ 1 - 1
htdocs/filefunc.inc.php

@@ -208,7 +208,7 @@ define('MAIN_DB_PREFIX',$dolibarr_main_db_prefix);
 // Path to root libraries
 if (! defined('ADODB_PATH'))           { define('ADODB_PATH',           (!isset($dolibarr_lib_ADODB_PATH))?DOL_DOCUMENT_ROOT.'/includes/adodbtime/':(empty($dolibarr_lib_ADODB_PATH)?'':$dolibarr_lib_ADODB_PATH.'/')); }
 if (! defined('FPDF_PATH'))            { define('FPDF_PATH',            (empty($dolibarr_lib_FPDF_PATH))?DOL_DOCUMENT_ROOT.'/includes/fpdf/':$dolibarr_lib_FPDF_PATH.'/'); }	// Used only for package that can't include tcpdf
-if (! defined('TCPDF_PATH'))           { define('TCPDF_PATH',           (empty($dolibarr_lib_TCPDF_PATH))?DOL_DOCUMENT_ROOT.'/includes/tecnick.com/tcpdf/':$dolibarr_lib_TCPDF_PATH.'/'); }
+if (! defined('TCPDF_PATH'))           { define('TCPDF_PATH',           (empty($dolibarr_lib_TCPDF_PATH))?DOL_DOCUMENT_ROOT.'/includes/tecnickcom/tcpdf/':$dolibarr_lib_TCPDF_PATH.'/'); }
 if (! defined('FPDI_PATH'))            { define('FPDI_PATH',            (empty($dolibarr_lib_FPDI_PATH))?DOL_DOCUMENT_ROOT.'/includes/fpdfi/':$dolibarr_lib_FPDI_PATH.'/'); }
 if (! defined('TCPDI_PATH'))           { define('TCPDI_PATH',           (empty($dolibarr_lib_TCPDI_PATH))?DOL_DOCUMENT_ROOT.'/includes/tcpdi/':$dolibarr_lib_TCPDI_PATH.'/'); }
 if (! defined('NUSOAP_PATH'))          { define('NUSOAP_PATH',          (!isset($dolibarr_lib_NUSOAP_PATH))?DOL_DOCUMENT_ROOT.'/includes/nusoap/lib/':(empty($dolibarr_lib_NUSOAP_PATH)?'':$dolibarr_lib_NUSOAP_PATH.'/')); }

+ 42 - 10
htdocs/includes/adodbtime/adodb-time.inc.php

@@ -57,7 +57,7 @@ adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)
 
 COPYRIGHT
 
-(c) 2003-2005 John Lim and released under BSD-style license except for code by
+(c) 2003-2014 John Lim and released under BSD-style license except for code by
 jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year
 and originally found at http://www.php.net/manual/en/function.mktime.php
 
@@ -73,6 +73,9 @@ These should be posted to the ADOdb forums at
 
 FUNCTION DESCRIPTIONS
 
+** FUNCTION adodb_time()
+
+Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) as an unsigned integer.
 
 ** FUNCTION adodb_getdate($date=false)
 
@@ -241,6 +244,14 @@ b. Implement daylight savings, which looks awfully complicated, see
 
 
 CHANGELOG
+- 16 Jan 2011 0.36
+Added adodb_time() which returns current time. If > 2038, will return as float
+
+- 7 Feb 2011 0.35
+Changed adodb_date to be symmetric with adodb_mktime. See $jan1_71. fix for bc.
+
+- 13 July 2010 0.34
+Changed adodb_get_gm_diff to use DateTimeZone().
 
 - 11 Feb 2008 0.33
 * Bug in 0.32 fix for hour handling. Fixed.
@@ -386,7 +397,7 @@ First implementation.
 /*
 	Version Number
 */
-define('ADODB_DATE_VERSION',0.33);
+define('ADODB_DATE_VERSION',0.35);
 
 $ADODB_DATETIME_CLASS = (PHP_VERSION >= 5.2);
 
@@ -601,6 +612,12 @@ function adodb_date_test()
 	else print "<p><b>Failed</b> :-(</p>";
 }
 
+function adodb_time()
+{
+	$d = new DateTime();
+	return $d->format('U');
+}
+
 /**
 	Returns day of week, 0 = Sunday,... 6=Saturday.
 	Algorithm from PEAR::Date_Calc
@@ -729,9 +746,17 @@ global $ADODB_DATETIME_CLASS;
 	} else {
 		if (isset($TZ)) return $TZ;
 		$y = date('Y');
-		$TZ = mktime(0,0,0,12,2,$y) - gmmktime(0,0,0,12,2,$y);
+		/*
+		if (function_exists('date_default_timezone_get') && function_exists('timezone_offset_get')) {
+			$tzonename = date_default_timezone_get();
+			if ($tzonename) {
+				$tobj = new DateTimeZone($tzonename);
+				$TZ = -timezone_offset_get($tobj,new DateTime("now",$tzo));
+			}
+		}
+		*/
+		if (empty($TZ)) $TZ = mktime(0,0,0,12,2,$y) - gmmktime(0,0,0,12,2,$y);
 	}
-
 	return $TZ;
 }
 
@@ -1006,7 +1031,6 @@ function adodb_tz_offset($gmt,$isphp5)
 		return sprintf('%s%02d%02d',($gmt<=0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
 	else
 		return sprintf('%s%02d%02d',($gmt<0)?'+':'-',floor($zhrs),($zhrs-$hrs)*60);
-	break;
 }
 
 
@@ -1041,11 +1065,19 @@ function adodb_date($fmt,$d=false,$is_gmt=false)
 {
 static $daylight;
 global $ADODB_DATETIME_CLASS;
+static $jan1_1971;
+
+
+	if (!isset($daylight)) {
+		$daylight = function_exists('adodb_daylight_sv');
+		if (empty($jan1_1971)) $jan1_1971 = mktime(0,0,0,1,1,1971); // we only use date() when > 1970 as adodb_mktime() only uses mktime() when > 1970
+	}
 
 	if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
 	if (!defined('ADODB_TEST_DATES')) {
 		if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
-			if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
+
+			if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= $jan1_1971) // if windows, must be +ve integer
 				return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d);
 
 		}
@@ -1054,7 +1086,6 @@ global $ADODB_DATETIME_CLASS;
 
 	$arr = _adodb_getdate($d,true,$is_gmt);
 
-	if (!isset($daylight)) $daylight = function_exists('adodb_daylight_sv');
 	if ($daylight) adodb_daylight_sv($arr, $is_gmt);
 
 	$year = $arr['year'];
@@ -1075,6 +1106,9 @@ global $ADODB_DATETIME_CLASS;
 	*/
 	for ($i=0; $i < $max; $i++) {
 		switch($fmt[$i]) {
+		case 'e':
+			$dates .= date('e');
+			break;
 		case 'T':
 			if ($ADODB_DATETIME_CLASS) {
 				$dt = new DateTime();
@@ -1215,7 +1249,7 @@ function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=fa
 
 		// for windows, we don't check 1970 because with timezone differences,
 		// 1 Jan 1970 could generate negative timestamp, which is illegal
-		$usephpfns = (1971 < $year && $year < 2038
+		$usephpfns = (1970 < $year && $year < 2038
 			|| !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
 			);
 
@@ -1422,5 +1456,3 @@ global $ADODB_DATE_LOCALE;
 	$ret = adodb_date($fmtdate, $ts, $is_gmt);
 	return $ret;
 }
-
-?>

+ 62 - 19
htdocs/includes/ckeditor/ckeditor/README.md

@@ -1,39 +1,82 @@
-CKEditor 4
-==========
+CKEditor 4 - Releases
+=====================
 
-Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.  
-http://ckeditor.com - See LICENSE.md for license information.
+## Releases Code
 
-CKEditor is a text editor to be used inside web pages. It's not a replacement
-for desktop text editors like Word or OpenOffice, but a component to be used as
-part of web applications and websites.
+This repository contains the official release versions of [CKEditor](http://ckeditor.com).
+
+There are four versions for each release &mdash; `standard-all`, `basic`, `standard`, and `full`.
+They differ in the number of plugins that are compiled into the main `ckeditor.js` file as well as the toolbar configuration.
+
+See the [comparison](http://ckeditor.com/presets) of the `basic`, `standard`, and `full` installation presets for more details.
+
+The `standard-all` build includes all official CKSource plugins with only those from the `standard` installation preset compiled into the `ckeditor.js` file and enabled in the configuration. 
+
+All versions available in this repository were built using [CKBuilder](http://ckeditor.com/builder), so they are optimized and ready to be used in a production environment.
 
 ## Documentation
 
-The full editor documentation is available online at the following address:
-http://docs.ckeditor.com
+Developer documentation for CKEditor is available online at: <http://docs.ckeditor.com>.
 
 ## Installation
 
-Installing CKEditor is an easy task. Just follow these simple steps:
+### Git clone
+
+To install one of the available releases, just clone this repository and switch to the respective branch (see next section):
+
+	git clone -b <release branch> git://github.com/ckeditor/ckeditor-releases.git
+	
+### Git submodule
+
+If you are using git for your project and you want to integrate CKEditor, we recommend to add this repository as a
+[submodule](http://git-scm.com/book/en/Git-Tools-Submodules).
+
+	git submodule add -b <release branch> git://github.com/ckeditor/ckeditor-releases.git <clone dir>
+	git commit -m "Added CKEditor submodule in <clone dir> directory."
+
+### Using Package Managers
+
+See the [Installing CKEditor with Package Managers](http://docs.ckeditor.com/#!/guide/dev_package_managers) article for more details about installing CKEditor with Bower and Composer.
 
- 1. **Download** the latest version from the CKEditor website:
-    http://ckeditor.com. You should have already completed this step, but be
-    sure you have the very latest version.
- 2. **Extract** (decompress) the downloaded file into the root of your website.
+## Repository Structure
 
-**Note:** CKEditor is by default installed in the `ckeditor` folder. You can
-place the files in whichever you want though.
+### Branches
+
+This repository contains the following branches:
+
+  - `master` and `latest` &ndash; the latest release of the `standard-all` preset (including betas).
+  - `stable` &ndash; the latest stable release of the `standard-all` preset (non-beta).
+  - `A.B.x` (e.g. `4.3.x`) &ndash; the latest release of the `standard-all` preset in the `A.B` branch.
+  - `(basic|standard|full)/stable` &ndash; the latest stable release tag point (non-beta).
+  - `(basic|standard|full)/latest` &ndash; the latest release tag point (including betas).
+  - `(basic|standard|full)/A.B.x` (e.g. `basic/4.0.x`) &ndash; the latest releases in the `A.B` branch.
+
+### Tags
+
+**Since version 4.3.3** this repository uses the following tag naming rules:
+
+  - `x.y.z` &ndash; contains the `standard-all` editor build, e.g. `4.3.3`, `4.4.0` etc.
+  - `(basic|standard|full)/x.y.z` &ndash; contains the editor build with a given preset, e.g. `basic/4.3.3`.
+
+The version numbers follow the [Semantic Versioning 2.0.0](http://semver.org/) scheme.
+
+Up to version **4.3.2** the tags were released in the following form `x.y[.z]/(basic|standard|full)`.
+For example: `4.0/basic`, `4.0.1/standard`. This convention was changed in CKEditor 4.3.3 to conform to the Semantic Versioning scheme.
 
 ## Checking Your Installation
 
-The editor comes with a few sample pages that can be used to verify that
-installation proceeded properly. Take a look at the `samples` directory.
+The editor comes with a few sample pages that can be used to verify if the installation succeeded. Take a look at the `samples` directory.
 
-To test your installation, just call the following page at your website:
+To test your installation, just call the following page for your website:
 
 	http://<your site>/<CKEditor installation path>/samples/index.html
 
 For example:
 
 	http://www.example.com/ckeditor/samples/index.html
+
+### License
+
+Licensed under the GPL, LGPL, and MPL licenses, at your choice.
+
+Please check the `LICENSE.md` file for more information about the license.

+ 0 - 442
htdocs/includes/ckeditor/ckeditor/_source/CHANGES.md

@@ -1,442 +0,0 @@
-CKEditor 4 Changelog
-====================
-
-## CKEditor 4.3.3
-
-Fixed Issues:
-
-* [#11500](http://dev.ckeditor.com/ticket/11500): [Webkit/Blink] Fixed: Selection lost when setting data in another inline editor. Additionally, [`selection.removeAllRanges()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-removeAllRanges) is now scoped to selection's [root](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-property-root).
-* [#11104](http://dev.ckeditor.com/ticket/11104): [IE] Fixed: Various issues with scrolling and selection when focusing widgets.
-* [#11487](http://dev.ckeditor.com/ticket/11487): Moving mouse over the [Enhanced Image](http://ckeditor.com/addon/image2) widget will no longer change the value returned by the [`editor.checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) method.
-* [#8673](http://dev.ckeditor.com/ticket/8673): [WebKit] Fixed: Cannot select and remove the [Page Break](http://ckeditor.com/addon/pagebreak).
-* [#11413](http://dev.ckeditor.com/ticket/11413): Fixed: Incorrect [`editor.execCommand()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-execCommand) behavior.
-* [#11438](http://dev.ckeditor.com/ticket/11438): Splitting table cells vertically is no longer changing table structure.
-* [#8899](http://dev.ckeditor.com/ticket/8899): Fixed: Links in the [About CKEditor](http://ckeditor.com/addon/about) dialog window now open in a new browser window or tab.
-* [#11490](http://dev.ckeditor.com/ticket/11490): Fixed: [Menu button](http://ckeditor.com/addon/menubutton) panel not showing in the source mode.
-* [#11417](http://dev.ckeditor.com/ticket/11417): The [`widget.doubleclick`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-event-doubleclick) event is not canceled anymore after editing was triggered.
-* [#11253](http://dev.ckeditor.com/ticket/11253): [IE] Fixed: Clipped upload button in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.
-* [#11359](http://dev.ckeditor.com/ticket/11359): Standardized the way anchors are discovered by the [Link](http://ckeditor.com/addon/link) plugin.
-* [#11058](http://dev.ckeditor.com/ticket/11058): [IE8] Fixed: Error when deleting a table row.
-* [#11508](http://dev.ckeditor.com/ticket/11508): Fixed: [`htmlDataProcessor`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor) discovering protected attributes within other attributes' values.
-* [#11533](http://dev.ckeditor.com/ticket/11533): Widgets: Avoid recurring upcasts if the DOM structure was modified during an upcast.
-* [#11400](http://dev.ckeditor.com/ticket/11400): Fixed: The [`domObject.removeAllListeners()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.domObject-method-removeAllListeners) method does not remove custom listeners completely.
-* [#11493](http://dev.ckeditor.com/ticket/11493): Fixed: The [`selection.getRanges()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-getRanges) method does not override cached ranges when used with the `onlyEditables` argument.
-* [#11390](http://dev.ckeditor.com/ticket/11390): [IE] All [XML](http://ckeditor.com/addon/xml) plugin [methods](http://docs.ckeditor.com/#!/api/CKEDITOR.xml) now work in IE10+.
-* [#11542](http://dev.ckeditor.com/ticket/11542): [IE11] Fixed: Blurry toolbar icons when Right-to-Left UI language is set.
-* [#11504](http://dev.ckeditor.com/ticket/11504): Fixed: When [`config.fullPage`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fullPage) is set to `true`, entities are not encoded in editor output.
-* [#11004](http://dev.ckeditor.com/ticket/11004): Integrated [Enhanced Image](http://ckeditor.com/addon/image2) dialog window with [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter).
-* [#11439](http://dev.ckeditor.com/ticket/11439): Fixed: Properties get cloned in the Cell Properties dialog window if multiple cells are selected.
-
-## CKEditor 4.3.2
-
-Fixed Issues:
-
-* [#11331](http://dev.ckeditor.com/ticket/11331): A menu button will have a changed label when selected instead of using the `aria-pressed` attribute.
-* [#11177](http://dev.ckeditor.com/ticket/11177): Widget drag handler improvements:
-  * [#11176](http://dev.ckeditor.com/ticket/11176): Fixed: Initial position is not updated when the widget data object is empty.
-  * [#11001](http://dev.ckeditor.com/ticket/11001): Fixed: Multiple synchronous layout recalculations are caused by initial drag handler positioning causing performance issues.
-  * [#11161](http://dev.ckeditor.com/ticket/11161): Fixed: Drag handler is not repositioned in various situations.
-  * [#11281](http://dev.ckeditor.com/ticket/11281): Fixed: Drag handler and mask are duplicated after widget reinitialization.
-* [#11207](http://dev.ckeditor.com/ticket/11207): [Firefox] Fixed: Misplaced [Enhanced Image](http://ckeditor.com/addon/image2) resizer in the inline editor.
-* [#11102](http://dev.ckeditor.com/ticket/11102): `CKEDITOR.template` improvements:
-  * [#11102](http://dev.ckeditor.com/ticket/11102): Added newline character support.
-  * [#11216](http://dev.ckeditor.com/ticket/11216): Added "\\'" substring support.
-* [#11121](http://dev.ckeditor.com/ticket/11121): [Firefox] Fixed: High Contrast mode is enabled when the editor is loaded in a hidden iframe.
-* [#11350](http://dev.ckeditor.com/ticket/11350): The default value of [`config.contentsCss`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-contentsCss) is affected by [`CKEDITOR.getUrl()`](http://docs.ckeditor.com/#!/api/CKEDITOR-method-getUrl).
-* [#11097](http://dev.ckeditor.com/ticket/11097): Improved the [Autogrow](http://ckeditor.com/addon/autogrow) plugin performance when dealing with very big tables.
-* [#11290](http://dev.ckeditor.com/ticket/11290): Removed redundant code in the [Source Dialog](http://ckeditor.com/addon/sourcedialog) plugin.
-* [#11133](http://dev.ckeditor.com/ticket/11133): [Page Break](http://ckeditor.com/addon/pagebreak) becomes editable if pasted.
-* [#11126](http://dev.ckeditor.com/ticket/11126): Fixed: Native Undo executed once the bottom of the snapshot stack is reached.
-* [#11131](http://dev.ckeditor.com/ticket/11131): [Div Editing Area](http://ckeditor.com/addon/divarea): Fixed: Error thrown when switching to source mode if the selection was in widget's nested editable.
-* [#11139](http://dev.ckeditor.com/ticket/11139): [Div Editing Area](http://ckeditor.com/addon/divarea): Fixed: Elements Path is not cleared after switching to source mode.
-* [#10778](http://dev.ckeditor.com/ticket/10778): Fixed a bug with range enlargement. The range no longer expands to visible whitespace.
-* [#11146](http://dev.ckeditor.com/ticket/11146): [IE] Fixed: Preview window switches Internet Explorer to Quirks Mode.
-* [#10762](http://dev.ckeditor.com/ticket/10762): [IE] Fixed: JavaScript code displayed in preview window's URL bar.
-* [#11186](http://dev.ckeditor.com/ticket/11186): Introduced the [`widgets.repository.addUpcastCallback()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-addUpcastCallback) method that allows to block upcasting given element to a widget.
-* [#11307](http://dev.ckeditor.com/ticket/11307): Fixed: Paste as Plain Text conflict with the [MooTools](http://mootools.net) library.
-* [#11140](http://dev.ckeditor.com/ticket/11140): [IE11] Fixed: Anchors are not draggable.
-* [#11379](http://dev.ckeditor.com/ticket/11379): Changed default contents `line-height` to unitless values to avoid huge text overlapping (like in [#9696](http://dev.ckeditor.com/ticket/9696)).
-* [#10787](http://dev.ckeditor.com/ticket/10787): [Firefox] Fixed: Broken replacement of text while pasting into `div`-based editor.
-* [#10884](http://dev.ckeditor.com/ticket/10884): Widgets integration with the [Show Blocks](http://ckeditor.com/addon/showblocks) plugin.
-* [#11021](http://dev.ckeditor.com/ticket/11021): Fixed: An error thrown when selecting entire editable contents while fake selection is on.
-* [#11086](http://dev.ckeditor.com/ticket/11086): [IE8] Re-enable inline widgets drag&drop in Internet Explorer 8.
-* [#11372](http://dev.ckeditor.com/ticket/11372): Widgets: Special characters encoded twice in nested editables.
-* [#10068](http://dev.ckeditor.com/ticket/10068): Fixed: Support for protocol-relative URLs.
-* [#11283](http://dev.ckeditor.com/ticket/11283): [Enhanced Image](http://ckeditor.com/addon/image2): A `<div>` element with `text-align: center` and an image inside is not recognised correctly.
-* [#11196](http://dev.ckeditor.com/ticket/11196): [Accessibility Instructions](http://ckeditor.com/addon/a11yhelp): Allowed additional keyboard button labels to be translated in the dialog window.
-
-## CKEditor 4.3.1
-
-**Important Notes:**
-
-* To match the naming convention, the `language` button is now `Language` ([#11201](http://dev.ckeditor.com/ticket/11201)).
-* [Enhanced Image](http://ckeditor.com/addon/image2) button, context menu, command, and icon names match those of the [Image](http://ckeditor.com/addon/image) plugin ([#11222](http://dev.ckeditor.com/ticket/11222)).
-
-Fixed Issues:
-
-* [#11244](http://dev.ckeditor.com/ticket/11244): Changed: The [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method now fires the [`widget.repository.checkWidgets`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-event-checkWidgets) event, so from CKEditor 4.3.1 it is preferred to use the method rather than fire the event.
-* [#11171](http://dev.ckeditor.com/ticket/11171): Fixed: [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) and [`editor.insertText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertText) methods do not call the [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method.
-* [#11085](http://dev.ckeditor.com/ticket/11085): [IE8] Replaced preview generated by the [Mathematical Formulas](http://ckeditor.com/addon/mathjax) widget with a placeholder.
-* [#11044](http://dev.ckeditor.com/ticket/11044): Enhanced WAI-ARIA support for the [Language](http://ckeditor.com/addon/language) plugin drop-down menu.
-* [#11075](http://dev.ckeditor.com/ticket/11075): With drop-down menu button focused, pressing the *Down Arrow* key will now open the menu and focus its first option.
-* [#11165](http://dev.ckeditor.com/ticket/11165): Fixed: The [File Browser](http://ckeditor.com/addon/filebrowser) plugin cannot be removed from the editor.
-* [#11159](http://dev.ckeditor.com/ticket/11159): [IE9-10] [Enhanced Image](http://ckeditor.com/addon/image2): Fixed buggy discovery of image dimensions.
-* [#11101](http://dev.ckeditor.com/ticket/11101): Drop-down lists no longer break when given double quotes.
-* [#11077](http://dev.ckeditor.com/ticket/11077): [Enhanced Image](http://ckeditor.com/addon/image2): Empty undo step recorded when resizing the image.
-* [#10853](http://dev.ckeditor.com/ticket/10853): [Enhanced Image](http://ckeditor.com/addon/image2): Widget has paragraph wrapper when de-captioning unaligned image.
-* [#11198](http://dev.ckeditor.com/ticket/11198): Widgets: Drag handler is not fully visible when an inline widget is in a heading.
-* [#11132](http://dev.ckeditor.com/ticket/11132): [Firefox] Fixed: Caret is lost after drag and drop of an inline widget.
-* [#11182](http://dev.ckeditor.com/ticket/11182): [IE10-11] Fixed: Editor crashes (IE11) or works with minor issues (IE10) if a page is loaded in Quirks Mode. See [`env.quirks`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-quirks) for more details.
-* [#11204](http://dev.ckeditor.com/ticket/11204): Added `figure` and `figcaption` styles to the `contents.css` file so [Enhanced Image](http://ckeditor.com/addon/image2) looks nicer.
-* [#11202](http://dev.ckeditor.com/ticket/11202): Fixed: No newline in [BBCode](http://ckeditor.com/addon/bbcode) mode.
-* [#10890](http://dev.ckeditor.com/ticket/10890): Fixed: Error thrown when pressing the *Delete* key in a list item.
-* [#10055](http://dev.ckeditor.com/ticket/10055): [IE8-10] Fixed: *Delete* pressed on a selected image causes the browser to go back.
-* [#11183](http://dev.ckeditor.com/ticket/11183): Fixed: Inserting a horizontal rule or a table in multiple row selection causes a browser crash. Additionally, the [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) method does not insert the element into every range of a selection any more.
-* [#11042](http://dev.ckeditor.com/ticket/11042): Fixed: Selection made on an element containing a non-editable element was not auto faked.
-* [#11125](http://dev.ckeditor.com/ticket/11125): Fixed: Keyboard navigation through menu and drop-down items will now cycle.
-* [#11011](http://dev.ckeditor.com/ticket/11011): Fixed: The [`editor.applyStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-applyStyle) method removes attributes from nested elements.
-* [#11179](http://dev.ckeditor.com/ticket/11179): Fixed: [`editor.destroy()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-destroy) does not cleanup content generated by the [Table Resize](http://ckeditor.com/addon/tableresize) plugin for inline editors.
-* [#11237](http://dev.ckeditor.com/ticket/11237): Fixed: Table border attribute value is deleted when pasting content from Microsoft Word.
-* [#11250](http://dev.ckeditor.com/ticket/11250): Fixed: HTML entities inside the `<textarea>` element are not encoded.
-* [#11260](http://dev.ckeditor.com/ticket/11260): Fixed: Initially disabled buttons are not read by JAWS as disabled.
-* [#11200](http://dev.ckeditor.com/ticket/11200):  Added [Clipboard](http://ckeditor.com/addon/clipboard) plugin as a dependency for [Widget](http://ckeditor.com/addon/widget) to fix drag and drop.
-
-## CKEditor 4.3
-
-New Features:
-
-* [#10612](http://dev.ckeditor.com/ticket/10612): Internet Explorer 11 support.
-* [#10869](http://dev.ckeditor.com/ticket/10869): Widgets: Added better integration with the [Elements Path](http://ckeditor.com/addon/elementspath) plugin.
-* [#10886](http://dev.ckeditor.com/ticket/10886): Widgets: Added tooltip to the drag handle.
-* [#10933](http://dev.ckeditor.com/ticket/10933): Widgets: Introduced drag and drop of block widgets with the [Line Utilities](http://ckeditor.com/addon/lineutils) plugin.
-* [#10936](http://dev.ckeditor.com/ticket/10936): Widget System changes for easier integration with other dialog systems.
-* [#10895](http://dev.ckeditor.com/ticket/10895): [Enhanced Image](http://ckeditor.com/addon/image2): Added file browser integration.
-* [#11002](http://dev.ckeditor.com/ticket/11002): Added the [`draggable`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-draggable) option to disable drag and drop support for widgets.
-* [#10937](http://dev.ckeditor.com/ticket/10937): [Mathematical Formulas](http://ckeditor.com/addon/mathjax) widget improvements:
-  * loading indicator ([#10948](http://dev.ckeditor.com/ticket/10948)),
-  * applying paragraph changes (like font color change) to iframe ([#10841](http://dev.ckeditor.com/ticket/10841)),
-  * Firefox and IE9 clipboard fixes ([#10857](http://dev.ckeditor.com/ticket/10857)),
-  * fixing same origin policy issue ([#10840](http://dev.ckeditor.com/ticket/10840)),
-  * fixing undo bugs ([#10842](http://dev.ckeditor.com/ticket/10842), [#10930](http://dev.ckeditor.com/ticket/10930)),
-  * fixing other minor bugs.
-* [#10862](http://dev.ckeditor.com/ticket/10862): [Placeholder](http://ckeditor.com/addon/placeholder) plugin was rewritten as a widget.
-* [#10822](http://dev.ckeditor.com/ticket/10822): Added styles system integration with non-editable elements (for example widgets) and their nested editables. Styles cannot change non-editable content and are applied in nested editable only if allowed by its type and content filter.
-* [#10856](http://dev.ckeditor.com/ticket/10856): Menu buttons will now toggle the visibility of their panels when clicked multiple times. [Language](http://ckeditor.com/addon/language) plugin fixes: Added active language highlighting, added an option to remove the language.
-* [#10028](http://dev.ckeditor.com/ticket/10028): New [`config.dialog_noConfirmCancel`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-dialog_noConfirmCancel) configuration option that eliminates the need to confirm closing of a dialog window when the user changed any of its fields.
-* [#10848](http://dev.ckeditor.com/ticket/10848): Integrate remaining plugins ([Styles](http://ckeditor.com/addon/stylescombo), [Format](http://ckeditor.com/addon/format), [Font](http://ckeditor.com/addon/font), [Color Button](http://ckeditor.com/addon/colorbutton), [Language](http://ckeditor.com/addon/language) and [Indent](http://ckeditor.com/addon/indent)) with [active filter](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeFilter).
-* [#10855](http://dev.ckeditor.com/ticket/10855): Change the extension of emoticons in the [BBCode](http://ckeditor.com/addon/bbcode) sample from GIF to PNG.
-
-Fixed Issues:
-
-* [#10831](http://dev.ckeditor.com/ticket/10831): [Enhanced Image](http://ckeditor.com/addon/image2): Merged `image2inline` and `image2block` into one `image2` widget.
-* [#10835](http://dev.ckeditor.com/ticket/10835): [Enhanced Image](http://ckeditor.com/addon/image2): Improved visibility of the resize handle.
-* [#10836](http://dev.ckeditor.com/ticket/10836): [Enhanced Image](http://ckeditor.com/addon/image2): Preserve custom mouse cursor while resizing the image.
-* [#10939](http://dev.ckeditor.com/ticket/10939): [Firefox] [Enhanced Image](http://ckeditor.com/addon/image2): hovering the image causes it to change.
-* [#10866](http://dev.ckeditor.com/ticket/10866): Fixed: Broken *Tab* key navigation in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.
-* [#10833](http://dev.ckeditor.com/ticket/10833): Fixed: *Lock ratio* option should be on by default in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.
-* [#10881](http://dev.ckeditor.com/ticket/10881): Various improvements to *Enter* key behavior in nested editables.
-* [#10879](http://dev.ckeditor.com/ticket/10879): [Remove Format](http://ckeditor.com/addon/removeformat) should not leak from a nested editable.
-* [#10877](http://dev.ckeditor.com/ticket/10877): Fixed: [WebSpellChecker](http://ckeditor.com/addon/wsc) fails to apply changes if a nested editable was focused.
-* [#10877](http://dev.ckeditor.com/ticket/10877): Fixed: [SCAYT](http://ckeditor.com/addon/wsc) blocks typing in nested editables.
-* [#11079](http://dev.ckeditor.com/ticket/11079): Add button icons to the [Placeholder](http://ckeditor.com/addon/placeholder) sample.
-* [#10870](http://dev.ckeditor.com/ticket/10870): The `paste` command is no longer being disabled when the clipboard is empty.
-* [#10854](http://dev.ckeditor.com/ticket/10854): Fixed: Firefox prepends `<br>` to `<body>`, so it is stripped by the HTML data processor.
-* [#10823](http://dev.ckeditor.com/ticket/10823): Fixed: [Link](http://ckeditor.com/addon/link) plugin does not work with non-editable content.
-* [#10828](http://dev.ckeditor.com/ticket/10828): [Magic Line](http://ckeditor.com/addon/magicline) integration with the Widget System.
-* [#10865](http://dev.ckeditor.com/ticket/10865): Improved hiding copybin, so copying widgets works smoothly.
-* [#11066](http://dev.ckeditor.com/ticket/11066): Widget's private parts use CSS reset.
-* [#11027](http://dev.ckeditor.com/ticket/11027): Fixed: Block commands break on widgets; added the [`contentDomInvalidated`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-contentDomInvalidated) event.
-* [#10430](http://dev.ckeditor.com/ticket/10430): Resolve dependence of the [Image](http://ckeditor.com/addon/image) plugin on the [Form Elements](http://ckeditor.com/addon/forms) plugin.
-* [#10911](http://dev.ckeditor.com/ticket/10911): Fixed: Browser *Alt* hotkeys will no longer be blocked while a widget is focused.
-* [#11082](http://dev.ckeditor.com/ticket/11082): Fixed: Selected widget is not copied or cut when using toolbar buttons or context menu.
-* [#11083](http://dev.ckeditor.com/ticket/11083): Fixed list and div element application to block widgets.
-* [#10887](http://dev.ckeditor.com/ticket/10887): Internet Explorer 8 compatibility issues related to the Widget System.
-* [#11074](http://dev.ckeditor.com/ticket/11074): Temporarily disabled inline widget drag and drop, because of seriously buggy native `range#moveToPoint` method.
-* [#11098](http://dev.ckeditor.com/ticket/11098): Fixed: Wrong selection position after undoing widget drag and drop.
-* [#11110](http://dev.ckeditor.com/ticket/11110): Fixed: IFrame and Flash objects are being incorrectly pasted in certain conditions.
-* [#11129](http://dev.ckeditor.com/ticket/11129): Page break is lost when loading data.
-* [#11123](http://dev.ckeditor.com/ticket/11123): [Firefox] Widget is destroyed after being dragged outside of `<body>`.
-* [#11124](http://dev.ckeditor.com/ticket/11124): Fixed the [Elements Path](http://ckeditor.com/addon/elementspath) in an editor using the [Div Editing Area](http://ckeditor.com/addon/divarea).
-
-## CKEditor 4.3 Beta
-
-New Features:
-
-* [#9764](http://dev.ckeditor.com/ticket/9764): Widget System.
-  * [Widget plugin](http://ckeditor.com/addon/widget) introducing the [Widget API](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget).
-  * New [`editor.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-enterMode) and [`editor.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-shiftEnterMode) properties &ndash; normalized versions of [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) and [`config.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode).
-  * Dynamic editor settings. Starting from CKEditor 4.3 Beta, *Enter* mode values and [content filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) instances may be changed dynamically (for example when the caret was placed in an element in which editor features should be adjusted). When you are implementing a new editor feature, you should base its behavior on [dynamic](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeEnterMode) or [static](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-enterMode) *Enter* mode values depending on whether this feature works in selection context or globally on editor content.
-      * Dynamic *Enter* mode values &ndash; [`editor.setActiveEnterMode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setActiveEnterMode) method, [`editor.activeEnterModeChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-activeEnterModeChange) event, and two properties: [`editor.activeEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeEnterMode) and [`editor.activeShiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeShiftEnterMode).
-      * Dynamic content filter instances &ndash; [`editor.setActiveFilter()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setActiveFilter) method, [`editor.activeFilterChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-activeFilterChange) event, and [`editor.activeFilter`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeFilter) property.
-  * "Fake" selection was introduced. It makes it possible to virtually select any element when the real selection remains hidden. See the  [`selection.fake()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-fake) method.
-  * Default [`htmlParser.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter) rules are not applied to non-editable elements (elements with `contenteditable` attribute set to `false` and their descendants) anymore. To add a rule which will be applied to all elements you need to pass an additional argument to the [`filter.addRules()`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter-method-addRules) method.
-  * Dozens of new methods were introduced &ndash; most interesting ones:
-      * [`document.find()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.document-method-find),
-      * [`document.findOne()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.document-method-findOne),
-      * [`editable.insertElementIntoRange()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElementIntoRange),
-      * [`range.moveToClosestEditablePosition()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-moveToClosestEditablePosition),
-      * New methods for [`htmlParser.node`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.node) and [`htmlParser.element`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.element).
-* [#10659](http://dev.ckeditor.com/ticket/10659): New [Enhanced Image](http://ckeditor.com/addon/image2) plugin that introduces a widget with integrated image captions, an option to center images, and dynamic "click and drag" resizing.
-* [#10664](http://dev.ckeditor.com/ticket/10664): New [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin that introduces the MathJax widget.
-* [#7987](https://dev.ckeditor.com/ticket/7987): New [Language](http://ckeditor.com/addon/language) plugin that implements Language toolbar button to support [WCAG 3.1.2 Language of Parts](http://www.w3.org/TR/UNDERSTANDING-WCAG20/meaning-other-lang-id.html).
-* [#10708](http://dev.ckeditor.com/ticket/10708): New [smileys](http://ckeditor.com/addon/smiley).
-
-## CKEditor 4.2.3
-
-Fixed Issues:
-
-* [#10994](http://dev.ckeditor.com/ticket/10994): Fixed: Loading external jQuery library when opening the [jQuery Adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) sample directly from file.
-* [#10975](http://dev.ckeditor.com/ticket/10975): [IE] Fixed: Error thrown while opening the color palette.
-* [#9929](http://dev.ckeditor.com/ticket/9929): [Blink/WebKit] Fixed: A non-breaking space is created once a character is deleted and a regular space is typed.
-* [#10963](http://dev.ckeditor.com/ticket/10963): Fixed: JAWS issue with the keyboard shortcut for [Magic Line](http://ckeditor.com/addon/magicline).
-* [#11096](http://dev.ckeditor.com/ticket/11096): Fixed: TypeError: Object has no method 'is'.
-
-## CKEditor 4.2.2
-
-Fixed Issues:
-
-* [#9314](http://dev.ckeditor.com/ticket/9314): Fixed: Incorrect error message on closing a dialog window without saving changs.
-* [#10308](http://dev.ckeditor.com/ticket/10308): [IE10] Fixed: Unspecified error when deleting a row.
-* [#10945](http://dev.ckeditor.com/ticket/10945): [Chrome] Fixed: Clicking with a mouse inside the editor does not show the caret.
-* [#10912](http://dev.ckeditor.com/ticket/10912): Prevent default action when content of a non-editable link is clicked.
-* [#10913](http://dev.ckeditor.com/ticket/10913): Fixed [`CKEDITOR.plugins.addExternal()`](http://docs.ckeditor.com/#!/api/CKEDITOR.resourceManager-method-addExternal) not handling paths including file name specified.
-* [#10666](http://dev.ckeditor.com/ticket/10666): Fixed [`CKEDITOR.tools.isArray()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-isArray) not working cross frame.
-* [#10910](http://dev.ckeditor.com/ticket/10910): [IE9] Fixed JavaScript error thrown in Compatibility Mode when clicking and/or typing in the editing area.
-* [#10868](http://dev.ckeditor.com/ticket/10868): [IE8] Prevent the browser from crashing when applying the Inline Quotation style.
-* [#10915](http://dev.ckeditor.com/ticket/10915): Fixed: Invalid CSS filter in the Kama skin.
-* [#10914](http://dev.ckeditor.com/ticket/10914): Plugins [Indent List](http://ckeditor.com/addon/indentlist) and [Indent Block](http://ckeditor.com/addon/indentblock) are now included in the build configuration.
-* [#10812](http://dev.ckeditor.com/ticket/10812): Fixed [`range.createBookmark2()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-createBookmark2) incorrectly normalizing offsets. This bug was causing many issues: [#10850](http://dev.ckeditor.com/ticket/10850), [#10842](http://dev.ckeditor.com/ticket/10842).
-* [#10951](http://dev.ckeditor.com/ticket/10951): Reviewed and optimized focus handling on panels (combo, menu buttons, color buttons, and context menu) to enhance accessibility. Fixed [#10705](http://dev.ckeditor.com/ticket/10705), [#10706](http://dev.ckeditor.com/ticket/10706) and [#10707](http://dev.ckeditor.com/ticket/10707).
-* [#10704](http://dev.ckeditor.com/ticket/10704): Fixed a JAWS issue with the Select Color dialog window title not being announced.
-* [#10753](http://dev.ckeditor.com/ticket/10753): The floating toolbar in inline instances now has a dedicated accessibility label.
-
-## CKEditor 4.2.1
-
-Fixed Issues:
-
-* [#10301](http://dev.ckeditor.com/ticket/10301): [IE9-10] Undo fails after 3+ consecutive paste actions with a JavaScript error.
-* [#10689](http://dev.ckeditor.com/ticket/10689): Save toolbar button saves only the first editor instance.
-* [#10368](http://dev.ckeditor.com/ticket/10368): Move language reading direction definition (`dir`) from main language file to core.
-* [#9330](http://dev.ckeditor.com/ticket/9330): Fixed pasting anchors from MS Word.
-* [#8103](http://dev.ckeditor.com/ticket/8103): Fixed pasting nested lists from MS Word.
-* [#9958](http://dev.ckeditor.com/ticket/9958): [IE9] Pressing the "OK" button will trigger the `onbeforeunload` event in the popup dialog.
-* [#10662](http://dev.ckeditor.com/ticket/10662): Fixed styles from the Styles drop-down list not registering to the ACF in case when the [Shared Spaces plugin](http://ckeditor.com/addon/sharedspace) is used.
-* [#9654](http://dev.ckeditor.com/ticket/9654): Problems with Internet Explorer 10 Quirks Mode.
-* [#9816](http://dev.ckeditor.com/ticket/9816): Floating toolbar does not reposition vertically in several cases.
-* [#10646](http://dev.ckeditor.com/ticket/10646): Removing a selected sublist or nested table with *Backspace/Delete* removes the parent element.
-* [#10623](http://dev.ckeditor.com/ticket/10623): [WebKit] Page is scrolled when opening a drop-down list.
-* [#10004](http://dev.ckeditor.com/ticket/10004): [ChromeVox] Button names are not announced.
-* [#10731](http://dev.ckeditor.com/ticket/10731): [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin breaks cloning of editor configuration.
-* It is now possible to set per instance [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin configuration instead of setting the configuration globally.
-
-## CKEditor 4.2
-
-**Important Notes:**
-
-* Dropped compatibility support for Internet Explorer 7 and Firefox 3.6.
-
-* Both the Basic and the Standard distribution packages will not contain the new [Indent Block](http://ckeditor.com/addon/indentblock) plugin. Because of this the [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) might remove block indentations from existing contents. If you want to prevent this, either [add an appropriate ACF rule to your filter](http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules) or create a custom build based on the Basic/Standard package and add the Indent Block plugin in [CKBuilder](http://ckeditor.com/builder).
-
-New Features:
-
-* [#10027](http://dev.ckeditor.com/ticket/10027): Separated list and block indentation into two plugins: [Indent List](http://ckeditor.com/addon/indentlist) and [Indent Block](http://ckeditor.com/addon/indentblock).
-* [#8244](http://dev.ckeditor.com/ticket/8244): Use *(Shift+)Tab* to indent and outdent lists.
-* [#10281](http://dev.ckeditor.com/ticket/10281): The [jQuery Adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) is now available. Several jQuery-related issues fixed: [#8261](http://dev.ckeditor.com/ticket/8261), [#9077](http://dev.ckeditor.com/ticket/9077), [#8710](http://dev.ckeditor.com/ticket/8710), [#8530](http://dev.ckeditor.com/ticket/8530), [#9019](http://dev.ckeditor.com/ticket/9019), [#6181](http://dev.ckeditor.com/ticket/6181), [#7876](http://dev.ckeditor.com/ticket/7876), [#6906](http://dev.ckeditor.com/ticket/6906).
-* [#10042](http://dev.ckeditor.com/ticket/10042): Introduced [`config.title`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-title) setting to change the human-readable title of the editor.
-* [#9794](http://dev.ckeditor.com/ticket/9794): Added [`editor.onChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event.
-* [#9923](http://dev.ckeditor.com/ticket/9923): HiDPI support in the editor UI. HiDPI icons for [Moono skin](http://ckeditor.com/addon/moono) added.
-* [#8031](http://dev.ckeditor.com/ticket/8031): Handle `required` attributes on `<textarea>` elements &mdash; introduced [`editor.required`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-required) event.
-* [#10280](http://dev.ckeditor.com/ticket/10280): Ability to replace `<textarea>` elements with the inline editor.
-
-Fixed Issues:
-
-* [#10599](http://dev.ckeditor.com/ticket/10599): [Indent](http://ckeditor.com/addon/indent) plugin is no longer required by the [List](http://ckeditor.com/addon/list) plugin.
-* [#10370](http://dev.ckeditor.com/ticket/10370): Inconsistency in data events between framed and inline editors.
-* [#10438](http://dev.ckeditor.com/ticket/10438): [FF, IE] No selection is done on an editable element on executing [`editor.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData).
-
-## CKEditor 4.1.3
-
-New Features:
-
-* Added new translation: Indonesian.
-
-Fixed Issues:
-
-* [#10644](http://dev.ckeditor.com/ticket/10644): Fixed a critical bug when pasting plain text in Blink-based browsers.
-* [#5189](http://dev.ckeditor.com/ticket/5189): [Find/Replace](http://ckeditor.com/addon/find) dialog window: rename "Cancel" button to "Close".
-* [#10562](http://dev.ckeditor.com/ticket/10562): [Housekeeping] Unified CSS gradient filter formats in the [Moono](http://ckeditor.com/addon/moono) skin.
-* [#10537](http://dev.ckeditor.com/ticket/10537): Advanced Content Filter should register a default rule for [`config.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode).
-* [#10610](http://dev.ckeditor.com/ticket/10610): [`CKEDITOR.dialog.addIframe()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dialog-static-method-addIframe) incorrectly sets the iframe size in dialog windows.
-
-## CKEditor 4.1.2
-
-New Features:
-
-* Added new translation: Sinhala.
-
-Fixed Issues:
-
-* [#10339](http://dev.ckeditor.com/ticket/10339): Fixed: Error thrown when inserted data was totally stripped out after filtering and processing.
-* [#10298](http://dev.ckeditor.com/ticket/10298): Fixed: Data processor breaks attributes containing protected parts.
-* [#10367](http://dev.ckeditor.com/ticket/10367): Fixed: [`editable.insertText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertText) loses characters when `RegExp` replace controls are being inserted.
-* [#10165](http://dev.ckeditor.com/ticket/10165): [IE] Access denied error when `document.domain` has been altered.
-* [#9761](http://dev.ckeditor.com/ticket/9761): Update the *Backspace* key state in [`keystrokeHandler.blockedKeystrokes`](http://docs.ckeditor.com/#!/api/CKEDITOR.keystrokeHandler-property-blockedKeystrokes) when calling [`editor.setReadOnly()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setReadOnly).
-* [#6504](http://dev.ckeditor.com/ticket/6504): Fixed: Race condition while loading several [`config.customConfig`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-customConfig) files.
-* [#10146](http://dev.ckeditor.com/ticket/10146): [Firefox] Empty lines are being removed while [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) is [`CKEDITOR.ENTER_BR`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-ENTER_BR).
-* [#10360](http://dev.ckeditor.com/ticket/10360): Fixed: ARIA `role="application"` should not be used for dialog windows.
-* [#10361](http://dev.ckeditor.com/ticket/10361): Fixed: ARIA `role="application"` should not be used for floating panels.
-* [#10510](http://dev.ckeditor.com/ticket/10510): Introduced unique voice labels to differentiate between different editor instances.
-* [#9945](http://dev.ckeditor.com/ticket/9945): [iOS] Scrolling not possible on iPad.
-* [#10389](http://dev.ckeditor.com/ticket/10389): Fixed: Invalid HTML in the "Text and Table" template.
-* [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin user interface was changed to match CKEditor 4 style.
-
-## CKEditor 4.1.1
-
-New Features:
-
-* Added new translation: Albanian.
-
-Fixed Issues:
-
-* [#10172](http://dev.ckeditor.com/ticket/10172): Pressing *Delete* or *Backspace* in an empty table cell moves the cursor to the next/previous cell.
-* [#10219](http://dev.ckeditor.com/ticket/10219): Error thrown when destroying an editor instance in parallel with a `mouseup` event.
-* [#10265](http://dev.ckeditor.com/ticket/10265): Wrong loop type in the [File Browser](http://ckeditor.com/addon/filebrowser) plugin.
-* [#10249](http://dev.ckeditor.com/ticket/10249): Wrong undo/redo states at start.
-* [#10268](http://dev.ckeditor.com/ticket/10268): [Show Blocks](http://ckeditor.com/addon/showblocks) does not recover after switching to Source view.
-* [#9995](http://dev.ckeditor.com/ticket/9995): HTML code in the `<textarea>` should not be modified by the [`htmlDataProcessor`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor).
-* [#10320](http://dev.ckeditor.com/ticket/10320): [Justify](http://ckeditor.com/addon/justify) plugin should add elements to Advanced Content Filter based on current [Enter mode](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode).
-* [#10260](http://dev.ckeditor.com/ticket/10260): Fixed: Advanced Content Filter blocks [`tabSpaces`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-tabSpaces). Unified `data-cke-*` attributes filtering.
-* [#10315](http://dev.ckeditor.com/ticket/10315): [WebKit] [Undo manager](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager) should not record snapshots after a filling character was added/removed.
-* [#10291](http://dev.ckeditor.com/ticket/10291): [WebKit] Space after a filling character should be secured.
-* [#10330](http://dev.ckeditor.com/ticket/10330): [WebKit] The filling character is not removed on `keydown` in specific cases.
-* [#10285](http://dev.ckeditor.com/ticket/10285): Fixed: Styled text pasted from MS Word causes an infinite loop.
-* [#10131](http://dev.ckeditor.com/ticket/10131): Fixed: [`undoManager.update()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager-method-update) does not refresh the command state.
-* [#10337](http://dev.ckeditor.com/ticket/10337): Fixed: Unable to remove `<s>` using [Remove Format](http://ckeditor.com/addon/removeformat).
-
-## CKEditor 4.1
-
-Fixed Issues:
-
-* [#10192](http://dev.ckeditor.com/ticket/10192): Closing lists with the *Enter* key does not work with [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) in several cases.
-* [#10191](http://dev.ckeditor.com/ticket/10191): Fixed allowed content rules unification, so the [`filter.allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter-property-allowedContent) property always contains rules in the same format.
-* [#10224](http://dev.ckeditor.com/ticket/10224): Advanced Content Filter does not remove non-empty `<a>` elements anymore.
-* Minor issues in plugin integration with Advanced Content Filter:
-  * [#10166](http://dev.ckeditor.com/ticket/10166): Added transformation from the `align` attribute to `float` style to preserve backward compatibility after the introduction of Advanced Content Filter.
-  * [#10195](http://dev.ckeditor.com/ticket/10195): [Image](http://ckeditor.com/addon/image) plugin no longer registers rules for links to Advanced Content Filter.
-  * [#10213](http://dev.ckeditor.com/ticket/10213): [Justify](http://ckeditor.com/addon/justify) plugin is now correctly registering rules to Advanced Content Filter when [`config.justifyClasses`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-justifyClasses) is defined.
-
-## CKEditor 4.1 RC
-
-New Features:
-
-* [#9829](http://dev.ckeditor.com/ticket/9829): Advanced Content Filter - data and features activation based on editor configuration.
-
-  Brand new data filtering system that works in 2 modes:
-
-  * Based on loaded features (toolbar items, plugins) - the data will be filtered according to what the editor in its
-  current configuration can handle.
-  * Based on [`config.allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent) rules - the data
-  will be filtered and the editor features (toolbar items, commands, keystrokes) will be enabled if they are allowed.
-
-  See the `datafiltering.html` sample, [guides](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) and [`CKEDITOR.filter` API documentation](http://docs.ckeditor.com/#!/api/CKEDITOR.filter).
-* [#9387](http://dev.ckeditor.com/ticket/9387): Reintroduced [Shared Spaces](http://ckeditor.com/addon/sharedspace) - the ability to display toolbar and bottom editor space in selected locations and to share them by different editor instances.
-* [#9907](http://dev.ckeditor.com/ticket/9907): Added the [`contentPreview`](http://docs.ckeditor.com/#!/api/CKEDITOR-event-contentPreview) event for preview data manipulation.
-* [#9713](http://dev.ckeditor.com/ticket/9713): Introduced the [Source Dialog](http://ckeditor.com/addon/sourcedialog) plugin that brings raw HTML editing for inline editor instances.
-* Included in [#9829](http://dev.ckeditor.com/ticket/9829): Introduced new events, [`toHtml`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-toHtml) and [`toDataFormat`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-toDataFormat), allowing for better integration with data processing.
-* [#9981](http://dev.ckeditor.com/ticket/9981): Added ability to filter [`htmlParser.fragment`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.fragment), [`htmlParser.element`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.element) etc. by many [`htmlParser.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter)s before writing structure to an HTML string.
-* Included in [#10103](http://dev.ckeditor.com/ticket/10103):
-  * Introduced the [`editor.status`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-status) property to make it easier to check the current status of the editor.
-  * Default [`command`](http://docs.ckeditor.com/#!/api/CKEDITOR.command) state is now [`CKEDITOR.TRISTATE_DISABLE`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-TRISTATE_DISABLED). It will be activated on [`editor.instanceReady`](http://docs.ckeditor.com/#!/api/CKEDITOR-event-instanceReady) or immediately after being added if the editor is already initialized.
-* [#9796](http://dev.ckeditor.com/ticket/9796): Introduced `<s>` as a default tag for strikethrough, which replaces obsolete `<strike>` in HTML5.
-
-## CKEditor 4.0.3
-
-Fixed Issues:
-
-* [#10196](http://dev.ckeditor.com/ticket/10196): Fixed context menus not opening with keyboard shortcuts when [Autogrow](http://ckeditor.com/addon/autogrow) is enabled.
-* [#10212](http://dev.ckeditor.com/ticket/10212): [IE7-10] Undo command throws errors after multiple switches between Source and WYSIWYG view.
-* [#10219](http://dev.ckeditor.com/ticket/10219): [Inline editor] Error thrown after calling [`editor.destroy()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-destroy).
-
-## CKEditor 4.0.2
-
-Fixed Issues:
-
-* [#9779](http://dev.ckeditor.com/ticket/9779): Fixed overriding [`CKEDITOR.getUrl()`](http://docs.ckeditor.com/#!/api/CKEDITOR-method-getUrl) with `CKEDITOR_GETURL`.
-* [#9772](http://dev.ckeditor.com/ticket/9772): Custom buttons in the dialog window footer have different look and size ([Moono](http://ckeditor.com/addon/moono), [Kama](http://ckeditor.com/addon/kama) skins).
-* [#9029](http://dev.ckeditor.com/ticket/9029): Custom styles added with the [`stylesSet.add()`](http://docs.ckeditor.com/#!/api/CKEDITOR.stylesSet-method-add) are displayed in the wrong order.
-* [#9887](http://dev.ckeditor.com/ticket/9887): Disable [Magic Line](http://ckeditor.com/addon/magicline) when [`editor.readOnly`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) is set.
-* [#9882](http://dev.ckeditor.com/ticket/9882): Fixed empty document title on [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) if set via the Document Properties dialog window.
-* [#9773](http://dev.ckeditor.com/ticket/9773): Fixed rendering problems with selection fields in the Kama skin.
-* [#9851](http://dev.ckeditor.com/ticket/9851): The [`selectionChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-selectionChange) event is not fired when mouse selection ended outside editable.
-* [#9903](http://dev.ckeditor.com/ticket/9903): [Inline editor] Bad positioning of floating space with page horizontal scroll.
-* [#9872](http://dev.ckeditor.com/ticket/9872): [`editor.checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) returns `true` when called onload. Removed the obsolete `editor.mayBeDirty` flag.
-* [#9893](http://dev.ckeditor.com/ticket/9893): [IE] Fixed broken toolbar when editing mixed direction content in Quirks mode.
-* [#9845](http://dev.ckeditor.com/ticket/9845): Fixed TAB navigation in the [Link](http://ckeditor.com/addon/link) dialog window when the Anchor option is used and no anchors are available.
-* [#9883](http://dev.ckeditor.com/ticket/9883): Maximizing was making the entire page editable with [divarea](http://ckeditor.com/addon/divarea)-based editors.
-* [#9940](http://dev.ckeditor.com/ticket/9940): [Firefox] Navigating back to a page with the editor was making the entire page editable.
-* [#9966](http://dev.ckeditor.com/ticket/9966): Fixed: Unable to type square brackets with French keyboard layout. Changed [Magic Line](http://ckeditor.com/addon/magicline) keystrokes.
-* [#9507](http://dev.ckeditor.com/ticket/9507): [Firefox] Selection is moved before editable position when the editor is focused for the first time.
-* [#9947](http://dev.ckeditor.com/ticket/9947): [WebKit] Editor overflows parent container in some edge cases.
-* [#10105](http://dev.ckeditor.com/ticket/10105): Fixed: Broken [sourcearea](http://ckeditor.com/addon/sourcearea) view when an RTL language is set.
-* [#10123](http://dev.ckeditor.com/ticket/10123): [WebKit] Fixed: Several dialog windows have broken layout since the latest WebKit release.
-* [#10152](http://dev.ckeditor.com/ticket/10152): Fixed: Invalid ARIA property used on menu items.
-
-## CKEditor 4.0.1.1
-
-Fixed Issues:
-
-* Security update: Added protection against XSS attack and possible path disclosure in the PHP sample.
-
-## CKEditor 4.0.1
-
-Fixed Issues:
-
-* [#9655](http://dev.ckeditor.com/ticket/9655): Support for IE Quirks Mode in the new [Moono skin](http://ckeditor.com/addon/moono).
-* Accessibility issues (mainly in inline editor): [#9364](http://dev.ckeditor.com/ticket/9364), [#9368](http://dev.ckeditor.com/ticket/9368), [#9369](http://dev.ckeditor.com/ticket/9369), [#9370](http://dev.ckeditor.com/ticket/9370), [#9541](http://dev.ckeditor.com/ticket/9541), [#9543](http://dev.ckeditor.com/ticket/9543), [#9841](http://dev.ckeditor.com/ticket/9841), [#9844](http://dev.ckeditor.com/ticket/9844).
-* [Magic Line](http://ckeditor.com/addon/magicline) plugin:
-    * [#9481](http://dev.ckeditor.com/ticket/9481): Added accessibility support for Magic Line.
-    * [#9509](http://dev.ckeditor.com/ticket/9509): Added Magic Line support for forms.
-    * [#9573](http://dev.ckeditor.com/ticket/9573): Magic Line does not disappear on `mouseout` in a specific case.
-* [#9754](http://dev.ckeditor.com/ticket/9754): [WebKit] Cutting & pasting simple unformatted text generates an inline wrapper in WebKit browsers.
-* [#9456](http://dev.ckeditor.com/ticket/9456): [Chrome] Properly paste bullet list style from MS Word.
-* [#9699](http://dev.ckeditor.com/ticket/9699), [#9758](http://dev.ckeditor.com/ticket/9758): Improved selection locking when selecting by dragging.
-* Context menu:
-    * [#9712](http://dev.ckeditor.com/ticket/9712): Opening the context menu destroys editor focus.
-    * [#9366](http://dev.ckeditor.com/ticket/9366): Context menu should be displayed over the floating toolbar.
-    * [#9706](http://dev.ckeditor.com/ticket/9706): Context menu generates a JavaScript error in inline mode when the editor is attached to a header element.
-* [#9800](http://dev.ckeditor.com/ticket/9800): Hide float panel when resizing the window.
-* [#9721](http://dev.ckeditor.com/ticket/9721): Padding in content of div-based editor puts the editing area under the bottom UI space.
-* [#9528](http://dev.ckeditor.com/ticket/9528): Host page `box-sizing` style should not influence the editor UI elements.
-* [#9503](http://dev.ckeditor.com/ticket/9503): [Form Elements](http://ckeditor.com/addon/forms) plugin adds context menu listeners only on supported input types. Added support for `tel`, `email`, `search` and `url` input types.
-* [#9769](http://dev.ckeditor.com/ticket/9769): Improved floating toolbar positioning in a narrow window.
-* [#9875](http://dev.ckeditor.com/ticket/9875): Table dialog window does not populate width correctly.
-* [#8675](http://dev.ckeditor.com/ticket/8675): Deleting cells in a nested table removes the outer table cell.
-* [#9815](http://dev.ckeditor.com/ticket/9815): Cannot edit dialog window fields in an editor initialized in the jQuery UI modal dialog.
-* [#8888](http://dev.ckeditor.com/ticket/8888): CKEditor dialog windows do not show completely in a small window.
-* [#9360](http://dev.ckeditor.com/ticket/9360): [Inline editor] Blocks shown for a `<div>` element stay permanently even after the user exits editing the `<div>`.
-* [#9531](http://dev.ckeditor.com/ticket/9531): [Firefox & Inline editor] Toolbar is lost when closing the Format drop-down list by clicking its button.
-* [#9553](http://dev.ckeditor.com/ticket/9553): Table width incorrectly set when the `border-width` style is specified.
-* [#9594](http://dev.ckeditor.com/ticket/9594): Cannot tab past CKEditor when it is in read-only mode.
-* [#9658](http://dev.ckeditor.com/ticket/9658): [IE9] Justify not working on selected images.
-* [#9686](http://dev.ckeditor.com/ticket/9686): Added missing contents styles for `<pre>` elements.
-* [#9709](http://dev.ckeditor.com/ticket/9709): [Paste from Word](http://ckeditor.com/addon/pastefromword) should not depend on configuration from other styles.
-* [#9726](http://dev.ckeditor.com/ticket/9726): Removed [Color Dialog](http://ckeditor.com/addon/colordialog) plugin dependency from [Table Tools](http://ckeditor.com/addon/tabletools).
-* [#9765](http://dev.ckeditor.com/ticket/9765): Toolbar Collapse command documented incorrectly in the [Accessibility Instructions](http://ckeditor.com/addon/a11yhelp) dialog window.
-* [#9771](http://dev.ckeditor.com/ticket/9771): [WebKit & Opera] Fixed scrolling issues when pasting.
-* [#9787](http://dev.ckeditor.com/ticket/9787): [IE9] `onChange` is not fired for checkboxes in dialogs.
-* [#9842](http://dev.ckeditor.com/ticket/9842): [Firefox 17] When opening a toolbar menu for the first time and pressing the *Down Arrow* key, focus goes to the next toolbar button instead of the menu options.
-* [#9847](http://dev.ckeditor.com/ticket/9847): [Elements Path](http://ckeditor.com/addon/elementspath) should not be initialized in the inline editor.
-* [#9853](http://dev.ckeditor.com/ticket/9853): [`editor.addRemoveFormatFilter()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-addRemoveFormatFilter) is exposed before it really works.
-* [#8893](http://dev.ckeditor.com/ticket/8893): Value of the [`pasteFromWordCleanupFile`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordCleanupFile) configuration option is now taken from the instance configuration.
-* [#9693](http://dev.ckeditor.com/ticket/9693): Removed "Live Preview" checkbox from UI color picker.
-
-
-## CKEditor 4.0
-
-The first stable release of the new CKEditor 4 code line.
-
-The CKEditor JavaScript API has been kept compatible with CKEditor 4, whenever
-possible. The list of relevant changes can be found in the [API Changes page of
-the CKEditor 4 documentation][1].
-
-[1]: http://docs.ckeditor.com/#!/guide/dev_api_changes "API Changes"

+ 0 - 1274
htdocs/includes/ckeditor/ckeditor/_source/LICENSE.md

@@ -1,1274 +0,0 @@
-Software License Agreement
-==========================
-
-CKEditor - The text editor for Internet - http://ckeditor.com
-Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
-
-Licensed under the terms of any of the following licenses at your
-choice:
-
- - GNU General Public License Version 2 or later (the "GPL")
-   http://www.gnu.org/licenses/gpl.html
-   (See Appendix A)
-
- - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
-   http://www.gnu.org/licenses/lgpl.html
-   (See Appendix B)
-
- - Mozilla Public License Version 1.1 or later (the "MPL")
-   http://www.mozilla.org/MPL/MPL-1.1.html
-   (See Appendix C)
-
-You are not required to, but if you want to explicitly declare the
-license you have chosen to be bound to when using, reproducing,
-modifying and distributing this software, just include a text file
-titled "legal.txt" in your version of this software, indicating your
-license choice. In any case, your choice will not restrict any
-recipient of your version of this software to use, reproduce, modify
-and distribute this software under any of the above licenses.
-
-Sources of Intellectual Property Included in CKEditor
------------------------------------------------------
-
-Where not otherwise indicated, all CKEditor content is authored by
-CKSource engineers and consists of CKSource-owned intellectual
-property. In some specific instances, CKEditor will incorporate work
-done by developers outside of CKSource with their express permission.
-
-(Ignore this line: %REMOVE_START%)
-
-Software available at our repository and developer version only:
-
-JavaScript Lint: At _dev/_thirdparty/jsl can be found the executable
-files of JavaScript Lint, which are licensed under the terms of the
-Mozilla Public License Version 1.1 (http://www.mozilla.org/MPL/).
-JavaScript Lint is Copyright (c) 2006 Matthias Miller.
-
-(Ignore this line: %REMOVE_END%)
-Trademarks
-----------
-
-CKEditor is a trademark of CKSource - Frederico Knabben. All other brand
-and product names are trademarks, registered trademarks or service
-marks of their respective holders.
-
----
-
-Appendix A: The GPL License
----------------------------
-
-GNU GENERAL PUBLIC LICENSE
-Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software-to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-GNU GENERAL PUBLIC LICENSE
-TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-END OF TERMS AND CONDITIONS
-
-
-Appendix B: The LGPL License
-----------------------------
-
-GNU LESSER GENERAL PUBLIC LICENSE
-Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software-to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages-typically libraries-of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
-GNU LESSER GENERAL PUBLIC LICENSE
-TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-END OF TERMS AND CONDITIONS
-
-
-Appendix C: The MPL License
----------------------------
-
-MOZILLA PUBLIC LICENSE
-Version 1.1
-
-1. Definitions.
-
-     1.0.1. "Commercial Use" means distribution or otherwise making the
-     Covered Code available to a third party.
-
-     1.1. "Contributor" means each entity that creates or contributes to
-     the creation of Modifications.
-
-     1.2. "Contributor Version" means the combination of the Original
-     Code, prior Modifications used by a Contributor, and the Modifications
-     made by that particular Contributor.
-
-     1.3. "Covered Code" means the Original Code or Modifications or the
-     combination of the Original Code and Modifications, in each case
-     including portions thereof.
-
-     1.4. "Electronic Distribution Mechanism" means a mechanism generally
-     accepted in the software development community for the electronic
-     transfer of data.
-
-     1.5. "Executable" means Covered Code in any form other than Source
-     Code.
-
-     1.6. "Initial Developer" means the individual or entity identified
-     as the Initial Developer in the Source Code notice required by Exhibit
-     A.
-
-     1.7. "Larger Work" means a work which combines Covered Code or
-     portions thereof with code not governed by the terms of this License.
-
-     1.8. "License" means this document.
-
-     1.8.1. "Licensable" means having the right to grant, to the maximum
-     extent possible, whether at the time of the initial grant or
-     subsequently acquired, any and all of the rights conveyed herein.
-
-     1.9. "Modifications" means any addition to or deletion from the
-     substance or structure of either the Original Code or any previous
-     Modifications. When Covered Code is released as a series of files, a
-     Modification is:
-          A. Any addition to or deletion from the contents of a file
-          containing Original Code or previous Modifications.
-
-          B. Any new file that contains any part of the Original Code or
-          previous Modifications.
-
-     1.10. "Original Code" means Source Code of computer software code
-     which is described in the Source Code notice required by Exhibit A as
-     Original Code, and which, at the time of its release under this
-     License is not already Covered Code governed by this License.
-
-     1.10.1. "Patent Claims" means any patent claim(s), now owned or
-     hereafter acquired, including without limitation,  method, process,
-     and apparatus claims, in any patent Licensable by grantor.
-
-     1.11. "Source Code" means the preferred form of the Covered Code for
-     making modifications to it, including all modules it contains, plus
-     any associated interface definition files, scripts used to control
-     compilation and installation of an Executable, or source code
-     differential comparisons against either the Original Code or another
-     well known, available Covered Code of the Contributor's choice. The
-     Source Code can be in a compressed or archival form, provided the
-     appropriate decompression or de-archiving software is widely available
-     for no charge.
-
-     1.12. "You" (or "Your")  means an individual or a legal entity
-     exercising rights under, and complying with all of the terms of, this
-     License or a future version of this License issued under Section 6.1.
-     For legal entities, "You" includes any entity which controls, is
-     controlled by, or is under common control with You. For purposes of
-     this definition, "control" means (a) the power, direct or indirect,
-     to cause the direction or management of such entity, whether by
-     contract or otherwise, or (b) ownership of more than fifty percent
-     (50%) of the outstanding shares or beneficial ownership of such
-     entity.
-
-2. Source Code License.
-
-     2.1. The Initial Developer Grant.
-     The Initial Developer hereby grants You a world-wide, royalty-free,
-     non-exclusive license, subject to third party intellectual property
-     claims:
-          (a)  under intellectual property rights (other than patent or
-          trademark) Licensable by Initial Developer to use, reproduce,
-          modify, display, perform, sublicense and distribute the Original
-          Code (or portions thereof) with or without Modifications, and/or
-          as part of a Larger Work; and
-
-          (b) under Patents Claims infringed by the making, using or
-          selling of Original Code, to make, have made, use, practice,
-          sell, and offer for sale, and/or otherwise dispose of the
-          Original Code (or portions thereof).
-
-          (c) the licenses granted in this Section 2.1(a) and (b) are
-          effective on the date Initial Developer first distributes
-          Original Code under the terms of this License.
-
-          (d) Notwithstanding Section 2.1(b) above, no patent license is
-          granted: 1) for code that You delete from the Original Code; 2)
-          separate from the Original Code;  or 3) for infringements caused
-          by: i) the modification of the Original Code or ii) the
-          combination of the Original Code with other software or devices.
-
-     2.2. Contributor Grant.
-     Subject to third party intellectual property claims, each Contributor
-     hereby grants You a world-wide, royalty-free, non-exclusive license
-
-          (a)  under intellectual property rights (other than patent or
-          trademark) Licensable by Contributor, to use, reproduce, modify,
-          display, perform, sublicense and distribute the Modifications
-          created by such Contributor (or portions thereof) either on an
-          unmodified basis, with other Modifications, as Covered Code
-          and/or as part of a Larger Work; and
-
-          (b) under Patent Claims infringed by the making, using, or
-          selling of  Modifications made by that Contributor either alone
-          and/or in combination with its Contributor Version (or portions
-          of such combination), to make, use, sell, offer for sale, have
-          made, and/or otherwise dispose of: 1) Modifications made by that
-          Contributor (or portions thereof); and 2) the combination of
-          Modifications made by that Contributor with its Contributor
-          Version (or portions of such combination).
-
-          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
-          effective on the date Contributor first makes Commercial Use of
-          the Covered Code.
-
-          (d)    Notwithstanding Section 2.2(b) above, no patent license is
-          granted: 1) for any code that Contributor has deleted from the
-          Contributor Version; 2)  separate from the Contributor Version;
-          3)  for infringements caused by: i) third party modifications of
-          Contributor Version or ii)  the combination of Modifications made
-          by that Contributor with other software  (except as part of the
-          Contributor Version) or other devices; or 4) under Patent Claims
-          infringed by Covered Code in the absence of Modifications made by
-          that Contributor.
-
-3. Distribution Obligations.
-
-     3.1. Application of License.
-     The Modifications which You create or to which You contribute are
-     governed by the terms of this License, including without limitation
-     Section 2.2. The Source Code version of Covered Code may be
-     distributed only under the terms of this License or a future version
-     of this License released under Section 6.1, and You must include a
-     copy of this License with every copy of the Source Code You
-     distribute. You may not offer or impose any terms on any Source Code
-     version that alters or restricts the applicable version of this
-     License or the recipients' rights hereunder. However, You may include
-     an additional document offering the additional rights described in
-     Section 3.5.
-
-     3.2. Availability of Source Code.
-     Any Modification which You create or to which You contribute must be
-     made available in Source Code form under the terms of this License
-     either on the same media as an Executable version or via an accepted
-     Electronic Distribution Mechanism to anyone to whom you made an
-     Executable version available; and if made available via Electronic
-     Distribution Mechanism, must remain available for at least twelve (12)
-     months after the date it initially became available, or at least six
-     (6) months after a subsequent version of that particular Modification
-     has been made available to such recipients. You are responsible for
-     ensuring that the Source Code version remains available even if the
-     Electronic Distribution Mechanism is maintained by a third party.
-
-     3.3. Description of Modifications.
-     You must cause all Covered Code to which You contribute to contain a
-     file documenting the changes You made to create that Covered Code and
-     the date of any change. You must include a prominent statement that
-     the Modification is derived, directly or indirectly, from Original
-     Code provided by the Initial Developer and including the name of the
-     Initial Developer in (a) the Source Code, and (b) in any notice in an
-     Executable version or related documentation in which You describe the
-     origin or ownership of the Covered Code.
-
-     3.4. Intellectual Property Matters
-          (a) Third Party Claims.
-          If Contributor has knowledge that a license under a third party's
-          intellectual property rights is required to exercise the rights
-          granted by such Contributor under Sections 2.1 or 2.2,
-          Contributor must include a text file with the Source Code
-          distribution titled "LEGAL" which describes the claim and the
-          party making the claim in sufficient detail that a recipient will
-          know whom to contact. If Contributor obtains such knowledge after
-          the Modification is made available as described in Section 3.2,
-          Contributor shall promptly modify the LEGAL file in all copies
-          Contributor makes available thereafter and shall take other steps
-          (such as notifying appropriate mailing lists or newsgroups)
-          reasonably calculated to inform those who received the Covered
-          Code that new knowledge has been obtained.
-
-          (b) Contributor APIs.
-          If Contributor's Modifications include an application programming
-          interface and Contributor has knowledge of patent licenses which
-          are reasonably necessary to implement that API, Contributor must
-          also include this information in the LEGAL file.
-
-               (c)    Representations.
-          Contributor represents that, except as disclosed pursuant to
-          Section 3.4(a) above, Contributor believes that Contributor's
-          Modifications are Contributor's original creation(s) and/or
-          Contributor has sufficient rights to grant the rights conveyed by
-          this License.
-
-     3.5. Required Notices.
-     You must duplicate the notice in Exhibit A in each file of the Source
-     Code.  If it is not possible to put such notice in a particular Source
-     Code file due to its structure, then You must include such notice in a
-     location (such as a relevant directory) where a user would be likely
-     to look for such a notice.  If You created one or more Modification(s)
-     You may add your name as a Contributor to the notice described in
-     Exhibit A.  You must also duplicate this License in any documentation
-     for the Source Code where You describe recipients' rights or ownership
-     rights relating to Covered Code.  You may choose to offer, and to
-     charge a fee for, warranty, support, indemnity or liability
-     obligations to one or more recipients of Covered Code. However, You
-     may do so only on Your own behalf, and not on behalf of the Initial
-     Developer or any Contributor. You must make it absolutely clear than
-     any such warranty, support, indemnity or liability obligation is
-     offered by You alone, and You hereby agree to indemnify the Initial
-     Developer and every Contributor for any liability incurred by the
-     Initial Developer or such Contributor as a result of warranty,
-     support, indemnity or liability terms You offer.
-
-     3.6. Distribution of Executable Versions.
-     You may distribute Covered Code in Executable form only if the
-     requirements of Section 3.1-3.5 have been met for that Covered Code,
-     and if You include a notice stating that the Source Code version of
-     the Covered Code is available under the terms of this License,
-     including a description of how and where You have fulfilled the
-     obligations of Section 3.2. The notice must be conspicuously included
-     in any notice in an Executable version, related documentation or
-     collateral in which You describe recipients' rights relating to the
-     Covered Code. You may distribute the Executable version of Covered
-     Code or ownership rights under a license of Your choice, which may
-     contain terms different from this License, provided that You are in
-     compliance with the terms of this License and that the license for the
-     Executable version does not attempt to limit or alter the recipient's
-     rights in the Source Code version from the rights set forth in this
-     License. If You distribute the Executable version under a different
-     license You must make it absolutely clear that any terms which differ
-     from this License are offered by You alone, not by the Initial
-     Developer or any Contributor. You hereby agree to indemnify the
-     Initial Developer and every Contributor for any liability incurred by
-     the Initial Developer or such Contributor as a result of any such
-     terms You offer.
-
-     3.7. Larger Works.
-     You may create a Larger Work by combining Covered Code with other code
-     not governed by the terms of this License and distribute the Larger
-     Work as a single product. In such a case, You must make sure the
-     requirements of this License are fulfilled for the Covered Code.
-
-4. Inability to Comply Due to Statute or Regulation.
-
-     If it is impossible for You to comply with any of the terms of this
-     License with respect to some or all of the Covered Code due to
-     statute, judicial order, or regulation then You must: (a) comply with
-     the terms of this License to the maximum extent possible; and (b)
-     describe the limitations and the code they affect. Such description
-     must be included in the LEGAL file described in Section 3.4 and must
-     be included with all distributions of the Source Code. Except to the
-     extent prohibited by statute or regulation, such description must be
-     sufficiently detailed for a recipient of ordinary skill to be able to
-     understand it.
-
-5. Application of this License.
-
-     This License applies to code to which the Initial Developer has
-     attached the notice in Exhibit A and to related Covered Code.
-
-6. Versions of the License.
-
-     6.1. New Versions.
-     Netscape Communications Corporation ("Netscape") may publish revised
-     and/or new versions of the License from time to time. Each version
-     will be given a distinguishing version number.
-
-     6.2. Effect of New Versions.
-     Once Covered Code has been published under a particular version of the
-     License, You may always continue to use it under the terms of that
-     version. You may also choose to use such Covered Code under the terms
-     of any subsequent version of the License published by Netscape. No one
-     other than Netscape has the right to modify the terms applicable to
-     Covered Code created under this License.
-
-     6.3. Derivative Works.
-     If You create or use a modified version of this License (which you may
-     only do in order to apply it to code which is not already Covered Code
-     governed by this License), You must (a) rename Your license so that
-     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
-     "MPL", "NPL" or any confusingly similar phrase do not appear in your
-     license (except to note that your license differs from this License)
-     and (b) otherwise make it clear that Your version of the license
-     contains terms which differ from the Mozilla Public License and
-     Netscape Public License. (Filling in the name of the Initial
-     Developer, Original Code or Contributor in the notice described in
-     Exhibit A shall not of themselves be deemed to be modifications of
-     this License.)
-
-7. DISCLAIMER OF WARRANTY.
-
-     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
-     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
-     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
-     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
-     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
-     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
-     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
-     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
-     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
-     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
-
-8. TERMINATION.
-
-     8.1.  This License and the rights granted hereunder will terminate
-     automatically if You fail to comply with terms herein and fail to cure
-     such breach within 30 days of becoming aware of the breach. All
-     sublicenses to the Covered Code which are properly granted shall
-     survive any termination of this License. Provisions which, by their
-     nature, must remain in effect beyond the termination of this License
-     shall survive.
-
-     8.2.  If You initiate litigation by asserting a patent infringement
-     claim (excluding declatory judgment actions) against Initial Developer
-     or a Contributor (the Initial Developer or Contributor against whom
-     You file such action is referred to as "Participant")  alleging that:
-
-     (a)  such Participant's Contributor Version directly or indirectly
-     infringes any patent, then any and all rights granted by such
-     Participant to You under Sections 2.1 and/or 2.2 of this License
-     shall, upon 60 days notice from Participant terminate prospectively,
-     unless if within 60 days after receipt of notice You either: (i)
-     agree in writing to pay Participant a mutually agreeable reasonable
-     royalty for Your past and future use of Modifications made by such
-     Participant, or (ii) withdraw Your litigation claim with respect to
-     the Contributor Version against such Participant.  If within 60 days
-     of notice, a reasonable royalty and payment arrangement are not
-     mutually agreed upon in writing by the parties or the litigation claim
-     is not withdrawn, the rights granted by Participant to You under
-     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
-     the 60 day notice period specified above.
-
-     (b)  any software, hardware, or device, other than such Participant's
-     Contributor Version, directly or indirectly infringes any patent, then
-     any rights granted to You by such Participant under Sections 2.1(b)
-     and 2.2(b) are revoked effective as of the date You first made, used,
-     sold, distributed, or had made, Modifications made by that
-     Participant.
-
-     8.3.  If You assert a patent infringement claim against Participant
-     alleging that such Participant's Contributor Version directly or
-     indirectly infringes any patent where such claim is resolved (such as
-     by license or settlement) prior to the initiation of patent
-     infringement litigation, then the reasonable value of the licenses
-     granted by such Participant under Sections 2.1 or 2.2 shall be taken
-     into account in determining the amount or value of any payment or
-     license.
-
-     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
-     all end user license agreements (excluding distributors and resellers)
-     which have been validly granted by You or any distributor hereunder
-     prior to termination shall survive termination.
-
-9. LIMITATION OF LIABILITY.
-
-     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
-     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
-     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
-     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
-     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
-     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
-     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
-     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
-     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
-     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
-     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
-     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
-     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
-     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
-
-10. U.S. GOVERNMENT END USERS.
-
-     The Covered Code is a "commercial item," as that term is defined in
-     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
-     software" and "commercial computer software documentation," as such
-     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
-     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
-     all U.S. Government End Users acquire Covered Code with only those
-     rights set forth herein.
-
-11. MISCELLANEOUS.
-
-     This License represents the complete agreement concerning subject
-     matter hereof. If any provision of this License is held to be
-     unenforceable, such provision shall be reformed only to the extent
-     necessary to make it enforceable. This License shall be governed by
-     California law provisions (except to the extent applicable law, if
-     any, provides otherwise), excluding its conflict-of-law provisions.
-     With respect to disputes in which at least one party is a citizen of,
-     or an entity chartered or registered to do business in the United
-     States of America, any litigation relating to this License shall be
-     subject to the jurisdiction of the Federal Courts of the Northern
-     District of California, with venue lying in Santa Clara County,
-     California, with the losing party responsible for costs, including
-     without limitation, court costs and reasonable attorneys' fees and
-     expenses. The application of the United Nations Convention on
-     Contracts for the International Sale of Goods is expressly excluded.
-     Any law or regulation which provides that the language of a contract
-     shall be construed against the drafter shall not apply to this
-     License.
-
-12. RESPONSIBILITY FOR CLAIMS.
-
-     As between Initial Developer and the Contributors, each party is
-     responsible for claims and damages arising, directly or indirectly,
-     out of its utilization of rights under this License and You agree to
-     work with Initial Developer and Contributors to distribute such
-     responsibility on an equitable basis. Nothing herein is intended or
-     shall be deemed to constitute any admission of liability.
-
-13. MULTIPLE-LICENSED CODE.
-
-     Initial Developer may designate portions of the Covered Code as
-     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
-     Developer permits you to utilize portions of the Covered Code under
-     Your choice of the NPL or the alternative licenses, if any, specified
-     by the Initial Developer in the file described in Exhibit A.
-
-EXHIBIT A -Mozilla Public License.
-
-     ``The contents of this file are subject to the Mozilla Public License
-     Version 1.1 (the "License"); you may not use this file except in
-     compliance with the License. You may obtain a copy of the License at
-     http://www.mozilla.org/MPL/
-
-     Software distributed under the License is distributed on an "AS IS"
-     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-     License for the specific language governing rights and limitations
-     under the License.
-
-     The Original Code is ______________________________________.
-
-     The Initial Developer of the Original Code is ________________________.
-     Portions created by ______________________ are Copyright (C) ______
-     _______________________. All Rights Reserved.
-
-     Contributor(s): ______________________________________.
-
-     Alternatively, the contents of this file may be used under the terms
-     of the _____ license (the  "[___] License"), in which case the
-     provisions of [______] License are applicable instead of those
-     above.  If you wish to allow use of your version of this file only
-     under the terms of the [____] License and not to allow others to use
-     your version of this file under the MPL, indicate your decision by
-     deleting  the provisions above and replace  them with the notice and
-     other provisions required by the [___] License.  If you do not delete
-     the provisions above, a recipient may use your version of this file
-     under either the MPL or the [___] License."
-
-     [NOTE: The text of this Exhibit A may differ slightly from the text of
-     the notices in the Source Code files of the Original Code. You should
-     use the text of this Exhibit A rather than the text found in the
-     Original Code Source Code for Your Modifications.]

+ 0 - 39
htdocs/includes/ckeditor/ckeditor/_source/README.md

@@ -1,39 +0,0 @@
-CKEditor 4
-==========
-
-Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.  
-http://ckeditor.com - See LICENSE.md for license information.
-
-CKEditor is a text editor to be used inside web pages. It's not a replacement
-for desktop text editors like Word or OpenOffice, but a component to be used as
-part of web applications and websites.
-
-## Documentation
-
-The full editor documentation is available online at the following address:
-http://docs.ckeditor.com
-
-## Installation
-
-Installing CKEditor is an easy task. Just follow these simple steps:
-
- 1. **Download** the latest version from the CKEditor website:
-    http://ckeditor.com. You should have already completed this step, but be
-    sure you have the very latest version.
- 2. **Extract** (decompress) the downloaded file into the root of your website.
-
-**Note:** CKEditor is by default installed in the `ckeditor` folder. You can
-place the files in whichever you want though.
-
-## Checking Your Installation
-
-The editor comes with a few sample pages that can be used to verify that
-installation proceeded properly. Take a look at the `samples` directory.
-
-To test your installation, just call the following page at your website:
-
-	http://<your site>/<CKEditor installation path>/samples/index.html
-
-For example:
-
-	http://www.example.com/ckeditor/samples/index.html

+ 0 - 165
htdocs/includes/ckeditor/ckeditor/_source/build-config.js

@@ -1,165 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * This file was added automatically by CKEditor builder.
- * You may re-use it at any time to build CKEditor again.
- *
- * If you would like to build CKEditor online again
- * (for example to upgrade), visit one the following links:
- *
- * (1) http://ckeditor.com/builder
- *     Visit online builder to build CKEditor from scratch.
- *
- * (2) http://ckeditor.com/builder/6df6f619a26d5e0aab9c5392e3ab2c31
- *     Visit online builder to build CKEditor, starting with the same setup as before.
- *
- * (3) http://ckeditor.com/builder/download/6df6f619a26d5e0aab9c5392e3ab2c31
- *     Straight download link to the latest version of CKEditor (Optimized) with the same setup as before.
- *
- * NOTE:
- *    This file is not used by CKEditor, you may remove it.
- *    Changing this file will not change your CKEditor configuration.
- */
-
-var CKBUILDER_CONFIG = {
-	skin: 'moonocolor',
-	preset: 'full',
-	ignore: [
-		'dev',
-		'.gitignore',
-		'.gitattributes',
-		'README.md',
-		'.mailmap'
-	],
-	plugins : {
-		'a11yhelp' : 1,
-		'about' : 1,
-		'basicstyles' : 1,
-		'bidi' : 1,
-		'blockquote' : 1,
-		'clipboard' : 1,
-		'colorbutton' : 1,
-		'colordialog' : 1,
-		'contextmenu' : 1,
-		'dialogadvtab' : 1,
-		'div' : 1,
-		'elementspath' : 1,
-		'enterkey' : 1,
-		'entities' : 1,
-		'filebrowser' : 1,
-		'find' : 1,
-		'flash' : 1,
-		'floatingspace' : 1,
-		'font' : 1,
-		'format' : 1,
-		'forms' : 1,
-		'horizontalrule' : 1,
-		'htmlwriter' : 1,
-		'iframe' : 1,
-		'image' : 1,
-		'indentblock' : 1,
-		'indentlist' : 1,
-		'justify' : 1,
-		'language' : 1,
-		'link' : 1,
-		'list' : 1,
-		'liststyle' : 1,
-		'magicline' : 1,
-		'maximize' : 1,
-		'newpage' : 1,
-		'pagebreak' : 1,
-		'pastefromword' : 1,
-		'pastetext' : 1,
-		'preview' : 1,
-		'print' : 1,
-		'removeformat' : 1,
-		'resize' : 1,
-		'save' : 1,
-		'scayt' : 1,
-		'selectall' : 1,
-		'showblocks' : 1,
-		'showborders' : 1,
-		'smiley' : 1,
-		'sourcearea' : 1,
-		'specialchar' : 1,
-		'stylescombo' : 1,
-		'tab' : 1,
-		'table' : 1,
-		'tabletools' : 1,
-		'templates' : 1,
-		'toolbar' : 1,
-		'undo' : 1,
-		'wsc' : 1,
-		'wysiwygarea' : 1
-	},
-	languages : {
-		'af' : 1,
-		'ar' : 1,
-		'bg' : 1,
-		'bn' : 1,
-		'bs' : 1,
-		'ca' : 1,
-		'cs' : 1,
-		'cy' : 1,
-		'da' : 1,
-		'de' : 1,
-		'el' : 1,
-		'en' : 1,
-		'en-au' : 1,
-		'en-ca' : 1,
-		'en-gb' : 1,
-		'eo' : 1,
-		'es' : 1,
-		'et' : 1,
-		'eu' : 1,
-		'fa' : 1,
-		'fi' : 1,
-		'fo' : 1,
-		'fr' : 1,
-		'fr-ca' : 1,
-		'gl' : 1,
-		'gu' : 1,
-		'he' : 1,
-		'hi' : 1,
-		'hr' : 1,
-		'hu' : 1,
-		'id' : 1,
-		'is' : 1,
-		'it' : 1,
-		'ja' : 1,
-		'ka' : 1,
-		'km' : 1,
-		'ko' : 1,
-		'ku' : 1,
-		'lt' : 1,
-		'lv' : 1,
-		'mk' : 1,
-		'mn' : 1,
-		'ms' : 1,
-		'nb' : 1,
-		'nl' : 1,
-		'no' : 1,
-		'pl' : 1,
-		'pt' : 1,
-		'pt-br' : 1,
-		'ro' : 1,
-		'ru' : 1,
-		'si' : 1,
-		'sk' : 1,
-		'sl' : 1,
-		'sq' : 1,
-		'sr' : 1,
-		'sr-latn' : 1,
-		'sv' : 1,
-		'th' : 1,
-		'tr' : 1,
-		'ug' : 1,
-		'uk' : 1,
-		'vi' : 1,
-		'zh' : 1,
-		'zh-cn' : 1
-	}
-};

+ 0 - 42
htdocs/includes/ckeditor/ckeditor/_source/ckeditor.js

@@ -1,42 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-// Compressed version of core/ckeditor_base.js. See original for instructions.
-/*jsl:ignore*/
-window.CKEDITOR||(window.CKEDITOR=function(){var b={timestamp:"",version:"%VERSION%",revision:"%REV%",rnd:Math.floor(900*Math.random())+100,_:{pending:[]},status:"unloaded",basePath:function(){var a=window.CKEDITOR_BASEPATH||"";if(!a)for(var b=document.getElementsByTagName("script"),c=0;c<b.length;c++){var d=b[c].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(d){a=d[1];break}}-1==a.indexOf(":/")&&"//"!=a.slice(0,2)&&(a=0===a.indexOf("/")?location.href.match(/^.*?:\/\/[^\/]*/)[0]+a:location.href.match(/^[^\?]*\/(?:)/)[0]+a);if(!a)throw'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';return a}(),getUrl:function(a){-1==a.indexOf(":/")&&0!==a.indexOf("/")&&(a=this.basePath+a);this.timestamp&&"/"!=a.charAt(a.length-1)&&!/[&?]t=/.test(a)&&(a+=(0<=a.indexOf("?")?"&":"?")+"t="+this.timestamp);return a},domReady:function(){function a(){try{document.addEventListener?(document.removeEventListener("DOMContentLoaded",a,!1),b()):document.attachEvent&&"complete"===document.readyState&&(document.detachEvent("onreadystatechange",a),b())}catch(d){}}function b(){for(var a;a=c.shift();)a()}var c=[];return function(b){c.push(b);"complete"===document.readyState&&setTimeout(a,1);if(1==c.length)if(document.addEventListener)document.addEventListener("DOMContentLoaded",a,!1),window.addEventListener("load",a,!1);else if(document.attachEvent){document.attachEvent("onreadystatechange",a);window.attachEvent("onload",a);b=!1;try{b=!window.frameElement}catch(e){}if(document.documentElement.doScroll&&b){var f=function(){try{document.documentElement.doScroll("left")}catch(b){setTimeout(f,1);return}a()};f()}}}}()},e=window.CKEDITOR_GETURL;if(e){var g=b.getUrl;b.getUrl=function(a){return e.call(b,a)||g.call(b,a)}}return b}());
-/*jsl:end*/
-
-if ( CKEDITOR.loader )
-	CKEDITOR.loader.load( 'ckeditor' );
-else {
-	// Set the script name to be loaded by the loader.
-	CKEDITOR._autoLoad = 'ckeditor';
-
-	// Include the loader script.
-	if ( document.body && ( !document.readyState || document.readyState == 'complete' ) ) {
-		var script = document.createElement( 'script' );
-		script.type = 'text/javascript';
-		script.src = CKEDITOR.getUrl( 'core/loader.js' );
-		document.body.appendChild( script );
-	} else
-		document.write( '<script type="text/javascript" src="' + CKEDITOR.getUrl( 'core/loader.js' ) + '"></script>' );
-
-}
-
-/**
- * The skin to load for all created instances, it may be the name of the skin
- * folder inside the editor installation path, or the name and the path separated
- * by a comma.
- *
- * **Note:** This is a global configuration that applies to all instances.
- *
- *		CKEDITOR.skinName = 'moono';
- *
- *		CKEDITOR.skinName = 'myskin,/customstuff/myskin/';
- *
- * @cfg {String} [skinName='moono']
- * @member CKEDITOR
- */
-CKEDITOR.skinName = 'moono';

+ 0 - 17
htdocs/includes/ckeditor/ckeditor/_source/config.js

@@ -1,17 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.html or http://ckeditor.com/license
- */
-
-CKEDITOR.editorConfig = function( config ) {
-	
-	// %REMOVE_START%
-	// The configuration options below are needed when running CKEditor from source files.
-	config.plugins = 'dialogui,dialog,about,a11yhelp,dialogadvtab,basicstyles,bidi,blockquote,clipboard,button,panelbutton,panel,floatpanel,colorbutton,colordialog,templates,menu,contextmenu,div,resize,toolbar,elementspath,enterkey,entities,popup,filebrowser,find,fakeobjects,flash,floatingspace,listblock,richcombo,font,forms,format,horizontalrule,htmlwriter,iframe,wysiwygarea,image,indent,indentblock,indentlist,smiley,justify,menubutton,language,link,list,liststyle,magicline,maximize,newpage,pagebreak,pastetext,pastefromword,preview,print,removeformat,save,selectall,showblocks,showborders,sourcearea,specialchar,scayt,stylescombo,tab,table,tabletools,undo,wsc';
-	config.skin = 'moonocolor';
-	// %REMOVE_END%
-
-	// Define changes to default configuration here. For example:
-	// config.language = 'fr';
-	// config.uiColor = '#AADC6E';
-};

+ 0 - 123
htdocs/includes/ckeditor/ckeditor/_source/contents.css

@@ -1,123 +0,0 @@
-/*
-Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
-For licensing, see LICENSE.md or http://ckeditor.com/license
-*/
-
-body
-{
-	/* Font */
-	font-family: sans-serif, Arial, Verdana, "Trebuchet MS";
-	font-size: 12px;
-
-	/* Text color */
-	color: #333;
-
-	/* Remove the background color to make it transparent */
-	background-color: #fff;
-
-	margin: 20px;
-}
-
-.cke_editable
-{
-	font-size: 13px;
-	line-height: 1.6;
-}
-
-blockquote
-{
-	font-style: italic;
-	font-family: Georgia, Times, "Times New Roman", serif;
-	padding: 2px 0;
-	border-style: solid;
-	border-color: #ccc;
-	border-width: 0;
-}
-
-.cke_contents_ltr blockquote
-{
-	padding-left: 20px;
-	padding-right: 8px;
-	border-left-width: 5px;
-}
-
-.cke_contents_rtl blockquote
-{
-	padding-left: 8px;
-	padding-right: 20px;
-	border-right-width: 5px;
-}
-
-a
-{
-	color: #0782C1;
-}
-
-ol,ul,dl
-{
-	/* IE7: reset rtl list margin. (#7334) */
-	*margin-right: 0px;
-	/* preserved spaces for list items with text direction other than the list. (#6249,#8049)*/
-	padding: 0 40px;
-}
-
-h1,h2,h3,h4,h5,h6
-{
-	font-weight: normal;
-	line-height: 1.2;
-}
-
-hr
-{
-	border: 0px;
-	border-top: 1px solid #ccc;
-}
-
-img.right
-{
-	border: 1px solid #ccc;
-	float: right;
-	margin-left: 15px;
-	padding: 5px;
-}
-
-img.left
-{
-	border: 1px solid #ccc;
-	float: left;
-	margin-right: 15px;
-	padding: 5px;
-}
-
-pre
-{
-	white-space: pre-wrap; /* CSS 2.1 */
-	word-wrap: break-word; /* IE7 */
-}
-
-.marker
-{
-	background-color: Yellow;
-}
-
-span[lang]
-{
-   font-style: italic;
-}
-
-figure
-{
-	text-align: center;
-	border: solid 1px #ccc;
-	border-radius: 2px;
-	background: rgba(0,0,0,0.05);
-	padding: 10px;
-	margin: 10px 20px;
-	display: block; /* For IE8 */
-}
-
-figure figcaption
-{
-	text-align: center;
-	display: block; /* For IE8 */
-}

+ 0 - 74
htdocs/includes/ckeditor/ckeditor/_source/core/_bootstrap.js

@@ -1,74 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview API initialization code.
- */
-
-( function() {
-	// Disable HC detection in WebKit. (#5429)
-	if ( CKEDITOR.env.webkit )
-		CKEDITOR.env.hc = false;
-	else {
-		// Check whether high contrast is active by creating a colored border.
-		var hcDetect = CKEDITOR.dom.element.createFromHtml( '<div style="width:0;height:0;position:absolute;left:-10000px;' +
-			'border:1px solid;border-color:red blue"></div>', CKEDITOR.document );
-
-		hcDetect.appendTo( CKEDITOR.document.getHead() );
-
-		// Update CKEDITOR.env.
-		// Catch exception needed sometimes for FF. (#4230)
-		try {
-			var top = hcDetect.getComputedStyle( 'border-top-color' ),
-				right = hcDetect.getComputedStyle( 'border-right-color' );
-
-			// We need to check if getComputedStyle returned any value, because on FF
-			// it returnes empty string if CKEditor is loaded in hidden iframe. (#11121)
-			CKEDITOR.env.hc = !!( top && top == right );
-		} catch ( e ) {
-			CKEDITOR.env.hc = false;
-		}
-
-		hcDetect.remove();
-	}
-
-	if ( CKEDITOR.env.hc )
-		CKEDITOR.env.cssClass += ' cke_hc';
-
-	// Initially hide UI spaces when relevant skins are loading, later restored by skin css.
-	CKEDITOR.document.appendStyleText( '.cke{visibility:hidden;}' );
-
-	// Mark the editor as fully loaded.
-	CKEDITOR.status = 'loaded';
-	CKEDITOR.fireOnce( 'loaded' );
-
-	// Process all instances created by the "basic" implementation.
-	var pending = CKEDITOR._.pending;
-	if ( pending ) {
-		delete CKEDITOR._.pending;
-
-		for ( var i = 0; i < pending.length; i++ ) {
-			CKEDITOR.editor.prototype.constructor.apply( pending[ i ][ 0 ], pending[ i ][ 1 ] );
-			CKEDITOR.add( pending[ i ][ 0 ] );
-		}
-	}
-} )();
-
-/**
- * Indicates that CKEditor is running on a High Contrast environment.
- *
- *		if ( CKEDITOR.env.hc )
- *			alert( 'You\'re running on High Contrast mode. The editor interface will get adapted to provide you a better experience.' );
- *
- * @property {Boolean} hc
- * @member CKEDITOR.env
- */
-
-/**
- * Fired when a CKEDITOR core object is fully loaded and ready for interaction.
- *
- * @event loaded
- * @member CKEDITOR
- */

+ 0 - 204
htdocs/includes/ckeditor/ckeditor/_source/core/ckeditor.js

@@ -1,204 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Contains the third and last part of the {@link CKEDITOR} object
- *		definition.
- */
-
-/** @class CKEDITOR */
-
-// Remove the CKEDITOR.loadFullCore reference defined on ckeditor_basic.
-delete CKEDITOR.loadFullCore;
-
-/**
- * Stores references to all editor instances created. The name of the properties
- * in this object correspond to instance names, and their values contain the
- * {@link CKEDITOR.editor} object representing them.
- *
- *		alert( CKEDITOR.instances.editor1.name ); // 'editor1'
- *
- * @property {Object}
- */
-CKEDITOR.instances = {};
-
-/**
- * The document of the window storing the CKEDITOR object.
- *
- *		alert( CKEDITOR.document.getBody().getName() ); // 'body'
- *
- * @property {CKEDITOR.dom.document}
- */
-CKEDITOR.document = new CKEDITOR.dom.document( document );
-
-/**
- * Adds an editor instance to the global {@link CKEDITOR} object. This function
- * is available for internal use mainly.
- *
- * @param {CKEDITOR.editor} editor The editor instance to be added.
- */
-CKEDITOR.add = function( editor ) {
-	CKEDITOR.instances[ editor.name ] = editor;
-
-	editor.on( 'focus', function() {
-		if ( CKEDITOR.currentInstance != editor ) {
-			CKEDITOR.currentInstance = editor;
-			CKEDITOR.fire( 'currentInstance' );
-		}
-	} );
-
-	editor.on( 'blur', function() {
-		if ( CKEDITOR.currentInstance == editor ) {
-			CKEDITOR.currentInstance = null;
-			CKEDITOR.fire( 'currentInstance' );
-		}
-	} );
-
-	CKEDITOR.fire( 'instance', null, editor );
-};
-
-/**
- * Removes an editor instance from the global {@link CKEDITOR} object. This function
- * is available for internal use only. External code must use {@link CKEDITOR.editor#method-destroy}.
- *
- * @private
- * @param {CKEDITOR.editor} editor The editor instance to be removed.
- */
-CKEDITOR.remove = function( editor ) {
-	delete CKEDITOR.instances[ editor.name ];
-};
-
-( function() {
-	var tpls = {};
-
-	/**
-	 * Adds a named {@link CKEDITOR.template} instance to be reused among all editors.
-	 * This will return the existing one if a template with same name is already
-	 * defined. Additionally, it fires the "template" event to allow template source customization.
-	 *
-	 * @param {String} name The name which identifies a UI template.
-	 * @param {String} source The source string for constructing this template.
-	 * @returns {CKEDITOR.template} The created template instance.
-	 */
-	CKEDITOR.addTemplate = function( name, source ) {
-		var tpl = tpls[ name ];
-		if ( tpl )
-			return tpl;
-
-		// Make it possible to customize the template through event.
-		var params = { name: name, source: source };
-		CKEDITOR.fire( 'template', params );
-
-		return ( tpls[ name ] = new CKEDITOR.template( params.source ) );
-	};
-
-	/**
-	 * Retrieves a defined template created with {@link CKEDITOR#addTemplate}.
-	 *
-	 * @param {String} name The template name.
-	 */
-	CKEDITOR.getTemplate = function( name ) {
-		return tpls[ name ];
-	};
-} )();
-
-( function() {
-	var styles = [];
-
-	/**
-	 * Adds CSS rules to be appended to the editor document.
-	 * This method is mostly used by plugins to add custom styles to the editor
-	 * document. For basic content styling the `contents.css` file should be
-	 * used instead.
-	 *
-	 * **Note:** This function should be called before the creation of editor instances.
-	 *
-	 *		// Add styles for all headings inside editable contents.
-	 *		CKEDITOR.addCss( '.cke_editable h1,.cke_editable h2,.cke_editable h3 { border-bottom: 1px dotted red }' );
-	 *
-	 * @param {String} css The style rules to be appended.
-	 * @see CKEDITOR.config#contentsCss
-	 */
-	CKEDITOR.addCss = function( css ) {
-		styles.push( css );
-	};
-
-	/**
-	 * Returns a string will all CSS rules passed to the {@link CKEDITOR#addCss} method.
-	 *
-	 * @returns {String} A string containing CSS rules.
-	 */
-	CKEDITOR.getCss = function() {
-		return styles.join( '\n' );
-	};
-} )();
-
-// Perform global clean up to free as much memory as possible
-// when there are no instances left
-CKEDITOR.on( 'instanceDestroyed', function() {
-	if ( CKEDITOR.tools.isEmpty( this.instances ) )
-		CKEDITOR.fire( 'reset' );
-} );
-
-// Load the bootstrap script.
-CKEDITOR.loader.load( '_bootstrap' ); // %REMOVE_LINE%
-
-// Tri-state constants.
-/**
- * Used to indicate the ON or ACTIVE state.
- *
- * @readonly
- * @property {Number} [=1]
- */
-CKEDITOR.TRISTATE_ON = 1;
-
-/**
- * Used to indicate the OFF or INACTIVE state.
- *
- * @readonly
- * @property {Number} [=2]
- */
-CKEDITOR.TRISTATE_OFF = 2;
-
-/**
- * Used to indicate the DISABLED state.
- *
- * @readonly
- * @property {Number} [=0]
- */
-CKEDITOR.TRISTATE_DISABLED = 0;
-
-/**
- * The editor which is currently active (has user focus).
- *
- *		function showCurrentEditorName() {
- *			if ( CKEDITOR.currentInstance )
- *				alert( CKEDITOR.currentInstance.name );
- *			else
- *				alert( 'Please focus an editor first.' );
- *		}
- *
- * @property {CKEDITOR.editor} currentInstance
- * @see CKEDITOR#event-currentInstance
- */
-
-/**
- * Fired when the CKEDITOR.currentInstance object reference changes. This may
- * happen when setting the focus on different editor instances in the page.
- *
- *		var editor; // A variable to store a reference to the current editor.
- *		CKEDITOR.on( 'currentInstance', function() {
- *			editor = CKEDITOR.currentInstance;
- *		} );
- *
- * @event currentInstance
- */
-
-/**
- * Fired when the last instance has been destroyed. This event is used to perform
- * global memory cleanup.
- *
- * @event reset
- */

+ 0 - 315
htdocs/includes/ckeditor/ckeditor/_source/core/ckeditor_base.js

@@ -1,315 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Contains the first and essential part of the {@link CKEDITOR}
- *		object definition.
- */
-
-// #### Compressed Code
-// Must be updated on changes in the script as well as updated in the ckeditor.js file.
-
-// window.CKEDITOR||(window.CKEDITOR=function(){var b={timestamp:"",version:"%VERSION%",revision:"%REV%",rnd:Math.floor(900*Math.random())+100,_:{pending:[]},status:"unloaded",basePath:function(){var a=window.CKEDITOR_BASEPATH||"";if(!a)for(var b=document.getElementsByTagName("script"),c=0;c<b.length;c++){var d=b[c].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(d){a=d[1];break}}-1==a.indexOf(":/")&&"//"!=a.slice(0,2)&&(a=0===a.indexOf("/")?location.href.match(/^.*?:\/\/[^\/]*/)[0]+a:location.href.match(/^[^\?]*\/(?:)/)[0]+a);if(!a)throw'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';return a}(),getUrl:function(a){-1==a.indexOf(":/")&&0!==a.indexOf("/")&&(a=this.basePath+a);this.timestamp&&"/"!=a.charAt(a.length-1)&&!/[&?]t=/.test(a)&&(a+=(0<=a.indexOf("?")?"&":"?")+"t="+this.timestamp);return a},domReady:function(){function a(){try{document.addEventListener?(document.removeEventListener("DOMContentLoaded",a,!1),b()):document.attachEvent&&"complete"===document.readyState&&(document.detachEvent("onreadystatechange",a),b())}catch(d){}}function b(){for(var a;a=c.shift();)a()}var c=[];return function(b){c.push(b);"complete"===document.readyState&&setTimeout(a,1);if(1==c.length)if(document.addEventListener)document.addEventListener("DOMContentLoaded",a,!1),window.addEventListener("load",a,!1);else if(document.attachEvent){document.attachEvent("onreadystatechange",a);window.attachEvent("onload",a);b=!1;try{b=!window.frameElement}catch(e){}if(document.documentElement.doScroll&&b){var f=function(){try{document.documentElement.doScroll("left")}catch(b){setTimeout(f,1);return}a()};f()}}}}()},e=window.CKEDITOR_GETURL;if(e){var g=b.getUrl;b.getUrl=function(a){return e.call(b,a)||g.call(b,a)}}return b}());
-// The Closure Compiler online service should be used when updating this manually:
-// http://closure-compiler.appspot.com/
-
-// #### Raw code
-// ATTENTION: read the above "Compressed Code" notes when changing this code.
-
-if ( !window.CKEDITOR ) {
-	/**
-	 * This is the API entry point. The entire CKEditor code runs under this object.
-	 * @class CKEDITOR
-	 * @singleton
-	 */
-	window.CKEDITOR = ( function() {
-		var CKEDITOR = {
-
-			/**
-			 * A constant string unique for each release of CKEditor. Its value
-			 * is used, by default, to build the URL for all resources loaded
-			 * by the editor code, guaranteeing clean cache results when
-			 * upgrading.
-			 *
-			 *		alert( CKEDITOR.timestamp ); // e.g. '87dm'
-			 */
-			timestamp: '',				// %REMOVE_LINE%
-			/*							// %REMOVE_LINE%
-			// The production implementation contains a fixed timestamp, unique
-			// for each release and generated by the releaser.
-			// (Base 36 value of each component of YYMMDDHH - 4 chars total - e.g. 87bm == 08071122)
-			timestamp: '%TIMESTAMP%',
-			*/							// %REMOVE_LINE%
-
-			/**
-			 * Contains the CKEditor version number.
-			 *
-			 *		alert( CKEDITOR.version ); // e.g. 'CKEditor 3.4.1'
-			 */
-			version: '%VERSION%',
-
-			/**
-			 * Contains the CKEditor revision number.
-			 * The revision number is incremented automatically, following each
-			 * modification to the CKEditor source code.
-			 *
-			 *		alert( CKEDITOR.revision ); // e.g. '3975'
-			 */
-			revision: '%REV%',
-
-			/**
-			 * A 3-digit random integer, valid for the entire life of the CKEDITOR object.
-			 *
-			 *		alert( CKEDITOR.rnd ); // e.g. 319
-			 *
-			 * @property {Number}
-			 */
-			rnd: Math.floor( Math.random() * ( 999 /*Max*/ - 100 /*Min*/ + 1 ) ) + 100 /*Min*/,
-
-			/**
-			 * Private object used to hold core stuff. It should not be used outside of
-			 * the API code as properties defined here may change at any time
-			 * without notice.
-			 *
-			 * @private
-			 */
-			_: {
-				pending: []
-			},
-
-			/**
-			 * Indicates the API loading status. The following statuses are available:
-			 *
-			 * * **unloaded**: the API is not yet loaded.
-			 * * **basic_loaded**: the basic API features are available.
-			 * * **basic_ready**: the basic API is ready to load the full core code.
-			 * * **loaded**: the API can be fully used.
-			 *
-			 * Example:
-			 *
-			 *		if ( CKEDITOR.status == 'loaded' ) {
-			 *			// The API can now be fully used.
-			 *			doSomething();
-			 *		} else {
-			 *			// Wait for the full core to be loaded and fire its loading.
-			 *			CKEDITOR.on( 'load', doSomething );
-			 *			CKEDITOR.loadFullCore && CKEDITOR.loadFullCore();
-			 *		}
-			 */
-			status: 'unloaded',
-
-			/**
-			 * The full URL for the CKEditor installation directory.
-			 * It is possible to manually provide the base path by setting a
-			 * global variable named `CKEDITOR_BASEPATH`. This global variable
-			 * must be set **before** the editor script loading.
-			 *
-			 *		alert( CKEDITOR.basePath ); // e.g. 'http://www.example.com/ckeditor/'
-			 *
-			 * @property {String}
-			 */
-			basePath: ( function() {
-				// ATTENTION: fixes to this code must be ported to
-				// var basePath in "core/loader.js".
-
-				// Find out the editor directory path, based on its <script> tag.
-				var path = window.CKEDITOR_BASEPATH || '';
-
-				if ( !path ) {
-					var scripts = document.getElementsByTagName( 'script' );
-
-					for ( var i = 0; i < scripts.length; i++ ) {
-						var match = scripts[ i ].src.match( /(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i );
-
-						if ( match ) {
-							path = match[ 1 ];
-							break;
-						}
-					}
-				}
-
-				// In IE (only) the script.src string is the raw value entered in the
-				// HTML source. Other browsers return the full resolved URL instead.
-				if ( path.indexOf( ':/' ) == -1 && path.slice( 0, 2 ) != '//' ) {
-					// Absolute path.
-					if ( path.indexOf( '/' ) === 0 )
-						path = location.href.match( /^.*?:\/\/[^\/]*/ )[ 0 ] + path;
-					// Relative path.
-					else
-						path = location.href.match( /^[^\?]*\/(?:)/ )[ 0 ] + path;
-				}
-
-				if ( !path )
-					throw 'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';
-
-				return path;
-			} )(),
-
-			/**
-			 * Gets the full URL for CKEditor resources. By default, URLs
-			 * returned by this function contain a querystring parameter ("t")
-			 * set to the {@link CKEDITOR#timestamp} value.
-			 *
-			 * It is possible to provide a custom implementation of this
-			 * function by setting a global variable named `CKEDITOR_GETURL`.
-			 * This global variable must be set **before** the editor script
-			 * loading. If the custom implementation returns nothing (`==null`), the
-			 * default implementation is used.
-			 *
-			 *		// e.g. 'http://www.example.com/ckeditor/skins/default/editor.css?t=87dm'
-			 *		alert( CKEDITOR.getUrl( 'skins/default/editor.css' ) );
-			 *
-			 *		// e.g. 'http://www.example.com/skins/default/editor.css?t=87dm'
-			 *		alert( CKEDITOR.getUrl( '/skins/default/editor.css' ) );
-			 *
-			 *		// e.g. 'http://www.somesite.com/skins/default/editor.css?t=87dm'
-			 *		alert( CKEDITOR.getUrl( 'http://www.somesite.com/skins/default/editor.css' ) );
-			 *
-			 * @param {String} resource The resource whose full URL we want to get.
-			 * It may be a full, absolute, or relative URL.
-			 * @returns {String} The full URL.
-			 */
-			getUrl: function( resource ) {
-				// If this is not a full or absolute path.
-				if ( resource.indexOf( ':/' ) == -1 && resource.indexOf( '/' ) !== 0 )
-					resource = this.basePath + resource;
-
-				// Add the timestamp, except for directories.
-				if ( this.timestamp && resource.charAt( resource.length - 1 ) != '/' && !( /[&?]t=/ ).test( resource ) )
-					resource += ( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) + 't=' + this.timestamp;
-
-				return resource;
-			},
-
-			/**
-			 * Specify a function to execute when the DOM is fully loaded.
-			 *
-			 * If called after the DOM has been initialized, the function passed in will
-			 * be executed immediately.
-			 *
-			 * @method
-			 * @todo
-			 */
-			domReady: ( function() {
-				// Based on the original jQuery code.
-
-				var callbacks = [];
-
-				function onReady() {
-					try {
-						// Cleanup functions for the document ready method
-						if ( document.addEventListener ) {
-							document.removeEventListener( 'DOMContentLoaded', onReady, false );
-							executeCallbacks();
-						}
-						// Make sure body exists, at least, in case IE gets a little overzealous.
-						else if ( document.attachEvent && document.readyState === 'complete' ) {
-							document.detachEvent( 'onreadystatechange', onReady );
-							executeCallbacks();
-						}
-					} catch ( er ) {}
-				}
-
-				function executeCallbacks() {
-					var i;
-					while ( ( i = callbacks.shift() ) )
-						i();
-				}
-
-				return function( fn ) {
-					callbacks.push( fn );
-
-					// Catch cases where this is called after the
-					// browser event has already occurred.
-					if ( document.readyState === 'complete' )
-						// Handle it asynchronously to allow scripts the opportunity to delay ready
-						setTimeout( onReady, 1 );
-
-					// Run below once on demand only.
-					if ( callbacks.length != 1 )
-						return;
-
-					// For IE>8, Firefox, Opera and Webkit.
-					if ( document.addEventListener ) {
-						// Use the handy event callback
-						document.addEventListener( 'DOMContentLoaded', onReady, false );
-
-						// A fallback to window.onload, that will always work
-						window.addEventListener( 'load', onReady, false );
-
-					}
-					// If old IE event model is used
-					else if ( document.attachEvent ) {
-						// ensure firing before onload,
-						// maybe late but safe also for iframes
-						document.attachEvent( 'onreadystatechange', onReady );
-
-						// A fallback to window.onload, that will always work
-						window.attachEvent( 'onload', onReady );
-
-						// If IE and not a frame
-						// continually check to see if the document is ready
-						// use the trick by Diego Perini
-						// http://javascript.nwbox.com/IEContentLoaded/
-						var toplevel = false;
-
-						try {
-							toplevel = !window.frameElement;
-						} catch ( e ) {}
-
-						if ( document.documentElement.doScroll && toplevel ) {
-							function scrollCheck() {
-								try {
-									document.documentElement.doScroll( 'left' );
-								} catch ( e ) {
-									setTimeout( scrollCheck, 1 );
-									return;
-								}
-								onReady();
-							}
-							scrollCheck();
-						}
-					}
-				};
-
-			} )()
-		};
-
-		// Make it possible to override the "url" function with a custom
-		// implementation pointing to a global named CKEDITOR_GETURL.
-		var newGetUrl = window.CKEDITOR_GETURL;
-		if ( newGetUrl ) {
-			var originalGetUrl = CKEDITOR.getUrl;
-			CKEDITOR.getUrl = function( resource ) {
-				return newGetUrl.call( CKEDITOR, resource ) || originalGetUrl.call( CKEDITOR, resource );
-			};
-		}
-
-		return CKEDITOR;
-	} )();
-}
-
-/**
- * Function called upon loading a custom configuration file that can
- * modify the editor instance configuration ({@link CKEDITOR.editor#config}).
- * It is usually defined inside the custom configuration files that can
- * include developer defined settings.
- *
- *		// This is supposed to be placed in the config.js file.
- *		CKEDITOR.editorConfig = function( config ) {
- *			// Define changes to default configuration here. For example:
- *			config.language = 'fr';
- *			config.uiColor = '#AADC6E';
- *		};
- *
- * @method editorConfig
- * @param {CKEDITOR.config} config A configuration object containing the
- * settings defined for a {@link CKEDITOR.editor} instance up to this
- * function call. Note that not all settings may still be available. See
- * [Configuration Loading Order](http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Setting_Configurations#Configuration_Loading_Order)
- * for details.
- */
-
-// PACKAGER_RENAME( CKEDITOR )

+ 0 - 94
htdocs/includes/ckeditor/ckeditor/_source/core/ckeditor_basic.js

@@ -1,94 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Contains the second part of the {@link CKEDITOR} object
- *		definition, which defines the basic editor features to be available in
- *		the root ckeditor_basic.js file.
- */
-
-if ( CKEDITOR.status == 'unloaded' ) {
-	( function() {
-		CKEDITOR.event.implementOn( CKEDITOR );
-
-		/**
-		 * Forces the full CKEditor core code, in the case only the basic code has been
-		 * loaded (`ckeditor_basic.js`). This method self-destroys (becomes undefined) in
-		 * the first call or as soon as the full code is available.
-		 *
-		 *		// Check if the full core code has been loaded and load it.
-		 *		if ( CKEDITOR.loadFullCore )
-		 *			CKEDITOR.loadFullCore();
-		 *
-		 * @member CKEDITOR
-		 */
-		CKEDITOR.loadFullCore = function() {
-			// If the basic code is not ready, just mark it to be loaded.
-			if ( CKEDITOR.status != 'basic_ready' ) {
-				CKEDITOR.loadFullCore._load = 1;
-				return;
-			}
-
-			// Destroy this function.
-			delete CKEDITOR.loadFullCore;
-
-			// Append the script to the head.
-			var script = document.createElement( 'script' );
-			script.type = 'text/javascript';
-			script.src = CKEDITOR.basePath + 'ckeditor.js';
-			script.src = CKEDITOR.basePath + 'ckeditor_source.js'; // %REMOVE_LINE%
-
-			document.getElementsByTagName( 'head' )[ 0 ].appendChild( script );
-		};
-
-		/**
-		 * The time to wait (in seconds) to load the full editor code after the
-		 * page load, if the "ckeditor_basic" file is used. If set to zero, the
-		 * editor is loaded on demand, as soon as an instance is created.
-		 *
-		 * This value must be set on the page before the page load completion.
-		 *
-		 *		// Loads the full source after five seconds.
-		 *		CKEDITOR.loadFullCoreTimeout = 5;
-		 *
-		 * @property
-		 * @member CKEDITOR
-		 */
-		CKEDITOR.loadFullCoreTimeout = 0;
-
-		// Documented at ckeditor.js.
-		CKEDITOR.add = function( editor ) {
-			// For now, just put the editor in the pending list. It will be
-			// processed as soon as the full code gets loaded.
-			var pending = this._.pending || ( this._.pending = [] );
-			pending.push( editor );
-		};
-
-		( function() {
-			var onload = function() {
-					var loadFullCore = CKEDITOR.loadFullCore,
-						loadFullCoreTimeout = CKEDITOR.loadFullCoreTimeout;
-
-					if ( !loadFullCore )
-						return;
-
-					CKEDITOR.status = 'basic_ready';
-
-					if ( loadFullCore && loadFullCore._load )
-						loadFullCore();
-					else if ( loadFullCoreTimeout ) {
-						setTimeout( function() {
-							if ( CKEDITOR.loadFullCore )
-								CKEDITOR.loadFullCore();
-						}, loadFullCoreTimeout * 1000 );
-					}
-				};
-
-			CKEDITOR.domReady( onload );
-		} )();
-
-		CKEDITOR.status = 'basic_loaded';
-	} )();
-}

+ 0 - 271
htdocs/includes/ckeditor/ckeditor/_source/core/command.js

@@ -1,271 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * Represents a command that can be executed on an editor instance.
- *
- *		var command = new CKEDITOR.command( editor, {
- *			exec: function( editor ) {
- *				alert( editor.document.getBody().getHtml() );
- *			}
- *		} );
- *
- * @class
- * @mixins CKEDITOR.event
- * @constructor Creates a command class instance.
- * @param {CKEDITOR.editor} editor The editor instance this command will be
- * related to.
- * @param {CKEDITOR.commandDefinition} commandDefinition The command
- * definition.
- */
-CKEDITOR.command = function( editor, commandDefinition ) {
-	/**
-	 * Lists UI items that are associated to this command. This list can be
-	 * used to interact with the UI on command execution (by the execution code
-	 * itself, for example).
-	 *
-	 *		alert( 'Number of UI items associated to this command: ' + command.uiItems.length );
-	 */
-	this.uiItems = [];
-
-	/**
-	 * Executes the command.
-	 *
-	 *		command.exec(); // The command gets executed.
-	 *
-	 * @param {Object} [data] Any data to pass to the command. Depends on the
-	 * command implementation and requirements.
-	 * @returns {Boolean} A boolean indicating that the command has been successfully executed.
-	 */
-	this.exec = function( data ) {
-		if ( this.state == CKEDITOR.TRISTATE_DISABLED || !this.checkAllowed() )
-			return false;
-
-		if ( this.editorFocus ) // Give editor focus if necessary (#4355).
-			editor.focus();
-
-		if ( this.fire( 'exec' ) === false )
-			return true;
-
-		return ( commandDefinition.exec.call( this, editor, data ) !== false );
-	};
-
-	/**
-	 * Explicitly update the status of the command, by firing the {@link CKEDITOR.command#event-refresh} event,
-	 * as well as invoke the {@link CKEDITOR.commandDefinition#refresh} method if defined, this method
-	 * is to allow different parts of the editor code to contribute in command status resolution.
-	 *
-	 * @param {CKEDITOR.editor} editor The editor instance.
-	 * @param {CKEDITOR.dom.elementPath} path
-	 */
-	this.refresh = function( editor, path ) {
-		// Do nothing is we're on read-only and this command doesn't support it.
-		// We don't need to disabled the command explicitely here, because this
-		// is already done by the "readOnly" event listener.
-		if ( !this.readOnly && editor.readOnly )
-			return true;
-
-		// Disable commands that are not allowed in the current selection path context.
-		if ( this.context && !path.isContextFor( this.context ) ) {
-			this.disable();
-			return true;
-		}
-
-		// Disable commands that are not allowed by the active filter.
-		if ( !this.checkAllowed( true ) ) {
-			this.disable();
-			return true;
-		}
-
-		// Make the "enabled" state a default for commands enabled from start.
-		if ( !this.startDisabled )
-			this.enable();
-
-		// Disable commands which shouldn't be enabled in this mode.
-		if ( this.modes && !this.modes[ editor.mode ] )
-			this.disable();
-
-		if ( this.fire( 'refresh', { editor: editor, path: path } ) === false )
-			return true;
-
-		return ( commandDefinition.refresh && commandDefinition.refresh.apply( this, arguments ) !== false );
-	};
-
-	var allowed;
-
-	/**
-	 * Checks whether this command is allowed by the active allowed
-	 * content filter ({@link CKEDITOR.editor#activeFilter}). This means
-	 * that if command implements {@link CKEDITOR.feature} interface it will be tested
-	 * by the {@link CKEDITOR.filter#checkFeature} method.
-	 *
-	 * @since 4.1
-	 * @param {Boolean} [noCache] Skip cache for example due to active filter change. Since CKEditor 4.2.
-	 * @returns {Boolean} Whether this command is allowed.
-	 */
-	this.checkAllowed = function( noCache ) {
-		if ( !noCache && typeof allowed == 'boolean' )
-			return allowed;
-
-		return allowed = editor.activeFilter.checkFeature( this );
-	};
-
-	CKEDITOR.tools.extend( this, commandDefinition, {
-		/**
-		 * The editor modes within which the command can be executed. The
-		 * execution will have no action if the current mode is not listed
-		 * in this property.
-		 *
-		 *		// Enable the command in both WYSIWYG and Source modes.
-		 *		command.modes = { wysiwyg:1,source:1 };
-		 *
-		 *		// Enable the command in Source mode only.
-		 *		command.modes = { source:1 };
-		 *
-		 * @see CKEDITOR.editor#mode
-		 */
-		modes: { wysiwyg: 1 },
-
-		/**
-		 * Indicates that the editor will get the focus before executing
-		 * the command.
-		 *
-		 *		// Do not force the editor to have focus when executing the command.
-		 *		command.editorFocus = false;
-		 *
-		 * @property {Boolean} [=true]
-		 */
-		editorFocus: 1,
-
-		/**
-		 * Indicates that this command is sensible to the selection context.
-		 * If `true`, the {@link CKEDITOR.command#method-refresh} method will be
-		 * called for this command on the {@link CKEDITOR.editor#event-selectionChange} event.
-		 *
-		 * @property {Boolean} [=false]
-		 */
-		contextSensitive: !!commandDefinition.context,
-
-		/**
-		 * Indicates the editor state. Possible values are:
-		 *
-		 * * {@link CKEDITOR#TRISTATE_DISABLED}: the command is
-		 *     disabled. It's execution will have no effect. Same as {@link #disable}.
-		 * * {@link CKEDITOR#TRISTATE_ON}: the command is enabled
-		 *     and currently active in the editor (for context sensitive commands,	for example).
-		 * * {@link CKEDITOR#TRISTATE_OFF}: the command is enabled
-		 *     and currently inactive in the editor (for context sensitive	commands, for example).
-		 *
-		 * Do not set this property directly, using the {@link #setState} method instead.
-		 *
-		 *		if ( command.state == CKEDITOR.TRISTATE_DISABLED )
-		 *			alert( 'This command is disabled' );
-		 *
-		 * @property {Number} [=CKEDITOR.TRISTATE_DISABLED]
-		 */
-		state: CKEDITOR.TRISTATE_DISABLED
-	} );
-
-	// Call the CKEDITOR.event constructor to initialize this instance.
-	CKEDITOR.event.call( this );
-};
-
-CKEDITOR.command.prototype = {
-	/**
-	 * Enables the command for execution. The command state (see
-	 * {@link CKEDITOR.command#property-state}) available before disabling it is restored.
-	 *
-	 *		command.enable();
-	 *		command.exec(); // Execute the command.
-	 */
-	enable: function() {
-		if ( this.state == CKEDITOR.TRISTATE_DISABLED && this.checkAllowed() )
-			this.setState( ( !this.preserveState || ( typeof this.previousState == 'undefined' ) ) ? CKEDITOR.TRISTATE_OFF : this.previousState );
-	},
-
-	/**
-	 * Disables the command for execution. The command state (see
-	 * {@link CKEDITOR.command#property-state}) will be set to {@link CKEDITOR#TRISTATE_DISABLED}.
-	 *
-	 *		command.disable();
-	 *		command.exec(); // "false" - Nothing happens.
-	 */
-	disable: function() {
-		this.setState( CKEDITOR.TRISTATE_DISABLED );
-	},
-
-	/**
-	 * Sets the command state.
-	 *
-	 *		command.setState( CKEDITOR.TRISTATE_ON );
-	 *		command.exec(); // Execute the command.
-	 *		command.setState( CKEDITOR.TRISTATE_DISABLED );
-	 *		command.exec(); // 'false' - Nothing happens.
-	 *		command.setState( CKEDITOR.TRISTATE_OFF );
-	 *		command.exec(); // Execute the command.
-	 *
-	 * @param {Number} newState The new state. See {@link #property-state}.
-	 * @returns {Boolean} Returns `true` if the command state changed.
-	 */
-	setState: function( newState ) {
-		// Do nothing if there is no state change.
-		if ( this.state == newState )
-			return false;
-
-		if ( newState != CKEDITOR.TRISTATE_DISABLED && !this.checkAllowed() )
-			return false;
-
-		this.previousState = this.state;
-
-		// Set the new state.
-		this.state = newState;
-
-		// Fire the "state" event, so other parts of the code can react to the
-		// change.
-		this.fire( 'state' );
-
-		return true;
-	},
-
-	/**
-	 * Toggles the on/off (active/inactive) state of the command. This is
-	 * mainly used internally by context sensitive commands.
-	 *
-	 *		command.toggleState();
-	 */
-	toggleState: function() {
-		if ( this.state == CKEDITOR.TRISTATE_OFF )
-			this.setState( CKEDITOR.TRISTATE_ON );
-		else if ( this.state == CKEDITOR.TRISTATE_ON )
-			this.setState( CKEDITOR.TRISTATE_OFF );
-	}
-};
-
-CKEDITOR.event.implementOn( CKEDITOR.command.prototype );
-
-/**
- * Indicates the previous command state.
- *
- *		alert( command.previousState );
- *
- * @property {Number} previousState
- * @see #state
- */
-
-/**
- * Fired when the command state changes.
- *
- *		command.on( 'state', function() {
- *			// Alerts the new state.
- *			alert( this.state );
- *		} );
- *
- * @event state
- */
-
- /**
- * @event refresh
- * @todo
- */

+ 0 - 139
htdocs/includes/ckeditor/ckeditor/_source/core/commanddefinition.js

@@ -1,139 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the "virtual" {@link CKEDITOR.commandDefinition} class,
- *		which contains the defintion of a command. This file is for
- *		documentation purposes only.
- */
-
-/**
- * Virtual class that illustrates the features of command objects to be
- * passed to the {@link CKEDITOR.editor#addCommand} function.
- *
- * @class CKEDITOR.commandDefinition
- * @abstract
- */
-
-/**
- * The function to be fired when the commend is executed.
- *
- *		editorInstance.addCommand( 'sample', {
- *			exec: function( editor ) {
- *				alert( 'Executing a command for the editor name "' + editor.name + '"!' );
- *			}
- *		} );
- *
- * @method exec
- * @param {CKEDITOR.editor} editor The editor within which run the command.
- * @param {Object} [data] Additional data to be used to execute the command.
- * @returns {Boolean} Whether the command has been successfully executed.
- * Defaults to `true`, if nothing is returned.
- */
-
-/**
- * Whether the command need to be hooked into the redo/undo system.
- *
- *		editorInstance.addCommand( 'alertName', {
- *			exec: function( editor ) {
- *				alert( editor.name );
- *			},
- *			canUndo: false // No support for undo/redo.
- *		} );
- *
- * @property {Boolean} [canUndo=true]
- */
-
-/**
- * Whether the command is asynchronous, which means that the
- * {@link CKEDITOR.editor#event-afterCommandExec} event will be fired by the
- * command itself manually, and that the return value of this command is not to
- * be returned by the {@link #exec} function.
- *
- * 		editorInstance.addCommand( 'loadOptions', {
- * 			exec: function( editor ) {
- * 				// Asynchronous operation below.
- * 				CKEDITOR.ajax.loadXml( 'data.xml', function() {
- * 					editor.fire( 'afterCommandExec' );
- * 				} );
- * 			},
- * 			async: true // The command need some time to complete after exec function returns.
- * 		} );
- *
- * @property {Boolean} [async=false]
- */
-
-/**
- * Whether the command should give focus to the editor before execution.
- *
- *		editorInstance.addCommand( 'maximize', {
- *				exec: function( editor ) {
- *				// ...
- *			},
- *			editorFocus: false // The command doesn't require focusing the editing document.
- *		} );
- *
- * @property {Boolean} [editorFocus=true]
- * @see CKEDITOR.command#editorFocus
- */
-
-
-/**
- * Whether the command state should be set to {@link CKEDITOR#TRISTATE_DISABLED} on startup.
- *
- *		editorInstance.addCommand( 'unlink', {
- *			exec: function( editor ) {
- *				// ...
- *			},
- *			startDisabled: true // Command is unavailable until selection is inside a link.
- *		} );
- *
- * @property {Boolean} [startDisabled=false]
- */
-
-/**
- * Indicates that this command is sensible to the selection context.
- * If `true`, the {@link CKEDITOR.command#method-refresh} method will be
- * called for this command on selection changes, with a single parameter
- * representing the current elements path.
- *
- * @property {Boolean} [contextSensitive=true]
- */
-
-/**
- * Defined by command definition a function to determinate the command state, it will be invoked
- * when editor has it's `states` or `selection` changed.
- *
- * **Note:** The function provided must be calling {@link CKEDITOR.command#setState} in all circumstance,
- * if it is intended to update the command state.
- *
- * @method refresh
- * @param {CKEDITOR.editor} editor
- * @param {CKEDITOR.dom.elementPath} path
- */
-
-/**
- * Sets the element name used to reflect the command state on selection changes.
- * If the selection is in a place where the element is not allowed, the command
- * will be disabled.
- * Setting this property overrides {@link #contextSensitive} to `true`.
- *
- * @property {Boolean} [context=true]
- */
-
-/**
- * The editor modes within which the command can be executed. The execution
- * will have no action if the current mode is not listed in this property.
- *
- *		editorInstance.addCommand( 'link', {
- *			exec: function( editor ) {
- *				// ...
- *			},
- *			modes: { wysiwyg:1 } // Command is available in wysiwyg mode only.
- *		} );
- *
- * @property {Object} [modes={ wysiwyg:1 }]
- * @see CKEDITOR.command#modes
- */

+ 0 - 383
htdocs/includes/ckeditor/ckeditor/_source/core/config.js

@@ -1,383 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.config} object that stores the
- * default configuration settings.
- */
-
-/**
- * Used in conjunction with {@link CKEDITOR.config#enterMode}
- * and {@link CKEDITOR.config#shiftEnterMode} configuration
- * settings to make the editor produce `<p>` tags when
- * using the *Enter* key.
- *
- * @readonly
- * @property {Number} [=1]
- * @member CKEDITOR
- */
-CKEDITOR.ENTER_P = 1;
-
-/**
- * Used in conjunction with {@link CKEDITOR.config#enterMode}
- * and {@link CKEDITOR.config#shiftEnterMode} configuration
- * settings to make the editor produce `<br>` tags when
- * using the *Enter* key.
- *
- * @readonly
- * @property {Number} [=2]
- * @member CKEDITOR
- */
-CKEDITOR.ENTER_BR = 2;
-
-/**
- * Used in conjunction with {@link CKEDITOR.config#enterMode}
- * and {@link CKEDITOR.config#shiftEnterMode} configuration
- * settings to make the editor produce `<div>` tags when
- * using the *Enter* key.
- *
- * @readonly
- * @property {Number} [=3]
- * @member CKEDITOR
- */
-CKEDITOR.ENTER_DIV = 3;
-
-/**
- * Stores default configuration settings. Changes to this object are
- * reflected in all editor instances, if not specified otherwise for a particular
- * instance.
- *
- * @class
- * @singleton
- */
-CKEDITOR.config = {
-	/**
-	 * The URL path for the custom configuration file to be loaded. If not
-	 * overloaded with inline configuration, it defaults to the `config.js`
-	 * file present in the root of the CKEditor installation directory.
-	 *
-	 * CKEditor will recursively load custom configuration files defined inside
-	 * other custom configuration files.
-	 *
-	 *		// Load a specific configuration file.
-	 *		CKEDITOR.replace( 'myfield', { customConfig: '/myconfig.js' } );
-	 *
-	 *		// Do not load any custom configuration file.
-	 *		CKEDITOR.replace( 'myfield', { customConfig: '' } );
-	 *
-	 * @cfg {String} [="<CKEditor folder>/config.js"]
-	 */
-	customConfig: 'config.js',
-
-	/**
-	 * Whether the replaced element (usually a `<textarea>`)
-	 * is to be updated automatically when posting the form containing the editor.
-	 *
-	 * @cfg
-	 */
-	autoUpdateElement: true,
-
-	/**
-	 * The user interface language localization to use. If left empty, the editor
-	 * will automatically be localized to the user language. If the user language is not supported,
-	 * the language specified in the {@link CKEDITOR.config#defaultLanguage}
-	 * configuration setting is used.
-	 *
-	 *		// Load the German interface.
-	 *		config.language = 'de';
-	 *
-	 * @cfg
-	 */
-	language: '',
-
-	/**
-	 * The language to be used if the {@link CKEDITOR.config#language}
-	 * setting is left empty and it is not possible to localize the editor to the user language.
-	 *
-	 *		config.defaultLanguage = 'it';
-	 *
-	 * @cfg
-	 */
-	defaultLanguage: 'en',
-
-	/**
-	 * The writting direction of the language used to write the editor
-	 * contents. Allowed values are:
-	 *
-	 * * `''` (empty string) - indicate content direction will be the same with either the editor
-	 *     UI direction or page element direction depending on the creators:
-	 *     * Themed UI: The same with user interface language direction;
-	 *     * Inline: The same with the editable element text direction;
-	 * * `'ltr'` - for Left-To-Right language (like English);
-	 * * `'rtl'` - for Right-To-Left languages (like Arabic).
-	 *
-	 * Example:
-	 *
-	 *		config.contentsLangDirection = 'rtl';
-	 *
-	 * @cfg
-	 */
-	contentsLangDirection: '',
-
-	/**
-	 * Sets the behavior of the *Enter* key. It also determines other behavior
-	 * rules of the editor, like whether the `<br>` element is to be used
-	 * as a paragraph separator when indenting text.
-	 * The allowed values are the following constants that cause the behavior outlined below:
-	 *
-	 * * {@link CKEDITOR#ENTER_P} (1) &ndash; new `<p>` paragraphs are created;
-	 * * {@link CKEDITOR#ENTER_BR} (2) &ndash; lines are broken with `<br>` elements;
-	 * * {@link CKEDITOR#ENTER_DIV} (3) &ndash; new `<div>` blocks are created.
-	 *
-	 * **Note**: It is recommended to use the {@link CKEDITOR#ENTER_P} setting because of
-	 * its semantic value and correctness. The editor is optimized for this setting.
-	 *
-	 *		// Not recommended.
-	 *		config.enterMode = CKEDITOR.ENTER_BR;
-	 *
-	 * @cfg {Number} [=CKEDITOR.ENTER_P]
-	 */
-	enterMode: CKEDITOR.ENTER_P,
-
-	/**
-	 * Force the use of {@link CKEDITOR.config#enterMode} as line break regardless
-	 * of the context. If, for example, {@link CKEDITOR.config#enterMode} is set
-	 * to {@link CKEDITOR#ENTER_P}, pressing the *Enter* key inside a
-	 * `<div>` element will create a new paragraph with `<p>`
-	 * instead of a `<div>`.
-	 *
-	 *		// Not recommended.
-	 *		config.forceEnterMode = true;
-	 *
-	 * @since 3.2.1
-	 * @cfg
-	 */
-	forceEnterMode: false,
-
-	/**
-	 * Similarly to the {@link CKEDITOR.config#enterMode} setting, it defines the behavior
-	 * of the *Shift+Enter* key combination.
-	 *
-	 * The allowed values are the following constants the behavior outlined below:
-	 *
-	 * * {@link CKEDITOR#ENTER_P} (1) &ndash; new `<p>` paragraphs are created;
-	 * * {@link CKEDITOR#ENTER_BR} (2) &ndash; lines are broken with `<br>` elements;
-	 * * {@link CKEDITOR#ENTER_DIV} (3) &ndash; new `<div>` blocks are created.
-	 *
-	 * Example:
-	 *
-	 *		config.shiftEnterMode = CKEDITOR.ENTER_P;
-	 *
-	 * @cfg {Number} [=CKEDITOR.ENTER_BR]
-	 */
-	shiftEnterMode: CKEDITOR.ENTER_BR,
-
-	/**
-	 * Sets the `DOCTYPE` to be used when loading the editor content as HTML.
-	 *
-	 *		// Set the DOCTYPE to the HTML 4 (Quirks) mode.
-	 *		config.docType = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';
-	 *
-	 * @cfg
-	 */
-	docType: '<!DOCTYPE html>',
-
-	/**
-	 * Sets the `id` attribute to be used on the `body` element
-	 * of the editing area. This can be useful when you intend to reuse the original CSS
-	 * file you are using on your live website and want to assign the editor the same ID
-	 * as the section that will include the contents. In this way ID-specific CSS rules will
-	 * be enabled.
-	 *
-	 *		config.bodyId = 'contents_id';
-	 *
-	 * @since 3.1
-	 * @cfg
-	 */
-	bodyId: '',
-
-	/**
-	 * Sets the `class` attribute to be used on the `body` element
-	 * of the editing area. This can be useful when you intend to reuse the original CSS
-	 * file you are using on your live website and want to assign the editor the same class
-	 * as the section that will include the contents. In this way class-specific CSS rules will
-	 * be enabled.
-	 *
-	 *		config.bodyClass = 'contents';
-	 *
-	 * **Note:** Editor needs to load stylesheets containing contents styles. You can either
-	 * copy them to the `contents.css` file that editor loads by default or set the {@link #contentsCss}
-	 * option.
-	 *
-	 * **Note:** This setting applies only to the classic editor (the one that uses `iframe`).
-	 *
-	 * @since 3.1
-	 * @cfg
-	 */
-	bodyClass: '',
-
-	/**
-	 * Indicates whether the contents to be edited are being input as a full HTML page.
-	 * A full page includes the `<html>`, `<head>`, and `<body>` elements.
-	 * The final output will also reflect this setting, including the
-	 * `<body>` contents only if this setting is disabled.
-	 *
-	 *		config.fullPage = true;
-	 *
-	 * @since 3.1
-	 * @cfg
-	 */
-	fullPage: false,
-
-	/**
-	 * The height of the editing area (that includes the editor content). This
-	 * can be an integer, for pixel sizes, or any CSS-defined length unit.
-	 *
-	 * **Note:** Percent units (%) are not supported.
-	 *
-	 *		config.height = 500;		// 500 pixels.
-	 *		config.height = '25em';		// CSS length.
-	 *		config.height = '300px';	// CSS length.
-	 *
-	 * @cfg {Number/String}
-	 */
-	height: 200,
-
-	/**
-	 * Comma separated list of plugins to be used for an editor instance,
-	 * besides, the actual plugins that to be loaded could be still affected by two other settings:
-	 * {@link CKEDITOR.config#extraPlugins} and {@link CKEDITOR.config#removePlugins}.
-	 *
-	 * @cfg {String} [="<default list of plugins>"]
-	 */
-	plugins: '', // %REMOVE_LINE%
-
-	/**
-	 * A list of additional plugins to be loaded. This setting makes it easier
-	 * to add new plugins without having to touch {@link CKEDITOR.config#plugins} setting.
-	 *
-	 *		config.extraPlugins = 'myplugin,anotherplugin';
-	 *
-	 * @cfg
-	 */
-	extraPlugins: '',
-
-	/**
-	 * A list of plugins that must not be loaded. This setting makes it possible
-	 * to avoid loading some plugins defined in the {@link CKEDITOR.config#plugins}
-	 * setting, without having to touch it.
-	 *
-	 * **Note:** Plugin required by other plugin cannot be removed (error will be thrown).
-	 * So e.g. if `contextmenu` is required by `tabletools`, then it can be removed
-	 * only if `tabletools` isn't loaded.
-	 *
-	 *		config.removePlugins = 'elementspath,save,font';
-	 *
-	 * @cfg
-	 */
-	removePlugins: '',
-
-	/**
-	 * List of regular expressions to be executed on input HTML,
-	 * indicating HTML source code that when matched, must **not** be available in the WYSIWYG
-	 * mode for editing.
-	 *
-	 *		config.protectedSource.push( /<\?[\s\S]*?\?>/g );											// PHP code
-	 *		config.protectedSource.push( /<%[\s\S]*?%>/g );												// ASP code
-	 *		config.protectedSource.push( /(<asp:[^\>]+>[\s|\S]*?<\/asp:[^\>]+>)|(<asp:[^\>]+\/>)/gi );	// ASP.Net code
-	 *
-	 * @cfg
-	 */
-	protectedSource: [],
-
-	/**
-	 * The editor `tabindex` value.
-	 *
-	 *		config.tabIndex = 1;
-	 *
-	 * @cfg
-	 */
-	tabIndex: 0,
-
-	/**
-	 * The editor UI outer width. This can be an integer, for pixel sizes, or
-	 * any CSS-defined unit.
-	 *
-	 * Unlike the {@link CKEDITOR.config#height} setting, this
-	 * one will set the outer width of the entire editor UI, not for the
-	 * editing area only.
-	 *
-	 *		config.width = 850;		// 850 pixels wide.
-	 *		config.width = '75%';	// CSS unit.
-	 *
-	 * @cfg {String/Number}
-	 */
-	width: '',
-
-	/**
-	 * The base Z-index for floating dialog windows and popups.
-	 *
-	 *		config.baseFloatZIndex = 2000;
-	 *
-	 * @cfg
-	 */
-	baseFloatZIndex: 10000,
-
-	/**
-	 * The keystrokes that are blocked by default as the browser implementation
-	 * is buggy. These default keystrokes are handled by the editor.
-	 *
-	 *		// Default setting.
-	 *		config.blockedKeystrokes = [
-	 *			CKEDITOR.CTRL + 66, // CTRL+B
-	 *			CKEDITOR.CTRL + 73, // CTRL+I
-	 *			CKEDITOR.CTRL + 85, // CTRL+U
-	 *			CKEDITOR.CTRL + 89, // CTRL+Y
-	 *			CKEDITOR.CTRL + 90, // CTRL+Z
-	 *			CKEDITOR.CTRL + CKEDITOR.SHIFT + 90  // CTRL+SHIFT+Z
-	 *		];
-	 *
-	 * @cfg {Array} [blockedKeystrokes=see example]
-	 */
-	blockedKeystrokes: [
-		CKEDITOR.CTRL + 66, // CTRL+B
-		CKEDITOR.CTRL + 73, // CTRL+I
-		CKEDITOR.CTRL + 85, // CTRL+U
-
-		CKEDITOR.CTRL + 89, // CTRL+Y
-		CKEDITOR.CTRL + 90, // CTRL+Z
-		CKEDITOR.CTRL + CKEDITOR.SHIFT + 90  // CTRL+SHIFT+Z
-	]
-};
-
-/**
- * Indicates that some of the editor features, like alignment and text
- * direction, should use the "computed value" of the feature to indicate its
- * on/off state instead of using the "real value".
- *
- * If enabled in a Left-To-Right written document, the "Left Justify"
- * alignment button will be shown as active, even if the alignment style is not
- * explicitly applied to the current paragraph in the editor.
- *
- *		config.useComputedState = false;
- *
- * @since 3.4
- * @cfg {Boolean} [useComputedState=true]
- */
-
-/**
- * The base user interface color to be used by the editor. Not all skins are
- * compatible with this setting.
- *
- *		// Using a color code.
- *		config.uiColor = '#AADC6E';
- *
- *		// Using an HTML color name.
- *		config.uiColor = 'Gold';
- *
- * @cfg {String} uiColor
- */
-
-// PACKAGER_RENAME( CKEDITOR.config )

+ 0 - 153
htdocs/includes/ckeditor/ckeditor/_source/core/creators/inline.js

@@ -1,153 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-( function() {
-	/** @class CKEDITOR */
-
-	/**
-	 * Turns a DOM element with `contenteditable` attribute set to `true` into a
-	 * CKEditor instance. Check {@link CKEDITOR.dtd#$editable} for the list of
-	 * allowed element names.
-	 *
-	 *		<div contenteditable="true" id="content">...</div>
-	 *		...
-	 *		CKEDITOR.inline( 'content' );
-	 *
-	 * It is also possible to create an inline editor from the `<textarea>` element.
-	 * If you do so, an additional `<div>` element with editable content will be created
-	 * directly after the `<textarea>` element and the `<textarea>` element will be hidden.
-	 *
-	 * @param {Object/String} element The DOM element or its ID.
-	 * @param {Object} [instanceConfig] The specific configurations to apply to this editor instance.
-	 * See {@link CKEDITOR.config}.
-	 * @returns {CKEDITOR.editor} The editor instance created.
-	 */
-	CKEDITOR.inline = function( element, instanceConfig ) {
-		if ( !CKEDITOR.env.isCompatible )
-			return null;
-
-		element = CKEDITOR.dom.element.get( element );
-
-		// Avoid multiple inline editor instances on the same element.
-		if ( element.getEditor() )
-			throw 'The editor instance "' + element.getEditor().name + '" is already attached to the provided element.';
-
-		var editor = new CKEDITOR.editor( instanceConfig, element, CKEDITOR.ELEMENT_MODE_INLINE ),
-			textarea = element.is( 'textarea' ) ? element : null;
-
-		if ( textarea ) {
-			editor.setData( textarea.getValue(), null, true );
-
-			//Change element from textarea to div
-			element = CKEDITOR.dom.element.createFromHtml(
-				'<div contenteditable="' + !!editor.readOnly + '" class="cke_textarea_inline">' +
-					textarea.getValue() +
-				'</div>',
-				CKEDITOR.document );
-
-			element.insertAfter( textarea );
-			textarea.hide();
-
-			// Attaching the concrete form.
-			if ( textarea.$.form )
-				editor._attachToForm();
-		} else {
-			// Initial editor data is simply loaded from the page element content to make
-			// data retrieval possible immediately after the editor creation.
-			editor.setData( element.getHtml(), null, true );
-		}
-
-		// Once the editor is loaded, start the UI.
-		editor.on( 'loaded', function() {
-			editor.fire( 'uiReady' );
-
-			// Enable editing on the element.
-			editor.editable( element );
-
-			// Editable itself is the outermost element.
-			editor.container = element;
-
-			// Load and process editor data.
-			editor.setData( editor.getData( 1 ) );
-
-			// Clean on startup.
-			editor.resetDirty();
-
-			editor.fire( 'contentDom' );
-
-			// Inline editing defaults to "wysiwyg" mode, so plugins don't
-			// need to make special handling for this "mode-less" environment.
-			editor.mode = 'wysiwyg';
-			editor.fire( 'mode' );
-
-			// The editor is completely loaded for interaction.
-			editor.status = 'ready';
-			editor.fireOnce( 'instanceReady' );
-			CKEDITOR.fire( 'instanceReady', null, editor );
-
-			// give priority to plugins that relay on editor#loaded for bootstrapping.
-		}, null, null, 10000 );
-
-		// Handle editor destroying.
-		editor.on( 'destroy', function() {
-			// Remove container from DOM if inline-textarea editor.
-			// Show <textarea> back again.
-			if ( textarea ) {
-				editor.container.clearCustomData();
-				editor.container.remove();
-				textarea.show();
-			}
-
-			editor.element.clearCustomData();
-
-			delete editor.element;
-		} );
-
-		return editor;
-	};
-
-	/**
-	 * Calls {@link CKEDITOR#inline} for all page elements with
-	 * `contenteditable` attribute set to `true`.
-	 *
-	 */
-	CKEDITOR.inlineAll = function() {
-		var el, data;
-
-		for ( var name in CKEDITOR.dtd.$editable ) {
-			var elements = CKEDITOR.document.getElementsByTag( name );
-
-			for ( var i = 0, len = elements.count(); i < len; i++ ) {
-				el = elements.getItem( i );
-
-				if ( el.getAttribute( 'contenteditable' ) == 'true' ) {
-					// Fire the "inline" event, making it possible to customize
-					// the instance settings and eventually cancel the creation.
-
-					data = {
-						element: el,
-						config: {}
-					};
-
-					if ( CKEDITOR.fire( 'inline', data ) !== false )
-						CKEDITOR.inline( el, data.config );
-				}
-			}
-		}
-	};
-
-	CKEDITOR.domReady( function() {
-		!CKEDITOR.disableAutoInline && CKEDITOR.inlineAll();
-	} );
-} )();
-
-/**
- * Disables creating the inline editor automatically for elements with
- * `contenteditable` attribute set to the `true`.
- *
- *		CKEDITOR.disableAutoInline = true;
- *
- * @cfg {Boolean} [disableAutoInline=false]
- */

+ 0 - 457
htdocs/includes/ckeditor/ckeditor/_source/core/creators/themedui.js

@@ -1,457 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
- /** @class CKEDITOR */
-
-/**
- * The class name used to identify `<textarea>` elements to be replaced
- * by CKEditor instances. Set it to empty/`null` to disable this feature.
- *
- *		CKEDITOR.replaceClass = 'rich_editor';
- *
- * @cfg {String} [replaceClass='ckeditor']
- */
-CKEDITOR.replaceClass = 'ckeditor';
-
-( function() {
-	/**
-	 * Replaces a `<textarea>` or a DOM element (`<div>`) with a CKEditor
-	 * instance. For textareas, the initial value in the editor will be the
-	 * textarea value. For DOM elements, their `innerHTML` will be used
-	 * instead. We recommend using `<textarea>` and `<div>` elements only.
-	 *
-	 *		<textarea id="myfield" name="myfield"></textarea>
-	 *		...
-	 *		CKEDITOR.replace( 'myfield' );
-	 *
-	 *		var textarea = document.body.appendChild( document.createElement( 'textarea' ) );
-	 *		CKEDITOR.replace( textarea );
-	 *
-	 * @param {Object/String} element The DOM element (textarea), its ID, or name.
-	 * @param {Object} [config] The specific configuration to apply to this
-	 * editor instance. Configuration set here will override the global CKEditor settings
-	 * (see {@link CKEDITOR.config}).
-	 * @returns {CKEDITOR.editor} The editor instance created.
-	 */
-	CKEDITOR.replace = function( element, config ) {
-		return createInstance( element, config, null, CKEDITOR.ELEMENT_MODE_REPLACE );
-	};
-
-	/**
-	 * Creates a new editor instance at the end of a specific DOM element.
-	 *
-	 *		<div id="editorSpace"></div>
-	 *		...
-	 *		CKEDITOR.appendTo( 'editorSpace' );
-	 *
-	 * @param {Object/String} element The DOM element, its ID, or name.
-	 * @param {Object} [config] The specific configuration to apply to this
-	 * editor instance. Configuration set here will override the global CKEditor settings
-	 * (see {@link CKEDITOR.config}).
-	 * @param {String} [data] Since 3.3. Initial value for the instance.
-	 * @returns {CKEDITOR.editor} The editor instance created.
-	 */
-	CKEDITOR.appendTo = function( element, config, data )
-	{
-		return createInstance( element, config, data, CKEDITOR.ELEMENT_MODE_APPENDTO );
-	};
-
-	/**
-	 * Replaces all `<textarea>` elements available in the document with
-	 * editor instances.
-	 *
-	 *		// Replace all <textarea> elements in the page.
-	 *		CKEDITOR.replaceAll();
-	 *
-	 *		// Replace all <textarea class="myClassName"> elements in the page.
-	 *		CKEDITOR.replaceAll( 'myClassName' );
-	 *
-	 *		// Selectively replace <textarea> elements, based on custom assertions.
-	 *		CKEDITOR.replaceAll( function( textarea, config ) {
-	 *			// An assertion function that needs to be evaluated for the <textarea>
-	 *			// to be replaced. It must explicitely return "false" to ignore a
-	 *			// specific <textarea>.
-	 *			// You can also customize the editor instance by having the function
-	 *			// modify the "config" parameter.
-	 *		} );
-	 *
-	 * @param {String} [className] The `<textarea>` class name.
-	 * @param {Function} [function] An assertion function that must return `true` for a `<textarea>`
-	 * to be replaced with the editor. If the function returns `false`, the `<textarea>` element
-	 * will not be replaced.
-	 */
-	CKEDITOR.replaceAll = function() {
-		var textareas = document.getElementsByTagName( 'textarea' );
-
-		for ( var i = 0; i < textareas.length; i++ ) {
-			var config = null,
-				textarea = textareas[ i ];
-
-			// The "name" and/or "id" attribute must exist.
-			if ( !textarea.name && !textarea.id )
-				continue;
-
-			if ( typeof arguments[ 0 ] == 'string' ) {
-				// The textarea class name could be passed as the function
-				// parameter.
-
-				var classRegex = new RegExp( '(?:^|\\s)' + arguments[ 0 ] + '(?:$|\\s)' );
-
-				if ( !classRegex.test( textarea.className ) )
-					continue;
-			} else if ( typeof arguments[ 0 ] == 'function' ) {
-				// An assertion function could be passed as the function parameter.
-				// It must explicitly return "false" to ignore a specific <textarea>.
-				config = {};
-				if ( arguments[ 0 ]( textarea, config ) === false )
-					continue;
-			}
-
-			this.replace( textarea, config );
-		}
-	};
-
-	/** @class CKEDITOR.editor */
-
-	/**
-	 * Registers an editing mode. This function is to be used mainly by plugins.
-	 *
-	 * @param {String} mode The mode name.
-	 * @param {Function} exec The function that performs the actual mode change.
-	 */
-	CKEDITOR.editor.prototype.addMode = function( mode, exec ) {
-		( this._.modes || ( this._.modes = {} ) )[ mode ] = exec;
-	};
-
-	/**
-	 * Changes the editing mode of this editor instance.
-	 *
-	 * **Note:** The mode switch could be asynchronous depending on the mode provider.
-	 * Use the `callback` to hook subsequent code.
-	 *
-	 *		// Switch to "source" view.
-	 *		CKEDITOR.instances.editor1.setMode( 'source' );
-	 *		// Switch to "wysiwyg" view and be notified on completion.
-	 *		CKEDITOR.instances.editor1.setMode( 'wysiwyg', function() { alert( 'wysiwyg mode loaded!' ); } );
-	 *
-	 * @param {String} [newMode] If not specified, the {@link CKEDITOR.config#startupMode} will be used.
-	 * @param {Function} [callback] Optional callback function which is invoked once the mode switch has succeeded.
-	 */
-	CKEDITOR.editor.prototype.setMode = function( newMode, callback ) {
-		var editor = this;
-
-		var modes = this._.modes;
-
-		// Mode loading quickly fails.
-		if ( newMode == editor.mode || !modes || !modes[ newMode ] )
-			return;
-
-		editor.fire( 'beforeSetMode', newMode );
-
-		if ( editor.mode ) {
-			var isDirty = editor.checkDirty();
-
-			editor._.previousMode = editor.mode;
-
-			editor.fire( 'beforeModeUnload' );
-
-			// Detach the current editable.
-			editor.editable( 0 );
-
-			// Clear up the mode space.
-			editor.ui.space( 'contents' ).setHtml( '' );
-
-			editor.mode = '';
-		}
-
-		// Fire the mode handler.
-		this._.modes[ newMode ]( function() {
-			// Set the current mode.
-			editor.mode = newMode;
-
-			if ( isDirty !== undefined )
-				!isDirty && editor.resetDirty();
-
-			// Delay to avoid race conditions (setMode inside setMode).
-			setTimeout( function() {
-				editor.fire( 'mode' );
-				callback && callback.call( editor );
-			}, 0 );
-		} );
-	};
-
-	/**
-	 * Resizes the editor interface.
-	 *
-	 *		editor.resize( 900, 300 );
-	 *
-	 *		editor.resize( '100%', 450, true );
-	 *
-	 * @param {Number/String} width The new width. It can be an integer denoting a value
-	 * in pixels or a CSS size value with unit.
-	 * @param {Number/String} height The new height. It can be an integer denoting a value
-	 * in pixels or a CSS size value with unit.
-	 * @param {Boolean} [isContentHeight] Indicates that the provided height is to
-	 * be applied to the editor content area, and not to the entire editor
-	 * interface. Defaults to `false`.
-	 * @param {Boolean} [resizeInner] Indicates that it is the inner interface
-	 * element that must be resized, not the outer element. The default theme
-	 * defines the editor interface inside a pair of `<span>` elements
-	 * (`<span><span>...</span></span>`). By default the first,
-	 * outer `<span>` element receives the sizes. If this parameter is set to
-	 * `true`, the second, inner `<span>` is resized instead.
-	 */
-	CKEDITOR.editor.prototype.resize = function( width, height, isContentHeight, resizeInner ) {
-		var container = this.container,
-			contents = this.ui.space( 'contents' ),
-			contentsFrame = CKEDITOR.env.webkit && this.document && this.document.getWindow().$.frameElement,
-			outer = resizeInner ? container.getChild( 1 ) : container;
-
-		// Set as border box width. (#5353)
-		outer.setSize( 'width', width, true );
-
-		// WebKit needs to refresh the iframe size to avoid rendering issues. (1/2) (#8348)
-		contentsFrame && ( contentsFrame.style.width = '1%' );
-
-		// Get the height delta between the outer table and the content area.
-		// If we're setting the content area's height, then we don't need the delta.
-		var delta = isContentHeight ? 0 : ( outer.$.offsetHeight || 0 ) - ( contents.$.clientHeight || 0 );
-		contents.setStyle( 'height', Math.max( height - delta, 0 ) + 'px' );
-
-		// WebKit needs to refresh the iframe size to avoid rendering issues. (2/2) (#8348)
-		contentsFrame && ( contentsFrame.style.width = '100%' );
-
-		// Emit a resize event.
-		this.fire( 'resize' );
-	};
-
-	/**
-	 * Gets the element that can be used to check the editor size. This method
-	 * is mainly used by the `resize` plugin, which adds a UI handle that can be used
-	 * to resize the editor.
-	 *
-	 * @param {Boolean} forContents Whether to return the "contents" part of the theme instead of the container.
-	 * @returns {CKEDITOR.dom.element} The resizable element.
-	 */
-	CKEDITOR.editor.prototype.getResizable = function( forContents ) {
-		return forContents ? this.ui.space( 'contents' ) : this.container;
-	};
-
-	function createInstance( element, config, data, mode ) {
-		if ( !CKEDITOR.env.isCompatible )
-			return null;
-
-		element = CKEDITOR.dom.element.get( element );
-
-		// Avoid multiple inline editor instances on the same element.
-		if ( element.getEditor() )
-			throw 'The editor instance "' + element.getEditor().name + '" is already attached to the provided element.';
-
-		// Create the editor instance.
-		var editor = new CKEDITOR.editor( config, element, mode );
-
-		if ( mode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
-			// Do not replace the textarea right now, just hide it. The effective
-			// replacement will be done later in the editor creation lifecycle.
-			element.setStyle( 'visibility', 'hidden' );
-
-			// #8031 Remember if textarea was required and remove the attribute.
-			editor._.required = element.hasAttribute( 'required' );
-			element.removeAttribute( 'required' );
-		}
-
-		data && editor.setData( data, null, true );
-
-		// Once the editor is loaded, start the UI.
-		editor.on( 'loaded', function() {
-			loadTheme( editor );
-
-			if ( mode == CKEDITOR.ELEMENT_MODE_REPLACE && editor.config.autoUpdateElement && element.$.form )
-				editor._attachToForm();
-
-			editor.setMode( editor.config.startupMode, function() {
-				// Clean on startup.
-				editor.resetDirty();
-
-				// Editor is completely loaded for interaction.
-				editor.status = 'ready';
-				editor.fireOnce( 'instanceReady' );
-				CKEDITOR.fire( 'instanceReady', null, editor );
-			} );
-		} );
-
-		editor.on( 'destroy', destroy );
-		return editor;
-	}
-
-	function destroy() {
-		var editor = this,
-			container = editor.container,
-			element = editor.element;
-
-		if ( container ) {
-			container.clearCustomData();
-			container.remove();
-		}
-
-		if ( element ) {
-			element.clearCustomData();
-			if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
-				element.show();
-				if ( editor._.required )
-					element.setAttribute( 'required', 'required' );
-			}
-			delete editor.element;
-		}
-	}
-
-	var themedTpl;
-
-	function loadTheme( editor ) {
-		var name = editor.name,
-			element = editor.element,
-			elementMode = editor.elementMode;
-
-		// Get the HTML for the predefined spaces.
-		var topHtml = editor.fire( 'uiSpace', { space: 'top', html: '' } ).html;
-		var bottomHtml = editor.fire( 'uiSpace', { space: 'bottom', html: '' } ).html;
-
-		if ( !themedTpl ) {
-			themedTpl = CKEDITOR.addTemplate( 'maincontainer', '<{outerEl}' +
-				' id="cke_{name}"' +
-				' class="{id} cke cke_reset cke_chrome cke_editor_{name} cke_{langDir} ' + CKEDITOR.env.cssClass + '" ' +
-				' dir="{langDir}"' +
-				' lang="{langCode}"' +
-				' role="application"' +
-				' aria-labelledby="cke_{name}_arialbl">' +
-				'<span id="cke_{name}_arialbl" class="cke_voice_label">{voiceLabel}</span>' +
-					'<{outerEl} class="cke_inner cke_reset" role="presentation">' +
-						'{topHtml}' +
-						'<{outerEl} id="{contentId}" class="cke_contents cke_reset" role="presentation"></{outerEl}>' +
-						'{bottomHtml}' +
-					'</{outerEl}>' +
-				'</{outerEl}>' );
-		}
-
-		var container = CKEDITOR.dom.element.createFromHtml( themedTpl.output( {
-			id: editor.id,
-			name: name,
-			langDir: editor.lang.dir,
-			langCode: editor.langCode,
-			voiceLabel: [ editor.lang.editor, editor.name ].join( ', ' ),
-			topHtml: topHtml ? '<span id="' + editor.ui.spaceId( 'top' ) + '" class="cke_top cke_reset_all" role="presentation" style="height:auto">' + topHtml + '</span>' : '',
-			contentId: editor.ui.spaceId( 'contents' ),
-			bottomHtml: bottomHtml ? '<span id="' + editor.ui.spaceId( 'bottom' ) + '" class="cke_bottom cke_reset_all" role="presentation">' + bottomHtml + '</span>' : '',
-			outerEl: CKEDITOR.env.ie ? 'span' : 'div'	// #9571
-		} ) );
-
-		if ( elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
-			element.hide();
-			container.insertAfter( element );
-		} else
-			element.append( container );
-
-		editor.container = container;
-
-		// Make top and bottom spaces unelectable, but not content space,
-		// otherwise the editable area would be affected.
-		topHtml && editor.ui.space( 'top' ).unselectable();
-		bottomHtml && editor.ui.space( 'bottom' ).unselectable();
-
-		var width = editor.config.width, height = editor.config.height;
-		if ( width )
-			container.setStyle( 'width', CKEDITOR.tools.cssLength( width ) );
-
-		// The editor height is applied to the contents space.
-		if ( height )
-			editor.ui.space( 'contents' ).setStyle( 'height', CKEDITOR.tools.cssLength( height ) );
-
-		// Disable browser context menu for editor's chrome.
-		container.disableContextMenu();
-
-		// Redirect the focus into editor for webkit. (#5713)
-		CKEDITOR.env.webkit && container.on( 'focus', function() {
-			editor.focus();
-		} );
-
-		editor.fireOnce( 'uiReady' );
-	}
-
-	// Replace all textareas with the default class name.
-	CKEDITOR.domReady( function() {
-		CKEDITOR.replaceClass && CKEDITOR.replaceAll( CKEDITOR.replaceClass );
-	} );
-} )();
-
-/**
- * The current editing mode. An editing mode basically provides
- * different ways of editing or viewing the contents.
- *
- *		alert( CKEDITOR.instances.editor1.mode ); // (e.g.) 'wysiwyg'
- *
- * @readonly
- * @property {String} mode
- */
-
-/**
- * The mode to load at the editor startup. It depends on the plugins
- * loaded. By default, the `wysiwyg` and `source` modes are available.
- *
- *		config.startupMode = 'source';
- *
- * @cfg {String} [startupMode='wysiwyg']
- * @member CKEDITOR.config
- */
-CKEDITOR.config.startupMode = 'wysiwyg';
-
-/**
- * Fired after the editor instance is resized through
- * the {@link CKEDITOR.editor#method-resize CKEDITOR.resize} method.
- *
- * @event resize
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Fired before changing the editing mode. See also
- * {@link #beforeSetMode} and {@link #event-mode}.
- *
- * @event beforeModeUnload
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Fired before the editor mode is set. See also
- * {@link #event-mode} and {@link #beforeModeUnload}.
- *
- * @since 3.5.3
- * @event beforeSetMode
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param {String} data The name of the mode which is about to be set.
- */
-
-/**
- * Fired after setting the editing mode. See also {@link #beforeSetMode} and {@link #beforeModeUnload}
- *
- * @event mode
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Fired when the editor (replacing a `<textarea>` which has a `required` attribute) is empty during form submission.
- *
- * This event replaces native required fields validation that the browsers cannot
- * perform when CKEditor replaces `<textarea>` elements.
- *
- * You can cancel this event to prevent the page from submitting data.
- *
- *		editor.on( 'required', function( evt ) {
- *			alert( 'Article content is required.' );
- *			evt.cancel();
- *		} );
- *
- * @event required
- * @param {CKEDITOR.editor} editor This editor instance.
- */

+ 0 - 70
htdocs/includes/ckeditor/ckeditor/_source/core/dataprocessor.js

@@ -1,70 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the "virtual" {@link CKEDITOR.dataProcessor} class, which
- *		defines the basic structure of data processor objects to be
- *		set to {@link CKEDITOR.editor.dataProcessor}.
- */
-
-/**
- * If defined, points to the data processor which is responsible to translate
- * and transform the editor data on input and output.
- * Generaly it will point to an instance of {@link CKEDITOR.htmlDataProcessor},
- * which handles HTML data. The editor may also handle other data formats by
- * using different data processors provided by specific plugins.
- *
- * @property {CKEDITOR.dataProcessor} dataProcessor
- * @member CKEDITOR.editor
- */
-
-/**
- * Represents a data processor, which is responsible to translate and
- * transform the editor data on input and output.
- *
- * This class is here for documentation purposes only and is not really part of
- * the API. It serves as the base ("interface") for data processors implementation.
- *
- * @class CKEDITOR.dataProcessor
- * @abstract
- */
-
-/**
- * Transforms input data into HTML to be loaded in the editor.
- * While the editor is able to handle non HTML data (like BBCode), at runtime
- * it can handle HTML data only. The role of the data processor is transforming
- * the input data into HTML through this function.
- *
- *		// Tranforming BBCode data, having a custom BBCode data processor.
- *		var data = 'This is [b]an example[/b].';
- *		var html = editor.dataProcessor.toHtml( data ); // '<p>This is <b>an example</b>.</p>'
- *
- * @method toHtml
- * @param {String} data The input data to be transformed.
- * @param {String} [fixForBody] The tag name to be used if the data must be
- * fixed because it is supposed to be loaded direcly into the `<body>`
- * tag. This is generally not used by non-HTML data processors.
- * @todo fixForBody type - compare to htmlDataProcessor.
- */
-
-/**
- * Transforms HTML into data to be outputted by the editor, in the format
- * expected by the data processor.
- *
- * While the editor is able to handle non HTML data (like BBCode), at runtime
- * it can handle HTML data only. The role of the data processor is transforming
- * the HTML data containined by the editor into a specific data format through
- * this function.
- *
- *		// Tranforming into BBCode data, having a custom BBCode data processor.
- *		var html = '<p>This is <b>an example</b>.</p>';
- *		var data = editor.dataProcessor.toDataFormat( html ); // 'This is [b]an example[/b].'
- *
- * @method toDataFormat
- * @param {String} html The HTML to be transformed.
- * @param {String} fixForBody The tag name to be used if the output data is
- * coming from `<body>` and may be eventually fixed for it. This is
- * generally not used by non-HTML data processors.
- */

+ 0 - 13
htdocs/includes/ckeditor/ckeditor/_source/core/dom.js

@@ -1,13 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.dom} object, which contains DOM
- *		manipulation objects and function.
- */
-
-CKEDITOR.dom = {};
-
-// PACKAGER_RENAME( CKEDITOR.dom )

+ 0 - 53
htdocs/includes/ckeditor/ckeditor/_source/core/dom/comment.js

@@ -1,53 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.dom.comment} class, which represents
- *		a DOM comment node.
- */
-
-/**
- * Represents a DOM comment node.
- *
- *		var nativeNode = document.createComment( 'Example' );
- *		var comment = new CKEDITOR.dom.comment( nativeNode );
- *
- *		var comment = new CKEDITOR.dom.comment( 'Example' );
- *
- * @class
- * @extends CKEDITOR.dom.node
- * @constructor Creates a comment class instance.
- * @param {Object/String} comment A native DOM comment node or a string containing
- * the text to use to create a new comment node.
- * @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
- * the node in case of new node creation. Defaults to the current document.
- */
-CKEDITOR.dom.comment = function( comment, ownerDocument ) {
-	if ( typeof comment == 'string' )
-		comment = ( ownerDocument ? ownerDocument.$ : document ).createComment( comment );
-
-	CKEDITOR.dom.domObject.call( this, comment );
-};
-
-CKEDITOR.dom.comment.prototype = new CKEDITOR.dom.node();
-
-CKEDITOR.tools.extend( CKEDITOR.dom.comment.prototype, {
-	/**
-	 * The node type. This is a constant value set to {@link CKEDITOR#NODE_COMMENT}.
-	 *
-	 * @readonly
-	 * @property {Number} [=CKEDITOR.NODE_COMMENT]
-	 */
-	type: CKEDITOR.NODE_COMMENT,
-
-	/**
-	 * Gets the outer HTML of this comment.
-	 *
-	 * @returns {String} The HTML `<!-- comment value -->`.
-	 */
-	getOuterHtml: function() {
-		return '<!--' + this.$.nodeValue + '-->';
-	}
-} );

+ 0 - 316
htdocs/includes/ckeditor/ckeditor/_source/core/dom/document.js

@@ -1,316 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.dom.document} class, which
- *		represents a DOM document.
- */
-
-/**
- * Represents a DOM document.
- *
- *		var document = new CKEDITOR.dom.document( document );
- *
- * @class
- * @extends CKEDITOR.dom.domObject
- * @constructor Creates a document class instance.
- * @param {Object} domDocument A native DOM document.
- */
-CKEDITOR.dom.document = function( domDocument ) {
-	CKEDITOR.dom.domObject.call( this, domDocument );
-};
-
-// PACKAGER_RENAME( CKEDITOR.dom.document )
-
-CKEDITOR.dom.document.prototype = new CKEDITOR.dom.domObject();
-
-CKEDITOR.tools.extend( CKEDITOR.dom.document.prototype, {
-	/**
-	 * The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT}.
-	 *
-	 * @readonly
-	 * @property {Number} [=CKEDITOR.NODE_DOCUMENT]
-	 */
-	type: CKEDITOR.NODE_DOCUMENT,
-
-	/**
-	 * Appends a CSS file to the document.
-	 *
-	 *		CKEDITOR.document.appendStyleSheet( '/mystyles.css' );
-	 *
-	 * @param {String} cssFileUrl The CSS file URL.
-	 */
-	appendStyleSheet: function( cssFileUrl ) {
-		if ( this.$.createStyleSheet )
-			this.$.createStyleSheet( cssFileUrl );
-		else {
-			var link = new CKEDITOR.dom.element( 'link' );
-			link.setAttributes( {
-				rel: 'stylesheet',
-				type: 'text/css',
-				href: cssFileUrl
-			} );
-
-			this.getHead().append( link );
-		}
-	},
-
-	/**
-	 * Creates a CSS style sheet and inserts it into the document.
-	 *
-	 * @param cssStyleText {String} CSS style text.
-	 * @returns {Object} The created DOM native style sheet object.
-	 */
-	appendStyleText: function( cssStyleText ) {
-		if ( this.$.createStyleSheet ) {
-			var styleSheet = this.$.createStyleSheet( "" );
-			styleSheet.cssText = cssStyleText;
-		} else {
-			var style = new CKEDITOR.dom.element( 'style', this );
-			style.append( new CKEDITOR.dom.text( cssStyleText, this ) );
-			this.getHead().append( style );
-		}
-
-		return styleSheet || style.$.sheet;
-	},
-
-	/**
-	 * Creates {@link CKEDITOR.dom.element} instance in this document.
-	 *
-	 * @returns {CKEDITOR.dom.element}
-	 * @todo
-	 */
-	createElement: function( name, attribsAndStyles ) {
-		var element = new CKEDITOR.dom.element( name, this );
-
-		if ( attribsAndStyles ) {
-			if ( attribsAndStyles.attributes )
-				element.setAttributes( attribsAndStyles.attributes );
-
-			if ( attribsAndStyles.styles )
-				element.setStyles( attribsAndStyles.styles );
-		}
-
-		return element;
-	},
-
-	/**
-	 * Creates {@link CKEDITOR.dom.text} instance in this document.
-	 *
-	 * @param {String} text Value of the text node.
-	 * @returns {CKEDITOR.dom.element}
-	 */
-	createText: function( text ) {
-		return new CKEDITOR.dom.text( text, this );
-	},
-
-	/**
-	 * Moves the selection focus to this document's window.
-	 */
-	focus: function() {
-		this.getWindow().focus();
-	},
-
-	/**
-	 * Returns the element that is currently designated as the active element in the document.
-	 *
-	 * **Note:** Only one element can be active at a time in a document.
-	 * An active element does not necessarily have focus,
-	 * but an element with focus is always the active element in a document.
-	 *
-	 * @returns {CKEDITOR.dom.element}
-	 */
-	getActive: function() {
-		return new CKEDITOR.dom.element( this.$.activeElement );
-	},
-
-	/**
-	 * Gets an element based on its id.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myElement' );
-	 *		alert( element.getId() ); // 'myElement'
-	 *
-	 * @param {String} elementId The element id.
-	 * @returns {CKEDITOR.dom.element} The element instance, or null if not found.
-	 */
-	getById: function( elementId ) {
-		var $ = this.$.getElementById( elementId );
-		return $ ? new CKEDITOR.dom.element( $ ) : null;
-	},
-
-	/**
-	 * Gets a node based on its address. See {@link CKEDITOR.dom.node#getAddress}.
-	 *
-	 * @param {Array} address
-	 * @param {Boolean} [normalized=false]
-	 */
-	getByAddress: function( address, normalized ) {
-		var $ = this.$.documentElement;
-
-		for ( var i = 0; $ && i < address.length; i++ ) {
-			var target = address[ i ];
-
-			if ( !normalized ) {
-				$ = $.childNodes[ target ];
-				continue;
-			}
-
-			var currentIndex = -1;
-
-			for ( var j = 0; j < $.childNodes.length; j++ ) {
-				var candidate = $.childNodes[ j ];
-
-				if ( normalized === true && candidate.nodeType == 3 && candidate.previousSibling && candidate.previousSibling.nodeType == 3 )
-					continue;
-
-				currentIndex++;
-
-				if ( currentIndex == target ) {
-					$ = candidate;
-					break;
-				}
-			}
-		}
-
-		return $ ? new CKEDITOR.dom.node( $ ) : null;
-	},
-
-	/**
-	 * Gets elements list based on given tag name.
-	 *
-	 * @param {String} tagName The element tag name.
-	 * @returns {CKEDITOR.dom.nodeList} The nodes list.
-	 */
-	getElementsByTag: function( tagName, namespace ) {
-		if ( !( CKEDITOR.env.ie && !( document.documentMode > 8 ) ) && namespace )
-			tagName = namespace + ':' + tagName;
-		return new CKEDITOR.dom.nodeList( this.$.getElementsByTagName( tagName ) );
-	},
-
-	/**
-	 * Gets the `<head>` element for this document.
-	 *
-	 *		var element = CKEDITOR.document.getHead();
-	 *		alert( element.getName() ); // 'head'
-	 *
-	 * @returns {CKEDITOR.dom.element} The `<head>` element.
-	 */
-	getHead: function() {
-		var head = this.$.getElementsByTagName( 'head' )[ 0 ];
-		if ( !head )
-			head = this.getDocumentElement().append( new CKEDITOR.dom.element( 'head' ), true );
-		else
-			head = new CKEDITOR.dom.element( head );
-
-		return head;
-	},
-
-	/**
-	 * Gets the `<body>` element for this document.
-	 *
-	 *		var element = CKEDITOR.document.getBody();
-	 *		alert( element.getName() ); // 'body'
-	 *
-	 * @returns {CKEDITOR.dom.element} The `<body>` element.
-	 */
-	getBody: function() {
-		return new CKEDITOR.dom.element( this.$.body );
-	},
-
-	/**
-	 * Gets the DOM document element for this document.
-	 *
-	 * @returns {CKEDITOR.dom.element} The DOM document element.
-	 */
-	getDocumentElement: function() {
-		return new CKEDITOR.dom.element( this.$.documentElement );
-	},
-
-	/**
-	 * Gets the window object that holds this document.
-	 *
-	 * @returns {CKEDITOR.dom.window} The window object.
-	 */
-	getWindow: function() {
-		return new CKEDITOR.dom.window( this.$.parentWindow || this.$.defaultView );
-	},
-
-	/**
-	 * Defines the document contents through document.write. Note that the
-	 * previous document contents will be lost (cleaned).
-	 *
-	 *		document.write(
-	 *			'<html>' +
-	 *				'<head><title>Sample Doc</title></head>' +
-	 *				'<body>Document contents created by code</body>' +
-	 *			'</html>'
-	 *		);
-	 *
-	 * @since 3.5
-	 * @param {String} html The HTML defining the document contents.
-	 */
-	write: function( html ) {
-		// Don't leave any history log in IE. (#5657)
-		this.$.open( 'text/html', 'replace' );
-
-		// Support for custom document.domain in IE.
-		//
-		// The script must be appended because if placed before the
-		// doctype, IE will go into quirks mode and mess with
-		// the editable, e.g. by changing its default height.
-		if ( CKEDITOR.env.ie )
-			html = html.replace( /(?:^\s*<!DOCTYPE[^>]*?>)|^/i, '$&\n<script data-cke-temp="1">(' + CKEDITOR.tools.fixDomain + ')();</script>' );
-
-		this.$.write( html );
-		this.$.close();
-	},
-
-	/**
-	 * Wrapper for `querySelectorAll`. Returns a list of elements within this document that match
-	 * specified `selector`.
-	 *
-	 * **Note:** returned list is not a live collection (like a result of native `querySelectorAll`).
-	 *
-	 * @since 4.3
-	 * @param {String} selector
-	 * @returns {CKEDITOR.dom.nodeList}
-	 */
-	find: function( selector ) {
-		return new CKEDITOR.dom.nodeList( this.$.querySelectorAll( selector ) );
-	},
-
-	/**
-	 * Wrapper for `querySelector`. Returns first element within this document that matches
-	 * specified `selector`.
-	 *
-	 * @since 4.3
-	 * @param {String} selector
-	 * @returns {CKEDITOR.dom.element}
-	 */
-	findOne: function( selector ) {
-		var el = this.$.querySelector( selector );
-
-		return el ? new CKEDITOR.dom.element( el ) : null;
-	},
-
-	/**
-	 * IE8 only method. It returns document fragment which has all HTML5 elements enabled.
-	 *
-	 * @since 4.3
-	 * @private
-	 * @returns DocumentFragment
-	 */
-	_getHtml5ShivFrag: function() {
-		var $frag = this.getCustomData( 'html5ShivFrag' );
-
-		if ( !$frag ) {
-			$frag = this.$.createDocumentFragment();
-			CKEDITOR.tools.enableHtml5Elements( $frag, true );
-			this.setCustomData( 'html5ShivFrag', $frag );
-		}
-
-		return $frag;
-	}
-} );

+ 0 - 45
htdocs/includes/ckeditor/ckeditor/_source/core/dom/documentfragment.js

@@ -1,45 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * DocumentFragment is a "lightweight" or "minimal" Document object. It is
- * commonly used to extract a portion of a document's tree or to create a new
- * fragment of a document. Various operations may take DocumentFragment objects
- * as arguments and results in all the child nodes of the DocumentFragment being
- * moved to the child list of this node.
- *
- * @class
- * @constructor Creates a document fragment class instance.
- * @param {Object} nodeOrDoc
- * @todo example and param doc
- */
-CKEDITOR.dom.documentFragment = function( nodeOrDoc ) {
-	nodeOrDoc = nodeOrDoc || CKEDITOR.document;
-
-	if ( nodeOrDoc.type == CKEDITOR.NODE_DOCUMENT )
-		this.$ = nodeOrDoc.$.createDocumentFragment();
-	else
-		this.$ = nodeOrDoc;
-};
-
-CKEDITOR.tools.extend( CKEDITOR.dom.documentFragment.prototype, CKEDITOR.dom.element.prototype, {
-	/**
-	 * The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
-	 *
-	 * @readonly
-	 * @property {Number} [=CKEDITOR.NODE_DOCUMENT_FRAGMENT]
-	 */
-	type: CKEDITOR.NODE_DOCUMENT_FRAGMENT,
-
-	/**
-	 * Inserts document fragment's contents after specified node.
-	 *
-	 * @param {CKEDITOR.dom.node} node
-	 */
-	insertAfterNode: function( node ) {
-		node = node.$;
-		node.parentNode.insertBefore( this.$, node.nextSibling );
-	}
-}, true, { 'append': 1, 'appendBogus': 1, 'getFirst': 1, 'getLast': 1, 'getParent': 1, 'getNext': 1, 'getPrevious': 1, 'appendTo': 1, 'moveChildren': 1, 'insertBefore': 1, 'insertAfterNode': 1, 'replace': 1, 'trim': 1, 'type': 1, 'ltrim': 1, 'rtrim': 1, 'getDocument': 1, 'getChildCount': 1, 'getChild': 1, 'getChildren': 1 } );

+ 0 - 262
htdocs/includes/ckeditor/ckeditor/_source/core/dom/domobject.js

@@ -1,262 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.editor} class, which is the base
- *		for other classes representing DOM objects.
- */
-
-/**
- * Represents a DOM object. This class is not intended to be used directly. It
- * serves as the base class for other classes representing specific DOM
- * objects.
- *
- * @class
- * @mixins CKEDITOR.event
- * @constructor Creates a domObject class instance.
- * @param {Object} nativeDomObject A native DOM object.
- */
-CKEDITOR.dom.domObject = function( nativeDomObject ) {
-	if ( nativeDomObject ) {
-		/**
-		 * The native DOM object represented by this class instance.
-		 *
-		 *		var element = new CKEDITOR.dom.element( 'span' );
-		 *		alert( element.$.nodeType ); // '1'
-		 *
-		 * @readonly
-		 * @property {Object}
-		 */
-		this.$ = nativeDomObject;
-	}
-};
-
-CKEDITOR.dom.domObject.prototype = ( function() {
-	// Do not define other local variables here. We want to keep the native
-	// listener closures as clean as possible.
-
-	var getNativeListener = function( domObject, eventName ) {
-			return function( domEvent ) {
-				// In FF, when reloading the page with the editor focused, it may
-				// throw an error because the CKEDITOR global is not anymore
-				// available. So, we check it here first. (#2923)
-				if ( typeof CKEDITOR != 'undefined' )
-					domObject.fire( eventName, new CKEDITOR.dom.event( domEvent ) );
-			};
-		};
-
-	return {
-
-		/**
-		 * Get the private `_` object which is bound to the native
-		 * DOM object using {@link #getCustomData}.
-		 *
-		 *		var elementA = new CKEDITOR.dom.element( nativeElement );
-		 *		elementA.getPrivate().value = 1;
-		 *		...
-		 *		var elementB = new CKEDITOR.dom.element( nativeElement );
-		 *		elementB.getPrivate().value; // 1
-		 *
-		 * @returns {Object} The private object.
-		 */
-		getPrivate: function() {
-			var priv;
-
-			// Get the main private object from the custom data. Create it if not defined.
-			if ( !( priv = this.getCustomData( '_' ) ) )
-				this.setCustomData( '_', ( priv = {} ) );
-
-			return priv;
-		},
-
-		// Docs inherited from event.
-		on: function( eventName ) {
-			// We customize the "on" function here. The basic idea is that we'll have
-			// only one listener for a native event, which will then call all listeners
-			// set to the event.
-
-			// Get the listeners holder object.
-			var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
-
-			if ( !nativeListeners ) {
-				nativeListeners = {};
-				this.setCustomData( '_cke_nativeListeners', nativeListeners );
-			}
-
-			// Check if we have a listener for that event.
-			if ( !nativeListeners[ eventName ] ) {
-				var listener = nativeListeners[ eventName ] = getNativeListener( this, eventName );
-
-				if ( this.$.addEventListener )
-					this.$.addEventListener( eventName, listener, !!CKEDITOR.event.useCapture );
-				else if ( this.$.attachEvent )
-					this.$.attachEvent( 'on' + eventName, listener );
-			}
-
-			// Call the original implementation.
-			return CKEDITOR.event.prototype.on.apply( this, arguments );
-		},
-
-		// Docs inherited from event.
-		removeListener: function( eventName ) {
-			// Call the original implementation.
-			CKEDITOR.event.prototype.removeListener.apply( this, arguments );
-
-			// If we don't have listeners for this event, clean the DOM up.
-			if ( !this.hasListeners( eventName ) ) {
-				var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
-				var listener = nativeListeners && nativeListeners[ eventName ];
-				if ( listener ) {
-					if ( this.$.removeEventListener )
-						this.$.removeEventListener( eventName, listener, false );
-					else if ( this.$.detachEvent )
-						this.$.detachEvent( 'on' + eventName, listener );
-
-					delete nativeListeners[ eventName ];
-				}
-			}
-		},
-
-		/**
-		 * Removes any listener set on this object.
-		 *
-		 * To avoid memory leaks we must assure that there are no
-		 * references left after the object is no longer needed.
-		 */
-		removeAllListeners: function() {
-			var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
-			for ( var eventName in nativeListeners ) {
-				var listener = nativeListeners[ eventName ];
-				if ( this.$.detachEvent )
-					this.$.detachEvent( 'on' + eventName, listener );
-				else if ( this.$.removeEventListener )
-					this.$.removeEventListener( eventName, listener, false );
-
-				delete nativeListeners[ eventName ];
-			}
-
-			// Remove events from events object so fire() method will not call
-			// listeners (#11400).
-			CKEDITOR.event.prototype.removeAllListeners.call( this );
-		}
-	};
-} )();
-
-( function( domObjectProto ) {
-	var customData = {};
-
-	CKEDITOR.on( 'reset', function() {
-		customData = {};
-	} );
-
-	/**
-	 * Determines whether the specified object is equal to the current object.
-	 *
-	 *		var doc = new CKEDITOR.dom.document( document );
-	 *		alert( doc.equals( CKEDITOR.document ) );	// true
-	 *		alert( doc == CKEDITOR.document );			// false
-	 *
-	 * @param {Object} object The object to compare with the current object.
-	 * @returns {Boolean} `true` if the object is equal.
-	 */
-	domObjectProto.equals = function( object ) {
-		// Try/Catch to avoid IE permission error when object is from different document.
-		try {
-			return ( object && object.$ === this.$ );
-		} catch ( er ) {
-			return false;
-		}
-	};
-
-	/**
-	 * Sets a data slot value for this object. These values are shared by all
-	 * instances pointing to that same DOM object.
-	 *
-	 * **Note:** The created data slot is only guarantied to be available on this unique dom node,
-	 * thus any wish to continue access it from other element clones (either created by
-	 * clone node or from `innerHtml`) will fail, for such usage, please use
-	 * {@link CKEDITOR.dom.element#setAttribute} instead.
-	 *
-	 *		var element = new CKEDITOR.dom.element( 'span' );
-	 *		element.setCustomData( 'hasCustomData', true );
-	 *
-	 * @param {String} key A key used to identify the data slot.
-	 * @param {Object} value The value to set to the data slot.
-	 * @returns {CKEDITOR.dom.domObject} This DOM object instance.
-	 * @chainable
-	 */
-	domObjectProto.setCustomData = function( key, value ) {
-		var expandoNumber = this.getUniqueId(),
-			dataSlot = customData[ expandoNumber ] || ( customData[ expandoNumber ] = {} );
-
-		dataSlot[ key ] = value;
-
-		return this;
-	};
-
-	/**
-	 * Gets the value set to a data slot in this object.
-	 *
-	 *		var element = new CKEDITOR.dom.element( 'span' );
-	 *		alert( element.getCustomData( 'hasCustomData' ) );		// e.g. 'true'
-	 *		alert( element.getCustomData( 'nonExistingKey' ) );		// null
-	 *
-	 * @param {String} key The key used to identify the data slot.
-	 * @returns {Object} This value set to the data slot.
-	 */
-	domObjectProto.getCustomData = function( key ) {
-		var expandoNumber = this.$[ 'data-cke-expando' ],
-			dataSlot = expandoNumber && customData[ expandoNumber ];
-
-		return ( dataSlot && key in dataSlot ) ? dataSlot[ key ] : null;
-	};
-
-	/**
-	 * Removes the value in data slot under given `key`.
-	 *
-	 * @param {String} key
-	 * @returns {Object} Removed value or `null` if not found.
-	 */
-	domObjectProto.removeCustomData = function( key ) {
-		var expandoNumber = this.$[ 'data-cke-expando' ],
-			dataSlot = expandoNumber && customData[ expandoNumber ],
-			retval, hadKey;
-
-		if ( dataSlot ) {
-			retval = dataSlot[ key ];
-			hadKey = key in dataSlot;
-			delete dataSlot[ key ];
-		}
-
-		return hadKey ? retval : null;
-	};
-
-	/**
-	 * Removes any data stored on this object.
-	 * To avoid memory leaks we must assure that there are no
-	 * references left after the object is no longer needed.
-	 */
-	domObjectProto.clearCustomData = function() {
-		// Clear all event listeners
-		this.removeAllListeners();
-
-		var expandoNumber = this.$[ 'data-cke-expando' ];
-		expandoNumber && delete customData[ expandoNumber ];
-	};
-
-	/**
-	 * Gets an ID that can be used to identiquely identify this DOM object in
-	 * the running session.
-	 *
-	 * @returns {Number} A unique ID.
-	 */
-	domObjectProto.getUniqueId = function() {
-		return this.$[ 'data-cke-expando' ] || ( this.$[ 'data-cke-expando' ] = CKEDITOR.tools.getNextNumber() );
-	};
-
-	// Implement CKEDITOR.event.
-	CKEDITOR.event.implementOn( domObjectProto );
-
-} )( CKEDITOR.dom.domObject.prototype );

+ 0 - 2007
htdocs/includes/ckeditor/ckeditor/_source/core/dom/element.js

@@ -1,2007 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.dom.element} class, which
- *		represents a DOM element.
- */
-
-/**
- * Represents a DOM element.
- *
- *		// Create a new <span> element.
- *		var element = new CKEDITOR.dom.element( 'span' );
- *
- *		// Create an element based on a native DOM element.
- *		var element = new CKEDITOR.dom.element( document.getElementById( 'myId' ) );
- *
- * @class
- * @extends CKEDITOR.dom.node
- * @constructor Creates an element class instance.
- * @param {Object/String} element A native DOM element or the element name for
- * new elements.
- * @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
- * the element in case of element creation.
- */
-CKEDITOR.dom.element = function( element, ownerDocument ) {
-	if ( typeof element == 'string' )
-		element = ( ownerDocument ? ownerDocument.$ : document ).createElement( element );
-
-	// Call the base constructor (we must not call CKEDITOR.dom.node).
-	CKEDITOR.dom.domObject.call( this, element );
-};
-
-// PACKAGER_RENAME( CKEDITOR.dom.element )
-/**
- * The the {@link CKEDITOR.dom.element} representing and element. If the
- * element is a native DOM element, it will be transformed into a valid
- * CKEDITOR.dom.element object.
- *
- *		var element = new CKEDITOR.dom.element( 'span' );
- *		alert( element == CKEDITOR.dom.element.get( element ) ); // true
- *
- *		var element = document.getElementById( 'myElement' );
- *		alert( CKEDITOR.dom.element.get( element ).getName() ); // (e.g.) 'p'
- *
- * @static
- * @param {String/Object} element Element's id or name or native DOM element.
- * @returns {CKEDITOR.dom.element} The transformed element.
- */
-CKEDITOR.dom.element.get = function( element ) {
-	var el = typeof element == 'string' ? document.getElementById( element ) || document.getElementsByName( element )[ 0 ] : element;
-
-	return el && ( el.$ ? el : new CKEDITOR.dom.element( el ) );
-};
-
-CKEDITOR.dom.element.prototype = new CKEDITOR.dom.node();
-
-/**
- * Creates an instance of the {@link CKEDITOR.dom.element} class based on the
- * HTML representation of an element.
- *
- *		var element = CKEDITOR.dom.element.createFromHtml( '<strong class="anyclass">My element</strong>' );
- *		alert( element.getName() ); // 'strong'
- *
- * @static
- * @param {String} html The element HTML. It should define only one element in
- * the "root" level. The "root" element can have child nodes, but not siblings.
- * @returns {CKEDITOR.dom.element} The element instance.
- */
-CKEDITOR.dom.element.createFromHtml = function( html, ownerDocument ) {
-	var temp = new CKEDITOR.dom.element( 'div', ownerDocument );
-	temp.setHtml( html );
-
-	// When returning the node, remove it from its parent to detach it.
-	return temp.getFirst().remove();
-};
-
-/**
- * @static
- * @todo
- */
-CKEDITOR.dom.element.setMarker = function( database, element, name, value ) {
-	var id = element.getCustomData( 'list_marker_id' ) || ( element.setCustomData( 'list_marker_id', CKEDITOR.tools.getNextNumber() ).getCustomData( 'list_marker_id' ) ),
-		markerNames = element.getCustomData( 'list_marker_names' ) || ( element.setCustomData( 'list_marker_names', {} ).getCustomData( 'list_marker_names' ) );
-	database[ id ] = element;
-	markerNames[ name ] = 1;
-
-	return element.setCustomData( name, value );
-};
-
-/**
- * @static
- * @todo
- */
-CKEDITOR.dom.element.clearAllMarkers = function( database ) {
-	for ( var i in database )
-		CKEDITOR.dom.element.clearMarkers( database, database[ i ], 1 );
-};
-
-/**
- * @static
- * @todo
- */
-CKEDITOR.dom.element.clearMarkers = function( database, element, removeFromDatabase ) {
-	var names = element.getCustomData( 'list_marker_names' ),
-		id = element.getCustomData( 'list_marker_id' );
-	for ( var i in names )
-		element.removeCustomData( i );
-	element.removeCustomData( 'list_marker_names' );
-	if ( removeFromDatabase ) {
-		element.removeCustomData( 'list_marker_id' );
-		delete database[ id ];
-	}
-};
-( function() {
-
-CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype, {
-	/**
-	 * The node type. This is a constant value set to {@link CKEDITOR#NODE_ELEMENT}.
-	 *
-	 * @readonly
-	 * @property {Number} [=CKEDITOR.NODE_ELEMENT]
-	 */
-	type: CKEDITOR.NODE_ELEMENT,
-
-	/**
-	 * Adds a CSS class to the element. It appends the class to the
-	 * already existing names.
-	 *
-	 *		var element = new CKEDITOR.dom.element( 'div' );
-	 *		element.addClass( 'classA' ); // <div class="classA">
-	 *		element.addClass( 'classB' ); // <div class="classA classB">
-	 *		element.addClass( 'classA' ); // <div class="classA classB">
-	 *
-	 * @param {String} className The name of the class to be added.
-	 */
-	addClass: function( className ) {
-		var c = this.$.className;
-		if ( c ) {
-			var regex = new RegExp( '(?:^|\\s)' + className + '(?:\\s|$)', '' );
-			if ( !regex.test( c ) )
-				c += ' ' + className;
-		}
-		this.$.className = c || className;
-	},
-
-	/**
-	 * Removes a CSS class name from the elements classes. Other classes
-	 * remain untouched.
-	 *
-	 *		var element = new CKEDITOR.dom.element( 'div' );
-	 *		element.addClass( 'classA' );		// <div class="classA">
-	 *		element.addClass( 'classB' );		// <div class="classA classB">
-	 *		element.removeClass( 'classA' );	// <div class="classB">
-	 *		element.removeClass( 'classB' );	// <div>
-	 *
-	 * @chainable
-	 * @param {String} className The name of the class to remove.
-	 */
-	removeClass: function( className ) {
-		var c = this.getAttribute( 'class' );
-		if ( c ) {
-			var regex = new RegExp( '(?:^|\\s+)' + className + '(?=\\s|$)', 'i' );
-			if ( regex.test( c ) ) {
-				c = c.replace( regex, '' ).replace( /^\s+/, '' );
-
-				if ( c )
-					this.setAttribute( 'class', c );
-				else
-					this.removeAttribute( 'class' );
-			}
-		}
-
-		return this;
-	},
-
-	/**
-	 * Checks if element has class name.
-	 *
-	 * @param {String} className
-	 * @returns {Boolean}
-	 */
-	hasClass: function( className ) {
-		var regex = new RegExp( '(?:^|\\s+)' + className + '(?=\\s|$)', '' );
-		return regex.test( this.getAttribute( 'class' ) );
-	},
-
-	/**
-	 * Append a node as a child of this element.
-	 *
-	 *		var p = new CKEDITOR.dom.element( 'p' );
-	 *
-	 *		var strong = new CKEDITOR.dom.element( 'strong' );
-	 *		p.append( strong );
-	 *
-	 *		var em = p.append( 'em' );
-	 *
-	 *		// Result: '<p><strong></strong><em></em></p>'
-	 *
-	 * @param {CKEDITOR.dom.node/String} node The node or element name to be appended.
-	 * @param {Boolean} [toStart=false] Indicates that the element is to be appended at the start.
-	 * @returns {CKEDITOR.dom.node} The appended node.
-	 */
-	append: function( node, toStart ) {
-		if ( typeof node == 'string' )
-			node = this.getDocument().createElement( node );
-
-		if ( toStart )
-			this.$.insertBefore( node.$, this.$.firstChild );
-		else
-			this.$.appendChild( node.$ );
-
-		return node;
-	},
-
-	/**
-	 * Append HTML as a child(ren) of this element.
-	 *
-	 * @param {String} html
-	 */
-	appendHtml: function( html ) {
-		if ( !this.$.childNodes.length )
-			this.setHtml( html );
-		else {
-			var temp = new CKEDITOR.dom.element( 'div', this.getDocument() );
-			temp.setHtml( html );
-			temp.moveChildren( this );
-		}
-	},
-
-	/**
-	 * Append text to this element.
-	 *
-	 *		var p = new CKEDITOR.dom.element( 'p' );
-	 *		p.appendText( 'This is' );
-	 *		p.appendText( ' some text' );
-	 *
-	 *		// Result: '<p>This is some text</p>'
-	 *
-	 * @param {String} text The text to be appended.
-	 * @returns {CKEDITOR.dom.node} The appended node.
-	 */
-	appendText: function( text ) {
-		if ( this.$.text != undefined )
-			this.$.text += text;
-		else
-			this.append( new CKEDITOR.dom.text( text ) );
-	},
-
-	/**
-	 * Appends a `<br>` filler element to this element if the filler is not present already.
-	 * By default filler is appended only if {@link CKEDITOR.env#needsBrFiller} is `true`,
-	 * however when `force` is set to `true` filler will be appended regardless of the environment.
-	 *
-	 * @param {Boolean} [force] Append filler regardless of the environment.
-	 */
-	appendBogus: function( force ) {
-		if ( !force && !( CKEDITOR.env.needsBrFiller || CKEDITOR.env.opera ) )
-			return;
-
-		var lastChild = this.getLast();
-
-		// Ignore empty/spaces text.
-		while ( lastChild && lastChild.type == CKEDITOR.NODE_TEXT && !CKEDITOR.tools.rtrim( lastChild.getText() ) )
-			lastChild = lastChild.getPrevious();
-		if ( !lastChild || !lastChild.is || !lastChild.is( 'br' ) ) {
-			var bogus = CKEDITOR.env.opera ? this.getDocument().createText( '' ) : this.getDocument().createElement( 'br' );
-
-			CKEDITOR.env.gecko && bogus.setAttribute( 'type', '_moz' );
-
-			this.append( bogus );
-		}
-	},
-
-	/**
-	 * Breaks one of the ancestor element in the element position, moving
-	 * this element between the broken parts.
-	 *
-	 *		// Before breaking:
-	 *		//		<b>This <i>is some<span /> sample</i> test text</b>
-	 *		// If "element" is <span /> and "parent" is <i>:
-	 *		//		<b>This <i>is some</i><span /><i> sample</i> test text</b>
-	 *		element.breakParent( parent );
-	 *
-	 *		// Before breaking:
-	 *		//		<b>This <i>is some<span /> sample</i> test text</b>
-	 *		// If "element" is <span /> and "parent" is <b>:
-	 *		//		<b>This <i>is some</i></b><span /><b><i> sample</i> test text</b>
-	 *		element.breakParent( parent );
-	 *
-	 * @param {CKEDITOR.dom.element} parent The anscestor element to get broken.
-	 */
-	breakParent: function( parent ) {
-		var range = new CKEDITOR.dom.range( this.getDocument() );
-
-		// We'll be extracting part of this element, so let's use our
-		// range to get the correct piece.
-		range.setStartAfter( this );
-		range.setEndAfter( parent );
-
-		// Extract it.
-		var docFrag = range.extractContents();
-
-		// Move the element outside the broken element.
-		range.insertNode( this.remove() );
-
-		// Re-insert the extracted piece after the element.
-		docFrag.insertAfterNode( this );
-	},
-
-	/**
-	 * Checks if this element contains given node.
-	 *
-	 * @method
-	 * @param {CKEDITOR.dom.node} node
-	 * @returns {Boolean}
-	 */
-	contains: CKEDITOR.env.ie || CKEDITOR.env.webkit ?
-		function( node ) {
-			var $ = this.$;
-
-			return node.type != CKEDITOR.NODE_ELEMENT ? $.contains( node.getParent().$ ) : $ != node.$ && $.contains( node.$ );
-		} : function( node ) {
-			return !!( this.$.compareDocumentPosition( node.$ ) & 16 );
-		},
-
-	/**
-	 * Moves the selection focus to this element.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myTextarea' );
-	 *		element.focus();
-	 *
-	 * @method
-	 * @param  {Boolean} defer Whether to asynchronously defer the
-	 * execution by 100 ms.
-	 */
-	focus: ( function() {
-		function exec() {
-			// IE throws error if the element is not visible.
-			try {
-				this.$.focus();
-			} catch ( e ) {}
-		}
-
-		return function( defer ) {
-			if ( defer )
-				CKEDITOR.tools.setTimeout( exec, 100, this );
-			else
-				exec.call( this );
-		};
-	} )(),
-
-	/**
-	 * Gets the inner HTML of this element.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b></div>' );
-	 *		alert( element.getHtml() ); // '<b>Example</b>'
-	 *
-	 * @returns {String} The inner HTML of this element.
-	 */
-	getHtml: function() {
-		var retval = this.$.innerHTML;
-		// Strip <?xml:namespace> tags in IE. (#3341).
-		return CKEDITOR.env.ie ? retval.replace( /<\?[^>]*>/g, '' ) : retval;
-	},
-
-	/**
-	 * Gets the outer (inner plus tags) HTML of this element.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<div class="bold"><b>Example</b></div>' );
-	 *		alert( element.getOuterHtml() ); // '<div class="bold"><b>Example</b></div>'
-	 *
-	 * @returns {String} The outer HTML of this element.
-	 */
-	getOuterHtml: function() {
-		if ( this.$.outerHTML ) {
-			// IE includes the <?xml:namespace> tag in the outerHTML of
-			// namespaced element. So, we must strip it here. (#3341)
-			return this.$.outerHTML.replace( /<\?[^>]*>/, '' );
-		}
-
-		var tmpDiv = this.$.ownerDocument.createElement( 'div' );
-		tmpDiv.appendChild( this.$.cloneNode( true ) );
-		return tmpDiv.innerHTML;
-	},
-
-	/**
-	 * Retrieve the bounding rectangle of the current element, in pixels,
-	 * relative to the upper-left corner of the browser's client area.
-	 *
-	 * @returns {Object} The dimensions of the DOM element including
-	 * `left`, `top`, `right`, `bottom`, `width` and `height`.
-	 */
-	getClientRect: function() {
-		// http://help.dottoro.com/ljvmcrrn.php
-		var rect = CKEDITOR.tools.extend( {}, this.$.getBoundingClientRect() );
-
-		!rect.width && ( rect.width = rect.right - rect.left );
-		!rect.height && ( rect.height = rect.bottom - rect.top );
-
-		return rect;
-	},
-
-	/**
-	 * Sets the inner HTML of this element.
-	 *
-	 *		var p = new CKEDITOR.dom.element( 'p' );
-	 *		p.setHtml( '<b>Inner</b> HTML' );
-	 *
-	 *		// Result: '<p><b>Inner</b> HTML</p>'
-	 *
-	 * @method
-	 * @param {String} html The HTML to be set for this element.
-	 * @returns {String} The inserted HTML.
-	 */
-	setHtml: ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) ?
-			// old IEs throws error on HTML manipulation (through the "innerHTML" property)
-			// on the element which resides in an DTD invalid position,  e.g. <span><div></div></span>
-			// fortunately it can be worked around with DOM manipulation.
-			function( html ) {
-				try {
-					var $ = this.$;
-
-					// Fix the case when setHtml is called on detached element.
-					// HTML5 shiv used for document in which this element was created
-					// won't affect that detached element. So get document fragment with
-					// all HTML5 elements enabled and set innerHTML while this element is appended to it.
-					if ( this.getParent() )
-						return ( $.innerHTML = html );
-					else {
-						var $frag = this.getDocument()._getHtml5ShivFrag();
-						$frag.appendChild( $ );
-						$.innerHTML = html;
-						$frag.removeChild( $ );
-
-						return html;
-					}
-				}
-				catch ( e ) {
-					this.$.innerHTML = '';
-
-					var temp = new CKEDITOR.dom.element( 'body', this.getDocument() );
-					temp.$.innerHTML = html;
-
-					var children = temp.getChildren();
-					while ( children.count() )
-						this.append( children.getItem( 0 ) );
-
-					return html;
-				}
-			}
-		:
-			function( html ) {
-				return ( this.$.innerHTML = html );
-			},
-
-	/**
-	 * Sets the element contents as plain text.
-	 *
-	 *		var element = new CKEDITOR.dom.element( 'div' );
-	 *		element.setText( 'A > B & C < D' );
-	 *		alert( element.innerHTML ); // 'A &gt; B &amp; C &lt; D'
-	 *
-	 * @param {String} text The text to be set.
-	 * @returns {String} The inserted text.
-	 */
-	setText: function( text ) {
-		CKEDITOR.dom.element.prototype.setText = ( this.$.innerText != undefined ) ?
-			function( text ) {
-				return this.$.innerText = text;
-			} : function( text ) {
-				return this.$.textContent = text;
-			};
-
-		return this.setText( text );
-	},
-
-	/**
-	 * Gets the value of an element attribute.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<input type="text" />' );
-	 *		alert( element.getAttribute( 'type' ) ); // 'text'
-	 *
-	 * @method
-	 * @param {String} name The attribute name.
-	 * @returns {String} The attribute value or null if not defined.
-	 */
-	getAttribute: ( function() {
-		var standard = function( name ) {
-				return this.$.getAttribute( name, 2 );
-			};
-
-		if ( CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) ) {
-			return function( name ) {
-				switch ( name ) {
-					case 'class':
-						name = 'className';
-						break;
-
-					case 'http-equiv':
-						name = 'httpEquiv';
-						break;
-
-					case 'name':
-						return this.$.name;
-
-					case 'tabindex':
-						var tabIndex = standard.call( this, name );
-
-						// IE returns tabIndex=0 by default for all
-						// elements. For those elements,
-						// getAtrribute( 'tabindex', 2 ) returns 32768
-						// instead. So, we must make this check to give a
-						// uniform result among all browsers.
-						if ( tabIndex !== 0 && this.$.tabIndex === 0 )
-							tabIndex = null;
-
-						return tabIndex;
-						break;
-
-					case 'checked':
-						{
-							var attr = this.$.attributes.getNamedItem( name ),
-								attrValue = attr.specified ? attr.nodeValue // For value given by parser.
-								: this.$.checked; // For value created via DOM interface.
-
-							return attrValue ? 'checked' : null;
-						}
-
-					case 'hspace':
-					case 'value':
-						return this.$[ name ];
-
-					case 'style':
-						// IE does not return inline styles via getAttribute(). See #2947.
-						return this.$.style.cssText;
-
-					case 'contenteditable':
-					case 'contentEditable':
-						return this.$.attributes.getNamedItem( 'contentEditable' ).specified ? this.$.getAttribute( 'contentEditable' ) : null;
-				}
-
-				return standard.call( this, name );
-			};
-		} else
-			return standard;
-	} )(),
-
-	/**
-	 * Gets the nodes list containing all children of this element.
-	 *
-	 * @returns {CKEDITOR.dom.nodeList}
-	 */
-	getChildren: function() {
-		return new CKEDITOR.dom.nodeList( this.$.childNodes );
-	},
-
-	/**
-	 * Gets the current computed value of one of the element CSS style
-	 * properties.
-	 *
-	 *		var element = new CKEDITOR.dom.element( 'span' );
-	 *		alert( element.getComputedStyle( 'display' ) ); // 'inline'
-	 *
-	 * @method
-	 * @param {String} propertyName The style property name.
-	 * @returns {String} The property value.
-	 */
-	getComputedStyle: CKEDITOR.env.ie ?
-		function( propertyName ) {
-			return this.$.currentStyle[ CKEDITOR.tools.cssStyleToDomStyle( propertyName ) ];
-		} : function( propertyName ) {
-			var style = this.getWindow().$.getComputedStyle( this.$, null );
-			// Firefox may return null if we call the above on a hidden iframe. (#9117)
-			return style ? style.getPropertyValue( propertyName ) : '';
-		},
-
-	/**
-	 * Gets the DTD entries for this element.
-	 *
-	 * @returns {Object} An object containing the list of elements accepted
-	 * by this element.
-	 */
-	getDtd: function() {
-		var dtd = CKEDITOR.dtd[ this.getName() ];
-
-		this.getDtd = function() {
-			return dtd;
-		};
-
-		return dtd;
-	},
-
-	/**
-	 * Gets all this element's descendants having given tag name.
-	 *
-	 * @method
-	 * @param {String} tagName
-	 */
-	getElementsByTag: CKEDITOR.dom.document.prototype.getElementsByTag,
-
-	/**
-	 * Gets the computed tabindex for this element.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myDiv' );
-	 *		alert( element.getTabIndex() ); // (e.g.) '-1'
-	 *
-	 * @method
-	 * @returns {Number} The tabindex value.
-	 */
-	getTabIndex: CKEDITOR.env.ie ?
-		function() {
-			var tabIndex = this.$.tabIndex;
-
-			// IE returns tabIndex=0 by default for all elements. In
-			// those cases we must check that the element really has
-			// the tabindex attribute set to zero, or it is one of
-			// those element that should have zero by default.
-			if ( tabIndex === 0 && !CKEDITOR.dtd.$tabIndex[ this.getName() ] && parseInt( this.getAttribute( 'tabindex' ), 10 ) !== 0 )
-				tabIndex = -1;
-
-			return tabIndex;
-		} : CKEDITOR.env.webkit ?
-		function() {
-			var tabIndex = this.$.tabIndex;
-
-			// Safari returns "undefined" for elements that should not
-			// have tabindex (like a div). So, we must try to get it
-			// from the attribute.
-			// https://bugs.webkit.org/show_bug.cgi?id=20596
-			if ( tabIndex == undefined ) {
-				tabIndex = parseInt( this.getAttribute( 'tabindex' ), 10 );
-
-				// If the element don't have the tabindex attribute,
-				// then we should return -1.
-				if ( isNaN( tabIndex ) )
-					tabIndex = -1;
-			}
-
-			return tabIndex;
-		} : function() {
-			return this.$.tabIndex;
-		},
-
-	/**
-	 * Gets the text value of this element.
-	 *
-	 * Only in IE (which uses innerText), `<br>` will cause linebreaks,
-	 * and sucessive whitespaces (including line breaks) will be reduced to
-	 * a single space. This behavior is ok for us, for now. It may change
-	 * in the future.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<div>Sample <i>text</i>.</div>' );
-	 *		alert( <b>element.getText()</b> ); // 'Sample text.'
-	 *
-	 * @returns {String} The text value.
-	 */
-	getText: function() {
-		return this.$.textContent || this.$.innerText || '';
-	},
-
-	/**
-	 * Gets the window object that contains this element.
-	 *
-	 * @returns {CKEDITOR.dom.window} The window object.
-	 */
-	getWindow: function() {
-		return this.getDocument().getWindow();
-	},
-
-	/**
-	 * Gets the value of the `id` attribute of this element.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<p id="myId"></p>' );
-	 *		alert( element.getId() ); // 'myId'
-	 *
-	 * @returns {String} The element id, or null if not available.
-	 */
-	getId: function() {
-		return this.$.id || null;
-	},
-
-	/**
-	 * Gets the value of the `name` attribute of this element.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<input name="myName"></input>' );
-	 *		alert( <b>element.getNameAtt()</b> ); // 'myName'
-	 *
-	 * @returns {String} The element name, or null if not available.
-	 */
-	getNameAtt: function() {
-		return this.$.name || null;
-	},
-
-	/**
-	 * Gets the element name (tag name). The returned name is guaranteed to
-	 * be always full lowercased.
-	 *
-	 *		var element = new CKEDITOR.dom.element( 'span' );
-	 *		alert( element.getName() ); // 'span'
-	 *
-	 * @returns {String} The element name.
-	 */
-	getName: function() {
-		// Cache the lowercased name inside a closure.
-		var nodeName = this.$.nodeName.toLowerCase();
-
-		if ( CKEDITOR.env.ie && !( document.documentMode > 8 ) ) {
-			var scopeName = this.$.scopeName;
-			if ( scopeName != 'HTML' )
-				nodeName = scopeName.toLowerCase() + ':' + nodeName;
-		}
-
-		return ( this.getName = function() {
-			return nodeName;
-		} )();
-	},
-
-	/**
-	 * Gets the value set to this element. This value is usually available
-	 * for form field elements.
-	 *
-	 * @returns {String} The element value.
-	 */
-	getValue: function() {
-		return this.$.value;
-	},
-
-	/**
-	 * Gets the first child node of this element.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b></div>' );
-	 *		var first = element.getFirst();
-	 *		alert( first.getName() ); // 'b'
-	 *
-	 * @param {Function} evaluator Filtering the result node.
-	 * @returns {CKEDITOR.dom.node} The first child node or null if not available.
-	 */
-	getFirst: function( evaluator ) {
-		var first = this.$.firstChild,
-			retval = first && new CKEDITOR.dom.node( first );
-		if ( retval && evaluator && !evaluator( retval ) )
-			retval = retval.getNext( evaluator );
-
-		return retval;
-	},
-
-	/**
-	 * See {@link #getFirst}.
-	 *
-	 * @param {Function} evaluator Filtering the result node.
-	 * @returns {CKEDITOR.dom.node}
-	 */
-	getLast: function( evaluator ) {
-		var last = this.$.lastChild,
-			retval = last && new CKEDITOR.dom.node( last );
-		if ( retval && evaluator && !evaluator( retval ) )
-			retval = retval.getPrevious( evaluator );
-
-		return retval;
-	},
-
-	/**
-	 * Gets CSS style value.
-	 *
-	 * @param {String} name The CSS property name.
-	 * @returns {String} Style value.
-	 */
-	getStyle: function( name ) {
-		return this.$.style[ CKEDITOR.tools.cssStyleToDomStyle( name ) ];
-	},
-
-	/**
-	 * Checks if the element name matches the specified criteria.
-	 *
-	 *		var element = new CKEDITOR.element( 'span' );
-	 *		alert( element.is( 'span' ) );			// true
-	 *		alert( element.is( 'p', 'span' ) );		// true
-	 *		alert( element.is( 'p' ) );				// false
-	 *		alert( element.is( 'p', 'div' ) );		// false
-	 *		alert( element.is( { p:1,span:1 } ) );	// true
-	 *
-	 * @param {String.../Object} name One or more names to be checked, or a {@link CKEDITOR.dtd} object.
-	 * @returns {Boolean} `true` if the element name matches any of the names.
-	 */
-	is: function() {
-		var name = this.getName();
-
-		// Check against the specified DTD liternal.
-		if ( typeof arguments[ 0 ] == 'object' )
-			return !!arguments[ 0 ][ name ];
-
-		// Check for tag names
-		for ( var i = 0; i < arguments.length; i++ ) {
-			if ( arguments[ i ] == name )
-				return true;
-		}
-		return false;
-	},
-
-	/**
-	 * Decide whether one element is able to receive cursor.
-	 *
-	 * @param {Boolean} [textCursor=true] Only consider element that could receive text child.
-	 */
-	isEditable: function( textCursor ) {
-		var name = this.getName();
-
-		if ( this.isReadOnly() || this.getComputedStyle( 'display' ) == 'none' ||
-				 this.getComputedStyle( 'visibility' ) == 'hidden' ||
-				 CKEDITOR.dtd.$nonEditable[ name ] ||
-				 CKEDITOR.dtd.$empty[ name ] ||
-				 ( this.is( 'a' ) &&
-					 ( this.data( 'cke-saved-name' ) || this.hasAttribute( 'name' ) ) &&
-					 !this.getChildCount()
-				 ) )
-		{
-			return false;
-		}
-
-		if ( textCursor !== false ) {
-			// Get the element DTD (defaults to span for unknown elements).
-			var dtd = CKEDITOR.dtd[ name ] || CKEDITOR.dtd.span;
-			// In the DTD # == text node.
-			return !!( dtd && dtd[ '#' ] );
-		}
-
-		return true;
-	},
-
-	/**
-	 * Compare this element's inner html, tag name, attributes, etc. with other one.
-	 *
-	 * See [W3C's DOM Level 3 spec - node#isEqualNode](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isEqualNode)
-	 * for more details.
-	 *
-	 * @param {CKEDITOR.dom.element} otherElement Element to compare.
-	 * @returns {Boolean}
-	 */
-	isIdentical: function( otherElement ) {
-		// do shallow clones, but with IDs
-		var thisEl = this.clone( 0, 1 ),
-			otherEl = otherElement.clone( 0, 1 );
-
-		// Remove distractions.
-		thisEl.removeAttributes( [ '_moz_dirty', 'data-cke-expando', 'data-cke-saved-href', 'data-cke-saved-name' ] );
-		otherEl.removeAttributes( [ '_moz_dirty', 'data-cke-expando', 'data-cke-saved-href', 'data-cke-saved-name' ] );
-
-		// Native comparison available.
-		if ( thisEl.$.isEqualNode ) {
-			// Styles order matters.
-			thisEl.$.style.cssText = CKEDITOR.tools.normalizeCssText( thisEl.$.style.cssText );
-			otherEl.$.style.cssText = CKEDITOR.tools.normalizeCssText( otherEl.$.style.cssText );
-			return thisEl.$.isEqualNode( otherEl.$ );
-		} else {
-			thisEl = thisEl.getOuterHtml();
-			otherEl = otherEl.getOuterHtml();
-
-			// Fix tiny difference between link href in older IEs.
-			if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 && this.is( 'a' ) ) {
-				var parent = this.getParent();
-				if ( parent.type == CKEDITOR.NODE_ELEMENT ) {
-					var el = parent.clone();
-					el.setHtml( thisEl ), thisEl = el.getHtml();
-					el.setHtml( otherEl ), otherEl = el.getHtml();
-				}
-			}
-
-			return thisEl == otherEl;
-		}
-	},
-
-	/**
-	 * Checks if this element is visible. May not work if the element is
-	 * child of an element with visibility set to `hidden`, but works well
-	 * on the great majority of cases.
-	 *
-	 * @returns {Boolean} True if the element is visible.
-	 */
-	isVisible: function() {
-		var isVisible = ( this.$.offsetHeight || this.$.offsetWidth ) && this.getComputedStyle( 'visibility' ) != 'hidden',
-			elementWindow, elementWindowFrame;
-
-		// Webkit and Opera report non-zero offsetHeight despite that
-		// element is inside an invisible iframe. (#4542)
-		if ( isVisible && ( CKEDITOR.env.webkit || CKEDITOR.env.opera ) ) {
-			elementWindow = this.getWindow();
-
-			if ( !elementWindow.equals( CKEDITOR.document.getWindow() ) && ( elementWindowFrame = elementWindow.$.frameElement ) )
-				isVisible = new CKEDITOR.dom.element( elementWindowFrame ).isVisible();
-
-		}
-
-		return !!isVisible;
-	},
-
-	/**
-	 * Whether it's an empty inline elements which has no visual impact when removed.
-	 *
-	 * @returns {Boolean}
-	 */
-	isEmptyInlineRemoveable: function() {
-		if ( !CKEDITOR.dtd.$removeEmpty[ this.getName() ] )
-			return false;
-
-		var children = this.getChildren();
-		for ( var i = 0, count = children.count(); i < count; i++ ) {
-			var child = children.getItem( i );
-
-			if ( child.type == CKEDITOR.NODE_ELEMENT && child.data( 'cke-bookmark' ) )
-				continue;
-
-			if ( child.type == CKEDITOR.NODE_ELEMENT && !child.isEmptyInlineRemoveable() || child.type == CKEDITOR.NODE_TEXT && CKEDITOR.tools.trim( child.getText() ) )
-				return false;
-
-		}
-		return true;
-	},
-
-	/**
-	 * Checks if the element has any defined attributes.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<div title="Test">Example</div>' );
-	 *		alert( element.hasAttributes() ); // true
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<div>Example</div>' );
-	 *		alert( element.hasAttributes() ); // false
-	 *
-	 * @method
-	 * @returns {Boolean} True if the element has attributes.
-	 */
-	hasAttributes: CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) ?
-		function() {
-			var attributes = this.$.attributes;
-
-			for ( var i = 0; i < attributes.length; i++ ) {
-				var attribute = attributes[ i ];
-
-				switch ( attribute.nodeName ) {
-					case 'class':
-						// IE has a strange bug. If calling removeAttribute('className'),
-						// the attributes collection will still contain the "class"
-						// attribute, which will be marked as "specified", even if the
-						// outerHTML of the element is not displaying the class attribute.
-						// Note : I was not able to reproduce it outside the editor,
-						// but I've faced it while working on the TC of #1391.
-						if ( this.getAttribute( 'class' ) )
-							return true;
-
-						// Attributes to be ignored.
-					case 'data-cke-expando':
-						continue;
-
-						/*jsl:fallthru*/
-
-					default:
-						if ( attribute.specified )
-							return true;
-				}
-			}
-
-			return false;
-		} : function() {
-			var attrs = this.$.attributes,
-				attrsNum = attrs.length;
-
-			// The _moz_dirty attribute might get into the element after pasting (#5455)
-			var execludeAttrs = { 'data-cke-expando': 1, _moz_dirty: 1 };
-
-			return attrsNum > 0 && ( attrsNum > 2 || !execludeAttrs[ attrs[ 0 ].nodeName ] || ( attrsNum == 2 && !execludeAttrs[ attrs[ 1 ].nodeName ] ) );
-		},
-
-	/**
-	 * Checks if the specified attribute is defined for this element.
-	 *
-	 * @method
-	 * @param {String} name The attribute name.
-	 * @returns {Boolean} `true` if the specified attribute is defined.
-	 */
-	hasAttribute: ( function() {
-		function standard( name ) {
-			var $attr = this.$.attributes.getNamedItem( name );
-			return !!( $attr && $attr.specified );
-		}
-
-		return ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) ?
-		function( name ) {
-			// On IE < 8 the name attribute cannot be retrieved
-			// right after the element creation and setting the
-			// name with setAttribute.
-			if ( name == 'name' )
-				return !!this.$.name;
-
-			return standard.call( this, name );
-		} : standard;
-	} )(),
-
-	/**
-	 * Hides this element (sets `display: none`).
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myElement' );
-	 *		element.hide();
-	 */
-	hide: function() {
-		this.setStyle( 'display', 'none' );
-	},
-
-	/**
-	 * Moves this element's children to the target element.
-	 *
-	 * @param {CKEDITOR.dom.element} target
-	 * @param {Boolean} [toStart=false] Insert moved children at the
-	 * beginning of the target element.
-	 */
-	moveChildren: function( target, toStart ) {
-		var $ = this.$;
-		target = target.$;
-
-		if ( $ == target )
-			return;
-
-		var child;
-
-		if ( toStart ) {
-			while ( ( child = $.lastChild ) )
-				target.insertBefore( $.removeChild( child ), target.firstChild );
-		} else {
-			while ( ( child = $.firstChild ) )
-				target.appendChild( $.removeChild( child ) );
-		}
-	},
-
-	/**
-	 * Merges sibling elements that are identical to this one.
-	 *
-	 * Identical child elements are also merged. For example:
-	 *
-	 *		<b><i></i></b><b><i></i></b> => <b><i></i></b>
-	 *
-	 * @method
-	 * @param {Boolean} [inlineOnly=true] Allow only inline elements to be merged.
-	 */
-	mergeSiblings: ( function() {
-		function mergeElements( element, sibling, isNext ) {
-			if ( sibling && sibling.type == CKEDITOR.NODE_ELEMENT ) {
-				// Jumping over bookmark nodes and empty inline elements, e.g. <b><i></i></b>,
-				// queuing them to be moved later. (#5567)
-				var pendingNodes = [];
-
-				while ( sibling.data( 'cke-bookmark' ) || sibling.isEmptyInlineRemoveable() ) {
-					pendingNodes.push( sibling );
-					sibling = isNext ? sibling.getNext() : sibling.getPrevious();
-					if ( !sibling || sibling.type != CKEDITOR.NODE_ELEMENT )
-						return;
-				}
-
-				if ( element.isIdentical( sibling ) ) {
-					// Save the last child to be checked too, to merge things like
-					// <b><i></i></b><b><i></i></b> => <b><i></i></b>
-					var innerSibling = isNext ? element.getLast() : element.getFirst();
-
-					// Move pending nodes first into the target element.
-					while ( pendingNodes.length )
-						pendingNodes.shift().move( element, !isNext );
-
-					sibling.moveChildren( element, !isNext );
-					sibling.remove();
-
-					// Now check the last inner child (see two comments above).
-					if ( innerSibling && innerSibling.type == CKEDITOR.NODE_ELEMENT )
-						innerSibling.mergeSiblings();
-				}
-			}
-		}
-
-		return function( inlineOnly ) {
-			if ( !( inlineOnly === false || CKEDITOR.dtd.$removeEmpty[ this.getName() ] || this.is( 'a' ) ) ) // Merge empty links and anchors also. (#5567)
-			{
-				return;
-			}
-
-			mergeElements( this, this.getNext(), true );
-			mergeElements( this, this.getPrevious() );
-		};
-	} )(),
-
-	/**
-	 * Shows this element (displays it).
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myElement' );
-	 *		element.show();
-	 */
-	show: function() {
-		this.setStyles( {
-			display: '',
-			visibility: ''
-		} );
-	},
-
-	/**
-	 * Sets the value of an element attribute.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myElement' );
-	 *		element.setAttribute( 'class', 'myClass' );
-	 *		element.setAttribute( 'title', 'This is an example' );
-	 *
-	 * @method
-	 * @param {String} name The name of the attribute.
-	 * @param {String} value The value to be set to the attribute.
-	 * @returns {CKEDITOR.dom.element} This element instance.
-	 */
-	setAttribute: ( function() {
-		var standard = function( name, value ) {
-				this.$.setAttribute( name, value );
-				return this;
-			};
-
-		if ( CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) ) {
-			return function( name, value ) {
-				if ( name == 'class' )
-					this.$.className = value;
-				else if ( name == 'style' )
-					this.$.style.cssText = value;
-				else if ( name == 'tabindex' ) // Case sensitive.
-				this.$.tabIndex = value;
-				else if ( name == 'checked' )
-					this.$.checked = value;
-				else if ( name == 'contenteditable' )
-					standard.call( this, 'contentEditable', value );
-				else
-					standard.apply( this, arguments );
-				return this;
-			};
-		} else if ( CKEDITOR.env.ie8Compat && CKEDITOR.env.secure ) {
-			return function( name, value ) {
-				// IE8 throws error when setting src attribute to non-ssl value. (#7847)
-				if ( name == 'src' && value.match( /^http:\/\// ) )
-					try {
-					standard.apply( this, arguments );
-				} catch ( e ) {} else
-					standard.apply( this, arguments );
-				return this;
-			};
-		} else
-			return standard;
-	} )(),
-
-	/**
-	 * Sets the value of several element attributes.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myElement' );
-	 *		element.setAttributes( {
-	 *			'class':	'myClass',
-	 *			title:		'This is an example'
-	 *		} );
-	 *
-	 * @chainable
-	 * @param {Object} attributesPairs An object containing the names and
-	 * values of the attributes.
-	 * @returns {CKEDITOR.dom.element} This element instance.
-	 */
-	setAttributes: function( attributesPairs ) {
-		for ( var name in attributesPairs )
-			this.setAttribute( name, attributesPairs[ name ] );
-		return this;
-	},
-
-	/**
-	 * Sets the element value. This function is usually used with form
-	 * field element.
-	 *
-	 * @chainable
-	 * @param {String} value The element value.
-	 * @returns {CKEDITOR.dom.element} This element instance.
-	 */
-	setValue: function( value ) {
-		this.$.value = value;
-		return this;
-	},
-
-	/**
-	 * Removes an attribute from the element.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<div class="classA"></div>' );
-	 *		element.removeAttribute( 'class' );
-	 *
-	 * @method
-	 * @param {String} name The attribute name.
-	 */
-	removeAttribute: ( function() {
-		var standard = function( name ) {
-				this.$.removeAttribute( name );
-			};
-
-		if ( CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) ) {
-			return function( name ) {
-				if ( name == 'class' )
-					name = 'className';
-				else if ( name == 'tabindex' )
-					name = 'tabIndex';
-				else if ( name == 'contenteditable' )
-					name = 'contentEditable';
-				standard.call( this, name );
-			};
-		} else
-			return standard;
-	} )(),
-
-	/**
-	 * Removes all element's attributes or just given ones.
-	 *
-	 * @param {Array} [attributes] The array with attributes names.
-	 */
-	removeAttributes: function( attributes ) {
-		if ( CKEDITOR.tools.isArray( attributes ) ) {
-			for ( var i = 0; i < attributes.length; i++ )
-				this.removeAttribute( attributes[ i ] );
-		} else {
-			for ( var attr in attributes )
-				attributes.hasOwnProperty( attr ) && this.removeAttribute( attr );
-		}
-	},
-
-	/**
-	 * Removes a style from the element.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<div style="display:none"></div>' );
-	 *		element.removeStyle( 'display' );
-	 *
-	 * @method
-	 * @param {String} name The style name.
-	 */
-	removeStyle: function( name ) {
-		// Removes the specified property from the current style object.
-		var $ = this.$.style;
-
-		// "removeProperty" need to be specific on the following styles.
-		if ( !$.removeProperty && ( name == 'border' || name == 'margin' || name == 'padding' ) ) {
-			var names = expandedRules( name );
-			for ( var i = 0 ; i < names.length ; i++ )
-				this.removeStyle( names[ i ] );
-			return;
-		}
-
-		$.removeProperty ? $.removeProperty( name ) : $.removeAttribute( CKEDITOR.tools.cssStyleToDomStyle( name ) );
-
-		// Eventually remove empty style attribute.
-		if ( !this.$.style.cssText )
-			this.removeAttribute( 'style' );
-	},
-
-	/**
-	 * Sets the value of an element style.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myElement' );
-	 *		element.setStyle( 'background-color', '#ff0000' );
-	 *		element.setStyle( 'margin-top', '10px' );
-	 *		element.setStyle( 'float', 'right' );
-	 *
-	 * @param {String} name The name of the style. The CSS naming notation
-	 * must be used (e.g. `background-color`).
-	 * @param {String} value The value to be set to the style.
-	 * @returns {CKEDITOR.dom.element} This element instance.
-	 */
-	setStyle: function( name, value ) {
-		this.$.style[ CKEDITOR.tools.cssStyleToDomStyle( name ) ] = value;
-		return this;
-	},
-
-	/**
-	 * Sets the value of several element styles.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myElement' );
-	 *		element.setStyles( {
-	 *			position:	'absolute',
-	 *			float:		'right'
-	 *		} );
-	 *
-	 * @param {Object} stylesPairs An object containing the names and
-	 * values of the styles.
-	 * @returns {CKEDITOR.dom.element} This element instance.
-	 */
-	setStyles: function( stylesPairs ) {
-		for ( var name in stylesPairs )
-			this.setStyle( name, stylesPairs[ name ] );
-		return this;
-	},
-
-	/**
-	 * Sets the opacity of an element.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myElement' );
-	 *		element.setOpacity( 0.75 );
-	 *
-	 * @param {Number} opacity A number within the range `[0.0, 1.0]`.
-	 */
-	setOpacity: function( opacity ) {
-		if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) {
-			opacity = Math.round( opacity * 100 );
-			this.setStyle( 'filter', opacity >= 100 ? '' : 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + opacity + ')' );
-		} else
-			this.setStyle( 'opacity', opacity );
-	},
-
-	/**
-	 * Makes the element and its children unselectable.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myElement' );
-	 *		element.unselectable();
-	 *
-	 * @method
-	 */
-	unselectable: function() {
-		// CSS unselectable.
-		this.setStyles( CKEDITOR.tools.cssVendorPrefix( 'user-select', 'none' ) );
-
-		// For IE/Opera which doesn't support for the above CSS style,
-		// the unselectable="on" attribute only specifies the selection
-		// process cannot start in the element itself, and it doesn't inherit.
-		if ( CKEDITOR.env.ie || CKEDITOR.env.opera ) {
-			this.setAttribute( 'unselectable', 'on' );
-
-			var element,
-				elements = this.getElementsByTag( "*" );
-
-			for ( var i = 0, count = elements.count() ; i < count ; i++ ) {
-				element = elements.getItem( i );
-				element.setAttribute( 'unselectable', 'on' );
-			}
-		}
-	},
-
-	/**
-	 * Gets closest positioned (`position != static`) ancestor.
-	 *
-	 * @returns {CKEDITOR.dom.element} Positioned ancestor or `null`.
-	 */
-	getPositionedAncestor: function() {
-		var current = this;
-		while ( current.getName() != 'html' ) {
-			if ( current.getComputedStyle( 'position' ) != 'static' )
-				return current;
-
-			current = current.getParent();
-		}
-		return null;
-	},
-
-	/**
-	 * Gets this element's position in document.
-	 *
-	 * @param {CKEDITOR.dom.document} [refDocument]
-	 * @returns {Object} Element's position.
-	 * @returns {Number} return.x
-	 * @returns {Number} return.y
-	 * @todo refDocument
-	 */
-	getDocumentPosition: function( refDocument ) {
-		var x = 0,
-			y = 0,
-			doc = this.getDocument(),
-			body = doc.getBody(),
-			quirks = doc.$.compatMode == 'BackCompat';
-
-		if ( document.documentElement[ "getBoundingClientRect" ] ) {
-			var box = this.$.getBoundingClientRect(),
-				$doc = doc.$,
-				$docElem = $doc.documentElement;
-
-			var clientTop = $docElem.clientTop || body.$.clientTop || 0,
-				clientLeft = $docElem.clientLeft || body.$.clientLeft || 0,
-				needAdjustScrollAndBorders = true;
-
-			// #3804: getBoundingClientRect() works differently on IE and non-IE
-			// browsers, regarding scroll positions.
-			//
-			// On IE, the top position of the <html> element is always 0, no matter
-			// how much you scrolled down.
-			//
-			// On other browsers, the top position of the <html> element is negative
-			// scrollTop.
-			if ( CKEDITOR.env.ie ) {
-				var inDocElem = doc.getDocumentElement().contains( this ),
-					inBody = doc.getBody().contains( this );
-
-				needAdjustScrollAndBorders = ( quirks && inBody ) || ( !quirks && inDocElem );
-			}
-
-			if ( needAdjustScrollAndBorders ) {
-				x = box.left + ( !quirks && $docElem.scrollLeft || body.$.scrollLeft );
-				x -= clientLeft;
-				y = box.top + ( !quirks && $docElem.scrollTop || body.$.scrollTop );
-				y -= clientTop;
-			}
-		} else {
-			var current = this,
-				previous = null,
-				offsetParent;
-			while ( current && !( current.getName() == 'body' || current.getName() == 'html' ) ) {
-				x += current.$.offsetLeft - current.$.scrollLeft;
-				y += current.$.offsetTop - current.$.scrollTop;
-
-				// Opera includes clientTop|Left into offsetTop|Left.
-				if ( !current.equals( this ) ) {
-					x += ( current.$.clientLeft || 0 );
-					y += ( current.$.clientTop || 0 );
-				}
-
-				var scrollElement = previous;
-				while ( scrollElement && !scrollElement.equals( current ) ) {
-					x -= scrollElement.$.scrollLeft;
-					y -= scrollElement.$.scrollTop;
-					scrollElement = scrollElement.getParent();
-				}
-
-				previous = current;
-				current = ( offsetParent = current.$.offsetParent ) ? new CKEDITOR.dom.element( offsetParent ) : null;
-			}
-		}
-
-		if ( refDocument ) {
-			var currentWindow = this.getWindow(),
-				refWindow = refDocument.getWindow();
-
-			if ( !currentWindow.equals( refWindow ) && currentWindow.$.frameElement ) {
-				var iframePosition = ( new CKEDITOR.dom.element( currentWindow.$.frameElement ) ).getDocumentPosition( refDocument );
-
-				x += iframePosition.x;
-				y += iframePosition.y;
-			}
-		}
-
-		if ( !document.documentElement[ "getBoundingClientRect" ] ) {
-			// In Firefox, we'll endup one pixel before the element positions,
-			// so we must add it here.
-			if ( CKEDITOR.env.gecko && !quirks ) {
-				x += this.$.clientLeft ? 1 : 0;
-				y += this.$.clientTop ? 1 : 0;
-			}
-		}
-
-		return { x: x, y: y };
-	},
-
-	/**
-	 * Make any page element visible inside the browser viewport.
-	 *
-	 * @param {Boolean} [alignToTop=false]
-	 */
-	scrollIntoView: function( alignToTop ) {
-		var parent = this.getParent();
-		if ( !parent )
-			return;
-
-		// Scroll the element into parent container from the inner out.
-		do {
-			// Check ancestors that overflows.
-			var overflowed =
-				parent.$.clientWidth && parent.$.clientWidth < parent.$.scrollWidth ||
-				parent.$.clientHeight && parent.$.clientHeight < parent.$.scrollHeight;
-
-			// Skip body element, which will report wrong clientHeight when containing
-			// floated content. (#9523)
-			if ( overflowed && !parent.is( 'body' ) )
-				this.scrollIntoParent( parent, alignToTop, 1 );
-
-			// Walk across the frame.
-			if ( parent.is( 'html' ) ) {
-				var win = parent.getWindow();
-
-				// Avoid security error.
-				try {
-					var iframe = win.$.frameElement;
-					iframe && ( parent = new CKEDITOR.dom.element( iframe ) );
-				} catch ( er ) {}
-			}
-		}
-		while ( ( parent = parent.getParent() ) );
-	},
-
-	/**
-	 * Make any page element visible inside one of the ancestors by scrolling the parent.
-	 *
-	 * @param {CKEDITOR.dom.element/CKEDITOR.dom.window} parent The container to scroll into.
-	 * @param {Boolean} [alignToTop] Align the element's top side with the container's
-	 * when `true` is specified; align the bottom with viewport bottom when
-	 * `false` is specified. Otherwise scroll on either side with the minimum
-	 * amount to show the element.
-	 * @param {Boolean} [hscroll] Whether horizontal overflow should be considered.
-	 */
-	scrollIntoParent: function( parent, alignToTop, hscroll ) {
-		!parent && ( parent = this.getWindow() );
-
-		var doc = parent.getDocument();
-		var isQuirks = doc.$.compatMode == 'BackCompat';
-
-		// On window <html> is scrolled while quirks scrolls <body>.
-		if ( parent instanceof CKEDITOR.dom.window )
-			parent = isQuirks ? doc.getBody() : doc.getDocumentElement();
-
-		// Scroll the parent by the specified amount.
-		function scrollBy( x, y ) {
-			// Webkit doesn't support "scrollTop/scrollLeft"
-			// on documentElement/body element.
-			if ( /body|html/.test( parent.getName() ) )
-				parent.getWindow().$.scrollBy( x, y );
-			else {
-				parent.$[ 'scrollLeft' ] += x;
-				parent.$[ 'scrollTop' ] += y;
-			}
-		}
-
-		// Figure out the element position relative to the specified window.
-		function screenPos( element, refWin ) {
-			var pos = { x: 0, y: 0 };
-
-			if ( !( element.is( isQuirks ? 'body' : 'html' ) ) ) {
-				var box = element.$.getBoundingClientRect();
-				pos.x = box.left, pos.y = box.top;
-			}
-
-			var win = element.getWindow();
-			if ( !win.equals( refWin ) ) {
-				var outerPos = screenPos( CKEDITOR.dom.element.get( win.$.frameElement ), refWin );
-				pos.x += outerPos.x, pos.y += outerPos.y;
-			}
-
-			return pos;
-		}
-
-		// calculated margin size.
-		function margin( element, side ) {
-			return parseInt( element.getComputedStyle( 'margin-' + side ) || 0, 10 ) || 0;
-		}
-
-		var win = parent.getWindow();
-
-		var thisPos = screenPos( this, win ),
-			parentPos = screenPos( parent, win ),
-			eh = this.$.offsetHeight,
-			ew = this.$.offsetWidth,
-			ch = parent.$.clientHeight,
-			cw = parent.$.clientWidth,
-			lt, br;
-
-		// Left-top margins.
-		lt = {
-			x: thisPos.x - margin( this, 'left' ) - parentPos.x || 0,
-			y: thisPos.y - margin( this, 'top' ) - parentPos.y || 0
-		};
-
-		// Bottom-right margins.
-		br = {
-			x: thisPos.x + ew + margin( this, 'right' ) - ( ( parentPos.x ) + cw ) || 0,
-			y: thisPos.y + eh + margin( this, 'bottom' ) - ( ( parentPos.y ) + ch ) || 0
-		};
-
-		// 1. Do the specified alignment as much as possible;
-		// 2. Otherwise be smart to scroll only the minimum amount;
-		// 3. Never cut at the top;
-		// 4. DO NOT scroll when already visible.
-		if ( lt.y < 0 || br.y > 0 )
-			scrollBy( 0, alignToTop === true ? lt.y : alignToTop === false ? br.y : lt.y < 0 ? lt.y : br.y );
-
-		if ( hscroll && ( lt.x < 0 || br.x > 0 ) )
-			scrollBy( lt.x < 0 ? lt.x : br.x, 0 );
-	},
-
-	/**
-	 * Switch the `class` attribute to reflect one of the triple states of an
-	 * element in one of {@link CKEDITOR#TRISTATE_ON}, {@link CKEDITOR#TRISTATE_OFF}
-	 * or {@link CKEDITOR#TRISTATE_DISABLED}.
-	 *
-	 *		link.setState( CKEDITOR.TRISTATE_ON );
-	 *		// <a class="cke_on" aria-pressed="true">...</a>
-	 *		link.setState( CKEDITOR.TRISTATE_OFF );
-	 *		// <a class="cke_off">...</a>
-	 *		link.setState( CKEDITOR.TRISTATE_DISABLED );
-	 *		// <a class="cke_disabled" aria-disabled="true">...</a>
-	 *
-	 *		span.setState( CKEDITOR.TRISTATE_ON, 'cke_button' );
-	 *		// <span class="cke_button_on">...</span>
-	 *
-	 * @param {Number} state Indicate the element state. One of {@link CKEDITOR#TRISTATE_ON},
-	 * {@link CKEDITOR#TRISTATE_OFF}, {@link CKEDITOR#TRISTATE_DISABLED}.
-	 * @param [base='cke'] The prefix apply to each of the state class name.
-	 * @param [useAria=true] Whether toggle the ARIA state attributes besides of class name change.
-	 */
-	setState: function( state, base, useAria ) {
-		base = base || 'cke';
-
-		switch ( state ) {
-			case CKEDITOR.TRISTATE_ON:
-				this.addClass( base + '_on' );
-				this.removeClass( base + '_off' );
-				this.removeClass( base + '_disabled' );
-				useAria && this.setAttribute( 'aria-pressed', true );
-				useAria && this.removeAttribute( 'aria-disabled' );
-				break;
-
-			case CKEDITOR.TRISTATE_DISABLED:
-				this.addClass( base + '_disabled' );
-				this.removeClass( base + '_off' );
-				this.removeClass( base + '_on' );
-				useAria && this.setAttribute( 'aria-disabled', true );
-				useAria && this.removeAttribute( 'aria-pressed' );
-				break;
-
-			default:
-				this.addClass( base + '_off' );
-				this.removeClass( base + '_on' );
-				this.removeClass( base + '_disabled' );
-				useAria && this.removeAttribute( 'aria-pressed' );
-				useAria && this.removeAttribute( 'aria-disabled' );
-				break;
-		}
-	},
-
-	/**
-	 * Returns the inner document of this `<iframe>` element.
-	 *
-	 * @returns {CKEDITOR.dom.document} The inner document.
-	 */
-	getFrameDocument: function() {
-		var $ = this.$;
-
-		try {
-			// In IE, with custom document.domain, it may happen that
-			// the iframe is not yet available, resulting in "Access
-			// Denied" for the following property access.
-			$.contentWindow.document;
-		} catch ( e ) {
-			// Trick to solve this issue, forcing the iframe to get ready
-			// by simply setting its "src" property.
-			$.src = $.src;
-		}
-
-		return $ && new CKEDITOR.dom.document( $.contentWindow.document );
-	},
-
-	/**
-	 * Copy all the attributes from one node to the other, kinda like a clone
-	 * skipAttributes is an object with the attributes that must **not** be copied.
-	 *
-	 * @param {CKEDITOR.dom.element} dest The destination element.
-	 * @param {Object} skipAttributes A dictionary of attributes to skip.
-	 */
-	copyAttributes: function( dest, skipAttributes ) {
-		var attributes = this.$.attributes;
-		skipAttributes = skipAttributes || {};
-
-		for ( var n = 0; n < attributes.length; n++ ) {
-			var attribute = attributes[ n ];
-
-			// Lowercase attribute name hard rule is broken for
-			// some attribute on IE, e.g. CHECKED.
-			var attrName = attribute.nodeName.toLowerCase(),
-				attrValue;
-
-			// We can set the type only once, so do it with the proper value, not copying it.
-			if ( attrName in skipAttributes )
-				continue;
-
-			if ( attrName == 'checked' && ( attrValue = this.getAttribute( attrName ) ) )
-				dest.setAttribute( attrName, attrValue );
-			// IE BUG: value attribute is never specified even if it exists.
-			else if ( attribute.specified || ( CKEDITOR.env.ie && attribute.nodeValue && attrName == 'value' ) ) {
-				attrValue = this.getAttribute( attrName );
-				if ( attrValue === null )
-					attrValue = attribute.nodeValue;
-
-				dest.setAttribute( attrName, attrValue );
-			}
-		}
-
-		// The style:
-		if ( this.$.style.cssText !== '' )
-			dest.$.style.cssText = this.$.style.cssText;
-	},
-
-	/**
-	 * Changes the tag name of the current element.
-	 *
-	 * @param {String} newTag The new tag for the element.
-	 */
-	renameNode: function( newTag ) {
-		// If it's already correct exit here.
-		if ( this.getName() == newTag )
-			return;
-
-		var doc = this.getDocument();
-
-		// Create the new node.
-		var newNode = new CKEDITOR.dom.element( newTag, doc );
-
-		// Copy all attributes.
-		this.copyAttributes( newNode );
-
-		// Move children to the new node.
-		this.moveChildren( newNode );
-
-		// Replace the node.
-		this.getParent() && this.$.parentNode.replaceChild( newNode.$, this.$ );
-		newNode.$[ 'data-cke-expando' ] = this.$[ 'data-cke-expando' ];
-		this.$ = newNode.$;
-	},
-
-	/**
-	 * Gets a DOM tree descendant under the current node.
-	 *
-	 *		var strong = p.getChild( 0 );
-	 *
-	 * @method
-	 * @param {Array/Number} indices The child index or array of child indices under the node.
-	 * @returns {CKEDITOR.dom.node} The specified DOM child under the current node. Null if child does not exist.
-	 */
-	getChild: ( function() {
-		function getChild( rawNode, index ) {
-			var childNodes = rawNode.childNodes;
-
-			if ( index >= 0 && index < childNodes.length )
-				return childNodes[ index ];
-		}
-
-		return function( indices ) {
-			var rawNode = this.$;
-
-			if ( !indices.slice )
-				rawNode = getChild( rawNode, indices );
-			else {
-				while ( indices.length > 0 && rawNode )
-					rawNode = getChild( rawNode, indices.shift() );
-			}
-
-			return rawNode ? new CKEDITOR.dom.node( rawNode ) : null;
-		};
-	} )(),
-
-	/**
-	 * Gets number of element's children.
-	 *
-	 * @returns {Number}
-	 */
-	getChildCount: function() {
-		return this.$.childNodes.length;
-	},
-
-	/**
-	 * Disables browser's context menu in this element.
-	 */
-	disableContextMenu: function() {
-		this.on( 'contextmenu', function( event ) {
-			// Cancel the browser context menu.
-			if ( !event.data.getTarget().hasClass( 'cke_enable_context_menu' ) )
-				event.data.preventDefault();
-		} );
-	},
-
-	/**
-	 * Gets element's direction. Supports both CSS `direction` prop and `dir` attr.
-	 */
-	getDirection: function( useComputed ) {
-		if ( useComputed ) {
-			return this.getComputedStyle( 'direction' ) ||
-					this.getDirection() ||
-					this.getParent() && this.getParent().getDirection( 1 ) ||
-					this.getDocument().$.dir ||
-					'ltr';
-		}
-		else
-			return this.getStyle( 'direction' ) || this.getAttribute( 'dir' );
-	},
-
-	/**
-	 * Gets, sets and removes custom data to be stored as HTML5 data-* attributes.
-	 *
-	 *		element.data( 'extra-info', 'test' );	// Appended the attribute data-extra-info="test" to the element.
-	 *		alert( element.data( 'extra-info' ) );	// 'test'
-	 *		element.data( 'extra-info', false );	// Remove the data-extra-info attribute from the element.
-	 *
-	 * @param {String} name The name of the attribute, excluding the `data-` part.
-	 * @param {String} [value] The value to set. If set to false, the attribute will be removed.
-	 */
-	data: function( name, value ) {
-		name = 'data-' + name;
-		if ( value === undefined )
-			return this.getAttribute( name );
-		else if ( value === false )
-			this.removeAttribute( name );
-		else
-			this.setAttribute( name, value );
-
-		return null;
-	},
-
-	/**
-	 * Retrieves an editor instance which is based on this element (if any).
-	 * It basically loops over {@link CKEDITOR#instances} in search for an instance
-	 * that uses the element.
-	 *
-	 *		var element = new CKEDITOR.dom.element( 'div' );
-	 *		element.appendTo( CKEDITOR.document.getBody() );
-	 *		CKEDITOR.replace( element );
-	 *		alert( element.getEditor().name ); // 'editor1'
-	 *
-	 * @returns {CKEDITOR.editor} An editor instance or null if nothing has been found.
-	 */
-	getEditor: function() {
-		var instances = CKEDITOR.instances,
-			name, instance;
-
-		for ( name in instances ) {
-			instance = instances[ name ];
-
-			if ( instance.element.equals( this ) && instance.elementMode != CKEDITOR.ELEMENT_MODE_APPENDTO )
-				return instance;
-		}
-
-		return null;
-	},
-
-	/**
-	 * Returns list of elements within this element that match specified `selector`.
-	 *
-	 * **Notes:**
-	 *
-	 *	* Not available in IE7.
-	 *	* Returned list is not a live collection (like a result of native `querySelectorAll`).
-	 *	* Unlike native `querySelectorAll` this method ensures selector contextualization. This is:
-	 *
-	 *			HTML:		'<body><div><i>foo</i></div></body>'
-	 *			Native:		div.querySelectorAll( 'body i' ) // ->		[ <i>foo</i> ]
-	 *			Method:		div.find( 'body i' ) // ->					[]
-	 *						div.find( 'i' ) // ->						[ <i>foo</i> ]
-	 *
-	 * @since 4.3
-	 * @param {String} selector
-	 * @returns {CKEDITOR.dom.nodeList}
-	 */
-	find: function( selector ) {
-		var removeTmpId = createTmpId( this ),
-			list = new CKEDITOR.dom.nodeList(
-				this.$.querySelectorAll( getContextualizedSelector( this, selector ) )
-			);
-
-		removeTmpId();
-
-		return list;
-	},
-
-	/**
-	 * Returns first element within this element that matches specified `selector`.
-	 *
-	 * **Notes:**
-	 *
-	 *	* Not available in IE7.
-	 *	* Unlike native `querySelectorAll` this method ensures selector contextualization. This is:
-	 *
-	 *			HTML:		'<body><div><i>foo</i></div></body>'
-	 *			Native:		div.querySelector( 'body i' ) // ->			<i>foo</i>
-	 *			Method:		div.findOne( 'body i' ) // ->				null
-	 *						div.findOne( 'i' ) // ->					<i>foo</i>
-	 *
-	 * @since 4.3
-	 * @param {String} selector
-	 * @returns {CKEDITOR.dom.element}
-	 */
-	findOne: function( selector ) {
-		var removeTmpId = createTmpId( this ),
-			found = this.$.querySelector( getContextualizedSelector( this, selector ) );
-
-		removeTmpId();
-
-		return found ? new CKEDITOR.dom.element( found ) : null;
-	},
-
-	/**
-	 * Traverse the DOM of this element (inclusive), executing a callback for
-	 * each node.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<div><p>foo<b>bar</b>bom</p></div>' );
-	 *		element.forEach( function( node ) {
-	 *			console.log( node );
-	 *		} );
-	 *		// Will log:
-	 *		// 1. <div> element,
-	 *		// 2. <p> element,
-	 *		// 3. "foo" text node,
-	 *		// 4. <b> element,
-	 *		// 5. "bar" text node,
-	 *		// 6. "bom" text node.
-	 *
-	 * @since 4.3
-	 * @param {Function} callback Function to be executed on every node.
-	 * If `callback` returns `false` descendants of the node will be ignored.
-	 * @param {CKEDITOR.htmlParser.node} callback.node Node passed as argument.
-	 * @param {Number} [type] If specified `callback` will be executed only on
-	 * nodes of this type.
-	 * @param {Boolean} [skipRoot] Don't execute `callback` on this element.
-	 */
-	forEach: function( callback, type, skipRoot ) {
-		if ( !skipRoot && ( !type || this.type == type ) )
-				var ret = callback( this );
-
-		// Do not filter children if callback returned false.
-		if ( ret === false )
-			return;
-
-		var children = this.getChildren(),
-			node,
-			i = 0;
-
-		// We do not cache the size, because the live list of nodes may be changed by the callback.
-		for ( ; i < children.count(); i++ ) {
-			node = children.getItem( i );
-			if ( node.type == CKEDITOR.NODE_ELEMENT )
-				node.forEach( callback, type );
-			else if ( !type || node.type == type )
-				callback( node );
-		}
-	}
-} );
-
-	function createTmpId( element ) {
-		var hadId = true;
-
-		if ( !element.$.id ) {
-			element.$.id = 'cke_tmp_' + CKEDITOR.tools.getNextNumber();
-			hadId = false;
-		}
-
-		return function() {
-			if ( !hadId )
-				element.removeAttribute( 'id' );
-		};
-	}
-
-	function getContextualizedSelector( element, selector ) {
-		return '#' + element.$.id + ' ' + selector.split( /,\s*/ ).join( ', #' + element.$.id + ' ' );
-	}
-
-	var sides = {
-		width: [ 'border-left-width', 'border-right-width', 'padding-left', 'padding-right' ],
-		height: [ 'border-top-width', 'border-bottom-width', 'padding-top', 'padding-bottom' ]
-	};
-
-	// Generate list of specific style rules, applicable to margin/padding/border.
-	function expandedRules( style ) {
-		var sides = [ 'top', 'left', 'right', 'bottom' ], components;
-
-		if ( style == 'border' )
-				components = [ 'color', 'style', 'width' ];
-
-		var styles = [];
-		for ( var i = 0 ; i < sides.length ; i++ ) {
-
-			if ( components ) {
-				for ( var j = 0 ; j < components.length ; j++ )
-					styles.push( [ style, sides[ i ], components[ j ] ].join( '-' ) );
-			}
-			else
-				styles.push( [ style, sides[ i ] ].join( '-' ) );
-		}
-
-		return styles;
-	}
-
-	function marginAndPaddingSize( type ) {
-		var adjustment = 0;
-		for ( var i = 0, len = sides[ type ].length; i < len; i++ )
-			adjustment += parseInt( this.getComputedStyle( sides[ type ][ i ] ) || 0, 10 ) || 0;
-		return adjustment;
-	}
-
-	/**
-	 * Sets the element size considering the box model.
-	 *
-	 * @param {'width'/'height'} type The dimension to set.
-	 * @param {Number} size The length unit in px.
-	 * @param {Boolean} isBorderBox Apply the size based on the border box model.
-	 */
-	CKEDITOR.dom.element.prototype.setSize = function( type, size, isBorderBox ) {
-		if ( typeof size == 'number' ) {
-			if ( isBorderBox && !( CKEDITOR.env.ie && CKEDITOR.env.quirks ) )
-				size -= marginAndPaddingSize.call( this, type );
-
-			this.setStyle( type, size + 'px' );
-		}
-	};
-
-	/**
-	 * Gets the element size, possibly considering the box model.
-	 *
-	 * @param {'width'/'height'} type The dimension to get.
-	 * @param {Boolean} isBorderBox Get the size based on the border box model.
-	 */
-	CKEDITOR.dom.element.prototype.getSize = function( type, isBorderBox ) {
-		var size = Math.max( this.$[ 'offset' + CKEDITOR.tools.capitalize( type ) ], this.$[ 'client' + CKEDITOR.tools.capitalize( type ) ] ) || 0;
-
-		if ( isBorderBox )
-			size -= marginAndPaddingSize.call( this, type );
-
-		return size;
-	};
-} )();

+ 0 - 251
htdocs/includes/ckeditor/ckeditor/_source/core/dom/elementpath.js

@@ -1,251 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-'use strict';
-
-( function() {
-
-	var pathBlockLimitElements = {},
-		pathBlockElements = {},
-		tag;
-
-	// Elements that are considered the "Block limit" in an element path.
-	for ( tag in CKEDITOR.dtd.$blockLimit ) {
-		// Exclude from list roots.
-		if ( !( tag in CKEDITOR.dtd.$list ) )
-			pathBlockLimitElements[ tag ] = 1;
-	}
-
-	// Elements that are considered the "End level Block" in an element path.
-	for ( tag in CKEDITOR.dtd.$block ) {
-		// Exclude block limits, and empty block element, e.g. hr.
-		if ( !( tag in CKEDITOR.dtd.$blockLimit || tag in CKEDITOR.dtd.$empty ) )
-			pathBlockElements[ tag ] = 1;
-	}
-
-	// Check if an element contains any block element.
-	function checkHasBlock( element ) {
-		var childNodes = element.getChildren();
-
-		for ( var i = 0, count = childNodes.count(); i < count; i++ ) {
-			var child = childNodes.getItem( i );
-
-			if ( child.type == CKEDITOR.NODE_ELEMENT && CKEDITOR.dtd.$block[ child.getName() ] )
-				return true;
-		}
-
-		return false;
-	}
-
-	/**
-	 * Retrieve the list of nodes walked from the start node up to the editable element of the editor.
-	 *
-	 * @class
-	 * @constructor Creates an element path class instance.
-	 * @param {CKEDITOR.dom.element} startNode From which the path should start.
-	 * @param {CKEDITOR.dom.element} root To which element the path should stop, defaults to the `body` element.
-	 */
-	CKEDITOR.dom.elementPath = function( startNode, root ) {
-		var block = null,
-			blockLimit = null,
-			elements = [],
-			e = startNode,
-			elementName;
-
-		// Backward compact.
-		root = root || startNode.getDocument().getBody();
-
-		do {
-			if ( e.type == CKEDITOR.NODE_ELEMENT ) {
-				elements.push( e );
-
-				if ( !this.lastElement ) {
-					this.lastElement = e;
-
-					// If an object or non-editable element is fully selected at the end of the element path,
-					// it must not become the block limit.
-					if ( e.is( CKEDITOR.dtd.$object ) || e.getAttribute( 'contenteditable' ) == 'false' )
-						continue;
-				}
-
-				if ( e.equals( root ) )
-					break;
-
-				if ( !blockLimit ) {
-					elementName = e.getName();
-
-					// First editable element becomes a block limit, because it cannot be split.
-					if ( e.getAttribute( 'contenteditable' ) == 'true' )
-						blockLimit = e;
-					// "Else" because element cannot be both - block and block levelimit.
-					else if ( !block && pathBlockElements[ elementName ] )
-						block = e;
-
-					if ( pathBlockLimitElements[ elementName ] ) {
-						// End level DIV is considered as the block, if no block is available. (#525)
-						// But it must NOT be the root element (checked above).
-						if ( !block && elementName == 'div' && !checkHasBlock( e ) )
-							block = e;
-						else
-							blockLimit = e;
-					}
-				}
-			}
-		}
-		while ( ( e = e.getParent() ) );
-
-		// Block limit defaults to root.
-		if ( !blockLimit )
-			blockLimit = root;
-
-		/**
-		 * First non-empty block element which:
-		 *
-		 * * is not a {@link CKEDITOR.dtd#$blockLimit},
-		 * * or is a `div` which does not contain block elements and is not a `root`.
-		 *
-		 * This means a first, splittable block in elements path.
-		 *
-		 * @readonly
-		 * @property {CKEDITOR.dom.element}
-		 */
-		this.block = block;
-
-		/**
-		 * See the {@link CKEDITOR.dtd#$blockLimit} description.
-		 *
-		 * @readonly
-		 * @property {CKEDITOR.dom.element}
-		 */
-		this.blockLimit = blockLimit;
-
-		/**
-		 * The root of the elements path - `root` argument passed to class constructor or a `body` element.
-		 *
-		 * @readonly
-		 * @property {CKEDITOR.dom.element}
-		 */
-		this.root = root;
-
-		/**
-		 * An array of elements (from `startNode` to `root`) in the path.
-		 *
-		 * @readonly
-		 * @property {CKEDITOR.dom.element[]}
-		 */
-		this.elements = elements;
-
-		/**
-		 * The last element of the elements path - `startNode` or its parent.
-		 *
-		 * @readonly
-		 * @property {CKEDITOR.dom.element} lastElement
-		 */
-	};
-
-} )();
-
-CKEDITOR.dom.elementPath.prototype = {
-	/**
-	 * Compares this element path with another one.
-	 *
-	 * @param {CKEDITOR.dom.elementPath} otherPath The elementPath object to be
-	 * compared with this one.
-	 * @returns {Boolean} `true` if the paths are equal, containing the same
-	 * number of elements and the same elements in the same order.
-	 */
-	compare: function( otherPath ) {
-		var thisElements = this.elements;
-		var otherElements = otherPath && otherPath.elements;
-
-		if ( !otherElements || thisElements.length != otherElements.length )
-			return false;
-
-		for ( var i = 0; i < thisElements.length; i++ ) {
-			if ( !thisElements[ i ].equals( otherElements[ i ] ) )
-				return false;
-		}
-
-		return true;
-	},
-
-	/**
-	 * Search the path elements that meets the specified criteria.
-	 *
-	 * @param {String/Array/Function/Object/CKEDITOR.dom.element} query The criteria that can be
-	 * either a tag name, list (array and object) of tag names, element or an node evaluator function.
-	 * @param {Boolean} [excludeRoot] Not taking path root element into consideration.
-	 * @param {Boolean} [fromTop] Search start from the topmost element instead of bottom.
-	 * @returns {CKEDITOR.dom.element} The first matched dom element or `null`.
-	 */
-	contains: function( query, excludeRoot, fromTop ) {
-		var evaluator;
-		if ( typeof query == 'string' )
-			evaluator = function( node ) {
-				return node.getName() == query;
-			};
-		if ( query instanceof CKEDITOR.dom.element )
-			evaluator = function( node ) {
-				return node.equals( query );
-			};
-		else if ( CKEDITOR.tools.isArray( query ) )
-			evaluator = function( node ) {
-				return CKEDITOR.tools.indexOf( query, node.getName() ) > -1;
-			};
-		else if ( typeof query == 'function' )
-			evaluator = query;
-		else if ( typeof query == 'object' )
-			evaluator = function( node ) {
-				return node.getName() in query;
-			};
-
-		var elements = this.elements,
-			length = elements.length;
-		excludeRoot && length--;
-
-		if ( fromTop ) {
-			elements = Array.prototype.slice.call( elements, 0 );
-			elements.reverse();
-		}
-
-		for ( var i = 0; i < length; i++ ) {
-			if ( evaluator( elements[ i ] ) )
-				return elements[ i ];
-		}
-
-		return null;
-	},
-
-	/**
-	 * Check whether the elements path is the proper context for the specified
-	 * tag name in the DTD.
-	 *
-	 * @param {String} tag The tag name.
-	 * @returns {Boolean}
-	 */
-	isContextFor: function( tag ) {
-		var holder;
-
-		// Check for block context.
-		if ( tag in CKEDITOR.dtd.$block ) {
-			// Indeterminate elements which are not subjected to be splitted or surrounded must be checked first.
-			var inter = this.contains( CKEDITOR.dtd.$intermediate );
-			holder = inter || ( this.root.equals( this.block ) && this.block ) || this.blockLimit;
-			return !!holder.getDtd()[ tag ];
-		}
-
-		return true;
-	},
-
-	/**
-	 * Retrieve the text direction for this elements path.
-	 *
-	 * @returns {'ltr'/'rtl'}
-	 */
-	direction: function() {
-		var directionNode = this.block || this.blockLimit || this.root;
-		return directionNode.getDirection( 1 );
-	}
-};

+ 0 - 208
htdocs/includes/ckeditor/ckeditor/_source/core/dom/event.js

@@ -1,208 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.dom.event} class, which
- *		represents the a native DOM event object.
- */
-
-/**
- * Represents a native DOM event object.
- *
- * @class
- * @constructor Creates an event class instance.
- * @param {Object} domEvent A native DOM event object.
- */
-CKEDITOR.dom.event = function( domEvent ) {
-	/**
-	 * The native DOM event object represented by this class instance.
-	 *
-	 * @readonly
-	 */
-	this.$ = domEvent;
-};
-
-CKEDITOR.dom.event.prototype = {
-	/**
-	 * Gets the key code associated to the event.
-	 *
-	 *		alert( event.getKey() ); // '65' is 'a' has been pressed
-	 *
-	 * @returns {Number} The key code.
-	 */
-	getKey: function() {
-		return this.$.keyCode || this.$.which;
-	},
-
-	/**
-	 * Gets a number represeting the combination of the keys pressed during the
-	 * event. It is the sum with the current key code and the {@link CKEDITOR#CTRL},
-	 * {@link CKEDITOR#SHIFT} and {@link CKEDITOR#ALT} constants.
-	 *
-	 *		alert( event.getKeystroke() == 65 );									// 'a' key
-	 *		alert( event.getKeystroke() == CKEDITOR.CTRL + 65 );					// CTRL + 'a' key
-	 *		alert( event.getKeystroke() == CKEDITOR.CTRL + CKEDITOR.SHIFT + 65 );	// CTRL + SHIFT + 'a' key
-	 *
-	 * @returns {Number} The number representing the keys combination.
-	 */
-	getKeystroke: function() {
-		var keystroke = this.getKey();
-
-		if ( this.$.ctrlKey || this.$.metaKey )
-			keystroke += CKEDITOR.CTRL;
-
-		if ( this.$.shiftKey )
-			keystroke += CKEDITOR.SHIFT;
-
-		if ( this.$.altKey )
-			keystroke += CKEDITOR.ALT;
-
-		return keystroke;
-	},
-
-	/**
-	 * Prevents the original behavior of the event to happen. It can optionally
-	 * stop propagating the event in the event chain.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myElement' );
-	 *		element.on( 'click', function( ev ) {
-	 *			// The DOM event object is passed by the 'data' property.
-	 *			var domEvent = ev.data;
-	 *			// Prevent the click to chave any effect in the element.
-	 *			domEvent.preventDefault();
-	 *		} );
-	 *
-	 * @param {Boolean} [stopPropagation=false] Stop propagating this event in the
-	 * event chain.
-	 */
-	preventDefault: function( stopPropagation ) {
-		var $ = this.$;
-		if ( $.preventDefault )
-			$.preventDefault();
-		else
-			$.returnValue = false;
-
-		if ( stopPropagation )
-			this.stopPropagation();
-	},
-
-	/**
-	 * Stops this event propagation in the event chain.
-	 */
-	stopPropagation: function() {
-		var $ = this.$;
-		if ( $.stopPropagation )
-			$.stopPropagation();
-		else
-			$.cancelBubble = true;
-	},
-
-	/**
-	 * Returns the DOM node where the event was targeted to.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'myElement' );
-	 *		element.on( 'click', function( ev ) {
-	 *			// The DOM event object is passed by the 'data' property.
-	 *			var domEvent = ev.data;
-	 *			// Add a CSS class to the event target.
-	 *			domEvent.getTarget().addClass( 'clicked' );
-	 *		} );
-	 *
-	 * @returns {CKEDITOR.dom.node} The target DOM node.
-	 */
-	getTarget: function() {
-		var rawNode = this.$.target || this.$.srcElement;
-		return rawNode ? new CKEDITOR.dom.node( rawNode ) : null;
-	},
-
-	/**
-	 * Returns an integer value that indicates the current processing phase of an event.
-	 * For browsers that doesn't support event phase, {@link CKEDITOR#EVENT_PHASE_AT_TARGET} is always returned.
-	 *
-	 * @returns {Number} One of {@link CKEDITOR#EVENT_PHASE_CAPTURING},
-	 * {@link CKEDITOR#EVENT_PHASE_AT_TARGET}, or {@link CKEDITOR#EVENT_PHASE_BUBBLING}.
-	 */
-	getPhase: function() {
-		return this.$.eventPhase || 2;
-	},
-
-	/**
-	 * Retrieves the coordinates of the mouse pointer relative to the top-left
-	 * corner of the document, in mouse related event.
-	 *
-	 *		element.on( 'mousemouse', function( ev ) {
-	 *			var pageOffset = ev.data.getPageOffset();
-	 *			alert( pageOffset.x );			// page offset X
-	 *			alert( pageOffset.y );			// page offset Y
-	 *     } );
-	 *
-	 * @returns {Object} The object contains the position.
-	 * @returns {Number} return.x
-	 * @returns {Number} return.y
-	 */
-	getPageOffset : function() {
-		var doc = this.getTarget().getDocument().$;
-		var pageX = this.$.pageX || this.$.clientX + ( doc.documentElement.scrollLeft || doc.body.scrollLeft );
-		var pageY = this.$.pageY || this.$.clientY + ( doc.documentElement.scrollTop || doc.body.scrollTop );
-		return { x : pageX, y : pageY };
-	}
-};
-
-// For the followind constants, we need to go over the Unicode boundaries
-// (0x10FFFF) to avoid collision.
-
-/**
- * CTRL key (0x110000).
- *
- * @readonly
- * @property {Number} [=0x110000]
- * @member CKEDITOR
- */
-CKEDITOR.CTRL = 0x110000;
-
-/**
- * SHIFT key (0x220000).
- *
- * @readonly
- * @property {Number} [=0x220000]
- * @member CKEDITOR
- */
-CKEDITOR.SHIFT = 0x220000;
-
-/**
- * ALT key (0x440000).
- *
- * @readonly
- * @property {Number} [=0x440000]
- * @member CKEDITOR
- */
-CKEDITOR.ALT = 0x440000;
-
-/**
- * Capturing phase.
- *
- * @readonly
- * @property {Number} [=1]
- * @member CKEDITOR
- */
-CKEDITOR.EVENT_PHASE_CAPTURING = 1;
-
-/**
- * Event at target.
- *
- * @readonly
- * @property {Number} [=2]
- * @member CKEDITOR
- */
-CKEDITOR.EVENT_PHASE_AT_TARGET = 2;
-
-/**
- * Bubbling phase.
- *
- * @readonly
- * @property {Number} [=3]
- * @member CKEDITOR
- */
-CKEDITOR.EVENT_PHASE_BUBBLING = 3;

+ 0 - 500
htdocs/includes/ckeditor/ckeditor/_source/core/dom/iterator.js

@@ -1,500 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @ignore
- * File overview: DOM iterator, which iterates over list items, lines and paragraphs.
- */
-
-'use strict';
-
-( function() {
-	/**
-	 * Represents iterator class. It can be used to iterate
-	 * over all elements (or even text nodes in case of {@link #enlargeBr} set to `false`)
-	 * which establish "paragraph-like" spaces within passed range.
-	 *
-	 *		// <h1>[foo</h1><p>bar]</p>
-	 *		var iterator = range.createIterator();
-	 *		iterator.getNextParagraph(); // h1 element
-	 *		iterator.getNextParagraph(); // p element
-	 *
-	 *		// <ul><li>[foo</li><li>bar]</li>
-	 *		// With enforceRealBlocks set to false iterator will return two list item elements.
-	 *		// With enforceRealBlocks set to true iterator will return two paragraphs and the DOM will be changed to:
-	 *		// <ul><li><p>foo</p></li><li><p>bar</p></li>
-	 *
-	 * @class CKEDITOR.dom.iterator
-	 * @constructor Creates an iterator class instance.
-	 * @param {CKEDITOR.dom.range} range
-	 */
-	function iterator( range ) {
-		if ( arguments.length < 1 )
-			return;
-
-		this.range = range;
-		this.forceBrBreak = 0;
-
-		// (#3730).
-		/**
-		 * Whether include `<br>`s into the enlarged range. Should be
-		 * set to `false` when using iterator in {@link CKEDITOR#ENTER_BR} mode.
-		 *
-		 * @property {Boolean} [enlargeBr=true]
-		 */
-		this.enlargeBr = 1;
-
-		/**
-		 * Whether iterator should create transformable block
-		 * if the current one contains text and it cannot be transformed.
-		 * For example new blocks will be established in elements like
-		 * `<li>` or `<td>`.
-		 *
-		 * @property {Boolean} [enforceRealBlocks=false]
-		 */
-		this.enforceRealBlocks = 0;
-
-		this._ || ( this._ = {} );
-	}
-
-	/**
-	 * Default iterator's filter. It is set only for nested iterators.
-	 *
-	 * @since 4.3
-	 * @readonly
-	 * @property {CKEDITOR.filter} filter
-	 */
-
-	/**
-	 * Iterator's active filter. It is set by the {@link #getNextParagraph} method
-	 * when it enters nested editable.
-	 *
-	 * @since 4.3
-	 * @readonly
-	 * @property {CKEDITOR.filter} activeFilter
-	 */
-
-	var beginWhitespaceRegex = /^[\r\n\t ]+$/,
-		// Ignore bookmark nodes.(#3783)
-		bookmarkGuard = CKEDITOR.dom.walker.bookmark( false, true ),
-		whitespacesGuard = CKEDITOR.dom.walker.whitespaces( true ),
-		skipGuard = function( node ) {
-			return bookmarkGuard( node ) && whitespacesGuard( node );
-		};
-
-	// Get a reference for the next element, bookmark nodes are skipped.
-	function getNextSourceNode( node, startFromSibling, lastNode ) {
-		var next = node.getNextSourceNode( startFromSibling, null, lastNode );
-		while ( !bookmarkGuard( next ) )
-			next = next.getNextSourceNode( startFromSibling, null, lastNode );
-		return next;
-	}
-
-	iterator.prototype = {
-		/**
-		 * Returns next paragraph-like element or `null` if reached the end of range.
-		 *
-		 * @param {String} [blockTag='p'] Name of a block element which will be established by
-		 * iterator in block-less elements (see {@link #enforceRealBlocks}).
-		 */
-		getNextParagraph: function( blockTag ) {
-			// The block element to be returned.
-			var block;
-
-			// The range object used to identify the paragraph contents.
-			var range;
-
-			// Indicats that the current element in the loop is the last one.
-			var isLast;
-
-			// Instructs to cleanup remaining BRs.
-			var removePreviousBr, removeLastBr;
-
-			blockTag = blockTag || 'p';
-
-			// We're iterating over nested editable.
-			if ( this._.nestedEditable ) {
-				// Get next block from nested iterator and returns it if was found.
-				block = this._.nestedEditable.iterator.getNextParagraph( blockTag );
-				if ( block ) {
-					// Inherit activeFilter from the nested iterator.
-					this.activeFilter = this._.nestedEditable.iterator.activeFilter;
-					return block;
-				}
-
-				// No block in nested iterator means that we reached the end of the nested editable.
-				// Reset the active filter to the default filter (or undefined if this iterator didn't have it).
-				this.activeFilter = this.filter;
-
-				// Try to find next nested editable or get back to parent (this) iterator.
-				if ( startNestedEditableIterator( this, blockTag, this._.nestedEditable.container, this._.nestedEditable.remaining ) ) {
-					// Inherit activeFilter from the nested iterator.
-					this.activeFilter = this._.nestedEditable.iterator.activeFilter;
-					return this._.nestedEditable.iterator.getNextParagraph( blockTag );
-				} else
-					this._.nestedEditable = null;
-			}
-
-			// Block-less range should be checked first.
-			if ( !this.range.root.getDtd()[ blockTag ] )
-				return null;
-
-			// This is the first iteration. Let's initialize it.
-			if ( !this._.started )
-				range = startIterator.call( this );
-
-			var currentNode = this._.nextNode,
-				lastNode = this._.lastNode;
-
-			this._.nextNode = null;
-			while ( currentNode ) {
-				// closeRange indicates that a paragraph boundary has been found,
-				// so the range can be closed.
-				var closeRange = 0,
-					parentPre = currentNode.hasAscendant( 'pre' );
-
-				// includeNode indicates that the current node is good to be part
-				// of the range. By default, any non-element node is ok for it.
-				var includeNode = ( currentNode.type != CKEDITOR.NODE_ELEMENT ),
-					continueFromSibling = 0;
-
-				// If it is an element node, let's check if it can be part of the range.
-				if ( !includeNode ) {
-					var nodeName = currentNode.getName();
-
-					// Non-editable block was found - return it and move to processing
-					// its nested editables if they exist.
-					if ( CKEDITOR.dtd.$block[ nodeName ] && currentNode.getAttribute( 'contenteditable' ) == 'false' ) {
-						block = currentNode;
-
-						// Setup iterator for first of nested editables.
-						// If there's no editable, then algorithm will move to next element after current block.
-						startNestedEditableIterator( this, blockTag, block );
-
-						// Gets us straight to the end of getParagraph() because block variable is set.
-						break;
-					} else if ( currentNode.isBlockBoundary( this.forceBrBreak && !parentPre && { br: 1 } ) ) {
-						// <br> boundaries must be part of the range. It will
-						// happen only if ForceBrBreak.
-						if ( nodeName == 'br' )
-							includeNode = 1;
-						else if ( !range && !currentNode.getChildCount() && nodeName != 'hr' ) {
-							// If we have found an empty block, and haven't started
-							// the range yet, it means we must return this block.
-							block = currentNode;
-							isLast = currentNode.equals( lastNode );
-							break;
-						}
-
-						// The range must finish right before the boundary,
-						// including possibly skipped empty spaces. (#1603)
-						if ( range ) {
-							range.setEndAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
-
-							// The found boundary must be set as the next one at this
-							// point. (#1717)
-							if ( nodeName != 'br' )
-								this._.nextNode = currentNode;
-						}
-
-						closeRange = 1;
-					} else {
-						// If we have child nodes, let's check them.
-						if ( currentNode.getFirst() ) {
-							// If we don't have a range yet, let's start it.
-							if ( !range ) {
-								range = this.range.clone();
-								range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
-							}
-
-							currentNode = currentNode.getFirst();
-							continue;
-						}
-						includeNode = 1;
-					}
-				} else if ( currentNode.type == CKEDITOR.NODE_TEXT ) {
-					// Ignore normal whitespaces (i.e. not including &nbsp; or
-					// other unicode whitespaces) before/after a block node.
-					if ( beginWhitespaceRegex.test( currentNode.getText() ) )
-						includeNode = 0;
-				}
-
-				// The current node is good to be part of the range and we are
-				// starting a new range, initialize it first.
-				if ( includeNode && !range ) {
-					range = this.range.clone();
-					range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
-				}
-
-				// The last node has been found.
-				isLast = ( ( !closeRange || includeNode ) && currentNode.equals( lastNode ) );
-
-				// If we are in an element boundary, let's check if it is time
-				// to close the range, otherwise we include the parent within it.
-				if ( range && !closeRange ) {
-					while ( !currentNode.getNext( skipGuard ) && !isLast ) {
-						var parentNode = currentNode.getParent();
-
-						if ( parentNode.isBlockBoundary( this.forceBrBreak && !parentPre && { br: 1 } ) ) {
-							closeRange = 1;
-							includeNode = 0;
-							isLast = isLast || ( parentNode.equals( lastNode ) );
-							// Make sure range includes bookmarks at the end of the block. (#7359)
-							range.setEndAt( parentNode, CKEDITOR.POSITION_BEFORE_END );
-							break;
-						}
-
-						currentNode = parentNode;
-						includeNode = 1;
-						isLast = ( currentNode.equals( lastNode ) );
-						continueFromSibling = 1;
-					}
-				}
-
-				// Now finally include the node.
-				if ( includeNode )
-					range.setEndAt( currentNode, CKEDITOR.POSITION_AFTER_END );
-
-				currentNode = getNextSourceNode( currentNode, continueFromSibling, lastNode );
-				isLast = !currentNode;
-
-				// We have found a block boundary. Let's close the range and move out of the
-				// loop.
-				if ( isLast || ( closeRange && range ) )
-					break;
-			}
-
-			// Now, based on the processed range, look for (or create) the block to be returned.
-			if ( !block ) {
-				// If no range has been found, this is the end.
-				if ( !range ) {
-					this._.docEndMarker && this._.docEndMarker.remove();
-					this._.nextNode = null;
-					return null;
-				}
-
-				var startPath = new CKEDITOR.dom.elementPath( range.startContainer, range.root );
-				var startBlockLimit = startPath.blockLimit,
-					checkLimits = { div: 1, th: 1, td: 1 };
-				block = startPath.block;
-
-				if ( !block && startBlockLimit && !this.enforceRealBlocks && checkLimits[ startBlockLimit.getName() ] && range.checkStartOfBlock() && range.checkEndOfBlock() && !startBlockLimit.equals( range.root ) )
-					block = startBlockLimit;
-				else if ( !block || ( this.enforceRealBlocks && block.getName() == 'li' ) ) {
-					// Create the fixed block.
-					block = this.range.document.createElement( blockTag );
-
-					// Move the contents of the temporary range to the fixed block.
-					range.extractContents().appendTo( block );
-					block.trim();
-
-					// Insert the fixed block into the DOM.
-					range.insertNode( block );
-
-					removePreviousBr = removeLastBr = true;
-				} else if ( block.getName() != 'li' ) {
-					// If the range doesn't includes the entire contents of the
-					// block, we must split it, isolating the range in a dedicated
-					// block.
-					if ( !range.checkStartOfBlock() || !range.checkEndOfBlock() ) {
-						// The resulting block will be a clone of the current one.
-						block = block.clone( false );
-
-						// Extract the range contents, moving it to the new block.
-						range.extractContents().appendTo( block );
-						block.trim();
-
-						// Split the block. At this point, the range will be in the
-						// right position for our intents.
-						var splitInfo = range.splitBlock();
-
-						removePreviousBr = !splitInfo.wasStartOfBlock;
-						removeLastBr = !splitInfo.wasEndOfBlock;
-
-						// Insert the new block into the DOM.
-						range.insertNode( block );
-					}
-				} else if ( !isLast ) {
-					// LIs are returned as is, with all their children (due to the
-					// nested lists). But, the next node is the node right after
-					// the current range, which could be an <li> child (nested
-					// lists) or the next sibling <li>.
-
-					this._.nextNode = ( block.equals( lastNode ) ? null : getNextSourceNode( range.getBoundaryNodes().endNode, 1, lastNode ) );
-				}
-			}
-
-			if ( removePreviousBr ) {
-				var previousSibling = block.getPrevious();
-				if ( previousSibling && previousSibling.type == CKEDITOR.NODE_ELEMENT ) {
-					if ( previousSibling.getName() == 'br' )
-						previousSibling.remove();
-					else if ( previousSibling.getLast() && previousSibling.getLast().$.nodeName.toLowerCase() == 'br' )
-						previousSibling.getLast().remove();
-				}
-			}
-
-			if ( removeLastBr ) {
-				var lastChild = block.getLast();
-				if ( lastChild && lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.getName() == 'br' ) {
-					// Remove br filler on browser which do not need it.
-					if ( !CKEDITOR.env.needsBrFiller || lastChild.getPrevious( bookmarkGuard ) || lastChild.getNext( bookmarkGuard ) )
-						lastChild.remove();
-				}
-			}
-
-			// Get a reference for the next element. This is important because the
-			// above block can be removed or changed, so we can rely on it for the
-			// next interation.
-			if ( !this._.nextNode )
-				this._.nextNode = ( isLast || block.equals( lastNode ) || !lastNode ) ? null : getNextSourceNode( block, 1, lastNode );
-
-			return block;
-		}
-	};
-
-	// @context CKEDITOR.dom.iterator
-	// @returns Collapsed range which will be reused when during furter processing.
-	function startIterator() {
-		var range = this.range.clone(),
-			// Indicate at least one of the range boundaries is inside a preformat block.
-			touchPre;
-
-		// Shrink the range to exclude harmful "noises" (#4087, #4450, #5435).
-		range.shrink( CKEDITOR.SHRINK_ELEMENT, true );
-
-		touchPre = range.endContainer.hasAscendant( 'pre', true ) || range.startContainer.hasAscendant( 'pre', true );
-
-		range.enlarge( this.forceBrBreak && !touchPre || !this.enlargeBr ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
-
-		if ( !range.collapsed ) {
-			var walker = new CKEDITOR.dom.walker( range.clone() ),
-				ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( true, true );
-			// Avoid anchor inside bookmark inner text.
-			walker.evaluator = ignoreBookmarkTextEvaluator;
-			this._.nextNode = walker.next();
-			// TODO: It's better to have walker.reset() used here.
-			walker = new CKEDITOR.dom.walker( range.clone() );
-			walker.evaluator = ignoreBookmarkTextEvaluator;
-			var lastNode = walker.previous();
-			this._.lastNode = lastNode.getNextSourceNode( true );
-
-			// We may have an empty text node at the end of block due to [3770].
-			// If that node is the lastNode, it would cause our logic to leak to the
-			// next block.(#3887)
-			if ( this._.lastNode && this._.lastNode.type == CKEDITOR.NODE_TEXT && !CKEDITOR.tools.trim( this._.lastNode.getText() ) && this._.lastNode.getParent().isBlockBoundary() ) {
-				var testRange = this.range.clone();
-				testRange.moveToPosition( this._.lastNode, CKEDITOR.POSITION_AFTER_END );
-				if ( testRange.checkEndOfBlock() ) {
-					var path = new CKEDITOR.dom.elementPath( testRange.endContainer, testRange.root ),
-						lastBlock = path.block || path.blockLimit;
-					this._.lastNode = lastBlock.getNextSourceNode( true );
-				}
-			}
-
-			// The end of document or range.root was reached, so we need a marker node inside.
-			if ( !this._.lastNode || !range.root.contains( this._.lastNode ) ) {
-				this._.lastNode = this._.docEndMarker = range.document.createText( '' );
-				this._.lastNode.insertAfter( lastNode );
-			}
-
-			// Let's reuse this variable.
-			range = null;
-		}
-
-		this._.started = 1;
-
-		return range;
-	}
-
-	// Does a nested editables lookup inside editablesContainer.
-	// If remainingEditables is set will lookup inside this array.
-	// @param {CKEDITOR.dom.element} editablesContainer
-	// @param {CKEDITOR.dom.element[]} [remainingEditables]
-	function getNestedEditableIn( editablesContainer, remainingEditables ) {
-		if ( remainingEditables == undefined )
-			remainingEditables = findNestedEditables( editablesContainer );
-
-		var editable;
-
-		while ( ( editable = remainingEditables.shift() ) ) {
-			if ( isIterableEditable( editable ) )
-				return { element: editable, remaining: remainingEditables };
-		}
-
-		return null;
-	}
-
-	// Checkes whether we can iterate over this editable.
-	function isIterableEditable( editable ) {
-		// Reject blockless editables.
-		return editable.getDtd().p;
-	}
-
-	// Finds nested editables within container. Does not return
-	// editables nested in another editable (twice).
-	function findNestedEditables( container ) {
-		var editables = [];
-
-		container.forEach( function( element ) {
-			if ( element.getAttribute( 'contenteditable' ) == 'true' ) {
-				editables.push( element );
-				return false; // Skip children.
-			}
-		}, CKEDITOR.NODE_ELEMENT, true );
-
-		return editables;
-	}
-
-	// Looks for a first nested editable after previousEditable (if passed) and creates
-	// nested iterator for it.
-	function startNestedEditableIterator( parentIterator, blockTag, editablesContainer, remainingEditables ) {
-		var editable = getNestedEditableIn( editablesContainer, remainingEditables );
-
-		if ( !editable )
-			return 0;
-
-		var filter = CKEDITOR.filter.instances[ editable.element.data( 'cke-filter' ) ];
-
-		// If current editable has a filter and this filter does not allow for block tag,
-		// search for next nested editable in remaining ones.
-		if ( filter && !filter.check( blockTag ) )
-			return startNestedEditableIterator( parentIterator, blockTag, editablesContainer, editable.remaining );
-
-		var range = new CKEDITOR.dom.range( editable.element );
-		range.selectNodeContents( editable.element );
-
-		var iterator = range.createIterator();
-		// This setting actually does not change anything in this case,
-		// because entire range contents is selected, so there're no <br>s to be included.
-		// But it seems right to copy it too.
-		iterator.enlargeBr = parentIterator.enlargeBr;
-		// Inherit configuration from parent iterator.
-		iterator.enforceRealBlocks = parentIterator.enforceRealBlocks;
-		// Set the activeFilter (which can be overriden when this iteator will start nested iterator)
-		// and the default filter, which will make it possible to reset to
-		// current iterator's activeFilter after leaving nested editable.
-		iterator.activeFilter = iterator.filter = filter;
-
-		parentIterator._.nestedEditable = {
-			element: editable.element,
-			container: editablesContainer,
-			remaining: editable.remaining,
-			iterator: iterator
-		};
-
-		return 1;
-	}
-
-	/**
-	 * Creates {CKEDITOR.dom.iterator} instance for this range.
-	 *
-	 * @member CKEDITOR.dom.range
-	 * @returns {CKEDITOR.dom.iterator}
-	 */
-	CKEDITOR.dom.range.prototype.createIterator = function() {
-		return new iterator( this );
-	};
-} )();

+ 0 - 748
htdocs/includes/ckeditor/ckeditor/_source/core/dom/node.js

@@ -1,748 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.dom.node} class which is the base
- *		class for classes that represent DOM nodes.
- */
-
-/**
- * Base class for classes representing DOM nodes. This constructor may return
- * an instance of a class that inherits from this class, like
- * {@link CKEDITOR.dom.element} or {@link CKEDITOR.dom.text}.
- *
- * @class
- * @extends CKEDITOR.dom.domObject
- * @constructor Creates a node class instance.
- * @param {Object} domNode A native DOM node.
- * @see CKEDITOR.dom.element
- * @see CKEDITOR.dom.text
- */
-CKEDITOR.dom.node = function( domNode ) {
-	if ( domNode ) {
-		var type = domNode.nodeType == CKEDITOR.NODE_DOCUMENT ? 'document' : domNode.nodeType == CKEDITOR.NODE_ELEMENT ? 'element' : domNode.nodeType == CKEDITOR.NODE_TEXT ? 'text' : domNode.nodeType == CKEDITOR.NODE_COMMENT ? 'comment' : domNode.nodeType == CKEDITOR.NODE_DOCUMENT_FRAGMENT ? 'documentFragment' : 'domObject'; // Call the base constructor otherwise.
-
-		return new CKEDITOR.dom[ type ]( domNode );
-	}
-
-	return this;
-};
-
-CKEDITOR.dom.node.prototype = new CKEDITOR.dom.domObject();
-
-/**
- * Element node type.
- *
- * @readonly
- * @property {Number} [=1]
- * @member CKEDITOR
- */
-CKEDITOR.NODE_ELEMENT = 1;
-
-/**
- * Document node type.
- *
- * @readonly
- * @property {Number} [=9]
- * @member CKEDITOR
- */
-CKEDITOR.NODE_DOCUMENT = 9;
-
-/**
- * Text node type.
- *
- * @readonly
- * @property {Number} [=3]
- * @member CKEDITOR
- */
-CKEDITOR.NODE_TEXT = 3;
-
-/**
- * Comment node type.
- *
- * @readonly
- * @property {Number} [=8]
- * @member CKEDITOR
- */
-CKEDITOR.NODE_COMMENT = 8;
-
-/**
- * Document fragment node type.
- *
- * @readonly
- * @property {Number} [=11]
- * @member CKEDITOR
- */
-CKEDITOR.NODE_DOCUMENT_FRAGMENT = 11;
-
-CKEDITOR.POSITION_IDENTICAL = 0;
-CKEDITOR.POSITION_DISCONNECTED = 1;
-CKEDITOR.POSITION_FOLLOWING = 2;
-CKEDITOR.POSITION_PRECEDING = 4;
-CKEDITOR.POSITION_IS_CONTAINED = 8;
-CKEDITOR.POSITION_CONTAINS = 16;
-
-CKEDITOR.tools.extend( CKEDITOR.dom.node.prototype, {
-	/**
-	 * Makes this node a child of another element.
-	 *
-	 *		var p = new CKEDITOR.dom.element( 'p' );
-	 *		var strong = new CKEDITOR.dom.element( 'strong' );
-	 *		strong.appendTo( p );
-	 *
-	 *		// Result: '<p><strong></strong></p>'.
-	 *
-	 * @param {CKEDITOR.dom.element} element The target element to which this node will be appended.
-	 * @returns {CKEDITOR.dom.element} The target element.
-	 */
-	appendTo: function( element, toStart ) {
-		element.append( this, toStart );
-		return element;
-	},
-
-	/**
-	 * Clone this node.
-	 *
-	 * **Note**: Values set by {#setCustomData} won't be available in the clone.
-	 *
-	 * @param {Boolean} [includeChildren=false] If `true` then all node's
-	 * children will be cloned recursively.
-	 * @param {Boolean} [cloneId=false] Whether ID attributes should be cloned too.
-	 * @returns {CKEDITOR.dom.node} Clone of this node.
-	 */
-	clone: function( includeChildren, cloneId ) {
-		var $clone = this.$.cloneNode( includeChildren );
-
-		var removeIds = function( node ) {
-				// Reset data-cke-expando only when has been cloned (IE and only for some types of objects).
-				if ( node[ 'data-cke-expando' ] )
-					node[ 'data-cke-expando' ] = false;
-
-				if ( node.nodeType != CKEDITOR.NODE_ELEMENT )
-					return;
-				if ( !cloneId )
-					node.removeAttribute( 'id', false );
-
-				if ( includeChildren ) {
-					var childs = node.childNodes;
-					for ( var i = 0; i < childs.length; i++ )
-						removeIds( childs[ i ] );
-				}
-			};
-
-		// The "id" attribute should never be cloned to avoid duplication.
-		removeIds( $clone );
-
-		return new CKEDITOR.dom.node( $clone );
-	},
-
-	/**
-	 * Check if node is preceded by any sibling.
-	 *
-	 * @returns {Boolean}
-	 */
-	hasPrevious: function() {
-		return !!this.$.previousSibling;
-	},
-
-	/**
-	 * Check if node is succeeded by any sibling.
-	 *
-	 * @returns {Boolean}
-	 */
-	hasNext: function() {
-		return !!this.$.nextSibling;
-	},
-
-	/**
-	 * Inserts this element after a node.
-	 *
-	 *		var em = new CKEDITOR.dom.element( 'em' );
-	 *		var strong = new CKEDITOR.dom.element( 'strong' );
-	 *		strong.insertAfter( em );
-	 *
-	 *		// Result: '<em></em><strong></strong>'
-	 *
-	 * @param {CKEDITOR.dom.node} node The node that will precede this element.
-	 * @returns {CKEDITOR.dom.node} The node preceding this one after insertion.
-	 */
-	insertAfter: function( node ) {
-		node.$.parentNode.insertBefore( this.$, node.$.nextSibling );
-		return node;
-	},
-
-	/**
-	 * Inserts this element before a node.
-	 *
-	 *		var em = new CKEDITOR.dom.element( 'em' );
-	 *		var strong = new CKEDITOR.dom.element( 'strong' );
-	 *		strong.insertBefore( em );
-	 *
-	 *		// result: '<strong></strong><em></em>'
-	 *
-	 * @param {CKEDITOR.dom.node} node The node that will succeed this element.
-	 * @returns {CKEDITOR.dom.node} The node being inserted.
-	 */
-	insertBefore: function( node ) {
-		node.$.parentNode.insertBefore( this.$, node.$ );
-		return node;
-	},
-
-	/**
-	 * Inserts node before this node.
-	 *
-	 *		var em = new CKEDITOR.dom.element( 'em' );
-	 *		var strong = new CKEDITOR.dom.element( 'strong' );
-	 *		strong.insertBeforeMe( em );
-	 *
-	 *		// result: '<em></em><strong></strong>'
-	 *
-	 * @param {CKEDITOR.dom.node} node The node that will preceed this element.
-	 * @returns {CKEDITOR.dom.node} The node being inserted.
-	 */
-	insertBeforeMe: function( node ) {
-		this.$.parentNode.insertBefore( node.$, this.$ );
-		return node;
-	},
-
-	/**
-	 * Retrieves a uniquely identifiable tree address for this node.
-	 * The tree address returned is an array of integers, with each integer
-	 * indicating a child index of a DOM node, starting from
-	 * `document.documentElement`.
-	 *
-	 * For example, assuming `<body>` is the second child
-	 * of `<html>` (`<head>` being the first),
-	 * and we would like to address the third child under the
-	 * fourth child of `<body>`, the tree address returned would be:
-	 * `[1, 3, 2]`.
-	 *
-	 * The tree address cannot be used for finding back the DOM tree node once
-	 * the DOM tree structure has been modified.
-	 *
-	 * @param {Boolean} [normalized=false] See {@link #getIndex}.
-	 * @returns {Array} The address.
-	 */
-	getAddress: function( normalized ) {
-		var address = [];
-		var $documentElement = this.getDocument().$.documentElement;
-		var node = this.$;
-
-		while ( node && node != $documentElement ) {
-			var parentNode = node.parentNode;
-
-			if ( parentNode ) {
-				// Get the node index. For performance, call getIndex
-				// directly, instead of creating a new node object.
-				address.unshift( this.getIndex.call( { $: node }, normalized ) );
-			}
-
-			node = parentNode;
-		}
-
-		return address;
-	},
-
-	/**
-	 * Gets the document containing this element.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'example' );
-	 *		alert( element.getDocument().equals( CKEDITOR.document ) ); // true
-	 *
-	 * @returns {CKEDITOR.dom.document} The document.
-	 */
-	getDocument: function() {
-		return new CKEDITOR.dom.document( this.$.ownerDocument || this.$.parentNode.ownerDocument );
-	},
-
-	/**
-	 * Get index of a node in an array of its parent.childNodes.
-	 *
-	 * Let's assume having childNodes array:
-	 *
-	 *		[ emptyText, element1, text, text, element2 ]
-	 *		element1.getIndex();		// 1
-	 *		element1.getIndex( true );	// 0
-	 *		element2.getIndex();		// 4
-	 *		element2.getIndex( true );	// 2
-	 *
-	 * @param {Boolean} normalized When `true` empty text nodes and one followed
-	 * by another one text node are not counted in.
-	 * @returns {Number} Index of a node.
-	 */
-	getIndex: function( normalized ) {
-		// Attention: getAddress depends on this.$
-		// getIndex is called on a plain object: { $ : node }
-
-		var current = this.$,
-			index = -1,
-			isNormalizing;
-
-		if ( !this.$.parentNode )
-			return index;
-
-		do {
-			// Bypass blank node and adjacent text nodes.
-			if ( normalized && current != this.$ && current.nodeType == CKEDITOR.NODE_TEXT && ( isNormalizing || !current.nodeValue ) )
-				continue;
-
-			index++;
-			isNormalizing = current.nodeType == CKEDITOR.NODE_TEXT;
-		}
-		while ( ( current = current.previousSibling ) )
-
-		return index;
-	},
-
-	/**
-	 * @todo
-	 */
-	getNextSourceNode: function( startFromSibling, nodeType, guard ) {
-		// If "guard" is a node, transform it in a function.
-		if ( guard && !guard.call ) {
-			var guardNode = guard;
-			guard = function( node ) {
-				return !node.equals( guardNode );
-			};
-		}
-
-		var node = ( !startFromSibling && this.getFirst && this.getFirst() ),
-			parent;
-
-		// Guarding when we're skipping the current element( no children or 'startFromSibling' ).
-		// send the 'moving out' signal even we don't actually dive into.
-		if ( !node ) {
-			if ( this.type == CKEDITOR.NODE_ELEMENT && guard && guard( this, true ) === false )
-				return null;
-			node = this.getNext();
-		}
-
-		while ( !node && ( parent = ( parent || this ).getParent() ) ) {
-			// The guard check sends the "true" paramenter to indicate that
-			// we are moving "out" of the element.
-			if ( guard && guard( parent, true ) === false )
-				return null;
-
-			node = parent.getNext();
-		}
-
-		if ( !node )
-			return null;
-
-		if ( guard && guard( node ) === false )
-			return null;
-
-		if ( nodeType && nodeType != node.type )
-			return node.getNextSourceNode( false, nodeType, guard );
-
-		return node;
-	},
-
-	/**
-	 * @todo
-	 */
-	getPreviousSourceNode: function( startFromSibling, nodeType, guard ) {
-		if ( guard && !guard.call ) {
-			var guardNode = guard;
-			guard = function( node ) {
-				return !node.equals( guardNode );
-			};
-		}
-
-		var node = ( !startFromSibling && this.getLast && this.getLast() ),
-			parent;
-
-		// Guarding when we're skipping the current element( no children or 'startFromSibling' ).
-		// send the 'moving out' signal even we don't actually dive into.
-		if ( !node ) {
-			if ( this.type == CKEDITOR.NODE_ELEMENT && guard && guard( this, true ) === false )
-				return null;
-			node = this.getPrevious();
-		}
-
-		while ( !node && ( parent = ( parent || this ).getParent() ) ) {
-			// The guard check sends the "true" paramenter to indicate that
-			// we are moving "out" of the element.
-			if ( guard && guard( parent, true ) === false )
-				return null;
-
-			node = parent.getPrevious();
-		}
-
-		if ( !node )
-			return null;
-
-		if ( guard && guard( node ) === false )
-			return null;
-
-		if ( nodeType && node.type != nodeType )
-			return node.getPreviousSourceNode( false, nodeType, guard );
-
-		return node;
-	},
-
-	/**
-	 * Gets the node that preceed this element in its parent's child list.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<div><i>prev</i><b>Example</b></div>' );
-	 *		var first = element.getLast().getPrev();
-	 *		alert( first.getName() ); // 'i'
-	 *
-	 * @param {Function} [evaluator] Filtering the result node.
-	 * @returns {CKEDITOR.dom.node} The previous node or null if not available.
-	 */
-	getPrevious: function( evaluator ) {
-		var previous = this.$,
-			retval;
-		do {
-			previous = previous.previousSibling;
-
-			// Avoid returning the doc type node.
-			// http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-412266927
-			retval = previous && previous.nodeType != 10 && new CKEDITOR.dom.node( previous );
-		}
-		while ( retval && evaluator && !evaluator( retval ) )
-		return retval;
-	},
-
-	/**
-	 * Gets the node that follows this element in its parent's child list.
-	 *
-	 *		var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b><i>next</i></div>' );
-	 *		var last = element.getFirst().getNext();
-	 *		alert( last.getName() ); // 'i'
-	 *
-	 * @param {Function} [evaluator] Filtering the result node.
-	 * @returns {CKEDITOR.dom.node} The next node or null if not available.
-	 */
-	getNext: function( evaluator ) {
-		var next = this.$,
-			retval;
-		do {
-			next = next.nextSibling;
-			retval = next && new CKEDITOR.dom.node( next );
-		}
-		while ( retval && evaluator && !evaluator( retval ) )
-		return retval;
-	},
-
-	/**
-	 * Gets the parent element for this node.
-	 *
-	 *		var node = editor.document.getBody().getFirst();
-	 *		var parent = node.getParent();
-	 *		alert( parent.getName() ); // 'body'
-	 *
-	 * @param {Boolean} [allowFragmentParent=false] Consider also parent node that is of
-	 * fragment type {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
-	 * @returns {CKEDITOR.dom.element} The parent element.
-	 */
-	getParent: function( allowFragmentParent ) {
-		var parent = this.$.parentNode;
-		return ( parent && ( parent.nodeType == CKEDITOR.NODE_ELEMENT || allowFragmentParent && parent.nodeType == CKEDITOR.NODE_DOCUMENT_FRAGMENT ) ) ? new CKEDITOR.dom.node( parent ) : null;
-	},
-
-	/**
-	 * Returns array containing node parents and node itself. By default nodes are in _descending_ order.
-	 *
-	 *		// Assuming that body has paragraph as first child.
-	 *		var node = editor.document.getBody().getFirst();
-	 *		var parents = node.getParents();
-	 *		alert( parents[ 0 ].getName() + ',' + parents[ 2 ].getName() ); // 'html,p'
-	 *
-	 * @param {Boolean} [closerFirst=false] Determines order of returned nodes.
-	 * @returns {Array} Returns array of {@link CKEDITOR.dom.node}.
-	 */
-	getParents: function( closerFirst ) {
-		var node = this;
-		var parents = [];
-
-		do {
-			parents[ closerFirst ? 'push' : 'unshift' ]( node );
-		}
-		while ( ( node = node.getParent() ) )
-
-		return parents;
-	},
-
-	/**
-	 * @todo
-	 */
-	getCommonAncestor: function( node ) {
-		if ( node.equals( this ) )
-			return this;
-
-		if ( node.contains && node.contains( this ) )
-			return node;
-
-		var start = this.contains ? this : this.getParent();
-
-		do {
-			if ( start.contains( node ) ) return start;
-		}
-		while ( ( start = start.getParent() ) );
-
-		return null;
-	},
-
-	/**
-	 * @todo
-	 */
-	getPosition: function( otherNode ) {
-		var $ = this.$;
-		var $other = otherNode.$;
-
-		if ( $.compareDocumentPosition )
-			return $.compareDocumentPosition( $other );
-
-		// IE and Safari have no support for compareDocumentPosition.
-
-		if ( $ == $other )
-			return CKEDITOR.POSITION_IDENTICAL;
-
-		// Only element nodes support contains and sourceIndex.
-		if ( this.type == CKEDITOR.NODE_ELEMENT && otherNode.type == CKEDITOR.NODE_ELEMENT ) {
-			if ( $.contains ) {
-				if ( $.contains( $other ) )
-					return CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING;
-
-				if ( $other.contains( $ ) )
-					return CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
-			}
-
-			if ( 'sourceIndex' in $ )
-				return ( $.sourceIndex < 0 || $other.sourceIndex < 0 ) ? CKEDITOR.POSITION_DISCONNECTED : ( $.sourceIndex < $other.sourceIndex ) ? CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING;
-
-		}
-
-		// For nodes that don't support compareDocumentPosition, contains
-		// or sourceIndex, their "address" is compared.
-
-		var addressOfThis = this.getAddress(),
-			addressOfOther = otherNode.getAddress(),
-			minLevel = Math.min( addressOfThis.length, addressOfOther.length );
-
-		// Determinate preceed/follow relationship.
-		for ( var i = 0; i <= minLevel - 1; i++ ) {
-			if ( addressOfThis[ i ] != addressOfOther[ i ] ) {
-				if ( i < minLevel )
-					return addressOfThis[ i ] < addressOfOther[ i ] ? CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING;
-
-				break;
-			}
-		}
-
-		// Determinate contains/contained relationship.
-		return ( addressOfThis.length < addressOfOther.length ) ? CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
-	},
-
-	/**
-	 * Gets the closest ancestor node of this node, specified by its name.
-	 *
-	 *		// Suppose we have the following HTML structure:
-	 *		// <div id="outer"><div id="inner"><p><b>Some text</b></p></div></div>
-	 *		// If node == <b>
-	 *		ascendant = node.getAscendant( 'div' );				// ascendant == <div id="inner">
-	 *		ascendant = node.getAscendant( 'b' );				// ascendant == null
-	 *		ascendant = node.getAscendant( 'b', true );			// ascendant == <b>
-	 *		ascendant = node.getAscendant( { div:1,p:1 } );		// Searches for the first 'div' or 'p': ascendant == <div id="inner">
-	 *
-	 * @since 3.6.1
-	 * @param {String} reference The name of the ancestor node to search or
-	 * an object with the node names to search for.
-	 * @param {Boolean} [includeSelf] Whether to include the current
-	 * node in the search.
-	 * @returns {CKEDITOR.dom.node} The located ancestor node or null if not found.
-	 */
-	getAscendant: function( reference, includeSelf ) {
-		var $ = this.$,
-			name;
-
-		if ( !includeSelf )
-			$ = $.parentNode;
-
-		while ( $ ) {
-			if ( $.nodeName && ( name = $.nodeName.toLowerCase(), ( typeof reference == 'string' ? name == reference : name in reference ) ) )
-				return new CKEDITOR.dom.node( $ );
-
-			try {
-				$ = $.parentNode;
-			} catch ( e ) {
-				$ = null;
-			}
-		}
-		return null;
-	},
-
-	/**
-	 * @todo
-	 */
-	hasAscendant: function( name, includeSelf ) {
-		var $ = this.$;
-
-		if ( !includeSelf )
-			$ = $.parentNode;
-
-		while ( $ ) {
-			if ( $.nodeName && $.nodeName.toLowerCase() == name )
-				return true;
-
-			$ = $.parentNode;
-		}
-		return false;
-	},
-
-	/**
-	 * @todo
-	 */
-	move: function( target, toStart ) {
-		target.append( this.remove(), toStart );
-	},
-
-	/**
-	 * Removes this node from the document DOM.
-	 *
-	 *		var element = CKEDITOR.document.getById( 'MyElement' );
-	 *		element.remove();
-	 *
-	 * @param {Boolean} [preserveChildren=false] Indicates that the children
-	 * elements must remain in the document, removing only the outer tags.
-	 */
-	remove: function( preserveChildren ) {
-		var $ = this.$;
-		var parent = $.parentNode;
-
-		if ( parent ) {
-			if ( preserveChildren ) {
-				// Move all children before the node.
-				for ( var child;
-				( child = $.firstChild ); ) {
-					parent.insertBefore( $.removeChild( child ), $ );
-				}
-			}
-
-			parent.removeChild( $ );
-		}
-
-		return this;
-	},
-
-	/**
-	 * @todo
-	 */
-	replace: function( nodeToReplace ) {
-		this.insertBefore( nodeToReplace );
-		nodeToReplace.remove();
-	},
-
-	/**
-	 * @todo
-	 */
-	trim: function() {
-		this.ltrim();
-		this.rtrim();
-	},
-
-	/**
-	 * @todo
-	 */
-	ltrim: function() {
-		var child;
-		while ( this.getFirst && ( child = this.getFirst() ) ) {
-			if ( child.type == CKEDITOR.NODE_TEXT ) {
-				var trimmed = CKEDITOR.tools.ltrim( child.getText() ),
-					originalLength = child.getLength();
-
-				if ( !trimmed ) {
-					child.remove();
-					continue;
-				} else if ( trimmed.length < originalLength ) {
-					child.split( originalLength - trimmed.length );
-
-					// IE BUG: child.remove() may raise JavaScript errors here. (#81)
-					this.$.removeChild( this.$.firstChild );
-				}
-			}
-			break;
-		}
-	},
-
-	/**
-	 * @todo
-	 */
-	rtrim: function() {
-		var child;
-		while ( this.getLast && ( child = this.getLast() ) ) {
-			if ( child.type == CKEDITOR.NODE_TEXT ) {
-				var trimmed = CKEDITOR.tools.rtrim( child.getText() ),
-					originalLength = child.getLength();
-
-				if ( !trimmed ) {
-					child.remove();
-					continue;
-				} else if ( trimmed.length < originalLength ) {
-					child.split( trimmed.length );
-
-					// IE BUG: child.getNext().remove() may raise JavaScript errors here.
-					// (#81)
-					this.$.lastChild.parentNode.removeChild( this.$.lastChild );
-				}
-			}
-			break;
-		}
-
-		if ( CKEDITOR.env.needsBrFiller ) {
-			child = this.$.lastChild;
-
-			if ( child && child.type == 1 && child.nodeName.toLowerCase() == 'br' ) {
-				// Use "eChildNode.parentNode" instead of "node" to avoid IE bug (#324).
-				child.parentNode.removeChild( child );
-			}
-		}
-	},
-
-	/**
-	 * Checks if this node is read-only (should not be changed).
-	 *
-	 * **Note:** When `attributeCheck` is not used, this method only work for elements
-	 * that are already presented in the document, otherwise the result
-	 * is not guaranteed, it's mainly for performance consideration.
-	 *
-	 *		// For the following HTML:
-	 *		// <div contenteditable="false">Some <b>text</b></div>
-	 *
-	 *		// If "ele" is the above <div>
-	 *		element.isReadOnly(); // true
-	 *
-	 * @since 3.5
-	 * @returns {Boolean}
-	 */
-	isReadOnly: function() {
-		var element = this;
-		if ( this.type != CKEDITOR.NODE_ELEMENT )
-			element = this.getParent();
-
-		if ( element && typeof element.$.isContentEditable != 'undefined' )
-			return !( element.$.isContentEditable || element.data( 'cke-editable' ) );
-		else {
-			// Degrade for old browsers which don't support "isContentEditable", e.g. FF3
-
-			while ( element ) {
-				if ( element.data( 'cke-editable' ) )
-					break;
-
-				if ( element.getAttribute( 'contentEditable' ) == 'false' )
-					return true;
-				else if ( element.getAttribute( 'contentEditable' ) == 'true' )
-					break;
-
-				element = element.getParent();
-			}
-
-			// Reached the root of DOM tree, no editable found.
-			return !element;
-		}
-	}
-} );

+ 0 - 43
htdocs/includes/ckeditor/ckeditor/_source/core/dom/nodelist.js

@@ -1,43 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * Represents a list of {@link CKEDITOR.dom.node} objects.
- * It's a wrapper for native nodes list.
- *
- *		var nodeList = CKEDITOR.document.getBody().getChildren();
- *		alert( nodeList.count() ); // number [0;N]
- *
- * @class
- * @constructor Creates a document class instance.
- * @param {Object} nativeList
- */
-CKEDITOR.dom.nodeList = function( nativeList ) {
-	this.$ = nativeList;
-};
-
-CKEDITOR.dom.nodeList.prototype = {
-	/**
-	 * Get count of nodes in this list.
-	 *
-	 * @returns {Number}
-	 */
-	count: function() {
-		return this.$.length;
-	},
-
-	/**
-	 * Get node from the list.
-	 *
-	 * @returns {CKEDITOR.dom.node}
-	 */
-	getItem: function( index ) {
-		if ( index < 0 || index >= this.$.length )
-			return null;
-
-		var $node = this.$[ index ];
-		return $node ? new CKEDITOR.dom.node( $node ) : null;
-	}
-};

+ 0 - 2391
htdocs/includes/ckeditor/ckeditor/_source/core/dom/range.js

@@ -1,2391 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * Represents a delimited piece of content in a DOM Document.
- * It is contiguous in the sense that it can be characterized as selecting all
- * of the content between a pair of boundary-points.
- *
- * This class shares much of the W3C
- * [Document Object Model Range](http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html)
- * ideas and features, adding several range manipulation tools to it, but it's
- * not intended to be compatible with it.
- *
- *		// Create a range for the entire contents of the editor document body.
- *		var range = new CKEDITOR.dom.range( editor.document );
- *		range.selectNodeContents( editor.document.getBody() );
- *		// Delete the contents.
- *		range.deleteContents();
- *
- * @class
- * @constructor Creates a {@link CKEDITOR.dom.range} instance that can be used inside a specific DOM Document.
- * @param {CKEDITOR.dom.document/CKEDITOR.dom.element} root The document or element
- * within which the range will be scoped.
- * @todo global "TODO" - precise algorithms descriptions needed for the most complex methods like #enlarge.
- */
-CKEDITOR.dom.range = function( root ) {
-	/**
-	 * Node within which the range begins.
-	 *
-	 *		var range = new CKEDITOR.dom.range( editor.document );
-	 *		range.selectNodeContents( editor.document.getBody() );
-	 *		alert( range.startContainer.getName() ); // 'body'
-	 *
-	 * @readonly
-	 * @property {CKEDITOR.dom.element/CKEDITOR.dom.text}
-	 */
-	this.startContainer = null;
-
-	/**
-	 * Offset within the starting node of the range.
-	 *
-	 *		var range = new CKEDITOR.dom.range( editor.document );
-	 *		range.selectNodeContents( editor.document.getBody() );
-	 *		alert( range.startOffset ); // 0
-	 *
-	 * @readonly
-	 * @property {Number}
-	 */
-	this.startOffset = null;
-
-	/**
-	 * Node within which the range ends.
-	 *
-	 *		var range = new CKEDITOR.dom.range( editor.document );
-	 *		range.selectNodeContents( editor.document.getBody() );
-	 *		alert( range.endContainer.getName() ); // 'body'
-	 *
-	 * @readonly
-	 * @property {CKEDITOR.dom.element/CKEDITOR.dom.text}
-	 */
-	this.endContainer = null;
-
-	/**
-	 * Offset within the ending node of the range.
-	 *
-	 *		var range = new CKEDITOR.dom.range( editor.document );
-	 *		range.selectNodeContents( editor.document.getBody() );
-	 *		alert( range.endOffset ); // == editor.document.getBody().getChildCount()
-	 *
-	 * @readonly
-	 * @property {Number}
-	 */
-	this.endOffset = null;
-
-	/**
-	 * Indicates that this is a collapsed range. A collapsed range has its
-	 * start and end boundaries at the very same point so nothing is contained
-	 * in it.
-	 *
-	 *		var range = new CKEDITOR.dom.range( editor.document );
-	 *		range.selectNodeContents( editor.document.getBody() );
-	 *		alert( range.collapsed ); // false
-	 *		range.collapse();
-	 *		alert( range.collapsed ); // true
-	 *
-	 * @readonly
-	 */
-	this.collapsed = true;
-
-	var isDocRoot = root instanceof CKEDITOR.dom.document;
-	/**
-	 * The document within which the range can be used.
-	 *
-	 *		// Selects the body contents of the range document.
-	 *		range.selectNodeContents( range.document.getBody() );
-	 *
-	 * @readonly
-	 * @property {CKEDITOR.dom.document}
-	 */
-	this.document = isDocRoot ? root : root.getDocument();
-
-	/**
-	 * The ancestor DOM element within which the range manipulation are limited.
-	 *
-	 * @readonly
-	 * @property {CKEDITOR.dom.element}
-	 */
-	this.root = isDocRoot ? root.getBody() : root;
-};
-
-( function() {
-	// Updates the "collapsed" property for the given range object.
-	var updateCollapsed = function( range ) {
-			range.collapsed = ( range.startContainer && range.endContainer && range.startContainer.equals( range.endContainer ) && range.startOffset == range.endOffset );
-		};
-
-	// This is a shared function used to delete, extract and clone the range
-	// contents.
-	// V2
-	var execContentsAction = function( range, action, docFrag, mergeThen ) {
-			range.optimizeBookmark();
-
-			var startNode = range.startContainer;
-			var endNode = range.endContainer;
-
-			var startOffset = range.startOffset;
-			var endOffset = range.endOffset;
-
-			var removeStartNode;
-			var removeEndNode;
-
-			// For text containers, we must simply split the node and point to the
-			// second part. The removal will be handled by the rest of the code .
-			if ( endNode.type == CKEDITOR.NODE_TEXT )
-				endNode = endNode.split( endOffset );
-			else {
-				// If the end container has children and the offset is pointing
-				// to a child, then we should start from it.
-				if ( endNode.getChildCount() > 0 ) {
-					// If the offset points after the last node.
-					if ( endOffset >= endNode.getChildCount() ) {
-						// Let's create a temporary node and mark it for removal.
-						endNode = endNode.append( range.document.createText( '' ) );
-						removeEndNode = true;
-					} else
-						endNode = endNode.getChild( endOffset );
-				}
-			}
-
-			// For text containers, we must simply split the node. The removal will
-			// be handled by the rest of the code .
-			if ( startNode.type == CKEDITOR.NODE_TEXT ) {
-				startNode.split( startOffset );
-
-				// In cases the end node is the same as the start node, the above
-				// splitting will also split the end, so me must move the end to
-				// the second part of the split.
-				if ( startNode.equals( endNode ) )
-					endNode = startNode.getNext();
-			} else {
-				// If the start container has children and the offset is pointing
-				// to a child, then we should start from its previous sibling.
-
-				// If the offset points to the first node, we don't have a
-				// sibling, so let's use the first one, but mark it for removal.
-				if ( !startOffset ) {
-					// Let's create a temporary node and mark it for removal.
-					startNode = startNode.append( range.document.createText( '' ), 1 );
-					removeStartNode = true;
-				} else if ( startOffset >= startNode.getChildCount() ) {
-					// Let's create a temporary node and mark it for removal.
-					startNode = startNode.append( range.document.createText( '' ) );
-					removeStartNode = true;
-				} else
-					startNode = startNode.getChild( startOffset ).getPrevious();
-			}
-
-			// Get the parent nodes tree for the start and end boundaries.
-			var startParents = startNode.getParents();
-			var endParents = endNode.getParents();
-
-			// Compare them, to find the top most siblings.
-			var i, topStart, topEnd;
-
-			for ( i = 0; i < startParents.length; i++ ) {
-				topStart = startParents[ i ];
-				topEnd = endParents[ i ];
-
-				// The compared nodes will match until we find the top most
-				// siblings (different nodes that have the same parent).
-				// "i" will hold the index in the parents array for the top
-				// most element.
-				if ( !topStart.equals( topEnd ) )
-					break;
-			}
-
-			var clone = docFrag,
-				levelStartNode, levelClone, currentNode, currentSibling;
-
-			// Remove all successive sibling nodes for every node in the
-			// startParents tree.
-			for ( var j = i; j < startParents.length; j++ ) {
-				levelStartNode = startParents[ j ];
-
-				// For Extract and Clone, we must clone this level.
-				if ( clone && !levelStartNode.equals( startNode ) ) // action = 0 = Delete
-				levelClone = clone.append( levelStartNode.clone() );
-
-				currentNode = levelStartNode.getNext();
-
-				while ( currentNode ) {
-					// Stop processing when the current node matches a node in the
-					// endParents tree or if it is the endNode.
-					if ( currentNode.equals( endParents[ j ] ) || currentNode.equals( endNode ) )
-						break;
-
-					// Cache the next sibling.
-					currentSibling = currentNode.getNext();
-
-					// If cloning, just clone it.
-					if ( action == 2 ) // 2 = Clone
-					clone.append( currentNode.clone( true ) );
-					else {
-						// Both Delete and Extract will remove the node.
-						currentNode.remove();
-
-						// When Extracting, move the removed node to the docFrag.
-						if ( action == 1 ) // 1 = Extract
-						clone.append( currentNode );
-					}
-
-					currentNode = currentSibling;
-				}
-
-				if ( clone )
-					clone = levelClone;
-			}
-
-			clone = docFrag;
-
-			// Remove all previous sibling nodes for every node in the
-			// endParents tree.
-			for ( var k = i; k < endParents.length; k++ ) {
-				levelStartNode = endParents[ k ];
-
-				// For Extract and Clone, we must clone this level.
-				if ( action > 0 && !levelStartNode.equals( endNode ) ) // action = 0 = Delete
-				levelClone = clone.append( levelStartNode.clone() );
-
-				// The processing of siblings may have already been done by the parent.
-				if ( !startParents[ k ] || levelStartNode.$.parentNode != startParents[ k ].$.parentNode ) {
-					currentNode = levelStartNode.getPrevious();
-
-					while ( currentNode ) {
-						// Stop processing when the current node matches a node in the
-						// startParents tree or if it is the startNode.
-						if ( currentNode.equals( startParents[ k ] ) || currentNode.equals( startNode ) )
-							break;
-
-						// Cache the next sibling.
-						currentSibling = currentNode.getPrevious();
-
-						// If cloning, just clone it.
-						if ( action == 2 ) // 2 = Clone
-						clone.$.insertBefore( currentNode.$.cloneNode( true ), clone.$.firstChild );
-						else {
-							// Both Delete and Extract will remove the node.
-							currentNode.remove();
-
-							// When Extracting, mode the removed node to the docFrag.
-							if ( action == 1 ) // 1 = Extract
-							clone.$.insertBefore( currentNode.$, clone.$.firstChild );
-						}
-
-						currentNode = currentSibling;
-					}
-				}
-
-				if ( clone )
-					clone = levelClone;
-			}
-
-			if ( action == 2 ) // 2 = Clone.
-			{
-				// No changes in the DOM should be done, so fix the split text (if any).
-
-				var startTextNode = range.startContainer;
-				if ( startTextNode.type == CKEDITOR.NODE_TEXT ) {
-					startTextNode.$.data += startTextNode.$.nextSibling.data;
-					startTextNode.$.parentNode.removeChild( startTextNode.$.nextSibling );
-				}
-
-				var endTextNode = range.endContainer;
-				if ( endTextNode.type == CKEDITOR.NODE_TEXT && endTextNode.$.nextSibling ) {
-					endTextNode.$.data += endTextNode.$.nextSibling.data;
-					endTextNode.$.parentNode.removeChild( endTextNode.$.nextSibling );
-				}
-			} else {
-				// Collapse the range.
-
-				// If a node has been partially selected, collapse the range between
-				// topStart and topEnd. Otherwise, simply collapse it to the start. (W3C specs).
-				if ( topStart && topEnd && ( startNode.$.parentNode != topStart.$.parentNode || endNode.$.parentNode != topEnd.$.parentNode ) ) {
-					var endIndex = topEnd.getIndex();
-
-					// If the start node is to be removed, we must correct the
-					// index to reflect the removal.
-					if ( removeStartNode && topEnd.$.parentNode == startNode.$.parentNode )
-						endIndex--;
-
-					// Merge splitted parents.
-					if ( mergeThen && topStart.type == CKEDITOR.NODE_ELEMENT ) {
-						var span = CKEDITOR.dom.element.createFromHtml( '<span ' +
-							'data-cke-bookmark="1" style="display:none">&nbsp;</span>', range.document );
-						span.insertAfter( topStart );
-						topStart.mergeSiblings( false );
-						range.moveToBookmark( { startNode: span } );
-					} else
-						range.setStart( topEnd.getParent(), endIndex );
-				}
-
-				// Collapse it to the start.
-				range.collapse( true );
-			}
-
-			// Cleanup any marked node.
-			if ( removeStartNode )
-				startNode.remove();
-
-			if ( removeEndNode && endNode.$.parentNode )
-				endNode.remove();
-		};
-
-	var inlineChildReqElements = { abbr: 1, acronym: 1, b: 1, bdo: 1, big: 1, cite: 1, code: 1, del: 1,
-		dfn: 1, em: 1, font: 1, i: 1, ins: 1, label: 1, kbd: 1, q: 1, samp: 1, small: 1, span: 1, strike: 1,
-		strong: 1, sub: 1, sup: 1, tt: 1, u: 1, 'var': 1 };
-
-	// Creates the appropriate node evaluator for the dom walker used inside
-	// check(Start|End)OfBlock.
-	function getCheckStartEndBlockEvalFunction() {
-		var skipBogus = false,
-			whitespaces = CKEDITOR.dom.walker.whitespaces(),
-			bookmarkEvaluator = CKEDITOR.dom.walker.bookmark( true ),
-			isBogus = CKEDITOR.dom.walker.bogus();
-
-		return function( node ) {
-			// First skip empty nodes
-			if ( bookmarkEvaluator( node ) || whitespaces( node ) )
-				return true;
-
-			// Skip the bogus node at the end of block.
-			if ( isBogus( node ) && !skipBogus ) {
-				skipBogus = true;
-				return true;
-			}
-
-			// If there's any visible text, then we're not at the start.
-			if ( node.type == CKEDITOR.NODE_TEXT &&
-					 ( node.hasAscendant( 'pre' ) ||
-						 CKEDITOR.tools.trim( node.getText() ).length ) )
-				return false;
-
-			// If there are non-empty inline elements (e.g. <img />), then we're not
-			// at the start.
-			if ( node.type == CKEDITOR.NODE_ELEMENT && !node.is( inlineChildReqElements ) )
-				return false;
-
-			return true;
-		};
-	}
-
-
-	var isBogus = CKEDITOR.dom.walker.bogus(),
-		nbspRegExp = /^[\t\r\n ]*(?:&nbsp;|\xa0)$/,
-		editableEval = CKEDITOR.dom.walker.editable(),
-		notIgnoredEval = CKEDITOR.dom.walker.ignored( true );
-
-	// Evaluator for CKEDITOR.dom.element::checkBoundaryOfElement, reject any
-	// text node and non-empty elements unless it's being bookmark text.
-	function elementBoundaryEval( checkStart ) {
-		var whitespaces = CKEDITOR.dom.walker.whitespaces(),
-			bookmark = CKEDITOR.dom.walker.bookmark( 1 );
-
-		return function( node ) {
-			// First skip empty nodes.
-			if ( bookmark( node ) || whitespaces( node ) )
-				return true;
-
-			// Tolerant bogus br when checking at the end of block.
-			// Reject any text node unless it's being bookmark
-			// OR it's spaces.
-			// Reject any element unless it's being invisible empty. (#3883)
-			return !checkStart && isBogus( node ) ||
-						 node.type == CKEDITOR.NODE_ELEMENT &&
-						 node.is( CKEDITOR.dtd.$removeEmpty );
-		};
-	}
-
-	function getNextEditableNode( isPrevious ) {
-		return function() {
-			var first;
-
-			return this[ isPrevious ? 'getPreviousNode' : 'getNextNode' ]( function( node ) {
-				// Cache first not ignorable node.
-				if ( !first && notIgnoredEval( node ) )
-					first = node;
-
-				// Return true if found editable node, but not a bogus next to start of our lookup (first != bogus).
-				return editableEval( node ) && !( isBogus( node ) && node.equals( first ) );
-			} );
-		};
-	}
-
-	CKEDITOR.dom.range.prototype = {
-		/**
-		 * Clones this range.
-		 *
-		 * @returns {CKEDITOR.dom.range}
-		 */
-		clone: function() {
-			var clone = new CKEDITOR.dom.range( this.root );
-
-			clone.startContainer = this.startContainer;
-			clone.startOffset = this.startOffset;
-			clone.endContainer = this.endContainer;
-			clone.endOffset = this.endOffset;
-			clone.collapsed = this.collapsed;
-
-			return clone;
-		},
-
-		/**
-		 * Makes range collapsed by moving its start point (or end point if `toStart==true`)
-		 * to the second end.
-		 *
-		 * @param {Boolean} toStart Collapse range "to start".
-		 */
-		collapse: function( toStart ) {
-			if ( toStart ) {
-				this.endContainer = this.startContainer;
-				this.endOffset = this.startOffset;
-			} else {
-				this.startContainer = this.endContainer;
-				this.startOffset = this.endOffset;
-			}
-
-			this.collapsed = true;
-		},
-
-		/**
-		 * The content nodes of the range are cloned and added to a document fragment, which is returned.
-		 *
-		 * **Note:** Text selection may lost after invoking this method (caused by text node splitting).
-		 *
-		 * @returns {CKEDITOR.dom.documentFragment} Document fragment containing clone of range's content.
-		 */
-		cloneContents: function() {
-			var docFrag = new CKEDITOR.dom.documentFragment( this.document );
-
-			if ( !this.collapsed )
-				execContentsAction( this, 2, docFrag );
-
-			return docFrag;
-		},
-
-		/**
-		 * Deletes the content nodes of the range permanently from the DOM tree.
-		 *
-		 * @param {Boolean} [mergeThen] Merge any splitted elements result in DOM true due to partial selection.
-		 */
-		deleteContents: function( mergeThen ) {
-			if ( this.collapsed )
-				return;
-
-			execContentsAction( this, 0, null, mergeThen );
-		},
-
-		/**
-		 * The content nodes of the range are cloned and added to a document fragment,
-		 * meanwhile they are removed permanently from the DOM tree.
-		 *
-		 * @param {Boolean} [mergeThen] Merge any splitted elements result in DOM true due to partial selection.
-		 * @returns {CKEDITOR.dom.documentFragment} Document fragment containing extracted content.
-		 */
-		extractContents: function( mergeThen ) {
-			var docFrag = new CKEDITOR.dom.documentFragment( this.document );
-
-			if ( !this.collapsed )
-				execContentsAction( this, 1, docFrag, mergeThen );
-
-			return docFrag;
-		},
-
-		/**
-		 * Creates a bookmark object, which can be later used to restore the
-		 * range by using the {@link #moveToBookmark} function.
-		 *
-		 * This is an "intrusive" way to create a bookmark. It includes `<span>` tags
-		 * in the range boundaries. The advantage of it is that it is possible to
-		 * handle DOM mutations when moving back to the bookmark.
-		 *
-		 * **Note:** The inclusion of nodes in the DOM is a design choice and
-		 * should not be changed as there are other points in the code that may be
-		 * using those nodes to perform operations.
-		 *
-		 * @param {Boolean} [serializable] Indicates that the bookmark nodes
-		 * must contain IDs, which can be used to restore the range even
-		 * when these nodes suffer mutations (like cloning or `innerHTML` change).
-		 * @returns {Object} And object representing a bookmark.
-		 * @returns {CKEDITOR.dom.node/String} return.startNode Node or element ID.
-		 * @returns {CKEDITOR.dom.node/String} return.endNode Node or element ID.
-		 * @returns {Boolean} return.serializable
-		 * @returns {Boolean} return.collapsed
-		 */
-		createBookmark: function( serializable ) {
-			var startNode, endNode;
-			var baseId;
-			var clone;
-			var collapsed = this.collapsed;
-
-			startNode = this.document.createElement( 'span' );
-			startNode.data( 'cke-bookmark', 1 );
-			startNode.setStyle( 'display', 'none' );
-
-			// For IE, it must have something inside, otherwise it may be
-			// removed during DOM operations.
-			startNode.setHtml( '&nbsp;' );
-
-			if ( serializable ) {
-				baseId = 'cke_bm_' + CKEDITOR.tools.getNextNumber();
-				startNode.setAttribute( 'id', baseId + ( collapsed ? 'C' : 'S' ) );
-			}
-
-			// If collapsed, the endNode will not be created.
-			if ( !collapsed ) {
-				endNode = startNode.clone();
-				endNode.setHtml( '&nbsp;' );
-
-				if ( serializable )
-					endNode.setAttribute( 'id', baseId + 'E' );
-
-				clone = this.clone();
-				clone.collapse();
-				clone.insertNode( endNode );
-			}
-
-			clone = this.clone();
-			clone.collapse( true );
-			clone.insertNode( startNode );
-
-			// Update the range position.
-			if ( endNode ) {
-				this.setStartAfter( startNode );
-				this.setEndBefore( endNode );
-			} else
-				this.moveToPosition( startNode, CKEDITOR.POSITION_AFTER_END );
-
-			return {
-				startNode: serializable ? baseId + ( collapsed ? 'C' : 'S' ) : startNode,
-				endNode: serializable ? baseId + 'E' : endNode,
-				serializable: serializable,
-				collapsed: collapsed
-			};
-		},
-
-		/**
-		 * Creates a "non intrusive" and "mutation sensible" bookmark. This
-		 * kind of bookmark should be used only when the DOM is supposed to
-		 * remain stable after its creation.
-		 *
-		 * @param {Boolean} [normalized] Indicates that the bookmark must
-		 * be normalized. When normalized, the successive text nodes are
-		 * considered a single node. To successfully load a normalized
-		 * bookmark, the DOM tree must also be normalized before calling
-		 * {@link #moveToBookmark}.
-		 * @returns {Object} An object representing the bookmark.
-		 * @returns {Array} return.start Start container's address (see {@link CKEDITOR.dom.node#getAddress}).
-		 * @returns {Array} return.end Start container's address.
-		 * @returns {Number} return.startOffset
-		 * @returns {Number} return.endOffset
-		 * @returns {Boolean} return.collapsed
-		 * @returns {Boolean} return.normalized
-		 * @returns {Boolean} return.is2 This is "bookmark2".
-		 */
-		createBookmark2: ( function() {
-			// Returns true for limit anchored in element and placed between text nodes.
-			//
-			//               v
-			// <p>[text node] [text node]</p> -> true
-			//
-			//    v
-			// <p> [text node]</p> -> false
-			//
-			//              v
-			// <p>[text node][text node]</p> -> false (limit is anchored in text node)
-			function betweenTextNodes( container, offset ) {
-				// Not anchored in element or limit is on the edge.
-				if ( container.type != CKEDITOR.NODE_ELEMENT || offset === 0 || offset == container.getChildCount() )
-					return 0;
-
-				return container.getChild( offset - 1 ).type == CKEDITOR.NODE_TEXT &&
-					container.getChild( offset ).type == CKEDITOR.NODE_TEXT;
-			}
-
-			// Sums lengths of all preceding text nodes.
-			function getLengthOfPrecedingTextNodes( node ) {
-				var sum = 0;
-
-				while ( ( node = node.getPrevious() ) && node.type == CKEDITOR.NODE_TEXT )
-					sum += node.getLength();
-
-				return sum;
-			}
-
-			function normalize( limit ) {
-				var container = limit.container,
-					offset = limit.offset;
-
-				// If limit is between text nodes move it to the end of preceding one,
-				// because they will be merged.
-				if ( betweenTextNodes( container, offset ) ) {
-					container = container.getChild( offset - 1 );
-					offset = container.getLength();
-				}
-
-				// Now, if limit is anchored in element and has at least two nodes before it,
-				// it may happen that some of them will be merged. Normalize the offset
-				// by setting it to normalized index of its preceding node.
-				if ( container.type == CKEDITOR.NODE_ELEMENT && offset > 1 )
-					offset = container.getChild( offset - 1 ).getIndex( true ) + 1;
-
-				// The last step - fix the offset inside text node by adding
-				// lengths of preceding text nodes which will be merged with container.
-				if ( container.type == CKEDITOR.NODE_TEXT )
-					offset += getLengthOfPrecedingTextNodes( container );
-
-				limit.container = container;
-				limit.offset = offset;
-			}
-
-			return function( normalized ) {
-				var collapsed = this.collapsed,
-					bmStart = {
-						container: this.startContainer,
-						offset: this.startOffset
-					},
-					bmEnd = {
-						container: this.endContainer,
-						offset: this.endOffset
-					};
-
-				if ( normalized ) {
-					normalize( bmStart );
-
-					if ( !collapsed )
-						normalize( bmEnd );
-				}
-
-				return {
-					start: bmStart.container.getAddress( normalized ),
-					end: collapsed ? null : bmEnd.container.getAddress( normalized ),
-					startOffset: bmStart.offset,
-					endOffset: bmEnd.offset,
-					normalized: normalized,
-					collapsed: collapsed,
-					is2: true // It's a createBookmark2 bookmark.
-				};
-			};
-		} )(),
-
-		/**
-		 * Moves this range to the given bookmark. See {@link #createBookmark} and {@link #createBookmark2}.
-		 *
-		 * If serializable bookmark passed, then its `<span>` markers will be removed.
-		 *
-		 * @param {Object} bookmark
-		 */
-		moveToBookmark: function( bookmark ) {
-			if ( bookmark.is2 ) // Created with createBookmark2().
-			{
-				// Get the start information.
-				var startContainer = this.document.getByAddress( bookmark.start, bookmark.normalized ),
-					startOffset = bookmark.startOffset;
-
-				// Get the end information.
-				var endContainer = bookmark.end && this.document.getByAddress( bookmark.end, bookmark.normalized ),
-					endOffset = bookmark.endOffset;
-
-				// Set the start boundary.
-				this.setStart( startContainer, startOffset );
-
-				// Set the end boundary. If not available, collapse it.
-				if ( endContainer )
-					this.setEnd( endContainer, endOffset );
-				else
-					this.collapse( true );
-			} else // Created with createBookmark().
-			{
-				var serializable = bookmark.serializable,
-					startNode = serializable ? this.document.getById( bookmark.startNode ) : bookmark.startNode,
-					endNode = serializable ? this.document.getById( bookmark.endNode ) : bookmark.endNode;
-
-				// Set the range start at the bookmark start node position.
-				this.setStartBefore( startNode );
-
-				// Remove it, because it may interfere in the setEndBefore call.
-				startNode.remove();
-
-				// Set the range end at the bookmark end node position, or simply
-				// collapse it if it is not available.
-				if ( endNode ) {
-					this.setEndBefore( endNode );
-					endNode.remove();
-				} else
-					this.collapse( true );
-			}
-		},
-
-		/**
-		 * Returns two nodes which are on the boundaries of this range.
-		 *
-		 * @returns {Object}
-		 * @returns {CKEDITOR.dom.node} return.startNode
-		 * @returns {CKEDITOR.dom.node} return.endNode
-		 * @todo precise desc/algorithm
-		 */
-		getBoundaryNodes: function() {
-			var startNode = this.startContainer,
-				endNode = this.endContainer,
-				startOffset = this.startOffset,
-				endOffset = this.endOffset,
-				childCount;
-
-			if ( startNode.type == CKEDITOR.NODE_ELEMENT ) {
-				childCount = startNode.getChildCount();
-				if ( childCount > startOffset )
-					startNode = startNode.getChild( startOffset );
-				else if ( childCount < 1 )
-					startNode = startNode.getPreviousSourceNode();
-				else // startOffset > childCount but childCount is not 0
-				{
-					// Try to take the node just after the current position.
-					startNode = startNode.$;
-					while ( startNode.lastChild )
-						startNode = startNode.lastChild;
-					startNode = new CKEDITOR.dom.node( startNode );
-
-					// Normally we should take the next node in DFS order. But it
-					// is also possible that we've already reached the end of
-					// document.
-					startNode = startNode.getNextSourceNode() || startNode;
-				}
-			}
-			if ( endNode.type == CKEDITOR.NODE_ELEMENT ) {
-				childCount = endNode.getChildCount();
-				if ( childCount > endOffset )
-					endNode = endNode.getChild( endOffset ).getPreviousSourceNode( true );
-				else if ( childCount < 1 )
-					endNode = endNode.getPreviousSourceNode();
-				else // endOffset > childCount but childCount is not 0
-				{
-					// Try to take the node just before the current position.
-					endNode = endNode.$;
-					while ( endNode.lastChild )
-						endNode = endNode.lastChild;
-					endNode = new CKEDITOR.dom.node( endNode );
-				}
-			}
-
-			// Sometimes the endNode will come right before startNode for collapsed
-			// ranges. Fix it. (#3780)
-			if ( startNode.getPosition( endNode ) & CKEDITOR.POSITION_FOLLOWING )
-				startNode = endNode;
-
-			return { startNode: startNode, endNode: endNode };
-		},
-
-		/**
-		 * Find the node which fully contains the range.
-		 *
-		 * @param {Boolean} [includeSelf=false]
-		 * @param {Boolean} [ignoreTextNode=false] Whether ignore {@link CKEDITOR#NODE_TEXT} type.
-		 * @returns {CKEDITOR.dom.element}
-		 */
-		getCommonAncestor: function( includeSelf, ignoreTextNode ) {
-			var start = this.startContainer,
-				end = this.endContainer,
-				ancestor;
-
-			if ( start.equals( end ) ) {
-				if ( includeSelf && start.type == CKEDITOR.NODE_ELEMENT && this.startOffset == this.endOffset - 1 )
-					ancestor = start.getChild( this.startOffset );
-				else
-					ancestor = start;
-			} else
-				ancestor = start.getCommonAncestor( end );
-
-			return ignoreTextNode && !ancestor.is ? ancestor.getParent() : ancestor;
-		},
-
-		/**
-		 * Transforms the {@link #startContainer} and {@link #endContainer} properties from text
-		 * nodes to element nodes, whenever possible. This is actually possible
-		 * if either of the boundary containers point to a text node, and its
-		 * offset is set to zero, or after the last char in the node.
-		 */
-		optimize: function() {
-			var container = this.startContainer;
-			var offset = this.startOffset;
-
-			if ( container.type != CKEDITOR.NODE_ELEMENT ) {
-				if ( !offset )
-					this.setStartBefore( container );
-				else if ( offset >= container.getLength() )
-					this.setStartAfter( container );
-			}
-
-			container = this.endContainer;
-			offset = this.endOffset;
-
-			if ( container.type != CKEDITOR.NODE_ELEMENT ) {
-				if ( !offset )
-					this.setEndBefore( container );
-				else if ( offset >= container.getLength() )
-					this.setEndAfter( container );
-			}
-		},
-
-		/**
-		 * Move the range out of bookmark nodes if they'd been the container.
-		 */
-		optimizeBookmark: function() {
-			var startNode = this.startContainer,
-				endNode = this.endContainer;
-
-			if ( startNode.is && startNode.is( 'span' ) && startNode.data( 'cke-bookmark' ) )
-				this.setStartAt( startNode, CKEDITOR.POSITION_BEFORE_START );
-			if ( endNode && endNode.is && endNode.is( 'span' ) && endNode.data( 'cke-bookmark' ) )
-				this.setEndAt( endNode, CKEDITOR.POSITION_AFTER_END );
-		},
-
-		/**
-		 * @param {Boolean} [ignoreStart=false]
-		 * @param {Boolean} [ignoreEnd=false]
-		 * @todo precise desc/algorithm
-		 */
-		trim: function( ignoreStart, ignoreEnd ) {
-			var startContainer = this.startContainer,
-				startOffset = this.startOffset,
-				collapsed = this.collapsed;
-			if ( ( !ignoreStart || collapsed ) && startContainer && startContainer.type == CKEDITOR.NODE_TEXT ) {
-				// If the offset is zero, we just insert the new node before
-				// the start.
-				if ( !startOffset ) {
-					startOffset = startContainer.getIndex();
-					startContainer = startContainer.getParent();
-				}
-				// If the offset is at the end, we'll insert it after the text
-				// node.
-				else if ( startOffset >= startContainer.getLength() ) {
-					startOffset = startContainer.getIndex() + 1;
-					startContainer = startContainer.getParent();
-				}
-				// In other case, we split the text node and insert the new
-				// node at the split point.
-				else {
-					var nextText = startContainer.split( startOffset );
-
-					startOffset = startContainer.getIndex() + 1;
-					startContainer = startContainer.getParent();
-
-					// Check all necessity of updating the end boundary.
-					if ( this.startContainer.equals( this.endContainer ) )
-						this.setEnd( nextText, this.endOffset - this.startOffset );
-					else if ( startContainer.equals( this.endContainer ) )
-						this.endOffset += 1;
-				}
-
-				this.setStart( startContainer, startOffset );
-
-				if ( collapsed ) {
-					this.collapse( true );
-					return;
-				}
-			}
-
-			var endContainer = this.endContainer;
-			var endOffset = this.endOffset;
-
-			if ( !( ignoreEnd || collapsed ) && endContainer && endContainer.type == CKEDITOR.NODE_TEXT ) {
-				// If the offset is zero, we just insert the new node before
-				// the start.
-				if ( !endOffset ) {
-					endOffset = endContainer.getIndex();
-					endContainer = endContainer.getParent();
-				}
-				// If the offset is at the end, we'll insert it after the text
-				// node.
-				else if ( endOffset >= endContainer.getLength() ) {
-					endOffset = endContainer.getIndex() + 1;
-					endContainer = endContainer.getParent();
-				}
-				// In other case, we split the text node and insert the new
-				// node at the split point.
-				else {
-					endContainer.split( endOffset );
-
-					endOffset = endContainer.getIndex() + 1;
-					endContainer = endContainer.getParent();
-				}
-
-				this.setEnd( endContainer, endOffset );
-			}
-		},
-
-		/**
-		 * Expands the range so that partial units are completely contained.
-		 *
-		 * @param unit {Number} The unit type to expand with.
-		 * @param {Boolean} [excludeBrs=false] Whether include line-breaks when expanding.
-		 */
-		enlarge: function( unit, excludeBrs ) {
-			var leadingWhitespaceRegex = new RegExp( /[^\s\ufeff]/ );
-
-			switch ( unit ) {
-				case CKEDITOR.ENLARGE_INLINE:
-					var enlargeInlineOnly = 1;
-					/*jsl:fallthru*/
-				case CKEDITOR.ENLARGE_ELEMENT:
-
-					if ( this.collapsed )
-						return;
-
-					// Get the common ancestor.
-					var commonAncestor = this.getCommonAncestor();
-
-					var boundary = this.root;
-
-					// For each boundary
-					//		a. Depending on its position, find out the first node to be checked (a sibling) or, if not available, to be enlarge.
-					//		b. Go ahead checking siblings and enlarging the boundary as much as possible until the common ancestor is not reached. After reaching the common ancestor, just save the enlargeable node to be used later.
-
-					var startTop, endTop;
-
-					var enlargeable, sibling, commonReached;
-
-					// Indicates that the node can be added only if whitespace
-					// is available before it.
-					var needsWhiteSpace = false;
-					var isWhiteSpace;
-					var siblingText;
-
-					// Process the start boundary.
-
-					var container = this.startContainer;
-					var offset = this.startOffset;
-
-					if ( container.type == CKEDITOR.NODE_TEXT ) {
-						if ( offset ) {
-							// Check if there is any non-space text before the
-							// offset. Otherwise, container is null.
-							container = !CKEDITOR.tools.trim( container.substring( 0, offset ) ).length && container;
-
-							// If we found only whitespace in the node, it
-							// means that we'll need more whitespace to be able
-							// to expand. For example, <i> can be expanded in
-							// "A <i> [B]</i>", but not in "A<i> [B]</i>".
-							needsWhiteSpace = !!container;
-						}
-
-						if ( container ) {
-							if ( !( sibling = container.getPrevious() ) )
-								enlargeable = container.getParent();
-						}
-					} else {
-						// If we have offset, get the node preceeding it as the
-						// first sibling to be checked.
-						if ( offset )
-							sibling = container.getChild( offset - 1 ) || container.getLast();
-
-						// If there is no sibling, mark the container to be
-						// enlarged.
-						if ( !sibling )
-							enlargeable = container;
-					}
-
-					// Ensures that enlargeable can be indeed enlarged, if not it will be nulled.
-					enlargeable = getValidEnlargeable( enlargeable );
-
-					while ( enlargeable || sibling ) {
-						if ( enlargeable && !sibling ) {
-							// If we reached the common ancestor, mark the flag
-							// for it.
-							if ( !commonReached && enlargeable.equals( commonAncestor ) )
-								commonReached = true;
-
-							if ( enlargeInlineOnly ? enlargeable.isBlockBoundary() : !boundary.contains( enlargeable ) )
-								break;
-
-							// If we don't need space or this element breaks
-							// the line, then enlarge it.
-							if ( !needsWhiteSpace || enlargeable.getComputedStyle( 'display' ) != 'inline' ) {
-								needsWhiteSpace = false;
-
-								// If the common ancestor has been reached,
-								// we'll not enlarge it immediately, but just
-								// mark it to be enlarged later if the end
-								// boundary also enlarges it.
-								if ( commonReached )
-									startTop = enlargeable;
-								else
-									this.setStartBefore( enlargeable );
-							}
-
-							sibling = enlargeable.getPrevious();
-						}
-
-						// Check all sibling nodes preceeding the enlargeable
-						// node. The node wil lbe enlarged only if none of them
-						// blocks it.
-						while ( sibling ) {
-							// This flag indicates that this node has
-							// whitespaces at the end.
-							isWhiteSpace = false;
-
-							if ( sibling.type == CKEDITOR.NODE_COMMENT ) {
-								sibling = sibling.getPrevious();
-								continue;
-							} else if ( sibling.type == CKEDITOR.NODE_TEXT ) {
-								siblingText = sibling.getText();
-
-								if ( leadingWhitespaceRegex.test( siblingText ) )
-									sibling = null;
-
-								isWhiteSpace = /[\s\ufeff]$/.test( siblingText );
-							} else {
-								// If this is a visible element.
-								// We need to check for the bookmark attribute because IE insists on
-								// rendering the display:none nodes we use for bookmarks. (#3363)
-								// Line-breaks (br) are rendered with zero width, which we don't want to include. (#7041)
-								if ( ( sibling.$.offsetWidth > 0 || excludeBrs && sibling.is( 'br' ) ) && !sibling.data( 'cke-bookmark' ) ) {
-									// We'll accept it only if we need
-									// whitespace, and this is an inline
-									// element with whitespace only.
-									if ( needsWhiteSpace && CKEDITOR.dtd.$removeEmpty[ sibling.getName() ] ) {
-										// It must contains spaces and inline elements only.
-
-										siblingText = sibling.getText();
-
-										if ( leadingWhitespaceRegex.test( siblingText ) ) // Spaces + Zero Width No-Break Space (U+FEFF)
-										sibling = null;
-										else {
-											var allChildren = sibling.$.getElementsByTagName( '*' );
-											for ( var i = 0, child; child = allChildren[ i++ ]; ) {
-												if ( !CKEDITOR.dtd.$removeEmpty[ child.nodeName.toLowerCase() ] ) {
-													sibling = null;
-													break;
-												}
-											}
-										}
-
-										if ( sibling )
-											isWhiteSpace = !!siblingText.length;
-									} else
-										sibling = null;
-								}
-							}
-
-							// A node with whitespaces has been found.
-							if ( isWhiteSpace ) {
-								// Enlarge the last enlargeable node, if we
-								// were waiting for spaces.
-								if ( needsWhiteSpace ) {
-									if ( commonReached )
-										startTop = enlargeable;
-									else if ( enlargeable )
-										this.setStartBefore( enlargeable );
-								} else
-									needsWhiteSpace = true;
-							}
-
-							if ( sibling ) {
-								var next = sibling.getPrevious();
-
-								if ( !enlargeable && !next ) {
-									// Set the sibling as enlargeable, so it's
-									// parent will be get later outside this while.
-									enlargeable = sibling;
-									sibling = null;
-									break;
-								}
-
-								sibling = next;
-							} else {
-								// If sibling has been set to null, then we
-								// need to stop enlarging.
-								enlargeable = null;
-							}
-						}
-
-						if ( enlargeable )
-							enlargeable = getValidEnlargeable( enlargeable.getParent() );
-					}
-
-					// Process the end boundary. This is basically the same
-					// code used for the start boundary, with small changes to
-					// make it work in the oposite side (to the right). This
-					// makes it difficult to reuse the code here. So, fixes to
-					// the above code are likely to be replicated here.
-
-					container = this.endContainer;
-					offset = this.endOffset;
-
-					// Reset the common variables.
-					enlargeable = sibling = null;
-					commonReached = needsWhiteSpace = false;
-
-					// Function check if there are only whitespaces from the given starting point
-					// (startContainer and startOffset) till the end on block.
-					// Examples ("[" is the start point):
-					//  - <p>foo[ </p>           - will return true,
-					//  - <p><b>foo[ </b> </p>   - will return true,
-					//  - <p>foo[ bar</p>        - will return false,
-					//  - <p><b>foo[ </b>bar</p> - will return false,
-					//  - <p>foo[ <b></b></p>    - will return false.
-					function onlyWhiteSpaces( startContainer, startOffset ) {
-						// We need to enlarge range if there is white space at the end of the block,
-						// because it is not displayed in WYSIWYG mode and user can not select it. So
-						// "<p>foo[bar] </p>" should be changed to "<p>foo[bar ]</p>". On the other hand
-						// we should do nothing if we are not at the end of the block, so this should not
-						// be changed: "<p><i>[foo] </i>bar</p>".
-						var walkerRange = new CKEDITOR.dom.range( boundary );
-						walkerRange.setStart( startContainer, startOffset );
-						// The guard will find the end of range so I put boundary here.
-						walkerRange.setEndAt( boundary, CKEDITOR.POSITION_BEFORE_END );
-
-						var walker = new CKEDITOR.dom.walker( walkerRange ),
-							node;
-
-						walker.guard = function( node, movingOut ) {
-							// Stop if you exit block.
-							return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary() );
-						};
-
-						while ( ( node = walker.next() ) ) {
-							if ( node.type != CKEDITOR.NODE_TEXT ) {
-								// Stop if you enter to any node (walker.next() will return node only
-								// it goes out, not if it is go into node).
-								return false;
-							} else {
-								// Trim the first node to startOffset.
-								if ( node != startContainer )
-									siblingText = node.getText();
-								else
-									siblingText = node.substring( startOffset );
-
-								// Check if it is white space.
-								if ( leadingWhitespaceRegex.test( siblingText ) )
-									return false;
-							}
-						}
-
-						return true;
-					}
-
-					if ( container.type == CKEDITOR.NODE_TEXT ) {
-						// Check if there is only white space after the offset.
-						if ( CKEDITOR.tools.trim( container.substring( offset ) ).length ) {
-							// If we found only whitespace in the node, it
-							// means that we'll need more whitespace to be able
-							// to expand. For example, <i> can be expanded in
-							// "A <i> [B]</i>", but not in "A<i> [B]</i>".
-							needsWhiteSpace = true;
-						} else {
-							needsWhiteSpace = !container.getLength();
-
-							if ( offset == container.getLength() ) {
-								// If we are at the end of container and this is the last text node,
-								// we should enlarge end to the parent.
-								if ( !( sibling = container.getNext() ) )
-									enlargeable = container.getParent();
-							} else {
-								// If we are in the middle on text node and there are only whitespaces
-								// till the end of block, we should enlarge element.
-								if ( onlyWhiteSpaces( container, offset ) )
-									enlargeable = container.getParent();
-							}
-						}
-					} else {
-						// Get the node right after the boudary to be checked
-						// first.
-						sibling = container.getChild( offset );
-
-						if ( !sibling )
-							enlargeable = container;
-					}
-
-					while ( enlargeable || sibling ) {
-						if ( enlargeable && !sibling ) {
-							if ( !commonReached && enlargeable.equals( commonAncestor ) )
-								commonReached = true;
-
-							if ( enlargeInlineOnly ? enlargeable.isBlockBoundary() : !boundary.contains( enlargeable ) )
-								break;
-
-							if ( !needsWhiteSpace || enlargeable.getComputedStyle( 'display' ) != 'inline' ) {
-								needsWhiteSpace = false;
-
-								if ( commonReached )
-									endTop = enlargeable;
-								else if ( enlargeable )
-									this.setEndAfter( enlargeable );
-							}
-
-							sibling = enlargeable.getNext();
-						}
-
-						while ( sibling ) {
-							isWhiteSpace = false;
-
-							if ( sibling.type == CKEDITOR.NODE_TEXT ) {
-								siblingText = sibling.getText();
-
-								// Check if there are not whitespace characters till the end of editable.
-								// If so stop expanding.
-								if ( !onlyWhiteSpaces( sibling, 0 ) )
-									sibling = null;
-
-								isWhiteSpace = /^[\s\ufeff]/.test( siblingText );
-							} else if ( sibling.type == CKEDITOR.NODE_ELEMENT ) {
-								// If this is a visible element.
-								// We need to check for the bookmark attribute because IE insists on
-								// rendering the display:none nodes we use for bookmarks. (#3363)
-								// Line-breaks (br) are rendered with zero width, which we don't want to include. (#7041)
-								if ( ( sibling.$.offsetWidth > 0 || excludeBrs && sibling.is( 'br' ) ) && !sibling.data( 'cke-bookmark' ) ) {
-									// We'll accept it only if we need
-									// whitespace, and this is an inline
-									// element with whitespace only.
-									if ( needsWhiteSpace && CKEDITOR.dtd.$removeEmpty[ sibling.getName() ] ) {
-										// It must contains spaces and inline elements only.
-
-										siblingText = sibling.getText();
-
-										if ( leadingWhitespaceRegex.test( siblingText ) )
-											sibling = null;
-										else {
-											allChildren = sibling.$.getElementsByTagName( '*' );
-											for ( i = 0; child = allChildren[ i++ ]; ) {
-												if ( !CKEDITOR.dtd.$removeEmpty[ child.nodeName.toLowerCase() ] ) {
-													sibling = null;
-													break;
-												}
-											}
-										}
-
-										if ( sibling )
-											isWhiteSpace = !!siblingText.length;
-									} else
-										sibling = null;
-								}
-							} else
-								isWhiteSpace = 1;
-
-							if ( isWhiteSpace ) {
-								if ( needsWhiteSpace ) {
-									if ( commonReached )
-										endTop = enlargeable;
-									else
-										this.setEndAfter( enlargeable );
-								}
-							}
-
-							if ( sibling ) {
-								next = sibling.getNext();
-
-								if ( !enlargeable && !next ) {
-									enlargeable = sibling;
-									sibling = null;
-									break;
-								}
-
-								sibling = next;
-							} else {
-								// If sibling has been set to null, then we
-								// need to stop enlarging.
-								enlargeable = null;
-							}
-						}
-
-						if ( enlargeable )
-							enlargeable = getValidEnlargeable( enlargeable.getParent() );
-					}
-
-					// If the common ancestor can be enlarged by both boundaries, then include it also.
-					if ( startTop && endTop ) {
-						commonAncestor = startTop.contains( endTop ) ? endTop : startTop;
-
-						this.setStartBefore( commonAncestor );
-						this.setEndAfter( commonAncestor );
-					}
-					break;
-
-				case CKEDITOR.ENLARGE_BLOCK_CONTENTS:
-				case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:
-
-					// Enlarging the start boundary.
-					var walkerRange = new CKEDITOR.dom.range( this.root );
-
-					boundary = this.root;
-
-					walkerRange.setStartAt( boundary, CKEDITOR.POSITION_AFTER_START );
-					walkerRange.setEnd( this.startContainer, this.startOffset );
-
-					var walker = new CKEDITOR.dom.walker( walkerRange ),
-						blockBoundary, // The node on which the enlarging should stop.
-						tailBr, // In case BR as block boundary.
-						notBlockBoundary = CKEDITOR.dom.walker.blockBoundary( ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ? { br: 1 } : null ),
-						inNonEditable = null,
-						// Record the encountered 'blockBoundary' for later use.
-						boundaryGuard = function( node ) {
-							// We should not check contents of non-editable elements. It may happen
-							// that inline widget has display:table child which should not block range#enlarge.
-							// When encoutered non-editable element...
-							if ( node.type == CKEDITOR.NODE_ELEMENT && node.getAttribute( 'contenteditable' ) == 'false' ) {
-								if ( inNonEditable ) {
-									// ... in which we already were, reset it (because we're leaving it) and return.
-									if ( inNonEditable.equals( node ) ) {
-										inNonEditable = null;
-										return;
-									}
-								// ... which we're entering, remember it but check it (no return).
-								} else
-									inNonEditable = node;
-							}
-							// When we are in non-editable element, do not check if current node is a block boundary.
-							else if ( inNonEditable )
-								return;
-
-							var retval = notBlockBoundary( node );
-							if ( !retval )
-								blockBoundary = node;
-							return retval;
-						},
-						// Record the encounted 'tailBr' for later use.
-						tailBrGuard = function( node ) {
-							var retval = boundaryGuard( node );
-							if ( !retval && node.is && node.is( 'br' ) )
-								tailBr = node;
-							return retval;
-						};
-
-					walker.guard = boundaryGuard;
-
-					enlargeable = walker.lastBackward();
-
-					// It's the body which stop the enlarging if no block boundary found.
-					blockBoundary = blockBoundary || boundary;
-
-					// Start the range either after the end of found block (<p>...</p>[text)
-					// or at the start of block (<p>[text...), by comparing the document position
-					// with 'enlargeable' node.
-					this.setStartAt( blockBoundary, !blockBoundary.is( 'br' ) && ( !enlargeable && this.checkStartOfBlock() || enlargeable && blockBoundary.contains( enlargeable ) ) ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_AFTER_END );
-
-					// Avoid enlarging the range further when end boundary spans right after the BR. (#7490)
-					if ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) {
-						var theRange = this.clone();
-						walker = new CKEDITOR.dom.walker( theRange );
-
-						var whitespaces = CKEDITOR.dom.walker.whitespaces(),
-							bookmark = CKEDITOR.dom.walker.bookmark();
-
-						walker.evaluator = function( node ) {
-							return !whitespaces( node ) && !bookmark( node );
-						};
-						var previous = walker.previous();
-						if ( previous && previous.type == CKEDITOR.NODE_ELEMENT && previous.is( 'br' ) )
-							return;
-					}
-
-
-					// Enlarging the end boundary.
-					walkerRange = this.clone();
-					walkerRange.collapse();
-					walkerRange.setEndAt( boundary, CKEDITOR.POSITION_BEFORE_END );
-					walker = new CKEDITOR.dom.walker( walkerRange );
-
-					// tailBrGuard only used for on range end.
-					walker.guard = ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ? tailBrGuard : boundaryGuard;
-					blockBoundary = null;
-					// End the range right before the block boundary node.
-
-					enlargeable = walker.lastForward();
-
-					// It's the body which stop the enlarging if no block boundary found.
-					blockBoundary = blockBoundary || boundary;
-
-					// Close the range either before the found block start (text]<p>...</p>) or at the block end (...text]</p>)
-					// by comparing the document position with 'enlargeable' node.
-					this.setEndAt( blockBoundary, ( !enlargeable && this.checkEndOfBlock() || enlargeable && blockBoundary.contains( enlargeable ) ) ? CKEDITOR.POSITION_BEFORE_END : CKEDITOR.POSITION_BEFORE_START );
-					// We must include the <br> at the end of range if there's
-					// one and we're expanding list item contents
-					if ( tailBr )
-						this.setEndAfter( tailBr );
-			}
-
-			// Ensures that returned element can be enlarged by selection, null otherwise.
-			// @param {CKEDITOR.dom.element} enlargeable
-			// @returns {CKEDITOR.dom.element/null}
-			function getValidEnlargeable( enlargeable ) {
-				return enlargeable && enlargeable.type == CKEDITOR.NODE_ELEMENT && enlargeable.hasAttribute( 'contenteditable' ) ? null : enlargeable;
-			}
-		},
-
-		/**
-		 * Descrease the range to make sure that boundaries
-		 * always anchor beside text nodes or innermost element.
-		 *
-		 * @param {Number} mode The shrinking mode ({@link CKEDITOR#SHRINK_ELEMENT} or {@link CKEDITOR#SHRINK_TEXT}).
-		 *
-		 * * {@link CKEDITOR#SHRINK_ELEMENT} - Shrink the range boundaries to the edge of the innermost element.
-		 * * {@link CKEDITOR#SHRINK_TEXT} - Shrink the range boudaries to anchor by the side of enclosed text
-		 *     node, range remains if there's no text nodes on boundaries at all.
-		 *
-		 * @param {Boolean} selectContents Whether result range anchors at the inner OR outer boundary of the node.
-		 */
-		shrink: function( mode, selectContents, shrinkOnBlockBoundary ) {
-			// Unable to shrink a collapsed range.
-			if ( !this.collapsed ) {
-				mode = mode || CKEDITOR.SHRINK_TEXT;
-
-				var walkerRange = this.clone();
-
-				var startContainer = this.startContainer,
-					endContainer = this.endContainer,
-					startOffset = this.startOffset,
-					endOffset = this.endOffset,
-					collapsed = this.collapsed;
-
-				// Whether the start/end boundary is moveable.
-				var moveStart = 1,
-					moveEnd = 1;
-
-				if ( startContainer && startContainer.type == CKEDITOR.NODE_TEXT ) {
-					if ( !startOffset )
-						walkerRange.setStartBefore( startContainer );
-					else if ( startOffset >= startContainer.getLength() )
-						walkerRange.setStartAfter( startContainer );
-					else {
-						// Enlarge the range properly to avoid walker making
-						// DOM changes caused by triming the text nodes later.
-						walkerRange.setStartBefore( startContainer );
-						moveStart = 0;
-					}
-				}
-
-				if ( endContainer && endContainer.type == CKEDITOR.NODE_TEXT ) {
-					if ( !endOffset )
-						walkerRange.setEndBefore( endContainer );
-					else if ( endOffset >= endContainer.getLength() )
-						walkerRange.setEndAfter( endContainer );
-					else {
-						walkerRange.setEndAfter( endContainer );
-						moveEnd = 0;
-					}
-				}
-
-				var walker = new CKEDITOR.dom.walker( walkerRange ),
-					isBookmark = CKEDITOR.dom.walker.bookmark();
-
-				walker.evaluator = function( node ) {
-					return node.type == ( mode == CKEDITOR.SHRINK_ELEMENT ? CKEDITOR.NODE_ELEMENT : CKEDITOR.NODE_TEXT );
-				};
-
-				var currentElement;
-				walker.guard = function( node, movingOut ) {
-					if ( isBookmark( node ) )
-						return true;
-
-					// Stop when we're shrink in element mode while encountering a text node.
-					if ( mode == CKEDITOR.SHRINK_ELEMENT && node.type == CKEDITOR.NODE_TEXT )
-						return false;
-
-					// Stop when we've already walked "through" an element.
-					if ( movingOut && node.equals( currentElement ) )
-						return false;
-
-					if ( shrinkOnBlockBoundary === false && node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary() )
-						return false;
-
-					// Stop shrinking when encountering an editable border.
-					if ( node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'contenteditable' ) )
-						return false;
-
-					if ( !movingOut && node.type == CKEDITOR.NODE_ELEMENT )
-						currentElement = node;
-
-					return true;
-				};
-
-				if ( moveStart ) {
-					var textStart = walker[ mode == CKEDITOR.SHRINK_ELEMENT ? 'lastForward' : 'next' ]();
-					textStart && this.setStartAt( textStart, selectContents ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_BEFORE_START );
-				}
-
-				if ( moveEnd ) {
-					walker.reset();
-					var textEnd = walker[ mode == CKEDITOR.SHRINK_ELEMENT ? 'lastBackward' : 'previous' ]();
-					textEnd && this.setEndAt( textEnd, selectContents ? CKEDITOR.POSITION_BEFORE_END : CKEDITOR.POSITION_AFTER_END );
-				}
-
-				return !!( moveStart || moveEnd );
-			}
-		},
-
-		/**
-		 * Inserts a node at the start of the range. The range will be expanded
-		 * the contain the node.
-		 *
-		 * @param {CKEDITOR.dom.node} node
-		 */
-		insertNode: function( node ) {
-			this.optimizeBookmark();
-			this.trim( false, true );
-
-			var startContainer = this.startContainer;
-			var startOffset = this.startOffset;
-
-			var nextNode = startContainer.getChild( startOffset );
-
-			if ( nextNode )
-				node.insertBefore( nextNode );
-			else
-				startContainer.append( node );
-
-			// Check if we need to update the end boundary.
-			if ( node.getParent() && node.getParent().equals( this.endContainer ) )
-				this.endOffset++;
-
-			// Expand the range to embrace the new node.
-			this.setStartBefore( node );
-		},
-
-		/**
-		 * @todo
-		 */
-		moveToPosition: function( node, position ) {
-			this.setStartAt( node, position );
-			this.collapse( true );
-		},
-
-		/**
-		 * @todo
-		 */
-		moveToRange: function( range ) {
-			this.setStart( range.startContainer, range.startOffset );
-			this.setEnd( range.endContainer, range.endOffset );
-		},
-
-		/**
-		 * Select nodes content. Range will start and end inside this node.
-		 *
-		 * @param {CKEDITOR.dom.node} node
-		 */
-		selectNodeContents: function( node ) {
-			this.setStart( node, 0 );
-			this.setEnd( node, node.type == CKEDITOR.NODE_TEXT ? node.getLength() : node.getChildCount() );
-		},
-
-		/**
-		 * Sets the start position of a range.
-		 *
-		 * @param {CKEDITOR.dom.node} startNode The node to start the range.
-		 * @param {Number} startOffset An integer greater than or equal to zero
-		 * representing the offset for the start of the range from the start
-		 * of `startNode`.
-		 */
-		setStart: function( startNode, startOffset ) {
-			// W3C requires a check for the new position. If it is after the end
-			// boundary, the range should be collapsed to the new start. It seams
-			// we will not need this check for our use of this class so we can
-			// ignore it for now.
-
-			// Fixing invalid range start inside dtd empty elements.
-			if ( startNode.type == CKEDITOR.NODE_ELEMENT && CKEDITOR.dtd.$empty[ startNode.getName() ] )
-				startOffset = startNode.getIndex(), startNode = startNode.getParent();
-
-			this.startContainer = startNode;
-			this.startOffset = startOffset;
-
-			if ( !this.endContainer ) {
-				this.endContainer = startNode;
-				this.endOffset = startOffset;
-			}
-
-			updateCollapsed( this );
-		},
-
-		/**
-		 * Sets the end position of a Range.
-		 *
-		 * @param {CKEDITOR.dom.node} endNode The node to end the range.
-		 * @param {Number} endOffset An integer greater than or equal to zero
-		 * representing the offset for the end of the range from the start
-		 * of `endNode`.
-		 */
-		setEnd: function( endNode, endOffset ) {
-			// W3C requires a check for the new position. If it is before the start
-			// boundary, the range should be collapsed to the new end. It seams we
-			// will not need this check for our use of this class so we can ignore
-			// it for now.
-
-			// Fixing invalid range end inside dtd empty elements.
-			if ( endNode.type == CKEDITOR.NODE_ELEMENT && CKEDITOR.dtd.$empty[ endNode.getName() ] )
-				endOffset = endNode.getIndex() + 1, endNode = endNode.getParent();
-
-			this.endContainer = endNode;
-			this.endOffset = endOffset;
-
-			if ( !this.startContainer ) {
-				this.startContainer = endNode;
-				this.startOffset = endOffset;
-			}
-
-			updateCollapsed( this );
-		},
-
-		/**
-		 * @todo
-		 */
-		setStartAfter: function( node ) {
-			this.setStart( node.getParent(), node.getIndex() + 1 );
-		},
-
-		/**
-		 * @todo
-		 */
-		setStartBefore: function( node ) {
-			this.setStart( node.getParent(), node.getIndex() );
-		},
-
-		/**
-		 * @todo
-		 */
-		setEndAfter: function( node ) {
-			this.setEnd( node.getParent(), node.getIndex() + 1 );
-		},
-
-		/**
-		 * @todo
-		 */
-		setEndBefore: function( node ) {
-			this.setEnd( node.getParent(), node.getIndex() );
-		},
-
-		/**
-		 * @todo
-		 */
-		setStartAt: function( node, position ) {
-			switch ( position ) {
-				case CKEDITOR.POSITION_AFTER_START:
-					this.setStart( node, 0 );
-					break;
-
-				case CKEDITOR.POSITION_BEFORE_END:
-					if ( node.type == CKEDITOR.NODE_TEXT )
-						this.setStart( node, node.getLength() );
-					else
-						this.setStart( node, node.getChildCount() );
-					break;
-
-				case CKEDITOR.POSITION_BEFORE_START:
-					this.setStartBefore( node );
-					break;
-
-				case CKEDITOR.POSITION_AFTER_END:
-					this.setStartAfter( node );
-			}
-
-			updateCollapsed( this );
-		},
-
-		/**
-		 * @todo
-		 */
-		setEndAt: function( node, position ) {
-			switch ( position ) {
-				case CKEDITOR.POSITION_AFTER_START:
-					this.setEnd( node, 0 );
-					break;
-
-				case CKEDITOR.POSITION_BEFORE_END:
-					if ( node.type == CKEDITOR.NODE_TEXT )
-						this.setEnd( node, node.getLength() );
-					else
-						this.setEnd( node, node.getChildCount() );
-					break;
-
-				case CKEDITOR.POSITION_BEFORE_START:
-					this.setEndBefore( node );
-					break;
-
-				case CKEDITOR.POSITION_AFTER_END:
-					this.setEndAfter( node );
-			}
-
-			updateCollapsed( this );
-		},
-
-		/**
-		 * @todo
-		 */
-		fixBlock: function( isStart, blockTag ) {
-			var bookmark = this.createBookmark(),
-				fixedBlock = this.document.createElement( blockTag );
-
-			this.collapse( isStart );
-
-			this.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
-
-			this.extractContents().appendTo( fixedBlock );
-			fixedBlock.trim();
-
-			fixedBlock.appendBogus();
-
-			this.insertNode( fixedBlock );
-
-			this.moveToBookmark( bookmark );
-
-			return fixedBlock;
-		},
-
-		/**
-		 * @todo
-		 */
-		splitBlock: function( blockTag ) {
-			var startPath = new CKEDITOR.dom.elementPath( this.startContainer, this.root ),
-				endPath = new CKEDITOR.dom.elementPath( this.endContainer, this.root );
-
-			var startBlockLimit = startPath.blockLimit,
-				endBlockLimit = endPath.blockLimit;
-
-			var startBlock = startPath.block,
-				endBlock = endPath.block;
-
-			var elementPath = null;
-			// Do nothing if the boundaries are in different block limits.
-			if ( !startBlockLimit.equals( endBlockLimit ) )
-				return null;
-
-			// Get or fix current blocks.
-			if ( blockTag != 'br' ) {
-				if ( !startBlock ) {
-					startBlock = this.fixBlock( true, blockTag );
-					endBlock = new CKEDITOR.dom.elementPath( this.endContainer, this.root ).block;
-				}
-
-				if ( !endBlock )
-					endBlock = this.fixBlock( false, blockTag );
-			}
-
-			// Get the range position.
-			var isStartOfBlock = startBlock && this.checkStartOfBlock(),
-				isEndOfBlock = endBlock && this.checkEndOfBlock();
-
-			// Delete the current contents.
-			// TODO: Why is 2.x doing CheckIsEmpty()?
-			this.deleteContents();
-
-			if ( startBlock && startBlock.equals( endBlock ) ) {
-				if ( isEndOfBlock ) {
-					elementPath = new CKEDITOR.dom.elementPath( this.startContainer, this.root );
-					this.moveToPosition( endBlock, CKEDITOR.POSITION_AFTER_END );
-					endBlock = null;
-				} else if ( isStartOfBlock ) {
-					elementPath = new CKEDITOR.dom.elementPath( this.startContainer, this.root );
-					this.moveToPosition( startBlock, CKEDITOR.POSITION_BEFORE_START );
-					startBlock = null;
-				} else {
-					endBlock = this.splitElement( startBlock );
-
-					// In Gecko, the last child node must be a bogus <br>.
-					// Note: bogus <br> added under <ul> or <ol> would cause
-					// lists to be incorrectly rendered.
-					if ( !startBlock.is( 'ul', 'ol' ) )
-						startBlock.appendBogus();
-				}
-			}
-
-			return {
-				previousBlock: startBlock,
-				nextBlock: endBlock,
-				wasStartOfBlock: isStartOfBlock,
-				wasEndOfBlock: isEndOfBlock,
-				elementPath: elementPath
-			};
-		},
-
-		/**
-		 * Branch the specified element from the collapsed range position and
-		 * place the caret between the two result branches.
-		 *
-		 * **Note:** The range must be collapsed and been enclosed by this element.
-		 *
-		 * @param {CKEDITOR.dom.element} element
-		 * @returns {CKEDITOR.dom.element} Root element of the new branch after the split.
-		 */
-		splitElement: function( toSplit ) {
-			if ( !this.collapsed )
-				return null;
-
-			// Extract the contents of the block from the selection point to the end
-			// of its contents.
-			this.setEndAt( toSplit, CKEDITOR.POSITION_BEFORE_END );
-			var documentFragment = this.extractContents();
-
-			// Duplicate the element after it.
-			var clone = toSplit.clone( false );
-
-			// Place the extracted contents into the duplicated element.
-			documentFragment.appendTo( clone );
-			clone.insertAfter( toSplit );
-			this.moveToPosition( toSplit, CKEDITOR.POSITION_AFTER_END );
-			return clone;
-		},
-
-		/**
-		 * Recursively remove any empty path blocks at the range boundary.
-		 *
-		 * @method
-		 * @param {Boolean} atEnd Removal to perform at the end boundary,
-		 * otherwise to perform at the start.
-		 */
-		removeEmptyBlocksAtEnd: ( function() {
-
-			var whitespace = CKEDITOR.dom.walker.whitespaces(),
-					bookmark = CKEDITOR.dom.walker.bookmark( false );
-
-			function childEval( parent ) {
-				return function( node ) {
-
-					// whitespace, bookmarks, empty inlines.
-					if ( whitespace( node ) || bookmark( node ) ||
-					     node.type == CKEDITOR.NODE_ELEMENT &&
-					     node.isEmptyInlineRemoveable() )
-						return false;
-					else if ( parent.is( 'table' ) && node.is( 'caption' ) )
-						return false;
-
-					return true;
-				};
-			}
-
-			return function( atEnd ) {
-
-				var bm = this.createBookmark();
-				var path = this[ atEnd ? 'endPath' : 'startPath' ]();
-				var block = path.block || path.blockLimit, parent;
-
-				// Remove any childless block, including list and table.
-				while ( block && !block.equals( path.root ) &&
-				        !block.getFirst( childEval( block ) ) )
-				{
-					parent = block.getParent();
-					this[ atEnd ? 'setEndAt' : 'setStartAt' ]( block, CKEDITOR.POSITION_AFTER_END );
-					block.remove( 1 );
-					block = parent;
-				}
-
-				this.moveToBookmark( bm );
-			};
-
-		} )(),
-
-		/**
-		 * Gets {@link CKEDITOR.dom.elementPath} for the {@link #startContainer}.
-		 *
-		 * @returns {CKEDITOR.dom.elementPath}
-		 */
-		startPath: function() {
-			return new CKEDITOR.dom.elementPath( this.startContainer, this.root );
-		},
-
-		/**
-		 * Gets {@link CKEDITOR.dom.elementPath} for the {@link #endContainer}.
-		 *
-		 * @returns {CKEDITOR.dom.elementPath}
-		 */
-		endPath: function() {
-			return new CKEDITOR.dom.elementPath( this.endContainer, this.root );
-		},
-
-		/**
-		 * Check whether a range boundary is at the inner boundary of a given
-		 * element.
-		 *
-		 * @param {CKEDITOR.dom.element} element The target element to check.
-		 * @param {Number} checkType The boundary to check for both the range
-		 * and the element. It can be {@link CKEDITOR#START} or {@link CKEDITOR#END}.
-		 * @returns {Boolean} `true` if the range boundary is at the inner
-		 * boundary of the element.
-		 */
-		checkBoundaryOfElement: function( element, checkType ) {
-			var checkStart = ( checkType == CKEDITOR.START );
-
-			// Create a copy of this range, so we can manipulate it for our checks.
-			var walkerRange = this.clone();
-
-			// Collapse the range at the proper size.
-			walkerRange.collapse( checkStart );
-
-			// Expand the range to element boundary.
-			walkerRange[ checkStart ? 'setStartAt' : 'setEndAt' ]
-			( element, checkStart ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_BEFORE_END );
-
-			// Create the walker, which will check if we have anything useful
-			// in the range.
-			var walker = new CKEDITOR.dom.walker( walkerRange );
-			walker.evaluator = elementBoundaryEval( checkStart );
-
-			return walker[ checkStart ? 'checkBackward' : 'checkForward' ]();
-		},
-
-		/**
-		 * **Note:** Calls to this function may produce changes to the DOM. The range may
-		 * be updated to reflect such changes.
-		 *
-		 * @returns {Boolean}
-		 * @todo
-		 */
-		checkStartOfBlock: function() {
-			var startContainer = this.startContainer,
-				startOffset = this.startOffset;
-
-			// [IE] Special handling for range start in text with a leading NBSP,
-			// we it to be isolated, for bogus check.
-			if ( CKEDITOR.env.ie && startOffset && startContainer.type == CKEDITOR.NODE_TEXT )
-			{
-				var textBefore = CKEDITOR.tools.ltrim( startContainer.substring( 0, startOffset ) );
-				if ( nbspRegExp.test( textBefore ) )
-					this.trim( 0, 1 );
-			}
-
-			// Antecipate the trim() call here, so the walker will not make
-			// changes to the DOM, which would not get reflected into this
-			// range otherwise.
-			this.trim();
-
-			// We need to grab the block element holding the start boundary, so
-			// let's use an element path for it.
-			var path = new CKEDITOR.dom.elementPath( this.startContainer, this.root );
-
-			// Creates a range starting at the block start until the range start.
-			var walkerRange = this.clone();
-			walkerRange.collapse( true );
-			walkerRange.setStartAt( path.block || path.blockLimit, CKEDITOR.POSITION_AFTER_START );
-
-			var walker = new CKEDITOR.dom.walker( walkerRange );
-			walker.evaluator = getCheckStartEndBlockEvalFunction();
-
-			return walker.checkBackward();
-		},
-
-		/**
-		 * **Note:** Calls to this function may produce changes to the DOM. The range may
-		 * be updated to reflect such changes.
-		 *
-		 * @returns {Boolean}
-		 * @todo
-		 */
-		checkEndOfBlock: function() {
-			var endContainer = this.endContainer,
-				endOffset = this.endOffset;
-
-			// [IE] Special handling for range end in text with a following NBSP,
-			// we it to be isolated, for bogus check.
-			if ( CKEDITOR.env.ie && endContainer.type == CKEDITOR.NODE_TEXT )
-			{
-				var textAfter = CKEDITOR.tools.rtrim( endContainer.substring( endOffset ) );
-				if ( nbspRegExp.test( textAfter ) )
-					this.trim( 1, 0 );
-			}
-
-			// Antecipate the trim() call here, so the walker will not make
-			// changes to the DOM, which would not get reflected into this
-			// range otherwise.
-			this.trim();
-
-			// We need to grab the block element holding the start boundary, so
-			// let's use an element path for it.
-			var path = new CKEDITOR.dom.elementPath( this.endContainer, this.root );
-
-			// Creates a range starting at the block start until the range start.
-			var walkerRange = this.clone();
-			walkerRange.collapse( false );
-			walkerRange.setEndAt( path.block || path.blockLimit, CKEDITOR.POSITION_BEFORE_END );
-
-			var walker = new CKEDITOR.dom.walker( walkerRange );
-			walker.evaluator = getCheckStartEndBlockEvalFunction();
-
-			return walker.checkForward();
-		},
-
-		/**
-		 * Traverse with {@link CKEDITOR.dom.walker} to retrieve the previous element before the range start.
-		 *
-		 * @param {Function} evaluator Function used as the walker's evaluator.
-		 * @param {Function} [guard] Function used as the walker's guard.
-		 * @param {CKEDITOR.dom.element} [boundary] A range ancestor element in which the traversal is limited,
-		 * default to the root editable if not defined.
-		 * @returns {CKEDITOR.dom.element/null} The returned node from the traversal.
-		 */
-		getPreviousNode : function( evaluator, guard, boundary ) {
-			var walkerRange = this.clone();
-			walkerRange.collapse( 1 );
-			walkerRange.setStartAt( boundary || this.root, CKEDITOR.POSITION_AFTER_START );
-
-			var walker = new CKEDITOR.dom.walker( walkerRange );
-			walker.evaluator = evaluator;
-			walker.guard = guard;
-			return walker.previous();
-		},
-
-		/**
-		 * Traverse with {@link CKEDITOR.dom.walker} to retrieve the next element before the range start.
-		 *
-		 * @param {Function} evaluator Function used as the walker's evaluator.
-		 * @param {Function} [guard] Function used as the walker's guard.
-		 * @param {CKEDITOR.dom.element} [boundary] A range ancestor element in which the traversal is limited,
-		 * default to the root editable if not defined.
-		 * @returns {CKEDITOR.dom.element/null} The returned node from the traversal.
-		 */
-		getNextNode: function( evaluator, guard, boundary ) {
-			var walkerRange = this.clone();
-			walkerRange.collapse();
-			walkerRange.setEndAt( boundary || this.root, CKEDITOR.POSITION_BEFORE_END );
-
-			var walker = new CKEDITOR.dom.walker( walkerRange );
-			walker.evaluator = evaluator;
-			walker.guard = guard;
-			return walker.next();
-		},
-
-		/**
-		 * Check if elements at which the range boundaries anchor are read-only,
-		 * with respect to `contenteditable` attribute.
-		 *
-		 * @returns {Boolean}
-		 */
-		checkReadOnly: ( function() {
-			function checkNodesEditable( node, anotherEnd ) {
-				while ( node ) {
-					if ( node.type == CKEDITOR.NODE_ELEMENT ) {
-						if ( node.getAttribute( 'contentEditable' ) == 'false' && !node.data( 'cke-editable' ) )
-							return 0;
-
-						// Range enclosed entirely in an editable element.
-						else if ( node.is( 'html' ) || node.getAttribute( 'contentEditable' ) == 'true' && ( node.contains( anotherEnd ) || node.equals( anotherEnd ) ) )
-							break;
-
-					}
-					node = node.getParent();
-				}
-
-				return 1;
-			}
-
-			return function() {
-				var startNode = this.startContainer,
-					endNode = this.endContainer;
-
-				// Check if elements path at both boundaries are editable.
-				return !( checkNodesEditable( startNode, endNode ) && checkNodesEditable( endNode, startNode ) );
-			};
-		} )(),
-
-		/**
-		 * Moves the range boundaries to the first/end editing point inside an
-		 * element.
-		 *
-		 * For example, in an element tree like
-		 * `<p><b><i></i></b> Text</p>`, the start editing point is
-		 * `<p><b><i>^</i></b> Text</p>` (inside `<i>`).
-		 *
-		 * @param {CKEDITOR.dom.element} el The element into which look for the
-		 * editing spot.
-		 * @param {Boolean} isMoveToEnd Whether move to the end editable position.
-		 * @returns {Boolean} Whether range was moved.
-		 */
-		moveToElementEditablePosition: function( el, isMoveToEnd ) {
-
-			function nextDFS( node, childOnly ) {
-				var next;
-
-				if ( node.type == CKEDITOR.NODE_ELEMENT && node.isEditable( false ) )
-					next = node[ isMoveToEnd ? 'getLast' : 'getFirst' ]( notIgnoredEval );
-
-				if ( !childOnly && !next )
-					next = node[ isMoveToEnd ? 'getPrevious' : 'getNext' ]( notIgnoredEval );
-
-				return next;
-			}
-
-			// Handle non-editable element e.g. HR.
-			if ( el.type == CKEDITOR.NODE_ELEMENT && !el.isEditable( false ) ) {
-				this.moveToPosition( el, isMoveToEnd ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START );
-				return true;
-			}
-
-			var found = 0;
-
-			while ( el ) {
-				// Stop immediately if we've found a text node.
-				if ( el.type == CKEDITOR.NODE_TEXT ) {
-					// Put cursor before block filler.
-					if ( isMoveToEnd && this.endContainer && this.checkEndOfBlock() && nbspRegExp.test( el.getText() ) )
-						this.moveToPosition( el, CKEDITOR.POSITION_BEFORE_START );
-					else
-						this.moveToPosition( el, isMoveToEnd ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START );
-					found = 1;
-					break;
-				}
-
-				// If an editable element is found, move inside it, but not stop the searching.
-				if ( el.type == CKEDITOR.NODE_ELEMENT ) {
-					if ( el.isEditable() ) {
-						this.moveToPosition( el, isMoveToEnd ? CKEDITOR.POSITION_BEFORE_END : CKEDITOR.POSITION_AFTER_START );
-						found = 1;
-					}
-					// Put cursor before padding block br.
-					else if ( isMoveToEnd && el.is( 'br' ) && this.endContainer && this.checkEndOfBlock() )
-						this.moveToPosition( el, CKEDITOR.POSITION_BEFORE_START );
-					// Special case - non-editable block. Select entire element, because it does not make sense
-					// to place collapsed selection next to it, because browsers can't handle that.
-					else if ( el.getAttribute( 'contenteditable' ) == 'false' && el.is( CKEDITOR.dtd.$block ) ) {
-						this.setStartBefore( el );
-						this.setEndAfter( el );
-						return true;
-					}
-				}
-
-				el = nextDFS( el, found );
-			}
-
-			return !!found;
-		},
-
-		/**
-		 * Moves the range boundaries to the closest editing point after/before an
-		 * element.
-		 *
-		 * For example, if the start element has `id="start"`,
-		 * `<p><b>foo</b><span id="start">start</start></p>`, the closest previous editing point is
-		 * `<p><b>foo</b>^<span id="start">start</start></p>` (between `<b>` and `<span>`).
-		 *
-		 * See also: {@link #moveToElementEditablePosition}.
-		 *
-		 * @since 4.3
-		 * @param {CKEDITOR.dom.element} element The starting element.
-		 * @param {Boolean} isMoveToEnd Whether move to the end of editable. Otherwise, look back.
-		 * @returns {Boolean} Whether the range was moved.
-		 */
-		moveToClosestEditablePosition: function( element, isMoveToEnd ) {
-			// We don't want to modify original range if there's no editable position.
-			var range = new CKEDITOR.dom.range( this.root ),
-				found = 0,
-				sibling,
-				positions = [ CKEDITOR.POSITION_AFTER_END, CKEDITOR.POSITION_BEFORE_START ];
-
-			// Set collapsed range at one of ends of element.
-			range.moveToPosition( element, positions[ isMoveToEnd ? 0 : 1 ] );
-
-			// Start element isn't a block, so we can automatically place range
-			// next to it.
-			if ( !element.is( CKEDITOR.dtd.$block ) )
-				found = 1;
-			else {
-				// Look for first node that fulfills eval function and place range next to it.
-				sibling = range[ isMoveToEnd ? 'getNextEditableNode' : 'getPreviousEditableNode' ]();
-				if ( sibling ) {
-					found = 1;
-
-					// Special case - eval accepts block element only if it's a non-editable block,
-					// which we want to select, not place collapsed selection next to it (which browsers
-					// can't handle).
-					if ( sibling.type == CKEDITOR.NODE_ELEMENT && sibling.is( CKEDITOR.dtd.$block ) && sibling.getAttribute( 'contenteditable' ) == 'false' ) {
-						range.setStartAt( sibling, CKEDITOR.POSITION_BEFORE_START );
-						range.setEndAt( sibling, CKEDITOR.POSITION_AFTER_END );
-					}
-					else
-						range.moveToPosition( sibling, positions[ isMoveToEnd ? 1 : 0 ] );
-				}
-			}
-
-			if ( found )
-				this.moveToRange( range );
-
-			return !!found;
-		},
-
-		/**
-		 * See {@link #moveToElementEditablePosition}.
-		 *
-		 * @returns {Boolean} Whether range was moved.
-		 */
-		moveToElementEditStart: function( target ) {
-			return this.moveToElementEditablePosition( target );
-		},
-
-		/**
-		 * See {@link #moveToElementEditablePosition}.
-		 *
-		 * @returns {Boolean} Whether range was moved.
-		 */
-		moveToElementEditEnd: function( target ) {
-			return this.moveToElementEditablePosition( target, true );
-		},
-
-		/**
-		 * Get the single node enclosed within the range if there's one.
-		 *
-		 * @returns {CKEDITOR.dom.node}
-		 */
-		getEnclosedNode: function() {
-			var walkerRange = this.clone();
-
-			// Optimize and analyze the range to avoid DOM destructive nature of walker. (#5780)
-			walkerRange.optimize();
-			if ( walkerRange.startContainer.type != CKEDITOR.NODE_ELEMENT || walkerRange.endContainer.type != CKEDITOR.NODE_ELEMENT )
-				return null;
-
-			var walker = new CKEDITOR.dom.walker( walkerRange ),
-				isNotBookmarks = CKEDITOR.dom.walker.bookmark( false, true ),
-				isNotWhitespaces = CKEDITOR.dom.walker.whitespaces( true );
-
-			walker.evaluator = function( node ) {
-				return isNotWhitespaces( node ) && isNotBookmarks( node );
-			};
-			var node = walker.next();
-			walker.reset();
-			return node && node.equals( walker.previous() ) ? node : null;
-		},
-
-		/**
-		 * Get the node adjacent to the range start or {@link #startContainer}.
-		 *
-		 * @returns {CKEDITOR.dom.node}
-		 */
-		getTouchedStartNode: function() {
-			var container = this.startContainer;
-
-			if ( this.collapsed || container.type != CKEDITOR.NODE_ELEMENT )
-				return container;
-
-			return container.getChild( this.startOffset ) || container;
-		},
-
-		/**
-		 * Get the node adjacent to the range end or {@link #endContainer}.
-		 *
-		 * @returns {CKEDITOR.dom.node}
-		 */
-		getTouchedEndNode: function() {
-			var container = this.endContainer;
-
-			if ( this.collapsed || container.type != CKEDITOR.NODE_ELEMENT )
-				return container;
-
-			return container.getChild( this.endOffset - 1 ) || container;
-		},
-
-		/**
-		 * Gets next node which can be a container of a selection.
-		 * This methods mimics a behavior of right/left arrow keys in case of
-		 * collapsed selection. It does not return an exact position (with offset) though,
-		 * but just a selection's container.
-		 *
-		 * Note: use this method on a collapsed range.
-		 *
-		 * @since 4.3
-		 * @returns {CKEDITOR.dom.element/CKEDITOR.dom.text}
-		 */
-		getNextEditableNode: getNextEditableNode(),
-
-		/**
-		 * See {@link #getNextEditableNode}.
-		 *
-		 * @since 4.3
-		 * @returns {CKEDITOR.dom.element/CKEDITOR.dom.text}
-		 */
-		getPreviousEditableNode: getNextEditableNode( 1 ),
-
-		/**
-		 * Scrolls the start of current range into view.
-		 */
-		scrollIntoView: function() {
-
-			// The reference element contains a zero-width space to avoid
-			// a premature removal. The view is to be scrolled with respect
-			// to this element.
-			var reference = new CKEDITOR.dom.element.createFromHtml( '<span>&nbsp;</span>', this.document ),
-				afterCaretNode, startContainerText, isStartText;
-
-			var range = this.clone();
-
-			// Work with the range to obtain a proper caret position.
-			range.optimize();
-
-			// Currently in a text node, so we need to split it into two
-			// halves and put the reference between.
-			if ( isStartText = range.startContainer.type == CKEDITOR.NODE_TEXT ) {
-				// Keep the original content. It will be restored.
-				startContainerText = range.startContainer.getText();
-
-				// Split the startContainer at the this position.
-				afterCaretNode = range.startContainer.split( range.startOffset );
-
-				// Insert the reference between two text nodes.
-				reference.insertAfter( range.startContainer );
-			}
-
-			// If not in a text node, simply insert the reference into the range.
-			else
-				range.insertNode( reference );
-
-			// Scroll with respect to the reference element.
-			reference.scrollIntoView();
-
-			// Get rid of split parts if "in a text node" case.
-			// Revert the original text of the startContainer.
-			if ( isStartText ) {
-				range.startContainer.setText( startContainerText );
-				afterCaretNode.remove();
-			}
-
-			// Get rid of the reference node. It is no longer necessary.
-			reference.remove();
-		}
-	};
-} )();
-
-CKEDITOR.POSITION_AFTER_START = 1; // <element>^contents</element>		"^text"
-CKEDITOR.POSITION_BEFORE_END = 2; // <element>contents^</element>		"text^"
-CKEDITOR.POSITION_BEFORE_START = 3; // ^<element>contents</element>		^"text"
-CKEDITOR.POSITION_AFTER_END = 4; // <element>contents</element>^		"text"
-
-CKEDITOR.ENLARGE_ELEMENT = 1;
-CKEDITOR.ENLARGE_BLOCK_CONTENTS = 2;
-CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS = 3;
-CKEDITOR.ENLARGE_INLINE = 4;
-
-// Check boundary types.
-
-/**
- * See {@link CKEDITOR.dom.range#checkBoundaryOfElement}.
- *
- * @readonly
- * @member CKEDITOR
- * @property {Number} [=1]
- */
-CKEDITOR.START = 1;
-
-/**
- * See {@link CKEDITOR.dom.range#checkBoundaryOfElement}.
- *
- * @readonly
- * @member CKEDITOR
- * @property {Number} [=2]
- */
-CKEDITOR.END = 2;
-
-// Shrink range types.
-
-/**
- * See {@link CKEDITOR.dom.range#shrink}.
- *
- * @readonly
- * @member CKEDITOR
- * @property {Number} [=1]
- */
-CKEDITOR.SHRINK_ELEMENT = 1;
-
-/**
- * See {@link CKEDITOR.dom.range#shrink}.
- *
- * @readonly
- * @member CKEDITOR
- * @property {Number} [=2]
- */
-CKEDITOR.SHRINK_TEXT = 2;

+ 0 - 201
htdocs/includes/ckeditor/ckeditor/_source/core/dom/rangelist.js

@@ -1,201 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-( function() {
-	/**
-	 * Represents a list os CKEDITOR.dom.range objects, which can be easily
-	 * iterated sequentially.
-	 *
-	 * @class
-	 * @extends Array
-	 * @constructor Creates a rangeList class instance.
-	 * @param {CKEDITOR.dom.range/CKEDITOR.dom.range[]} [ranges] The ranges contained on this list.
-	 * Note that, if an array of ranges is specified, the range sequence
-	 * should match its DOM order. This class will not help to sort them.
-	 */
-	CKEDITOR.dom.rangeList = function( ranges ) {
-		if ( ranges instanceof CKEDITOR.dom.rangeList )
-			return ranges;
-
-		if ( !ranges )
-			ranges = [];
-		else if ( ranges instanceof CKEDITOR.dom.range )
-			ranges = [ ranges ];
-
-		return CKEDITOR.tools.extend( ranges, mixins );
-	};
-
-	var mixins = {
-		/**
-		 * Creates an instance of the rangeList iterator, it should be used
-		 * only when the ranges processing could be DOM intrusive, which
-		 * means it may pollute and break other ranges in this list.
-		 * Otherwise, it's enough to just iterate over this array in a for loop.
-		 *
-		 * @returns {CKEDITOR.dom.rangeListIterator}
-		 */
-		createIterator: function() {
-			var rangeList = this,
-				bookmark = CKEDITOR.dom.walker.bookmark(),
-				guard = function( node ) {
-					return !( node.is && node.is( 'tr' ) );
-				},
-				bookmarks = [],
-				current;
-
-			return {
-				/**
-				 * Retrieves the next range in the list.
-				 *
-				 * @member CKEDITOR.dom.rangeListIterator
-				 * @param {Boolean} [mergeConsequent=false] Whether join two adjacent
-				 * ranges into single, e.g. consequent table cells.
-				 */
-				getNextRange: function( mergeConsequent ) {
-					current = current == undefined ? 0 : current + 1;
-
-					var range = rangeList[ current ];
-
-					// Multiple ranges might be mangled by each other.
-					if ( range && rangeList.length > 1 ) {
-						// Bookmarking all other ranges on the first iteration,
-						// the range correctness after it doesn't matter since we'll
-						// restore them before the next iteration.
-						if ( !current ) {
-							// Make sure bookmark correctness by reverse processing.
-							for ( var i = rangeList.length - 1; i >= 0; i-- )
-								bookmarks.unshift( rangeList[ i ].createBookmark( true ) );
-						}
-
-						if ( mergeConsequent ) {
-							// Figure out how many ranges should be merged.
-							var mergeCount = 0;
-							while ( rangeList[ current + mergeCount + 1 ] ) {
-								var doc = range.document,
-									found = 0,
-									left = doc.getById( bookmarks[ mergeCount ].endNode ),
-									right = doc.getById( bookmarks[ mergeCount + 1 ].startNode ),
-									next;
-
-								// Check subsequent range.
-								while ( 1 ) {
-									next = left.getNextSourceNode( false );
-									if ( !right.equals( next ) ) {
-										// This could be yet another bookmark or
-										// walking across block boundaries.
-										if ( bookmark( next ) || ( next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() ) ) {
-											left = next;
-											continue;
-										}
-									} else
-										found = 1;
-
-									break;
-								}
-
-								if ( !found )
-									break;
-
-								mergeCount++;
-							}
-						}
-
-						range.moveToBookmark( bookmarks.shift() );
-
-						// Merge ranges finally after moving to bookmarks.
-						while ( mergeCount-- ) {
-							next = rangeList[ ++current ];
-							next.moveToBookmark( bookmarks.shift() );
-							range.setEnd( next.endContainer, next.endOffset );
-						}
-					}
-
-					return range;
-				}
-			};
-		},
-
-		/**
-		 * Create bookmarks for all ranges. See {@link CKEDITOR.dom.range#createBookmark}.
-		 *
-		 * @param {Boolean} [serializable=false] See {@link CKEDITOR.dom.range#createBookmark}.
-		 * @returns {Array} Array of bookmarks.
-		 */
-		createBookmarks: function( serializable ) {
-			var retval = [],
-				bookmark;
-			for ( var i = 0; i < this.length; i++ ) {
-				retval.push( bookmark = this[ i ].createBookmark( serializable, true ) );
-
-				// Updating the container & offset values for ranges
-				// that have been touched.
-				for ( var j = i + 1; j < this.length; j++ ) {
-					this[ j ] = updateDirtyRange( bookmark, this[ j ] );
-					this[ j ] = updateDirtyRange( bookmark, this[ j ], true );
-				}
-			}
-			return retval;
-		},
-
-		/**
-		 * Create "unobtrusive" bookmarks for all ranges. See {@link CKEDITOR.dom.range#createBookmark2}.
-		 *
-		 * @param {Boolean} [normalized=false] See {@link CKEDITOR.dom.range#createBookmark2}.
-		 * @returns {Array} Array of bookmarks.
-		 */
-		createBookmarks2: function( normalized ) {
-			var bookmarks = [];
-
-			for ( var i = 0; i < this.length; i++ )
-				bookmarks.push( this[ i ].createBookmark2( normalized ) );
-
-			return bookmarks;
-		},
-
-		/**
-		 * Move each range in the list to the position specified by a list of bookmarks.
-		 *
-		 * @param {Array} bookmarks The list of bookmarks, each one matching a range in the list.
-		 */
-		moveToBookmarks: function( bookmarks ) {
-			for ( var i = 0; i < this.length; i++ )
-				this[ i ].moveToBookmark( bookmarks[ i ] );
-		}
-	};
-
-	// Update the specified range which has been mangled by previous insertion of
-	// range bookmark nodes.(#3256)
-	function updateDirtyRange( bookmark, dirtyRange, checkEnd ) {
-		var serializable = bookmark.serializable,
-			container = dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ],
-			offset = checkEnd ? 'endOffset' : 'startOffset';
-
-		var bookmarkStart = serializable ? dirtyRange.document.getById( bookmark.startNode ) : bookmark.startNode;
-
-		var bookmarkEnd = serializable ? dirtyRange.document.getById( bookmark.endNode ) : bookmark.endNode;
-
-		if ( container.equals( bookmarkStart.getPrevious() ) ) {
-			dirtyRange.startOffset = dirtyRange.startOffset - container.getLength() - bookmarkEnd.getPrevious().getLength();
-			container = bookmarkEnd.getNext();
-		} else if ( container.equals( bookmarkEnd.getPrevious() ) ) {
-			dirtyRange.startOffset = dirtyRange.startOffset - container.getLength();
-			container = bookmarkEnd.getNext();
-		}
-
-		container.equals( bookmarkStart.getParent() ) && dirtyRange[ offset ]++;
-		container.equals( bookmarkEnd.getParent() ) && dirtyRange[ offset ]++;
-
-		// Update and return this range.
-		dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ] = container;
-		return dirtyRange;
-	}
-} )();
-
-/**
- * (Virtual Class) Do not call this constructor. This class is not really part
- * of the API. It just describes the return type of {@link CKEDITOR.dom.rangeList#createIterator}.
- *
- * @class CKEDITOR.dom.rangeListIterator
- */

+ 0 - 139
htdocs/includes/ckeditor/ckeditor/_source/core/dom/text.js

@@ -1,139 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.dom.text} class, which represents
- *		a DOM text node.
- */
-
-/**
- * Represents a DOM text node.
- *
- *		var nativeNode = document.createTextNode( 'Example' );
- *		var text = CKEDITOR.dom.text( nativeNode );
- *
- *		var text = CKEDITOR.dom.text( 'Example' );
- *
- * @class
- * @extends CKEDITOR.dom.node
- * @constructor Creates a text class instance.
- * @param {Object/String} text A native DOM text node or a string containing
- * the text to use to create a new text node.
- * @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
- * the node in case of new node creation. Defaults to the current document.
- */
-CKEDITOR.dom.text = function( text, ownerDocument ) {
-	if ( typeof text == 'string' )
-		text = ( ownerDocument ? ownerDocument.$ : document ).createTextNode( text );
-
-	// Theoretically, we should call the base constructor here
-	// (not CKEDITOR.dom.node though). But, IE doesn't support expando
-	// properties on text node, so the features provided by domObject will not
-	// work for text nodes (which is not a big issue for us).
-	//
-	// CKEDITOR.dom.domObject.call( this, element );
-
-	this.$ = text;
-};
-
-CKEDITOR.dom.text.prototype = new CKEDITOR.dom.node();
-
-CKEDITOR.tools.extend( CKEDITOR.dom.text.prototype, {
-	/**
-	 * The node type. This is a constant value set to {@link CKEDITOR#NODE_TEXT}.
-	 *
-	 * @readonly
-	 * @property {Number} [=CKEDITOR.NODE_TEXT]
-	 */
-	type: CKEDITOR.NODE_TEXT,
-
-	/**
-	 * Gets length of node's value.
-	 *
-	 * @returns {Number}
-	 */
-	getLength: function() {
-		return this.$.nodeValue.length;
-	},
-
-	/**
-	 * Gets node's value.
-	 *
-	 * @returns {String}
-	 */
-	getText: function() {
-		return this.$.nodeValue;
-	},
-
-	/**
-	 * Sets node's value.
-	 *
-	 * @param {String} text
-	 */
-	setText: function( text ) {
-		this.$.nodeValue = text;
-	},
-
-	/**
-	 * Breaks this text node into two nodes at the specified offset,
-	 * keeping both in the tree as siblings. This node then only contains
-	 * all the content up to the offset point. A new text node, which is
-	 * inserted as the next sibling of this node, contains all the content
-	 * at and after the offset point. When the offset is equal to the
-	 * length of this node, the new node has no data.
-	 *
-	 * @param {Number} The position at which to split, starting from zero.
-	 * @returns {CKEDITOR.dom.text} The new text node.
-	 */
-	split: function( offset ) {
-
-		// Saved the children count and text length beforehand.
-		var parent = this.$.parentNode,
-			count = parent.childNodes.length,
-			length = this.getLength();
-
-		var doc = this.getDocument();
-		var retval = new CKEDITOR.dom.text( this.$.splitText( offset ), doc );
-
-		if ( parent.childNodes.length == count )
-		{
-			// If the offset is after the last char, IE creates the text node
-			// on split, but don't include it into the DOM. So, we have to do
-			// that manually here.
-			if ( offset >= length )
-			{
-				retval = doc.createText( '' );
-				retval.insertAfter( this );
-			}
-			else
-			{
-				// IE BUG: IE8+ does not update the childNodes array in DOM after splitText(),
-				// we need to make some DOM changes to make it update. (#3436)
-				var workaround = doc.createText( '' );
-				workaround.insertAfter( retval );
-				workaround.remove();
-			}
-		}
-
-		return retval;
-	},
-
-	/**
-	 * Extracts characters from indexA up to but not including `indexB`.
-	 *
-	 * @param {Number} indexA An integer between `0` and one less than the
-	 * length of the text.
-	 * @param {Number} [indexB] An integer between `0` and the length of the
-	 * string. If omitted, extracts characters to the end of the text.
-	 */
-	substring: function( indexA, indexB ) {
-		// We need the following check due to a Firefox bug
-		// https://bugzilla.mozilla.org/show_bug.cgi?id=458886
-		if ( typeof indexB != 'number' )
-			return this.$.nodeValue.substr( indexA );
-		else
-			return this.$.nodeValue.substring( indexA, indexB );
-	}
-} );

+ 0 - 616
htdocs/includes/ckeditor/ckeditor/_source/core/dom/walker.js

@@ -1,616 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-( function() {
-	// This function is to be called under a "walker" instance scope.
-	function iterate( rtl, breakOnFalse ) {
-		var range = this.range;
-
-		// Return null if we have reached the end.
-		if ( this._.end )
-			return null;
-
-		// This is the first call. Initialize it.
-		if ( !this._.start ) {
-			this._.start = 1;
-
-			// A collapsed range must return null at first call.
-			if ( range.collapsed ) {
-				this.end();
-				return null;
-			}
-
-			// Move outside of text node edges.
-			range.optimize();
-		}
-
-		var node,
-			startCt = range.startContainer,
-			endCt = range.endContainer,
-			startOffset = range.startOffset,
-			endOffset = range.endOffset,
-			guard,
-			userGuard = this.guard,
-			type = this.type,
-			getSourceNodeFn = ( rtl ? 'getPreviousSourceNode' : 'getNextSourceNode' );
-
-		// Create the LTR guard function, if necessary.
-		if ( !rtl && !this._.guardLTR ) {
-			// The node that stops walker from moving up.
-			var limitLTR = endCt.type == CKEDITOR.NODE_ELEMENT ? endCt : endCt.getParent();
-
-			// The node that stops the walker from going to next.
-			var blockerLTR = endCt.type == CKEDITOR.NODE_ELEMENT ? endCt.getChild( endOffset ) : endCt.getNext();
-
-			this._.guardLTR = function( node, movingOut ) {
-				return ( ( !movingOut || !limitLTR.equals( node ) ) && ( !blockerLTR || !node.equals( blockerLTR ) ) && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || !node.equals( range.root ) ) );
-			};
-		}
-
-		// Create the RTL guard function, if necessary.
-		if ( rtl && !this._.guardRTL ) {
-			// The node that stops walker from moving up.
-			var limitRTL = startCt.type == CKEDITOR.NODE_ELEMENT ? startCt : startCt.getParent();
-
-			// The node that stops the walker from going to next.
-			var blockerRTL = startCt.type == CKEDITOR.NODE_ELEMENT ? startOffset ? startCt.getChild( startOffset - 1 ) : null : startCt.getPrevious();
-
-			this._.guardRTL = function( node, movingOut ) {
-				return ( ( !movingOut || !limitRTL.equals( node ) ) && ( !blockerRTL || !node.equals( blockerRTL ) ) && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || !node.equals( range.root ) ) );
-			};
-		}
-
-		// Define which guard function to use.
-		var stopGuard = rtl ? this._.guardRTL : this._.guardLTR;
-
-		// Make the user defined guard function participate in the process,
-		// otherwise simply use the boundary guard.
-		if ( userGuard ) {
-			guard = function( node, movingOut ) {
-				if ( stopGuard( node, movingOut ) === false )
-					return false;
-
-				return userGuard( node, movingOut );
-			};
-		} else
-			guard = stopGuard;
-
-		if ( this.current )
-			node = this.current[ getSourceNodeFn ]( false, type, guard );
-		else {
-			// Get the first node to be returned.
-			if ( rtl ) {
-				node = endCt;
-
-				if ( node.type == CKEDITOR.NODE_ELEMENT ) {
-					if ( endOffset > 0 )
-						node = node.getChild( endOffset - 1 );
-					else
-						node = ( guard( node, true ) === false ) ? null : node.getPreviousSourceNode( true, type, guard );
-				}
-			} else {
-				node = startCt;
-
-				if ( node.type == CKEDITOR.NODE_ELEMENT ) {
-					if ( !( node = node.getChild( startOffset ) ) )
-						node = ( guard( startCt, true ) === false ) ? null : startCt.getNextSourceNode( true, type, guard );
-				}
-			}
-
-			if ( node && guard( node ) === false )
-				node = null;
-		}
-
-		while ( node && !this._.end ) {
-			this.current = node;
-
-			if ( !this.evaluator || this.evaluator( node ) !== false ) {
-				if ( !breakOnFalse )
-					return node;
-			} else if ( breakOnFalse && this.evaluator )
-				return false;
-
-			node = node[ getSourceNodeFn ]( false, type, guard );
-		}
-
-		this.end();
-		return this.current = null;
-	}
-
-	function iterateToLast( rtl ) {
-		var node,
-			last = null;
-
-		while ( ( node = iterate.call( this, rtl ) ) )
-			last = node;
-
-		return last;
-	}
-
-	/**
-	 * Utility class to "walk" the DOM inside a range boundaries. If the
-	 * range starts or ends in the middle of the text node this node will
-	 * be included as a whole. Outside changes to the range may break the walker.
-	 *
-	 * The walker may return nodes that are not totaly included into the
-	 * range boundaires. Let's take the following range representation,
-	 * where the square brackets indicate the boundaries:
-	 *
-	 *		[<p>Some <b>sample] text</b>
-	 *
-	 * While walking forward into the above range, the following nodes are
-	 * returned: `<p>`, `"Some "`, `<b>` and `"sample"`. Going
-	 * backwards instead we have: `"sample"` and `"Some "`. So note that the
-	 * walker always returns nodes when "entering" them, but not when
-	 * "leaving" them. The guard function is instead called both when
-	 * entering and leaving nodes.
-	 *
-	 * @class
-	 */
-	CKEDITOR.dom.walker = CKEDITOR.tools.createClass( {
-		/**
-		 * Creates a walker class instance.
-		 *
-		 * @constructor
-		 * @param {CKEDITOR.dom.range} range The range within which walk.
-		 */
-		$: function( range ) {
-			this.range = range;
-
-			/**
-			 * A function executed for every matched node, to check whether
-			 * it's to be considered into the walk or not. If not provided, all
-			 * matched nodes are considered good.
-			 *
-			 * If the function returns `false` the node is ignored.
-			 *
-			 * @property {Function} evaluator
-			 */
-			// this.evaluator = null;
-
-			/**
-			 * A function executed for every node the walk pass by to check
-			 * whether the walk is to be finished. It's called when both
-			 * entering and exiting nodes, as well as for the matched nodes.
-			 *
-			 * If this function returns `false`, the walking ends and no more
-			 * nodes are evaluated.
-
-			 * @property {Function} guard
-			 */
-			// this.guard = null;
-
-			/** @private */
-			this._ = {};
-		},
-
-		//		statics :
-		//		{
-		//			/* Creates a CKEDITOR.dom.walker instance to walk inside DOM boundaries set by nodes.
-		//			 * @param {CKEDITOR.dom.node} startNode The node from wich the walk
-		//			 *		will start.
-		//			 * @param {CKEDITOR.dom.node} [endNode] The last node to be considered
-		//			 *		in the walk. No more nodes are retrieved after touching or
-		//			 *		passing it. If not provided, the walker stops at the
-		//			 *		&lt;body&gt; closing boundary.
-		//			 * @returns {CKEDITOR.dom.walker} A DOM walker for the nodes between the
-		//			 *		provided nodes.
-		//			 */
-		//			createOnNodes : function( startNode, endNode, startInclusive, endInclusive )
-		//			{
-		//				var range = new CKEDITOR.dom.range();
-		//				if ( startNode )
-		//					range.setStartAt( startNode, startInclusive ? CKEDITOR.POSITION_BEFORE_START : CKEDITOR.POSITION_AFTER_END ) ;
-		//				else
-		//					range.setStartAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_AFTER_START ) ;
-		//
-		//				if ( endNode )
-		//					range.setEndAt( endNode, endInclusive ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START ) ;
-		//				else
-		//					range.setEndAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_BEFORE_END ) ;
-		//
-		//				return new CKEDITOR.dom.walker( range );
-		//			}
-		//		},
-		//
-		proto: {
-			/**
-			 * Stops walking. No more nodes are retrieved if this function gets called.
-			 */
-			end: function() {
-				this._.end = 1;
-			},
-
-			/**
-			 * Retrieves the next node (at right).
-			 *
-			 * @returns {CKEDITOR.dom.node} The next node or null if no more
-			 * nodes are available.
-			 */
-			next: function() {
-				return iterate.call( this );
-			},
-
-			/**
-			 * Retrieves the previous node (at left).
-			 *
-			 * @returns {CKEDITOR.dom.node} The previous node or null if no more
-			 * nodes are available.
-			 */
-			previous: function() {
-				return iterate.call( this, 1 );
-			},
-
-			/**
-			 * Check all nodes at right, executing the evaluation function.
-			 *
-			 * @returns {Boolean} `false` if the evaluator function returned
-			 * `false` for any of the matched nodes. Otherwise `true`.
-			 */
-			checkForward: function() {
-				return iterate.call( this, 0, 1 ) !== false;
-			},
-
-			/**
-			 * Check all nodes at left, executing the evaluation function.
-			 *
-			 * @returns {Boolean} `false` if the evaluator function returned
-			 * `false` for any of the matched nodes. Otherwise `true`.
-			 */
-			checkBackward: function() {
-				return iterate.call( this, 1, 1 ) !== false;
-			},
-
-			/**
-			 * Executes a full walk forward (to the right), until no more nodes
-			 * are available, returning the last valid node.
-			 *
-			 * @returns {CKEDITOR.dom.node} The last node at the right or null
-			 * if no valid nodes are available.
-			 */
-			lastForward: function() {
-				return iterateToLast.call( this );
-			},
-
-			/**
-			 * Executes a full walk backwards (to the left), until no more nodes
-			 * are available, returning the last valid node.
-			 *
-			 * @returns {CKEDITOR.dom.node} The last node at the left or null
-			 * if no valid nodes are available.
-			 */
-			lastBackward: function() {
-				return iterateToLast.call( this, 1 );
-			},
-
-			/**
-			 * Resets walker.
-			 */
-			reset: function() {
-				delete this.current;
-				this._ = {};
-			}
-
-		}
-	} );
-
-	// Anything whose display computed style is block, list-item, table,
-	// table-row-group, table-header-group, table-footer-group, table-row,
-	// table-column-group, table-column, table-cell, table-caption, or whose node
-	// name is hr, br (when enterMode is br only) is a block boundary.
-	var blockBoundaryDisplayMatch = { block: 1, 'list-item': 1, table: 1, 'table-row-group': 1,
-			'table-header-group': 1, 'table-footer-group': 1, 'table-row': 1, 'table-column-group': 1,
-			'table-column': 1, 'table-cell': 1, 'table-caption': 1 },
-		outOfFlowPositions = { absolute: 1, fixed: 1 };
-
-	/**
-	 * Checks whether element is displayed as a block.
-	 *
-	 * @member CKEDITOR.dom.element
-	 * @param [customNodeNames] Custom list of nodes which will extend
-	 * default {@link CKEDITOR.dtd#$block} list.
-	 * @returns {Boolean}
-	 */
-	CKEDITOR.dom.element.prototype.isBlockBoundary = function( customNodeNames ) {
-		// Whether element is in normal page flow. Floated or positioned elements are out of page flow.
-		// Don't consider floated or positioned formatting as block boundary, fall back to dtd check in that case. (#6297)
-		var inPageFlow = this.getComputedStyle( 'float' ) == 'none' && !( this.getComputedStyle( 'position' ) in outOfFlowPositions );
-
-		if ( inPageFlow && blockBoundaryDisplayMatch[ this.getComputedStyle( 'display' ) ] )
-			return true;
-
-		// Either in $block or in customNodeNames if defined.
-		return !!( this.is( CKEDITOR.dtd.$block ) || customNodeNames && this.is( customNodeNames ) );
-	};
-
-	/**
-	 * Returns a function which checks whether the node is a block boundary.
-	 * See {@link CKEDITOR.dom.element#isBlockBoundary}.
-	 *
-	 * @static
-	 * @param customNodeNames
-	 * @returns {Function}
-	 */
-	CKEDITOR.dom.walker.blockBoundary = function( customNodeNames ) {
-		return function( node, type ) {
-			return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary( customNodeNames ) );
-		};
-	};
-
-	/**
-	 * @static
-	 * @todo
-	 */
-	CKEDITOR.dom.walker.listItemBoundary = function() {
-		return this.blockBoundary( { br: 1 } );
-	};
-
-	/**
-	 * Returns a function which checks whether the node is a bookmark node OR bookmark node
-	 * inner contents.
-	 *
-	 * @static
-	 * @param {Boolean} [contentOnly=false] Whether only test against the text content of
-	 * bookmark node instead of the element itself (default).
-	 * @param {Boolean} [isReject=false] Whether should return `false` for the bookmark
-	 * node instead of `true` (default).
-	 * @returns {Function}
-	 */
-	CKEDITOR.dom.walker.bookmark = function( contentOnly, isReject ) {
-		function isBookmarkNode( node ) {
-			return ( node && node.getName && node.getName() == 'span' && node.data( 'cke-bookmark' ) );
-		}
-
-		return function( node ) {
-			var isBookmark, parent;
-			// Is bookmark inner text node?
-			isBookmark = ( node && node.type != CKEDITOR.NODE_ELEMENT && ( parent = node.getParent() ) && isBookmarkNode( parent ) );
-			// Is bookmark node?
-			isBookmark = contentOnly ? isBookmark : isBookmark || isBookmarkNode( node );
-			return !!( isReject ^ isBookmark );
-		};
-	};
-
-	/**
-	 * Returns a function which checks whether the node is a text node containing only whitespaces characters.
-	 *
-	 * @static
-	 * @param {Boolean} [isReject=false]
-	 * @returns {Function}
-	 */
-	CKEDITOR.dom.walker.whitespaces = function( isReject ) {
-		return function( node ) {
-			var isWhitespace;
-			if ( node && node.type == CKEDITOR.NODE_TEXT ) {
-				// whitespace, as well as the text cursor filler node we used in Webkit. (#9384)
-				isWhitespace = !CKEDITOR.tools.trim( node.getText() ) ||
-					CKEDITOR.env.webkit && node.getText() == '\u200b';
-			}
-
-			return !!( isReject ^ isWhitespace );
-		};
-	};
-
-	/**
-	 * Returns a function which checks whether the node is invisible in wysiwyg mode.
-	 *
-	 * @static
-	 * @param {Boolean} [isReject=false]
-	 * @returns {Function}
-	 */
-	CKEDITOR.dom.walker.invisible = function( isReject ) {
-		var whitespace = CKEDITOR.dom.walker.whitespaces();
-		return function( node ) {
-			var invisible;
-
-			if ( whitespace( node ) )
-				invisible = 1;
-			else {
-				// Visibility should be checked on element.
-				if ( node.type == CKEDITOR.NODE_TEXT )
-					node = node.getParent();
-
-			// Nodes that take no spaces in wysiwyg:
-			// 1. White-spaces but not including NBSP;
-			// 2. Empty inline elements, e.g. <b></b> we're checking here
-			// 'offsetHeight' instead of 'offsetWidth' for properly excluding
-			// all sorts of empty paragraph, e.g. <br />.
-				invisible = !node.$.offsetHeight;
-			}
-
-			return !!( isReject ^ invisible );
-		};
-	};
-
-	/**
-	 * Returns a function which checks whether node's type is equal to passed one.
-	 *
-	 * @static
-	 * @param {Number} type
-	 * @param {Boolean} [isReject=false]
-	 * @returns {Function}
-	 */
-	CKEDITOR.dom.walker.nodeType = function( type, isReject ) {
-		return function( node ) {
-			return !!( isReject ^ ( node.type == type ) );
-		};
-	};
-
-	/**
-	 * Returns a function which checks whether node is a bogus (filler) node from
-	 * contenteditable element's point of view.
-	 *
-	 * @static
-	 * @param {Boolean} [isReject=false]
-	 * @returns {Function}
-	 */
-	CKEDITOR.dom.walker.bogus = function( isReject ) {
-		function nonEmpty( node ) {
-			return !isWhitespaces( node ) && !isBookmark( node );
-		}
-
-		return function( node ) {
-			var isBogus = CKEDITOR.env.needsBrFiller ? node.is && node.is( 'br' ) : node.getText && tailNbspRegex.test( node.getText() );
-
-			if ( isBogus ) {
-				var parent = node.getParent(),
-					next = node.getNext( nonEmpty );
-
-				isBogus = parent.isBlockBoundary() && ( !next || next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() );
-			}
-
-			return !!( isReject ^ isBogus );
-		};
-	};
-
-	/**
-	 * Returns a function which checks whether node is a temporary element
-	 * (element with `data-cke-temp` attribute) or its child.
-	 *
-	 * @since 4.3
-	 * @static
-	 * @param {Boolean} [isReject=false] Whether should return `false` for the
-	 * temporary element instead of `true` (default).
-	 * @returns {Function}
-	 */
-	CKEDITOR.dom.walker.temp = function( isReject ) {
-		return function( node ) {
-			if ( node.type != CKEDITOR.NODE_ELEMENT )
-				node = node.getParent();
-
-			var isTemp = node && node.hasAttribute( 'data-cke-temp' );
-
-			return !!( isReject ^ isTemp );
-		};
-	};
-
-	var tailNbspRegex = /^[\t\r\n ]*(?:&nbsp;|\xa0)$/,
-		isWhitespaces = CKEDITOR.dom.walker.whitespaces(),
-		isBookmark = CKEDITOR.dom.walker.bookmark(),
-		isTemp = CKEDITOR.dom.walker.temp(),
-		toSkip = function( node ) {
-			return isBookmark( node ) ||
-				isWhitespaces( node ) ||
-				node.type == CKEDITOR.NODE_ELEMENT && node.is( CKEDITOR.dtd.$inline ) && !node.is( CKEDITOR.dtd.$empty );
-		};
-
-	/**
-	 * Returns a function which checks whether node should be ignored in terms of "editability".
-	 *
-	 * This includes:
-	 *
-	 * * whitespaces (see {@link CKEDITOR.dom.walker#whitespaces}),
-	 * * bookmarks (see {@link CKEDITOR.dom.walker#bookmark}),
-	 * * temporary elements (see {@link CKEDITOR.dom.walker#temp}).
-	 *
-	 * @since 4.3
-	 * @static
-	 * @param {Boolean} [isReject=false] Whether should return `false` for the
-	 * ignored element instead of `true` (default).
-	 * @returns {Function}
-	 */
-	CKEDITOR.dom.walker.ignored = function( isReject ) {
-		return function( node ) {
-			var isIgnored = isWhitespaces( node ) || isBookmark( node ) || isTemp( node );
-
-			return !!( isReject ^ isIgnored );
-		};
-	};
-
-	var isIgnored = CKEDITOR.dom.walker.ignored();
-
-	function isEmpty( node ) {
-		var i = 0,
-			l = node.getChildCount();
-
-		for ( ; i < l; ++i ) {
-			if ( !isIgnored( node.getChild( i ) ) )
-				return false;
-		}
-		return true;
-	}
-
-	function filterTextContainers( dtd ) {
-		var hash = {},
-			name;
-
-		for ( name in dtd ) {
-			if ( CKEDITOR.dtd[ name ][ '#' ] )
-				hash[ name ] = 1;
-		}
-		return hash;
-	}
-
-	// Block elements which can contain text nodes (without ul, ol, dl, etc.).
-	var dtdTextBlock = filterTextContainers( CKEDITOR.dtd.$block );
-
-	function isEditable( node ) {
-		// Skip temporary elements, bookmarks and whitespaces.
-		if ( isIgnored( node ) )
-			return false;
-
-		if ( node.type == CKEDITOR.NODE_TEXT )
-			return true;
-
-		if ( node.type == CKEDITOR.NODE_ELEMENT ) {
-			// All inline and non-editable elements are valid editable places.
-			// Note: non-editable block has to be treated differently (should be selected entirely).
-			if ( node.is( CKEDITOR.dtd.$inline ) || node.getAttribute( 'contenteditable' ) == 'false' )
-				return true;
-
-			// Empty blocks are editable on IE.
-			if ( !CKEDITOR.env.needsBrFiller && node.is( dtdTextBlock ) && isEmpty( node ) )
-				return true;
-		}
-
-		// Skip all other nodes.
-		return false;
-	}
-
-	/**
-	 * Returns a function which checks whether node can be a container or a sibling
-	 * of selection end.
-	 *
-	 * This includes:
-	 *
-	 * * text nodes (but not whitespaces),
-	 * * inline elements,
-	 * * non-editable blocks (special case - such blocks cannot be containers nor
-	 * siblings, they need to be selected entirely),
-	 * * empty blocks which can contain text (IE only).
-	 *
-	 * @since 4.3
-	 * @static
-	 * @param {Boolean} [isReject=false] Whether should return `false` for the
-	 * ignored element instead of `true` (default).
-	 * @returns {Function}
-	 */
-	CKEDITOR.dom.walker.editable = function( isReject ) {
-		return function( node ) {
-			return !!( isReject ^ isEditable( node ) );
-		};
-	};
-
-	/**
-	 * Checks if there's a filler node at the end of an element, and returns it.
-	 *
-	 * @member CKEDITOR.dom.element
-	 * @returns {CKEDITOR.dom.node/Boolean} Bogus node or `false`.
-	 */
-	CKEDITOR.dom.element.prototype.getBogus = function() {
-		// Bogus are not always at the end, e.g. <p><a>text<br /></a></p> (#7070).
-		var tail = this;
-		do {
-			tail = tail.getPreviousSourceNode();
-		}
-		while ( toSkip( tail ) )
-
-		if ( tail && ( CKEDITOR.env.needsBrFiller ? tail.is && tail.is( 'br' ) : tail.getText && tailNbspRegex.test( tail.getText() ) ) )
-			return tail;
-
-		return false;
-	};
-
-} )();

+ 0 - 95
htdocs/includes/ckeditor/ckeditor/_source/core/dom/window.js

@@ -1,95 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.dom.document} class, which
- *		represents a DOM document.
- */
-
-/**
- * Represents a DOM window.
- *
- *		var document = new CKEDITOR.dom.window( window );
- *
- * @class
- * @extends CKEDITOR.dom.domObject
- * @constructor Creates a window class instance.
- * @param {Object} domWindow A native DOM window.
- */
-CKEDITOR.dom.window = function( domWindow ) {
-	CKEDITOR.dom.domObject.call( this, domWindow );
-};
-
-CKEDITOR.dom.window.prototype = new CKEDITOR.dom.domObject();
-
-CKEDITOR.tools.extend( CKEDITOR.dom.window.prototype, {
-	/**
-	 * Moves the selection focus to this window.
-	 *
-	 *		var win = new CKEDITOR.dom.window( window );
-	 *		win.focus();
-	 */
-	focus: function() {
-		this.$.focus();
-	},
-
-	/**
-	 * Gets the width and height of this window's viewable area.
-	 *
-	 *		var win = new CKEDITOR.dom.window( window );
-	 *		var size = win.getViewPaneSize();
-	 *		alert( size.width );
-	 *		alert( size.height );
-	 *
-	 * @returns {Object} An object with the `width` and `height`
-	 * properties containing the size.
-	 */
-	getViewPaneSize: function() {
-		var doc = this.$.document,
-			stdMode = doc.compatMode == 'CSS1Compat';
-		return {
-			width: ( stdMode ? doc.documentElement.clientWidth : doc.body.clientWidth ) || 0,
-			height: ( stdMode ? doc.documentElement.clientHeight : doc.body.clientHeight ) || 0
-		};
-	},
-
-	/**
-	 * Gets the current position of the window's scroll.
-	 *
-	 *		var win = new CKEDITOR.dom.window( window );
-	 *		var pos = win.getScrollPosition();
-	 *		alert( pos.x );
-	 *		alert( pos.y );
-	 *
-	 * @returns {Object} An object with the `x` and `y` properties
-	 * containing the scroll position.
-	 */
-	getScrollPosition: function() {
-		var $ = this.$;
-
-		if ( 'pageXOffset' in $ ) {
-			return {
-				x: $.pageXOffset || 0,
-				y: $.pageYOffset || 0
-			};
-		} else {
-			var doc = $.document;
-			return {
-				x: doc.documentElement.scrollLeft || doc.body.scrollLeft || 0,
-				y: doc.documentElement.scrollTop || doc.body.scrollTop || 0
-			};
-		}
-	},
-
-	/**
-	 * Gets the frame element containing this window context.
-	 *
-	 * @returns {CKEDITOR.dom.element} The frame element or `null` if not in a frame context.
-	 */
-	getFrame: function() {
-		var iframe = this.$.frameElement;
-		return iframe ? new CKEDITOR.dom.element.get( iframe ) : null;
-	}
-} );

+ 0 - 328
htdocs/includes/ckeditor/ckeditor/_source/core/dtd.js

@@ -1,328 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.dtd} object, which holds the DTD
- *		mapping for XHTML 1.0 Transitional. This file was automatically
- *		generated from the file: xhtml1-transitional.dtd.
- */
-
-/**
- * Holds and object representation of the HTML DTD to be used by the
- * editor in its internal operations.
- *
- * Each element in the DTD is represented by a property in this object. Each
- * property contains the list of elements that can be contained by the element.
- * Text is represented by the `#` property.
- *
- * Several special grouping properties are also available. Their names start
- * with the `$` character.
- *
- *		// Check if <div> can be contained in a <p> element.
- *		alert( !!CKEDITOR.dtd[ 'p' ][ 'div' ] ); // false
- *
- *		// Check if <p> can be contained in a <div> element.
- *		alert( !!CKEDITOR.dtd[ 'div' ][ 'p' ] ); // true
- *
- *		// Check if <p> is a block element.
- *		alert( !!CKEDITOR.dtd.$block[ 'p' ] ); // true
- *
- * @class CKEDITOR.dtd
- * @singleton
- */
-CKEDITOR.dtd = ( function() {
-	'use strict';
-
-	var X = CKEDITOR.tools.extend,
-		// Subtraction rest of sets, from the first set.
-		Y = function( source, removed ) {
-			var substracted = CKEDITOR.tools.clone( source );
-			for ( var i = 1; i < arguments.length; i++ ) {
-				removed = arguments[ i ];
-				for ( var name in removed )
-					delete substracted[ name ];
-			}
-			return substracted;
-		};
-
-	// Phrasing elements.
-	// P = { a: 1, em: 1, strong: 1, small: 1, abbr: 1, dfn: 1, i: 1, b: 1, s: 1,
-	//		u: 1, code: 1, 'var': 1, samp: 1, kbd: 1, sup: 1, sub: 1, q: 1, cite: 1,
-	//		span: 1, bdo: 1, bdi: 1, br: 1, wbr: 1, ins: 1, del: 1, img: 1, embed: 1,
-	//		object: 1, iframe: 1, map: 1, area: 1, script: 1, noscript: 1, ruby: 1,
-	//		video: 1, audio: 1, input: 1, textarea: 1, select: 1, button: 1, label: 1,
-	//		output: 1, keygen: 1, progress: 1, command: 1, canvas: 1, time: 1,
-	//		meter: 1, detalist: 1 },
-
-	// Flow elements.
-	// F = { a: 1, p: 1, hr: 1, pre: 1, ul: 1, ol: 1, dl: 1, div: 1, h1: 1, h2: 1,
-	//		h3: 1, h4: 1, h5: 1, h6: 1, hgroup: 1, address: 1, blockquote: 1, ins: 1,
-	//		del: 1, object: 1, map: 1, noscript: 1, section: 1, nav: 1, article: 1,
-	//		aside: 1, header: 1, footer: 1, video: 1, audio: 1, figure: 1, table: 1,
-	//		form: 1, fieldset: 1, menu: 1, canvas: 1, details:1 },
-
-	// Text can be everywhere.
-	// X( P, T );
-	// Flow elements set consists of phrasing elements set.
-	// X( F, P );
-
-	var P = {}, F = {},
-		// Intersection of flow elements set and phrasing elements set.
-		PF = { a: 1, abbr: 1, area: 1, audio: 1, b: 1, bdi: 1, bdo: 1, br: 1, button: 1, canvas: 1, cite: 1,
-			code: 1, command: 1, datalist: 1, del: 1, dfn: 1, em: 1, embed: 1, i: 1, iframe: 1, img: 1,
-			input: 1, ins: 1, kbd: 1, keygen: 1, label: 1, map: 1, mark: 1, meter: 1, noscript: 1, object: 1,
-			output: 1, progress: 1, q: 1, ruby: 1, s: 1, samp: 1, script: 1, select: 1, small: 1, span: 1,
-			strong: 1, sub: 1, sup: 1, textarea: 1, time: 1, u: 1, 'var': 1, video: 1, wbr: 1 },
-		// F - PF (Flow Only).
-		FO = { address: 1, article: 1, aside: 1, blockquote: 1, details: 1, div: 1, dl: 1, fieldset: 1,
-			figure: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, header: 1, hgroup: 1,
-			hr: 1, menu: 1, nav: 1, ol: 1, p: 1, pre: 1, section: 1, table: 1, ul: 1 },
-		// Metadata elements.
-		M = { command: 1, link: 1, meta: 1, noscript: 1, script: 1, style: 1 },
-		// Empty.
-		E = {},
-		// Text.
-		T = { '#': 1 },
-
-		// Deprecated phrasing elements.
-		DP = { acronym: 1, applet: 1, basefont: 1, big: 1, font: 1, isindex: 1, strike: 1, style: 1, tt: 1 }, // TODO remove "style".
-		// Deprecated flow only elements.
-		DFO = { center: 1, dir: 1, noframes: 1 };
-
-	// Phrasing elements := PF + T + DP
-	X( P, PF, T, DP );
-	// Flow elements := FO + P + DFO
-	X( F, FO, P, DFO );
-
-	var dtd = {
-		a: Y( P, { a: 1, button: 1 } ), // Treat as normal inline element (not a transparent one).
-		abbr: P,
-		address: F,
-		area: E,
-		article: X( { style: 1 }, F ),
-		aside: X( { style: 1 }, F ),
-		audio: X( { source: 1, track: 1 }, F ),
-		b: P,
-		base: E,
-		bdi: P,
-		bdo: P,
-		blockquote: F,
-		body: F,
-		br: E,
-		button: Y( P, { a: 1, button: 1 } ),
-		canvas: P, // Treat as normal inline element (not a transparent one).
-		caption: F,
-		cite: P,
-		code: P,
-		col: E,
-		colgroup: { col: 1 },
-		command: E,
-		datalist: X( { option: 1 }, P ),
-		dd: F,
-		del: P, // Treat as normal inline element (not a transparent one).
-		details: X( { summary: 1 }, F ),
-		dfn: P,
-		div: X( { style: 1 }, F ),
-		dl: { dt: 1, dd: 1 },
-		dt: F,
-		em: P,
-		embed: E,
-		fieldset: X( { legend: 1 }, F ),
-		figcaption: F,
-		figure: X( { figcaption: 1 }, F ),
-		footer: F,
-		form: F,
-		h1: P,
-		h2: P,
-		h3: P,
-		h4: P,
-		h5: P,
-		h6: P,
-		head: X( { title: 1, base: 1 }, M ),
-		header: F,
-		hgroup: { h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1 },
-		hr: E,
-		html: X( { head: 1, body: 1 }, F, M ), // Head and body are optional...
-		i: P,
-		iframe: T,
-		img: E,
-		input: E,
-		ins: P, // Treat as normal inline element (not a transparent one).
-		kbd: P,
-		keygen: E,
-		label: P,
-		legend: P,
-		li: F,
-		link: E,
-		map: F,
-		mark: P, // Treat as normal inline element (not a transparent one).
-		menu: X( { li: 1 }, F ),
-		meta: E,
-		meter: Y( P, { meter: 1 } ),
-		nav: F,
-		noscript: X( { link: 1, meta: 1, style: 1 }, P ), // Treat as normal inline element (not a transparent one).
-		object: X( { param: 1 }, P ), // Treat as normal inline element (not a transparent one).
-		ol: { li: 1 },
-		optgroup: { option: 1 },
-		option: T,
-		output: P,
-		p: P,
-		param: E,
-		pre: P,
-		progress: Y( P, { progress: 1 } ),
-		q: P,
-		rp: P,
-		rt: P,
-		ruby: X( { rp: 1, rt: 1 }, P ),
-		s: P,
-		samp: P,
-		script: T,
-		section: X( { style: 1 }, F ),
-		select: { optgroup: 1, option: 1 },
-		small: P,
-		source: E,
-		span: P,
-		strong: P,
-		style: T,
-		sub: P,
-		summary: P,
-		sup: P,
-		table: { caption: 1, colgroup: 1, thead: 1, tfoot: 1, tbody: 1, tr: 1 },
-		tbody: { tr: 1 },
-		td: F,
-		textarea: T,
-		tfoot: { tr: 1 },
-		th: F,
-		thead: { tr: 1 },
-		time: Y( P, { time: 1 } ),
-		title: T,
-		tr: { th: 1, td: 1 },
-		track: E,
-		u: P,
-		ul: { li: 1 },
-		'var': P,
-		video: X( { source: 1, track: 1 }, F ),
-		wbr: E,
-
-		// Deprecated tags.
-		acronym: P,
-		applet: X( { param: 1 }, F ),
-		basefont: E,
-		big: P,
-		center: F,
-		dialog: E,
-		dir: { li: 1 },
-		font: P,
-		isindex: E,
-		noframes: F,
-		strike: P,
-		tt: P
-	};
-
-	X( dtd, {
-		/**
-		 * List of block elements, like `<p>` or `<div>`.
-		 */
-		$block: X( { audio: 1, dd: 1, dt: 1, figcaption: 1, li: 1, video: 1 }, FO, DFO ),
-
-		/**
-		 * List of elements that contain other blocks, in which block-level operations should be limited,
-		 * this property is not intended to be checked directly, use {@link CKEDITOR.dom.elementPath#blockLimit} instead.
-		 *
-		 * Some examples of editor behaviors that are impacted by block limits:
-		 *
-		 * * Enter key never split a block-limit element;
-		 * * Style application is constraint by the block limit of the current selection.
-		 * * Pasted html will be inserted into the block limit of the current selection.
-		 *
-		 * **Note:** As an exception `<li>` is not considered as a block limit, as it's generally used as a text block.
-		 */
-		$blockLimit: { article: 1, aside: 1, audio: 1, body: 1, caption: 1, details: 1, dir: 1, div: 1, dl: 1,
-			fieldset: 1, figcaption: 1, figure: 1, footer: 1, form: 1, header: 1, hgroup: 1, menu: 1, nav: 1,
-			ol: 1, section: 1, table: 1, td: 1, th: 1, tr: 1, ul: 1, video: 1 },
-
-		/**
-		 * List of elements that contain character data.
-		 */
-		$cdata: { script: 1, style: 1 },
-
-		/**
-		 * List of elements that are accepted as inline editing hosts.
-		 */
-		$editable: { address: 1, article: 1, aside: 1, blockquote: 1, body: 1, details: 1, div: 1, fieldset: 1,
-			figcaption: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, header: 1, hgroup: 1,
-			nav: 1, p: 1, pre: 1, section: 1 },
-
-		/**
-		 * List of empty (self-closing) elements, like `<br>` or `<img>`.
-		 */
-		$empty: { area: 1, base: 1, basefont: 1, br: 1, col: 1, command: 1, dialog: 1, embed: 1, hr: 1, img: 1,
-			input: 1, isindex: 1, keygen: 1, link: 1, meta: 1, param: 1, source: 1, track: 1, wbr: 1 },
-
-		/**
-		 * List of inline (`<span>` like) elements.
-		 */
-		$inline: P,
-
-		/**
-		 * List of list root elements.
-		 */
-		$list: { dl: 1, ol: 1, ul: 1 },
-
-		/**
-		 * List of list item elements, like `<li>` or `<dd>`.
-		 */
-		$listItem: { dd: 1, dt: 1, li: 1 },
-
-		/**
-		 * List of elements which may live outside body.
-		 */
-		$nonBodyContent: X( { body: 1, head: 1, html: 1 }, dtd.head ),
-
-		/**
-		 * Elements that accept text nodes, but are not possible to edit into the browser.
-		 */
-		$nonEditable: { applet: 1, audio: 1, button: 1, embed: 1, iframe: 1, map: 1, object: 1, option: 1,
-			param: 1, script: 1, textarea: 1, video: 1 },
-
-		/**
-		 * Elements that are considered objects, therefore selected as a whole in the editor.
-		 */
-		$object: { applet: 1, audio: 1, button: 1, hr: 1, iframe: 1, img: 1, input: 1, object: 1, select: 1,
-			table: 1, textarea: 1, video: 1 },
-
-		/**
-		 * List of elements that can be ignored if empty, like `<b>` or `<span>`.
-		 */
-		$removeEmpty: { abbr: 1, acronym: 1, b: 1, bdi: 1, bdo: 1, big: 1, cite: 1, code: 1, del: 1, dfn: 1,
-			em: 1, font: 1, i: 1, ins: 1, label: 1, kbd: 1, mark: 1, meter: 1, output: 1, q: 1, ruby: 1, s: 1,
-			samp: 1, small: 1, span: 1, strike: 1, strong: 1, sub: 1, sup: 1, time: 1, tt: 1, u: 1, 'var': 1 },
-
-		/**
-		 * List of elements that have tabindex set to zero by default.
-		 */
-		$tabIndex: { a: 1, area: 1, button: 1, input: 1, object: 1, select: 1, textarea: 1 },
-
-		/**
-		 * List of elements used inside the `<table>` element, like `<tbody>` or `<td>`.
-		 */
-		$tableContent: { caption: 1, col: 1, colgroup: 1, tbody: 1, td: 1, tfoot: 1, th: 1, thead: 1, tr: 1 },
-
-		/**
-		 * List of "transparent" elements. See [W3C's definition of "transparent" element](http://dev.w3.org/html5/markup/terminology.html#transparent).
-		 */
-		$transparent: { a: 1, audio: 1, canvas: 1, del: 1, ins: 1, map: 1, noscript: 1, object: 1, video: 1 },
-
-		/**
-		 * List of elements that are not to exist standalone that must live under it's parent element.
-		 */
-		$intermediate: { caption: 1, colgroup: 1, dd: 1, dt: 1, figcaption: 1, legend: 1, li: 1, optgroup: 1,
-			option: 1, rp: 1, rt: 1, summary: 1, tbody: 1, td: 1, tfoot: 1, th: 1, thead: 1, tr: 1 }
-	} );
-
-	return dtd;
-} )();
-
-// PACKAGER_RENAME( CKEDITOR.dtd )

+ 0 - 1968
htdocs/includes/ckeditor/ckeditor/_source/core/editable.js

@@ -1,1968 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-( function() {
-	/**
-	 * Editable class which provides all editing related activities by
-	 * the `contenteditable` element, dynamically get attached to editor instance.
-	 *
-	 * @class CKEDITOR.editable
-	 * @extends CKEDITOR.dom.element
-	 */
-	CKEDITOR.editable = CKEDITOR.tools.createClass( {
-		base: CKEDITOR.dom.element,
-		/**
-		 * The constructor hold only generic editable creation logic that are commonly shared among all different editable elements.
-		 *
-		 * @constructor Creates an editable class instance.
-		 * @param {CKEDITOR.editor} editor The editor instance on which the editable operates.
-		 * @param {HTMLElement/CKEDITOR.dom.element} element Any DOM element that been used as the editor's
-		 * editing container, e.g. it could be either an HTML element with the `contenteditable` attribute
-		 * set to the true that handles wysiwyg editing or a `<textarea>` element that handles source editing.
-		 */
-		$: function( editor, element ) {
-			// Transform the element into a CKEDITOR.dom.element instance.
-			this.base( element.$ || element );
-
-			this.editor = editor;
-
-			/**
-			 * Indicate whether the editable element has gained focus.
-			 *
-			 * @property {Boolean} hasFocus
-			 */
-			this.hasFocus = false;
-
-			// The bootstrapping logic.
-			this.setup();
-		},
-		proto: {
-
-			focus: function() {
-
-				var active;
-
-				// [Webkit] When DOM focus is inside of nested contenteditable elements,
-				// apply focus on the main editable will compromise it's text selection.
-				if ( CKEDITOR.env.webkit && !this.hasFocus ) {
-					// Restore focus on element which we cached (on selectionCheck) as previously active.
-					active = this.editor._.previousActive || this.getDocument().getActive();
-					if ( this.contains( active ) ) {
-						active.focus();
-						return;
-					}
-				}
-
-				// [IE] Use instead "setActive" method to focus the editable if it belongs to
-				// the host page document, to avoid bringing an unexpected scroll.
-				try {
-					this.$[ CKEDITOR.env.ie && this.getDocument().equals( CKEDITOR.document ) ? 'setActive' : 'focus' ]();
-				} catch ( e ) {
-					// IE throws unspecified error when focusing editable after closing dialog opened on nested editable.
-					if ( !CKEDITOR.env.ie )
-						throw e;
-				}
-
-				// Remedy if Safari doens't applies focus properly. (#279)
-				if ( CKEDITOR.env.safari && !this.isInline() ) {
-					active = CKEDITOR.document.getActive();
-					if ( !active.equals( this.getWindow().getFrame() ) )
-						this.getWindow().focus();
-
-				}
-			},
-
-			/**
-			 * Overrides {@link CKEDITOR.dom.element#on} to have special `focus/blur` handling.
-			 * The `focusin/focusout` events are used in IE to replace regular `focus/blur` events
-			 * because we want to avoid the asynchronous nature of later ones.
-			 */
-			on: function( name, fn ) {
-				var args = Array.prototype.slice.call( arguments, 0 );
-
-				if ( CKEDITOR.env.ie && ( /^focus|blur$/ ).exec( name ) ) {
-					name = name == 'focus' ? 'focusin' : 'focusout';
-
-					// The "focusin/focusout" events bubbled, e.g. If there are elements with layout
-					// they fire this event when clicking in to edit them but it must be ignored
-					// to allow edit their contents. (#4682)
-					fn = isNotBubbling( fn, this );
-					args[ 0 ] = name;
-					args[ 1 ] = fn;
-				}
-
-				return CKEDITOR.dom.element.prototype.on.apply( this, args );
-			},
-
-			/**
-			 * Registers an event listener that needs to be removed when detaching this editable.
-			 * This means that it will be automatically removed when {@link #detach} is executed,
-			 * for example on {@link CKEDITOR.editor#setMode changing editor mode} or destroying editor.
-			 *
-			 * Except for `obj` all other arguments have the same meaning as in {@link CKEDITOR.event#on}.
-			 *
-			 * This method is strongly related to the {@link CKEDITOR.editor#contentDom} and
-			 * {@link CKEDITOR.editor#contentDomUnload} events, because they are fired
-			 * when an editable is being attached and detached. Therefore, this method is usually used
-			 * in the following way:
-			 *
-			 *		editor.on( 'contentDom', function() {
-			 *			var editable = editor.editable();
-			 *			editable.attachListener( editable, 'mousedown', function() {
-			 *				// ...
-			 *			} );
-			 *		} );
-			 *
-			 * This code will attach the `mousedown` listener every time a new editable is attached
-			 * to the editor, which in classic (`iframe`-based) editor happens every time the
-			 * data or the mode is set. This listener will also be removed when that editable is detached.
-			 *
-			 * It is also possible to attach a listener to another object (e.g. to a document).
-			 *
-			 *		editor.on( 'contentDom', function() {
-			 *			editor.editable().attachListener( editor.document, 'mousedown', function() {
-			 *				// ...
-			 *			} );
-			 *		} );
-			 *
-			 * @param {CKEDITOR.event} obj The element/object to which the listener will be attached. Every object
-			 * which inherits from {@link CKEDITOR.event} may be used including {@link CKEDITOR.dom.element},
-			 * {@link CKEDITOR.dom.document}, and {@link CKEDITOR.editable}.
-			 * @param {String} eventName The name of the event that will be listened to.
-			 * @param {Function} listenerFunction The function listening to the
-			 * event. A single {@link CKEDITOR.eventInfo} object instance
-			 * containing all the event data is passed to this function.
-			 * @param {Object} [scopeObj] The object used to scope the listener
-			 * call (the `this` object). If omitted, the current object is used.
-			 * @param {Object} [listenerData] Data to be sent as the
-			 * {@link CKEDITOR.eventInfo#listenerData} when calling the listener.
-			 * @param {Number} [priority=10] The listener priority. Lower priority
-			 * listeners are called first. Listeners with the same priority
-			 * value are called in the registration order.
-			 * @returns {Object} An object containing the `removeListener`
-			 * function that can be used to remove the listener at any time.
-			 */
-			attachListener: function( obj, event, fn, scope, listenerData, priority ) {
-				!this._.listeners && ( this._.listeners = [] );
-				// Register the listener.
-				var args = Array.prototype.slice.call( arguments, 1 ),
-					listener = obj.on.apply( obj, args );
-
-				this._.listeners.push( listener );
-
-				return listener;
-			},
-
-			/**
-			 * Remove all event listeners registered from {@link #attachListener}.
-			 */
-			clearListeners: function() {
-				var listeners = this._.listeners;
-				// Don't get broken by this.
-				try {
-					while ( listeners.length )
-						listeners.pop().removeListener();
-				} catch ( e ) {}
-			},
-
-			/**
-			 * Restore all attribution changes made by {@link #changeAttr }.
-			 */
-			restoreAttrs: function() {
-				var changes = this._.attrChanges, orgVal;
-				for ( var attr in changes ) {
-					if ( changes.hasOwnProperty( attr ) ) {
-						orgVal = changes[ attr ];
-						// Restore original attribute.
-						orgVal !== null ? this.setAttribute( attr, orgVal ) : this.removeAttribute( attr );
-					}
-				}
-			},
-
-			/**
-			 * Adds a CSS class name to this editable that needs to be removed on detaching.
-			 *
-			 * @param {String} className The class name to be added.
-			 * @see CKEDITOR.dom.element#addClass
-			 */
-			attachClass: function( cls ) {
-				var classes = this.getCustomData( 'classes' );
-				if ( !this.hasClass( cls ) ) {
-					!classes && ( classes = [] ), classes.push( cls );
-					this.setCustomData( 'classes', classes );
-					this.addClass( cls );
-				}
-			},
-
-			/**
-			 * Make an attribution change that would be reverted on editable detaching.
-			 * @param {String} attr The attribute name to be changed.
-			 * @param {String} val The value of specified attribute.
-			 */
-			changeAttr: function( attr, val ) {
-				var orgVal = this.getAttribute( attr );
-				if ( val !== orgVal ) {
-					!this._.attrChanges && ( this._.attrChanges = {} );
-
-					// Saved the original attribute val.
-					if ( !( attr in this._.attrChanges ) )
-						this._.attrChanges[ attr ] = orgVal;
-
-					this.setAttribute( attr, val );
-				}
-			},
-
-			/**
-			 * @see CKEDITOR.editor#insertHtml
-			 */
-			insertHtml: function( data, mode ) {
-				beforeInsert( this );
-				// Default mode is 'html'.
-				insert( this, mode || 'html', data );
-			},
-
-			/**
-			 * @see CKEDITOR.editor#insertText
-			 */
-			insertText: function( text ) {
-				beforeInsert( this );
-
-				var editor = this.editor,
-					mode = editor.getSelection().getStartElement().hasAscendant( 'pre', true ) ? CKEDITOR.ENTER_BR : editor.activeEnterMode,
-					isEnterBrMode = mode == CKEDITOR.ENTER_BR,
-					tools = CKEDITOR.tools;
-
-				// CRLF -> LF
-				var html = tools.htmlEncode( text.replace( /\r\n/g, '\n' ) );
-
-				// Tab -> &nbsp x 4;
-				html = html.replace( /\t/g, '&nbsp;&nbsp; &nbsp;' );
-
-				var paragraphTag = mode == CKEDITOR.ENTER_P ? 'p' : 'div';
-
-				// Two line-breaks create one paragraphing block.
-				if ( !isEnterBrMode ) {
-					var duoLF = /\n{2}/g;
-					if ( duoLF.test( html ) )
-					{
-						var openTag = '<' + paragraphTag + '>', endTag = '</' + paragraphTag + '>';
-						html = openTag + html.replace( duoLF, function() { return  endTag + openTag; } ) + endTag;
-					}
-				}
-
-				// One <br> per line-break.
-				html = html.replace( /\n/g, '<br>' );
-
-				// Compensate padding <br> at the end of block, avoid loosing them during insertion.
-				if ( !isEnterBrMode ) {
-					html = html.replace( new RegExp( '<br>(?=</' + paragraphTag + '>)' ), function( match ) {
-						return tools.repeat( match, 2 );
-					} );
-				}
-
-				// Preserve spaces at the ends, so they won't be lost after insertion (merged with adjacent ones).
-				html = html.replace( /^ | $/g, '&nbsp;' );
-
-				// Finally, preserve whitespaces that are to be lost.
-				html = html.replace( /(>|\s) /g, function( match, before ) {
-					return before + '&nbsp;';
-				} ).replace( / (?=<)/g, '&nbsp;' );
-
-				insert( this, 'text', html );
-			},
-
-			/**
-			 * @see CKEDITOR.editor#insertElement
-			 */
-			insertElement: function( element, range ) {
-				if ( !range )
-					this.insertElementIntoSelection( element );
-				else
-					this.insertElementIntoRange( element, range );
-			},
-
-			/**
-			 * Inserts an element into the position in the editor determined by range.
-			 *
-			 * @param {CKEDITOR.dom.element} element The element to be inserted.
-			 * @param {CKEDITOR.dom.range} range The range as a place of insertion.
-			 * @returns {Boolean} Informs whether insertion was successful.
-			 */
-			insertElementIntoRange: function( element, range ) {
-				var editor = this.editor,
-					enterMode = editor.config.enterMode,
-					elementName = element.getName(),
-					isBlock = CKEDITOR.dtd.$block[ elementName ];
-
-				if ( range.checkReadOnly() )
-					return false;
-
-				// Remove the original contents, merge split nodes.
-				range.deleteContents( 1 );
-
-				// If range is placed in inermediate element (not td or th), we need to do three things:
-				// * fill emptied <td/th>s with if browser needs them,
-				// * remove empty text nodes so IE8 won't crash (http://dev.ckeditor.com/ticket/11183#comment:8),
-				// * fix structure and move range into the <td/th> element.
-				if ( range.startContainer.type == CKEDITOR.NODE_ELEMENT && range.startContainer.is( { tr: 1, table: 1, tbody: 1, thead: 1, tfoot: 1 } ) )
-					fixTableAfterContentsDeletion( range );
-
-				// If we're inserting a block at dtd-violated position, split
-				// the parent blocks until we reach blockLimit.
-				var current, dtd;
-
-				if ( isBlock ) {
-					while ( ( current = range.getCommonAncestor( 0, 1 ) ) &&
-					        ( dtd = CKEDITOR.dtd[ current.getName() ] ) &&
-					        !( dtd && dtd[ elementName ] ) ) {
-
-						// Split up inline elements.
-						if ( current.getName() in CKEDITOR.dtd.span )
-							range.splitElement( current );
-
-						// If we're in an empty block which indicate a new paragraph,
-						// simply replace it with the inserting block.(#3664)
-						else if ( range.checkStartOfBlock() && range.checkEndOfBlock() ) {
-							range.setStartBefore( current );
-							range.collapse( true );
-							current.remove();
-						} else
-							range.splitBlock( enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p', editor.editable() );
-					}
-				}
-
-				// Insert the new node.
-				range.insertNode( element );
-
-				// Return true if insertion was successful.
-				return true;
-			},
-
-			/**
-			 * Inserts an element into the currently selected position in the editor.
-			 *
-			 * @param {CKEDITOR.dom.element} element The element to be inserted.
-			 */
-			insertElementIntoSelection: function( element ) {
-				var editor = this.editor,
-					enterMode = editor.activeEnterMode,
-					selection = editor.getSelection(),
-					range = selection.getRanges()[ 0 ],
-					elementName = element.getName(),
-					isBlock = CKEDITOR.dtd.$block[ elementName ];
-
-				// Prepare for the insertion.
-				beforeInsert( this );
-
-				// Insert element into first range only and ignore the rest (#11183).
-				if ( this.insertElementIntoRange( element, range ) ) {
-					range.moveToPosition( element, CKEDITOR.POSITION_AFTER_END );
-
-					// If we're inserting a block element, the new cursor position must be
-					// optimized. (#3100,#5436,#8950)
-					if ( isBlock ) {
-						// Find next, meaningful element.
-						var next = element.getNext( function( node ) {
-							return isNotEmpty( node ) && !isBogus( node );
-						} );
-
-						if ( next && next.type == CKEDITOR.NODE_ELEMENT && next.is( CKEDITOR.dtd.$block ) ) {
-							// If the next one is a text block, move cursor to the start of it's content.
-							if ( next.getDtd()[ '#' ] )
-								range.moveToElementEditStart( next );
-							// Otherwise move cursor to the before end of the last element.
-							else
-								range.moveToElementEditEnd( element );
-						}
-						// Open a new line if the block is inserted at the end of parent.
-						else if ( !next && enterMode != CKEDITOR.ENTER_BR ) {
-							next = range.fixBlock( true, enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' );
-							range.moveToElementEditStart( next );
-						}
-					}
-				}
-
-				// Set up the correct selection.
-				selection.selectRanges( [ range ] );
-
-				// Do not scroll after inserting, because Opera may fail on certain element (e.g. iframe/iframe.html).
-				afterInsert( this, CKEDITOR.env.opera );
-			},
-
-			/**
-			 * @see CKEDITOR.editor#setData
-			 */
-			setData: function( data, isSnapshot ) {
-				if ( !isSnapshot )
-					data = this.editor.dataProcessor.toHtml( data );
-
-				this.setHtml( data );
-				this.editor.fire( 'dataReady' );
-			},
-
-			/**
-			 * @see CKEDITOR.editor#getData
-			 */
-			getData: function( isSnapshot ) {
-				var data = this.getHtml();
-
-				if ( !isSnapshot )
-					data = this.editor.dataProcessor.toDataFormat( data );
-
-				return data;
-			},
-
-			/**
-			 * Change the read-only state on this editable.
-			 *
-			 * @param {Boolean} isReadOnly
-			 */
-			setReadOnly: function( isReadOnly ) {
-				this.setAttribute( 'contenteditable', !isReadOnly );
-			},
-
-			/**
-			 * Detach this editable object from the DOM (remove classes, listeners, etc.)
-			 */
-			detach: function() {
-				// Cleanup the element.
-				this.removeClass( 'cke_editable' );
-
-				// Save the editor reference which will be lost after
-				// calling detach from super class.
-				var editor = this.editor;
-
-				this._.detach();
-
-				delete editor.document;
-				delete editor.window;
-			},
-
-			/**
-			 * Check if the editable is one of the host page element, indicates the
-			 * an inline editing environment.
-			 *
-			 * @returns {Boolean}
-			 */
-			isInline : function() {
-				return this.getDocument().equals( CKEDITOR.document );
-			},
-
-			/**
-			 * Editable element bootstrapping.
-			 *
-			 * @private
-			 */
-			setup: function() {
-				var editor = this.editor;
-
-				// Handle the load/read of editor data/snapshot.
-				this.attachListener( editor, 'beforeGetData', function() {
-					var data = this.getData();
-
-					// Post processing html output of wysiwyg editable.
-					if ( !this.is( 'textarea' ) ) {
-						// Reset empty if the document contains only one empty paragraph.
-						if ( editor.config.ignoreEmptyParagraph !== false )
-							data = data.replace( emptyParagraphRegexp, function( match, lookback ) { return lookback; } );
-					}
-
-					editor.setData( data, null, 1 );
-				}, this );
-
-				this.attachListener( editor, 'getSnapshot', function( evt ) {
-					evt.data = this.getData( 1 );
-				}, this );
-
-				this.attachListener( editor, 'afterSetData', function() {
-					this.setData( editor.getData( 1 ) );
-				}, this );
-				this.attachListener( editor, 'loadSnapshot', function( evt ) {
-					this.setData( evt.data, 1 );
-				}, this );
-
-				// Delegate editor focus/blur to editable.
-				this.attachListener( editor, 'beforeFocus', function() {
-					var sel = editor.getSelection(),
-						ieSel = sel && sel.getNative();
-
-					// IE considers control-type element as separate
-					// focus host when selected, avoid destroying the
-					// selection in such case. (#5812) (#8949)
-					if ( ieSel && ieSel.type == 'Control' )
-						return;
-
-					this.focus();
-				}, this );
-
-				this.attachListener( editor, 'insertHtml', function( evt ) {
-					this.insertHtml( evt.data.dataValue, evt.data.mode );
-				}, this );
-				this.attachListener( editor, 'insertElement', function( evt ) {
-					this.insertElement( evt.data );
-				}, this );
-				this.attachListener( editor, 'insertText', function( evt ) {
-					this.insertText( evt.data );
-				}, this );
-
-				// Update editable state.
-				this.setReadOnly( editor.readOnly );
-
-				// The editable class.
-				this.attachClass( 'cke_editable' );
-
-				// The element mode css class.
-				this.attachClass( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ?
-					'cke_editable_inline' :
-					editor.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ||
-					editor.elementMode == CKEDITOR.ELEMENT_MODE_APPENDTO ?
-					'cke_editable_themed' : ''
-				);
-
-				this.attachClass( 'cke_contents_' + editor.config.contentsLangDirection );
-
-				// Setup editor keystroke handlers on this element.
-				var keystrokeHandler = editor.keystrokeHandler;
-
-				// If editor is read-only, then make sure that BACKSPACE key
-				// is blocked to prevent browser history navigation.
-				keystrokeHandler.blockedKeystrokes[ 8 ] = +editor.readOnly;
-
-				editor.keystrokeHandler.attach( this );
-
-				// Update focus states.
-				this.on( 'blur', function( evt ) {
-					// Opera might raise undesired blur event on editable, check if it's
-					// really blurred, otherwise cancel the event. (#9459)
-					if ( CKEDITOR.env.opera ) {
-						var active = CKEDITOR.document.getActive();
-						if ( active.equals( this.isInline() ? this : this.getWindow().getFrame() ) ) {
-							evt.cancel();
-							return;
-						}
-					}
-
-					this.hasFocus = false;
-				}, null, null, -1 );
-
-				this.on( 'focus', function() {
-					this.hasFocus = true;
-				}, null, null, -1 );
-
-				// Register to focus manager.
-				editor.focusManager.add( this );
-
-				// Inherit the initial focus on editable element.
-				if ( this.equals( CKEDITOR.document.getActive() ) ) {
-					this.hasFocus = true;
-					// Pending until this editable has attached.
-					editor.once( 'contentDom', function() {
-						editor.focusManager.focus();
-					} );
-				}
-
-				// Apply tab index on demand, with original direction saved.
-				if ( this.isInline() ) {
-
-					// tabIndex of the editable is different than editor's one.
-					// Update the attribute of the editable.
-					this.changeAttr( 'tabindex', editor.tabIndex );
-				}
-
-				// The above is all we'll be doing for a <textarea> editable.
-				if ( this.is( 'textarea' ) )
-					return;
-
-				// The DOM document which the editing acts upon.
-				editor.document = this.getDocument();
-				editor.window = this.getWindow();
-
-				var doc = editor.document;
-
-				this.changeAttr( 'spellcheck', !editor.config.disableNativeSpellChecker );
-
-				// Apply contents direction on demand, with original direction saved.
-				var dir = editor.config.contentsLangDirection;
-				if ( this.getDirection( 1 ) != dir )
-					this.changeAttr( 'dir', dir );
-
-				// Create the content stylesheet for this document.
-				var styles = CKEDITOR.getCss();
-				if ( styles ) {
-					var head = doc.getHead();
-					if ( !head.getCustomData( 'stylesheet' ) ) {
-						var sheet = doc.appendStyleText( styles );
-						sheet = new CKEDITOR.dom.element( sheet.ownerNode || sheet.owningElement );
-						head.setCustomData( 'stylesheet', sheet );
-						sheet.data( 'cke-temp', 1 );
-					}
-				}
-
-				// Update the stylesheet sharing count.
-				var ref = doc.getCustomData( 'stylesheet_ref' ) || 0;
-				doc.setCustomData( 'stylesheet_ref', ref + 1 );
-
-				// Pass this configuration to styles system.
-				this.setCustomData( 'cke_includeReadonly', !editor.config.disableReadonlyStyling );
-
-				// Prevent the browser opening read-only links. (#6032 & #10912)
-				this.attachListener( this, 'click', function( evt ) {
-					evt = evt.data;
-
-					var link = new CKEDITOR.dom.elementPath( evt.getTarget(), this ).contains( 'a' );
-
-					if ( link && evt.$.button != 2 && link.isReadOnly() )
-						evt.preventDefault();
-				} );
-
-				var backspaceOrDelete = { 8: 1, 46: 1 };
-
-				// Override keystrokes which should have deletion behavior
-				//  on fully selected element . (#4047) (#7645)
-				this.attachListener( editor, 'key', function( evt ) {
-					if ( editor.readOnly )
-						return true;
-
-					var keyCode = evt.data.keyCode, isHandled;
-
-					// Backspace OR Delete.
-					if ( keyCode in backspaceOrDelete ) {
-						var sel = editor.getSelection(),
-							selected,
-							range = sel.getRanges()[ 0 ],
-							path = range.startPath(),
-							block,
-							parent,
-							next,
-							rtl = keyCode == 8;
-
-						if (
-							// [IE<11] Remove selected image/anchor/etc here to avoid going back in history. (#10055)
-							( CKEDITOR.env.ie && CKEDITOR.env.version < 11 && ( selected = sel.getSelectedElement() ) ) ||
-							// Remove the entire list/table on fully selected content. (#7645)
-							( selected = getSelectedTableList( sel ) )
-						) {
-							// Make undo snapshot.
-							editor.fire( 'saveSnapshot' );
-
-							// Delete any element that 'hasLayout' (e.g. hr,table) in IE8 will
-							// break up the selection, safely manage it here. (#4795)
-							range.moveToPosition( selected, CKEDITOR.POSITION_BEFORE_START );
-							// Remove the control manually.
-							selected.remove();
-							range.select();
-
-							editor.fire( 'saveSnapshot' );
-
-							isHandled = 1;
-						} else if ( range.collapsed ) {
-							// Handle the following special cases: (#6217)
-							// 1. Del/Backspace key before/after table;
-							// 2. Backspace Key after start of table.
-							if ( ( block = path.block ) &&
-								 ( next = block[ rtl ? 'getPrevious' : 'getNext' ]( isNotWhitespace ) ) &&
-								 ( next.type == CKEDITOR.NODE_ELEMENT ) &&
-								 next.is( 'table' ) &&
-								 range[ rtl ? 'checkStartOfBlock' : 'checkEndOfBlock' ]() )
-							{
-								editor.fire( 'saveSnapshot' );
-
-								// Remove the current empty block.
-								if ( range[ rtl ? 'checkEndOfBlock' : 'checkStartOfBlock' ]() )
-									block.remove();
-
-								// Move cursor to the beginning/end of table cell.
-								range[ 'moveToElementEdit' + ( rtl ? 'End' : 'Start' ) ]( next );
-								range.select();
-
-								editor.fire( 'saveSnapshot' );
-
-								isHandled = 1;
-							}
-							else if ( path.blockLimit && path.blockLimit.is( 'td' ) &&
-									  ( parent = path.blockLimit.getAscendant( 'table' ) ) &&
-									  range.checkBoundaryOfElement( parent, rtl ? CKEDITOR.START : CKEDITOR.END ) &&
-									  ( next = parent[ rtl ? 'getPrevious' : 'getNext' ]( isNotWhitespace ) ) )
-							{
-								editor.fire( 'saveSnapshot' );
-
-								// Move cursor to the end of previous block.
-								range[ 'moveToElementEdit' + ( rtl ? 'End' : 'Start' ) ]( next );
-
-								// Remove any previous empty block.
-								if ( range.checkStartOfBlock() && range.checkEndOfBlock() )
-									next.remove();
-								else
-									range.select();
-
-								editor.fire( 'saveSnapshot' );
-
-								isHandled = 1;
-							}
-							// BACKSPACE/DEL pressed at the start/end of table cell.
-							else if ( ( parent = path.contains( [ 'td', 'th', 'caption' ] ) ) &&
-								      range.checkBoundaryOfElement( parent, rtl ? CKEDITOR.START : CKEDITOR.END ) ) {
-								isHandled = 1;
-							}
-						}
-
-					}
-
-					return !isHandled;
-				} );
-
-				// On IE>=11 we need to fill blockless editable with <br> if it was deleted.
-				if ( editor.blockless && CKEDITOR.env.ie && CKEDITOR.env.needsBrFiller ) {
-					this.attachListener( this, 'keyup', function( evt ) {
-						if ( evt.data.getKeystroke() in backspaceOrDelete && !this.getFirst( isNotEmpty ) ) {
-							this.appendBogus();
-
-							// Set the selection before bogus, because IE tends to put it after.
-							var range = editor.createRange();
-							range.moveToPosition( this, CKEDITOR.POSITION_AFTER_START );
-							range.select();
-						}
-					} );
-				}
-
-				this.attachListener( this, 'dblclick', function( evt ) {
-					if ( editor.readOnly )
-						return false;
-
-					var data = { element: evt.data.getTarget() };
-					editor.fire( 'doubleclick', data );
-				} );
-
-				// Prevent automatic submission in IE #6336
-				CKEDITOR.env.ie && this.attachListener( this, 'click', blockInputClick );
-
-				// Gecko/Webkit need some help when selecting control type elements. (#3448)
-				if ( !( CKEDITOR.env.ie || CKEDITOR.env.opera ) ) {
-					this.attachListener( this, 'mousedown', function( ev ) {
-						var control = ev.data.getTarget();
-						if ( control.is( 'img', 'hr', 'input', 'textarea', 'select' ) ) {
-							editor.getSelection().selectElement( control );
-
-							// Prevent focus from stealing from the editable. (#9515)
-							if ( control.is( 'input', 'textarea', 'select' ) )
-								ev.data.preventDefault();
-						}
-					} );
-				}
-
-				// Prevent right click from selecting an empty block even
-				// when selection is anchored inside it. (#5845)
-				if ( CKEDITOR.env.gecko ) {
-					this.attachListener( this, 'mouseup', function( ev ) {
-						if ( ev.data.$.button == 2 ) {
-							var target = ev.data.getTarget();
-
-							if ( !target.getOuterHtml().replace( emptyParagraphRegexp, '' ) ) {
-								var range = editor.createRange();
-								range.moveToElementEditStart( target );
-								range.select( true );
-							}
-						}
-					} );
-				}
-
-				// Webkit: avoid from editing form control elements content.
-				if ( CKEDITOR.env.webkit ) {
-					// Prevent from tick checkbox/radiobox/select
-					this.attachListener( this, 'click', function( ev ) {
-						if ( ev.data.getTarget().is( 'input', 'select' ) )
-							ev.data.preventDefault();
-					} );
-
-					// Prevent from editig textfield/textarea value.
-					this.attachListener( this, 'mouseup', function( ev ) {
-						if ( ev.data.getTarget().is( 'input', 'textarea' ) )
-							ev.data.preventDefault();
-					} );
-				}
-			}
-		},
-
-		_: {
-			detach: function() {
-				// Update the editor cached data with current data.
-				this.editor.setData( this.editor.getData(), 0, 1 );
-
-				this.clearListeners();
-				this.restoreAttrs();
-
-				// Cleanup our custom classes.
-				var classes;
-				if ( ( classes = this.removeCustomData( 'classes' ) ) ) {
-					while ( classes.length )
-						this.removeClass( classes.pop() );
-				}
-
-				// Remove contents stylesheet from document if it's the last usage.
-				var doc = this.getDocument(),
-					head = doc.getHead();
-				if ( head.getCustomData( 'stylesheet' ) ) {
-					var refs = doc.getCustomData( 'stylesheet_ref' );
-					if ( !( --refs ) ) {
-						doc.removeCustomData( 'stylesheet_ref' );
-						var sheet = head.removeCustomData( 'stylesheet' );
-						sheet.remove();
-					} else
-						doc.setCustomData( 'stylesheet_ref', refs );
-				}
-
-				this.editor.fire( 'contentDomUnload' );
-
-				// Free up the editor reference.
-				delete this.editor;
-			}
-		}
-	} );
-
-	/**
-	 * Create, retrieve or detach an editable element of the editor,
-	 * this method should always be used instead of calling directly {@link CKEDITOR.editable}.
-	 *
-	 * @method editable
-	 * @member CKEDITOR.editor
-	 * @param {CKEDITOR.dom.element/CKEDITOR.editable} elementOrEditable The
-	 * DOM element to become the editable or a {@link CKEDITOR.editable} object.
-	 */
-	CKEDITOR.editor.prototype.editable = function( element ) {
-		var editable = this._.editable;
-
-		// This editor has already associated with
-		// an editable element, silently fails.
-		if ( editable && element )
-			return 0;
-
-		if ( arguments.length ) {
-			editable = this._.editable = element ? ( element instanceof CKEDITOR.editable ? element : new CKEDITOR.editable( this, element ) ) :
-			// Detach the editable from editor.
-			( editable && editable.detach(), null );
-		}
-
-		// Just retrieve the editable.
-		return editable;
-	};
-
-	// Auto-fixing block-less content by wrapping paragraph (#3190), prevent
-	// non-exitable-block by padding extra br.(#3189)
-	// Returns truly value when dom was changed, falsy otherwise.
-	function fixDom( evt ) {
-		var editor = evt.editor,
-			path = evt.data.path,
-			blockLimit = path.blockLimit,
-			selection = evt.data.selection,
-			range = selection.getRanges()[ 0 ],
-			enterMode = editor.activeEnterMode,
-			selectionUpdateNeeded;
-
-		if ( CKEDITOR.env.gecko || ( CKEDITOR.env.ie && CKEDITOR.env.needsBrFiller ) ) {
-			var blockNeedsFiller = needsBrFiller( selection, path );
-			if ( blockNeedsFiller ) {
-				blockNeedsFiller.appendBogus();
-				// IE tends to place selection after appended bogus, so we need to
-				// select the original range (placed before bogus).
-				selectionUpdateNeeded = CKEDITOR.env.ie;
-			}
-		}
-
-		// When we're in block enter mode, a new paragraph will be established
-		// to encapsulate inline contents inside editable. (#3657)
-		// Don't autoparagraph if browser (namely - IE) incorrectly anchored selection
-		// inside non-editable content. This happens e.g. if non-editable block is the only
-		// content of editable.
-		if ( shouldAutoParagraph( editor, path.block, blockLimit ) && range.collapsed && !range.getCommonAncestor().isReadOnly() ) {
-			var testRng = range.clone();
-			testRng.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
-			var walker = new CKEDITOR.dom.walker( testRng );
-			walker.guard = function( node ) {
-				return !isNotEmpty( node ) ||
-				       node.type == CKEDITOR.NODE_COMMENT ||
-				       node.isReadOnly();
-			};
-
-			// 1. Inline content discovered under cursor;
-			// 2. Empty editable.
-			if ( !walker.checkForward() ||
-			     testRng.checkStartOfBlock() && testRng.checkEndOfBlock() ) {
-
-				var fixedBlock = range.fixBlock( true, editor.activeEnterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' );
-
-				// For IE<11, we should remove any filler node which was introduced before.
-				if ( !CKEDITOR.env.needsBrFiller ) {
-					var first = fixedBlock.getFirst( isNotEmpty );
-					if ( first && isNbsp( first ) )
-						first.remove();
-				}
-
-				selectionUpdateNeeded = 1;
-
-				// Cancel this selection change in favor of the next (correct). (#6811)
-				evt.cancel();
-			}
-		}
-
-		if ( selectionUpdateNeeded )
-			range.select();
-	}
-
-	// Checks whether current selection requires br filler to be appended.
-	// @returns Block which needs filler or falsy value.
-	function needsBrFiller( selection, path ) {
-		// Fake selection does not need filler, because it is fake.
-		if ( selection.isFake )
-			return 0;
-
-		// Ensure bogus br could help to move cursor (out of styles) to the end of block. (#7041)
-		var pathBlock = path.block || path.blockLimit,
-			lastNode = pathBlock && pathBlock.getLast( isNotEmpty );
-
-		// Check some specialities of the current path block:
-		// 1. It is really displayed as block; (#7221)
-		// 2. It doesn't end with one inner block; (#7467)
-		// 3. It doesn't have bogus br yet.
-		if (
-			pathBlock && pathBlock.isBlockBoundary() &&
-			!( lastNode && lastNode.type == CKEDITOR.NODE_ELEMENT && lastNode.isBlockBoundary() ) &&
-			!pathBlock.is( 'pre' ) && !pathBlock.getBogus()
-		)
-			return pathBlock;
-	}
-
-	function blockInputClick( evt ) {
-		var element = evt.data.getTarget();
-		if ( element.is( 'input' ) ) {
-			var type = element.getAttribute( 'type' );
-			if ( type == 'submit' || type == 'reset' )
-				evt.data.preventDefault();
-		}
-	}
-
-	function isBlankParagraph( block ) {
-		return block.getOuterHtml().match( emptyParagraphRegexp );
-	}
-
-	function isNotEmpty( node ) {
-		return isNotWhitespace( node ) && isNotBookmark( node );
-	}
-
-	function isNbsp( node ) {
-		return node.type == CKEDITOR.NODE_TEXT && CKEDITOR.tools.trim( node.getText() ).match( /^(?:&nbsp;|\xa0)$/ );
-	}
-
-	// Elements that could blink the cursor anchoring beside it, like hr, page-break. (#6554)
-	function nonEditable( element ) {
-		return element.isBlockBoundary() && CKEDITOR.dtd.$empty[ element.getName() ];
-	}
-
-	function isNotBubbling( fn, src ) {
-		return function( evt ) {
-			var other = CKEDITOR.dom.element.get( evt.data.$.toElement || evt.data.$.fromElement || evt.data.$.relatedTarget );
-			if ( !( other && ( src.equals( other ) || src.contains( other ) ) ) )
-				fn.call( this, evt );
-		};
-	}
-
-	var isBogus = CKEDITOR.dom.walker.bogus();
-
-	// Check if the entire table/list contents is selected.
-	function getSelectedTableList( sel ) {
-		var selected,
-			range = sel.getRanges()[ 0 ],
-			editable = sel.root,
-			path = range.startPath(),
-			structural = { table: 1, ul: 1, ol: 1, dl: 1 };
-
-		if ( path.contains( structural ) ) {
-			function guard( forwardGuard ) {
-				return function( node, isWalkOut ) {
-					// Save the encountered node as selected if going down the DOM structure
-					// and the node is structured element.
-					if ( isWalkOut && node.type == CKEDITOR.NODE_ELEMENT && node.is( structural ) )
-						selected = node;
-
-					// Stop the walker when either traversing another non-empty node at the same
-					// DOM level as in previous step.
-					// NOTE: When going forwards, stop if encountered a bogus.
-					if ( !isWalkOut && isNotEmpty( node ) && !( forwardGuard && isBogus( node ) ) )
-						return false;
-				};
-			}
-
-			// Clone the original range.
-			var walkerRng = range.clone();
-
-			// Enlarge the range: X<ul><li>[Y]</li></ul>X => [X<ul><li>]Y</li></ul>X
-			walkerRng.collapse( 1 );
-			walkerRng.setStartAt( editable, CKEDITOR.POSITION_AFTER_START );
-
-			// Create a new walker.
-			var walker = new CKEDITOR.dom.walker( walkerRng );
-
-			// Assign a new guard to the walker.
-			walker.guard = guard();
-
-			// Go backwards checking for selected structural node.
-			walker.checkBackward();
-
-			// If there's a selected structured element when checking backwards,
-			// then check the same forwards.
-			if ( selected ) {
-				// Clone the original range.
-				walkerRng = range.clone();
-
-				// Enlarge the range (assuming <ul> is selected element from guard):
-				//
-				// 	   X<ul><li>[Y]</li></ul>X    =>    X<ul><li>Y[</li></ul>]X
-				//
-				// If the walker went deeper down DOM than a while ago when traversing
-				// backwards, then it doesn't make sense: an element must be selected
-				// symmetrically. By placing range end **after previously selected node**,
-				// we make sure we don't go no deeper in DOM when going forwards.
-				walkerRng.collapse();
-				walkerRng.setEndAt( selected, CKEDITOR.POSITION_AFTER_END );
-
-				// Create a new walker.
-				walker = new CKEDITOR.dom.walker( walkerRng );
-
-				// Assign a new guard to the walker.
-				walker.guard = guard( true );
-
-				// Reset selected node.
-				selected = false;
-
-				// Go forwards checking for selected structural node.
-				walker.checkForward();
-
-				return selected;
-			}
-		}
-
-		return null;
-	}
-
-	// Whether in given context (pathBlock, pathBlockLimit and editor settings)
-	// editor should automatically wrap inline contents with blocks.
-	function shouldAutoParagraph( editor, pathBlock, pathBlockLimit ) {
-		return editor.config.autoParagraph !== false &&
-			editor.activeEnterMode != CKEDITOR.ENTER_BR &&
-			editor.editable().equals( pathBlockLimit ) && !pathBlock;
-	}
-
-	// Matching an empty paragraph at the end of document.
-	var emptyParagraphRegexp = /(^|<body\b[^>]*>)\s*<(p|div|address|h\d|center|pre)[^>]*>\s*(?:<br[^>]*>|&nbsp;|\u00A0|&#160;)?\s*(:?<\/\2>)?\s*(?=$|<\/body>)/gi;
-
-	var isNotWhitespace = CKEDITOR.dom.walker.whitespaces( true ),
-		isNotBookmark = CKEDITOR.dom.walker.bookmark( false, true );
-
-	CKEDITOR.on( 'instanceLoaded', function( evt ) {
-		var editor = evt.editor;
-
-		// and flag that the element was locked by our code so it'll be editable by the editor functions (#6046).
-		editor.on( 'insertElement', function( evt ) {
-			var element = evt.data;
-			if ( element.type == CKEDITOR.NODE_ELEMENT && ( element.is( 'input' ) || element.is( 'textarea' ) ) ) {
-				// // The element is still not inserted yet, force attribute-based check.
-				if ( element.getAttribute( 'contentEditable' ) != "false" )
-					element.data( 'cke-editable', element.hasAttribute( 'contenteditable' ) ? 'true' : '1' );
-				element.setAttribute( 'contentEditable', false );
-			}
-		} );
-
-		editor.on( 'selectionChange', function( evt ) {
-			if ( editor.readOnly )
-				return;
-
-			// Auto fixing on some document structure weakness to enhance usabilities. (#3190 and #3189)
-			var sel = editor.getSelection();
-			// Do it only when selection is not locked. (#8222)
-			if ( sel && !sel.isLocked ) {
-				var isDirty = editor.checkDirty();
-
-				// Lock undoM before touching DOM to prevent
-				// recording these changes as separate snapshot.
-				editor.fire( 'lockSnapshot' );
-				fixDom( evt );
-				editor.fire( 'unlockSnapshot' );
-
-				!isDirty && editor.resetDirty();
-			}
-		} );
-	} );
-
-
-	CKEDITOR.on( 'instanceCreated', function( evt ) {
-		var editor = evt.editor;
-
-		editor.on( 'mode', function() {
-
-			var editable = editor.editable();
-
-			// Setup proper ARIA roles and properties for inline editable, classic
-			// (iframe-based) editable is instead handled by plugin.
-			if ( editable && editable.isInline() ) {
-
-				var ariaLabel = editor.title;
-
-				editable.changeAttr( 'role', 'textbox' );
-				editable.changeAttr( 'aria-label', ariaLabel );
-
-				if ( ariaLabel )
-					editable.changeAttr( 'title', ariaLabel );
-
-				// Put the voice label in different spaces, depending on element mode, so
-				// the DOM element get auto detached on mode reload or editor destroy.
-				var ct = this.ui.space( this.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ? 'top' : 'contents' );
-				if ( ct ) {
-					var ariaDescId = CKEDITOR.tools.getNextId(),
-						desc = CKEDITOR.dom.element.createFromHtml( '<span id="' + ariaDescId + '" class="cke_voice_label">' + this.lang.common.editorHelp + '</span>' );
-					ct.append( desc );
-					editable.changeAttr( 'aria-describedby', ariaDescId );
-				}
-			}
-		} );
-	} );
-
-	// #9222: Show text cursor in Gecko.
-	// Show default cursor over control elements on all non-IEs.
-	CKEDITOR.addCss( '.cke_editable{cursor:text}.cke_editable img,.cke_editable input,.cke_editable textarea{cursor:default}' );
-
-	//
-	// Functions related to insertXXX methods
-	//
-	var insert = ( function() {
-		'use strict';
-
-		var DTD = CKEDITOR.dtd;
-
-		// Inserts the given (valid) HTML into the range position (with range content deleted),
-		// guarantee it's result to be a valid DOM tree.
-		function insert( editable, type, data ) {
-			var editor = editable.editor,
-				doc = editable.getDocument(),
-				selection = editor.getSelection(),
-				// HTML insertion only considers the first range.
-				// Note: getRanges will be overwritten for tests since we want to test
-				// 		custom ranges and bypass native selections.
-				// TODO what should we do with others? Remove?
-				range = selection.getRanges()[ 0 ],
-				dontFilter = false;
-
-			if ( type == 'unfiltered_html' ) {
-				type = 'html';
-				dontFilter = true;
-			}
-
-			// Check range spans in non-editable.
-			if ( range.checkReadOnly() )
-				return;
-
-			// RANGE PREPARATIONS
-
-			var path = new CKEDITOR.dom.elementPath( range.startContainer, range.root ),
-				// Let root be the nearest block that's impossible to be split
-				// during html processing.
-				blockLimit = path.blockLimit || range.root,
-				// The "state" value.
-				that = {
-					type: type,
-					dontFilter: dontFilter,
-					editable: editable,
-					editor: editor,
-					range: range,
-					blockLimit: blockLimit,
-					// During pre-processing / preparations startContainer of affectedRange should be placed
-					// in this element in which inserted or moved (in case when we merge blocks) content
-					// could create situation that will need merging inline elements.
-					// Examples:
-					// <div><b>A</b>^B</div> + <b>C</b> => <div><b>A</b><b>C</b>B</div> - affected container is <div>.
-					// <p><b>A[B</b></p><p><b>C]D</b></p> + E => <p><b>AE</b></p><p><b>D</b></p> =>
-					//		<p><b>AE</b><b>D</b></p> - affected container is <p> (in text mode).
-					mergeCandidates: [],
-					zombies: []
-				};
-
-			prepareRangeToDataInsertion( that );
-
-			// DATA PROCESSING
-
-			// Select range and stop execution.
-			// If data has been totally emptied after the filtering,
-			// any insertion is pointless (#10339).
-			if ( data && processDataForInsertion( that, data ) ) {
-				// DATA INSERTION
-				insertDataIntoRange( that );
-			}
-
-			// FINAL CLEANUP
-			// Set final range position and clean up.
-
-			cleanupAfterInsertion( that );
-
-			// Make the final range selection.
-			range.select();
-
-			afterInsert( editable );
-		}
-
-		// Prepare range to its data deletion.
-		// Delete its contents.
-		// Prepare it to insertion.
-		function prepareRangeToDataInsertion( that ) {
-			var range = that.range,
-				mergeCandidates = that.mergeCandidates,
-				node, marker, path, startPath, endPath, previous, bm;
-
-			// If range starts in inline element then insert a marker, so empty
-			// inline elements won't be removed while range.deleteContents
-			// and we will be able to move range back into this element.
-			// E.g. 'aa<b>[bb</b>]cc' -> (after deleting) 'aa<b><span/></b>cc'
-			if ( that.type == 'text' && range.shrink( CKEDITOR.SHRINK_ELEMENT, true, false ) ) {
-				marker = CKEDITOR.dom.element.createFromHtml( '<span>&nbsp;</span>', range.document );
-				range.insertNode( marker );
-				range.setStartAfter( marker );
-			}
-
-			// By using path we can recover in which element was startContainer
-			// before deleting contents.
-			// Start and endPathElements will be used to squash selected blocks, after removing
-			// selection contents. See rule 5.
-			startPath = new CKEDITOR.dom.elementPath( range.startContainer );
-			that.endPath = endPath = new CKEDITOR.dom.elementPath( range.endContainer );
-
-			if ( !range.collapsed ) {
-				// Anticipate the possibly empty block at the end of range after deletion.
-				node = endPath.block || endPath.blockLimit;
-				var ancestor = range.getCommonAncestor();
-				if ( node && !( node.equals( ancestor ) || node.contains( ancestor ) ) &&
-				     range.checkEndOfBlock() ) {
-					that.zombies.push( node );
-				}
-
-				range.deleteContents();
-			}
-
-			// Rule 4.
-			// Move range into the previous block.
-			while (
-				( previous = getRangePrevious( range ) ) && checkIfElement( previous ) && previous.isBlockBoundary() &&
-				// Check if previousNode was parent of range's startContainer before deleteContents.
-				startPath.contains( previous )
-			)
-				range.moveToPosition( previous, CKEDITOR.POSITION_BEFORE_END );
-
-			// Rule 5.
-			mergeAncestorElementsOfSelectionEnds( range, that.blockLimit, startPath, endPath );
-
-			// Rule 1.
-			if ( marker ) {
-				// If marker was created then move collapsed range into its place.
-				range.setEndBefore( marker );
-				range.collapse();
-				marker.remove();
-			}
-
-			// Split inline elements so HTML will be inserted with its own styles.
-			path = range.startPath();
-			if ( ( node = path.contains( isInline, false, 1 ) ) ) {
-				range.splitElement( node );
-				that.inlineStylesRoot = node;
-				that.inlineStylesPeak = path.lastElement;
-			}
-
-			// Record inline merging candidates for later cleanup in place.
-			bm = range.createBookmark();
-
-			// 1. Inline siblings.
-			node = bm.startNode.getPrevious( isNotEmpty );
-			node && checkIfElement( node ) && isInline( node ) && mergeCandidates.push( node );
-			node = bm.startNode.getNext( isNotEmpty );
-			node && checkIfElement( node ) && isInline( node ) && mergeCandidates.push( node );
-
-			// 2. Inline parents.
-			node = bm.startNode;
-			while ( ( node = node.getParent() ) && isInline( node ) )
-				mergeCandidates.push( node );
-
-			range.moveToBookmark( bm );
-		}
-
-		function processDataForInsertion( that, data ) {
-			var range = that.range;
-
-			// Rule 8. - wrap entire data in inline styles.
-			// (e.g. <p><b>x^z</b></p> + <p>a</p><p>b</p> -> <b><p>a</p><p>b</p></b>)
-			// Incorrect tags order will be fixed by htmlDataProcessor.
-			if ( that.type == 'text' && that.inlineStylesRoot )
-				data = wrapDataWithInlineStyles( data, that );
-
-
-			var context = that.blockLimit.getName();
-
-			// Wrap data to be inserted, to avoid loosing leading whitespaces
-			// when going through the below procedure.
-			if ( /^\s+|\s+$/.test( data ) && 'span' in CKEDITOR.dtd[ context ] ) {
-				var protect = '<span data-cke-marker="1">&nbsp;</span>';
-				data =  protect + data + protect;
-			}
-
-			// Process the inserted html, in context of the insertion root.
-			// Don't use the "fix for body" feature as auto paragraphing must
-			// be handled during insertion.
-			data = that.editor.dataProcessor.toHtml( data, {
-				context: null,
-				fixForBody: false,
-				dontFilter: that.dontFilter,
-				// Use the current, contextual settings.
-				filter: that.editor.activeFilter,
-				enterMode: that.editor.activeEnterMode
-			} );
-
-
-			// Build the node list for insertion.
-			var doc = range.document,
-				wrapper = doc.createElement( 'body' );
-
-			wrapper.setHtml( data );
-
-			// Eventually remove the temporaries.
-			if ( protect ) {
-				wrapper.getFirst().remove();
-				wrapper.getLast().remove();
-			}
-
-			// Rule 7.
-			var block = range.startPath().block;
-			if ( block &&													// Apply when there exists path block after deleting selection's content...
-				!( block.getChildCount() == 1 && block.getBogus() ) ) {		// ... and the only content of this block isn't a bogus.
-				stripBlockTagIfSingleLine( wrapper );
-			}
-
-			that.dataWrapper = wrapper;
-
-			return data;
-		}
-
-		function insertDataIntoRange( that ) {
-			var range = that.range,
-				doc = range.document,
-				path,
-				blockLimit = that.blockLimit,
-				nodesData, nodeData, node,
-				nodeIndex = 0,
-				bogus,
-				bogusNeededBlocks = [],
-				pathBlock, fixBlock,
-				splittingContainer = 0,
-				dontMoveCaret = 0,
-				insertionContainer, toSplit, newContainer,
-				startContainer = range.startContainer,
-				endContainer = that.endPath.elements[ 0 ],
-				filteredNodes,
-				// If endContainer was merged into startContainer: <p>a[b</p><p>c]d</p>
-				// or it's equal to startContainer: <p>a^b</p>
-				// or different situation happened :P
-				// then there's no separate container for the end of selection.
-				pos = endContainer.getPosition( startContainer ),
-				separateEndContainer = !!endContainer.getCommonAncestor( startContainer ) // endC is not detached.
-				&& pos != CKEDITOR.POSITION_IDENTICAL && !( pos & CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_IS_CONTAINED ); // endC & endS are in separate branches.
-
-			nodesData = extractNodesData( that.dataWrapper, that );
-
-			removeBrsAdjacentToPastedBlocks( nodesData, range );
-
-			for ( ; nodeIndex < nodesData.length; nodeIndex++ ) {
-				nodeData = nodesData[ nodeIndex ];
-
-				// Ignore trailing <brs>
-				if ( nodeData.isLineBreak && splitOnLineBreak( range, blockLimit, nodeData ) ) {
-					// Do not move caret towards the text (in cleanupAfterInsertion),
-					// because caret was placed after a line break.
-					dontMoveCaret = nodeIndex > 0;
-					continue;
-				}
-
-				path = range.startPath();
-
-				// Auto paragraphing.
-				if ( !nodeData.isBlock && shouldAutoParagraph( that.editor, path.block, path.blockLimit ) && ( fixBlock = autoParagraphTag( that.editor ) ) ) {
-					fixBlock = doc.createElement( fixBlock );
-					fixBlock.appendBogus();
-					range.insertNode( fixBlock );
-					if ( CKEDITOR.env.needsBrFiller && ( bogus = fixBlock.getBogus() ) )
-						bogus.remove();
-					range.moveToPosition( fixBlock, CKEDITOR.POSITION_BEFORE_END );
-				}
-
-				node = range.startPath().block;
-
-				// Remove any bogus element on the current path block for now, and mark
-				// it for later compensation.
-				if ( node && !node.equals( pathBlock ) ) {
-					bogus = node.getBogus();
-					if ( bogus ) {
-						bogus.remove();
-						bogusNeededBlocks.push( node );
-					}
-
-					pathBlock = node;
-				}
-
-				// First not allowed node reached - start splitting original container
-				if ( nodeData.firstNotAllowed )
-					splittingContainer = 1;
-
-				if ( splittingContainer && nodeData.isElement ) {
-					insertionContainer = range.startContainer;
-					toSplit = null;
-
-					// Find the first ancestor that can contain current node.
-					// This one won't be split.
-					while ( insertionContainer && !DTD[ insertionContainer.getName() ][ nodeData.name ] ) {
-						if ( insertionContainer.equals( blockLimit ) ) {
-							insertionContainer = null;
-							break;
-						}
-
-						toSplit = insertionContainer;
-						insertionContainer = insertionContainer.getParent();
-					}
-
-					// If split has to be done - do it and mark both ends as a possible zombies.
-					if ( insertionContainer ) {
-						if ( toSplit ) {
-							newContainer = range.splitElement( toSplit );
-							that.zombies.push( newContainer );
-							that.zombies.push( toSplit );
-						}
-					}
-					// Unable to make the insertion happen in place, resort to the content filter.
-					else {
-						// If everything worked fine insertionContainer == blockLimit here.
-						filteredNodes = filterElement( nodeData.node, blockLimit.getName(), !nodeIndex, nodeIndex == nodesData.length - 1 );
-					}
-				}
-
-				if ( filteredNodes ) {
-					while ( ( node = filteredNodes.pop() ) )
-						range.insertNode( node );
-					filteredNodes = 0;
-				} else
-					// Insert current node at the start of range.
-					range.insertNode( nodeData.node );
-
-				// Move range to the endContainer for the final allowed elements.
-				if ( nodeData.lastNotAllowed && nodeIndex < nodesData.length - 1 ) {
-					// If separateEndContainer exists move range there.
-					// Otherwise try to move range to container created during splitting.
-					// If this doesn't work - don't move range.
-					newContainer = separateEndContainer ? endContainer : newContainer;
-					newContainer && range.setEndAt( newContainer, CKEDITOR.POSITION_AFTER_START );
-					splittingContainer = 0;
-				}
-
-				// Collapse range after insertion to end.
-				range.collapse();
-			}
-
-			that.dontMoveCaret = dontMoveCaret;
-			that.bogusNeededBlocks = bogusNeededBlocks;
-		}
-
-		function cleanupAfterInsertion( that ) {
-			var range = that.range,
-				node, testRange, parent, movedIntoInline,
-				bogusNeededBlocks = that.bogusNeededBlocks,
-				// Create a bookmark to defend against the following range deconstructing operations.
-				bm = range.createBookmark();
-
-			// Remove all elements that could be created while splitting nodes
-			// with ranges at its start|end.
-			// E.g. remove <div><p></p></div>
-			// But not <div><p> </p></div>
-			// And replace <div><p><span data="cke-bookmark"/></p></div> with found bookmark.
-			while ( ( node = that.zombies.pop() ) ) {
-				// Detached element.
-				if ( !node.getParent() )
-					continue;
-
-				testRange = range.clone();
-				testRange.moveToElementEditStart( node );
-				testRange.removeEmptyBlocksAtEnd();
-			}
-
-			if ( bogusNeededBlocks ) {
-				// Bring back all block bogus nodes.
-				while ( ( node = bogusNeededBlocks.pop() ) ) {
-					if ( CKEDITOR.env.needsBrFiller )
-						node.appendBogus();
-					else
-						node.append( range.document.createText( '\u00a0' ) );
-				}
-			}
-
-			// Eventually merge identical inline elements.
-			while ( ( node = that.mergeCandidates.pop() ) )
-				node.mergeSiblings();
-
-			range.moveToBookmark( bm );
-
-			// Rule 3.
-			// Shrink range to the BEFOREEND of previous innermost editable node in source order.
-
-			if ( !that.dontMoveCaret ) {
-				node = getRangePrevious( range );
-
-				while ( node && checkIfElement( node ) && !node.is( DTD.$empty ) ) {
-					if ( node.isBlockBoundary() )
-						range.moveToPosition( node, CKEDITOR.POSITION_BEFORE_END );
-					else {
-						// Don't move into inline element (which ends with a text node)
-						// found which contains white-space at its end.
-						// If not - move range's end to the end of this element.
-						if ( isInline( node ) && node.getHtml().match( /(\s|&nbsp;)$/g ) ) {
-							movedIntoInline = null;
-							break;
-						}
-
-						movedIntoInline = range.clone();
-						movedIntoInline.moveToPosition( node, CKEDITOR.POSITION_BEFORE_END );
-					}
-
-					node = node.getLast( isNotEmpty );
-				}
-
-				movedIntoInline && range.moveToRange( movedIntoInline );
-			}
-
-		}
-
-		//
-		// HELPERS ------------------------------------------------------------
-		//
-
-		function autoParagraphTag( editor ) {
-			return ( editor.activeEnterMode != CKEDITOR.ENTER_BR && editor.config.autoParagraph !== false ) ? editor.activeEnterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' : false;
-		}
-
-		function checkIfElement( node ) {
-			return node.type == CKEDITOR.NODE_ELEMENT;
-		}
-
-		function extractNodesData( dataWrapper, that ) {
-			var node, sibling, nodeName, allowed,
-				nodesData = [],
-				startContainer = that.range.startContainer,
-				path = that.range.startPath(),
-				allowedNames = DTD[ startContainer.getName() ],
-				nodeIndex = 0,
-				nodesList = dataWrapper.getChildren(),
-				nodesCount = nodesList.count(),
-				firstNotAllowed = -1,
-				lastNotAllowed = -1,
-				lineBreak = 0,
-				blockSibling;
-
-			// Selection start within a list.
-			var insideOfList = path.contains( DTD.$list );
-
-			for ( ; nodeIndex < nodesCount; ++nodeIndex ) {
-				node = nodesList.getItem( nodeIndex );
-
-				if ( checkIfElement( node ) ) {
-					nodeName = node.getName();
-
-					// Extract only the list items, when insertion happens
-					// inside of a list, reads as rearrange list items. (#7957)
-					if ( insideOfList && nodeName in CKEDITOR.dtd.$list ) {
-						nodesData = nodesData.concat( extractNodesData( node, that ) );
-						continue;
-					}
-
-					allowed = !!allowedNames[ nodeName ];
-
-					// Mark <brs data-cke-eol="1"> at the beginning and at the end.
-					if ( nodeName == 'br' && node.data( 'cke-eol' ) && ( !nodeIndex || nodeIndex == nodesCount - 1 ) ) {
-						sibling = nodeIndex ? nodesData[ nodeIndex - 1 ].node : nodesList.getItem( nodeIndex + 1 );
-
-						// Line break has to have sibling which is not an <br>.
-						lineBreak = sibling && ( !checkIfElement( sibling ) || !sibling.is( 'br' ) );
-						// Line break has block element as a sibling.
-						blockSibling = sibling && checkIfElement( sibling ) && DTD.$block[ sibling.getName() ];
-					}
-
-					if ( firstNotAllowed == -1 && !allowed )
-						firstNotAllowed = nodeIndex;
-					if ( !allowed )
-						lastNotAllowed = nodeIndex;
-
-					nodesData.push( {
-						isElement: 1,
-						isLineBreak: lineBreak,
-						isBlock: node.isBlockBoundary(),
-						hasBlockSibling: blockSibling,
-						node: node,
-						name: nodeName,
-						allowed: allowed
-					} );
-
-					lineBreak = 0;
-					blockSibling = 0;
-				} else
-					nodesData.push( { isElement: 0, node: node, allowed: 1 } );
-			}
-
-			// Mark first node that cannot be inserted directly into startContainer
-			// and last node for which startContainer has to be split.
-			if ( firstNotAllowed > -1 )
-				nodesData[ firstNotAllowed ].firstNotAllowed = 1;
-			if ( lastNotAllowed > -1 )
-				nodesData[ lastNotAllowed ].lastNotAllowed = 1;
-
-			return nodesData;
-		}
-
-		// TODO: Review content transformation rules on filtering element.
-		function filterElement( element, parentName, isFirst, isLast ) {
-			var nodes = filterElementInner( element, parentName ),
-				nodes2 = [],
-				nodesCount = nodes.length,
-				nodeIndex = 0,
-				node,
-				afterSpace = 0,
-				lastSpaceIndex = -1;
-
-			// Remove duplicated spaces and spaces at the:
-			// * beginnig if filtered element isFirst (isFirst that's going to be inserted)
-			// * end if filtered element isLast.
-			for ( ; nodeIndex < nodesCount; nodeIndex++ ) {
-				node = nodes[ nodeIndex ];
-
-				if ( node == ' ' ) {
-					// Don't push doubled space and if it's leading space for insertion.
-					if ( !afterSpace && !( isFirst && !nodeIndex ) ) {
-						nodes2.push( new CKEDITOR.dom.text( ' ' ) );
-						lastSpaceIndex = nodes2.length;
-					}
-					afterSpace = 1;
-				} else {
-					nodes2.push( node );
-					afterSpace = 0;
-				}
-			}
-
-			// Remove trailing space.
-			if ( isLast && lastSpaceIndex == nodes2.length )
-				nodes2.pop();
-
-			return nodes2;
-		}
-
-		function filterElementInner( element, parentName ) {
-			var nodes = [],
-				children = element.getChildren(),
-				childrenCount = children.count(),
-				child,
-				childIndex = 0,
-				allowedNames = DTD[ parentName ],
-				surroundBySpaces = !element.is( DTD.$inline ) || element.is( 'br' );
-
-			if ( surroundBySpaces )
-				nodes.push( ' ' );
-
-			for ( ; childIndex < childrenCount; childIndex++ ) {
-				child = children.getItem( childIndex );
-
-				if ( checkIfElement( child ) && !child.is( allowedNames ) )
-					nodes = nodes.concat( filterElementInner( child, parentName ) );
-				else
-					nodes.push( child );
-			}
-
-			if ( surroundBySpaces )
-				nodes.push( ' ' );
-
-			return nodes;
-		}
-
-		function getRangePrevious( range ) {
-			return checkIfElement( range.startContainer ) && range.startContainer.getChild( range.startOffset - 1 );
-		}
-
-		function isInline( node ) {
-			return node && checkIfElement( node ) && ( node.is( DTD.$removeEmpty ) || node.is( 'a' ) && !node.isBlockBoundary() );
-		}
-
-		var blockMergedTags = { p: 1, div: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, ul: 1, ol: 1, li: 1, pre: 1, dl: 1, blockquote: 1 };
-
-		// See rule 5. in TCs.
-		// Initial situation:
-		// <ul><li>AA^</li></ul><ul><li>BB</li></ul>
-		// We're looking for 2nd <ul>, comparing with 1st <ul> and merging.
-		// We're not merging if caret is between these elements.
-		function mergeAncestorElementsOfSelectionEnds( range, blockLimit, startPath, endPath ) {
-			var walkerRange = range.clone(),
-				walker, nextNode, previousNode;
-
-			walkerRange.setEndAt( blockLimit, CKEDITOR.POSITION_BEFORE_END );
-			walker = new CKEDITOR.dom.walker( walkerRange );
-
-			if ( ( nextNode = walker.next() )							// Find next source node
-				&& checkIfElement( nextNode )							// which is an element
-				&& blockMergedTags[ nextNode.getName() ]				// that can be merged.
-				&& ( previousNode = nextNode.getPrevious() )			// Take previous one
-				&& checkIfElement( previousNode )						// which also has to be an element.
-				&& !previousNode.getParent().equals( range.startContainer ) // Fail if caret is on the same level.
-																		// This means that caret is between these nodes.
-				&& startPath.contains( previousNode )					// Elements path of start of selection has
-				&& endPath.contains( nextNode )							// to contain prevNode and vice versa.
-				&& nextNode.isIdentical( previousNode ) )				// Check if elements are identical.
-			{
-				// Merge blocks and repeat.
-				nextNode.moveChildren( previousNode );
-				nextNode.remove();
-				mergeAncestorElementsOfSelectionEnds( range, blockLimit, startPath, endPath );
-			}
-		}
-
-		// If last node that will be inserted is a block (but not a <br>)
-		// and it will be inserted right before <br> remove this <br>.
-		// Do the same for the first element that will be inserted and preceding <br>.
-		function removeBrsAdjacentToPastedBlocks( nodesData, range ) {
-			var succeedingNode = range.endContainer.getChild( range.endOffset ),
-				precedingNode = range.endContainer.getChild( range.endOffset - 1 );
-
-			if ( succeedingNode )
-				remove( succeedingNode, nodesData[ nodesData.length - 1 ] );
-
-			if ( precedingNode && remove( precedingNode, nodesData[ 0 ] ) ) {
-				// If preceding <br> was removed - move range left.
-				range.setEnd( range.endContainer, range.endOffset - 1 );
-				range.collapse();
-			}
-
-			function remove( maybeBr, maybeBlockData ) {
-				if ( maybeBlockData.isBlock && maybeBlockData.isElement && !maybeBlockData.node.is( 'br' ) &&
-					checkIfElement( maybeBr ) && maybeBr.is( 'br' ) ) {
-					maybeBr.remove();
-					return 1;
-				}
-			}
-		}
-
-		// Return 1 if <br> should be skipped when inserting, 0 otherwise.
-		function splitOnLineBreak( range, blockLimit, nodeData ) {
-			var firstBlockAscendant, pos;
-
-			if ( nodeData.hasBlockSibling )
-				return 1;
-
-			firstBlockAscendant = range.startContainer.getAscendant( DTD.$block, 1 );
-			if ( !firstBlockAscendant || !firstBlockAscendant.is( { div: 1, p: 1 } ) )
-				return 0;
-
-			pos = firstBlockAscendant.getPosition( blockLimit );
-
-			if ( pos == CKEDITOR.POSITION_IDENTICAL || pos == CKEDITOR.POSITION_CONTAINS )
-				return 0;
-
-			var newContainer = range.splitElement( firstBlockAscendant );
-			range.moveToPosition( newContainer, CKEDITOR.POSITION_AFTER_START );
-
-			return 1;
-		}
-
-		var stripSingleBlockTags = { p: 1, div: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1 },
-			inlineButNotBr = CKEDITOR.tools.extend( {}, DTD.$inline );
-		delete inlineButNotBr.br;
-
-		// Rule 7.
-		function stripBlockTagIfSingleLine( dataWrapper ) {
-			var block, children;
-
-			if ( dataWrapper.getChildCount() == 1 &&					// Only one node bein inserted.
-				checkIfElement( block = dataWrapper.getFirst() ) &&		// And it's an element.
-				block.is( stripSingleBlockTags ) )						// That's <p> or <div> or header.
-			{
-				// Check children not containing block.
-				children = block.getElementsByTag( '*' );
-				for ( var i = 0, child, count = children.count(); i < count; i++ ) {
-					child = children.getItem( i );
-					if ( !child.is( inlineButNotBr ) )
-						return;
-				}
-
-				block.moveChildren( block.getParent( 1 ) );
-				block.remove();
-			}
-		}
-
-		function wrapDataWithInlineStyles( data, that ) {
-			var element = that.inlineStylesPeak,
-				doc = element.getDocument(),
-				wrapper = doc.createText( '{cke-peak}' ),
-				limit = that.inlineStylesRoot.getParent();
-
-			while ( !element.equals( limit ) ) {
-				wrapper = wrapper.appendTo( element.clone() );
-				element = element.getParent();
-			}
-
-			// Don't use String.replace because it fails in IE7 if special replacement
-			// characters ($$, $&, etc.) are in data (#10367).
-			return wrapper.getOuterHtml().split( '{cke-peak}' ).join( data );
-		}
-
-		return insert;
-	} )();
-
-	function beforeInsert( editable ) {
-		// TODO: For unknown reason we must call directly on the editable to put the focus immediately.
-		editable.editor.focus();
-
-		editable.editor.fire( 'saveSnapshot' );
-	}
-
-	function afterInsert( editable, noScroll ) {
-		var editor = editable.editor;
-
-		// Scroll using selection, not ranges, to affect native pastes.
-		!noScroll && editor.getSelection().scrollIntoView();
-
-		// Save snaps after the whole execution completed.
-		// This's a workaround for make DOM modification's happened after
-		// 'insertElement' to be included either, e.g. Form-based dialogs' 'commitContents'
-		// call.
-		setTimeout( function() {
-			editor.fire( 'saveSnapshot' );
-		}, 0 );
-	}
-
-	// 1. Fixes a range which is a result of deleteContents() and is placed in an intermediate element (see dtd.$intermediate),
-	// inside a table. A goal is to find a closest <td> or <th> element and when this fails, recreate the structure of the table.
-	// 2. Fixes empty cells by appending bogus <br>s or deleting empty text nodes in IE<=8 case.
-	var fixTableAfterContentsDeletion = ( function() {
-		// Creates an element walker which can only "go deeper". It won't
-		// move out from any element. Therefore it can be used to find <td>x</td> in cases like:
-		// <table><tbody><tr><td>x</td></tr></tbody>^<tfoot>...
-		function getFixTableSelectionWalker( testRange ) {
-			var walker = new CKEDITOR.dom.walker( testRange );
-			walker.guard = function( node, isMovingOut ) {
-				if ( isMovingOut )
-					return false;
-				if ( node.type == CKEDITOR.NODE_ELEMENT )
-					return node.is( CKEDITOR.dtd.$tableContent );
-			};
-			walker.evaluator = function( node ) {
-				return node.type == CKEDITOR.NODE_ELEMENT;
-			};
-
-			return walker;
-		}
-
-		function fixTableStructure( element, newElementName, appendToStart ) {
-			var temp = element.getDocument().createElement( newElementName );
-			element.append( temp, appendToStart );
-			return temp;
-		}
-
-		// Fix empty cells. This means:
-		// * add bogus <br> if browser needs it
-		// * remove empty text nodes on IE8, because it will crash (http://dev.ckeditor.com/ticket/11183#comment:8).
-		function fixEmptyCells( cells ) {
-			var i = cells.count(),
-				cell;
-
-			for ( i; i-- > 0; ) {
-				cell = cells.getItem( i );
-
-				if ( !CKEDITOR.tools.trim( cell.getHtml() ) ) {
-					cell.appendBogus();
-					if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 && cell.getChildCount() )
-						cell.getFirst().remove();
-				}
-			}
-		}
-
-		return function( range ) {
-			var container = range.startContainer,
-				table = container.getAscendant( 'table', 1 ),
-				testRange,
-				walker,
-				deeperSibling,
-				doc = range.document,
-				appendToStart = false;
-
-			fixEmptyCells( table.getElementsByTag( 'td' ) );
-			fixEmptyCells( table.getElementsByTag( 'th' ) );
-
-			// Look left.
-			testRange = range.clone();
-			testRange.setStart( container, 0 );
-			deeperSibling = getFixTableSelectionWalker( testRange ).lastBackward();
-
-			// If left is empty, look right.
-			if ( !deeperSibling ) {
-				testRange = range.clone();
-				testRange.setEndAt( container, CKEDITOR.POSITION_BEFORE_END );
-				deeperSibling = getFixTableSelectionWalker( testRange ).lastForward();
-				appendToStart = true;
-			}
-
-			// If there's no deeper nested element in both direction - container is empty - we'll use it then.
-			if ( !deeperSibling )
-				deeperSibling = container;
-
-			// Fix structure...
-
-			// We found a table what means that it's empty - remove it completely.
-			if ( deeperSibling.is( 'table' ) ) {
-				range.setStartAt( deeperSibling, CKEDITOR.POSITION_BEFORE_START );
-				range.collapse( true );
-				deeperSibling.remove();
-				return;
-			}
-
-			// Found an empty txxx element - append tr.
-			if ( deeperSibling.is( { tbody: 1, thead: 1, tfoot: 1 } ) )
-				deeperSibling = fixTableStructure( deeperSibling, 'tr', appendToStart );
-
-			// Found an empty tr element - append td/th.
-			if ( deeperSibling.is( 'tr' ) )
-				deeperSibling = fixTableStructure( deeperSibling, deeperSibling.getParent().is( 'thead' ) ? 'th' : 'td', appendToStart );
-
-			// To avoid setting selection after bogus, remove it from the current cell.
-			// We can safely do that, because we'll insert element into that cell.
-			var bogus = deeperSibling.getBogus();
-			if ( bogus )
-				bogus.remove();
-
-			range.moveToPosition( deeperSibling, appendToStart ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_BEFORE_END );
-		};
-	} )();
-
-} )();
-
-/**
- * Whether the editor must output an empty value (`''`) if it's contents is made
- * by an empty paragraph only.
- *
- *		config.ignoreEmptyParagraph = false;
- *
- * @cfg {Boolean} [ignoreEmptyParagraph=true]
- * @member CKEDITOR.config
- */
-
-/**
- * @event focus
- * @todo
- */
-
- /**
- * @event blur
- * @todo
- */

+ 0 - 1775
htdocs/includes/ckeditor/ckeditor/_source/core/editor.js

@@ -1,1775 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.editor} class that represents an
- *		editor instance.
- */
-
-( function() {
-	// Override the basic constructor defined at editor_basic.js.
-	Editor.prototype = CKEDITOR.editor.prototype;
-	CKEDITOR.editor = Editor;
-
-	/**
-	 * Represents an editor instance. This constructor should be rarely
-	 * used in favor of the {@link CKEDITOR} editor creation functions.
-	 *
-	 * @class CKEDITOR.editor
-	 * @mixins CKEDITOR.event
-	 * @constructor Creates an editor class instance.
-	 * @param {Object} [instanceConfig] Configuration values for this specific instance.
-	 * @param {CKEDITOR.dom.element} [element] The DOM element upon which this editor
-	 * will be created.
-	 * @param {Number} [mode] The element creation mode to be used by this editor.
-	 */
-	function Editor( instanceConfig, element, mode ) {
-		// Call the CKEDITOR.event constructor to initialize this instance.
-		CKEDITOR.event.call( this );
-
-		// Make a clone of the config object, to avoid having it touched by our code. (#9636)
-		instanceConfig = instanceConfig && CKEDITOR.tools.clone( instanceConfig );
-
-		// if editor is created off one page element.
-		if ( element !== undefined ) {
-			// Asserting element and mode not null.
-			if ( !( element instanceof CKEDITOR.dom.element ) )
-				throw new Error( 'Expect element of type CKEDITOR.dom.element.' );
-			else if ( !mode )
-				throw new Error( 'One of the element modes must be specified.' );
-
-			if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && mode == CKEDITOR.ELEMENT_MODE_INLINE )
-				throw new Error( 'Inline element mode is not supported on IE quirks.' );
-
-			if ( !isSupportedElement( element, mode ) )
-				throw new Error( 'The specified element mode is not supported on element: "' + element.getName() + '".' );
-
-			/**
-			 * The original host page element upon which the editor is created, it's only
-			 * supposed to be provided by the concrete editor creator and is not subjected to
-			 * be modified.
-			 *
-			 * @readonly
-			 * @property {CKEDITOR.dom.element}
-			 */
-			this.element = element;
-
-			/**
-			 * This property indicate the way how this instance is associated with the {@link #element}.
-			 *
-			 * @readonly
-			 * @property {Number}
-			 * @see CKEDITOR#ELEMENT_MODE_INLINE
-			 * @see CKEDITOR#ELEMENT_MODE_REPLACE
-			 */
-			this.elementMode = mode;
-
-			this.name = ( this.elementMode != CKEDITOR.ELEMENT_MODE_APPENDTO ) && ( element.getId() || element.getNameAtt() );
-		}
-		else
-			this.elementMode = CKEDITOR.ELEMENT_MODE_NONE;
-
-		// Declare the private namespace.
-		this._ = {};
-
-		this.commands = {};
-
-		/**
-		 * Contains all UI templates created for this editor instance.
-		 *
-		 * @readonly
-		 * @property {Object}
-		 */
-		this.templates = {};
-
-		/**
-		 * A unique identifier of this editor instance.
-		 *
-		 * **Note:** It will be originated from the ID or name
-		 * attribute of the {@link #element}, otherwise a name pattern of
-		 * `'editor{n}'` will be used.
-		 *
-		 * @readonly
-		 * @property {String}
-		 */
-		this.name = this.name || genEditorName();
-
-		/**
-		 * A unique random string assigned to each editor instance in the page.
-		 *
-		 * @readonly
-		 * @property {String}
-		 */
-		this.id = CKEDITOR.tools.getNextId();
-
-		/**
-		 * Indicates editor initialization status. The following statuses are available:
-		 *
-		 *	* **unloaded**: the initial state - editor's instance has been initialized,
-		 *	but its components (config, plugins, language files) are not loaded yet.
-		 *	* **loaded**: editor's components have been loaded - see {@link CKEDITOR.editor#loaded} event.
-		 *	* **ready**: editor is fully initialized and ready - see {@link CKEDITOR.editor#instanceReady} event.
-		 *	* **destroyed**: the editor has been destroyed - see {@link CKEDITOR.editor#method-destroy} method.
-		 *
-		 * @since 4.1
-		 * @readonly
-		 * @property {String}
-		 */
-		this.status = 'unloaded';
-
-		/**
-		 * The configurations for this editor instance. It inherits all
-		 * settings defined in {@link CKEDITOR.config}, combined with settings
-		 * loaded from custom configuration files and those defined inline in
-		 * the page when creating the editor.
-		 *
-		 *		var editor = CKEDITOR.instances.editor1;
-		 *		alert( editor.config.skin ); // e.g. 'moono'
-		 *
-		 * @readonly
-		 * @property {CKEDITOR.config}
-		 */
-		this.config = CKEDITOR.tools.prototypedCopy( CKEDITOR.config );
-
-		/**
-		 * Namespace containing UI features related to this editor instance.
-		 *
-		 * @readonly
-		 * @property {CKEDITOR.ui}
-		 */
-		this.ui = new CKEDITOR.ui( this );
-
-		/**
-		 * Controls the focus state of this editor instance. This property
-		 * is rarely used for normal API operations. It is mainly
-		 * destinated to developer adding UI elements to the editor interface.
-		 *
-		 * @readonly
-		 * @property {CKEDITOR.focusManager}
-		 */
-		this.focusManager = new CKEDITOR.focusManager( this );
-
-		/**
-		 * Controls keystrokes typing in this editor instance.
-		 *
-		 * @readonly
-		 * @property {CKEDITOR.keystrokeHandler}
-		 */
-		this.keystrokeHandler = new CKEDITOR.keystrokeHandler( this );
-
-		// Make the editor update its command states on mode change.
-		this.on( 'readOnly', updateCommands );
-		this.on( 'selectionChange', function( evt ) {
-			updateCommandsContext( this, evt.data.path );
-		} );
-		this.on( 'activeFilterChange', function( evt ) {
-			updateCommandsContext( this, this.elementPath(), true );
-		} );
-		this.on( 'mode', updateCommands );
-
-		// Handle startup focus.
-		this.on( 'instanceReady', function( event ) {
-			this.config.startupFocus && this.focus();
-		} );
-
-		CKEDITOR.fire( 'instanceCreated', null, this );
-
-		// Add this new editor to the CKEDITOR.instances collections.
-		CKEDITOR.add( this );
-
-		// Return the editor instance immediately to enable early stage event registrations.
-		CKEDITOR.tools.setTimeout( function() {
-			initConfig( this, instanceConfig );
-		}, 0, this );
-	}
-
-	var nameCounter = 0;
-
-	function genEditorName() {
-		do {
-			var name = 'editor' + ( ++nameCounter );
-		}
-		while ( CKEDITOR.instances[ name ] )
-
-		return name;
-	}
-
-	// Asserting element DTD depending on mode.
-	function isSupportedElement( element, mode ) {
-		if ( mode == CKEDITOR.ELEMENT_MODE_INLINE )
-			return element.is( CKEDITOR.dtd.$editable ) || element.is( 'textarea' );
-		else if ( mode == CKEDITOR.ELEMENT_MODE_REPLACE )
-			return !element.is( CKEDITOR.dtd.$nonBodyContent );
-		return 1;
-	}
-
-	function updateCommands() {
-		var commands = this.commands,
-			name;
-
-		for ( name in commands )
-			updateCommand( this, commands[ name ] );
-	}
-
-	function updateCommand( editor, cmd ) {
-		cmd[ cmd.startDisabled ? 'disable' : editor.readOnly && !cmd.readOnly ? 'disable' : cmd.modes[ editor.mode ] ? 'enable' : 'disable' ]();
-	}
-
-	function updateCommandsContext( editor, path, forceRefresh ) {
-		// Commands cannot be refreshed without a path. In edge cases
-		// it may happen that there's no selection when this function is executed.
-		// For example when active filter is changed in #10877.
-		if ( !path )
-			return;
-
-		var command,
-			name,
-			commands = editor.commands;
-
-		for ( name in commands ) {
-			command = commands[ name ];
-
-			if ( forceRefresh || command.contextSensitive )
-				command.refresh( editor, path );
-		}
-	}
-
-	// ##### START: Config Privates
-
-	// These function loads custom configuration files and cache the
-	// CKEDITOR.editorConfig functions defined on them, so there is no need to
-	// download them more than once for several instances.
-	var loadConfigLoaded = {};
-
-	function loadConfig( editor ) {
-		var customConfig = editor.config.customConfig;
-
-		// Check if there is a custom config to load.
-		if ( !customConfig )
-			return false;
-
-		customConfig = CKEDITOR.getUrl( customConfig );
-
-		var loadedConfig = loadConfigLoaded[ customConfig ] || ( loadConfigLoaded[ customConfig ] = {} );
-
-		// If the custom config has already been downloaded, reuse it.
-		if ( loadedConfig.fn ) {
-			// Call the cached CKEDITOR.editorConfig defined in the custom
-			// config file for the editor instance depending on it.
-			loadedConfig.fn.call( editor, editor.config );
-
-			// If there is no other customConfig in the chain, fire the
-			// "configLoaded" event.
-			if ( CKEDITOR.getUrl( editor.config.customConfig ) == customConfig || !loadConfig( editor ) )
-				editor.fireOnce( 'customConfigLoaded' );
-		} else {
-			// Load the custom configuration file.
-			// To resolve customConfig race conflicts, use scriptLoader#queue
-			// instead of scriptLoader#load (#6504).
-			CKEDITOR.scriptLoader.queue( customConfig, function() {
-				// If the CKEDITOR.editorConfig function has been properly
-				// defined in the custom configuration file, cache it.
-				if ( CKEDITOR.editorConfig )
-					loadedConfig.fn = CKEDITOR.editorConfig;
-				else
-					loadedConfig.fn = function() {};
-
-				// Call the load config again. This time the custom
-				// config is already cached and so it will get loaded.
-				loadConfig( editor );
-			} );
-		}
-
-		return true;
-	}
-
-	function initConfig( editor, instanceConfig ) {
-		// Setup the lister for the "customConfigLoaded" event.
-		editor.on( 'customConfigLoaded', function() {
-			if ( instanceConfig ) {
-				// Register the events that may have been set at the instance
-				// configuration object.
-				if ( instanceConfig.on ) {
-					for ( var eventName in instanceConfig.on ) {
-						editor.on( eventName, instanceConfig.on[ eventName ] );
-					}
-				}
-
-				// Overwrite the settings from the in-page config.
-				CKEDITOR.tools.extend( editor.config, instanceConfig, true );
-
-				delete editor.config.on;
-			}
-
-			onConfigLoaded( editor );
-		} );
-
-		// The instance config may override the customConfig setting to avoid
-		// loading the default ~/config.js file.
-		if ( instanceConfig && instanceConfig.customConfig != undefined )
-			editor.config.customConfig = instanceConfig.customConfig;
-
-		// Load configs from the custom configuration files.
-		if ( !loadConfig( editor ) )
-			editor.fireOnce( 'customConfigLoaded' );
-	}
-
-	// ##### END: Config Privates
-
-	// Set config related properties.
-	function onConfigLoaded( editor ) {
-		var config = editor.config;
-
-		/**
-		 * Indicates the read-only state of this editor. This is a read-only property.
-		 *
-		 * @since 3.6
-		 * @readonly
-		 * @property {Boolean}
-		 * @see CKEDITOR.editor#setReadOnly
-		 */
-		editor.readOnly = !!(
-			config.readOnly || (
-				editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ?
-						editor.element.is( 'textarea' ) ?
-								editor.element.hasAttribute( 'disabled' )
-							:
-								editor.element.isReadOnly()
-					:
-						editor.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ?
-								editor.element.hasAttribute( 'disabled' )
-							:
-								false
-			)
-		);
-
-		/**
-		 * Indicates that the editor is running in an environment where
-		 * no block elements are accepted inside the content.
-		 *
-		 * This can be for example inline editor based on `<h1>` element.
-		 *
-		 * @readonly
-		 * @property {Boolean}
-		 */
-		editor.blockless = editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ?
-			!( editor.element.is( 'textarea' ) || CKEDITOR.dtd[ editor.element.getName() ][ 'p' ] ) :
-			false;
-
-		/**
-		 * The [tabbing navigation](http://en.wikipedia.org/wiki/Tabbing_navigation) order determined for this editor instance.
-		 * This can be set by the <code>{@link CKEDITOR.config#tabIndex}</code>
-		 * setting or taken from the `tabindex` attribute of the
-		 * {@link #element} associated with the editor.
-		 *
-		 *		alert( editor.tabIndex ); // e.g. 0
-		 *
-		 * @readonly
-		 * @property {Number} [=0]
-		 */
-		editor.tabIndex = config.tabIndex || editor.element && editor.element.getAttribute( 'tabindex' ) || 0;
-
-		editor.activeEnterMode = editor.enterMode = validateEnterMode( editor, config.enterMode );
-		editor.activeShiftEnterMode = editor.shiftEnterMode = validateEnterMode( editor, config.shiftEnterMode );
-
-		// Set CKEDITOR.skinName. Note that it is not possible to have
-		// different skins on the same page, so the last one to set it "wins".
-		if ( config.skin )
-			CKEDITOR.skinName = config.skin;
-
-		// Fire the "configLoaded" event.
-		editor.fireOnce( 'configLoaded' );
-
-		initComponents( editor );
-	}
-
-	// Various other core components that read editor configuration.
-	function initComponents( editor ) {
-		// Documented in dataprocessor.js.
-		editor.dataProcessor = new CKEDITOR.htmlDataProcessor( editor );
-
-		// Set activeFilter directly to avoid firing event.
-		editor.filter = editor.activeFilter = new CKEDITOR.filter( editor );
-
-		loadSkin( editor );
-	}
-
-	function loadSkin( editor ) {
-		CKEDITOR.skin.loadPart( 'editor', function() {
-			loadLang( editor );
-		} );
-	}
-
-	function loadLang( editor ) {
-		CKEDITOR.lang.load( editor.config.language, editor.config.defaultLanguage, function( languageCode, lang ) {
-			var configTitle = editor.config.title;
-
-			/**
-			 * The code for the language resources that have been loaded
-			 * for the user interface elements of this editor instance.
-			 *
-			 *		alert( editor.langCode ); // e.g. 'en'
-			 *
-			 * @readonly
-			 * @property {String}
-			 */
-			editor.langCode = languageCode;
-
-			/**
-			 * An object that contains all language strings used by the editor interface.
-			 *
-			 *		alert( editor.lang.basicstyles.bold ); // e.g. 'Negrito' (if the language is set to Portuguese)
-			 *
-			 * @readonly
-			 * @property {Object} lang
-			 */
-			// As we'll be adding plugin specific entries that could come
-			// from different language code files, we need a copy of lang,
-			// not a direct reference to it.
-			editor.lang = CKEDITOR.tools.prototypedCopy( lang );
-
-			/**
-			 * Indicates the human-readable title of this editor. Although this is a read-only property,
-			 * it can be initialized with {@link CKEDITOR.config#title}.
-			 *
-			 * **Note:** Please do not confuse this property with {@link CKEDITOR.editor#name editor.name}
-			 * which identifies the instance in the {@link CKEDITOR#instances} literal.
-			 *
-			 * @since 4.2
-			 * @readonly
-			 * @property {String/Boolean}
-			 */
-			editor.title = typeof configTitle == 'string' || configTitle === false ? configTitle : [ editor.lang.editor, editor.name ].join( ', ' );
-
-			// We're not able to support RTL in Firefox 2 at this time.
-			if ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 && editor.lang.dir == 'rtl' )
-				editor.lang.dir = 'ltr';
-
-			if ( !editor.config.contentsLangDirection ) {
-				// Fallback to either the editable element direction or editor UI direction depending on creators.
-				editor.config.contentsLangDirection = editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ? editor.element.getDirection( 1 ) : editor.lang.dir;
-			}
-
-			editor.fire( 'langLoaded' );
-
-			preloadStylesSet( editor );
-		} );
-	}
-
-	// Preloads styles set file (config.stylesSet).
-	// If stylesSet was defined directly (by an array)
-	// this function will call loadPlugins fully synchronously.
-	// If stylesSet is a string (path) loadPlugins will
-	// be called asynchronously.
-	// In both cases - styles will be preload before plugins initialization.
-	function preloadStylesSet( editor ) {
-		editor.getStylesSet( function( styles ) {
-			// Wait for editor#loaded, so plugins could add their listeners.
-			// But listen with high priority to fire editor#stylesSet before editor#uiReady and editor#setData.
-			editor.once( 'loaded', function() {
-				// Note: we can't use fireOnce because this event may canceled and fired again.
-				editor.fire( 'stylesSet', { styles: styles } );
-			}, null, null, 1 );
-
-			loadPlugins( editor );
-		} );
-	}
-
-	function loadPlugins( editor ) {
-		var config = editor.config,
-			plugins = config.plugins,
-			extraPlugins = config.extraPlugins,
-			removePlugins = config.removePlugins;
-
-		if ( extraPlugins ) {
-			// Remove them first to avoid duplications.
-			var extraRegex = new RegExp( '(?:^|,)(?:' + extraPlugins.replace( /\s*,\s*/g, '|' ) + ')(?=,|$)', 'g' );
-			plugins = plugins.replace( extraRegex, '' );
-
-			plugins += ',' + extraPlugins;
-		}
-
-		if ( removePlugins ) {
-			var removeRegex = new RegExp( '(?:^|,)(?:' + removePlugins.replace( /\s*,\s*/g, '|' ) + ')(?=,|$)', 'g' );
-			plugins = plugins.replace( removeRegex, '' );
-		}
-
-		// Load the Adobe AIR plugin conditionally.
-		CKEDITOR.env.air && ( plugins += ',adobeair' );
-
-		// Load all plugins defined in the "plugins" setting.
-		CKEDITOR.plugins.load( plugins.split( ',' ), function( plugins ) {
-			// The list of plugins.
-			var pluginsArray = [];
-
-			// The language code to get loaded for each plugin. Null
-			// entries will be appended for plugins with no language files.
-			var languageCodes = [];
-
-			// The list of URLs to language files.
-			var languageFiles = [];
-
-			/**
-			 * An object that contains references to all plugins used by this
-			 * editor instance.
-			 *
-			 *		alert( editor.plugins.dialog.path ); // e.g. 'http://example.com/ckeditor/plugins/dialog/'
-			 *
-			 *		// Check if a plugin is available.
-			 *		if ( editor.plugins.image ) {
-			 *			...
-			 *		}
-			 *
-			 * @readonly
-			 * @property {Object}
-			 */
-			editor.plugins = plugins;
-
-			// Loop through all plugins, to build the list of language
-			// files to get loaded.
-			//
-			// Check also whether any of loaded plugins doesn't require plugins
-			// defined in config.removePlugins. Throw non-blocking error if this happens.
-			for ( var pluginName in plugins ) {
-				var plugin = plugins[ pluginName ],
-					pluginLangs = plugin.lang,
-					lang = null,
-					requires = plugin.requires,
-					match, name;
-
-				// Transform it into a string, if it's not one.
-				if ( CKEDITOR.tools.isArray( requires ) )
-					requires = requires.join( ',' );
-
-				if ( requires && ( match = requires.match( removeRegex ) ) ) {
-					while ( ( name = match.pop() ) ) {
-						CKEDITOR.tools.setTimeout( function( name, pluginName ) {
-							throw new Error( 'Plugin "' + name.replace( ',', '' ) + '" cannot be removed from the plugins list, because it\'s required by "' + pluginName + '" plugin.' );
-						}, 0, null, [ name, pluginName ] );
-					}
-				}
-
-				// If the plugin has "lang".
-				if ( pluginLangs && !editor.lang[ pluginName ] ) {
-					// Trasnform the plugin langs into an array, if it's not one.
-					if ( pluginLangs.split )
-						pluginLangs = pluginLangs.split( ',' );
-
-					// Resolve the plugin language. If the current language
-					// is not available, get English or the first one.
-					if ( CKEDITOR.tools.indexOf( pluginLangs, editor.langCode ) >= 0 )
-						lang = editor.langCode;
-					else {
-						// The language code may have the locale information (zh-cn).
-						// Fall back to locale-less in that case (zh).
-						var langPart = editor.langCode.replace( /-.*/, '' );
-						if ( langPart != editor.langCode && CKEDITOR.tools.indexOf( pluginLangs, langPart ) >= 0 )
-							lang = langPart;
-						// Try the only "generic" option we have: English.
-						else if ( CKEDITOR.tools.indexOf( pluginLangs, 'en' ) >= 0 )
-							lang = 'en';
-						else
-							lang = pluginLangs[ 0 ];
-					}
-
-					if ( !plugin.langEntries || !plugin.langEntries[ lang ] ) {
-						// Put the language file URL into the list of files to
-						// get downloaded.
-						languageFiles.push( CKEDITOR.getUrl( plugin.path + 'lang/' + lang + '.js' ) );
-					} else {
-						editor.lang[ pluginName ] = plugin.langEntries[ lang ];
-						lang = null;
-					}
-				}
-
-				// Save the language code, so we know later which
-				// language has been resolved to this plugin.
-				languageCodes.push( lang );
-
-				pluginsArray.push( plugin );
-			}
-
-			// Load all plugin specific language files in a row.
-			CKEDITOR.scriptLoader.load( languageFiles, function() {
-				// Initialize all plugins that have the "beforeInit" and "init" methods defined.
-				var methods = [ 'beforeInit', 'init', 'afterInit' ];
-				for ( var m = 0; m < methods.length; m++ ) {
-					for ( var i = 0; i < pluginsArray.length; i++ ) {
-						var plugin = pluginsArray[ i ];
-
-						// Uses the first loop to update the language entries also.
-						if ( m === 0 && languageCodes[ i ] && plugin.lang && plugin.langEntries )
-							editor.lang[ plugin.name ] = plugin.langEntries[ languageCodes[ i ] ];
-
-						// Call the plugin method (beforeInit and init).
-						if ( plugin[ methods[ m ] ] )
-							plugin[ methods[ m ] ]( editor );
-					}
-				}
-
-				editor.fireOnce( 'pluginsLoaded' );
-
-				// Setup the configured keystrokes.
-				config.keystrokes && editor.setKeystroke( editor.config.keystrokes );
-
-				// Setup the configured blocked keystrokes.
-				for ( i = 0; i < editor.config.blockedKeystrokes.length; i++ )
-					editor.keystrokeHandler.blockedKeystrokes[ editor.config.blockedKeystrokes[ i ] ] = 1;
-
-				editor.status = 'loaded';
-				editor.fireOnce( 'loaded' );
-				CKEDITOR.fire( 'instanceLoaded', null, editor );
-			} );
-		} );
-	}
-
-	// Send to data output back to editor's associated element.
-	function updateEditorElement() {
-		var element = this.element;
-
-		// Some editor creation mode will not have the
-		// associated element.
-		if ( element && this.elementMode != CKEDITOR.ELEMENT_MODE_APPENDTO ) {
-			var data = this.getData();
-
-			if ( this.config.htmlEncodeOutput )
-				data = CKEDITOR.tools.htmlEncode( data );
-
-			if ( element.is( 'textarea' ) )
-				element.setValue( data );
-			else
-				element.setHtml( data );
-
-			return true;
-		}
-		return false;
-	}
-
-	// Always returns ENTER_BR in case of blockless editor.
-	function validateEnterMode( editor, enterMode ) {
-		return editor.blockless ? CKEDITOR.ENTER_BR : enterMode;
-	}
-
-	CKEDITOR.tools.extend( CKEDITOR.editor.prototype, {
-		/**
-		 * Adds a command definition to the editor instance. Commands added with
-		 * this function can be executed later with the <code>{@link #execCommand}</code> method.
-		 *
-		 * 		editorInstance.addCommand( 'sample', {
-		 * 			exec: function( editor ) {
-		 * 				alert( 'Executing a command for the editor name "' + editor.name + '"!' );
-		 * 			}
-		 * 		} );
-		 *
-		 * @param {String} commandName The indentifier name of the command.
-		 * @param {CKEDITOR.commandDefinition} commandDefinition The command definition.
-		 */
-		addCommand: function( commandName, commandDefinition ) {
-			commandDefinition.name = commandName.toLowerCase();
-			var cmd = new CKEDITOR.command( this, commandDefinition );
-
-			// Update command when mode is set.
-			// This guarantees that commands added before first editor#mode
-			// aren't immediately updated, but waits for editor#mode and that
-			// commands added later are immediately refreshed, even when added
-			// before instanceReady. #10103, #10249
-			if ( this.mode )
-				updateCommand( this, cmd );
-
-			return this.commands[ commandName ] = cmd;
-		},
-
-		/**
-		 * Attaches the editor to a form to call {@link #updateElement} before form submission.
-		 * This method is called by both creators ({@link CKEDITOR#replace replace} and
-		 * {@link CKEDITOR#inline inline}), so there is no reason to call it manually.
-		 *
-		 * @private
-		 */
-		_attachToForm: function() {
-			var editor = this,
-				element = editor.element,
-				form = new CKEDITOR.dom.element( element.$.form );
-
-			// If are replacing a textarea, we must
-			if ( element.is( 'textarea' ) ) {
-				if ( form ) {
-					function onSubmit( evt ) {
-						editor.updateElement();
-
-						// #8031 If textarea had required attribute and editor is empty fire 'required' event and if
-						// it was cancelled, prevent submitting the form.
-						if ( editor._.required && !element.getValue() && editor.fire( 'required' ) === false ) {
-							// When user press save button event (evt) is undefined (see save plugin).
-							// This method works because it throws error so originalSubmit won't be called.
-							// Also this error won't be shown because it will be caught in save plugin.
-							evt.data.preventDefault();
-						}
-					}
-					form.on( 'submit', onSubmit );
-
-					function isFunction( f ) {
-						// For IE8 typeof fun == object so we cannot use it.
-						return !!( f && f.call && f.apply );
-					}
-
-					// Check if there is no element/elements input with name == "submit".
-					// If they exists they will overwrite form submit function (form.$.submit).
-					// If form.$.submit is overwritten we can not do anything with it.
-					if ( isFunction( form.$.submit ) ) {
-						// Setup the submit function because it doesn't fire the
-						// "submit" event.
-						form.$.submit = CKEDITOR.tools.override( form.$.submit, function( originalSubmit ) {
-							return function() {
-								onSubmit();
-
-								// For IE, the DOM submit function is not a
-								// function, so we need third check.
-								if ( originalSubmit.apply )
-									originalSubmit.apply( this );
-								else
-									originalSubmit();
-							};
-						} );
-					}
-
-					// Remove 'submit' events registered on form element before destroying.(#3988)
-					editor.on( 'destroy', function() {
-						form.removeListener( 'submit', onSubmit );
-					} );
-				}
-			}
-		},
-
-		/**
-		 * Destroys the editor instance, releasing all resources used by it.
-		 * If the editor replaced an element, the element will be recovered.
-		 *
-		 *		alert( CKEDITOR.instances.editor1 ); // e.g. object
-		 *		CKEDITOR.instances.editor1.destroy();
-		 *		alert( CKEDITOR.instances.editor1 ); // undefined
-		 *
-		 * @param {Boolean} [noUpdate] If the instance is replacing a DOM
-		 * element, this parameter indicates whether or not to update the
-		 * element with the instance contents.
-		 */
-		destroy: function( noUpdate ) {
-			this.fire( 'beforeDestroy' );
-
-			!noUpdate && updateEditorElement.call( this );
-
-			this.editable( null );
-
-			this.status = 'destroyed';
-
-			this.fire( 'destroy' );
-
-			// Plug off all listeners to prevent any further events firing.
-			this.removeAllListeners();
-
-			CKEDITOR.remove( this );
-			CKEDITOR.fire( 'instanceDestroyed', null, this );
-		},
-
-		/**
-		 * Returns an {@link CKEDITOR.dom.elementPath element path} for the selection in the editor.
-		 *
-		 * @param {CKEDITOR.dom.node} [startNode] From which the path should start,
-		 * if not specified default to editor selection's
-		 * start element yield by {@link CKEDITOR.dom.selection#getStartElement}.
-		 * @returns {CKEDITOR.dom.elementPath}
-		 */
-		elementPath: function( startNode ) {
-			if ( !startNode ) {
-				var sel = this.getSelection();
-				if ( !sel )
-					return null;
-
-				startNode = sel.getStartElement();
-			}
-
-			return startNode ? new CKEDITOR.dom.elementPath( startNode, this.editable() ) : null;
-		},
-
-		/**
-		 * Shortcut to create a {@link CKEDITOR.dom.range} instance from the editable element.
-		 *
-		 * @returns {CKEDITOR.dom.range} The dom range created if the editable has presented.
-		 * @see CKEDITOR.dom.range
-		 */
-		createRange: function() {
-			var editable = this.editable();
-			return editable ? new CKEDITOR.dom.range( editable ) : null;
-		},
-
-		/**
-		 * Executes a command associated with the editor.
-		 *
-		 *		editorInstance.execCommand( 'bold' );
-		 *
-		 * @param {String} commandName The indentifier name of the command.
-		 * @param {Object} [data] Data to be passed to the command.
-		 * @returns {Boolean} `true` if the command was executed
-		 * successfully, otherwise `false`.
-		 * @see CKEDITOR.editor#addCommand
-		 */
-		execCommand: function( commandName, data ) {
-			var command = this.getCommand( commandName );
-
-			var eventData = {
-				name: commandName,
-				commandData: data,
-				command: command
-			};
-
-			if ( command && command.state != CKEDITOR.TRISTATE_DISABLED ) {
-				if ( this.fire( 'beforeCommandExec', eventData ) !== false ) {
-					eventData.returnValue = command.exec( eventData.commandData );
-
-					// Fire the 'afterCommandExec' immediately if command is synchronous.
-					if ( !command.async && this.fire( 'afterCommandExec', eventData ) !== false )
-						return eventData.returnValue;
-				}
-			}
-
-			// throw 'Unknown command name "' + commandName + '"';
-			return false;
-		},
-
-		/**
-		 * Gets one of the registered commands. Note that after registering a
-		 * command definition with {@link #addCommand}, it is
-		 * transformed internally into an instance of
-		 * {@link CKEDITOR.command}, which will then be returned by this function.
-		 *
-		 * @param {String} commandName The name of the command to be returned.
-		 * This is the same name that is used to register the command with `addCommand`.
-		 * @returns {CKEDITOR.command} The command object identified by the provided name.
-		 */
-		getCommand: function( commandName ) {
-			return this.commands[ commandName ];
-		},
-
-		/**
-		 * Gets the editor data. The data will be in raw format. It is the same
-		 * data that is posted by the editor.
-		 *
-		 *		if ( CKEDITOR.instances.editor1.getData() == '' )
-		 *			alert( 'There is no data available' );
-		 *
-		 * @returns {String} The editor data.
-		 */
-		getData: function( noEvents ) {
-			!noEvents && this.fire( 'beforeGetData' );
-
-			var eventData = this._.data;
-
-			if ( typeof eventData != 'string' ) {
-				var element = this.element;
-				if ( element && this.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE )
-					eventData = element.is( 'textarea' ) ? element.getValue() : element.getHtml();
-				else
-					eventData = '';
-			}
-
-			eventData = { dataValue: eventData };
-
-			// Fire "getData" so data manipulation may happen.
-			!noEvents && this.fire( 'getData', eventData );
-
-			return eventData.dataValue;
-		},
-
-		/**
-		 * Gets the "raw data" currently available in the editor. This is a
-		 * fast method which returns the data as is, without processing, so it is
-		 * not recommended to use it on resulting pages. Instead it can be used
-		 * combined with the {@link #method-loadSnapshot} method in order
-		 * to be able to automatically save the editor data from time to time
-		 * while the user is using the editor, to avoid data loss, without risking
-		 * performance issues.
-		 *
-		 *		alert( editor.getSnapshot() );
-		 *
-		 * @see CKEDITOR.editor#getData
-		 */
-		getSnapshot: function() {
-			var data = this.fire( 'getSnapshot' );
-
-			if ( typeof data != 'string' ) {
-				var element = this.element;
-				if ( element && this.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE )
-					data = element.is( 'textarea' ) ? element.getValue() : element.getHtml();
-			}
-
-			return data;
-		},
-
-		/**
-		 * Loads "raw data" into the editor. The data is loaded with processing
-		 * straight to the editing area. It should not be used as a way to load
-		 * any kind of data, but instead in combination with
-		 * {@link #method-getSnapshot} produced data.
-		 *
-		 *		var data = editor.getSnapshot();
-		 *		editor.loadSnapshot( data );
-		 *
-		 * @see CKEDITOR.editor#setData
-		 */
-		loadSnapshot: function( snapshot ) {
-			this.fire( 'loadSnapshot', snapshot );
-		},
-
-		/**
-		 * Sets the editor data. The data must be provided in the raw format (HTML).
-		 *
-		 * Note that this method is asynchronous. The `callback` parameter must
-		 * be used if interaction with the editor is needed after setting the data.
-		 *
-		 *		CKEDITOR.instances.editor1.setData( '<p>This is the editor data.</p>' );
-		 *
-		 *		CKEDITOR.instances.editor1.setData( '<p>Some other editor data.</p>', function() {
-		 *			this.checkDirty(); // true
-		 *		});
-		 *
-		 * @param {String} data HTML code to replace the curent content in the editor.
-		 * @param {Function} callback Function to be called after the `setData` is completed.
-		 * @param {Boolean} internal Whether to suppress any event firing when copying data internally inside the editor.
-		 */
-		setData: function( data, callback, internal ) {
-			if ( callback ) {
-				this.on( 'dataReady', function( evt ) {
-					evt.removeListener();
-					callback.call( evt.editor );
-				} );
-			}
-
-			// Fire "setData" so data manipulation may happen.
-			var eventData = { dataValue: data };
-			!internal && this.fire( 'setData', eventData );
-
-			this._.data = eventData.dataValue;
-
-			!internal && this.fire( 'afterSetData', eventData );
-		},
-
-		/**
-		 * Puts or restores the editor into read-only state. When in read-only,
-		 * the user is not able to change the editor contents, but can still use
-		 * some editor features. This function sets the {@link #property-readOnly}
-		 * property of the editor, firing the {@link #event-readOnly} event.
-		 *
-		 * **Note:** the current editing area will be reloaded.
-		 *
-		 * @since 3.6
-		 * @param {Boolean} [isReadOnly] Indicates that the editor must go
-		 * read-only (`true`, default) or be restored and made editable (`false`).
-		 */
-		setReadOnly: function( isReadOnly ) {
-			isReadOnly = ( isReadOnly == undefined ) || isReadOnly;
-
-			if ( this.readOnly != isReadOnly ) {
-				this.readOnly = isReadOnly;
-
-				// Block or release BACKSPACE key according to current read-only
-				// state to prevent browser's history navigation (#9761).
-				this.keystrokeHandler.blockedKeystrokes[ 8 ] = +isReadOnly;
-
-				this.editable().setReadOnly( isReadOnly );
-
-				// Fire the readOnly event so the editor features can update
-				// their state accordingly.
-				this.fire( 'readOnly' );
-			}
-		},
-
-		/**
-		 * Inserts HTML code into the currently selected position in the editor in WYSIWYG mode.
-		 *
-		 * * `"html"` - content being inserted will completely override styles
-		 *    of selected position.
-		 * * `"unfiltered_html"` - like `"html"` but content isn't filtered with {@link CKEDITOR.filter}.
-		 * * `"text"` - content being inserted will inherit styles applied in
-		 *    selected position. This mode should be used when inserting "htmlified" plain text
-		 *    (HTML without inline styles and styling elements like
-		 *    `<b/>, <strong/>, <span style="..."/>`).
-		 *
-		 * Example:
-		 *
-		 *		CKEDITOR.instances.editor1.insertHtml( '<p>This is a new paragraph.</p>' );
-		 *
-		 * @param {String} html HTML code to be inserted into the editor.
-		 * @param {String} [mode='html'] Mode in which HTML will be inserted.
-		 */
-		insertHtml: function( html, mode ) {
-			this.fire( 'insertHtml', { dataValue: html, mode: mode } );
-		},
-
-		/**
-		 * Insert text content into the currently selected position in the
-		 * editor in WYSIWYG mode. The styles of the selected element will be applied to the inserted text.
-		 * Spaces around the text will be leaving untouched.
-		 *
-		 *		CKEDITOR.instances.editor1.insertText( ' line1 \n\n line2' );
-		 *
-		 * @since 3.5
-		 * @param {String} text Text to be inserted into the editor.
-		 */
-		insertText: function( text ) {
-			this.fire( 'insertText', text );
-		},
-
-		/**
-		 * Inserts an element into the currently selected position in the
-		 * editor in WYSIWYG mode.
-		 *
-		 *		var element = CKEDITOR.dom.element.createFromHtml( '<img src="hello.png" border="0" title="Hello" />' );
-		 *		CKEDITOR.instances.editor1.insertElement( element );
-		 *
-		 * @param {CKEDITOR.dom.element} element The element to be inserted
-		 * into the editor.
-		 */
-		insertElement: function( element ) {
-			this.fire( 'insertElement', element );
-		},
-
-		/**
-		 * Moves the selection focus to the editing area space in the editor.
-		 */
-		focus: function() {
-			this.fire( 'beforeFocus' );
-		},
-
-		/**
-		 * Checks whether the current editor contents present changes when
-		 * compared to the contents loaded into the editor at startup, or to
-		 * the contents available in the editor when {@link #resetDirty}
-		 * was called.
-		 *
-		 *		function beforeUnload( evt ) {
-		 *			if ( CKEDITOR.instances.editor1.checkDirty() )
-		 *				return evt.returnValue = "You will lose the changes made in the editor.";
-		 *		}
-		 *
-		 *		if ( window.addEventListener )
-		 *			window.addEventListener( 'beforeunload', beforeUnload, false );
-		 *		else
-		 *			window.attachEvent( 'onbeforeunload', beforeUnload );
-		 *
-		 * @returns {Boolean} `true` if the contents contain changes.
-		 */
-		checkDirty: function() {
-			return this.status == 'ready' && this._.previousValue !== this.getSnapshot();
-		},
-
-		/**
-		 * Resets the "dirty state" of the editor so subsequent calls to
-		 * {@link #checkDirty} will return `false` if the user will not
-		 * have made further changes to the contents.
-		 *
-		 *		alert( editor.checkDirty() ); // e.g. true
-		 *		editor.resetDirty();
-		 *		alert( editor.checkDirty() ); // false
-		 */
-		resetDirty: function() {
-			this._.previousValue = this.getSnapshot();
-		},
-
-		/**
-		 * Updates the <code>&lt;textarea&gt;</code> element that was replaced by the editor with
-		 * the current data available in the editor.
-		 *
-		 * **Note:** This method will only affect those editor instances created
-		 * with {@link CKEDITOR#ELEMENT_MODE_REPLACE} element mode or inline instances
-		 * bound to `<textarea>` elements.
-		 *
-		 *		CKEDITOR.instances.editor1.updateElement();
-		 *		alert( document.getElementById( 'editor1' ).value ); // The current editor data.
-		 *
-		 * @see CKEDITOR.editor#element
-		 */
-		updateElement: function() {
-			return updateEditorElement.call( this );
-		},
-
-		/**
-		 * Assigns keystrokes associated to editor commands.
-		 *
-		 *		editor.setKeystroke( CKEDITOR.CTRL + 115, 'save' );	// Assigned CTRL+S to "save" command.
-		 *		editor.setKeystroke( CKEDITOR.CTRL + 115, false );	// Disabled CTRL+S keystroke assignment.
-		 *		editor.setKeystroke( [
-		 *			[ CKEDITOR.ALT + 122, false ],
-		 *			[ CKEDITOR.CTRL + 121, 'link' ],
-		 *			[ CKEDITOR.SHIFT + 120, 'bold' ]
-		 *		] );
-		 *
-		 * This method may be used in the following cases:
-		 *
-		 * * By plugins (like `link` or `basicstyles`) to set their keystrokes when plugins are being loaded.
-		 * * During the runtime to modify existing keystrokes.
-		 *
-		 * The editor handles keystroke configuration in the following order:
-		 *
-		 * 1. Plugins use this method to define default keystrokes.
-		 * 2. Editor extends default keystrokes with {@link CKEDITOR.config#keystrokes}.
-		 * 3. Editor blocks keystrokes defined in {@link CKEDITOR.config#blockedKeystrokes}.
-		 *
-		 * After all, you can still set new keystrokes using this method during the runtime.
-		 *
-		 * @since 4.0
-		 * @param {Number/Array} keystroke Keystroke or an array of keystroke definitions.
-		 * @param {String/Boolean} [behavior] A command to be executed on the keystroke.
-		 */
-		setKeystroke: function() {
-			var keystrokes = this.keystrokeHandler.keystrokes,
-				newKeystrokes = CKEDITOR.tools.isArray( arguments[ 0 ] ) ? arguments[ 0 ] : [ [].slice.call( arguments, 0 ) ],
-				keystroke, behavior;
-
-			for ( var i = newKeystrokes.length; i--; ) {
-				keystroke = newKeystrokes[ i ];
-				behavior = 0;
-
-				// It may be a pair of: [ key, command ]
-				if ( CKEDITOR.tools.isArray( keystroke ) ) {
-					behavior = keystroke[ 1 ];
-					keystroke = keystroke[ 0 ];
-				}
-
-				if ( behavior )
-					keystrokes[ keystroke ] = behavior;
-				else
-					delete keystrokes[ keystroke ];
-			}
-		},
-
-		/**
-		 * Shorthand for {@link CKEDITOR.filter#addFeature}.
-		 *
-		 * @since 4.1
-		 * @param {CKEDITOR.feature} feature See {@link CKEDITOR.filter#addFeature}.
-		 * @returns {Boolean} See {@link CKEDITOR.filter#addFeature}.
-		 */
-		addFeature: function( feature ) {
-			return this.filter.addFeature( feature );
-		},
-
-		/**
-		 * Sets the active filter ({@link #activeFilter}). Fires {@link #activeFilterChange} event.
-		 *
-		 *		// Set active filter which allows only 4 elements.
-		 *		// Buttons like Bold, Italic will be disabled.
-		 *		var filter = new CKEDITOR.filter( 'p strong em br' );
-		 *		editor.setActiveFilter( filter );
-		 *
-		 * Setting new filter will also change the {@link #setActiveEnterMode active enter modes} to the first values
-		 * allowed by the new filter (see {@link CKEDITOR.filter#getAllowedEnterMode}).
-		 *
-		 * @since 4.3
-		 * @param {CKEDITOR.filter} filter Filter instance or a falsy value (e.g. `null`) to reset to the default one.
-		 */
-		setActiveFilter: function( filter ) {
-			if ( !filter )
-				filter = this.filter;
-
-			if ( this.activeFilter !== filter ) {
-				this.activeFilter = filter;
-				this.fire( 'activeFilterChange' );
-
-				// Reseted active filter to the main one - reset enter modes too.
-				if ( filter === this.filter )
-					this.setActiveEnterMode( null, null );
-				else
-					this.setActiveEnterMode(
-						filter.getAllowedEnterMode( this.enterMode ),
-						filter.getAllowedEnterMode( this.shiftEnterMode, true )
-					);
-			}
-		},
-
-		/**
-		 * Sets the active enter modes ({@link #enterMode} and {@link #shiftEnterMode}).
-		 * Fires the {@link #activeEnterModeChange} event.
-		 *
-		 * Prior to CKEditor 4.3 enter modes were static and it was enough to check {@link CKEDITOR.config#enterMode}
-		 * and {@link CKEDITOR.config#shiftEnterMode} when implementing a feature which should depend on the enter modes.
-		 * Since CKEditor 4.3 these options are source of initial:
-		 *
-		 * * static {@link #enterMode} and {@link #shiftEnterMode} values,
-		 * * dynamic {@link #activeEnterMode} and {@link #activeShiftEnterMode} values.
-		 *
-		 * However, the dynamic enter modes can be changed during runtime by using this method, to reflect the selection context.
-		 * For example, if selection is moved to the {@link CKEDITOR.plugins.widget widget}'s nested editable which
-		 * is a {@link #blockless blockless one}, then the active enter modes should be changed to {@link CKEDITOR#ENTER_BR}
-		 * (in this case [Widget System](#!/guide/dev_widgets) takes care of that).
-		 *
-		 * **Note:** This method should not be used to configure editor &ndash; use {@link CKEDITOR.config#enterMode} and
-		 * {@link CKEDITOR.config#shiftEnterMode} instead. This method should be used only to dynamically change
-		 * enter modes during runtime based on selection changes.
-		 * Keep in mind that changed enter mode may be overwritten by other plugin/feature when it decided that
-		 * the changed context requires this.
-		 *
-		 * **Note:** In case of blockless editor (inline editor based on element which cannot contain block elements
-		 * &ndash; see {@link CKEDITOR.editor#blockless}) only {@link CKEDITOR#ENTER_BR} is a valid enter mode. Therefore
-		 * this method will not allow to set other values.
-		 *
-		 * **Note:** Changing the {@link #activeFilter active filter} may cause enter mode change if default enter modes
-		 * are not allowed by the new filter.
-		 *
-		 * @since 4.3
-		 * @param {Number} enterMode One of {@link CKEDITOR#ENTER_P}, {@link CKEDITOR#ENTER_DIV}, {@link CKEDITOR#ENTER_BR}.
-		 * Pass falsy value (e.g. `null`) to reset enter mode to the default value ({@link #enterMode} and/or {@link #shiftEnterMode}).
-		 * @param {Number} shiftEnterMode See the `enterMode` argument.
-		 */
-		setActiveEnterMode: function( enterMode, shiftEnterMode ) {
-			// Validate passed modes or use default ones (validated on init).
-			enterMode = enterMode ? validateEnterMode( this, enterMode ) : this.enterMode;
-			shiftEnterMode = shiftEnterMode ? validateEnterMode( this, shiftEnterMode ) : this.shiftEnterMode;
-
-			if ( this.activeEnterMode != enterMode || this.activeShiftEnterMode != shiftEnterMode ) {
-				this.activeEnterMode = enterMode;
-				this.activeShiftEnterMode = shiftEnterMode;
-				this.fire( 'activeEnterModeChange' );
-			}
-		}
-	} );
-} )();
-
-/**
- * The editor has no associated element.
- *
- * @readonly
- * @property {Number} [=0]
- * @member CKEDITOR
- */
-CKEDITOR.ELEMENT_MODE_NONE = 0;
-
-/**
- * The element is to be replaced by the editor instance.
- *
- * @readonly
- * @property {Number} [=1]
- * @member CKEDITOR
- */
-CKEDITOR.ELEMENT_MODE_REPLACE = 1;
-
-/**
- * The editor is to be created inside the element.
- *
- * @readonly
- * @property {Number} [=2]
- * @member CKEDITOR
- */
-CKEDITOR.ELEMENT_MODE_APPENDTO = 2;
-
-/**
- * The editor is to be attached to the element, using it as the editing block.
- *
- * @readonly
- * @property {Number} [=3]
- * @member CKEDITOR
- */
-CKEDITOR.ELEMENT_MODE_INLINE = 3;
-
-/**
- * Whether to escape HTML when the editor updates the original input element.
- *
- *		config.htmlEncodeOutput = true;
- *
- * @since 3.1
- * @cfg {Boolean} [htmlEncodeOutput=false]
- * @member CKEDITOR.config
- */
-
-/**
- * If `true`, makes the editor start in read-only state. Otherwise, it will check
- * if the linked `<textarea>` element has the `disabled` attribute.
- *
- *		config.readOnly = true;
- *
- * @since 3.6
- * @cfg {Boolean} [readOnly=false]
- * @member CKEDITOR.config
- * @see CKEDITOR.editor#setReadOnly
- */
-
-/**
- * Sets whether an editable element should have focus when the editor is loading for the first time.
- *
- *		config.startupFocus = true;
- *
- * @cfg {Boolean} [startupFocus=false]
- * @member CKEDITOR.config
- */
-
- /**
- * Customizes the {@link CKEDITOR.editor#title human-readable title} of this editor. This title is displayed in
- * tooltips and impacts various accessibility aspects, e.g. it is commonly used by screen readers
- * for distinguishing editor instances and for navigation. Accepted values are a string or `false`.
- *
- * **Note:** When `config.title` is set globally, the same value will be applied to all editor instances
- * loaded with this config. This may severely affect accessibility as screen reader users will be unable
- * to distinguish particular editor instances and navigate between them.
- *
- * **Note:** Setting `config.title = false` may also impair accessibility in a similar way.
- *
- * **Note:** Please do not confuse this property with {@link CKEDITOR.editor#name}
- * which identifies the instance in the {@link CKEDITOR#instances} literal.
- *
- *		// Sets the title to 'My WYSIWYG editor.'. The original title of the element (if it exists)
- *		// will be restored once the editor instance is destroyed.
- *		config.title = 'My WYSIWYG editor.';
- *
- *		// Do not touch the title. If the element already has a title, it remains unchanged.
- *		// Also if no title attribute exists, nothing new will be added.
- *		config.title = false;
- *
- * @since 4.2
- * @cfg {String/Boolean} [title=based on editor.name]
- * @member CKEDITOR.config
- * @see CKEDITOR.editor.name
- * @see CKEDITOR.editor.title
- */
-
-/**
- * Sets listeners on editor's events.
- *
- * **Note:** This property can only be set in the `config` object passed directly
- * to {@link CKEDITOR#replace}, {@link CKEDITOR#inline}, and other creators.
- *
- *		CKEDITOR.replace( 'editor1', {
- *			on: {
- *				instanceReady: function() {
- *					alert( this.name ); // 'editor1'
- *				},
- *
- *				key: function() {
- *					// ...
- *				}
- *			}
- *		} );
- *
- * @cfg {Object} on
- * @member CKEDITOR.config
- */
-
-/**
- * The outermost element in the DOM tree in which the editable element resides. It is provided
- * by a specific editor creator after editor UI is created and is not intended to
- * be modified.
- *
- *		var editor = CKEDITOR.instances.editor1;
- *		alert( editor.container.getName() ); // 'span'
- *
- * @readonly
- * @property {CKEDITOR.dom.element} container
- */
-
-/**
- * The document that stores the editor contents.
- *
- * * For the classic (`iframe`-based) editor it is equal to the document inside the
- * `iframe` containing the editable element.
- * * For the inline editor it is equal to {@link CKEDITOR#document}.
- *
- * The document object is available after the {@link #contentDom} event is fired
- * and may be invalidated when the {@link #contentDomUnload} event is fired
- * (classic editor only).
- *
- *		editor.on( 'contentDom', function() {
- *			console.log( editor.document );
- *		} );
- *
- * @readonly
- * @property {CKEDITOR.dom.document} document
- */
-
-/**
- * The window instance related to the {@link #document} property.
- *
- * It is always equal to the `editor.document.getWindow()`.
- *
- * See {@link #document} property documentation.
- *
- * @readonly
- * @property {CKEDITOR.dom.window} window
- */
-
-/**
- * The main filter instance used for input data filtering, data
- * transformations, and activation of features.
- *
- * It points to a {@link CKEDITOR.filter} instance set up based on
- * editor configuration.
- *
- * @since 4.1
- * @readonly
- * @property {CKEDITOR.filter} filter
- */
-
-/**
- * The active filter instance which should be used in the current context (location selection).
- * This instance will be used to make a decision which commands, buttons and other
- * {@link CKEDITOR.feature features} can be enabled.
- *
- * By default it equals the {@link #filter} and it can be changed by the {@link #setActiveFilter} method.
- *
- *		editor.on( 'activeFilterChange', function() {
- *			if ( editor.activeFilter.check( 'cite' ) )
- *				// Do something when <cite> was enabled - e.g. enable a button.
- *			else
- *				// Otherwise do something else.
- *		} );
- *
- * See also the {@link #setActiveEnterMode} method for an explanation of dynamic settings.
- *
- * @since 4.3
- * @readonly
- * @property {CKEDITOR.filter} activeFilter
- */
-
-/**
- * The main (static) enter mode which is a validated version of the {@link CKEDITOR.config#enterMode} setting.
- * Currently only one rule exists &ndash; {@link #blockless blockless editors} may have
- * enter modes set only to {@link CKEDITOR#ENTER_BR}.
- *
- * @since 4.3
- * @readonly
- * @property {Number} enterMode
- */
-
-/**
- * See the {@link #enterMode} property.
- *
- * @since 4.3
- * @readonly
- * @property {Number} shiftEnterMode
- */
-
-/**
- * The dynamic enter mode which should be used in the current context (selection location).
- * By default it equals the {@link #enterMode} and it can be changed by the {@link #setActiveEnterMode} method.
- *
- * See also the {@link #setActiveEnterMode} method for an explanation of dynamic settings.
- *
- * @since 4.3
- * @readonly
- * @property {Number} activeEnterMode
- */
-
-/**
- * See the {@link #activeEnterMode} property.
- *
- * @since 4.3
- * @readonly
- * @property {Number} activeShiftEnterMode
- */
-
-/**
- * Fired by the {@link #setActiveFilter} method when the {@link #activeFilter} is changed.
- *
- * @since 4.3
- * @event activeFilterChange
- */
-
-/**
- * Fired by the {@link #setActiveEnterMode} method when any of the active enter modes is changed.
- * See also the {@link #activeEnterMode} and {@link #activeShiftEnterMode} properties.
- *
- * @since 4.3
- * @event activeEnterModeChange
- */
-
-/**
- * Fired when a CKEDITOR instance is created, but still before initializing it.
- * To interact with a fully initialized instance, use the
- * {@link CKEDITOR#instanceReady} event instead.
- *
- * @event instanceCreated
- * @member CKEDITOR
- * @param {CKEDITOR.editor} editor The editor instance that has been created.
- */
-
-/**
- * Fired when CKEDITOR instance's components (config, languages and plugins) are fully
- * loaded and initialized. However, the editor will be fully ready to for interaction
- * on {@link CKEDITOR#instanceReady}.
- *
- * @event instanceLoaded
- * @member CKEDITOR
- * @param {CKEDITOR.editor} editor This editor instance that has been loaded.
- */
-
-/**
- * Fired when a CKEDITOR instance is destroyed.
- *
- * @event instanceDestroyed
- * @member CKEDITOR
- * @param {CKEDITOR.editor} editor The editor instance that has been destroyed.
- */
-
-/**
- * Fired when a CKEDITOR instance is created, fully initialized and ready for interaction.
- *
- * @event instanceReady
- * @member CKEDITOR
- * @param {CKEDITOR.editor} editor The editor instance that has been created.
- */
-
-/**
- * Fired when the language is loaded into the editor instance.
- *
- * @since 3.6.1
- * @event langLoaded
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Fired when all plugins are loaded and initialized into the editor instance.
- *
- * @event pluginsLoaded
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Fired when styles set is loaded. During editor initialization
- * phase the {@link #getStylesSet} method returns only styles that
- * are already loaded, which may not include e.g. styles parsed
- * by `stylesheetparser` plugin. Thus, to be notified when all
- * styles are ready you can listen on this event.
- *
- * @since 4.1
- * @event stylesSet
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param {Array} styles Array of styles definitions.
- */
-
-/**
- * Fired before the command execution when {@link #execCommand} is called.
- *
- * @event beforeCommandExec
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param data
- * @param {String} data.name The command name.
- * @param {Object} data.commandData The data to be sent to the command. This
- * can be manipulated by the event listener.
- * @param {CKEDITOR.command} data.command The command itself.
- */
-
-/**
- * Fired after the command execution when {@link #execCommand} is called.
- *
- * @event afterCommandExec
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param data
- * @param {String} data.name The command name.
- * @param {Object} data.commandData The data sent to the command.
- * @param {CKEDITOR.command} data.command The command itself.
- * @param {Object} data.returnValue The value returned by the command execution.
- */
-
-/**
- * Fired when the custom configuration file is loaded, before the final
- * configurations initialization.
- *
- * Custom configuration files can be loaded thorugh the
- * {@link CKEDITOR.config#customConfig} setting. Several files can be loaded
- * by changing this setting.
- *
- * @event customConfigLoaded
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Fired once the editor configuration is ready (loaded and processed).
- *
- * @event configLoaded
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Fired when this editor instance is destroyed. The editor at this
- * point is not usable and this event should be used to perform the clean-up
- * in any plugin.
- *
- * @event destroy
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Internal event to get the current data.
- *
- * @event beforeGetData
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Internal event to perform the {@link #method-getSnapshot} call.
- *
- * @event getSnapshot
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Internal event to perform the {@link #method-loadSnapshot} call.
- *
- * @event loadSnapshot
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param {String} data The data that will be used.
- */
-
-/**
- * Event fired before the {@link #method-getData} call returns allowing additional manipulation.
- *
- * @event getData
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param data
- * @param {String} data.dataValue The data that will be returned.
- */
-
-/**
- * Event fired before the {@link #method-setData} call is executed allowing additional manipulation.
- *
- * @event setData
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param data
- * @param {String} data.dataValue The data that will be used.
- */
-
-/**
- * Event fired at the end of the {@link #method-setData} call execution. Usually it is better to use the
- * {@link #dataReady} event.
- *
- * @event afterSetData
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param data
- * @param {String} data.dataValue The data that has been set.
- */
-
-/**
- * Fired as an indicator of the editor data loading. It may be the result of
- * calling {@link #method-setData} explicitly or an internal
- * editor function, like the editor editing mode switching (move to Source and back).
- *
- * @event dataReady
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Fired when the CKEDITOR instance is completely created, fully initialized
- * and ready for interaction.
- *
- * @event instanceReady
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Fired when editor's components (config, languages and plugins) are fully
- * loaded and initialized. However, the editor will be fully ready to for interaction
- * on {@link #instanceReady}.
- *
- * @event loaded
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Internal event to perform the {@link #method-insertHtml} call.
- *
- * @event insertHtml
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param data
- * @param {String} data.mode Mode in which data is inserted (see {@link #method-insertHtml}).
- * @param {String} data.dataValue The HTML to insert.
- */
-
-/**
- * Internal event to perform the {@link #method-insertText} call.
- *
- * @event insertText
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param {String} data The text to insert.
- */
-
-/**
- * Internal event to perform the {@link #method-insertElement} call.
- *
- * @event insertElement
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param {CKEDITOR.dom.element} data The element to insert.
- */
-
-/**
- * Event fired after the {@link #property-readOnly} property changes.
- *
- * @since 3.6
- * @event readOnly
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Event fired when an UI template is added to the editor instance. It makes
- * it possible to bring customizations to the template source.
- *
- * @event template
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param data
- * @param {String} data.name The template name.
- * @param {String} data.source The source data for this template.
- */
-
-/**
- * Fired when content of the editor (its DOM structure) is ready.
- * It is similar to native DOMContentLoaded event, but it concerns
- * editor's content. It is also a first event fired after
- * {@link CKEDITOR.editable} is initialized.
- *
- * This event is particularly important for classic (`iframe`-based)
- * editor, because on editor initialization and every time data are set
- * (by {@link CKEDITOR.editor#method-setData}) contents DOM structure
- * is rebuilt. Thus, e.g. you need to attach DOM events listeners
- * on editable one more time.
- *
- * On inline editor this event is fired only once - when editor
- * is initialized for the first time. That's because setting
- * editor's content doesn't cause editable destruction and creation.
- *
- * {@link #contentDom} goes along with {@link #contentDomUnload} which
- * is fired before contents DOM structure is destroyed. This is the
- * right moment to detach content DOM events listener. Otherwise
- * browsers like IE or Opera may throw exceptions when accessing
- * elements from detached document.
- *
- * **Note:** {@link CKEDITOR.editable#attachListener} is a convenient
- * way to attach listeners that will be detached on {@link #contentDomUnload}.
- *
- *		editor.on( 'contentDom', function() {
- *			var editable = editor.editable();
- *
- *			editable.attachListener( editable, 'click', function() {
- *				console.log( 'Editable has been clicked' );
- *			});
- *		});
- *
- * @event contentDom
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Fired before contents DOM structure is destroyed.
- * See {@link #contentDom} documentation for more details.
- *
- * @event contentDomUnload
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * The event fired when contents DOM changes and some of the references as well as
- * native DOM event listeners could be lost.
- * This event is useful when it is important to keep track of references
- * to elements in the editable contents from code.
- *
- * @since 4.3
- * @event contentDomInvalidated
- * @param {CKEDITOR.editor} editor This editor instance.
- */

+ 0 - 36
htdocs/includes/ckeditor/ckeditor/_source/core/editor_basic.js

@@ -1,36 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-if ( !CKEDITOR.editor ) {
-	// Documented at editor.js.
-	CKEDITOR.editor = function() {
-		// Push this editor to the pending list. It'll be processed later once
-		// the full editor code is loaded.
-		CKEDITOR._.pending.push( [ this, arguments ] );
-
-		// Call the CKEDITOR.event constructor to initialize this instance.
-		CKEDITOR.event.call( this );
-	};
-
-	// Both fire and fireOnce will always pass this editor instance as the
-	// "editor" param in CKEDITOR.event.fire. So, we override it to do that
-	// automaticaly.
-	CKEDITOR.editor.prototype.fire = function( eventName, data ) {
-		if ( eventName in { instanceReady: 1, loaded: 1 } )
-			this[ eventName ] = true;
-
-		return CKEDITOR.event.prototype.fire.call( this, eventName, data, this );
-	};
-
-	CKEDITOR.editor.prototype.fireOnce = function( eventName, data ) {
-		if ( eventName in { instanceReady: 1, loaded: 1 } )
-			this[ eventName ] = true;
-
-		return CKEDITOR.event.prototype.fireOnce.call( this, eventName, data, this );
-	};
-
-	// "Inherit" (copy actually) from CKEDITOR.event.
-	CKEDITOR.event.implementOn( CKEDITOR.editor.prototype );
-}

+ 0 - 359
htdocs/includes/ckeditor/ckeditor/_source/core/env.js

@@ -1,359 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.env} object which contains
- *		environment and browser information.
- */
-
-if ( !CKEDITOR.env ) {
-	/**
-	 * Environment and browser information.
-	 *
-	 * @class CKEDITOR.env
-	 * @singleton
-	 */
-	CKEDITOR.env = ( function() {
-		var agent = navigator.userAgent.toLowerCase();
-		var opera = window.opera;
-
-		var env = {
-			/**
-			 * Indicates that CKEditor is running in Internet Explorer.
-			 *
-			 *		if ( CKEDITOR.env.ie )
-			 *			alert( 'I\'m running in IE!' );
-			 *
-			 * @property {Boolean}
-			 */
-			ie: ( agent.indexOf( 'trident/' ) > -1 ),
-
-			/**
-			 * Indicates that CKEditor is running in Opera.
-			 *
-			 *		if ( CKEDITOR.env.opera )
-			 *			alert( 'I\'m running in Opera!' );
-			 *
-			 * @property {Boolean}
-			 */
-			opera: ( !!opera && opera.version ),
-
-			/**
-			 * Indicates that CKEditor is running in a WebKit-based browser, like Safari.
-			 *
-			 *		if ( CKEDITOR.env.webkit )
-			 *			alert( 'I\'m running in a WebKit browser!' );
-			 *
-			 * @property {Boolean}
-			 */
-			webkit: ( agent.indexOf( ' applewebkit/' ) > -1 ),
-
-			/**
-			 * Indicates that CKEditor is running in Adobe AIR.
-			 *
-			 *		if ( CKEDITOR.env.air )
-			 *			alert( 'I\'m on AIR!' );
-			 *
-			 * @property {Boolean}
-			 */
-			air: ( agent.indexOf( ' adobeair/' ) > -1 ),
-
-			/**
-			 * Indicates that CKEditor is running on Macintosh.
-			 *
-			 *		if ( CKEDITOR.env.mac )
-			 *			alert( 'I love apples!'' );
-			 *
-			 * @property {Boolean}
-			 */
-			mac: ( agent.indexOf( 'macintosh' ) > -1 ),
-
-			/**
-			 * Indicates that CKEditor is running in a Quirks Mode environment.
-			 *
-			 *		if ( CKEDITOR.env.quirks )
-			 *			alert( 'Nooooo!' );
-			 *
-			 * Internet Explorer 10 introduced the _New Quirks Mode_, which is similar to the _Quirks Mode_
-			 * implemented in other modern browsers and defined in the HTML5 specification. It can be handled
-			 * as the Standards mode, so the value of this property will be set to `false`.
-			 *
-			 * The _Internet Explorer 5 Quirks_ mode which is still available in Internet Explorer 10+
-			 * sets this value to `true` and {@link #version} to `7`.
-			 *
-			 * Read more: [IEBlog](http://blogs.msdn.com/b/ie/archive/2011/12/14/interoperable-html5-quirks-mode-in-ie10.aspx)
-			 *
-			 * @property {Boolean}
-			 */
-			quirks: ( document.compatMode == 'BackCompat' && ( !document.documentMode || document.documentMode < 10 ) ),
-
-			/**
-			 * Indicates that CKEditor is running in a mobile environemnt.
-			 *
-			 *		if ( CKEDITOR.env.mobile )
-			 *			alert( 'I\'m running with CKEditor today!' );
-			 *
-			 * @property {Boolean}
-			 */
-			mobile: ( agent.indexOf( 'mobile' ) > -1 ),
-
-			/**
-			 * Indicates that CKEditor is running on Apple iPhone/iPad/iPod devices.
-			 *
-			 *		if ( CKEDITOR.env.iOS )
-			 *			alert( 'I like little apples!' );
-			 *
-			 * @property {Boolean}
-			 */
-			iOS: /(ipad|iphone|ipod)/.test( agent ),
-
-			/**
-			 * Indicates that the browser has a custom domain enabled. This has
-			 * been set with `document.domain`.
-			 *
-			 *		if ( CKEDITOR.env.isCustomDomain() )
-			 *			alert( 'I\'m in a custom domain!' );
-			 *
-			 * @returns {Boolean} `true` if a custom domain is enabled.
-			 * @deprecated
-			 */
-			isCustomDomain: function() {
-				if ( !this.ie )
-					return false;
-
-				var domain = document.domain,
-					hostname = window.location.hostname;
-
-				return domain != hostname && domain != ( '[' + hostname + ']' ); // IPv6 IP support (#5434)
-			},
-
-			/**
-			 * Indicates that the page is running under an encrypted connection.
-			 *
-			 *		if ( CKEDITOR.env.secure )
-			 *			alert( 'I\'m on SSL!' );
-			 *
-			 * @returns {Boolean} `true` if the page has an encrypted connection.
-			 */
-			secure: location.protocol == 'https:'
-		};
-
-		/**
-		 * Indicates that CKEditor is running in a Gecko-based browser, like
-		 * Firefox.
-		 *
-		 *		if ( CKEDITOR.env.gecko )
-		 *			alert( 'I\'m riding a gecko!' );
-		 *
-		 * @property {Boolean}
-		 */
-		env.gecko = ( navigator.product == 'Gecko' && !env.webkit && !env.opera && !env.ie );
-
-		/**
-		 * Indicates that CKEditor is running in Chrome.
-		 *
-		 *		if ( CKEDITOR.env.chrome )
-		 *			alert( 'I\'m running in Chrome!' );
-		 *
-		 * @property {Boolean} chrome
-		 */
-
-		 /**
-		 * Indicates that CKEditor is running in Safari (including the mobile version).
-		 *
-		 *		if ( CKEDITOR.env.safari )
-		 *			alert( 'I\'m on Safari!' );
-		 *
-		 * @property {Boolean} safari
-		 */
-		if ( env.webkit ) {
-			if ( agent.indexOf( 'chrome' ) > -1 )
-				env.chrome = true;
-			else
-				env.safari = true;
-		}
-
-		var version = 0;
-
-		// Internet Explorer 6.0+
-		if ( env.ie ) {
-			// We use env.version for feature detection, so set it properly.
-			if ( env.quirks || !document.documentMode )
-				version = parseFloat( agent.match( /msie (\d+)/ )[ 1 ] );
-			else
-				version = document.documentMode;
-
-			// Deprecated features available just for backwards compatibility.
-			env.ie9Compat = version == 9;
-			env.ie8Compat = version == 8;
-			env.ie7Compat = version == 7;
-			env.ie6Compat = version < 7 || env.quirks;
-
-			/**
-			 * Indicates that CKEditor is running in an IE6-like environment, which
-			 * includes IE6 itself as well as IE7, IE8 and IE9 in Quirks Mode.
-			 *
-			 * @deprecated
-			 * @property {Boolean} ie6Compat
-			 */
-
-			/**
-			 * Indicates that CKEditor is running in an IE7-like environment, which
-			 * includes IE7 itself and IE8's IE7 Document Mode.
-			 *
-			 * @deprecated
-			 * @property {Boolean} ie7Compat
-			 */
-
-			/**
-			 * Indicates that CKEditor is running in Internet Explorer 8 on
-			 * Standards Mode.
-			 *
-			 * @deprecated
-			 * @property {Boolean} ie8Compat
-			 */
-
-			/**
-			 * Indicates that CKEditor is running in Internet Explorer 9 on
-			 * Standards Mode.
-			 *
-			 * @deprecated
-			 * @property {Boolean} ie9Compat
-			 */
-		}
-
-		// Gecko.
-		if ( env.gecko ) {
-			var geckoRelease = agent.match( /rv:([\d\.]+)/ );
-			if ( geckoRelease ) {
-				geckoRelease = geckoRelease[ 1 ].split( '.' );
-				version = geckoRelease[ 0 ] * 10000 + ( geckoRelease[ 1 ] || 0 ) * 100 + ( geckoRelease[ 2 ] || 0 ) * 1;
-			}
-		}
-
-		// Opera 9.50+
-		if ( env.opera )
-			version = parseFloat( opera.version() );
-
-		// Adobe AIR 1.0+
-		// Checked before Safari because AIR have the WebKit rich text editor
-		// features from Safari 3.0.4, but the version reported is 420.
-		if ( env.air )
-			version = parseFloat( agent.match( / adobeair\/(\d+)/ )[ 1 ] );
-
-		// WebKit 522+ (Safari 3+)
-		if ( env.webkit )
-			version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[ 1 ] );
-
-		/**
-		 * Contains the browser version.
-		 *
-		 * For Gecko-based browsers (like Firefox) it contains the revision
-		 * number with first three parts concatenated with a padding zero
-		 * (e.g. for revision 1.9.0.2 we have 10900).
-		 *
-		 * For WebKit-based browsers (like Safari and Chrome) it contains the
-		 * WebKit build version (e.g. 522).
-		 *
-		 * For IE browsers, it matches the "Document Mode".
-		 *
-		 *		if ( CKEDITOR.env.ie && CKEDITOR.env.version <= 6 )
-		 *			alert( 'Ouch!' );
-		 *
-		 * @property {Number}
-		 */
-		env.version = version;
-
-		/**
-		 * Indicates that CKEditor is running in a compatible browser.
-		 *
-		 *		if ( CKEDITOR.env.isCompatible )
-		 *			alert( 'Your browser is pretty cool!' );
-		 *
-		 * @property {Boolean}
-		 */
-		env.isCompatible =
-			// White list of mobile devices that CKEditor supports.
-			env.iOS && version >= 534 ||
-			!env.mobile && (
-				( env.ie && version > 6 ) ||
-				( env.gecko && version >= 10801 ) ||
-				( env.opera && version >= 9.5 ) ||
-				( env.air && version >= 1 ) ||
-				( env.webkit && version >= 522 ) ||
-				false
-			);
-
-		/**
-		 * Indicates that CKEditor is running in the HiDPI environment.
-		 *
-		 *		if ( CKEDITOR.env.hidpi )
-		 *			alert( 'You are using a screen with high pixel density.' );
-		 *
-		 * @property {Boolean}
-		 */
-		env.hidpi = window.devicePixelRatio >= 2;
-
-		/**
-		 * Indicates that CKEditor is running in a browser which uses a bogus
-		 * `<br>` filler in order to correctly display caret in empty blocks.
-		 *
-		 * @since 4.3
-		 * @property {Boolean}
-		 */
-		env.needsBrFiller = env.gecko || env.webkit || ( env.ie && version > 10 );
-
-		/**
-		 * Indicates that CKEditor is running in a browser which needs a
-		 * non-breaking space filler in order to correctly display caret in empty blocks.
-		 *
-		 * @since 4.3
-		 * @property {Boolean}
-		 */
-		env.needsNbspFiller = env.ie && version < 11;
-
-		/**
-		 * A CSS class that denotes the browser where CKEditor runs and is appended
-		 * to the HTML element that contains the editor. It makes it easier to apply
-		 * browser-specific styles to editor instances.
-		 *
-		 *		myDiv.className = CKEDITOR.env.cssClass;
-		 *
-		 * @property {String}
-		 */
-		env.cssClass = 'cke_browser_' + ( env.ie ? 'ie' : env.gecko ? 'gecko' : env.opera ? 'opera' : env.webkit ? 'webkit' : 'unknown' );
-
-		if ( env.quirks )
-			env.cssClass += ' cke_browser_quirks';
-
-		if ( env.ie ) {
-			env.cssClass += ' cke_browser_ie' + ( env.quirks || env.version < 7 ? '6' : env.version );
-
-			if ( env.quirks )
-				env.cssClass += ' cke_browser_iequirks';
-		}
-
-		if ( env.gecko ) {
-			if ( version < 10900 )
-				env.cssClass += ' cke_browser_gecko18';
-			else if ( version <= 11000 )
-				env.cssClass += ' cke_browser_gecko19';
-		}
-
-		if ( env.air )
-			env.cssClass += ' cke_browser_air';
-
-		if ( env.iOS )
-			env.cssClass += ' cke_browser_ios';
-
-		if ( env.hidpi )
-			env.cssClass += ' cke_hidpi';
-
-		return env;
-	} )();
-}
-
-// PACKAGER_RENAME( CKEDITOR.env )
-// PACKAGER_RENAME( CKEDITOR.env.ie )

+ 0 - 387
htdocs/includes/ckeditor/ckeditor/_source/core/event.js

@@ -1,387 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.event} class, which serves as the
- *		base for classes and objects that require event handling features.
- */
-
-if ( !CKEDITOR.event ) {
-	/**
-	 * Creates an event class instance. This constructor is rearely used, being
-	 * the {@link #implementOn} function used in class prototypes directly
-	 * instead.
-	 *
-	 * This is a base class for classes and objects that require event
-	 * handling features.
-	 *
-	 * Do not confuse this class with {@link CKEDITOR.dom.event} which is
-	 * instead used for DOM events. The CKEDITOR.event class implements the
-	 * internal event system used by the CKEditor to fire API related events.
-	 *
-	 * @class
-	 * @constructor Creates an event class instance.
-	 */
-	CKEDITOR.event = function() {};
-
-	/**
-	 * Implements the {@link CKEDITOR.event} features in an object.
-	 *
-	 *		var myObject = { message: 'Example' };
-	 *		CKEDITOR.event.implementOn( myObject );
-	 *
-	 *		myObject.on( 'testEvent', function() {
-	 *			alert( this.message );
-	 *		} );
-	 *		myObject.fire( 'testEvent' ); // 'Example'
-	 *
-	 * @static
-	 * @param {Object} targetObject The object into which implement the features.
-	 */
-	CKEDITOR.event.implementOn = function( targetObject ) {
-		var eventProto = CKEDITOR.event.prototype;
-
-		for ( var prop in eventProto ) {
-			if ( targetObject[ prop ] == undefined )
-				targetObject[ prop ] = eventProto[ prop ];
-		}
-	};
-
-	CKEDITOR.event.prototype = ( function() {
-		// Returns the private events object for a given object.
-		var getPrivate = function( obj ) {
-				var _ = ( obj.getPrivate && obj.getPrivate() ) || obj._ || ( obj._ = {} );
-				return _.events || ( _.events = {} );
-			};
-
-		var eventEntry = function( eventName ) {
-				this.name = eventName;
-				this.listeners = [];
-			};
-
-		eventEntry.prototype = {
-			// Get the listener index for a specified function.
-			// Returns -1 if not found.
-			getListenerIndex: function( listenerFunction ) {
-				for ( var i = 0, listeners = this.listeners; i < listeners.length; i++ ) {
-					if ( listeners[ i ].fn == listenerFunction )
-						return i;
-				}
-				return -1;
-			}
-		};
-
-		// Retrieve the event entry on the event host (create it if needed).
-		function getEntry( name ) {
-			// Get the event entry (create it if needed).
-			var events = getPrivate( this );
-			return events[ name ] || ( events[ name ] = new eventEntry( name ) );
-		}
-
-		return {
-			/**
-			 * Predefine some intrinsic properties on a specific event name.
-			 *
-			 * @param {String} name The event name
-			 * @param meta
-			 * @param [meta.errorProof=false] Whether the event firing should catch error thrown from a per listener call.
-			 */
-			define: function( name, meta ) {
-				var entry = getEntry.call( this, name );
-				CKEDITOR.tools.extend( entry, meta, true );
-			},
-
-			/**
-			 * Registers a listener to a specific event in the current object.
-			 *
-			 *		someObject.on( 'someEvent', function() {
-			 *			alert( this == someObject );		// true
-			 *		} );
-			 *
-			 *		someObject.on( 'someEvent', function() {
-			 *			alert( this == anotherObject );		// true
-			 *		}, anotherObject );
-			 *
-			 *		someObject.on( 'someEvent', function( event ) {
-			 *			alert( event.listenerData );		// 'Example'
-			 *		}, null, 'Example' );
-			 *
-			 *		someObject.on( 'someEvent', function() { ... } );						// 2nd called
-			 *		someObject.on( 'someEvent', function() { ... }, null, null, 100 );		// 3rd called
-			 *		someObject.on( 'someEvent', function() { ... }, null, null, 1 );		// 1st called
-			 *
-			 * @param {String} eventName The event name to which listen.
-			 * @param {Function} listenerFunction The function listening to the
-			 * event. A single {@link CKEDITOR.eventInfo} object instanced
-			 * is passed to this function containing all the event data.
-			 * @param {Object} [scopeObj] The object used to scope the listener
-			 * call (the `this` object). If omitted, the current object is used.
-			 * @param {Object} [listenerData] Data to be sent as the
-			 * {@link CKEDITOR.eventInfo#listenerData} when calling the
-			 * listener.
-			 * @param {Number} [priority=10] The listener priority. Lower priority
-			 * listeners are called first. Listeners with the same priority
-			 * value are called in registration order.
-			 * @returns {Object} An object containing the `removeListener`
-			 * function, which can be used to remove the listener at any time.
-			 */
-			on: function( eventName, listenerFunction, scopeObj, listenerData, priority ) {
-				// Create the function to be fired for this listener.
-				function listenerFirer( editor, publisherData, stopFn, cancelFn ) {
-					var ev = {
-						name: eventName,
-						sender: this,
-						editor: editor,
-						data: publisherData,
-						listenerData: listenerData,
-						stop: stopFn,
-						cancel: cancelFn,
-						removeListener: removeListener
-					};
-
-					var ret = listenerFunction.call( scopeObj, ev );
-
-					return ret === false ? false : ev.data;
-				}
-
-				function removeListener() {
-					me.removeListener( eventName, listenerFunction );
-				}
-
-				var event = getEntry.call( this, eventName );
-
-				if ( event.getListenerIndex( listenerFunction ) < 0 ) {
-					// Get the listeners.
-					var listeners = event.listeners;
-
-					// Fill the scope.
-					if ( !scopeObj )
-						scopeObj = this;
-
-					// Default the priority, if needed.
-					if ( isNaN( priority ) )
-						priority = 10;
-
-					var me = this;
-
-					listenerFirer.fn = listenerFunction;
-					listenerFirer.priority = priority;
-
-					// Search for the right position for this new listener, based on its
-					// priority.
-					for ( var i = listeners.length - 1; i >= 0; i-- ) {
-						// Find the item which should be before the new one.
-						if ( listeners[ i ].priority <= priority ) {
-							// Insert the listener in the array.
-							listeners.splice( i + 1, 0, listenerFirer );
-							return { removeListener: removeListener };
-						}
-					}
-
-					// If no position has been found (or zero length), put it in
-					// the front of list.
-					listeners.unshift( listenerFirer );
-				}
-
-				return { removeListener: removeListener };
-			},
-
-			/**
-			 * Similiar with {@link #on} but the listener will be called only once upon the next event firing.
-			 *
-			 * @see CKEDITOR.event#on
-			 */
-			once: function() {
-				var fn = arguments[ 1 ];
-
-				arguments[ 1 ] = function( evt ) {
-					evt.removeListener();
-					return fn.apply( this, arguments );
-				};
-
-				return this.on.apply( this, arguments );
-			},
-
-			/**
-			 * @static
-			 * @property {Boolean} useCapture
-			 * @todo
-			 */
-
-			/**
-			 * Register event handler under the capturing stage on supported target.
-			 */
-			capture: function() {
-				CKEDITOR.event.useCapture = 1;
-				var retval = this.on.apply( this, arguments );
-				CKEDITOR.event.useCapture = 0;
-				return retval;
-			},
-
-			/**
-			 * Fires an specific event in the object. All registered listeners are
-			 * called at this point.
-			 *
-			 *		someObject.on( 'someEvent', function() { ... } );
-			 *		someObject.on( 'someEvent', function() { ... } );
-			 *		someObject.fire( 'someEvent' );				// Both listeners are called.
-			 *
-			 *		someObject.on( 'someEvent', function( event ) {
-			 *			alert( event.data );					// 'Example'
-			 *		} );
-			 *		someObject.fire( 'someEvent', 'Example' );
-			 *
-			 * @method
-			 * @param {String} eventName The event name to fire.
-			 * @param {Object} [data] Data to be sent as the
-			 * {@link CKEDITOR.eventInfo#data} when calling the listeners.
-			 * @param {CKEDITOR.editor} [editor] The editor instance to send as the
-			 * {@link CKEDITOR.eventInfo#editor} when calling the listener.
-			 * @returns {Boolean/Object} A boolean indicating that the event is to be
-			 * canceled, or data returned by one of the listeners.
-			 */
-			fire: ( function() {
-				// Create the function that marks the event as stopped.
-				var stopped = 0;
-				var stopEvent = function() {
-						stopped = 1;
-					};
-
-				// Create the function that marks the event as canceled.
-				var canceled = 0;
-				var cancelEvent = function() {
-						canceled = 1;
-					};
-
-				return function( eventName, data, editor ) {
-					// Get the event entry.
-					var event = getPrivate( this )[ eventName ];
-
-					// Save the previous stopped and cancelled states. We may
-					// be nesting fire() calls.
-					var previousStopped = stopped,
-						previousCancelled = canceled;
-
-					// Reset the stopped and canceled flags.
-					stopped = canceled = 0;
-
-					if ( event ) {
-						var listeners = event.listeners;
-
-						if ( listeners.length ) {
-							// As some listeners may remove themselves from the
-							// event, the original array length is dinamic. So,
-							// let's make a copy of all listeners, so we are
-							// sure we'll call all of them.
-							listeners = listeners.slice( 0 );
-
-							var retData;
-							// Loop through all listeners.
-							for ( var i = 0; i < listeners.length; i++ ) {
-								// Call the listener, passing the event data.
-								if ( event.errorProof ) {
-									try {
-										retData = listeners[ i ].call( this, editor, data, stopEvent, cancelEvent );
-									} catch ( er ) {}
-								} else
-									retData = listeners[ i ].call( this, editor, data, stopEvent, cancelEvent );
-
-								if ( retData === false )
-									canceled = 1;
-								else if ( typeof retData != 'undefined' )
-									data = retData;
-
-								// No further calls is stopped or canceled.
-								if ( stopped || canceled )
-									break;
-							}
-						}
-					}
-
-					var ret = canceled ? false : ( typeof data == 'undefined' ? true : data );
-
-					// Restore the previous stopped and canceled states.
-					stopped = previousStopped;
-					canceled = previousCancelled;
-
-					return ret;
-				};
-			} )(),
-
-			/**
-			 * Fires an specific event in the object, releasing all listeners
-			 * registered to that event. The same listeners are not called again on
-			 * successive calls of it or of {@link #fire}.
-			 *
-			 *		someObject.on( 'someEvent', function() { ... } );
-			 *		someObject.fire( 'someEvent' );			// Above listener called.
-			 *		someObject.fireOnce( 'someEvent' );		// Above listener called.
-			 *		someObject.fire( 'someEvent' );			// No listeners called.
-			 *
-			 * @param {String} eventName The event name to fire.
-			 * @param {Object} [data] Data to be sent as the
-			 * {@link CKEDITOR.eventInfo#data} when calling the listeners.
-			 * @param {CKEDITOR.editor} [editor] The editor instance to send as the
-			 * {@link CKEDITOR.eventInfo#editor} when calling the listener.
-			 * @returns {Boolean/Object} A booloan indicating that the event is to be
-			 * canceled, or data returned by one of the listeners.
-			 */
-			fireOnce: function( eventName, data, editor ) {
-				var ret = this.fire( eventName, data, editor );
-				delete getPrivate( this )[ eventName ];
-				return ret;
-			},
-
-			/**
-			 * Unregisters a listener function from being called at the specified
-			 * event. No errors are thrown if the listener has not been registered previously.
-			 *
-			 *		var myListener = function() { ... };
-			 *		someObject.on( 'someEvent', myListener );
-			 *		someObject.fire( 'someEvent' );					// myListener called.
-			 *		someObject.removeListener( 'someEvent', myListener );
-			 *		someObject.fire( 'someEvent' );					// myListener not called.
-			 *
-			 * @param {String} eventName The event name.
-			 * @param {Function} listenerFunction The listener function to unregister.
-			 */
-			removeListener: function( eventName, listenerFunction ) {
-				// Get the event entry.
-				var event = getPrivate( this )[ eventName ];
-
-				if ( event ) {
-					var index = event.getListenerIndex( listenerFunction );
-					if ( index >= 0 )
-						event.listeners.splice( index, 1 );
-				}
-			},
-
-			/**
-			 * Remove all existing listeners on this object, for cleanup purpose.
-			 */
-			removeAllListeners: function() {
-				var events = getPrivate( this );
-				for ( var i in events )
-					delete events[ i ];
-			},
-
-			/**
-			 * Checks if there is any listener registered to a given event.
-			 *
-			 *		var myListener = function() { ... };
-			 *		someObject.on( 'someEvent', myListener );
-			 *		alert( someObject.hasListeners( 'someEvent' ) );	// true
-			 *		alert( someObject.hasListeners( 'noEvent' ) );		// false
-			 *
-			 * @param {String} eventName The event name.
-			 * @returns {Boolean}
-			 */
-			hasListeners: function( eventName ) {
-				var event = getPrivate( this )[ eventName ];
-				return ( event && event.listeners.length > 0 );
-			}
-		};
-	} )();
-}

+ 0 - 115
htdocs/includes/ckeditor/ckeditor/_source/core/eventInfo.js

@@ -1,115 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the "virtual" {@link CKEDITOR.eventInfo} class, which
- *		contains the defintions of the event object passed to event listeners.
- *		This file is for documentation purposes only.
- */
-
-/**
- * Virtual class that illustrates the features of the event object to be
- * passed to event listeners by a {@link CKEDITOR.event} based object.
- *
- * This class is not really part of the API.
- *
- * @class CKEDITOR.eventInfo
- * @abstract
- */
-
-/**
- * The event name.
- *
- *		someObject.on( 'someEvent', function( event ) {
- *			alert( event.name ); // 'someEvent'
- *		} );
- *		someObject.fire( 'someEvent' );
- *
- * @property {String} name
- */
-
-/**
- * The object that publishes (sends) the event.
- *
- *		someObject.on( 'someEvent', function( event ) {
- *			alert( event.sender == someObject ); // true
- *		} );
- *		someObject.fire( 'someEvent' );
- *
- * @property sender
- */
-
-/**
- * The editor instance that holds the sender. May be the same as sender. May be
- * null if the sender is not part of an editor instance, like a component
- * running in standalone mode.
- *
- *		myButton.on( 'someEvent', function( event ) {
- *			alert( event.editor == myEditor ); // true
- *		} );
- *		myButton.fire( 'someEvent', null, myEditor );
- *
- * @property {CKEDITOR.editor} editor
- */
-
-/**
- * Any kind of additional data. Its format and usage is event dependent.
- *
- *		someObject.on( 'someEvent', function( event ) {
- *			alert( event.data ); // 'Example'
- *		} );
- *		someObject.fire( 'someEvent', 'Example' );
- *
- * @property data
- */
-
-/**
- * Any extra data appended during the listener registration.
- *
- *		someObject.on( 'someEvent', function( event ) {
- *			alert( event.listenerData ); // 'Example'
- *		}, null, 'Example' );
- *
- * @property listenerData
- */
-
-/**
- * Indicates that no further listeners are to be called.
- *
- *		someObject.on( 'someEvent', function( event ) {
- *			event.stop();
- *		} );
- *		someObject.on( 'someEvent', function( event ) {
- *			// This one will not be called.
- *		} );
- *		alert( someObject.fire( 'someEvent' ) ); // false
- *
- * @method stop
- */
-
-/**
- * Indicates that the event is to be cancelled (if cancelable).
- *
- *		someObject.on( 'someEvent', function( event ) {
- *			event.cancel();
- *		} );
- *		someObject.on( 'someEvent', function( event ) {
- *			// This one will not be called.
- *		} );
- *		alert( someObject.fire( 'someEvent' ) ); // true
- *
- * @method cancel
- */
-
-/**
- * Removes the current listener.
- *
- *		someObject.on( 'someEvent', function( event ) {
- *			event.removeListener();
- *			// Now this function won't be called again by 'someEvent'.
- *		} );
- *
- * @method removeListener
- */

+ 0 - 2072
htdocs/includes/ckeditor/ckeditor/_source/core/filter.js

@@ -1,2072 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-( function() {
-	'use strict';
-
-	var DTD = CKEDITOR.dtd,
-		copy = CKEDITOR.tools.copy,
-		trim = CKEDITOR.tools.trim,
-		TEST_VALUE = 'cke-test',
-		enterModeTags = [ '', 'p', 'br', 'div' ];
-
-	/**
-	 * Highly configurable class which implements input data filtering mechanisms
-	 * and core functions used for the activation of editor features.
-	 *
-	 * A filter instance is always available under the {@link CKEDITOR.editor#filter}
-	 * property and is used by the editor in its core features like filtering input data,
-	 * applying data transformations, validating whether a feature may be enabled for
-	 * the current setup. It may be configured in two ways:
-	 *
-	 *	* By the user, with the {@link CKEDITOR.config#allowedContent} setting.
-	 *	* Automatically, by loaded features (toolbar items, commands, etc.).
-	 *
-	 * In both cases additional allowed content rules may be added by
-	 * setting the {@link CKEDITOR.config#extraAllowedContent}
-	 * configuration option.
-	 *
-	 * **Note**: Filter rules will be extended with the following elements
-	 * depending on the {@link CKEDITOR.config#enterMode} and
-	 * {@link CKEDITOR.config#shiftEnterMode} settings:
-	 *
-	 *	* `'p'` &ndash; for {@link CKEDITOR#ENTER_P},
-	 *	* `'div'` &ndash; for {@link CKEDITOR#ENTER_DIV},
-	 *	* `'br'` &ndash; for {@link CKEDITOR#ENTER_BR}.
-	 *
-	 * **Read more** about the Advanced Content Filter in [guides](#!/guide/dev_advanced_content_filter).
-	 *
-	 * Filter may also be used as a standalone instance by passing
-	 * {@link CKEDITOR.filter.allowedContentRules} instead of {@link CKEDITOR.editor}
-	 * to the constructor:
-	 *
-	 *		var filter = new CKEDITOR.filter( 'b' );
-	 *
-	 *		filter.check( 'b' ); // -> true
-	 *		filter.check( 'i' ); // -> false
-	 *		filter.allow( 'i' );
-	 *		filter.check( 'i' ); // -> true
-	 *
-	 * @since 4.1
-	 * @class
-	 * @constructor Creates a filter class instance.
-	 * @param {CKEDITOR.editor/CKEDITOR.filter.allowedContentRules} editorOrRules
-	 */
-	CKEDITOR.filter = function( editorOrRules ) {
-		/**
-		 * Whether custom {@link CKEDITOR.config#allowedContent} was set.
-		 *
-		 * This property does not apply to the standalone filter.
-		 *
-		 * @readonly
-		 * @property {Boolean} customConfig
-		 */
-
-		/**
-		 * Array of rules added by the {@link #allow} method (including those
-		 * loaded from {@link CKEDITOR.config#allowedContent} and
-		 * {@link CKEDITOR.config#extraAllowedContent}).
-		 *
-		 * Rules in this array are in unified allowed content rules format.
-		 *
-		 * This property is useful for debugging issues with rules string parsing
-		 * or for checking which rules were automatically added by editor features.
-		 *
-		 * @readonly
-		 */
-		this.allowedContent = [];
-
-		/**
-		 * Whether the filter is disabled.
-		 *
-		 * To disable the filter, set {@link CKEDITOR.config#allowedContent} to `true`
-		 * or use the {@link #disable} method.
-		 *
-		 * @readonly
-		 */
-		this.disabled = false;
-
-		/**
-		 * Editor instance if not a standalone filter.
-		 *
-		 * @readonly
-		 * @property {CKEDITOR.editor} [=null]
-		 */
-		this.editor = null;
-
-		/**
-		 * Filter's unique id. It can be used to find filter instance in
-		 * {@link CKEDITOR.filter#instances CKEDITOR.filter.instance} object.
-		 *
-		 * @since 4.3
-		 * @readonly
-		 * @property {Number} id
-		 */
-		this.id = CKEDITOR.tools.getNextNumber();
-
-		this._ = {
-			// Optimized allowed content rules.
-			rules: {},
-			// Object: element name => array of transformations groups.
-			transformations: {},
-			cachedTests: {}
-		};
-
-		// Register filter instance.
-		CKEDITOR.filter.instances[ this.id ] = this;
-
-		if ( editorOrRules instanceof CKEDITOR.editor ) {
-			var editor = this.editor = editorOrRules;
-			this.customConfig = true;
-
-			var allowedContent = editor.config.allowedContent;
-
-			// Disable filter completely by setting config.allowedContent = true.
-			if ( allowedContent === true ) {
-				this.disabled = true;
-				return;
-			}
-
-			if ( !allowedContent )
-				this.customConfig = false;
-
-			this.allow( allowedContent, 'config', 1 );
-			this.allow( editor.config.extraAllowedContent, 'extra', 1 );
-
-			// Enter modes should extend filter rules (ENTER_P adds 'p' rule, etc.).
-			this.allow( enterModeTags[ editor.enterMode ] + ' ' + enterModeTags[ editor.shiftEnterMode ], 'default', 1 );
-		}
-		// Rules object passed in editorOrRules argument - initialize standalone filter.
-		else {
-			this.customConfig = false;
-			this.allow( editorOrRules, 'default', 1 );
-		}
-	};
-
-	/**
-	 * Object containing all filter instances stored under their
-	 * {@link #id} properties.
-	 *
-	 *		var filter = new CKEDITOR.filter( 'p' );
-	 *		filter === CKEDITOR.filter.instances[ filter.id ];
-	 *
-	 * @since 4.3
-	 * @static
-	 * @property instances
-	 */
-	CKEDITOR.filter.instances = {};
-
-	CKEDITOR.filter.prototype = {
-		/**
-		 * Adds allowed content rules to the filter.
-		 *
-		 * Read about rules formats in [Allowed Content Rules guide](#!/guide/dev_allowed_content_rules).
-		 *
-		 *		// Add a basic rule for custom image feature (e.g. 'MyImage' button).
-		 *		editor.filter.allow( 'img[!src,alt]', 'MyImage' );
-		 *
-		 *		// Add rules for two header styles allowed by 'HeadersCombo'.
-		 *		var header1Style = new CKEDITOR.style( { element: 'h1' } ),
-		 *			header2Style = new CKEDITOR.style( { element: 'h2' } );
-		 *		editor.filter.allow( [ header1Style, header2Style ], 'HeadersCombo' );
-		 *
-		 * @param {CKEDITOR.filter.allowedContentRules} newRules Rule(s) to be added.
-		 * @param {String} [featureName] Name of a feature that allows this content (most often plugin/button/command name).
-		 * @param {Boolean} [overrideCustom] By default this method will reject any rules
-		 * if {@link CKEDITOR.config#allowedContent} is defined to avoid overriding it.
-		 * Pass `true` to force rules addition.
-		 * @returns {Boolean} Whether the rules were accepted.
-		 */
-		allow: function( newRules, featureName, overrideCustom ) {
-			if ( this.disabled )
-				return false;
-
-			// Don't override custom user's configuration if not explicitly requested.
-			if ( this.customConfig && !overrideCustom )
-				return false;
-
-			if ( !newRules )
-				return false;
-
-			// Clear cache, because new rules could change results of checks.
-			this._.cachedChecks = {};
-
-			var i, ret;
-
-			if ( typeof newRules == 'string' )
-				newRules = parseRulesString( newRules );
-			else if ( newRules instanceof CKEDITOR.style )
-				newRules = convertStyleToRules( newRules );
-			else if ( CKEDITOR.tools.isArray( newRules ) ) {
-				for ( i = 0; i < newRules.length; ++i )
-					ret = this.allow( newRules[ i ], featureName, overrideCustom );
-				return ret; // Return last status.
-			}
-
-			var groupName, rule,
-				rulesToOptimize = [];
-
-			for ( groupName in newRules ) {
-				rule = newRules[ groupName ];
-
-				// { 'p h1': true } => { 'p h1': {} }.
-				if ( typeof rule == 'boolean' )
-					rule = {};
-				// { 'p h1': func } => { 'p h1': { match: func } }.
-				else if ( typeof rule == 'function' )
-					rule = { match: rule };
-				// Clone (shallow) rule, because we'll modify it later.
-				else
-					rule = copy( rule );
-
-				// If this is not an unnamed rule ({ '$1' => { ... } })
-				// move elements list to property.
-				if ( groupName.charAt( 0 ) != '$' )
-					rule.elements = groupName;
-
-				if ( featureName )
-					rule.featureName = featureName.toLowerCase();
-
-				standardizeRule( rule );
-
-				// Save rule and remember to optimize it.
-				this.allowedContent.push( rule );
-				rulesToOptimize.push( rule );
-			}
-
-			optimizeRules( this._.rules, rulesToOptimize );
-
-			return true;
-		},
-
-		/**
-		 * Applies this filter to passed {@link CKEDITOR.htmlParser.fragment} or {@link CKEDITOR.htmlParser.element}.
-		 * The result of filtering is a DOM tree without disallowed content.
-		 *
-		 *			// Create standalone filter passing 'p' and 'b' elements.
-		 *		var filter = new CKEDITOR.filter( 'p b' ),
-		 *			// Parse HTML string to pseudo DOM structure.
-		 *			fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<p><b>foo</b> <i>bar</i></p>' ),
-		 *			writer = new CKEDITOR.htmlParser.basicWriter();
-		 *
-		 *		filter.applyTo( fragment );
-		 *		fragment.writeHtml( writer );
-		 *		writer.getHtml(); // -> '<p><b>foo</b> bar</p>'
-		 *
-		 * @param {CKEDITOR.htmlParser.fragment/CKEDITOR.htmlParser.element} fragment Node to be filtered.
-		 * @param {Boolean} [toHtml] Set to `true` if the filter is used together with {@link CKEDITOR.htmlDataProcessor#toHtml}.
-		 * @param {Boolean} [transformOnly] If set to `true` only transformations will be applied. Content
-		 * will not be filtered with allowed content rules.
-		 * @param {Number} [enterMode] Enter mode used by the filter when deciding how to strip disallowed element.
-		 * Defaults to {@link CKEDITOR.editor#activeEnterMode} for a editor's filter or to {@link CKEDITOR#ENTER_P} for standalone filter.
-		 * @returns {Boolean} Whether some part of the `fragment` was removed by the filter.
-		 */
-		applyTo: function( fragment, toHtml, transformOnly, enterMode ) {
-			if ( this.disabled )
-				return false;
-
-			var toBeRemoved = [],
-				rules = !transformOnly && this._.rules,
-				transformations = this._.transformations,
-				filterFn = getFilterFunction( this ),
-				protectedRegexs = this.editor && this.editor.config.protectedSource,
-				isModified = false;
-
-			// Filter all children, skip root (fragment or editable-like wrapper used by data processor).
-			fragment.forEach( function( el ) {
-				if ( el.type == CKEDITOR.NODE_ELEMENT ) {
-					// Do not filter element with data-cke-filter="off" and all their descendants.
-					if ( el.attributes[ 'data-cke-filter' ] == 'off' )
-						return false;
-
-					// (#10260) Don't touch elements like spans with data-cke-* attribute since they're
-					// responsible e.g. for placing markers, bookmarks, odds and stuff.
-					// We love 'em and we don't wanna lose anything during the filtering.
-					// '|' is to avoid tricky joints like data-="foo" + cke-="bar". Yes, they're possible.
-					//
-					// NOTE: data-cke-* assigned elements are preserved only when filter is used with
-					//       htmlDataProcessor.toHtml because we don't want to protect them when outputting data
-					//       (toDataFormat).
-					if ( toHtml && el.name == 'span' && ~CKEDITOR.tools.objectKeys( el.attributes ).join( '|' ).indexOf( 'data-cke-' ) )
-						return;
-
-					if ( filterFn( el, rules, transformations, toBeRemoved, toHtml ) )
-						isModified = true;
-				}
-				else if ( el.type == CKEDITOR.NODE_COMMENT && el.value.match( /^\{cke_protected\}(?!\{C\})/ ) ) {
-					if ( !filterProtectedElement( el, protectedRegexs, filterFn, rules, transformations, toHtml ) )
-						toBeRemoved.push( el );
-				}
-			}, null, true );
-
-			if ( toBeRemoved.length )
-				isModified = true;
-
-			var node, element, check,
-				toBeChecked = [],
-				enterTag = enterModeTags[ enterMode || ( this.editor ? this.editor.enterMode : CKEDITOR.ENTER_P ) ];
-
-			// Remove elements in reverse order - from leaves to root, to avoid conflicts.
-			while ( ( node = toBeRemoved.pop() ) ) {
-				if ( node.type == CKEDITOR.NODE_ELEMENT )
-					removeElement( node, enterTag, toBeChecked );
-				// This is a comment securing rejected element - remove it completely.
-				else
-					node.remove();
-			}
-
-			// Check elements that have been marked as possibly invalid.
-			while ( ( check = toBeChecked.pop() ) ) {
-				element = check.el;
-				// Element has been already removed.
-				if ( !element.parent )
-					continue;
-
-				switch ( check.check ) {
-					// Check if element itself is correct.
-					case 'it':
-						// Check if element included in $removeEmpty has no children.
-						if ( DTD.$removeEmpty[ element.name ] && !element.children.length )
-							removeElement( element, enterTag, toBeChecked );
-						// Check if that is invalid element.
-						else if ( !validateElement( element ) )
-							removeElement( element, enterTag, toBeChecked );
-						break;
-
-					// Check if element is in correct context. If not - remove element.
-					case 'el-up':
-						// Check if e.g. li is a child of body after ul has been removed.
-						if ( element.parent.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT &&
-							!DTD[ element.parent.name ][ element.name ]
-						)
-							removeElement( element, enterTag, toBeChecked );
-						break;
-
-					// Check if element is in correct context. If not - remove parent.
-					case 'parent-down':
-						if ( element.parent.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT &&
-							!DTD[ element.parent.name ][ element.name ]
-						)
-							removeElement( element.parent, enterTag, toBeChecked );
-						break;
-				}
-			}
-
-			return isModified;
-		},
-
-		/**
-		 * Checks whether a {@link CKEDITOR.feature} can be enabled. Unlike {@link #addFeature},
-		 * this method always checks the feature, even when the default configuration
-		 * for {@link CKEDITOR.config#allowedContent} is used.
-		 *
-		 *		// TODO example
-		 *
-		 * @param {CKEDITOR.feature} feature The feature to be tested.
-		 * @returns {Boolean} Whether this feature can be enabled.
-		 */
-		checkFeature: function( feature ) {
-			if ( this.disabled )
-				return true;
-
-			if ( !feature )
-				return true;
-
-			// Some features may want to register other features.
-			// E.g. a button may return a command bound to it.
-			if ( feature.toFeature )
-				feature = feature.toFeature( this.editor );
-
-			return !feature.requiredContent || this.check( feature.requiredContent );
-		},
-
-		/**
-		 * Disables Advanced Content Filter.
-		 *
-		 * This method is meant to be used by plugins which are not
-		 * compatible with the filter and in other cases in which the filter
-		 * has to be disabled during the initialization phase or runtime.
-		 *
-		 * In other cases the filter can be disabled by setting
-		 * {@link CKEDITOR.config#allowedContent} to `true`.
-		 */
-		disable: function() {
-			this.disabled = true;
-		},
-
-		/**
-		 * Adds an array of {@link CKEDITOR.feature} content forms. All forms
-		 * will then be transformed to the first form which is allowed by the filter.
-		 *
-		 *		editor.filter.allow( 'i; span{!font-style}' );
-		 *		editor.filter.addContentForms( [
-		 *			'em',
-		 *			'i',
-		 *			[ 'span', function( el ) {
-		 *				return el.styles[ 'font-style' ] == 'italic';
-		 *			} ]
-		 *		] );
-		 *		// Now <em> and <span style="font-style:italic"> will be replaced with <i>
-		 *		// because this is the first allowed form.
-		 *		// <span> is allowed too, but it is the last form and
-		 *		// additionaly, the editor cannot transform an element based on
-		 *		// the array+function form).
-		 *
-		 * This method is used by the editor to register {@link CKEDITOR.feature#contentForms}
-		 * when adding a feature with {@link #addFeature} or {@link CKEDITOR.editor#addFeature}.
-		 *
-		 * @param {Array} forms The content forms of a feature.
-		 */
-		addContentForms: function( forms ) {
-			if ( this.disabled )
-				return;
-
-			if ( !forms )
-				return;
-
-			var i, form,
-				transfGroups = [],
-				preferredForm;
-
-			// First, find preferred form - this is, first allowed.
-			for ( i = 0; i < forms.length && !preferredForm; ++i ) {
-				form = forms[ i ];
-
-				// Check only strings and styles - array format isn't supported by #check().
-				if ( ( typeof form == 'string' || form instanceof CKEDITOR.style ) && this.check( form ) )
-					preferredForm = form;
-			}
-
-			// This feature doesn't have preferredForm, so ignore it.
-			if ( !preferredForm )
-				return;
-
-			for ( i = 0; i < forms.length; ++i )
-				transfGroups.push( getContentFormTransformationGroup( forms[ i ], preferredForm ) );
-
-			this.addTransformations( transfGroups );
-		},
-
-		/**
-		 * Checks whether a feature can be enabled for the HTML restrictions in place
-		 * for the current CKEditor instance, based on the HTML code the feature might
-		 * generate and the minimal HTML code the feature needs to be able to generate.
-		 *
-		 *		// TODO example
-		 *
-		 * @param {CKEDITOR.feature} feature
-		 * @returns {Boolean} Whether this feature can be enabled.
-		 */
-		addFeature: function( feature ) {
-			if ( this.disabled )
-				return true;
-
-			if ( !feature )
-				return true;
-
-			// Some features may want to register other features.
-			// E.g. a button may return a command bound to it.
-			if ( feature.toFeature )
-				feature = feature.toFeature( this.editor );
-
-			// If default configuration (will be checked inside #allow()),
-			// then add allowed content rules.
-			this.allow( feature.allowedContent, feature.name );
-
-			this.addTransformations( feature.contentTransformations );
-			this.addContentForms( feature.contentForms );
-
-			// If custom configuration, then check if required content is allowed.
-			if ( this.customConfig && feature.requiredContent )
-				return this.check( feature.requiredContent );
-
-			return true;
-		},
-
-		/**
-		 * Adds an array of content transformation groups. One group
-		 * may contain many transformation rules, but only the first
-		 * matching rule in a group is executed.
-		 *
-		 * A single transformation rule is an object with four properties:
-		 *
-		 *	* `check` (optional) &ndash; if set and {@link CKEDITOR.filter} does
-		 *		not accept this {@link CKEDITOR.filter.contentRule}, this transformation rule
-		 *		will not be executed (it does not *match*). This value is passed
-		 *		to {@link #check}.
-		 *	* `element` (optional) &ndash; this string property tells the filter on which
-		 *		element this transformation can be run. It is optional, because
-		 *		the element name can be obtained from `check` (if it is a String format)
-		 *		or `left` (if it is a {@link CKEDITOR.style} instance).
-		 *	* `left` (optional) &ndash; a function accepting an element or a {@link CKEDITOR.style}
-		 *		instance verifying whether the transformation should be
-		 *		executed on this specific element. If it returns `false` or if an element
-		 *		does not match this style, this transformation rule does not *match*.
-		 *	* `right` &ndash; a function accepting an element and {@link CKEDITOR.filter.transformationsTools}
-		 *		or a string containing the name of the {@link CKEDITOR.filter.transformationsTools} method
-		 *		that should be called on an element.
-		 *
-		 * A shorthand format is also available. A transformation rule can be defined by
-		 * a single string `'check:right'`. The string before `':'` will be used as
-		 * the `check` property and the second part as the `right` property.
-		 *
-		 * Transformation rules can be grouped. The filter will try to apply
-		 * the first rule in a group. If it *matches*, the filter will ignore subsequent rules and
-		 * will move to the next group. If it does not *match*, the next rule will be checked.
-		 *
-		 * Examples:
-		 *
-		 *		editor.filter.addTransformations( [
-		 *			// First group.
-		 *			[
-		 *				// First rule. If table{width} is allowed, it
-		 *				// executes {@link CKEDITOR.filter.transformationsTools#sizeToStyle} on a table element.
-		 *				'table{width}: sizeToStyle',
-		 *				// Second rule should not be executed if the first was.
-		 *				'table[width]: sizeToAttribute'
-		 *			],
-		 *			// Second group.
-		 *			[
-		 *				// This rule will add the foo="1" attribute to all images that
-		 *				// do not have it.
-		 *				{
-		 *					element: 'img',
-		 *					left: function( el ) {
-		 *						return !el.attributes.foo;
-		 *					},
-		 *					right: function( el, tools ) {
-		 *						el.attributes.foo = '1';
-		 *					}
-		 *				}
-		 *			]
-		 *		] );
-		 *
-		 *		// Case 1:
-		 *		// config.allowedContent = 'table{height,width}; tr td'.
-		 *		//
-		 *		// '<table style="height:100px; width:200px">...</table>'		-> '<table style="height:100px; width:200px">...</table>'
-		 *		// '<table height="100" width="200">...</table>'				-> '<table style="height:100px; width:200px">...</table>'
-		 *
-		 *		// Case 2:
-		 *		// config.allowedContent = 'table[height,width]; tr td'.
-		 *		//
-		 *		// '<table style="height:100px; width:200px">...</table>'		-> '<table height="100" width="200">...</table>'
-		 *		// '<table height="100" width="200">...</table>'				-> '<table height="100" width="200"">...</table>'
-		 *
-		 *		// Case 3:
-		 *		// config.allowedContent = 'table{width,height}[height,width]; tr td'.
-		 *		//
-		 *		// '<table style="height:100px; width:200px">...</table>'		-> '<table style="height:100px; width:200px">...</table>'
-		 *		// '<table height="100" width="200">...</table>'				-> '<table style="height:100px; width:200px">...</table>'
-		 *		//
-		 *		// Note: Both forms are allowed (size set by style and by attributes), but only
-		 *		// the first transformation is applied &mdash; the size is always transformed to a style.
-		 *		// This is because only the first transformation matching allowed content rules is applied.
-		 *
-		 * This method is used by the editor to add {@link CKEDITOR.feature#contentTransformations}
-		 * when adding a feature by {@link #addFeature} or {@link CKEDITOR.editor#addFeature}.
-		 *
-		 * @param {Array} transformations
-		 */
-		addTransformations: function( transformations ) {
-			if ( this.disabled )
-				return;
-
-			if ( !transformations )
-				return;
-
-			var optimized = this._.transformations,
-				group, i;
-
-			for ( i = 0; i < transformations.length; ++i ) {
-				group = optimizeTransformationsGroup( transformations[ i ] );
-
-				if ( !optimized[ group.name ] )
-					optimized[ group.name ] = [];
-
-				optimized[ group.name ].push( group.rules );
-			}
-		},
-
-		/**
-		 * Checks whether the content defined in the `test` argument is allowed
-		 * by this filter.
-		 *
-		 * If `strictCheck` is set to `false` (default value), this method checks
-		 * if all parts of the `test` (styles, attributes, and classes) are
-		 * accepted by the filter. If `strictCheck` is set to `true`, the test
-		 * must also contain the required attributes, styles, and classes.
-		 *
-		 * For example:
-		 *
-		 *		// Rule: 'img[!src,alt]'.
-		 *		filter.check( 'img[alt]' ); // -> true
-		 *		filter.check( 'img[alt]', true, true ); // -> false
-		 *
-		 * Second `check()` call returned `false` because `src` is required.
-		 *
-		 * @param {CKEDITOR.filter.contentRule} test
-		 * @param {Boolean} [applyTransformations=true] Whether to use registered transformations.
-		 * @param {Boolean} [strictCheck] Whether the filter should check if an element with exactly
-		 * these properties is allowed.
-		 * @returns {Boolean} Returns `true` if the content is allowed.
-		 */
-		check: function( test, applyTransformations, strictCheck ) {
-			if ( this.disabled )
-				return true;
-
-			// If rules are an array, expand it and return the logical OR value of
-			// the rules.
-			if ( CKEDITOR.tools.isArray( test ) ) {
-				for ( var i = test.length ; i-- ; ) {
-					if ( this.check( test[ i ], applyTransformations, strictCheck ) )
-						return true;
-				}
-				return false;
-			}
-
-			var element, result, cacheKey;
-
-			if ( typeof test == 'string' ) {
-				cacheKey = test + '<' + ( applyTransformations === false ? '0' : '1' ) + ( strictCheck ? '1' : '0' ) + '>';
-
-				// Check if result of this check hasn't been already cached.
-				if ( cacheKey in this._.cachedChecks )
-					return this._.cachedChecks[ cacheKey ];
-
-				// Create test element from string.
-				element = mockElementFromString( test );
-			} else
-				// Create test element from CKEDITOR.style.
-				element = mockElementFromStyle( test );
-
-			// Make a deep copy.
-			var clone = CKEDITOR.tools.clone( element ),
-				toBeRemoved = [],
-				transformations;
-
-			// Apply transformations to original element.
-			// Transformations will be applied to clone by the filter function.
-			if ( applyTransformations !== false && ( transformations = this._.transformations[ element.name ] ) ) {
-				for ( i = 0; i < transformations.length; ++i )
-					applyTransformationsGroup( this, element, transformations[ i ] );
-
-				// Transformations could modify styles or classes, so they need to be copied
-				// to attributes object.
-				updateAttributes( element );
-			}
-
-			// Filter clone of mocked element.
-			// Do not run transformations.
-			getFilterFunction( this )( clone, this._.rules, applyTransformations === false ? false : this._.transformations, toBeRemoved, false, !strictCheck, !strictCheck );
-
-			// Element has been marked for removal.
-			if ( toBeRemoved.length > 0 )
-				result = false;
-			// Compare only left to right, because clone may be only trimmed version of original element.
-			else if ( !CKEDITOR.tools.objectCompare( element.attributes, clone.attributes, true ) )
-				result = false;
-			else
-				result = true;
-
-			// Cache result of this test - we can build cache only for string tests.
-			if ( typeof test == 'string' )
-				this._.cachedChecks[ cacheKey ] = result;
-
-			return result;
-		},
-
-		/**
-		 * Returns first enter mode allowed by this filter rules. Modes are checked in `p`, `div`, `br` order.
-		 * If none of tags is allowed this method will return {@link CKEDITOR#ENTER_BR}.
-		 *
-		 * @since 4.3
-		 * @param {Number} defaultMode The default mode which will be checked as the first one.
-		 * @param {Boolean} [reverse] Whether to check modes in reverse order (used for shift enter mode).
-		 * @returns {Number} Allowed enter mode.
-		 */
-		getAllowedEnterMode: ( function() {
-			var tagsToCheck = [ 'p', 'div', 'br' ],
-				enterModes = {
-					p: CKEDITOR.ENTER_P,
-					div: CKEDITOR.ENTER_DIV,
-					br: CKEDITOR.ENTER_BR
-				};
-
-			return function( defaultMode, reverse ) {
-				// Clone the array first.
-				var tags = tagsToCheck.slice(),
-					tag;
-
-				// Check the default mode first.
-				if ( this.check( enterModeTags[ defaultMode ] ) )
-					return defaultMode;
-
-				// If not reverse order, reverse array so we can pop() from it.
-				if ( !reverse )
-					tags = tags.reverse();
-
-				while ( ( tag = tags.pop() ) ) {
-					if ( this.check( tag ) )
-						return enterModes[ tag ];
-				}
-
-				return CKEDITOR.ENTER_BR;
-			};
-		} )()
-	};
-
-	// Apply ACR to an element
-	// @param rule
-	// @param element
-	// @param status Object containing status of element's filtering.
-	// @param {Boolean} isSpecific True if this is specific element's rule, false if generic.
-	// @param {Boolean} skipRequired If true don't check if element has all required properties.
-	function applyRule( rule, element, status, isSpecific, skipRequired ) {
-		var name = element.name;
-
-		// This generic rule doesn't apply to this element - skip it.
-		if ( !isSpecific && typeof rule.elements == 'function' && !rule.elements( name ) )
-			return;
-
-		// This rule doesn't match this element - skip it.
-		if ( rule.match ) {
-			if ( !rule.match( element ) )
-				return;
-		}
-
-		// If element doesn't have all required styles/attrs/classes
-		// this rule doesn't match it.
-		if ( !skipRequired && !hasAllRequired( rule, element ) )
-			return;
-
-		// If this rule doesn't validate properties only mark element as valid.
-		if ( !rule.propertiesOnly )
-			status.valid = true;
-
-		// Apply rule only when all attrs/styles/classes haven't been marked as valid.
-		if ( !status.allAttributes )
-			status.allAttributes = applyRuleToHash( rule.attributes, element.attributes, status.validAttributes );
-
-		if ( !status.allStyles )
-			status.allStyles = applyRuleToHash( rule.styles, element.styles, status.validStyles );
-
-		if ( !status.allClasses )
-			status.allClasses = applyRuleToArray( rule.classes, element.classes, status.validClasses );
-	}
-
-	// Apply itemsRule to items (only classes are kept in array).
-	// Push accepted items to validItems array.
-	// Return true when all items are valid.
-	function applyRuleToArray( itemsRule, items, validItems ) {
-		if ( !itemsRule )
-			return false;
-
-		// True means that all elements of array are accepted (the asterix was used for classes).
-		if ( itemsRule === true )
-			return true;
-
-		for ( var i = 0, l = items.length, item; i < l; ++i ) {
-			item = items[ i ];
-			if ( !validItems[ item ] )
-				validItems[ item ] = itemsRule( item );
-		}
-
-		return false;
-	}
-
-	function applyRuleToHash( itemsRule, items, validItems ) {
-		if ( !itemsRule )
-			return false;
-
-		if ( itemsRule === true )
-			return true;
-
-		for ( var name in items ) {
-			if ( !validItems[ name ] )
-				validItems[ name ] = itemsRule( name, items[ name ] );
-		}
-
-		return false;
-	}
-
-	// Convert CKEDITOR.style to filter's rule.
-	function convertStyleToRules( style ) {
-		var styleDef = style.getDefinition(),
-			rules = {},
-			rule,
-			attrs = styleDef.attributes;
-
-		rules[ styleDef.element ] = rule = {
-			styles: styleDef.styles,
-			requiredStyles: styleDef.styles && CKEDITOR.tools.objectKeys( styleDef.styles )
-		};
-
-		if ( attrs ) {
-			attrs = copy( attrs );
-			rule.classes = attrs[ 'class' ] ? attrs[ 'class' ].split( /\s+/ ) : null;
-			rule.requiredClasses = rule.classes;
-			delete attrs[ 'class' ];
-			rule.attributes = attrs;
-			rule.requiredAttributes = attrs && CKEDITOR.tools.objectKeys( attrs );
-		}
-
-		return rules;
-	}
-
-	// Convert all validator formats (string, array, object, boolean) to hash or boolean:
-	// * true is returned for '*'/true validator,
-	// * false is returned for empty validator (no validator at all (false/null) or e.g. empty array),
-	// * object is returned in other cases.
-	function convertValidatorToHash( validator, delimiter ) {
-		if ( !validator )
-			return false;
-
-		if ( validator === true )
-			return validator;
-
-		if ( typeof validator == 'string' ) {
-			validator = trim( validator );
-			if ( validator == '*' )
-				return true;
-			else
-				return CKEDITOR.tools.convertArrayToObject( validator.split( delimiter ) );
-		}
-		else if ( CKEDITOR.tools.isArray( validator ) ) {
-			if ( validator.length )
-				return CKEDITOR.tools.convertArrayToObject( validator );
-			else
-				return false;
-		}
-		// If object.
-		else {
-			var obj = {},
-				len = 0;
-
-			for ( var i in validator ) {
-				obj[ i ] = validator[ i ];
-				len++;
-			}
-
-			return len ? obj : false;
-		}
-	}
-
-	// Extract required properties from "required" validator and "all" properties.
-	// Remove exclamation marks from "all" properties.
-	//
-	// E.g.:
-	// requiredClasses = { cl1: true }
-	// (all) classes = { cl1: true, cl2: true, '!cl3': true }
-	//
-	// result:
-	// returned = { cl1: true, cl3: true }
-	// all = { cl1: true, cl2: true, cl3: true }
-	//
-	// This function returns false if nothing is required.
-	function extractRequired( required, all ) {
-		var unbang = [],
-			empty = true,
-			i;
-
-		if ( required )
-			empty = false;
-		else
-			required = {};
-
-		for ( i in all ) {
-			if ( i.charAt( 0 ) == '!' ) {
-				i = i.slice( 1 );
-				unbang.push( i );
-				required[ i ] = true;
-				empty = false;
-			}
-		}
-
-		while ( ( i = unbang.pop() ) ) {
-			all[ i ] = all[ '!' + i ];
-			delete all[ '!' + i ];
-		}
-
-		return empty ? false : required;
-	}
-
-	// Filter element protected with a comment.
-	// Returns true if protected content is ok, false otherwise.
-	function filterProtectedElement( comment, protectedRegexs, filterFn, rules, transformations, toHtml ) {
-		var source = decodeURIComponent( comment.value.replace( /^\{cke_protected\}/, '' ) ),
-			protectedFrag,
-			toBeRemoved = [],
-			node, i, match;
-
-		// Protected element's and protected source's comments look exactly the same.
-		// Check if what we have isn't a protected source instead of protected script/noscript.
-		if ( protectedRegexs ) {
-			for ( i = 0; i < protectedRegexs.length; ++i ) {
-				if ( ( match = source.match( protectedRegexs[ i ] ) ) &&
-					match[ 0 ].length == source.length	// Check whether this pattern matches entire source
-														// to avoid '<script>alert("<? 1 ?>")</script>' matching
-														// the PHP's protectedSource regexp.
-				)
-					return true;
-			}
-		}
-
-		protectedFrag = CKEDITOR.htmlParser.fragment.fromHtml( source );
-
-		if ( protectedFrag.children.length == 1 && ( node = protectedFrag.children[ 0 ] ).type == CKEDITOR.NODE_ELEMENT )
-			filterFn( node, rules, transformations, toBeRemoved, toHtml );
-
-		// If protected element has been marked to be removed, return 'false' - comment was rejected.
-		return !toBeRemoved.length;
-	}
-
-	// Returns function that accepts {@link CKEDITOR.htmlParser.element}
-	// and filters it basing on allowed content rules registered by
-	// {@link #allow} method.
-	//
-	// @param {CKEDITOR.filter} that
-	function getFilterFunction( that ) {
-		// Return cached function.
-		if ( that._.filterFunction )
-			return that._.filterFunction;
-
-		var unprotectElementsNamesRegexp = /^cke:(object|embed|param)$/,
-			protectElementsNamesRegexp = /^(object|embed|param)$/;
-
-		// Return and cache created function.
-		// @param {CKEDITOR.htmlParser.element}
-		// @param [optimizedRules] Rules to be used.
-		// @param [transformations] Transformations to be applied.
-		// @param {Array} toBeRemoved Array into which elements rejected by the filter will be pushed.
-		// @param {Boolean} [toHtml] Set to true if filter used together with htmlDP#toHtml
-		// @param {Boolean} [skipRequired] Whether element's required properties shouldn't be verified.
-		// @param {Boolean} [skipFinalValidation] Whether to not perform final element validation (a,img).
-		// @returns {Boolean} Whether content has been modified.
-		return that._.filterFunction = function( element, optimizedRules, transformations, toBeRemoved, toHtml, skipRequired, skipFinalValidation ) {
-			var name = element.name,
-				i, l, trans,
-				isModified = false;
-
-			// Unprotect elements names previously protected by htmlDataProcessor
-			// (see protectElementNames and protectSelfClosingElements functions).
-			// Note: body, title, etc. are not protected by htmlDataP (or are protected and then unprotected).
-			if ( toHtml )
-				element.name = name = name.replace( unprotectElementsNamesRegexp, '$1' );
-
-			// If transformations are set apply all groups.
-			if ( ( transformations = transformations && transformations[ name ] ) ) {
-				populateProperties( element );
-
-				for ( i = 0; i < transformations.length; ++i )
-					applyTransformationsGroup( that, element, transformations[ i ] );
-
-				// Do not count on updateElement(), because it:
-				// * may not be called,
-				// * may skip some properties when all are marked as valid.
-				updateAttributes( element );
-			}
-
-			if ( optimizedRules ) {
-				// Name could be changed by transformations.
-				name = element.name;
-
-				var rules = optimizedRules.elements[ name ],
-					genericRules = optimizedRules.generic,
-					status = {
-						// Whether any of rules accepted element.
-						// If not - it will be stripped.
-						valid: false,
-						// Objects containing accepted attributes, classes and styles.
-						validAttributes: {},
-						validClasses: {},
-						validStyles: {},
-						// Whether all are valid.
-						// If we know that all element's attrs/classes/styles are valid
-						// we can skip their validation, to improve performance.
-						allAttributes: false,
-						allClasses: false,
-						allStyles: false
-					};
-
-				// Early return - if there are no rules for this element (specific or generic), remove it.
-				if ( !rules && !genericRules ) {
-					toBeRemoved.push( element );
-					return true;
-				}
-
-				// Could not be done yet if there were no transformations and if this
-				// is real (not mocked) object.
-				populateProperties( element );
-
-				if ( rules ) {
-					for ( i = 0, l = rules.length; i < l; ++i )
-						applyRule( rules[ i ], element, status, true, skipRequired );
-				}
-
-				if ( genericRules ) {
-					for ( i = 0, l = genericRules.length; i < l; ++i )
-						applyRule( genericRules[ i ], element, status, false, skipRequired );
-				}
-
-				// Finally, if after running all filter rules it still hasn't been allowed - remove it.
-				if ( !status.valid ) {
-					toBeRemoved.push( element );
-					return true;
-				}
-
-				// Update element's attributes based on status of filtering.
-				if ( updateElement( element, status ) )
-					isModified = true;
-
-				if ( !skipFinalValidation && !validateElement( element ) ) {
-					toBeRemoved.push( element );
-					return true;
-				}
-			}
-
-			// Protect previously unprotected elements.
-			if ( toHtml )
-				element.name = element.name.replace( protectElementsNamesRegexp, 'cke:$1' );
-
-			return isModified;
-		};
-	}
-
-	// Check whether element has all properties (styles,classes,attrs) required by a rule.
-	function hasAllRequired( rule, element ) {
-		if ( rule.nothingRequired )
-			return true;
-
-		var i, reqs, existing;
-
-		if ( ( reqs = rule.requiredClasses ) ) {
-			existing = element.classes;
-			for ( i = 0; i < reqs.length; ++i ) {
-				if ( CKEDITOR.tools.indexOf( existing, reqs[ i ] ) == -1 )
-					return false;
-			}
-		}
-
-		return hasAllRequiredInHash( element.styles, rule.requiredStyles ) &&
-			hasAllRequiredInHash( element.attributes, rule.requiredAttributes );
-	}
-
-	// Check whether all items in required (array) exist in existing (object).
-	function hasAllRequiredInHash( existing, required ) {
-		if ( !required )
-			return true;
-
-		for ( var i = 0; i < required.length; ++i ) {
-			if ( !( required[ i ] in existing ) )
-				return false;
-		}
-
-		return true;
-	}
-
-	// Create pseudo element that will be passed through filter
-	// to check if tested string is allowed.
-	function mockElementFromString( str ) {
-		var element = parseRulesString( str )[ '$1' ],
-			styles = element.styles,
-			classes = element.classes;
-
-		element.name = element.elements;
-		element.classes = classes = ( classes ? classes.split( /\s*,\s*/ ) : [] );
-		element.styles = mockHash( styles );
-		element.attributes = mockHash( element.attributes );
-		element.children = [];
-
-		if ( classes.length )
-			element.attributes[ 'class' ] = classes.join( ' ' );
-		if ( styles )
-			element.attributes.style = CKEDITOR.tools.writeCssText( element.styles );
-
-		return element;
-	}
-
-	// Create pseudo element that will be passed through filter
-	// to check if tested style is allowed.
-	function mockElementFromStyle( style ) {
-		var styleDef = style.getDefinition(),
-			styles = styleDef.styles,
-			attrs = styleDef.attributes || {};
-
-		if ( styles ) {
-			styles = copy( styles );
-			attrs.style = CKEDITOR.tools.writeCssText( styles, true );
-		} else
-			styles = {};
-
-		var el = {
-			name: styleDef.element,
-			attributes: attrs,
-			classes: attrs[ 'class' ] ? attrs[ 'class' ].split( /\s+/ ) : [],
-			styles: styles,
-			children: []
-		};
-
-		return el;
-	}
-
-	// Mock hash based on string.
-	// 'a,b,c' => { a: 'cke-test', b: 'cke-test', c: 'cke-test' }
-	// Used to mock styles and attributes objects.
-	function mockHash( str ) {
-		// It may be a null or empty string.
-		if ( !str )
-			return {};
-
-		var keys = str.split( /\s*,\s*/ ).sort(),
-			obj = {};
-
-		while ( keys.length )
-			obj[ keys.shift() ] = TEST_VALUE;
-
-		return obj;
-	}
-
-	var validators = { styles: 1, attributes: 1, classes: 1 },
-		validatorsRequired = {
-			styles: 'requiredStyles',
-			attributes: 'requiredAttributes',
-			classes: 'requiredClasses'
-		};
-
-	// Optimize a rule by replacing validators with functions
-	// and rewriting requiredXXX validators to arrays.
-	function optimizeRule( rule ) {
-		var i;
-		for ( i in validators )
-			rule[ i ] = validatorFunction( rule[ i ] );
-
-		var nothingRequired = true;
-		for ( i in validatorsRequired ) {
-			i = validatorsRequired[ i ];
-			rule[ i ] = CKEDITOR.tools.objectKeys( rule[ i ] );
-			if ( rule[ i ] )
-				nothingRequired = false;
-		}
-
-		rule.nothingRequired = nothingRequired;
-	}
-
-	// Add optimized version of rule to optimizedRules object.
-	function optimizeRules( optimizedRules, rules ) {
-		var elementsRules = optimizedRules.elements || {},
-			genericRules = optimizedRules.generic || [],
-			i, l, j, rule, element, priority;
-
-		for ( i = 0, l = rules.length; i < l; ++i ) {
-			// Shallow copy. Do not modify original rule.
-			rule = copy( rules[ i ] );
-			priority = rule.classes === true || rule.styles === true || rule.attributes === true;
-			optimizeRule( rule );
-
-			// E.g. "*(xxx)[xxx]" - it's a generic rule that
-			// validates properties only.
-			// Or '$1': { match: function() {...} }
-			if ( rule.elements === true || rule.elements === null ) {
-				rule.elements = validatorFunction( rule.elements );
-				// Add priority rules at the beginning.
-				genericRules[ priority ? 'unshift' : 'push' ]( rule );
-			}
-			// If elements list was explicitly defined,
-			// add this rule for every defined element.
-			else {
-				// We don't need elements validator for this kind of rule.
-				var elements = rule.elements;
-				delete rule.elements;
-
-				for ( element in elements ) {
-					if ( !elementsRules[ element ] )
-						elementsRules[ element ] = [ rule ];
-					else
-						elementsRules[ element ][ priority ? 'unshift' : 'push' ]( rule );
-				}
-			}
-		}
-
-		optimizedRules.elements = elementsRules;
-		optimizedRules.generic = genericRules.length ? genericRules : null;
-	}
-
-	//                  <   elements   ><                      styles, attributes and classes                       >< separator >
-	var rulePattern = /^([a-z0-9*\s]+)((?:\s*\{[!\w\-,\s\*]+\}\s*|\s*\[[!\w\-,\s\*]+\]\s*|\s*\([!\w\-,\s\*]+\)\s*){0,3})(?:;\s*|$)/i,
-		groupsPatterns = {
-			styles: /{([^}]+)}/,
-			attrs: /\[([^\]]+)\]/,
-			classes: /\(([^\)]+)\)/
-		};
-
-	function parseRulesString( input ) {
-		var match,
-			props, styles, attrs, classes,
-			rules = {},
-			groupNum = 1;
-
-		input = trim( input );
-
-		while ( ( match = input.match( rulePattern ) ) ) {
-			if ( ( props = match[ 2 ] ) ) {
-				styles = parseProperties( props, 'styles' );
-				attrs = parseProperties( props, 'attrs' );
-				classes = parseProperties( props, 'classes' );
-			} else
-				styles = attrs = classes = null;
-
-			// Add as an unnamed rule, because there can be two rules
-			// for one elements set defined in string format.
-			rules[ '$' + groupNum++ ] = {
-				elements: match[ 1 ],
-				classes: classes,
-				styles: styles,
-				attributes: attrs
-			};
-
-			// Move to the next group.
-			input = input.slice( match[ 0 ].length );
-		}
-
-		return rules;
-	}
-
-	// Extract specified properties group (styles, attrs, classes) from
-	// what stands after the elements list in string format of allowedContent.
-	function parseProperties( properties, groupName ) {
-		var group = properties.match( groupsPatterns[ groupName ] );
-		return group ? trim( group[ 1 ] ) : null;
-	}
-
-	function populateProperties( element ) {
-		// Parse classes and styles if that hasn't been done before.
-		if ( !element.styles )
-			element.styles = CKEDITOR.tools.parseCssText( element.attributes.style || '', 1 );
-		if ( !element.classes )
-			element.classes = element.attributes[ 'class' ] ? element.attributes[ 'class' ].split( /\s+/ ) : [];
-	}
-
-	// Standardize a rule by converting all validators to hashes.
-	function standardizeRule( rule ) {
-		rule.elements = convertValidatorToHash( rule.elements, /\s+/ ) || null;
-		rule.propertiesOnly = rule.propertiesOnly || ( rule.elements === true );
-
-		var delim = /\s*,\s*/,
-			i;
-
-		for ( i in validators ) {
-			rule[ i ] = convertValidatorToHash( rule[ i ], delim ) || null;
-			rule[ validatorsRequired[ i ] ] = extractRequired( convertValidatorToHash(
-				rule[ validatorsRequired[ i ] ], delim ), rule[ i ] ) || null;
-		}
-
-		rule.match = rule.match || null;
-	}
-
-	// Copy element's styles and classes back to attributes array.
-	function updateAttributes( element ) {
-		var attrs = element.attributes,
-			stylesArr = [],
-			name, styles;
-
-		// Will be recreated later if any of styles/classes exists.
-		delete attrs.style;
-		delete attrs[ 'class' ];
-
-		if ( ( styles = CKEDITOR.tools.writeCssText( element.styles, true ) ) )
-			attrs.style = styles;
-
-		if ( element.classes.length )
-			attrs[ 'class' ] = element.classes.sort().join( ' ' );
-	}
-
-	// Update element object based on status of filtering.
-	// @returns Whether element was modified.
-	function updateElement( element, status ) {
-		var validAttrs = status.validAttributes,
-			validStyles = status.validStyles,
-			validClasses = status.validClasses,
-			attrs = element.attributes,
-			styles = element.styles,
-			origClasses = attrs[ 'class' ],
-			origStyles = attrs.style,
-			name, origName,
-			stylesArr = [],
-			classesArr = [],
-			internalAttr = /^data-cke-/,
-			isModified = false;
-
-		// Will be recreated later if any of styles/classes were passed.
-		delete attrs.style;
-		delete attrs[ 'class' ];
-
-		if ( !status.allAttributes ) {
-			for ( name in attrs ) {
-				// If not valid and not internal attribute delete it.
-				if ( !validAttrs[ name ] ) {
-					// Allow all internal attibutes...
-					if ( internalAttr.test( name ) ) {
-						// ... unless this is a saved attribute and the original one isn't allowed.
-						if ( name != ( origName = name.replace( /^data-cke-saved-/, '' ) ) &&
-							!validAttrs[ origName ]
-						) {
-							delete attrs[ name ];
-							isModified = true;
-						}
-					} else {
-						delete attrs[ name ];
-						isModified = true;
-					}
-				}
-
-			}
-		}
-
-		if ( !status.allStyles ) {
-			for ( name in styles ) {
-				if ( validStyles[ name ] )
-					stylesArr.push( name + ':' + styles[ name ] );
-				else
-					isModified = true;
-			}
-			if ( stylesArr.length )
-				attrs.style = stylesArr.sort().join( '; ' );
-		}
-		else if ( origStyles )
-			attrs.style = origStyles;
-
-		if ( !status.allClasses ) {
-			for ( name in validClasses ) {
-				if ( validClasses[ name ] )
-					classesArr.push( name );
-			}
-			if ( classesArr.length )
-				attrs[ 'class' ] = classesArr.sort().join( ' ' );
-
-			if ( origClasses && classesArr.length < origClasses.split( /\s+/ ).length )
-				isModified = true;
-		}
-		else if ( origClasses )
-			attrs[ 'class' ] = origClasses;
-
-		return isModified;
-	}
-
-	function validateElement( element ) {
-		var attrs;
-
-		switch ( element.name ) {
-			case 'a':
-				// Code borrowed from htmlDataProcessor, so ACF does the same clean up.
-				if ( !( element.children.length || element.attributes.name ) )
-					return false;
-				break;
-			case 'img':
-				if ( !element.attributes.src )
-					return false;
-				break;
-		}
-
-		return true;
-	}
-
-	function validatorFunction( validator ) {
-		if ( !validator )
-			return false;
-		if ( validator === true )
-			return true;
-
-		return function( value ) {
-			return value in validator;
-		};
-	}
-
-	//
-	// REMOVE ELEMENT ---------------------------------------------------------
-	//
-
-	// Checks whether node is allowed by DTD.
-	function allowedIn( node, parentDtd ) {
-		if ( node.type == CKEDITOR.NODE_ELEMENT )
-			return parentDtd[ node.name ];
-		if ( node.type == CKEDITOR.NODE_TEXT )
-			return parentDtd[ '#' ];
-		return true;
-	}
-
-	// Check whether all children will be valid in new context.
-	// Note: it doesn't verify if text node is valid, because
-	// new parent should accept them.
-	function checkChildren( children, newParentName ) {
-		var allowed = DTD[ newParentName ];
-
-		for ( var i = 0, l = children.length, child; i < l; ++i ) {
-			child = children[ i ];
-			if ( child.type == CKEDITOR.NODE_ELEMENT && !allowed[ child.name ] )
-				return false;
-		}
-
-		return true;
-	}
-
-	function createBr() {
-		return new CKEDITOR.htmlParser.element( 'br' );
-	}
-
-	// Whether this is an inline element or text.
-	function inlineNode( node ) {
-		return node.type == CKEDITOR.NODE_TEXT ||
-			node.type == CKEDITOR.NODE_ELEMENT && DTD.$inline[ node.name ];
-	}
-
-	function isBrOrBlock( node ) {
-		return node.type == CKEDITOR.NODE_ELEMENT &&
-			( node.name == 'br' || DTD.$block[ node.name ] );
-	}
-
-	// Try to remove element in the best possible way.
-	//
-	// @param {Array} toBeChecked After executing this function
-	// this array will contain elements that should be checked
-	// because they were marked as potentially:
-	// * in wrong context (e.g. li in body),
-	// * empty elements from $removeEmpty,
-	// * incorrect img/a/other element validated by validateElement().
-	function removeElement( element, enterTag, toBeChecked ) {
-		var name = element.name;
-
-		if ( DTD.$empty[ name ] || !element.children.length ) {
-			// Special case - hr in br mode should be replaced with br, not removed.
-			if ( name == 'hr' && enterTag == 'br' )
-				element.replaceWith( createBr() );
-			else {
-				// Parent might become an empty inline specified in $removeEmpty or empty a[href].
-				if ( element.parent )
-					toBeChecked.push( { check: 'it', el: element.parent } );
-
-				element.remove();
-			}
-		} else if ( DTD.$block[ name ] || name == 'tr' ) {
-			if ( enterTag == 'br' )
-				stripBlockBr( element, toBeChecked );
-			else
-				stripBlock( element, enterTag, toBeChecked );
-		}
-		// Special case - elements that may contain CDATA
-		// should be removed completely. <script> is handled
-		// by filterProtectedElement().
-		else if ( name == 'style' )
-			element.remove();
-		// The rest of inline elements. May also be the last resort
-		// for some special elements.
-		else {
-			// Parent might become an empty inline specified in $removeEmpty or empty a[href].
-			if ( element.parent )
-				toBeChecked.push( { check: 'it', el: element.parent } );
-			element.replaceWithChildren();
-		}
-	}
-
-	// Strip element block, but leave its content.
-	// Works in 'div' and 'p' enter modes.
-	function stripBlock( element, enterTag, toBeChecked ) {
-		var children = element.children;
-
-		// First, check if element's children may be wrapped with <p/div>.
-		// Ignore that <p/div> may not be allowed in element.parent.
-		// This will be fixed when removing parent or by toBeChecked rule.
-		if ( checkChildren( children, enterTag ) ) {
-			element.name = enterTag;
-			element.attributes = {};
-			// Check if this p/div was put in correct context.
-			// If not - strip parent.
-			toBeChecked.push( { check: 'parent-down', el: element } );
-			return;
-		}
-
-		var parent = element.parent,
-			shouldAutoP = parent.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT || parent.name == 'body',
-			i, j, child, p, node,
-			toBeRemoved = [];
-
-		for ( i = children.length; i > 0; ) {
-			child = children[ --i ];
-
-			// If parent requires auto paragraphing and child is inline node,
-			// insert this child into newly created paragraph.
-			if ( shouldAutoP && inlineNode( child )  ) {
-				if ( !p ) {
-					p = new CKEDITOR.htmlParser.element( enterTag );
-					p.insertAfter( element );
-
-					// Check if this p/div was put in correct context.
-					// If not - strip parent.
-					toBeChecked.push( { check: 'parent-down', el: p } );
-				}
-				p.add( child, 0 );
-			}
-			// Child which doesn't need to be auto paragraphed.
-			else {
-				p = null;
-				child.insertAfter( element );
-				// If inserted into invalid context, mark it and check
-				// after removing all elements.
-				if ( parent.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT &&
-					child.type == CKEDITOR.NODE_ELEMENT &&
-					!DTD[ parent.name ][ child.name ]
-				)
-					toBeChecked.push( { check: 'el-up', el: child } );
-			}
-		}
-
-		// All children have been moved to element's parent, so remove it.
-		element.remove();
-	}
-
-	// Prepend/append block with <br> if isn't
-	// already prepended/appended with <br> or block and
-	// isn't first/last child of its parent.
-	// Then replace element with its children.
-	// <p>a</p><p>b</p> => <p>a</p><br>b => a<br>b
-	function stripBlockBr( element, toBeChecked ) {
-		var br;
-
-		if ( element.previous && !isBrOrBlock( element.previous ) ) {
-			br = createBr();
-			br.insertBefore( element );
-		}
-
-		if ( element.next && !isBrOrBlock( element.next ) ) {
-			br = createBr();
-			br.insertAfter( element );
-		}
-
-		element.replaceWithChildren();
-	}
-
-	//
-	// TRANSFORMATIONS --------------------------------------------------------
-	//
-
-	// Apply given transformations group to the element.
-	function applyTransformationsGroup( filter, element, group ) {
-		var i, rule;
-
-		for ( i = 0; i < group.length; ++i ) {
-			rule = group[ i ];
-
-			// Test with #check or #left only if it's set.
-			// Do not apply transformations because that creates infinite loop.
-			if ( ( !rule.check || filter.check( rule.check, false ) ) &&
-				( !rule.left || rule.left( element ) ) ) {
-				rule.right( element, transformationsTools );
-				return; // Only first matching rule in a group is executed.
-			}
-		}
-	}
-
-	// Check whether element matches CKEDITOR.style.
-	// The element can be a "superset" of style,
-	// e.g. it may have more classes, but need to have
-	// at least those defined in style.
-	function elementMatchesStyle( element, style ) {
-		var def = style.getDefinition(),
-			defAttrs = def.attributes,
-			defStyles = def.styles,
-			attrName, styleName,
-			classes, classPattern, cl;
-
-		if ( element.name != def.element )
-			return false;
-
-		for ( attrName in defAttrs ) {
-			if ( attrName == 'class' ) {
-				classes = defAttrs[ attrName ].split( /\s+/ );
-				classPattern = element.classes.join( '|' );
-				while ( ( cl = classes.pop() ) ) {
-					if ( classPattern.indexOf( cl ) == -1 )
-						return false;
-				}
-			} else {
-				if ( element.attributes[ attrName ] != defAttrs[ attrName ] )
-					return false;
-			}
-		}
-
-		for ( styleName in defStyles ) {
-			if ( element.styles[ styleName ] != defStyles[ styleName ] )
-				return false;
-		}
-
-		return true;
-	}
-
-	// Return transformation group for content form.
-	// One content form makes one transformation rule in one group.
-	function getContentFormTransformationGroup( form, preferredForm ) {
-		var element, left;
-
-		if ( typeof form == 'string' )
-			element = form;
-		else if ( form instanceof CKEDITOR.style )
-			left = form;
-		else {
-			element = form[ 0 ];
-			left = form[ 1 ];
-		}
-
-		return [ {
-			element: element,
-			left: left,
-			right: function( el, tools ) {
-				tools.transform( el, preferredForm );
-			}
-		} ];
-	}
-
-	// Obtain element's name from transformation rule.
-	// It will be defined by #element, or #check or #left (styleDef.element).
-	function getElementNameForTransformation( rule, check ) {
-		if ( rule.element )
-			return rule.element;
-		if ( check )
-			return check.match( /^([a-z0-9]+)/i )[ 0 ];
-		return rule.left.getDefinition().element;
-	}
-
-	function getMatchStyleFn( style ) {
-		return function( el ) {
-			return elementMatchesStyle( el, style );
-		};
-	}
-
-	function getTransformationFn( toolName ) {
-		return function( el, tools ) {
-			tools[ toolName ]( el );
-		};
-	}
-
-	function optimizeTransformationsGroup( rules ) {
-		var groupName, i, rule,
-			check, left, right,
-			optimizedRules = [];
-
-		for ( i = 0; i < rules.length; ++i ) {
-			rule = rules[ i ];
-
-			if ( typeof rule == 'string' ) {
-				rule = rule.split( /\s*:\s*/ );
-				check = rule[ 0 ];
-				left = null;
-				right = rule[ 1 ];
-			} else {
-				check = rule.check;
-				left = rule.left;
-				right = rule.right;
-			}
-
-			// Extract element name.
-			if ( !groupName )
-				groupName = getElementNameForTransformation( rule, check );
-
-			if ( left instanceof CKEDITOR.style )
-				left = getMatchStyleFn( left );
-
-			optimizedRules.push( {
-				// It doesn't make sense to test against name rule (e.g. 'table'), so don't save it.
-				check: check == groupName ? null : check,
-
-				left: left,
-
-				// Handle shorthand format. E.g.: 'table[width]:sizeToAttribute'.
-				right: typeof right == 'string' ? getTransformationFn( right ) : right
-			} );
-		}
-
-		return {
-			name: groupName,
-			rules: optimizedRules
-		};
-	}
-
-	/**
-	 * Singleton containing tools useful for transformation rules.
-	 *
-	 * @class CKEDITOR.filter.transformationsTools
-	 * @singleton
-	 */
-	var transformationsTools = CKEDITOR.filter.transformationsTools = {
-		/**
-		 * Converts `width` and `height` attributes to styles.
-		 *
-		 * @param {CKEDITOR.htmlParser.element} element
-		 */
-		sizeToStyle: function( element ) {
-			this.lengthToStyle( element, 'width' );
-			this.lengthToStyle( element, 'height' );
-		},
-
-		/**
-		 * Converts `width` and `height` styles to attributes.
-		 *
-		 * @param {CKEDITOR.htmlParser.element} element
-		 */
-		sizeToAttribute: function( element ) {
-			this.lengthToAttribute( element, 'width' );
-			this.lengthToAttribute( element, 'height' );
-		},
-
-		/**
-		 * Converts length in the `attrName` attribute to a valid CSS length (like `width` or `height`).
-		 *
-		 * @param {CKEDITOR.htmlParser.element} element
-		 * @param {String} attrName Name of the attribute that will be converted.
-		 * @param {String} [styleName=attrName] Name of the style into which the attribute will be converted.
-		 */
-		lengthToStyle: function( element, attrName, styleName ) {
-			styleName = styleName || attrName;
-
-			if ( !( styleName in element.styles ) ) {
-				var value = element.attributes[ attrName ];
-
-				if ( value ) {
-					if ( ( /^\d+$/ ).test( value ) )
-						value += 'px';
-
-					element.styles[ styleName ] = value;
-				}
-			}
-
-			delete element.attributes[ attrName ];
-		},
-
-		/**
-		 * Converts length in the `styleName` style to a valid length attribute (like `width` or `height`).
-		 *
-		 * @param {CKEDITOR.htmlParser.element} element
-		 * @param {String} styleName Name of the style that will be converted.
-		 * @param {String} [attrName=styleName] Name of the attribute into which the style will be converted.
-		 */
-		lengthToAttribute: function( element, styleName, attrName ) {
-			attrName = attrName || styleName;
-
-			if ( !( attrName in element.attributes ) ) {
-				var value = element.styles[ styleName ],
-					match = value && value.match( /^(\d+)(?:\.\d*)?px$/ );
-
-				if ( match )
-					element.attributes[ attrName ] = match[ 1 ];
-				// Pass the TEST_VALUE used by filter#check when mocking element.
-				else if ( value == TEST_VALUE )
-					element.attributes[ attrName ] = TEST_VALUE;
-			}
-
-			delete element.styles[ styleName ];
-		},
-
-		/**
-		 * Converts the `align` attribute to the `float` style if not set. Attribute
-		 * is always removed.
-		 *
-		 * @param {CKEDITOR.htmlParser.element} element
-		 */
-		alignmentToStyle: function( element ) {
-			if ( !( 'float' in element.styles ) ) {
-				var value = element.attributes.align;
-
-				if ( value == 'left' || value == 'right' )
-					element.styles[ 'float' ] = value; // Uh... GCC doesn't like the 'float' prop name.
-			}
-
-			delete element.attributes.align;
-		},
-
-		/**
-		 * Converts the `float` style to the `align` attribute if not set.
-		 * Style is always removed.
-		 *
-		 * @param {CKEDITOR.htmlParser.element} element
-		 */
-		alignmentToAttribute: function( element ) {
-			if ( !( 'align' in element.attributes ) ) {
-				var value = element.styles[ 'float' ];
-
-				if ( value == 'left' || value == 'right' )
-					element.attributes.align = value;
-			}
-
-			delete element.styles[ 'float' ]; // Uh... GCC doesn't like the 'float' prop name.
-		},
-
-		/**
-		 * Checks whether an element matches a given {@link CKEDITOR.style}.
-		 * The element can be a "superset" of a style, e.g. it may have
-		 * more classes, but needs to have at least those defined in the style.
-		 *
-		 * @param {CKEDITOR.htmlParser.element} element
-		 * @param {CKEDITOR.style} style
-		 */
-		matchesStyle: elementMatchesStyle,
-
-		/**
-		 * Transforms element to given form.
-		 *
-		 * Form may be a:
-		 *
-		 *	* {@link CKEDITOR.style},
-		 *	* string &ndash; the new name of an element.
-		 *
-		 * @param {CKEDITOR.htmlParser.element} el
-		 * @param {CKEDITOR.style/String} form
-		 */
-		transform: function( el, form ) {
-			if ( typeof form == 'string' )
-				el.name = form;
-			// Form is an instance of CKEDITOR.style.
-			else {
-				var def = form.getDefinition(),
-					defStyles = def.styles,
-					defAttrs = def.attributes,
-					attrName, styleName,
-					existingClassesPattern, defClasses, cl;
-
-				el.name = def.element;
-
-				for ( attrName in defAttrs ) {
-					if ( attrName == 'class' ) {
-						existingClassesPattern = el.classes.join( '|' );
-						defClasses = defAttrs[ attrName ].split( /\s+/ );
-
-						while ( ( cl = defClasses.pop() ) ) {
-							if ( existingClassesPattern.indexOf( cl ) == -1 )
-								el.classes.push( cl );
-						}
-					} else
-						el.attributes[ attrName ] = defAttrs[ attrName ];
-
-				}
-
-				for ( styleName in defStyles ) {
-					el.styles[ styleName ] = defStyles[ styleName ];
-				}
-			}
-		}
-	};
-
-} )();
-
-/**
- * Allowed content rules. This setting is used when
- * instantiating {@link CKEDITOR.editor#filter}.
- *
- * The following values are accepted:
- *
- *	* {@link CKEDITOR.filter.allowedContentRules} &ndash; defined rules will be added
- *	to the {@link CKEDITOR.editor#filter}.
- *	* `true` &ndash; will disable the filter (data will not be filtered,
- *	all features will be activated).
- *	* default &ndash; the filter will be configured by loaded features
- *	(toolbar items, commands, etc.).
- *
- * In all cases filter configuration may be extended by
- * {@link CKEDITOR.config#extraAllowedContent}. This option may be especially
- * useful when you want to use the default `allowedContent` value
- * along with some additional rules.
- *
- *		CKEDITOR.replace( 'textarea_id', {
- *			allowedContent: 'p b i; a[!href]',
- *			on: {
- *				instanceReady: function( evt ) {
- *					var editor = evt.editor;
- *
- *					editor.filter.check( 'h1' ); // -> false
- *					editor.setData( '<h1><i>Foo</i></h1><p class="left"><span>Bar</span> <a href="http://foo.bar">foo</a></p>' );
- *					// Editor contents will be:
- *					'<p><i>Foo</i></p><p>Bar <a href="http://foo.bar">foo</a></p>'
- *				}
- *			}
- *		} );
- *
- * @since 4.1
- * @cfg {CKEDITOR.filter.allowedContentRules/Boolean} [allowedContent=null]
- * @member CKEDITOR.config
- */
-
-/**
- * This option makes it possible to set additional allowed
- * content rules for {@link CKEDITOR.editor#filter}.
- *
- * It is especially useful in combination with the default
- * {@link CKEDITOR.config#allowedContent} value:
- *
- *		CKEDITOR.replace( 'textarea_id', {
- *			plugins: 'wysiwygarea,toolbar,format',
- *			extraAllowedContent: 'b i',
- *			on: {
- *				instanceReady: function( evt ) {
- *					var editor = evt.editor;
- *
- *					editor.filter.check( 'h1' ); // -> true (thanks to Format combo)
- *					editor.filter.check( 'b' ); // -> true (thanks to extraAllowedContent)
- *					editor.setData( '<h1><i>Foo</i></h1><p class="left"><b>Bar</b> <a href="http://foo.bar">foo</a></p>' );
- *					// Editor contents will be:
- *					'<h1><i>Foo</i></h1><p><b>Bar</b> foo</p>'
- *				}
- *			}
- *		} );
- *
- * See {@link CKEDITOR.config#allowedContent} for more details.
- *
- * @since 4.1
- * @cfg {Object/String} extraAllowedContent
- * @member CKEDITOR.config
- */
-
-/**
- * This event is fired when {@link CKEDITOR.filter} has stripped some
- * content from the data that was loaded (e.g. by {@link CKEDITOR.editor#method-setData}
- * method or in the source mode) or inserted (e.g. when pasting or using the
- * {@link CKEDITOR.editor#method-insertHtml} method).
- *
- * This event is useful when testing whether the {@link CKEDITOR.config#allowedContent}
- * setting is sufficient and correct for a system that is migrating to CKEditor 4.1
- * (where the [Advanced Content Filter](#!/guide/dev_advanced_content_filter) was introduced).
- *
- * @since 4.1
- * @event dataFiltered
- * @member CKEDITOR.editor
- * @param {CKEDITOR.editor} editor This editor instance.
- */
-
-/**
- * Virtual class which is the [Allowed Content Rules](#!/guide/dev_allowed_content_rules) formats type.
- *
- * Possible formats are:
- *
- *	* the [string format](#!/guide/dev_allowed_content_rules-section-2),
- *	* the [object format](#!/guide/dev_allowed_content_rules-section-3),
- *	* a {@link CKEDITOR.style} instance &ndash; used mainly for integrating plugins with Advanced Content Filter,
- *	* an array of the above formats.
- *
- * @since 4.1
- * @class CKEDITOR.filter.allowedContentRules
- * @abstract
- */
-
-/**
- * Virtual class representing {@link CKEDITOR.filter#check} argument.
- *
- * This is a simplified version of the {@link CKEDITOR.filter.allowedContentRules} type.
- * It may contain only one element and its styles, classes, and attributes. Only the
- * string format and a {@link CKEDITOR.style} instances are accepted.
- *
- * @since 4.1
- * @class CKEDITOR.filter.contentRule
- * @abstract
- */
-
-/**
- * Interface that may be automatically implemented by any
- * instance of any class which has at least the `name` property and
- * can be meant as an editor feature.
- *
- * For example:
- *
- *	* "Bold" command, button, and keystroke &ndash; it does not mean exactly
- * `<strong>` or `<b>` but just the ability to create bold text.
- *	* "Format" drop-down list &ndash; it also does not imply any HTML tag.
- *	* "Link" command, button, and keystroke.
- *	* "Image" command, button, and dialog window.
- *
- * Thus most often a feature is an instance of one of the following classes:
- *
- *	* {@link CKEDITOR.command}
- *	* {@link CKEDITOR.ui.button}
- *	* {@link CKEDITOR.ui.richCombo}
- *
- * None of them have a `name` property explicitly defined, but
- * it is set by {@link CKEDITOR.editor#addCommand} and {@link CKEDITOR.ui#add}.
- *
- * During editor initialization all features that the editor should activate
- * should be passed to {@link CKEDITOR.editor#addFeature} (shorthand for {@link CKEDITOR.filter#addFeature}).
- *
- * This method checks if a feature can be activated (see {@link #requiredContent}) and if yes,
- * then it registers allowed content rules required by this feature (see {@link #allowedContent}) along
- * with two kinds of transformations: {@link #contentForms} and {@link #contentTransformations}.
- *
- * By default all buttons that are included in [toolbar layout configuration](#!/guide/dev_toolbar)
- * are checked and registered with {@link CKEDITOR.editor#addFeature}, all styles available in the
- * 'Format' and 'Styles' drop-down lists are checked and registered too and so on.
- *
- * @since 4.1
- * @class CKEDITOR.feature
- * @abstract
- */
-
-/**
- * HTML code that can be generated by this feature.
- *
- * For example a basic image feature (image button displaying the image dialog window)
- * may allow `'img[!src,alt,width,height]'`.
- *
- * During the feature activation this value is passed to {@link CKEDITOR.filter#allow}.
- *
- * @property {CKEDITOR.filter.allowedContentRules} [allowedContent=null]
- */
-
-/**
- * Minimal HTML code that this feature must be allowed to
- * generate in order to work.
- *
- * For example a basic image feature (image button displaying the image dialog window)
- * needs `'img[src,alt]'` in order to be activated.
- *
- * During the feature validation this value is passed to {@link CKEDITOR.filter#check}.
- *
- * If this value is not provided, a feature will be always activated.
- *
- * @property {CKEDITOR.filter.contentRule} [requiredContent=null]
- */
-
-/**
- * The name of the feature.
- *
- * It is used for example to identify which {@link CKEDITOR.filter#allowedContent}
- * rule was added for which feature.
- *
- * @property {String} name
- */
-
-/**
- * Feature content forms to be registered in the {@link CKEDITOR.editor#filter}
- * during the feature activation.
- *
- * See {@link CKEDITOR.filter#addContentForms} for more details.
- *
- * @property [contentForms=null]
- */
-
-/**
- * Transformations (usually for content generated by this feature, but not necessarily)
- * that will be registered in the {@link CKEDITOR.editor#filter} during the feature activation.
- *
- * See {@link CKEDITOR.filter#addTransformations} for more details.
- *
- * @property [contentTransformations=null]
- */
-
-/**
- * Returns a feature that this feature needs to register.
- *
- * In some cases, during activation, one feature may need to register
- * another feature. For example a {@link CKEDITOR.ui.button} often registers
- * a related command. See {@link CKEDITOR.ui.button#toFeature}.
- *
- * This method is executed when a feature is passed to the {@link CKEDITOR.editor#addFeature}.
- *
- * @method toFeature
- * @returns {CKEDITOR.feature}
- */

+ 0 - 271
htdocs/includes/ckeditor/ckeditor/_source/core/focusmanager.js

@@ -1,271 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.focusManager} class, which is used
- *		to handle the focus on editor instances..
- */
-
-( function() {
-	/**
-	 * Manages the focus activity in an editor instance. This class is to be
-	 * used mainly by UI elements coders when adding interface elements that need
-	 * to set the focus state of the editor.
-	 *
-	 *		var focusManager = new CKEDITOR.focusManager( editor );
-	 *		focusManager.focus();
-	 *
-	 * @class
-	 * @constructor Creates a focusManager class instance.
-	 * @param {CKEDITOR.editor} editor The editor instance.
-	 */
-	CKEDITOR.focusManager = function( editor ) {
-		if ( editor.focusManager )
-			return editor.focusManager;
-
-		/**
-		 * Indicates that the editor instance has focus.
-		 *
-		 *		alert( CKEDITOR.instances.editor1.focusManager.hasFocus ); // e.g. true
-		 */
-		this.hasFocus = false;
-
-		/**
-		 * Indicate the currently focused DOM element that makes the editor activated.
-		 *
-		 * @property {CKEDITOR.dom.domObject}
-		 */
-		this.currentActive = null;
-
-		/**
-		 * Object used to hold private stuff.
-		 *
-		 * @private
-		 */
-		this._ = {
-			editor: editor
-		};
-
-		return this;
-	};
-
-	var SLOT_NAME = 'focusmanager',
-		SLOT_NAME_LISTENERS = 'focusmanager_handlers';
-
-	/**
-	 * Object used to hold private stuff.
-	 *
-	 * @private
-	 * @class
-	 * @singleton
-	 */
-	CKEDITOR.focusManager._ = {
-		/**
-		 * The delay (in milliseconds) to deactivate the editor when UI dom element has lost focus.
-		 *
-		 * @private
-		 * @property {Number} [blurDelay=200]
-		 * @member CKEDITOR.focusManager._
-		 */
-		blurDelay: 200
-	};
-
-	CKEDITOR.focusManager.prototype = {
-
-		/**
-		 * Indicate this editor instance is activated (due to DOM focus change),
-		 * the `activated` state is a symbolic indicator of an active user
-		 * interaction session.
-		 *
-		 * **Note:** This method will not introduce UI focus
-		 * impact on DOM, it's here to record editor UI focus state internally.
-		 * If you want to make the cursor blink inside of the editable, use
-		 * {@link CKEDITOR.editor#method-focus} instead.
-		 *
-		 *		var editor = CKEDITOR.instances.editor1;
-		 *		editor.focusManage.focus( editor.editable() );
-		 *
-		 * @param {CKEDITOR.dom.element} [currentActive] The new value of {@link #currentActive} property.
-		 * @member CKEDITOR.focusManager
-		 */
-		focus: function( currentActive ) {
-			if ( this._.timer )
-				clearTimeout( this._.timer );
-
-			if ( currentActive )
-				this.currentActive = currentActive;
-
-			if ( !( this.hasFocus || this._.locked ) ) {
-				// If another editor has the current focus, we first "blur" it. In
-				// this way the events happen in a more logical sequence, like:
-				//		"focus 1" > "blur 1" > "focus 2"
-				// ... instead of:
-				//		"focus 1" > "focus 2" > "blur 1"
-				var current = CKEDITOR.currentInstance;
-				current && current.focusManager.blur( 1 );
-
-				this.hasFocus = true;
-
-				var ct = this._.editor.container;
-				ct && ct.addClass( 'cke_focus' );
-				this._.editor.fire( 'focus' );
-			}
-		},
-
-		/**
-		 * Prevent from changing the focus manager state until next {@link #unlock} is called.
-		 *
-		 * @member CKEDITOR.focusManager
-		 */
-		lock: function() {
-			this._.locked = 1;
-		},
-
-		/**
-		 * Restore the automatic focus management, if {@link #lock} is called.
-		 *
-		 * @member CKEDITOR.focusManager
-		 */
-		unlock: function() {
-			delete this._.locked;
-		},
-
-		/**
-		 * Used to indicate that the editor instance has been deactivated by the specified
-		 * element which has just lost focus.
-		 *
-		 * **Note:** that this functions acts asynchronously with a delay of 100ms to
-		 * avoid temporary deactivation. Use instead the `noDelay` parameter
-		 * to deactivate immediately.
-		 *
-		 *		var editor = CKEDITOR.instances.editor1;
-		 *		editor.focusManager.blur();
-		 *
-		 * @param {Boolean} [noDelay=false] Deactivate immediately the editor instance synchronously.
-		 * @member CKEDITOR.focusManager
-		 */
-		blur: function( noDelay ) {
-			if ( this._.locked )
-				return;
-
-			function doBlur() {
-				if ( this.hasFocus ) {
-					this.hasFocus = false;
-
-					var ct = this._.editor.container;
-					ct && ct.removeClass( 'cke_focus' );
-					this._.editor.fire( 'blur' );
-				}
-			}
-
-			if ( this._.timer )
-				clearTimeout( this._.timer );
-
-			var delay = CKEDITOR.focusManager._.blurDelay;
-			if ( noDelay || !delay )
-				doBlur.call( this );
-			else {
-				this._.timer = CKEDITOR.tools.setTimeout( function() {
-					delete this._.timer;
-					doBlur.call( this );
-				}, delay, this );
-			}
-		},
-
-		/**
-		 * Register an UI DOM element to the focus manager, which will make the focus manager "hasFocus"
-		 * once input focus is relieved on the element, it's to be used by plugins to expand the jurisdiction of the editor focus.
-		 *
-		 * @param {CKEDITOR.dom.element} element The container (top most) element of one UI part.
-		 * @param {Boolean} isCapture If specified {@link CKEDITOR.event#useCapture} will be used when listening to the focus event.
-		 * @member CKEDITOR.focusManager
-		 */
-		add: function( element, isCapture ) {
-			var fm = element.getCustomData( SLOT_NAME );
-			if ( !fm || fm != this ) {
-				// If this element is already taken by another instance, dismiss it first.
-				fm && fm.remove( element );
-
-				var focusEvent = 'focus',
-					blurEvent = 'blur';
-
-				// Bypass the element's internal DOM focus change.
-				if ( isCapture ) {
-
-					// Use "focusin/focusout" events instead of capture phase in IEs,
-					// which fires synchronously.
-					if ( CKEDITOR.env.ie ) {
-						focusEvent = 'focusin';
-						blurEvent = 'focusout';
-					} else
-						CKEDITOR.event.useCapture = 1;
-				}
-
-				var listeners = {
-					blur: function() {
-						if ( element.equals( this.currentActive ) )
-							this.blur();
-					},
-					focus: function() {
-						this.focus( element );
-					}
-				};
-
-				element.on( focusEvent, listeners.focus, this );
-				element.on( blurEvent, listeners.blur, this );
-
-				if ( isCapture )
-					CKEDITOR.event.useCapture = 0;
-
-				element.setCustomData( SLOT_NAME, this );
-				element.setCustomData( SLOT_NAME_LISTENERS, listeners );
-			}
-		},
-
-		/**
-		 * Dismiss an element from the the focus manager delegations added by {@link #add}.
-		 *
-		 * @param {CKEDITOR.dom.element} element The element to be removed from the focusmanager.
-		 * @member CKEDITOR.focusManager
-		 */
-		remove: function( element ) {
-			element.removeCustomData( SLOT_NAME );
-			var listeners = element.removeCustomData( SLOT_NAME_LISTENERS );
-			element.removeListener( 'blur', listeners.blur );
-			element.removeListener( 'focus', listeners.focus );
-		}
-
-	};
-
-} )();
-
-/**
- * Fired when the editor instance receives the input focus.
- *
- *		editor.on( 'focus', function( e ) {
- *			alert( 'The editor named ' + e.editor.name + ' is now focused' );
- *		} );
- *
- * @event focus
- * @member CKEDITOR.editor
- * @param {CKEDITOR.editor} editor The editor instance.
- */
-
-/**
- * Fired when the editor instance loses the input focus.
- *
- * **Note:** This event will **NOT** be triggered when focus is moved internally, e.g. from
- * the editable to other part of the editor UI like dialog.
- * If you're interested on only the editable focus state listen to the {@link CKEDITOR.editable#event-focus}
- * and {@link CKEDITOR.editable#blur} events instead.
- *
- *		editor.on( 'blur', function( e ) {
- *			alert( 'The editor named ' + e.editor.name + ' lost the focus' );
- *		} );
- *
- * @event blur
- * @member CKEDITOR.editor
- * @param {CKEDITOR.editor} editor The editor instance.
- */

+ 0 - 989
htdocs/includes/ckeditor/ckeditor/_source/core/htmldataprocessor.js

@@ -1,989 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-( function() {
-	/**
-	 * Represents an HTML data processor, which is responsible for translating and
-	 * transforming the editor data on input and output.
-	 *
-	 * @class
-	 * @extends CKEDITOR.dataProcessor
-	 * @constructor Creates an htmlDataProcessor class instance.
-	 * @param {CKEDITOR.editor} editor
-	 */
-	CKEDITOR.htmlDataProcessor = function( editor ) {
-		var dataFilter, htmlFilter,
-			that = this;
-
-		this.editor = editor;
-
-		/**
-		 * Data filter used when processing input by {@link #toHtml}.
-		 *
-		 * @property {CKEDITOR.htmlParser.filter}
-		 */
-		this.dataFilter = dataFilter = new CKEDITOR.htmlParser.filter();
-
-		/**
-		 * HTML filter used when processing output by {@link #toDataFormat}.
-		 *
-		 * @property {CKEDITOR.htmlParser.filter}
-		 */
-		this.htmlFilter = htmlFilter = new CKEDITOR.htmlParser.filter();
-
-		/**
-		 * The HTML writer used by this data processor to format the output.
-		 *
-		 * @property {CKEDITOR.htmlParser.basicWriter}
-		 */
-		this.writer = new CKEDITOR.htmlParser.basicWriter();
-
-		dataFilter.addRules( defaultDataFilterRulesEditableOnly );
-		dataFilter.addRules( defaultDataFilterRulesForAll, { applyToAll: true } );
-		dataFilter.addRules( createBogusAndFillerRules( editor, 'data' ), { applyToAll: true } );
-		htmlFilter.addRules( defaultHtmlFilterRulesEditableOnly );
-		htmlFilter.addRules( defaultHtmlFilterRulesForAll, { applyToAll: true } );
-		htmlFilter.addRules( createBogusAndFillerRules( editor, 'html' ), { applyToAll: true } );
-
-		editor.on( 'toHtml', function( evt ) {
-			var evtData = evt.data,
-				data = evtData.dataValue;
-
-			// The source data is already HTML, but we need to clean
-			// it up and apply the filter.
-			data = protectSource( data, editor );
-
-			// Protect content of textareas. (#9995)
-			// Do this before protecting attributes to avoid breaking:
-			// <textarea><img src="..." /></textarea>
-			data = protectElements( data, protectTextareaRegex );
-
-			// Before anything, we must protect the URL attributes as the
-			// browser may changing them when setting the innerHTML later in
-			// the code.
-			data = protectAttributes( data );
-
-			// Protect elements than can't be set inside a DIV. E.g. IE removes
-			// style tags from innerHTML. (#3710)
-			data = protectElements( data, protectElementsRegex );
-
-			// Certain elements has problem to go through DOM operation, protect
-			// them by prefixing 'cke' namespace. (#3591)
-			data = protectElementsNames( data );
-
-			// All none-IE browsers ignore self-closed custom elements,
-			// protecting them into open-close. (#3591)
-			data = protectSelfClosingElements( data );
-
-			// Compensate one leading line break after <pre> open as browsers
-			// eat it up. (#5789)
-			data = protectPreFormatted( data );
-
-			var fixBin = evtData.context || editor.editable().getName(),
-				isPre;
-
-			// Old IEs loose formats when load html into <pre>.
-			if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 && fixBin == 'pre' ) {
-				fixBin = 'div';
-				data = '<pre>' + data + '</pre>';
-				isPre = 1;
-			}
-
-			// Call the browser to help us fixing a possibly invalid HTML
-			// structure.
-			var el = editor.document.createElement( fixBin );
-			// Add fake character to workaround IE comments bug. (#3801)
-			el.setHtml( 'a' + data );
-			data = el.getHtml().substr( 1 );
-
-			// Restore shortly protected attribute names.
-			data = data.replace( new RegExp( ' data-cke-' + CKEDITOR.rnd + '-', 'ig' ), ' ' );
-
-			isPre && ( data = data.replace( /^<pre>|<\/pre>$/gi, '' ) );
-
-			// Unprotect "some" of the protected elements at this point.
-			data = unprotectElementNames( data );
-
-			data = unprotectElements( data );
-
-			// Restore the comments that have been protected, in this way they
-			// can be properly filtered.
-			data = unprotectRealComments( data );
-
-			// Now use our parser to make further fixes to the structure, as
-			// well as apply the filter.
-			evtData.dataValue = CKEDITOR.htmlParser.fragment.fromHtml(
-				data, evtData.context, evtData.fixForBody === false ? false : getFixBodyTag( evtData.enterMode, editor.config.autoParagraph ) );
-		}, null, null, 5 );
-
-		// Filter incoming "data".
-		// Add element filter before htmlDataProcessor.dataFilter when purifying input data to correct html.
-		editor.on( 'toHtml', function( evt ) {
-			if ( evt.data.filter.applyTo( evt.data.dataValue, true, evt.data.dontFilter, evt.data.enterMode ) )
-				editor.fire( 'dataFiltered' );
-		}, null, null, 6 );
-
-		editor.on( 'toHtml', function( evt ) {
-			evt.data.dataValue.filterChildren( that.dataFilter, true );
-		}, null, null, 10 );
-
-		editor.on( 'toHtml', function( evt ) {
-			var evtData = evt.data,
-				data = evtData.dataValue,
-				writer = new CKEDITOR.htmlParser.basicWriter();
-
-			data.writeChildrenHtml( writer );
-			data = writer.getHtml( true );
-
-			// Protect the real comments again.
-			evtData.dataValue = protectRealComments( data );
-		}, null, null, 15 );
-
-
-		editor.on( 'toDataFormat', function( evt ) {
-			var data = evt.data.dataValue;
-
-			// #10854 - we need to strip leading blockless <br> which FF adds
-			// automatically when editable contains only non-editable content.
-			// We do that for every browser (so it's a constant behavior) and
-			// not in BR mode, in which chance of valid leading blockless <br> is higher.
-			if ( evt.data.enterMode != CKEDITOR.ENTER_BR )
-				data = data.replace( /^<br *\/?>/i, '' );
-
-			evt.data.dataValue = CKEDITOR.htmlParser.fragment.fromHtml(
-				data, evt.data.context, getFixBodyTag( evt.data.enterMode, editor.config.autoParagraph ) );
-		}, null, null, 5 );
-
-		editor.on( 'toDataFormat', function( evt ) {
-			evt.data.dataValue.filterChildren( that.htmlFilter, true );
-		}, null, null, 10 );
-
-		// Transform outcoming "data".
-		// Add element filter after htmlDataProcessor.htmlFilter when preparing output data HTML.
-		editor.on( 'toDataFormat', function( evt ) {
-			evt.data.filter.applyTo( evt.data.dataValue, false, true );
-		}, null, null, 11 );
-
-		editor.on( 'toDataFormat', function( evt ) {
-			var data = evt.data.dataValue,
-				writer = that.writer;
-
-			writer.reset();
-			data.writeChildrenHtml( writer );
-			data = writer.getHtml( true );
-
-			// Restore those non-HTML protected source. (#4475,#4880)
-			data = unprotectRealComments( data );
-			data = unprotectSource( data, editor );
-
-			evt.data.dataValue = data;
-		}, null, null, 15 );
-	};
-
-	CKEDITOR.htmlDataProcessor.prototype = {
-		/**
-		 * Processes the input (potentially malformed) HTML to a purified form which
-		 * is suitable for using in the WYSIWYG editable.
-		 *
-		 * This method fires the {@link CKEDITOR.editor#toHtml} event which makes it possible
-		 * to hook into the process at various stages.
-		 *
-		 * **Note:** Since CKEditor 4.3 the signature of this method changed and all options
-		 * are now grouped in one `options` object. Previously `context`, `fixForBody` and `dontFilter`
-		 * were passed separately.
-		 *
-		 * @param {String} data The raw data.
-		 * @param {Object} [options] The options object.
-		 * @param {String} [options.context] The tag name of a context element within which
-		 * the input is to be processed, default to be the editable element.
-		 * If `null` is passed, then data will be parsed without context (as children of {@link CKEDITOR.htmlParser.fragment}).
-		 * See {@link CKEDITOR.htmlParser.fragment#fromHtml} for more details.
-		 * @param {Boolean} [options.fixForBody=true] Whether to trigger the auto paragraph for non-block contents.
-		 * @param {CKEDITOR.filter} [options.filter] When specified, instead of using the {@link CKEDITOR.editor#filter main filter},
-		 * passed instance will be used to filter the content.
-		 * @param {Boolean} [options.dontFilter] Do not filter data with {@link CKEDITOR.filter} (note: transformations
-		 * will be still applied).
-		 * @param {Number} [options.enterMode] When specified it will be used instead of the {@link CKEDITOR.editor#enterMode main enterMode}.
-		 * @returns {String}
-		 */
-		toHtml: function( data, options, fixForBody, dontFilter ) {
-			var editor = this.editor,
-				context, filter, enterMode;
-
-			// Typeof null == 'object', so check truthiness of options too.
-			if ( options && typeof options == 'object' ) {
-				context = options.context;
-				fixForBody = options.fixForBody;
-				dontFilter = options.dontFilter;
-				filter = options.filter;
-				enterMode = options.enterMode;
-			}
-			// Backward compatibility. Since CKEDITOR 4.3 every option was a separate argument.
-			else
-				context = options;
-
-			// Fall back to the editable as context if not specified.
-			if ( !context && context !== null )
-				context = editor.editable().getName();
-
-			return editor.fire( 'toHtml', {
-				dataValue: data,
-				context: context,
-				fixForBody: fixForBody,
-				dontFilter: dontFilter,
-				filter: filter || editor.filter,
-				enterMode: enterMode || editor.enterMode
-			} ).dataValue;
-		},
-
-		/**
-		 * See {@link CKEDITOR.dataProcessor#toDataFormat}.
-		 *
-		 * This method fires the {@link CKEDITOR.editor#toDataFormat} event which makes it possible
-		 * to hook into the process at various steps.
-		 *
-		 * @param {String} html
-		 * @param {Object} [options] The options object.
-		 * @param {String} [options.context] The tag name of a context element within which
-		 * the input is to be processed, default to be the editable element.
-		 * @param {CKEDITOR.filter} [options.filter] When specified, instead of using the {@link CKEDITOR.editor#filter main filter},
-		 * passed instance will be used to apply content transformations to the content.
-		 * @param {Number} [options.enterMode] When specified it will be used instead of the {@link CKEDITOR.editor#enterMode main enterMode}.
-		 * @returns {String}
-		 */
-		toDataFormat: function( html, options ) {
-			var context, filter, enterMode;
-
-			// Do not shorten this to `options && options.xxx`, because
-			// falsy `options` will be passed instead of undefined.
-			if ( options ) {
-				context = options.context;
-				filter = options.filter;
-				enterMode = options.enterMode;
-			}
-
-			// Fall back to the editable as context if not specified.
-			if ( !context && context !== null )
-				context = this.editor.editable().getName();
-
-			return this.editor.fire( 'toDataFormat', {
-				dataValue: html,
-				filter: filter || this.editor.filter,
-				context: context,
-				enterMode: enterMode || this.editor.enterMode
-			} ).dataValue;
-		}
-	};
-
-	// Produce a set of filtering rules that handles bogus and filler node at the
-	// end of block/pseudo block, in the following consequence:
-	// 1. elements:<block> - this filter removes any bogus node, then check
-	// if it's an empty block that requires a filler.
-	// 2. elements:<br> - After cleaned with bogus, this filter checks the real
-	// line-break BR to compensate a filler after it.
-	//
-	// Terms definitions:
-	// filler: An element that's either <BR> or &NBSP; at the end of block that established line height.
-	// bogus: Whenever a filler is proceeded with inline content, it becomes a bogus which is subjected to be removed.
-	//
-	// Various forms of the filler:
-	// In output HTML: Filler should be consistently &NBSP; <BR> at the end of block is always considered as bogus.
-	// In Wysiwyg HTML: Browser dependent - see env.needsBrFiller. Either BR for when needsBrFiller is true, or &NBSP; otherwise.
-	// <BR> is NEVER considered as bogus when needsBrFiller is true.
-	function createBogusAndFillerRules( editor, type ) {
-		function createFiller( isOutput ) {
-			return isOutput || CKEDITOR.env.needsNbspFiller ?
-				new CKEDITOR.htmlParser.text( '\xa0' ) :
-				new CKEDITOR.htmlParser.element( 'br', { 'data-cke-bogus': 1 } );
-		}
-
-		// This text block filter, remove any bogus and create the filler on demand.
-		function blockFilter( isOutput, fillEmptyBlock ) {
-
-			return function( block ) {
-
-				// DO NOT apply the filer if it's a fragment node.
-				if ( block.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT )
-					return;
-
-				cleanBogus( block );
-
-				// [Opera] it's mandatory for the filler to present inside of empty block when in WYSIWYG.
-				if ( ( ( CKEDITOR.env.opera && !isOutput ) ||
-						( typeof fillEmptyBlock == 'function' ? fillEmptyBlock( block ) !== false : fillEmptyBlock ) ) &&
-						 isEmptyBlockNeedFiller( block ) )
-				{
-					block.add( createFiller( isOutput ) );
-				}
-			};
-		}
-
-		// Append a filler right after the last line-break BR, found at the end of block.
-		function brFilter( isOutput ) {
-			return function( br ) {
-
-				// DO NOT apply the filer if parent's a fragment node.
-				if ( br.parent.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT )
-					return;
-
-				var attrs = br.attributes;
-				// Dismiss BRs that are either bogus or eol marker.
-				if ( 'data-cke-bogus' in attrs ||
-						 'data-cke-eol' in attrs ) {
-					delete attrs [ 'data-cke-bogus' ];
-					return;
-				}
-
-				// Judge the tail line-break BR, and to insert bogus after it.
-				var next = getNext( br ), previous = getPrevious( br );
-
-				if ( !next && isBlockBoundary( br.parent ) )
-					append( br.parent, createFiller( isOutput ) );
-				else if ( isBlockBoundary( next ) && previous && !isBlockBoundary( previous ) )
-					createFiller( isOutput ).insertBefore( next );
-			};
-		}
-
-		// Determinate whether this node is potentially a bogus node.
-		function maybeBogus( node, atBlockEnd ) {
-
-			// BR that's not from IE<11 DOM, except for a EOL marker.
-			if ( !( isOutput && !CKEDITOR.env.needsBrFiller ) &&
-					 node.type == CKEDITOR.NODE_ELEMENT && node.name == 'br' &&
-					 !node.attributes[ 'data-cke-eol' ] )
-				return true;
-
-			var match;
-			// NBSP, possibly.
-			if ( node.type == CKEDITOR.NODE_TEXT &&
-					 ( match = node.value.match( tailNbspRegex ) ) )
-			{
-				// We need to separate tail NBSP out of a text node, for later removal.
-				if ( match.index ) {
-					( new CKEDITOR.htmlParser.text( node.value.substring( 0, match.index ) ) ).insertBefore( node );
-					node.value = match[ 0 ];
-				}
-
-				// From IE<11 DOM, at the end of a text block, or before block boundary.
-				if ( !CKEDITOR.env.needsBrFiller && isOutput && ( !atBlockEnd || node.parent.name in textBlockTags ) )
-					return true;
-
-				// From the output.
-				if ( !isOutput ) {
-					var previous = node.previous;
-
-					// Following a line-break at the end of block.
-					if ( previous && previous.name == 'br' )
-						return true;
-
-					// Or a single NBSP between two blocks.
-					if ( !previous || isBlockBoundary( previous ) )
-						return true;
-				}
-			}
-
-			return false;
-		}
-
-		// Removes all bogus inside of this block, and to convert fillers into the proper form.
-		function cleanBogus( block ) {
-			var bogus = [];
-			var last = getLast( block ), node, previous;
-			if ( last ) {
-
-				// Check for bogus at the end of this block.
-				// e.g. <p>foo<br /></p>
-				maybeBogus( last, 1 ) && bogus.push( last );
-
-				while ( last ) {
-
-					// Check for bogus at the end of any pseudo block contained.
-					if ( isBlockBoundary( last ) &&
-							 ( node = getPrevious( last ) ) &&
-							 maybeBogus( node ) )
-					{
-						// Bogus must have inline proceeding, instead single BR between two blocks,
-						// is considered as filler, e.g. <hr /><br /><hr />
-						if ( ( previous = getPrevious( node ) ) && !isBlockBoundary( previous ) )
-							bogus.push( node );
-						// Convert the filler into appropriate form.
-						else {
-							createFiller( isOutput ).insertAfter( node );
-							node.remove();
-						}
-					}
-
-					last = last.previous;
-				}
-			}
-
-			// Now remove all bogus collected from above.
-			for ( var i = 0 ; i < bogus.length ; i++ )
-				bogus[ i ].remove();
-		}
-
-		// Judge whether it's an empty block that requires a filler node.
-		function isEmptyBlockNeedFiller( block ) {
-
-			// DO NOT fill empty editable in IE<11.
-			if ( !isOutput && !CKEDITOR.env.needsBrFiller && block.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT )
-				return false;
-
-			// 1. For IE version >=8,  empty blocks are displayed correctly themself in wysiwiyg;
-			// 2. For the rest, at least table cell and list item need no filler space. (#6248)
-			if ( !isOutput && !CKEDITOR.env.needsBrFiller &&
-					 ( document.documentMode > 7 ||
-						 block.name in CKEDITOR.dtd.tr ||
-						 block.name in CKEDITOR.dtd.$listItem ) ) {
-				return false;
-			}
-
-			var last = getLast( block );
-			return !last || block.name == 'form' && last.name == 'input' ;
-		}
-
-		var rules = { elements: {} };
-		var isOutput = type == 'html';
-
-		// Build the list of text blocks.
-		var textBlockTags = CKEDITOR.tools.extend( {}, blockLikeTags );
-		for ( var i in textBlockTags ) {
-			if ( !( '#' in dtd[ i ] ) )
-				delete textBlockTags[ i ];
-		}
-
-		for ( i in textBlockTags )
-			rules.elements[ i ] = blockFilter( isOutput, editor.config.fillEmptyBlocks !== false );
-
-		// Editable element is to be checked separately.
-		rules.root = blockFilter( isOutput );
-		rules.elements.br = brFilter( isOutput );
-		return rules;
-	}
-
-	function getFixBodyTag( enterMode, autoParagraph ) {
-		return ( enterMode != CKEDITOR.ENTER_BR && autoParagraph !== false ) ? enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' : false;
-	}
-
-	// Regex to scan for &nbsp; at the end of blocks, which are actually placeholders.
-	// Safari transforms the &nbsp; to \xa0. (#4172)
-	var tailNbspRegex = /(?:&nbsp;|\xa0)$/;
-
-	var protectedSourceMarker = '{cke_protected}';
-
-	function getLast( node ) {
-		var last = node.children[ node.children.length - 1 ];
-		while ( last && isEmpty( last ) )
-			last = last.previous;
-		return last;
-	}
-
-	function getNext( node ) {
-		var next = node.next;
-		while ( next && isEmpty( next ) )
-			next = next.next;
-		return next;
-	}
-
-	function getPrevious( node ) {
-		var previous = node.previous;
-		while ( previous && isEmpty( previous ) )
-			previous = previous.previous;
-		return previous;
-	}
-
-	// Judge whether the node is an ghost node to be ignored, when traversing.
-	function isEmpty( node ) {
-		return node.type == CKEDITOR.NODE_TEXT &&
-		  !CKEDITOR.tools.trim( node.value ) ||
-		  node.type == CKEDITOR.NODE_ELEMENT &&
-		  node.attributes[ 'data-cke-bookmark' ];
-	}
-
-	// Judge whether the node is a block-like element.
-	function isBlockBoundary( node ) {
-		return node &&
-					 ( node.type == CKEDITOR.NODE_ELEMENT && node.name in blockLikeTags ||
-						 node.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT );
-	}
-
-	function append( parent, node ) {
-		var last = parent.children[ parent.children.length -1 ];
-		parent.children.push( node );
-		node.parent = parent;
-		if ( last ) {
-			last.next = node;
-			node.previous = last;
-		}
-	}
-
-	function getNodeIndex( node ) {
-		return node.parent ? node.getIndex() : -1;
-	}
-
-	var dtd = CKEDITOR.dtd,
-		// Define orders of table elements.
-		tableOrder = [ 'caption', 'colgroup', 'col', 'thead', 'tfoot', 'tbody' ],
-		// List of all block elements.
-		blockLikeTags = CKEDITOR.tools.extend( {}, dtd.$blockLimit, dtd.$block );
-
-	//
-	// DATA filter rules ------------------------------------------------------
-	//
-
-	var defaultDataFilterRulesEditableOnly = {
-		elements: {
-			input: protectReadOnly,
-			textarea: protectReadOnly
-		}
-	};
-
-	// These rules will also be applied to non-editable content.
-	var defaultDataFilterRulesForAll = {
-		attributeNames: [
-			// Event attributes (onXYZ) must not be directly set. They can become
-			// active in the editing area (IE|WebKit).
-			[ ( /^on/ ), 'data-cke-pa-on' ],
-
-			// Don't let some old expando enter editor. Concerns only IE8,
-			// but for consistency remove on all browsers.
-			[ ( /^data-cke-expando$/ ), '' ]
-		]
-	};
-
-	// Disable form elements editing mode provided by some browsers. (#5746)
-	function protectReadOnly( element ) {
-		var attrs = element.attributes;
-
-		// We should flag that the element was locked by our code so
-		// it'll be editable by the editor functions (#6046).
-		if ( attrs.contenteditable != 'false' )
-			attrs[ 'data-cke-editable' ] = attrs.contenteditable ? 'true' : 1;
-
-		attrs.contenteditable = 'false';
-	}
-
-	//
-	// HTML filter rules ------------------------------------------------------
-	//
-
-	var defaultHtmlFilterRulesEditableOnly = {
-		elements: {
-			embed: function( element ) {
-				var parent = element.parent;
-
-				// If the <embed> is child of a <object>, copy the width
-				// and height attributes from it.
-				if ( parent && parent.name == 'object' ) {
-					var parentWidth = parent.attributes.width,
-						parentHeight = parent.attributes.height;
-					if ( parentWidth )
-						element.attributes.width = parentWidth;
-					if ( parentHeight )
-						element.attributes.height = parentHeight;
-				}
-			},
-
-			// Remove empty link but not empty anchor. (#3829)
-			a: function( element ) {
-				if ( !( element.children.length || element.attributes.name || element.attributes[ 'data-cke-saved-name' ] ) )
-					return false;
-			}
-		}
-	};
-
-	// These rules will also be applied to non-editable content.
-	var defaultHtmlFilterRulesForAll = {
-		elementNames: [
-			// Remove the "cke:" namespace prefix.
-			[ ( /^cke:/ ), '' ],
-
-			// Ignore <?xml:namespace> tags.
-			[ ( /^\?xml:namespace$/ ), '' ]
-		],
-
-		attributeNames: [
-			// Attributes saved for changes and protected attributes.
-			[ ( /^data-cke-(saved|pa)-/ ), '' ],
-
-			// All "data-cke-" attributes are to be ignored.
-			[ ( /^data-cke-.*/ ), '' ],
-
-			[ 'hidefocus', '' ]
-		],
-
-		elements: {
-			$: function( element ) {
-				var attribs = element.attributes;
-
-				if ( attribs ) {
-					// Elements marked as temporary are to be ignored.
-					if ( attribs[ 'data-cke-temp' ] )
-						return false;
-
-					// Remove duplicated attributes - #3789.
-					var attributeNames = [ 'name', 'href', 'src' ],
-						savedAttributeName;
-					for ( var i = 0; i < attributeNames.length; i++ ) {
-						savedAttributeName = 'data-cke-saved-' + attributeNames[ i ];
-						savedAttributeName in attribs && ( delete attribs[ attributeNames[ i ] ] );
-					}
-				}
-
-				return element;
-			},
-
-			// The contents of table should be in correct order (#4809).
-			table: function( element ) {
-					// Clone the array as it would become empty during the sort call.
-					var children = element.children.slice( 0 );
-					children.sort( function( node1, node2 ) {
-						var index1, index2;
-
-						// Compare in the predefined order.
-						if ( node1.type == CKEDITOR.NODE_ELEMENT &&
-								 node2.type == node1.type ) {
-							index1 = CKEDITOR.tools.indexOf( tableOrder, node1.name );
-							index2 = CKEDITOR.tools.indexOf( tableOrder, node2.name );
-						}
-
-						// Make sure the sort is stable, if no order can be established above.
-						if ( !( index1 > -1 && index2 > -1 && index1 != index2 ) ) {
-							index1 = getNodeIndex( node1 );
-							index2 = getNodeIndex( node2 );
-						}
-
-						return index1 > index2 ? 1 : -1;
-					} );
-			},
-
-			// Restore param elements into self-closing.
-			param: function( param ) {
-				param.children = [];
-				param.isEmpty = true;
-				return param;
-			},
-
-			// Remove dummy span in webkit.
-			span: function( element ) {
-				if ( element.attributes[ 'class' ] == 'Apple-style-span' )
-					delete element.name;
-			},
-
-			html: function( element ) {
-				delete element.attributes.contenteditable;
-				delete element.attributes[ 'class' ];
-			},
-
-			body: function( element ) {
-				delete element.attributes.spellcheck;
-				delete element.attributes.contenteditable;
-			},
-
-			style: function( element ) {
-				var child = element.children[ 0 ];
-				if ( child && child.value )
-					child.value = CKEDITOR.tools.trim( child.value );
-
-				if ( !element.attributes.type )
-					element.attributes.type = 'text/css';
-			},
-
-			title: function( element ) {
-				var titleText = element.children[ 0 ];
-
-				// Append text-node to title tag if not present (i.e. non-IEs) (#9882).
-				!titleText && append( element, titleText = new CKEDITOR.htmlParser.text() );
-
-				// Transfer data-saved title to title tag.
-				titleText.value = element.attributes[ 'data-cke-title' ] || '';
-			},
-
-			input: unprotectReadyOnly,
-			textarea: unprotectReadyOnly
-		},
-
-		attributes: {
-			'class': function( value, element ) {
-				// Remove all class names starting with "cke_".
-				return CKEDITOR.tools.ltrim( value.replace( /(?:^|\s+)cke_[^\s]*/g, '' ) ) || false;
-			}
-		}
-	};
-
-	if ( CKEDITOR.env.ie ) {
-		// IE outputs style attribute in capital letters. We should convert
-		// them back to lower case, while not hurting the values (#5930)
-		defaultHtmlFilterRulesForAll.attributes.style = function( value, element ) {
-			return value.replace( /(^|;)([^\:]+)/g, function( match ) {
-				return match.toLowerCase();
-			} );
-		};
-	}
-
-	// Disable form elements editing mode provided by some browsers. (#5746)
-	function unprotectReadyOnly( element ) {
-		var attrs = element.attributes;
-		switch ( attrs[ 'data-cke-editable' ] ) {
-			case 'true':
-				attrs.contenteditable = 'true';
-				break;
-			case '1':
-				delete attrs.contenteditable;
-				break;
-		}
-	}
-
-	//
-	// Preprocessor filters ---------------------------------------------------
-	//
-
-	var protectElementRegex = /<(a|area|img|input|source)\b([^>]*)>/gi,
-		// Be greedy while looking for protected attributes. This will let us avoid an unfortunate
-		// situation when "nested attributes", which may appear valid, are also protected.
-		// I.e. if we consider the following HTML:
-		//
-		// 	<img data-x="&lt;a href=&quot;X&quot;" />
-		//
-		// then the "non-greedy match" returns:
-		//
-		// 	'href' => '&quot;X&quot;' // It's wrong! Href is not an attribute of <img>.
-		//
-		// while greedy match returns:
-		//
-		// 	'data-x' => '&lt;a href=&quot;X&quot;'
-		//
-		// which, can be easily filtered out (#11508).
-		protectAttributeRegex = /([\w-]+)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+))/gi,
-		protectAttributeNameRegex = /^(href|src|name)$/i;
-
-		// Note: we use lazy star '*?' to prevent eating everything up to the last occurrence of </style> or </textarea>.
-	var protectElementsRegex = /(?:<style(?=[ >])[^>]*>[\s\S]*?<\/style>)|(?:<(:?link|meta|base)[^>]*>)/gi,
-		protectTextareaRegex = /(<textarea(?=[ >])[^>]*>)([\s\S]*?)(?:<\/textarea>)/gi,
-		encodedElementsRegex = /<cke:encoded>([^<]*)<\/cke:encoded>/gi;
-
-	var protectElementNamesRegex = /(<\/?)((?:object|embed|param|html|body|head|title)[^>]*>)/gi,
-		unprotectElementNamesRegex = /(<\/?)cke:((?:html|body|head|title)[^>]*>)/gi;
-
-	var protectSelfClosingRegex = /<cke:(param|embed)([^>]*?)\/?>(?!\s*<\/cke:\1)/gi;
-
-	function protectAttributes( html ) {
-		return html.replace( protectElementRegex, function( element, tag, attributes ) {
-			return '<' + tag + attributes.replace( protectAttributeRegex, function( fullAttr, attrName ) {
-				// Avoid corrupting the inline event attributes (#7243).
-				// We should not rewrite the existed protected attributes, e.g. clipboard content from editor. (#5218)
-				if ( protectAttributeNameRegex.test( attrName ) && attributes.indexOf( 'data-cke-saved-' + attrName ) == -1 )
-					return ' data-cke-saved-' + fullAttr + ' data-cke-' + CKEDITOR.rnd + '-' + fullAttr;
-
-				return fullAttr;
-			} ) + '>';
-		} );
-	}
-
-	function protectElements( html, regex ) {
-		return html.replace( regex, function( match, tag, content ) {
-			// Encode < and > in textarea because this won't be done by a browser, since
-			// textarea will be protected during passing data through fix bin.
-			if ( match.indexOf( '<textarea' ) === 0 )
-				match = tag + unprotectRealComments( content ).replace( /</g, '&lt;' ).replace( />/g, '&gt;' ) + '</textarea>';
-
-			return '<cke:encoded>' + encodeURIComponent( match ) + '</cke:encoded>';
-		} );
-	}
-
-	function unprotectElements( html ) {
-		return html.replace( encodedElementsRegex, function( match, encoded ) {
-			return decodeURIComponent( encoded );
-		} );
-	}
-
-	function protectElementsNames( html ) {
-		return html.replace( protectElementNamesRegex, '$1cke:$2' );
-	}
-
-	function unprotectElementNames( html ) {
-		return html.replace( unprotectElementNamesRegex, '$1$2' );
-	}
-
-	function protectSelfClosingElements( html ) {
-		return html.replace( protectSelfClosingRegex, '<cke:$1$2></cke:$1>' );
-	}
-
-	function protectPreFormatted( html ) {
-		return CKEDITOR.env.opera ? html : html.replace( /(<pre\b[^>]*>)(\r\n|\n)/g, '$1$2$2' );
-	}
-
-	function protectRealComments( html ) {
-		return html.replace( /<!--(?!{cke_protected})[\s\S]+?-->/g, function( match ) {
-			return '<!--' + protectedSourceMarker +
-				'{C}' +
-				encodeURIComponent( match ).replace( /--/g, '%2D%2D' ) +
-				'-->';
-		} );
-	}
-
-	function unprotectRealComments( html ) {
-		return html.replace( /<!--\{cke_protected\}\{C\}([\s\S]+?)-->/g, function( match, data ) {
-			return decodeURIComponent( data );
-		} );
-	}
-
-	function unprotectSource( html, editor ) {
-		var store = editor._.dataStore;
-
-		return html.replace( /<!--\{cke_protected\}([\s\S]+?)-->/g, function( match, data ) {
-			return decodeURIComponent( data );
-		} ).replace( /\{cke_protected_(\d+)\}/g, function( match, id ) {
-			return store && store[ id ] || '';
-		} );
-	}
-
-	function protectSource( data, editor ) {
-		var protectedHtml = [],
-			protectRegexes = editor.config.protectedSource,
-			store = editor._.dataStore || ( editor._.dataStore = { id: 1 } ),
-			tempRegex = /<\!--\{cke_temp(comment)?\}(\d*?)-->/g;
-
-		var regexes = [
-			// Script tags will also be forced to be protected, otherwise
-			// IE will execute them.
-			( /<script[\s\S]*?<\/script>/gi ),
-
-			// <noscript> tags (get lost in IE and messed up in FF).
-			/<noscript[\s\S]*?<\/noscript>/gi
-		].concat( protectRegexes );
-
-		// First of any other protection, we must protect all comments
-		// to avoid loosing them (of course, IE related).
-		// Note that we use a different tag for comments, as we need to
-		// transform them when applying filters.
-		data = data.replace( ( /<!--[\s\S]*?-->/g ), function( match ) {
-			return '<!--{cke_tempcomment}' + ( protectedHtml.push( match ) - 1 ) + '-->';
-		} );
-
-		for ( var i = 0; i < regexes.length; i++ ) {
-			data = data.replace( regexes[ i ], function( match ) {
-				match = match.replace( tempRegex, // There could be protected source inside another one. (#3869).
-				function( $, isComment, id ) {
-					return protectedHtml[ id ];
-				} );
-
-				// Avoid protecting over protected, e.g. /\{.*?\}/
-				return ( /cke_temp(comment)?/ ).test( match ) ? match : '<!--{cke_temp}' + ( protectedHtml.push( match ) - 1 ) + '-->';
-			} );
-		}
-		data = data.replace( tempRegex, function( $, isComment, id ) {
-			return '<!--' + protectedSourceMarker +
-				( isComment ? '{C}' : '' ) +
-				encodeURIComponent( protectedHtml[ id ] ).replace( /--/g, '%2D%2D' ) +
-				'-->';
-		} );
-
-		// Different protection pattern is used for those that
-		// live in attributes to avoid from being HTML encoded.
-		return data.replace( /(['"]).*?\1/g, function( match ) {
-			return match.replace( /<!--\{cke_protected\}([\s\S]+?)-->/g, function( match, data ) {
-				store[ store.id ] = decodeURIComponent( data );
-				return '{cke_protected_' + ( store.id++ ) + '}';
-			} );
-		} );
-	}
-} )();
-
-/**
- * Whether a filler text (non-breaking space entity &mdash; `&nbsp;`) will be
- * inserted into empty block elements in HTML output.
- * This is used to render block elements properly with `line-height`.
- * When a function is specified instead, it will be passed a {@link CKEDITOR.htmlParser.element}
- * to decide whether adding the filler text by expecting a Boolean return value.
- *
- *		config.fillEmptyBlocks = false; // Prevent filler nodes in all empty blocks.
- *
- *		// Prevent filler node only in float cleaners.
- *		config.fillEmptyBlocks = function( element ) {
- *			if ( element.attributes[ 'class' ].indexOf( 'clear-both' ) != -1 )
- *				return false;
- *		};
- *
- * @since 3.5
- * @cfg {Boolean} [fillEmptyBlocks=true]
- * @member CKEDITOR.config
- */
-
-/**
- * This event is fired by the {@link CKEDITOR.htmlDataProcessor} when input HTML
- * is to be purified by the {@link CKEDITOR.htmlDataProcessor#toHtml} method.
- *
- * By adding listeners with different priorities it is possible
- * to process input HTML on different stages:
- *
- *	* 1-4: Data is available in the original string format.
- *	* 5: Data is initially filtered with regexp patterns and parsed to
- *		{@link CKEDITOR.htmlParser.fragment} {@link CKEDITOR.htmlParser.element}.
- *	* 5-9: Data is available in the parsed format, but {@link CKEDITOR.htmlDataProcessor#dataFilter}
- *		is not applied yet.
- *	* 6: Data is filtered with the {CKEDITOR.filter content filter}.
- *	* 10: Data is processed with {@link CKEDITOR.htmlDataProcessor#dataFilter}.
- *	* 10-14: Data is available in the parsed format and {@link CKEDITOR.htmlDataProcessor#dataFilter}
- *		has already been applied.
- *	* 15: Data is written back to an HTML string.
- *	* 15-*: Data is available in an HTML string.
- *
- * For example to be able to process parsed, but not yet filtered data add listener this way:
- *
- *		editor.on( 'toHtml', function( evt) {
- *			evt.data.dataValue; // -> CKEDITOR.htmlParser.fragment instance
- *		}, null, null, 7 );
- *
- * @since 4.1
- * @event toHtml
- * @member CKEDITOR.editor
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param data
- * @param {String/CKEDITOR.htmlParser.fragment/CKEDITOR.htmlParser.element} data.dataValue Input data to be purified.
- * @param {String} data.context See {@link CKEDITOR.htmlDataProcessor#toHtml} The `context` argument.
- * @param {Boolean} data.fixForBody See {@link CKEDITOR.htmlDataProcessor#toHtml} The `fixForBody` argument.
- * @param {Boolean} data.dontFilter See {@link CKEDITOR.htmlDataProcessor#toHtml} The `dontFilter` argument.
- * @param {Boolean} data.filter See {@link CKEDITOR.htmlDataProcessor#toHtml} The `filter` argument.
- * @param {Boolean} data.enterMode See {@link CKEDITOR.htmlDataProcessor#toHtml} The `enterMode` argument.
- */
-
-/**
- * This event is fired when {@link CKEDITOR.htmlDataProcessor} is converting
- * internal HTML to output data HTML.
- *
- * By adding listeners with different priorities it is possible
- * to process input HTML on different stages:
- *
- *	* 1-4: Data is available in the original string format.
- *	* 5: Data is initially filtered with regexp patterns and parsed to
- *		{@link CKEDITOR.htmlParser.fragment} {@link CKEDITOR.htmlParser.element}.
- *	* 5-9: Data is available in the parsed format, but {@link CKEDITOR.htmlDataProcessor#htmlFilter}
- *		is not applied yet.
- *	* 10: Data is filtered with {@link CKEDITOR.htmlDataProcessor#htmlFilter}.
- *  * 11: Data is filtered with the {CKEDITOR.filter content filter} (on output the content filter makes
- *		only transformations, without filtering).
- *	* 10-14: Data is available in the parsed format and {@link CKEDITOR.htmlDataProcessor#htmlFilter}
- *		has already been applied.
- *	* 15: Data is written back to an HTML string.
- *	* 15-*: Data is available in an HTML string.
- *
- * For example to be able to process parsed and already processed data add listener this way:
- *
- *		editor.on( 'toDataFormat', function( evt) {
- *			evt.data.dataValue; // -> CKEDITOR.htmlParser.fragment instance
- *		}, null, null, 12 );
- *
- * @since 4.1
- * @event toDataFormat
- * @member CKEDITOR.editor
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param data
- * @param {String/CKEDITOR.htmlParser.fragment/CKEDITOR.htmlParser.element} data.dataValue Output data to be prepared.
- * @param {String} data.context See {@link CKEDITOR.htmlDataProcessor#toDataFormat} The `context` argument.
- * @param {Boolean} data.filter See {@link CKEDITOR.htmlDataProcessor#toDataFormat} The `filter` argument.
- * @param {Boolean} data.enterMode See {@link CKEDITOR.htmlDataProcessor#toDataFormat} The `enterMode` argument.
- */
-

+ 0 - 207
htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser.js

@@ -1,207 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * Provides an "event like" system to parse strings of HTML data.
- *
- *		var parser = new CKEDITOR.htmlParser();
- *		parser.onTagOpen = function( tagName, attributes, selfClosing ) {
- *			alert( tagName );
- *		};
- *		parser.parse( '<p>Some <b>text</b>.</p>' ); // Alerts 'p', 'b'.
- *
- * @class
- * @constructor Creates a htmlParser class instance.
- */
-CKEDITOR.htmlParser = function() {
-	this._ = {
-		htmlPartsRegex: new RegExp( '<(?:(?:\\/([^>]+)>)|(?:!--([\\S|\\s]*?)-->)|(?:([^\\s>]+)\\s*((?:(?:"[^"]*")|(?:\'[^\']*\')|[^"\'>])*)\\/?>))', 'g' )
-	};
-};
-
-( function() {
-	var attribsRegex = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,
-		emptyAttribs = { checked: 1, compact: 1, declare: 1, defer: 1, disabled: 1, ismap: 1, multiple: 1, nohref: 1, noresize: 1, noshade: 1, nowrap: 1, readonly: 1, selected: 1 };
-
-	CKEDITOR.htmlParser.prototype = {
-		/**
-		 * Function to be fired when a tag opener is found. This function
-		 * should be overriden when using this class.
-		 *
-		 *		var parser = new CKEDITOR.htmlParser();
-		 *		parser.onTagOpen = function( tagName, attributes, selfClosing ) {
-		 *			alert( tagName ); // e.g. 'b'
-		 *		} );
-		 *		parser.parse( '<!-- Example --><b>Hello</b>' );
-		 *
-		 * @param {String} tagName The tag name. The name is guarantted to be lowercased.
-		 * @param {Object} attributes An object containing all tag attributes. Each
-		 * property in this object represent and attribute name and its value is the attribute value.
-		 * @param {Boolean} selfClosing `true` if the tag closes itself, false if the tag doesn't.
-		 */
-		onTagOpen: function() {},
-
-		/**
-		 * Function to be fired when a tag closer is found. This function
-		 * should be overriden when using this class.
-		 *
-		 *		var parser = new CKEDITOR.htmlParser();
-		 *		parser.onTagClose = function( tagName ) {
-		 *			alert( tagName ); // 'b'
-		 *		} );
-		 *		parser.parse( '<!-- Example --><b>Hello</b>' );
-		 *
-		 * @param {String} tagName The tag name. The name is guarantted to be lowercased.
-		 */
-		onTagClose: function() {},
-
-		/**
-		 * Function to be fired when text is found. This function
-		 * should be overriden when using this class.
-		 *
-		 *		var parser = new CKEDITOR.htmlParser();
-		 *		parser.onText = function( text ) {
-		 *			alert( text ); // 'Hello'
-		 *		} );
-		 *		parser.parse( '<!-- Example --><b>Hello</b>' );
-		 *
-		 * @param {String} text The text found.
-		 */
-		onText: function() {},
-
-		/**
-		 * Function to be fired when CDATA section is found. This function
-		 * should be overriden when using this class.
-		 *
-		 *		var parser = new CKEDITOR.htmlParser();
-		 *		parser.onCDATA = function( cdata ) {
-		 *			alert( cdata ); // 'var hello;'
-		 *		} );
-		 *		parser.parse( '<script>var hello;</script>' );
-		 *
-		 * @param {String} cdata The CDATA been found.
-		 */
-		onCDATA: function() {},
-
-		/**
-		 * Function to be fired when a commend is found. This function
-		 * should be overriden when using this class.
-		 *
-		 *		var parser = new CKEDITOR.htmlParser();
-		 *		parser.onComment = function( comment ) {
-		 *			alert( comment ); // ' Example '
-		 *		} );
-		 *		parser.parse( '<!-- Example --><b>Hello</b>' );
-		 *
-		 * @param {String} comment The comment text.
-		 */
-		onComment: function() {},
-
-		/**
-		 * Parses text, looking for HTML tokens, like tag openers or closers,
-		 * or comments. This function fires the onTagOpen, onTagClose, onText
-		 * and onComment function during its execution.
-		 *
-		 *		var parser = new CKEDITOR.htmlParser();
-		 *		// The onTagOpen, onTagClose, onText and onComment should be overriden
-		 *		// at this point.
-		 *		parser.parse( '<!-- Example --><b>Hello</b>' );
-		 *
-		 * @param {String} html The HTML to be parsed.
-		 */
-		parse: function( html ) {
-			var parts, tagName,
-				nextIndex = 0,
-				cdata; // The collected data inside a CDATA section.
-
-			while ( ( parts = this._.htmlPartsRegex.exec( html ) ) ) {
-				var tagIndex = parts.index;
-				if ( tagIndex > nextIndex ) {
-					var text = html.substring( nextIndex, tagIndex );
-
-					if ( cdata )
-						cdata.push( text );
-					else
-						this.onText( text );
-				}
-
-				nextIndex = this._.htmlPartsRegex.lastIndex;
-
-				/*
-				 "parts" is an array with the following items:
-					0 : The entire match for opening/closing tags and comments.
-					1 : Group filled with the tag name for closing tags.
-					2 : Group filled with the comment text.
-					3 : Group filled with the tag name for opening tags.
-					4 : Group filled with the attributes part of opening tags.
-				 */
-
-				// Closing tag
-				if ( ( tagName = parts[ 1 ] ) ) {
-					tagName = tagName.toLowerCase();
-
-					if ( cdata && CKEDITOR.dtd.$cdata[ tagName ] ) {
-						// Send the CDATA data.
-						this.onCDATA( cdata.join( '' ) );
-						cdata = null;
-					}
-
-					if ( !cdata ) {
-						this.onTagClose( tagName );
-						continue;
-					}
-				}
-
-				// If CDATA is enabled, just save the raw match.
-				if ( cdata ) {
-					cdata.push( parts[ 0 ] );
-					continue;
-				}
-
-				// Opening tag
-				if ( ( tagName = parts[ 3 ] ) ) {
-					tagName = tagName.toLowerCase();
-
-					// There are some tag names that can break things, so let's
-					// simply ignore them when parsing. (#5224)
-					if ( /="/.test( tagName ) )
-						continue;
-
-					var attribs = {},
-						attribMatch,
-						attribsPart = parts[ 4 ],
-						selfClosing = !!( attribsPart && attribsPart.charAt( attribsPart.length - 1 ) == '/' );
-
-					if ( attribsPart ) {
-						while ( ( attribMatch = attribsRegex.exec( attribsPart ) ) ) {
-							var attName = attribMatch[ 1 ].toLowerCase(),
-								attValue = attribMatch[ 2 ] || attribMatch[ 3 ] || attribMatch[ 4 ] || '';
-
-							if ( !attValue && emptyAttribs[ attName ] )
-								attribs[ attName ] = attName;
-							else
-								attribs[ attName ] = CKEDITOR.tools.htmlDecodeAttr( attValue );
-						}
-					}
-
-					this.onTagOpen( tagName, attribs, selfClosing );
-
-					// Open CDATA mode when finding the appropriate tags.
-					if ( !cdata && CKEDITOR.dtd.$cdata[ tagName ] )
-						cdata = [];
-
-					continue;
-				}
-
-				// Comment
-				if ( ( tagName = parts[ 2 ] ) )
-					this.onComment( tagName );
-			}
-
-			if ( html.length > nextIndex )
-				this.onText( html.substring( nextIndex, html.length ) );
-		}
-	};
-} )();

+ 0 - 152
htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/basicwriter.js

@@ -1,152 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * TODO
- *
- * @class
- * @todo
- */
-CKEDITOR.htmlParser.basicWriter = CKEDITOR.tools.createClass( {
-	/**
-	 * Creates a basicWriter class instance.
-	 *
-	 * @constructor
-	 */
-	$: function() {
-		this._ = {
-			output: []
-		};
-	},
-
-	proto: {
-		/**
-		 * Writes the tag opening part for a opener tag.
-		 *
-		 *		// Writes '<p'.
-		 *		writer.openTag( 'p', { class : 'MyClass', id : 'MyId' } );
-		 *
-		 * @param {String} tagName The element name for this tag.
-		 * @param {Object} attributes The attributes defined for this tag. The
-		 * attributes could be used to inspect the tag.
-		 */
-		openTag: function( tagName, attributes ) {
-			this._.output.push( '<', tagName );
-		},
-
-		/**
-		 * Writes the tag closing part for a opener tag.
-		 *
-		 *		// Writes '>'.
-		 *		writer.openTagClose( 'p', false );
-		 *
-		 *		// Writes ' />'.
-		 *		writer.openTagClose( 'br', true );
-		 *
-		 * @param {String} tagName The element name for this tag.
-		 * @param {Boolean} isSelfClose Indicates that this is a self-closing tag,
-		 * like `<br>` or `<img>`.
-		 */
-		openTagClose: function( tagName, isSelfClose ) {
-			if ( isSelfClose )
-				this._.output.push( ' />' );
-			else
-				this._.output.push( '>' );
-		},
-
-		/**
-		 * Writes an attribute. This function should be called after opening the
-		 * tag with {@link #openTagClose}.
-		 *
-		 *		// Writes ' class="MyClass"'.
-		 *		writer.attribute( 'class', 'MyClass' );
-		 *
-		 * @param {String} attName The attribute name.
-		 * @param {String} attValue The attribute value.
-		 */
-		attribute: function( attName, attValue ) {
-			// Browsers don't always escape special character in attribute values. (#4683, #4719).
-			if ( typeof attValue == 'string' )
-				attValue = CKEDITOR.tools.htmlEncodeAttr( attValue );
-
-			this._.output.push( ' ', attName, '="', attValue, '"' );
-		},
-
-		/**
-		 * Writes a closer tag.
-		 *
-		 *		// Writes '</p>'.
-		 *		writer.closeTag( 'p' );
-		 *
-		 * @param {String} tagName The element name for this tag.
-		 */
-		closeTag: function( tagName ) {
-			this._.output.push( '</', tagName, '>' );
-		},
-
-		/**
-		 * Writes text.
-		 *
-		 *		// Writes 'Hello Word'.
-		 *		writer.text( 'Hello Word' );
-		 *
-		 * @param {String} text The text value.
-		 */
-		text: function( text ) {
-			this._.output.push( text );
-		},
-
-		/**
-		 * Writes a comment.
-		 *
-		 *		// Writes '<!-- My comment -->'.
-		 *		writer.comment( ' My comment ' );
-		 *
-		 * @param {String} comment The comment text.
-		 */
-		comment: function( comment ) {
-			this._.output.push( '<!--', comment, '-->' );
-		},
-
-		/**
-		 * Writes any kind of data to the ouput.
-		 *
-		 *		writer.write( 'This is an <b>example</b>.' );
-		 *
-		 * @param {String} data
-		 */
-		write: function( data ) {
-			this._.output.push( data );
-		},
-
-		/**
-		 * Empties the current output buffer.
-		 *
-		 *		writer.reset();
-		 */
-		reset: function() {
-			this._.output = [];
-			this._.indent = false;
-		},
-
-		/**
-		 * Empties the current output buffer.
-		 *
-		 *		var html = writer.getHtml();
-		 *
-		 * @param {Boolean} reset Indicates that the {@link #reset} method is to
-		 * be automatically called after retrieving the HTML.
-		 * @returns {String} The HTML written to the writer so far.
-		 */
-		getHtml: function( reset ) {
-			var html = this._.output.join( '' );
-
-			if ( reset )
-				this.reset();
-
-			return html;
-		}
-	}
-} );

+ 0 - 48
htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/cdata.js

@@ -1,48 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
- 'use strict';
-
-( function() {
-
-	/**
-	 * A lightweight representation of HTML CDATA.
-	 *
-	 * @class
-	 * @extends CKEDITOR.htmlParser.node
-	 * @constructor Creates a cdata class instance.
-	 * @param {String} value The CDATA section value.
-	 */
-	CKEDITOR.htmlParser.cdata = function( value ) {
-		/**
-		 * The CDATA value.
-		 *
-		 * @property {String}
-		 */
-		this.value = value;
-	};
-
-	CKEDITOR.htmlParser.cdata.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
-		/**
-		 * CDATA has the same type as {@link CKEDITOR.htmlParser.text} This is
-		 * a constant value set to {@link CKEDITOR#NODE_TEXT}.
-		 *
-		 * @readonly
-		 * @property {Number} [=CKEDITOR.NODE_TEXT]
-		 */
-		type: CKEDITOR.NODE_TEXT,
-
-		filter: function() {},
-
-		/**
-		 * Writes the CDATA with no special manipulations.
-		 *
-		 * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
-		 */
-		writeHtml: function( writer ) {
-			writer.write( this.value );
-		}
-	} );
-} )();

+ 0 - 80
htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/comment.js

@@ -1,80 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
- 'use strict';
-
-/**
- * A lightweight representation of an HTML comment.
- *
- * @class
- * @extends CKEDITOR.htmlParser.node
- * @constructor Creates a comment class instance.
- * @param {String} value The comment text value.
- */
-CKEDITOR.htmlParser.comment = function( value ) {
-	/**
-	 * The comment text.
-	 *
-	 * @property {String}
-	 */
-	this.value = value;
-
-	/** @private */
-	this._ = {
-		isBlockLike: false
-	};
-};
-
-CKEDITOR.htmlParser.comment.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
-	/**
-	 * The node type. This is a constant value set to {@link CKEDITOR#NODE_COMMENT}.
-	 *
-	 * @readonly
-	 * @property {Number} [=CKEDITOR.NODE_COMMENT]
-	 */
-	type: CKEDITOR.NODE_COMMENT,
-
-	/**
-	 * Filter this comment with given filter.
-	 *
-	 * @since 4.1
-	 * @param {CKEDITOR.htmlParser.filter} filter
-	 * @returns {Boolean} Method returns `false` when this comment has
-	 * been removed or replaced with other node. This is an information for
-	 * {@link CKEDITOR.htmlParser.element#filterChildren} that it has
-	 * to repeat filter on current position in parent's children array.
-	 */
-	filter: function( filter, context ) {
-		var comment = this.value;
-
-		if ( !( comment = filter.onComment( context, comment, this ) ) ) {
-			this.remove();
-			return false;
-		}
-
-		if ( typeof comment != 'string' ) {
-			this.replaceWith( comment );
-			return false;
-		}
-
-		this.value = comment;
-
-		return true;
-	},
-
-	/**
-	 * Writes the HTML representation of this comment to a CKEDITOR.htmlWriter.
-	 *
-	 * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
-	 * @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
-	 * **Note:** it's unsafe to filter offline (not appended) node.
-	 */
-	writeHtml: function( writer, filter ) {
-		if ( filter )
-			this.filter( filter );
-
-		writer.comment( this.value );
-	}
-} );

+ 0 - 519
htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/element.js

@@ -1,519 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-'use strict';
-
-/**
- * A lightweight representation of an HTML element.
- *
- * @class
- * @extends CKEDITOR.htmlParser.node
- * @constructor Creates an element class instance.
- * @param {String} name The element name.
- * @param {Object} attributes And object holding all attributes defined for
- * this element.
- */
-CKEDITOR.htmlParser.element = function( name, attributes ) {
-	/**
-	 * The element name.
-	 *
-	 * @property {String}
-	 */
-	this.name = name;
-
-	/**
-	 * Holds the attributes defined for this element.
-	 *
-	 * @property {Object}
-	 */
-	this.attributes = attributes || {};
-
-	/**
-	 * The nodes that are direct children of this element.
-	 */
-	this.children = [];
-
-	// Reveal the real semantic of our internal custom tag name (#6639),
-	// when resolving whether it's block like.
-	var realName = name || '',
-		prefixed = realName.match( /^cke:(.*)/ );
-	prefixed && ( realName = prefixed[ 1 ] );
-
-	var isBlockLike = !!( CKEDITOR.dtd.$nonBodyContent[ realName ] || CKEDITOR.dtd.$block[ realName ] || CKEDITOR.dtd.$listItem[ realName ] || CKEDITOR.dtd.$tableContent[ realName ] || CKEDITOR.dtd.$nonEditable[ realName ] || realName == 'br' );
-
-	this.isEmpty = !!CKEDITOR.dtd.$empty[ name ];
-	this.isUnknown = !CKEDITOR.dtd[ name ];
-
-	/** @private */
-	this._ = {
-		isBlockLike: isBlockLike,
-		hasInlineStarted: this.isEmpty || !isBlockLike
-	};
-};
-
-/**
- * Object presentation of CSS style declaration text.
- *
- * @class
- * @constructor Creates a cssStyle class instance.
- * @param {CKEDITOR.htmlParser.element/String} elementOrStyleText
- * A html parser element or the inline style text.
- */
-CKEDITOR.htmlParser.cssStyle = function() {
-	var styleText,
-		arg = arguments[ 0 ],
-		rules = {};
-
-	styleText = arg instanceof CKEDITOR.htmlParser.element ? arg.attributes.style : arg;
-
-	// html-encoded quote might be introduced by 'font-family'
-	// from MS-Word which confused the following regexp. e.g.
-	//'font-family: &quot;Lucida, Console&quot;'
-	// TODO reuse CSS methods from tools.
-	( styleText || '' ).replace( /&quot;/g, '"' ).replace( /\s*([^ :;]+)\s*:\s*([^;]+)\s*(?=;|$)/g, function( match, name, value ) {
-		name == 'font-family' && ( value = value.replace( /["']/g, '' ) );
-		rules[ name.toLowerCase() ] = value;
-	} );
-
-	return {
-
-		rules: rules,
-
-		/**
-		 * Apply the styles onto the specified element or object.
-		 *
-		 * @param {CKEDITOR.htmlParser.element/CKEDITOR.dom.element/Object} obj
-		 */
-		populate: function( obj ) {
-			var style = this.toString();
-			if ( style )
-				obj instanceof CKEDITOR.dom.element ? obj.setAttribute( 'style', style ) : obj instanceof CKEDITOR.htmlParser.element ? obj.attributes.style = style : obj.style = style;
-
-		},
-
-		/**
-		 * Serialize CSS style declaration to string.
-		 *
-		 * @returns {String}
-		 */
-		toString: function() {
-			var output = [];
-			for ( var i in rules )
-				rules[ i ] && output.push( i, ':', rules[ i ], ';' );
-			return output.join( '' );
-		}
-	};
-};
-
-/** @class CKEDITOR.htmlParser.element */
-( function() {
-	// Used to sort attribute entries in an array, where the first element of
-	// each object is the attribute name.
-	var sortAttribs = function( a, b ) {
-			a = a[ 0 ];
-			b = b[ 0 ];
-			return a < b ? -1 : a > b ? 1 : 0;
-		},
-		fragProto = CKEDITOR.htmlParser.fragment.prototype;
-
-	CKEDITOR.htmlParser.element.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
-		/**
-		 * The node type. This is a constant value set to {@link CKEDITOR#NODE_ELEMENT}.
-		 *
-		 * @readonly
-		 * @property {Number} [=CKEDITOR.NODE_ELEMENT]
-		 */
-		type: CKEDITOR.NODE_ELEMENT,
-
-		/**
-		 * Adds a node to the element children list.
-		 *
-		 * @method
-		 * @param {CKEDITOR.htmlParser.node} node The node to be added.
-		 * @param {Number} [index] From where the insertion happens.
-		 */
-		add: fragProto.add,
-
-		/**
-		 * Clone this element.
-		 *
-		 * @returns {CKEDITOR.htmlParser.element} The element clone.
-		 */
-		clone: function() {
-			return new CKEDITOR.htmlParser.element( this.name, this.attributes );
-		},
-
-		/**
-		 * Filter this element and its children with given filter.
-		 *
-		 * @since 4.1
-		 * @param {CKEDITOR.htmlParser.filter} filter
-		 * @returns {Boolean} Method returns `false` when this element has
-		 * been removed or replaced with other. This is an information for
-		 * {@link #filterChildren} that it has to repeat filter on current
-		 * position in parent's children array.
-		 */
-		filter: function( filter, context ) {
-			var element = this,
-				originalName, name;
-
-			context = element.getFilterContext( context );
-
-			// Do not process elements with data-cke-processor attribute set to off.
-			if ( context.off )
-				return true;
-
-			// Filtering if it's the root node.
-			if ( !element.parent )
-				filter.onRoot( context, element );
-
-			while ( true ) {
-				originalName = element.name;
-
-				if ( !( name = filter.onElementName( context, originalName ) ) ) {
-					this.remove();
-					return false;
-				}
-
-				element.name = name;
-
-				if ( !( element = filter.onElement( context, element ) ) ) {
-					this.remove();
-					return false;
-				}
-
-				// New element has been returned - replace current one
-				// and process it (stop processing this and return false, what
-				// means that element has been removed).
-				if ( element !== this ) {
-					this.replaceWith( element );
-					return false;
-				}
-
-				// If name has been changed - continue loop, so in next iteration
-				// filters for new name will be applied to this element.
-				// If name hasn't been changed - stop.
-				if ( element.name == originalName )
-					break;
-
-				// If element has been replaced with something of a
-				// different type, then make the replacement filter itself.
-				if ( element.type != CKEDITOR.NODE_ELEMENT ) {
-					this.replaceWith( element );
-					return false;
-				}
-
-				// This indicate that the element has been dropped by
-				// filter but not the children.
-				if ( !element.name ) {
-					this.replaceWithChildren();
-					return false;
-				}
-			}
-
-			var attributes = element.attributes,
-				a, value, newAttrName;
-
-			for ( a in attributes ) {
-				newAttrName = a;
-				value = attributes[ a ];
-
-				// Loop until name isn't modified.
-				// A little bit senseless, but IE would do that anyway
-				// because it iterates with for-in loop even over properties
-				// created during its run.
-				while ( true ) {
-					if ( !( newAttrName = filter.onAttributeName( context, a ) ) ) {
-						delete attributes[ a ];
-						break;
-					} else if ( newAttrName != a ) {
-						delete attributes[ a ];
-						a = newAttrName;
-						continue;
-					} else
-						break;
-				}
-
-				if ( newAttrName ) {
-					if ( ( value = filter.onAttribute( context, element, newAttrName, value ) ) === false )
-						delete attributes[ newAttrName ];
-					else
-						attributes[ newAttrName ] = value;
-				}
-			}
-
-			if ( !element.isEmpty )
-				this.filterChildren( filter, false, context );
-
-			return true;
-		},
-
-		/**
-		 * Filter this element's children with given filter.
-		 *
-		 * Element's children may only be filtered once by one
-		 * instance of filter.
-		 *
-		 * @method filterChildren
-		 * @param {CKEDITOR.htmlParser.filter} filter
-		 */
-		filterChildren: fragProto.filterChildren,
-
-		/**
-		 * Writes the element HTML to a CKEDITOR.htmlWriter.
-		 *
-		 * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
-		 * @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
-		 * **Note:** it's unsafe to filter offline (not appended) node.
-		 */
-		writeHtml: function( writer, filter ) {
-			if ( filter )
-				this.filter( filter );
-
-			var name = this.name,
-				attribsArray = [],
-				attributes = this.attributes,
-				attrName,
-				attr, i, l;
-
-			// Open element tag.
-			writer.openTag( name, attributes );
-
-			// Copy all attributes to an array.
-			for ( attrName in attributes )
-				attribsArray.push( [ attrName, attributes[ attrName ] ] );
-
-			// Sort the attributes by name.
-			if ( writer.sortAttributes )
-				attribsArray.sort( sortAttribs );
-
-			// Send the attributes.
-			for ( i = 0, l = attribsArray.length; i < l; i++ ) {
-				attr = attribsArray[ i ];
-				writer.attribute( attr[ 0 ], attr[ 1 ] );
-			}
-
-			// Close the tag.
-			writer.openTagClose( name, this.isEmpty );
-
-			this.writeChildrenHtml( writer );
-
-			// Close the element.
-			if ( !this.isEmpty )
-				writer.closeTag( name );
-		},
-
-		/**
-		 * Send children of this element to the writer.
-		 *
-		 * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
-		 * @param {CKEDITOR.htmlParser.filter} [filter]
-		 */
-		writeChildrenHtml: fragProto.writeChildrenHtml,
-
-		/**
-		 * Replace this element with its children.
-		 *
-		 * @since 4.1
-		 */
-		replaceWithChildren: function() {
-			var children = this.children;
-
-			for ( var i = children.length; i; )
-				children[ --i ].insertAfter( this );
-
-			this.remove();
-		},
-
-		/**
-		 * Execute callback on each node (of given type) in this element.
-		 *
-		 *		// Create <p> element with foo<b>bar</b>bom as its content.
-		 *		var elP = CKEDITOR.htmlParser.fragment.fromHtml( 'foo<b>bar</b>bom', 'p' );
-		 *		elP.forEach( function( node ) {
-		 *			console.log( node );
-		 *		} );
-		 *		// Will log:
-		 *		// 1. document fragment,
-		 *		// 2. <p> element,
-		 *		// 3. "foo" text node,
-		 *		// 4. <b> element,
-		 *		// 5. "bar" text node,
-		 *		// 6. "bom" text node.
-		 *
-		 * @since 4.1
-		 * @param {Function} callback Function to be executed on every node.
-		 * **Since 4.3** if `callback` returned `false` descendants of current node will be ignored.
-		 * @param {CKEDITOR.htmlParser.node} callback.node Node passed as argument.
-		 * @param {Number} [type] If specified `callback` will be executed only on nodes of this type.
-		 * @param {Boolean} [skipRoot] Don't execute `callback` on this element.
-		 */
-		forEach: fragProto.forEach,
-
-		/**
-		 * Gets this element's first child. If `condition` is given returns
-		 * first child which satisfies that condition.
-		 *
-		 * @since 4.3
-		 * @param {String/Object/Function} condition Name of a child, hash of names or validator function.
-		 * @returns {CKEDITOR.htmlParser.node}
-		 */
-		getFirst: function( condition ) {
-			if ( !condition )
-				return this.children.length ? this.children[ 0 ] : null;
-
-			if ( typeof condition != 'function' )
-				condition = nameCondition( condition );
-
-			for ( var i = 0, l = this.children.length; i < l; ++i ) {
-				if ( condition( this.children[ i ] ) )
-					return this.children[ i ];
-			}
-			return null;
-		},
-
-		/**
-		 * Gets this element's inner HTML.
-		 *
-		 * @since 4.3
-		 * @returns {String}
-		 */
-		getHtml: function() {
-			var writer = new CKEDITOR.htmlParser.basicWriter();
-			this.writeChildrenHtml( writer );
-			return writer.getHtml();
-		},
-
-		/**
-		 * Sets this element's inner HTML.
-		 *
-		 * @since 4.3
-		 * @param {String} html
-		 */
-		setHtml: function( html ) {
-			var children = this.children = CKEDITOR.htmlParser.fragment.fromHtml( html ).children;
-
-			for ( var i = 0, l = children.length; i < l; ++i )
-				children[ i ].parent = this;
-		},
-
-		/**
-		 * Gets this element's outer HTML.
-		 *
-		 * @since 4.3
-		 * @returns {String}
-		 */
-		getOuterHtml: function() {
-			var writer = new CKEDITOR.htmlParser.basicWriter();
-			this.writeHtml( writer );
-			return writer.getHtml();
-		},
-
-		/**
-		 * Splits this element at given index.
-		 *
-		 * @since 4.3
-		 * @param {Number} index Index at which element will be split &ndash; `0` means beginning,
-		 * `1` after first child node, etc.
-		 * @returns {CKEDITOR.htmlParser.element} New element, following this one.
-		 */
-		split: function( index ) {
-			var cloneChildren = this.children.splice( index, this.children.length - index ),
-				clone = this.clone();
-
-			for ( var i = 0; i < cloneChildren.length; ++i )
-				cloneChildren[ i ].parent = clone;
-
-			clone.children = cloneChildren;
-
-			if ( cloneChildren[ 0 ] )
-				cloneChildren[ 0 ].previous = null;
-
-			if ( index > 0 )
-				this.children[ index - 1 ].next = null;
-
-			this.parent.add( clone, this.getIndex() + 1 );
-
-			return clone;
-		},
-
-		/**
-		 * Removes class name from classes list.
-		 *
-		 * @since 4.3
-		 * @param {String} className The class name to be removed.
-		 */
-		removeClass: function( className ) {
-			var classes = this.attributes[ 'class' ],
-				index;
-
-			if ( !classes )
-				return;
-
-			// We can safely assume that className won't break regexp.
-			// http://stackoverflow.com/questions/448981/what-characters-are-valid-in-css-class-names
-			classes = CKEDITOR.tools.trim( classes.replace( new RegExp( '(?:\\s+|^)' + className + '(?:\\s+|$)' ), ' ' ) );
-
-			if ( classes )
-				this.attributes[ 'class' ] = classes;
-			else
-				delete this.attributes[ 'class' ];
-		},
-
-		/**
-		 * Checkes whether this element has a class name.
-		 *
-		 * @since 4.3
-		 * @param {String} className The class name to be checked.
-		 * @returns {Boolean} Whether this element has a `className`.
-		 */
-		hasClass: function( className ) {
-			var classes = this.attributes[ 'class' ];
-
-			if ( !classes )
-				return false;
-
-			return ( new RegExp( '(?:^|\\s)' + className + '(?=\\s|$)' ) ).test( classes );
-		},
-
-		getFilterContext: function( ctx ) {
-			var changes = [];
-
-			if ( !ctx ) {
-				ctx = {
-					off: false,
-					nonEditable: false,
-					nestedEditable: false
-				};
-			}
-
-			if ( !ctx.off && this.attributes[ 'data-cke-processor' ] == 'off' )
-				changes.push( 'off', true );
-
-			if ( !ctx.nonEditable && this.attributes.contenteditable == 'false' )
-				changes.push( 'nonEditable', true );
-			// A context to be given nestedEditable must be nonEditable first (by inheritance) (#11372).
-			// Never set "nestedEditable" context for a body. If body is processed then it indicates
-			// a fullPage editor and there's no slightest change of nesting such editable (#11504).
-			else if ( this.name != 'body' && !ctx.nestedEditable && this.attributes.contenteditable == 'true' )
-				changes.push( 'nestedEditable', true );
-
-			if ( changes.length ) {
-				ctx = CKEDITOR.tools.copy( ctx );
-				for ( var i = 0; i < changes.length; i += 2 )
-					ctx[ changes[ i ] ] = changes[ i + 1 ];
-			}
-
-			return ctx;
-		}
-	}, true );
-
-	function nameCondition( condition ) {
-		return function( el ) {
-			return el.type == CKEDITOR.NODE_ELEMENT &&
-				( typeof condition == 'string' ? el.name == condition : el.name in condition );
-		};
-	}
-} )();

+ 0 - 407
htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/filter.js

@@ -1,407 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-'use strict';
-
-( function() {
-	/**
-	 * Filter is a configurable tool for transforming and filtering {@link CKEDITOR.htmlParser.node nodes}.
-	 * It is mainly used during data processing phase which is done not on real DOM nodes,
-	 * but on their simplified form represented by {@link CKEDITOR.htmlParser.node} class and its subclasses.
-	 *
-	 *		var filter = new CKEDITOR.htmlParser.filter( {
-	 *			text: function( value ) {
-	 *				return '@' + value + '@';
-	 *			},
-	 *			elements: {
-	 *				p: function( element ) {
-	 *					element.attributes.foo = '1';
-	 *				}
-	 *			}
-	 *		} );
-	 *
-	 *		var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<p>Foo<b>bar!</b></p>' ),
-	 *			writer = new CKEDITOR.htmlParser.basicWriter();
-	 *		filter.applyTo( fragment );
-	 *		fragment.writeHtml( writer );
-	 *		writer.getHtml(); // '<p foo="1">@Foo@<b>@bar!@</b></p>'
-	 *
-	 * @class
-	 */
-	CKEDITOR.htmlParser.filter = CKEDITOR.tools.createClass( {
-		/**
-		 * @constructor Creates a filter class instance.
-		 * @param {CKEDITOR.htmlParser.filterRulesDefinition} [rules]
-		 */
-		$: function( rules ) {
-			/**
-			 * ID of filter instance, which is used to mark elements
-			 * to which this filter has been already applied.
-			 *
-			 * @property {Number} id
-			 * @readonly
-			 */
-			this.id = CKEDITOR.tools.getNextNumber();
-
-			/**
-			 * Rules for element names.
-			 *
-			 * @property {CKEDITOR.htmlParser.filterRulesGroup}
-			 * @readonly
-			 */
-			this.elementNameRules = new filterRulesGroup();
-
-			/**
-			 * Rules for attribute names.
-			 *
-			 * @property {CKEDITOR.htmlParser.filterRulesGroup}
-			 * @readonly
-			 */
-			this.attributeNameRules = new filterRulesGroup();
-
-			/**
-			 * Hash of elementName => {@link CKEDITOR.htmlParser.filterRulesGroup rules for elements}.
-			 *
-			 * @readonly
-			 */
-			this.elementsRules = {};
-
-			/**
-			 * Hash of attributeName => {@link CKEDITOR.htmlParser.filterRulesGroup rules for attributes}.
-			 *
-			 * @readonly
-			 */
-			this.attributesRules = {};
-
-			/**
-			 * Rules for text nodes.
-			 *
-			 * @property {CKEDITOR.htmlParser.filterRulesGroup}
-			 * @readonly
-			 */
-			this.textRules = new filterRulesGroup();
-
-			/**
-			 * Rules for comment nodes.
-			 *
-			 * @property {CKEDITOR.htmlParser.filterRulesGroup}
-			 * @readonly
-			 */
-			this.commentRules = new filterRulesGroup();
-
-			/**
-			 * Rules for a root node.
-			 *
-			 * @property {CKEDITOR.htmlParser.filterRulesGroup}
-			 * @readonly
-			 */
-			this.rootRules = new filterRulesGroup();
-
-			if ( rules )
-				this.addRules( rules, 10 );
-		},
-
-		proto: {
-			/**
-			 * Add rules to this filter.
-			 *
-			 * @param {CKEDITOR.htmlParser.filterRulesDefinition} rules Object containing filter rules.
-			 * @param {Object/Number} [options] Object containing rules' options or a priority
-			 * (for a backward compatibility with CKEditor versions up to 4.2.x).
-			 * @param {Number} [options.priority=10] The priority of a rule.
-			 * @param {Boolean} [options.applyToAll=false] Whether to apply rule to non-editable
-			 * elements and their descendants too.
-			 */
-			addRules: function( rules, options ) {
-				var priority;
-
-				// Backward compatibility.
-				if ( typeof options == 'number' )
-					priority = options;
-				// New version - try reading from options.
-				else if ( options && ( 'priority' in options ) )
-					priority = options.priority;
-
-				// Defaults.
-				if ( typeof priority != 'number' )
-					priority = 10;
-				if ( typeof options != 'object' )
-					options = {};
-
-				// Add the elementNames.
-				if ( rules.elementNames )
-					this.elementNameRules.addMany( rules.elementNames, priority, options );
-
-				// Add the attributeNames.
-				if ( rules.attributeNames )
-					this.attributeNameRules.addMany( rules.attributeNames, priority, options );
-
-				// Add the elements.
-				if ( rules.elements )
-					addNamedRules( this.elementsRules, rules.elements, priority, options );
-
-				// Add the attributes.
-				if ( rules.attributes )
-					addNamedRules( this.attributesRules, rules.attributes, priority, options );
-
-				// Add the text.
-				if ( rules.text )
-					this.textRules.add( rules.text, priority, options );
-
-				// Add the comment.
-				if ( rules.comment )
-					this.commentRules.add( rules.comment, priority, options );
-
-				// Add root node rules.
-				if ( rules.root )
-					this.rootRules.add( rules.root, priority, options );
-			},
-
-			/**
-			 * Apply this filter to given node.
-			 *
-			 * @param {CKEDITOR.htmlParser.node} node The node to be filtered.
-			 */
-			applyTo: function( node ) {
-				node.filter( this );
-			},
-
-			onElementName: function( context, name ) {
-				return this.elementNameRules.execOnName( context, name );
-			},
-
-			onAttributeName: function( context, name ) {
-				return this.attributeNameRules.execOnName( context, name );
-			},
-
-			onText: function( context, text ) {
-				return this.textRules.exec( context, text );
-			},
-
-			onComment: function( context, commentText, comment ) {
-				return this.commentRules.exec( context, commentText, comment );
-			},
-
-			onRoot: function( context, element ) {
-				return this.rootRules.exec( context, element );
-			},
-
-			onElement: function( context, element ) {
-				// We must apply filters set to the specific element name as
-				// well as those set to the generic ^/$ name. So, add both to an
-				// array and process them in a small loop.
-				var rulesGroups = [ this.elementsRules[ '^' ], this.elementsRules[ element.name ], this.elementsRules.$ ],
-					rulesGroup, ret;
-
-				for ( var i = 0; i < 3; i++ ) {
-					rulesGroup = rulesGroups[ i ];
-					if ( rulesGroup ) {
-						ret = rulesGroup.exec( context, element, this );
-
-						if ( ret === false )
-							return null;
-
-						if ( ret && ret != element )
-							return this.onNode( context, ret );
-
-						// The non-root element has been dismissed by one of the filters.
-						if ( element.parent && !element.name )
-							break;
-					}
-				}
-
-				return element;
-			},
-
-			onNode: function( context, node ) {
-				var type = node.type;
-
-				return type == CKEDITOR.NODE_ELEMENT ? this.onElement( context, node ) :
-					type == CKEDITOR.NODE_TEXT ? new CKEDITOR.htmlParser.text( this.onText( context, node.value ) ) :
-					type == CKEDITOR.NODE_COMMENT ? new CKEDITOR.htmlParser.comment( this.onComment( context, node.value ) ) : null;
-			},
-
-			onAttribute: function( context, element, name, value ) {
-				var rulesGroup = this.attributesRules[ name ];
-
-				if ( rulesGroup )
-					return rulesGroup.exec( context, value, element, this );
-				return value;
-			}
-		}
-	} );
-
-	/**
-	 * Class grouping filter rules for one subject (like element or attribute names).
-	 *
-	 * @class CKEDITOR.htmlParser.filterRulesGroup
-	 */
-	function filterRulesGroup() {
-		/**
-		 * Array of objects containing rule, priority and options.
-		 *
-		 * @property {Object[]}
-		 * @readonly
-		 */
-		this.rules = [];
-	}
-
-	CKEDITOR.htmlParser.filterRulesGroup = filterRulesGroup;
-
-	filterRulesGroup.prototype = {
-		/**
-		 * Adds specified rule to this group.
-		 *
-		 * @param {Function/Array} rule Function for function based rule or [ pattern, replacement ] array for
-		 * rule applicable to names.
-		 * @param {Number} priority
-		 * @param options
-		 */
-		add: function( rule, priority, options ) {
-			this.rules.splice( this.findIndex( priority ), 0, {
-				value: rule,
-				priority: priority,
-				options: options
-			} );
-		},
-
-		/**
-		 * Adds specified rules to this group.
-		 *
-		 * @param {Array} rules Array of rules - see {@link #add}.
-		 * @param {Number} priority
-		 * @param options
-		 */
-		addMany: function( rules, priority, options ) {
-			var args = [ this.findIndex( priority ), 0 ];
-
-			for ( var i = 0, len = rules.length; i < len; i++ ) {
-				args.push( {
-					value: rules[ i ],
-					priority: priority,
-					options: options
-				} );
-			}
-
-			this.rules.splice.apply( this.rules, args );
-		},
-
-		/**
-		 * Finds an index at which rule with given priority should be inserted.
-		 *
-		 * @param {Number} priority
-		 * @returns {Number} Index.
-		 */
-		findIndex: function( priority ) {
-			var rules = this.rules,
-				len = rules.length,
-				i = len - 1;
-
-			// Search from the end, because usually rules will be added with default priority, so
-			// we will be able to stop loop quickly.
-			while ( i >= 0 && priority < rules[ i ].priority )
-				i--;
-
-			return i + 1;
-		},
-
-		/**
-		 * Executes this rules group on given value. Applicable only if function based rules were added.
-		 *
-		 * All arguments passed to this function will be forwarded to rules' functions.
-		 *
-		 * @param {CKEDITOR.htmlParser.node/CKEDITOR.htmlParser.fragment/String} currentValue The value to be filtered.
-		 * @returns {CKEDITOR.htmlParser.node/CKEDITOR.htmlParser.fragment/String} Filtered value.
-		 */
-		exec: function( context, currentValue ) {
-			var isNode = currentValue instanceof CKEDITOR.htmlParser.node || currentValue instanceof CKEDITOR.htmlParser.fragment,
-				// Splice '1' to remove context, which we don't want to pass to filter rules.
-				args = Array.prototype.slice.call( arguments, 1 ),
-				rules = this.rules,
-				len = rules.length,
-				orgType, orgName, ret, i, rule;
-
-			for ( i = 0; i < len; i++ ) {
-				// Backup the node info before filtering.
-				if ( isNode ) {
-					orgType = currentValue.type;
-					orgName = currentValue.name;
-				}
-
-				rule = rules[ i ];
-				if ( isRuleApplicable( context, rule ) ) {
-					ret = rule.value.apply( null, args );
-
-					if ( ret === false )
-						return ret;
-
-					// We're filtering node (element/fragment).
-					// No further filtering if it's not anymore fitable for the subsequent filters.
-					if ( isNode && ret && ( ret.name != orgName || ret.type != orgType ) )
-						return ret;
-
-					// Update currentValue and corresponding argument in args array.
-					// Updated values will be used in next for-loop step.
-					if ( ret != undefined )
-						args[ 0 ] = currentValue = ret;
-
-					// ret == undefined will continue loop as nothing has happened.
-				}
-			}
-
-			return currentValue;
-		},
-
-		/**
-		 * Executes this rules group on name. Applicable only if filter rules for names were added.
-		 *
-		 * @param {String} currentName The name to be filtered.
-		 * @returns {String} Filtered name.
-		 */
-		execOnName: function( context, currentName ) {
-			var i = 0,
-				rules = this.rules,
-				len = rules.length,
-				rule;
-
-			for ( ; currentName && i < len; i++ ) {
-				rule = rules[ i ];
-				if ( isRuleApplicable( context, rule ) )
-					currentName = currentName.replace( rule.value[ 0 ], rule.value[ 1 ] );
-			}
-
-			return currentName;
-		}
-	};
-
-	function addNamedRules( rulesGroups, newRules, priority, options ) {
-		var ruleName, rulesGroup;
-
-		for ( ruleName in newRules ) {
-			rulesGroup = rulesGroups[ ruleName ];
-
-			if ( !rulesGroup )
-				rulesGroup = rulesGroups[ ruleName ] = new filterRulesGroup();
-
-			rulesGroup.add( newRules[ ruleName ], priority, options );
-		}
-	}
-
-	function isRuleApplicable( context, rule ) {
-		if ( context.nonEditable && !rule.options.applyToAll )
-			return false;
-
-		if ( context.nestedEditable && rule.options.excludeNestedEditable )
-			return false;
-
-		return true;
-	}
-
-} )();
-
-/**
- * @class CKEDITOR.htmlParser.filterRulesDefinition
- * @abstract
- */

+ 0 - 631
htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/fragment.js

@@ -1,631 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-'use strict';
-
-/**
- * A lightweight representation of an HTML DOM structure.
- *
- * @class
- * @constructor Creates a fragment class instance.
- */
-CKEDITOR.htmlParser.fragment = function() {
-	/**
-	 * The nodes contained in the root of this fragment.
-	 *
-	 *		var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<b>Sample</b> Text' );
-	 *		alert( fragment.children.length ); // 2
-	 */
-	this.children = [];
-
-	/**
-	 * Get the fragment parent. Should always be null.
-	 *
-	 * @property {Object} [=null]
-	 */
-	this.parent = null;
-
-	/** @private */
-	this._ = {
-		isBlockLike: true,
-		hasInlineStarted: false
-	};
-};
-
-( function() {
-	// Block-level elements whose internal structure should be respected during
-	// parser fixing.
-	var nonBreakingBlocks = CKEDITOR.tools.extend( { table: 1, ul: 1, ol: 1, dl: 1 }, CKEDITOR.dtd.table, CKEDITOR.dtd.ul, CKEDITOR.dtd.ol, CKEDITOR.dtd.dl );
-
-	var listBlocks = { ol: 1, ul: 1 };
-
-	// Dtd of the fragment element, basically it accept anything except for intermediate structure, e.g. orphan <li>.
-	var rootDtd = CKEDITOR.tools.extend( {}, { html: 1 }, CKEDITOR.dtd.html, CKEDITOR.dtd.body, CKEDITOR.dtd.head, { style: 1, script: 1 } );
-
-	function isRemoveEmpty( node ) {
-		// Keep marked element event if it is empty.
-		if ( node.attributes[ 'data-cke-survive' ] )
-			return false;
-
-		// Empty link is to be removed when empty but not anchor. (#7894)
-		return node.name == 'a' && node.attributes.href || CKEDITOR.dtd.$removeEmpty[ node.name ];
-	}
-
-	/**
-	 * Creates a {@link CKEDITOR.htmlParser.fragment} from an HTML string.
-	 *
-	 *		var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<b>Sample</b> Text' );
-	 *		alert( fragment.children[ 0 ].name );		// 'b'
-	 *		alert( fragment.children[ 1 ].value );	// ' Text'
-	 *
-	 * @static
-	 * @param {String} fragmentHtml The HTML to be parsed, filling the fragment.
-	 * @param {CKEDITOR.htmlParser.element/String} [parent] Optional contextual
-	 * element which makes the content been parsed as the content of this element and fix
-	 * to match it.
-	 * If not provided, then {@link CKEDITOR.htmlParser.fragment} will be used
-	 * as the parent and it will be returned.
-	 * @param {String/Boolean} [fixingBlock] When `parent` is a block limit element,
-	 * and the param is a string value other than `false`, it is to
-	 * avoid having block-less content as the direct children of parent by wrapping
-	 * the content with a block element of the specified tag, e.g.
-	 * when `fixingBlock` specified as `p`, the content `<body><i>foo</i></body>`
-	 * will be fixed into `<body><p><i>foo</i></p></body>`.
-	 * @returns {CKEDITOR.htmlParser.fragment/CKEDITOR.htmlParser.element} The created fragment or passed `parent`.
-	 */
-	CKEDITOR.htmlParser.fragment.fromHtml = function( fragmentHtml, parent, fixingBlock ) {
-		var parser = new CKEDITOR.htmlParser();
-
-		var root = parent instanceof CKEDITOR.htmlParser.element ? parent : typeof parent == 'string' ? new CKEDITOR.htmlParser.element( parent ) : new CKEDITOR.htmlParser.fragment();
-
-		var pendingInline = [],
-			pendingBRs = [],
-			currentNode = root,
-			// Indicate we're inside a <textarea> element, spaces should be touched differently.
-			inTextarea = root.name == 'textarea',
-			// Indicate we're inside a <pre> element, spaces should be touched differently.
-			inPre = root.name == 'pre';
-
-		function checkPending( newTagName ) {
-			var pendingBRsSent;
-
-			if ( pendingInline.length > 0 ) {
-				for ( var i = 0; i < pendingInline.length; i++ ) {
-					var pendingElement = pendingInline[ i ],
-						pendingName = pendingElement.name,
-						pendingDtd = CKEDITOR.dtd[ pendingName ],
-						currentDtd = currentNode.name && CKEDITOR.dtd[ currentNode.name ];
-
-					if ( ( !currentDtd || currentDtd[ pendingName ] ) && ( !newTagName || !pendingDtd || pendingDtd[ newTagName ] || !CKEDITOR.dtd[ newTagName ] ) ) {
-						if ( !pendingBRsSent ) {
-							sendPendingBRs();
-							pendingBRsSent = 1;
-						}
-
-						// Get a clone for the pending element.
-						pendingElement = pendingElement.clone();
-
-						// Add it to the current node and make it the current,
-						// so the new element will be added inside of it.
-						pendingElement.parent = currentNode;
-						currentNode = pendingElement;
-
-						// Remove the pending element (back the index by one
-						// to properly process the next entry).
-						pendingInline.splice( i, 1 );
-						i--;
-					} else {
-						// Some element of the same type cannot be nested, flat them,
-						// e.g. <a href="#">foo<a href="#">bar</a></a>. (#7894)
-						if ( pendingName == currentNode.name )
-							addElement( currentNode, currentNode.parent, 1 ), i--;
-					}
-				}
-			}
-		}
-
-		function sendPendingBRs() {
-			while ( pendingBRs.length )
-				addElement( pendingBRs.shift(), currentNode );
-		}
-
-		// Rtrim empty spaces on block end boundary. (#3585)
-		function removeTailWhitespace( element ) {
-			if ( element._.isBlockLike && element.name != 'pre' && element.name != 'textarea' ) {
-
-				var length = element.children.length,
-					lastChild = element.children[ length - 1 ],
-					text;
-				if ( lastChild && lastChild.type == CKEDITOR.NODE_TEXT ) {
-					if ( !( text = CKEDITOR.tools.rtrim( lastChild.value ) ) )
-						element.children.length = length - 1;
-					else
-						lastChild.value = text;
-				}
-			}
-		}
-
-		// Beside of simply append specified element to target, this function also takes
-		// care of other dirty lifts like forcing block in body, trimming spaces at
-		// the block boundaries etc.
-		//
-		// @param {Element} element  The element to be added as the last child of {@link target}.
-		// @param {Element} target The parent element to relieve the new node.
-		// @param {Boolean} [moveCurrent=false] Don't change the "currentNode" global unless
-		// there's a return point node specified on the element, otherwise move current onto {@link target} node.
-		//
-		function addElement( element, target, moveCurrent ) {
-			target = target || currentNode || root;
-
-			// Current element might be mangled by fix body below,
-			// save it for restore later.
-			var savedCurrent = currentNode;
-
-			// Ignore any element that has already been added.
-			if ( element.previous === undefined ) {
-				if ( checkAutoParagraphing( target, element ) ) {
-					// Create a <p> in the fragment.
-					currentNode = target;
-					parser.onTagOpen( fixingBlock, {} );
-
-					// The new target now is the <p>.
-					element.returnPoint = target = currentNode;
-				}
-
-				removeTailWhitespace( element );
-
-				// Avoid adding empty inline.
-				if ( !( isRemoveEmpty( element ) && !element.children.length ) )
-					target.add( element );
-
-				if ( element.name == 'pre' )
-					inPre = false;
-
-				if ( element.name == 'textarea' )
-					inTextarea = false;
-			}
-
-			if ( element.returnPoint ) {
-				currentNode = element.returnPoint;
-				delete element.returnPoint;
-			} else
-				currentNode = moveCurrent ? target : savedCurrent;
-		}
-
-		// Auto paragraphing should happen when inline content enters the root element.
-		function checkAutoParagraphing( parent, node ) {
-
-			// Check for parent that can contain block.
-			if ( ( parent == root || parent.name == 'body' ) && fixingBlock &&
-					 ( !parent.name || CKEDITOR.dtd[ parent.name ][ fixingBlock ] ) )
-			{
-				var name, realName;
-				if ( node.attributes && ( realName = node.attributes[ 'data-cke-real-element-type' ] ) )
-					name = realName;
-				else
-					name = node.name;
-
-				// Text node, inline elements are subjected, except for <script>/<style>.
-				return name && name in CKEDITOR.dtd.$inline &&
-				       !( name in CKEDITOR.dtd.head ) &&
-				       !node.isOrphan ||
-				       node.type == CKEDITOR.NODE_TEXT;
-			}
-		}
-
-		// Judge whether two element tag names are likely the siblings from the same
-		// structural element.
-		function possiblySibling( tag1, tag2 ) {
-
-			if ( tag1 in CKEDITOR.dtd.$listItem || tag1 in CKEDITOR.dtd.$tableContent )
-				return tag1 == tag2 || tag1 == 'dt' && tag2 == 'dd' || tag1 == 'dd' && tag2 == 'dt';
-
-			return false;
-		}
-
-		parser.onTagOpen = function( tagName, attributes, selfClosing, optionalClose ) {
-			var element = new CKEDITOR.htmlParser.element( tagName, attributes );
-
-			// "isEmpty" will be always "false" for unknown elements, so we
-			// must force it if the parser has identified it as a selfClosing tag.
-			if ( element.isUnknown && selfClosing )
-				element.isEmpty = true;
-
-			// Check for optional closed elements, including browser quirks and manually opened blocks.
-			element.isOptionalClose = optionalClose;
-
-			// This is a tag to be removed if empty, so do not add it immediately.
-			if ( isRemoveEmpty( element ) ) {
-				pendingInline.push( element );
-				return;
-			} else if ( tagName == 'pre' )
-				inPre = true;
-			else if ( tagName == 'br' && inPre ) {
-				currentNode.add( new CKEDITOR.htmlParser.text( '\n' ) );
-				return;
-			} else if ( tagName == 'textarea' )
-				inTextarea = true;
-
-			if ( tagName == 'br' ) {
-				pendingBRs.push( element );
-				return;
-			}
-
-			while ( 1 ) {
-				var currentName = currentNode.name;
-
-				var currentDtd = currentName ? ( CKEDITOR.dtd[ currentName ] || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ) ) : rootDtd;
-
-				// If the element cannot be child of the current element.
-				if ( !element.isUnknown && !currentNode.isUnknown && !currentDtd[ tagName ] ) {
-					// Current node doesn't have a close tag, time for a close
-					// as this element isn't fit in. (#7497)
-					if ( currentNode.isOptionalClose )
-						parser.onTagClose( currentName );
-					// Fixing malformed nested lists by moving it into a previous list item. (#3828)
-					else if ( tagName in listBlocks && currentName in listBlocks ) {
-						var children = currentNode.children,
-							lastChild = children[ children.length - 1 ];
-
-						// Establish the list item if it's not existed.
-						if ( !( lastChild && lastChild.name == 'li' ) )
-							addElement( ( lastChild = new CKEDITOR.htmlParser.element( 'li' ) ), currentNode );
-
-						!element.returnPoint && ( element.returnPoint = currentNode );
-						currentNode = lastChild;
-					}
-					// Establish new list root for orphan list items, but NOT to create
-					// new list for the following ones, fix them instead. (#6975)
-					// <dl><dt>foo<dd>bar</dl>
-					// <ul><li>foo<li>bar</ul>
-					else if ( tagName in CKEDITOR.dtd.$listItem &&
-							!possiblySibling( tagName, currentName ) ) {
-						parser.onTagOpen( tagName == 'li' ? 'ul' : 'dl', {}, 0, 1 );
-					}
-					// We're inside a structural block like table and list, AND the incoming element
-					// is not of the same type (e.g. <td>td1<td>td2</td>), we simply add this new one before it,
-					// and most importantly, return back to here once this element is added,
-					// e.g. <table><tr><td>td1</td><p>p1</p><td>td2</td></tr></table>
-					else if ( currentName in nonBreakingBlocks &&
-							!possiblySibling( tagName, currentName ) ) {
-						!element.returnPoint && ( element.returnPoint = currentNode );
-						currentNode = currentNode.parent;
-					} else {
-						// The current element is an inline element, which
-						// need to be continued even after the close, so put
-						// it in the pending list.
-						if ( currentName in CKEDITOR.dtd.$inline )
-							pendingInline.unshift( currentNode );
-
-						// The most common case where we just need to close the
-						// current one and append the new one to the parent.
-						if ( currentNode.parent )
-							addElement( currentNode, currentNode.parent, 1 );
-						// We've tried our best to fix the embarrassment here, while
-						// this element still doesn't find it's parent, mark it as
-						// orphan and show our tolerance to it.
-						else {
-							element.isOrphan = 1;
-							break;
-						}
-					}
-				} else
-					break;
-			}
-
-			checkPending( tagName );
-			sendPendingBRs();
-
-			element.parent = currentNode;
-
-			if ( element.isEmpty )
-				addElement( element );
-			else
-				currentNode = element;
-		};
-
-		parser.onTagClose = function( tagName ) {
-			// Check if there is any pending tag to be closed.
-			for ( var i = pendingInline.length - 1; i >= 0; i-- ) {
-				// If found, just remove it from the list.
-				if ( tagName == pendingInline[ i ].name ) {
-					pendingInline.splice( i, 1 );
-					return;
-				}
-			}
-
-			var pendingAdd = [],
-				newPendingInline = [],
-				candidate = currentNode;
-
-			while ( candidate != root && candidate.name != tagName ) {
-				// If this is an inline element, add it to the pending list, if we're
-				// really closing one of the parents element later, they will continue
-				// after it.
-				if ( !candidate._.isBlockLike )
-					newPendingInline.unshift( candidate );
-
-				// This node should be added to it's parent at this point. But,
-				// it should happen only if the closing tag is really closing
-				// one of the nodes. So, for now, we just cache it.
-				pendingAdd.push( candidate );
-
-				// Make sure return point is properly restored.
-				candidate = candidate.returnPoint || candidate.parent;
-			}
-
-			if ( candidate != root ) {
-				// Add all elements that have been found in the above loop.
-				for ( i = 0; i < pendingAdd.length; i++ ) {
-					var node = pendingAdd[ i ];
-					addElement( node, node.parent );
-				}
-
-				currentNode = candidate;
-
-				if ( candidate._.isBlockLike )
-					sendPendingBRs();
-
-				addElement( candidate, candidate.parent );
-
-				// The parent should start receiving new nodes now, except if
-				// addElement changed the currentNode.
-				if ( candidate == currentNode )
-					currentNode = currentNode.parent;
-
-				pendingInline = pendingInline.concat( newPendingInline );
-			}
-
-			if ( tagName == 'body' )
-				fixingBlock = false;
-		};
-
-		parser.onText = function( text ) {
-			// Trim empty spaces at beginning of text contents except <pre> and <textarea>.
-			if ( ( !currentNode._.hasInlineStarted || pendingBRs.length ) && !inPre && !inTextarea ) {
-				text = CKEDITOR.tools.ltrim( text );
-
-				if ( text.length === 0 )
-					return;
-			}
-
-			var currentName = currentNode.name,
-				currentDtd = currentName ? ( CKEDITOR.dtd[ currentName ] || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ) ) : rootDtd;
-
-			// Fix orphan text in list/table. (#8540) (#8870)
-			if ( !inTextarea && !currentDtd[ '#' ] && currentName in nonBreakingBlocks ) {
-				parser.onTagOpen( currentName in listBlocks ? 'li' : currentName == 'dl' ? 'dd' : currentName == 'table' ? 'tr' : currentName == 'tr' ? 'td' : '' );
-				parser.onText( text );
-				return;
-			}
-
-			sendPendingBRs();
-			checkPending();
-
-			// Shrinking consequential spaces into one single for all elements
-			// text contents.
-			if ( !inPre && !inTextarea )
-				text = text.replace( /[\t\r\n ]{2,}|[\t\r\n]/g, ' ' );
-
-			text = new CKEDITOR.htmlParser.text( text );
-
-
-			if ( checkAutoParagraphing( currentNode, text ) )
-				this.onTagOpen( fixingBlock, {}, 0, 1 );
-
-			currentNode.add( text );
-		};
-
-		parser.onCDATA = function( cdata ) {
-			currentNode.add( new CKEDITOR.htmlParser.cdata( cdata ) );
-		};
-
-		parser.onComment = function( comment ) {
-			sendPendingBRs();
-			checkPending();
-			currentNode.add( new CKEDITOR.htmlParser.comment( comment ) );
-		};
-
-		// Parse it.
-		parser.parse( fragmentHtml );
-
-		sendPendingBRs();
-
-		// Close all pending nodes, make sure return point is properly restored.
-		while ( currentNode != root )
-			addElement( currentNode, currentNode.parent, 1 );
-
-		removeTailWhitespace( root );
-
-		return root;
-	};
-
-	CKEDITOR.htmlParser.fragment.prototype = {
-
-		/**
-		 * The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
-		 *
-		 * @readonly
-		 * @property {Number} [=CKEDITOR.NODE_DOCUMENT_FRAGMENT]
-		 */
-		type: CKEDITOR.NODE_DOCUMENT_FRAGMENT,
-
-		/**
-		 * Adds a node to this fragment.
-		 *
-		 * @param {CKEDITOR.htmlParser.node} node The node to be added.
-		 * @param {Number} [index] From where the insertion happens.
-		 */
-		add: function( node, index ) {
-			isNaN( index ) && ( index = this.children.length );
-
-			var previous = index > 0 ? this.children[ index - 1 ] : null;
-			if ( previous ) {
-				// If the block to be appended is following text, trim spaces at
-				// the right of it.
-				if ( node._.isBlockLike && previous.type == CKEDITOR.NODE_TEXT ) {
-					previous.value = CKEDITOR.tools.rtrim( previous.value );
-
-					// If we have completely cleared the previous node.
-					if ( previous.value.length === 0 ) {
-						// Remove it from the list and add the node again.
-						this.children.pop();
-						this.add( node );
-						return;
-					}
-				}
-
-				previous.next = node;
-			}
-
-			node.previous = previous;
-			node.parent = this;
-
-			this.children.splice( index, 0, node );
-
-			if ( !this._.hasInlineStarted )
-				this._.hasInlineStarted = node.type == CKEDITOR.NODE_TEXT || ( node.type == CKEDITOR.NODE_ELEMENT && !node._.isBlockLike );
-		},
-
-		/**
-		 * Filter this fragment's content with given filter.
-		 *
-		 * @since 4.1
-		 * @param {CKEDITOR.htmlParser.filter} filter
-		 */
-		filter: function( filter, context ) {
-			context = this.getFilterContext( context );
-
-			// Apply the root filter.
-			filter.onRoot( context, this );
-
-			this.filterChildren( filter, false, context );
-		},
-
-		/**
-		 * Filter this fragment's children with given filter.
-		 *
-		 * Element's children may only be filtered once by one
-		 * instance of filter.
-		 *
-		 * @since 4.1
-		 * @param {CKEDITOR.htmlParser.filter} filter
-		 * @param {Boolean} [filterRoot] Whether to apply the "root" filter rule specified in the `filter`.
-		 */
-		filterChildren: function( filter, filterRoot, context ) {
-			// If this element's children were already filtered
-			// by current filter, don't filter them 2nd time.
-			// This situation may occur when filtering bottom-up
-			// (filterChildren() called manually in element's filter),
-			// or in unpredictable edge cases when filter
-			// is manipulating DOM structure.
-			if ( this.childrenFilteredBy == filter.id )
-				return;
-
-			context = this.getFilterContext( context );
-
-			// Filtering root if enforced.
-			if ( filterRoot && !this.parent )
-				filter.onRoot( context, this );
-
-			this.childrenFilteredBy = filter.id;
-
-			// Don't cache anything, children array may be modified by filter rule.
-			for ( var i = 0; i < this.children.length; i++ ) {
-				// Stay in place if filter returned false, what means
-				// that node has been removed.
-				if ( this.children[ i ].filter( filter, context ) === false )
-					i--;
-			}
-		},
-
-		/**
-		 * Writes the fragment HTML to a {@link CKEDITOR.htmlParser.basicWriter}.
-		 *
-		 *		var writer = new CKEDITOR.htmlWriter();
-		 *		var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<P><B>Example' );
-		 *		fragment.writeHtml( writer );
-		 *		alert( writer.getHtml() ); // '<p><b>Example</b></p>'
-		 *
-		 * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
-		 * @param {CKEDITOR.htmlParser.filter} [filter] The filter to use when writing the HTML.
-		 */
-		writeHtml: function( writer, filter ) {
-			if ( filter )
-				this.filter( filter );
-
-			this.writeChildrenHtml( writer );
-		},
-
-		/**
-		 * Write and filtering the child nodes of this fragment.
-		 *
-		 * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
-		 * @param {CKEDITOR.htmlParser.filter} [filter] The filter to use when writing the HTML.
-		 * @param {Boolean} [filterRoot] Whether to apply the "root" filter rule specified in the `filter`.
-		 */
-		writeChildrenHtml: function( writer, filter, filterRoot ) {
-			var context = this.getFilterContext();
-
-			// Filtering root if enforced.
-			if ( filterRoot && !this.parent && filter )
-				filter.onRoot( context, this );
-
-			if ( filter )
-				this.filterChildren( filter, false, context );
-
-			for ( var i = 0, children = this.children, l = children.length; i < l; i++ )
-				children[ i ].writeHtml( writer );
-		},
-
-		/**
-		 * Execute callback on each node (of given type) in this document fragment.
-		 *
-		 *		var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<p>foo<b>bar</b>bom</p>' );
-		 *		fragment.forEach( function( node ) {
-		 *			console.log( node );
-		 *		} );
-		 *		// Will log:
-		 *		// 1. document fragment,
-		 *		// 2. <p> element,
-		 *		// 3. "foo" text node,
-		 *		// 4. <b> element,
-		 *		// 5. "bar" text node,
-		 *		// 6. "bom" text node.
-		 *
-		 * @since 4.1
-		 * @param {Function} callback Function to be executed on every node.
-		 * **Since 4.3** if `callback` returned `false` descendants of current node will be ignored.
-		 * @param {CKEDITOR.htmlParser.node} callback.node Node passed as argument.
-		 * @param {Number} [type] If specified `callback` will be executed only on nodes of this type.
-		 * @param {Boolean} [skipRoot] Don't execute `callback` on this fragment.
-		 */
-		forEach: function( callback, type, skipRoot ) {
-			if ( !skipRoot && ( !type || this.type == type ) )
-				var ret = callback( this );
-
-			// Do not filter children if callback returned false.
-			if ( ret === false )
-				return;
-
-			var children = this.children,
-				node,
-				i = 0;
-
-			// We do not cache the size, because the list of nodes may be changed by the callback.
-			for ( ; i < children.length; i++ ) {
-				node = children[ i ];
-				if ( node.type == CKEDITOR.NODE_ELEMENT )
-					node.forEach( callback, type );
-				else if ( !type || node.type == type )
-					callback( node );
-			}
-		},
-
-		getFilterContext: function( context ) {
-			return context || {};
-		}
-	};
-} )();

+ 0 - 150
htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/node.js

@@ -1,150 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-'use strict';
-
-( function() {
-	/**
-	 * A lightweight representation of HTML node.
-	 *
-	 * @since 4.1
-	 * @class
-	 * @constructor Creates a node class instance.
-	 */
-	CKEDITOR.htmlParser.node = function() {};
-
-	CKEDITOR.htmlParser.node.prototype = {
-		/**
-		 * Remove this node from a tree.
-		 *
-		 * @since 4.1
-		 */
-		remove: function() {
-			var children = this.parent.children,
-				index = CKEDITOR.tools.indexOf( children, this ),
-				previous = this.previous,
-				next = this.next;
-
-			previous && ( previous.next = next );
-			next && ( next.previous = previous );
-			children.splice( index, 1 );
-			this.parent = null;
-		},
-
-		/**
-		 * Replace this node with given one.
-		 *
-		 * @since 4.1
-		 * @param {CKEDITOR.htmlParser.node} node The node that will replace this one.
-		 */
-		replaceWith: function( node ) {
-			var children = this.parent.children,
-				index = CKEDITOR.tools.indexOf( children, this ),
-				previous = node.previous = this.previous,
-				next = node.next = this.next;
-
-			previous && ( previous.next = node );
-			next && ( next.previous = node );
-
-			children[ index ] = node;
-
-			node.parent = this.parent;
-			this.parent = null;
-		},
-
-		/**
-		 * Insert this node after given one.
-		 *
-		 * @since 4.1
-		 * @param {CKEDITOR.htmlParser.node} node The node that will precede this element.
-		 */
-		insertAfter: function( node ) {
-			var children = node.parent.children,
-				index = CKEDITOR.tools.indexOf( children, node ),
-				next = node.next;
-
-			children.splice( index + 1, 0, this );
-
-			this.next = node.next;
-			this.previous = node;
-			node.next = this;
-			next && ( next.previous = this );
-
-			this.parent = node.parent;
-		},
-
-		/**
-		 * Insert this node before given one.
-		 *
-		 * @since 4.1
-		 * @param {CKEDITOR.htmlParser.node} node The node that will follow this element.
-		 */
-		insertBefore: function( node ) {
-			var children = node.parent.children,
-				index = CKEDITOR.tools.indexOf( children, node );
-
-			children.splice( index, 0, this );
-
-			this.next = node;
-			this.previous = node.previous;
-			node.previous && ( node.previous.next = this );
-			node.previous = this;
-
-			this.parent = node.parent;
-		},
-
-		/**
-		 * Gets the closest ancestor element of this element which satisfies given condition
-		 *
-		 * @since 4.3
-		 * @param {String/Object/Function} condition Name of an ancestor, hash of names or validator function.
-		 * @returns {CKEDITOR.htmlParser.element} The closest ancestor which satisfies given condition or `null`.
-		 */
-		getAscendant: function( condition ) {
-			var checkFn =
-				typeof condition == 'function' ?	condition :
-				typeof condition == 'string' ?		function( el ) { return el.name == condition; } :
-													function( el ) { return el.name in condition; };
-
-			var parent = this.parent;
-
-			// Parent has to be an element - don't check doc fragment.
-			while ( parent && parent.type == CKEDITOR.NODE_ELEMENT ) {
-				if ( checkFn( parent ) )
-					return parent;
-				parent = parent.parent;
-			}
-
-			return null;
-		},
-
-		/**
-		 * Wraps this element with given `wrapper`.
-		 *
-		 * @since 4.3
-		 * @param {CKEDITOR.htmlParser.element} wrapper The element which will be this element's new parent.
-		 * @returns {CKEDITOR.htmlParser.element} Wrapper.
-		 */
-		wrapWith: function( wrapper ) {
-			this.replaceWith( wrapper );
-			wrapper.add( this );
-			return wrapper;
-		},
-
-		/**
-		 * Gets this node's index in its parent's children array.
-		 *
-		 * @since 4.3
-		 * @returns {Number}
-		 */
-		getIndex: function() {
-			return CKEDITOR.tools.indexOf( this.parent.children, this );
-		},
-
-		getFilterContext: function( context ) {
-			return context || {};
-		}
-	};
-} )();

+ 0 - 70
htdocs/includes/ckeditor/ckeditor/_source/core/htmlparser/text.js

@@ -1,70 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
- 'use strict';
-
-( function() {
-	/**
-	 * A lightweight representation of HTML text.
-	 *
-	 * @class
-	 * @extends CKEDITOR.htmlParser.node
-	 * @constructor Creates a text class instance.
-	 * @param {String} value The text node value.
-	 */
-	CKEDITOR.htmlParser.text = function( value ) {
-		/**
-		 * The text value.
-		 *
-		 * @property {String}
-		 */
-		this.value = value;
-
-		/** @private */
-		this._ = {
-			isBlockLike: false
-		};
-	};
-
-	CKEDITOR.htmlParser.text.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
-		/**
-		 * The node type. This is a constant value set to {@link CKEDITOR#NODE_TEXT}.
-		 *
-		 * @readonly
-		 * @property {Number} [=CKEDITOR.NODE_TEXT]
-		 */
-		type: CKEDITOR.NODE_TEXT,
-
-		/**
-		 * Filter this text node with given filter.
-		 *
-		 * @since 4.1
-		 * @param {CKEDITOR.htmlParser.filter} filter
-		 * @returns {Boolean} Method returns `false` when this text node has
-		 * been removed. This is an information for {@link CKEDITOR.htmlParser.element#filterChildren}
-		 * that it has to repeat filter on current position in parent's children array.
-		 */
-		filter: function( filter, context ) {
-			if ( !( this.value = filter.onText( context, this.value, this ) ) ) {
-				this.remove();
-				return false;
-			}
-		},
-
-		/**
-		 * Writes the HTML representation of this text to a {CKEDITOR.htmlParser.basicWriter}.
-		 *
-		 * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
-		 * @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
-		 * **Note:** it's unsafe to filter offline (not appended) node.
-		 */
-		writeHtml: function( writer, filter ) {
-			if ( filter )
-				this.filter( filter );
-
-			writer.text( this.value );
-		}
-	} );
-} )();

+ 0 - 153
htdocs/includes/ckeditor/ckeditor/_source/core/keystrokehandler.js

@@ -1,153 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * Controls keystrokes typing in an editor instance.
- *
- * @class
- * @constructor Creates a keystrokeHandler class instance.
- * @param {CKEDITOR.editor} editor The editor instance.
- */
-CKEDITOR.keystrokeHandler = function( editor ) {
-	if ( editor.keystrokeHandler )
-		return editor.keystrokeHandler;
-
-	/**
-	 * List of keystrokes associated to commands. Each entry points to the
-	 * command to be executed.
-	 *
-	 * Since CKEditor 4 there's no need to modify this property directly during the runtime.
-	 * Use {@link CKEDITOR.editor#setKeystroke} instead.
-	 */
-	this.keystrokes = {};
-
-	/**
-	 * List of keystrokes that should be blocked if not defined at
-	 * {@link #keystrokes}. In this way it is possible to block the default
-	 * browser behavior for those keystrokes.
-	 */
-	this.blockedKeystrokes = {};
-
-	this._ = {
-		editor: editor
-	};
-
-	return this;
-};
-
-( function() {
-	var cancel;
-
-	var onKeyDown = function( event ) {
-			// The DOM event object is passed by the "data" property.
-			event = event.data;
-
-			var keyCombination = event.getKeystroke();
-			var command = this.keystrokes[ keyCombination ];
-			var editor = this._.editor;
-
-			cancel = ( editor.fire( 'key', { keyCode: keyCombination } ) === false );
-
-			if ( !cancel ) {
-				if ( command ) {
-					var data = { from: 'keystrokeHandler' };
-					cancel = ( editor.execCommand( command, data ) !== false );
-				}
-
-				if ( !cancel )
-					cancel = !!this.blockedKeystrokes[ keyCombination ];
-			}
-
-			if ( cancel )
-				event.preventDefault( true );
-
-			return !cancel;
-		};
-
-	var onKeyPress = function( event ) {
-			if ( cancel ) {
-				cancel = false;
-				event.data.preventDefault( true );
-			}
-		};
-
-	CKEDITOR.keystrokeHandler.prototype = {
-		/**
-		 * Attaches this keystroke handle to a DOM object. Keystrokes typed
-		 * over this object will get handled by this keystrokeHandler.
-		 *
-		 * @param {CKEDITOR.dom.domObject} domObject The DOM object to attach to.
-		 */
-		attach: function( domObject ) {
-			// For most browsers, it is enough to listen to the keydown event
-			// only.
-			domObject.on( 'keydown', onKeyDown, this );
-
-			// Some browsers instead, don't cancel key events in the keydown, but in the
-			// keypress. So we must do a longer trip in those cases.
-			if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) )
-				domObject.on( 'keypress', onKeyPress, this );
-		}
-	};
-} )();
-
-/**
- * A list associating keystrokes to editor commands. Each element in the list
- * is an array where the first item is the keystroke, and the second is the
- * name of the command to be executed.
- *
- * This setting should be used to define (as well as to overwrite or remove) keystrokes
- * set by plugins (like `link` and `basicstyles`). If you want to set a keystroke
- * for your plugin or during the runtime, use {@link CKEDITOR.editor#setKeystroke} instead.
- *
- * Since default keystrokes are set by {@link CKEDITOR.editor#setKeystroke}
- * method, by default `config.keystrokes` is an empty array.
- *
- * See {@link CKEDITOR.editor#setKeystroke} documentation for more details
- * regarding the start up order.
- *
- *		// Change default CTRL + L keystroke for 'link' command to CTRL + SHIFT + L.
- *		config.keystrokes = [
- *			...
- *			[ CKEDITOR.CTRL + CKEDITOR.SHIFT + 76, 'link' ],	// CTRL + SHIFT + L
- *			...
- *		];
- *
- * To reset a particular keystroke, the following approach can be used:
- *
- *		// Disable default CTRL + L keystroke which executes link command by default.
- *		config.keystrokes = [
- *			...
- *			[ CKEDITOR.CTRL + 76, null ],						// CTRL + L
- *			...
- *		];
- *
- * To reset all default keystrokes an {@link CKEDITOR#instanceReady} callback should be
- * used. This is since editor defaults are merged rather than overwritten by
- * user keystrokes.
- *
- * **Note**: This can be potentially harmful for an editor. Avoid this unless you're
- * aware of the consequences.
- *
- *		// Reset all default keystrokes.
- *		config.on.instanceReady = function() {
- *			this.keystrokeHandler.keystrokes = [];
- *		};
- *
- * @cfg {Array} [keystrokes=[]]
- * @member CKEDITOR.config
- */
-
-/**
- * Fired when any keyboard key (or combination) is pressed into the editing area.
- *
- * @event key
- * @member CKEDITOR.editor
- * @param data
- * @param {Number} data.keyCode A number representing the key code (or combination).
- * It is the sum of the current key code and the {@link CKEDITOR#CTRL}, {@link CKEDITOR#SHIFT}
- * and {@link CKEDITOR#ALT} constants, if those are pressed.
- * @param {CKEDITOR.editor} editor This editor instance.
- */

+ 0 - 100
htdocs/includes/ckeditor/ckeditor/_source/core/lang.js

@@ -1,100 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-( function() {
-	var loadedLangs = {};
-
-	/**
-	 * Stores language-related functions.
-	 *
-	 * @class
-	 * @singleton
-	 */
-	CKEDITOR.lang = {
-		/**
-		 * The list of languages available in the editor core.
-		 *
-		 *		alert( CKEDITOR.lang.en ); // 1
-		 */
-		languages: { af: 1, ar: 1, bg: 1, bn: 1, bs: 1, ca: 1, cs: 1, cy: 1, da: 1, de: 1, el: 1,
-			'en-au': 1, 'en-ca': 1, 'en-gb': 1, en: 1, eo: 1, es: 1, et: 1, eu: 1, fa: 1, fi: 1, fo: 1,
-			'fr-ca': 1, fr: 1, gl: 1, gu: 1, he: 1, hi: 1, hr: 1, hu: 1, id: 1, is: 1, it: 1, ja: 1, ka: 1,
-			km: 1, ko: 1, ku: 1, lt: 1, lv: 1, mk: 1, mn: 1, ms: 1, nb: 1, nl: 1, no: 1, pl: 1, 'pt-br': 1,
-			pt: 1, ro: 1, ru: 1, si: 1, sk: 1, sl: 1, sq: 1, 'sr-latn': 1, sr: 1, sv: 1, th: 1, tr: 1, ug: 1,
-			uk: 1, vi: 1, 'zh-cn': 1, zh: 1 },
-
-		/**
-		 * The list of languages that are written Right-To-Left (RTL) and are supported by the editor.
-		 */
-		rtl: { ar: 1, fa: 1, he: 1, ku: 1, ug: 1 },
-
-		/**
-		 * Loads a specific language file, or auto detects it. A callback is
-		 * then called when the file gets loaded.
-		 *
-		 * @param {String} languageCode The code of the language file to be
-		 * loaded. If null or empty, autodetection will be performed. The
-		 * same happens if the language is not supported.
-		 * @param {String} defaultLanguage The language to be used if
-		 * `languageCode` is not supported or if the autodetection fails.
-		 * @param {Function} callback A function to be called once the
-		 * language file is loaded. Two parameters are passed to this
-		 * function: the language code and the loaded language entries.
-		 */
-		load: function( languageCode, defaultLanguage, callback ) {
-			// If no languageCode - fallback to browser or default.
-			// If languageCode - fallback to no-localized version or default.
-			if ( !languageCode || !CKEDITOR.lang.languages[ languageCode ] )
-				languageCode = this.detect( defaultLanguage, languageCode );
-
-			if ( !this[ languageCode ] ) {
-				CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( 'lang/' + languageCode + '.js' ), function() {
-					this[ languageCode ].dir = this.rtl[ languageCode ] ? 'rtl' : 'ltr';
-					callback( languageCode, this[ languageCode ] );
-				}, this );
-			} else
-				callback( languageCode, this[ languageCode ] );
-		},
-
-		/**
-		 * Returns the language that best fits the user language. For example,
-		 * suppose that the user language is "pt-br". If this language is
-		 * supported by the editor, it is returned. Otherwise, if only "pt" is
-		 * supported, it is returned instead. If none of the previous are
-		 * supported, a default language is then returned.
-		 *
-		 *		alert( CKEDITOR.lang.detect( 'en' ) ); // e.g., in a German browser: 'de'
-		 *
-		 * @param {String} defaultLanguage The default language to be returned
-		 * if the user language is not supported.
-		 * @param {String} [probeLanguage] A language code to try to use,
-		 * instead of the browser-based autodetection.
-		 * @returns {String} The detected language code.
-		 */
-		detect: function( defaultLanguage, probeLanguage ) {
-			var languages = this.languages;
-			probeLanguage = probeLanguage || navigator.userLanguage || navigator.language || defaultLanguage;
-
-			var parts = probeLanguage.toLowerCase().match( /([a-z]+)(?:-([a-z]+))?/ ),
-				lang = parts[ 1 ],
-				locale = parts[ 2 ];
-
-			if ( languages[ lang + '-' + locale ] )
-				lang = lang + '-' + locale;
-			else if ( !languages[ lang ] )
-				lang = null;
-
-			CKEDITOR.lang.detect = lang ?
-			function() {
-				return lang;
-			} : function( defaultLanguage ) {
-				return defaultLanguage;
-			};
-
-			return lang || defaultLanguage;
-		}
-	};
-
-} )();

+ 0 - 247
htdocs/includes/ckeditor/ckeditor/_source/core/loader.js

@@ -1,247 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.loader} objects, which is used to
- *		load core scripts and their dependencies from _source.
- */
-
-if ( typeof CKEDITOR == 'undefined' )
-	CKEDITOR = {};
-
-if ( !CKEDITOR.loader ) {
-	/**
-	 * Load core scripts and their dependencies from _source.
-	 *
-	 * @class
-	 * @singleton
-	 */
-	CKEDITOR.loader = ( function() {
-		// Table of script names and their dependencies.
-		var scripts = {
-			'_bootstrap': [ 'config', 'creators/inline', 'creators/themedui', 'editable', 'ckeditor', 'plugins', 'scriptloader', 'style', 'tools', /* The following are entries that we want to force loading at the end to avoid dependence recursion */ 'dom/comment', 'dom/elementpath', 'dom/text', 'dom/rangelist', 'skin' ],
-			'ckeditor': [ 'ckeditor_basic', 'dom', 'dtd', 'dom/document', 'dom/element', 'dom/iterator', 'editor', 'event', 'htmldataprocessor', 'htmlparser', 'htmlparser/element', 'htmlparser/fragment', 'htmlparser/filter', 'htmlparser/basicwriter', 'template', 'tools' ],
-			'ckeditor_base': [],
-			'ckeditor_basic': [ 'editor_basic', 'env', 'event' ],
-			'command': [],
-			'config': [ 'ckeditor_base' ],
-			'dom': [],
-			'dom/comment': [ 'dom/node' ],
-			'dom/document': [ 'dom/node', 'dom/window' ],
-			'dom/documentfragment': [ 'dom/element' ],
-			'dom/element': [ 'dom', 'dom/document', 'dom/domobject', 'dom/node', 'dom/nodelist', 'tools' ],
-			'dom/elementpath': [ 'dom/element' ],
-			'dom/event': [],
-			'dom/iterator': [ 'dom/range' ],
-			'dom/node': [ 'dom/domobject', 'tools' ],
-			'dom/nodelist': [ 'dom/node' ],
-			'dom/domobject': [ 'dom/event' ],
-			'dom/range': [ 'dom/document', 'dom/documentfragment', 'dom/element', 'dom/walker' ],
-			'dom/rangelist': [ 'dom/range' ],
-			'dom/text': [ 'dom/node', 'dom/domobject' ],
-			'dom/walker': [ 'dom/node' ],
-			'dom/window': [ 'dom/domobject' ],
-			'dtd': [ 'tools' ],
-			'editable': [ 'editor', 'tools' ],
-			'editor': [ 'command', 'config', 'editor_basic', 'filter', 'focusmanager', 'keystrokehandler', 'lang', 'plugins', 'tools', 'ui' ],
-			'editor_basic': [ 'event' ],
-			'env': [],
-			'event': [],
-			'filter': [ 'dtd', 'tools' ],
-			'focusmanager': [],
-			'htmldataprocessor': [ 'htmlparser', 'htmlparser/basicwriter', 'htmlparser/fragment', 'htmlparser/filter' ],
-			'htmlparser': [],
-			'htmlparser/comment': [ 'htmlparser', 'htmlparser/node' ],
-			'htmlparser/element': [ 'htmlparser', 'htmlparser/fragment', 'htmlparser/node' ],
-			'htmlparser/fragment': [ 'htmlparser', 'htmlparser/comment', 'htmlparser/text', 'htmlparser/cdata' ],
-			'htmlparser/text': [ 'htmlparser', 'htmlparser/node' ],
-			'htmlparser/cdata': [ 'htmlparser', 'htmlparser/node' ],
-			'htmlparser/filter': [ 'htmlparser' ],
-			'htmlparser/basicwriter': [ 'htmlparser' ],
-			'htmlparser/node': [ 'htmlparser' ],
-			'keystrokehandler': [ 'event' ],
-			'lang': [],
-			'plugins': [ 'resourcemanager' ],
-			'resourcemanager': [ 'scriptloader', 'tools' ],
-			'scriptloader': [ 'dom/element', 'env' ],
-			'selection': [ 'dom/range', 'dom/walker' ],
-			'skin': [],
-			'style': [ 'selection' ],
-			'template': [],
-			'tools': [ 'env' ],
-			'ui': [],
-			'creators/themedui': [],
-			'creators/inline': []
-		};
-
-		var basePath = ( function() {
-			// This is a copy of CKEDITOR.basePath, but requires the script having
-			// "_source/loader.js".
-			if ( CKEDITOR && CKEDITOR.basePath )
-				return CKEDITOR.basePath;
-
-			// Find out the editor directory path, based on its <script> tag.
-			var path = '';
-			var scripts = document.getElementsByTagName( 'script' );
-
-			for ( var i = 0; i < scripts.length; i++ ) {
-				var match = scripts[ i ].src.match( /(^|.*?[\\\/])(?:_source\/)?core\/loader.js(?:\?.*)?$/i );
-
-				if ( match ) {
-					path = match[ 1 ];
-					break;
-				}
-			}
-
-			// In IE (only) the script.src string is the raw valued entered in the
-			// HTML. Other browsers return the full resolved URL instead.
-			if ( path.indexOf( '://' ) == -1 ) {
-				// Absolute path.
-				if ( path.indexOf( '/' ) === 0 )
-					path = location.href.match( /^.*?:\/\/[^\/]*/ )[ 0 ] + path;
-				// Relative path.
-				else
-					path = location.href.match( /^[^\?]*\// )[ 0 ] + path;
-			}
-
-			return path;
-		} )();
-
-		var timestamp = ( CKEDITOR && CKEDITOR.timestamp ) || ( new Date() ).valueOf(); // %REMOVE_LINE%
-		/*																				// %REMOVE_LINE%
-		 * The production implementation contains a fixed timestamp						// %REMOVE_LINE%
-		 * generated by the releaser													// %REMOVE_LINE%
-		var timestamp = '%TIMESTAMP%';
-		 */ // %REMOVE_LINE%
-
-		var getUrl = function( resource ) {
-				if ( CKEDITOR && CKEDITOR.getUrl )
-					return CKEDITOR.getUrl( resource );
-
-				return basePath + resource + ( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) + 't=' + timestamp;
-			};
-
-		var pendingLoad = [];
-
-		return {
-			/**
-			 * The list of loaded scripts in their loading order.
-			 *
-			 *		// Alert the loaded script names.
-			 *		alert( CKEDITOR.loader.loadedScripts );
-			 */
-			loadedScripts: [],
-			/**
-			 * Table of script names and their dependencies.
-			 *
-			 * @property {Array}
-			 */
-			scripts: scripts,
-
-			/**
-			 * @todo
-			 */
-			loadPending: function() {
-				var scriptName = pendingLoad.shift();
-
-				if ( !scriptName )
-					return;
-
-				var scriptSrc = getUrl( 'core/' + scriptName + '.js' );
-
-				var script = document.createElement( 'script' );
-				script.type = 'text/javascript';
-				script.src = scriptSrc;
-
-				function onScriptLoaded() {
-					// Append this script to the list of loaded scripts.
-					CKEDITOR.loader.loadedScripts.push( scriptName );
-
-					// Load the next.
-					CKEDITOR.loader.loadPending();
-				}
-
-				// We must guarantee the execution order of the scripts, so we
-				// need to load them one by one. (#4145)
-				// The following if/else block has been taken from the scriptloader core code.
-				if ( typeof( script.onreadystatechange ) !== "undefined" ) {
-					/** @ignore */
-					script.onreadystatechange = function() {
-						if ( script.readyState == 'loaded' || script.readyState == 'complete' ) {
-							script.onreadystatechange = null;
-							onScriptLoaded();
-						}
-					};
-				} else {
-					/** @ignore */
-					script.onload = function() {
-						// Some browsers, such as Safari, may call the onLoad function
-						// immediately. Which will break the loading sequence. (#3661)
-						setTimeout( function() {
-							onScriptLoaded( scriptName );
-						}, 0 );
-					};
-				}
-
-				document.body.appendChild( script );
-			},
-
-			/**
-			 * Loads a specific script, including its dependencies. This is not a
-			 * synchronous loading, which means that the code to be loaded will
-			 * not necessarily be available after this call.
-			 *
-			 *		CKEDITOR.loader.load( 'dom/element' );
-			 *
-			 * @param {String} scriptName
-			 * @param {Boolean} [defer=false]
-			 * @todo params
-			 */
-			load: function( scriptName, defer ) {
-				// Check if the script has already been loaded.
-				if ( ( 's:' + scriptName ) in this.loadedScripts )
-					return;
-
-				// Get the script dependencies list.
-				var dependencies = scripts[ scriptName ];
-				if ( !dependencies )
-					throw 'The script name"' + scriptName + '" is not defined.';
-
-				// Mark the script as loaded, even before really loading it, to
-				// avoid cross references recursion.
-				// Prepend script name with 's:' to avoid conflict with Array's methods.
-				this.loadedScripts[ 's:' + scriptName ] = true;
-
-				// Load all dependencies first.
-				for ( var i = 0; i < dependencies.length; i++ )
-					this.load( dependencies[ i ], true );
-
-				var scriptSrc = getUrl( 'core/' + scriptName + '.js' );
-
-				// Append the <script> element to the DOM.
-				// If the page is fully loaded, we can't use document.write
-				// but if the script is run while the body is loading then it's safe to use it
-				// Unfortunately, Firefox <3.6 doesn't support document.readyState, so it won't get this improvement
-				if ( document.body && ( !document.readyState || document.readyState == 'complete' ) ) {
-					pendingLoad.push( scriptName );
-
-					if ( !defer )
-						this.loadPending();
-				} else {
-					// Append this script to the list of loaded scripts.
-					this.loadedScripts.push( scriptName );
-
-					document.write( '<script src="' + scriptSrc + '" type="text/javascript"><\/script>' );
-				}
-			}
-		};
-	} )();
-}
-
-// Check if any script has been defined for autoload.
-if ( CKEDITOR._autoLoad ) {
-	CKEDITOR.loader.load( CKEDITOR._autoLoad );
-	delete CKEDITOR._autoLoad;
-}

+ 0 - 96
htdocs/includes/ckeditor/ckeditor/_source/core/plugindefinition.js

@@ -1,96 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the "virtual" {@link CKEDITOR.pluginDefinition} class which
- *		contains the defintion of a plugin. This file is for documentation
- *		purposes only.
- */
-
-/**
- * Virtual class which just illustrates the features of plugin objects to be
- * passed to the {@link CKEDITOR.plugins#add} method.
- *
- * This class is not really part of the API, so its constructor should not be called.
- *
- * @class CKEDITOR.pluginDefinition
- * @abstract
- */
-
-/**
- * A list of plugins that are required by this plugin. Note that this property
- * does not determine the loading order of the plugins.
- *
- *		CKEDITOR.plugins.add( 'sample', {
- *			requires: [ 'button', 'selection' ]
- *		} );
- *
- * @property {Array} requires
- */
-
-/**
- * A list of language files available for this plugin. These files are stored inside
- * the `lang` directory inside the plugin directory, follow the name
- * pattern of `langCode.js`, and contain the language definition created with
- * {@link CKEDITOR.plugins#setLang}.
- *
- * When the plugin is being loaded, the editor checks this list to see if
- * a language file of the current editor language ({@link CKEDITOR.editor#langCode})
- * is available, and if so, loads it. Otherwise, the file represented by the first item
- * in the list is loaded.
- *
- *		CKEDITOR.plugins.add( 'sample', {
- *			lang: [ 'en', 'fr' ]
- *		} );
- *
- * @property {Array} lang
- */
-
-/**
- * A function called on initialization of every editor instance created in the
- * page before the {@link #init} call task. The `beforeInit` function will be called for
- * all plugins, after that the `init` function is called for all of them. This
- * feature makes it possible to initialize things that could be used in the
- * `init` function of other plugins.
- *
- *		CKEDITOR.plugins.add( 'sample', {
- *			beforeInit: function( editor ) {
- *				alert( 'Editor "' + editor.name + '" is to be initialized!' );
- *			}
- *		} );
- *
- * @method beforeInit
- * @param {CKEDITOR.editor} editor The editor instance being initialized.
- */
-
-/**
- * Function called on initialization of every editor instance created in the page.
- *
- *		CKEDITOR.plugins.add( 'sample', {
- *			init: function( editor ) {
- *				alert( 'Editor "' + editor.name + '" is being initialized!' );
- *			}
- *		} );
- *
- * @method init
- * @param {CKEDITOR.editor} editor The editor instance being initialized.
- */
-
-/**
- * Announces the plugin as HiDPI-ready (optimized for high pixel density screens, e.g. *Retina*)
- * by providing high-resolution icons and images. HiDPI icons must be twice as big
- * (defaults are `16px x 16px`) and stored under `plugin_name/icons/hidpi/` directory.
- *
- * The common place for additional HiDPI images used by the plugin (**but not icons**)
- * is `plugin_name/images/hidpi/` directory.
- *
- * This property is optional and only makes sense if `32px x 32px` icons
- * and high-resolution images actually exist. If this flag is set `true`, the editor
- * will automatically detect the HiDPI environment and attempt to load the
- * high-resolution resources.
- *
- * @since 4.2
- * @property {Boolean} hidpi
- */

+ 0 - 119
htdocs/includes/ckeditor/ckeditor/_source/core/plugins.js

@@ -1,119 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.plugins} object, which is used to
- *		manage plugins registration and loading.
- */
-
-/**
- * Manages plugins registration and loading.
- *
- * @class
- * @extends CKEDITOR.resourceManager
- * @singleton
- */
-CKEDITOR.plugins = new CKEDITOR.resourceManager( 'plugins/', 'plugin' );
-
-// PACKAGER_RENAME( CKEDITOR.plugins )
-
-CKEDITOR.plugins.load = CKEDITOR.tools.override( CKEDITOR.plugins.load, function( originalLoad ) {
-	var initialized = {};
-
-	return function( name, callback, scope ) {
-		var allPlugins = {};
-
-		var loadPlugins = function( names ) {
-				originalLoad.call( this, names, function( plugins ) {
-					CKEDITOR.tools.extend( allPlugins, plugins );
-
-					var requiredPlugins = [];
-					for ( var pluginName in plugins ) {
-						var plugin = plugins[ pluginName ],
-							requires = plugin && plugin.requires;
-
-						if ( !initialized[ pluginName ] ) {
-							// Register all icons eventually defined by this plugin.
-							if ( plugin.icons ) {
-								var icons = plugin.icons.split( ',' );
-								for ( var ic = icons.length; ic--; ) {
-									CKEDITOR.skin.addIcon( icons[ ic ],
-										plugin.path +
-										'icons/' +
-										( CKEDITOR.env.hidpi && plugin.hidpi ? 'hidpi/' : '' ) +
-										icons[ ic ] +
-										'.png' );
-								}
-							}
-							initialized[ pluginName ] = 1;
-						}
-
-						if ( requires ) {
-							// Trasnform it into an array, if it's not one.
-							if ( requires.split )
-								requires = requires.split( ',' );
-
-							for ( var i = 0; i < requires.length; i++ ) {
-								if ( !allPlugins[ requires[ i ] ] )
-									requiredPlugins.push( requires[ i ] );
-							}
-						}
-					}
-
-					if ( requiredPlugins.length )
-						loadPlugins.call( this, requiredPlugins );
-					else {
-						// Call the "onLoad" function for all plugins.
-						for ( pluginName in allPlugins ) {
-							plugin = allPlugins[ pluginName ];
-							if ( plugin.onLoad && !plugin.onLoad._called ) {
-								// Make it possible to return false from plugin::onLoad to disable it.
-								if ( plugin.onLoad() === false )
-									delete allPlugins[ pluginName ];
-
-								plugin.onLoad._called = 1;
-							}
-						}
-
-						// Call the callback.
-						if ( callback )
-							callback.call( scope || window, allPlugins );
-					}
-				}, this );
-
-			};
-
-		loadPlugins.call( this, name );
-	};
-} );
-
-/**
- * Loads a specific language file, or auto detect it. A callback is
- * then called when the file gets loaded.
- *
- *		CKEDITOR.plugins.setLang( 'myPlugin', 'en', {
- *			title: 'My plugin',
- *			selectOption: 'Please select an option'
- *		} );
- *
- * @param {String} pluginName The name of the plugin to which the provided translation
- * should be attached.
- * @param {String} languageCode The code of the language translation provided.
- * @param {Object} languageEntries An object that contains pairs of label and
- * the respective translation.
- */
-CKEDITOR.plugins.setLang = function( pluginName, languageCode, languageEntries ) {
-	var plugin = this.get( pluginName ),
-		pluginLangEntries = plugin.langEntries || ( plugin.langEntries = {} ),
-		pluginLang = plugin.lang || ( plugin.lang = [] );
-
-	if ( pluginLang.split )
-		pluginLang = pluginLang.split( ',' );
-
-	if ( CKEDITOR.tools.indexOf( pluginLang, languageCode ) == -1 )
-		pluginLang.push( languageCode );
-
-	pluginLangEntries[ languageCode ] = languageEntries;
-};

+ 0 - 227
htdocs/includes/ckeditor/ckeditor/_source/core/resourcemanager.js

@@ -1,227 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.resourceManager} class, which is
- *		the base for resource managers, like plugins.
- */
-
-/**
- * Base class for resource managers, like plugins. This class is not
- * intended to be used out of the CKEditor core code.
- *
- * @class
- * @constructor Creates a resourceManager class instance.
- * @param {String} basePath The path for the resources folder.
- * @param {String} fileName The name used for resource files.
- */
-CKEDITOR.resourceManager = function( basePath, fileName ) {
-	/**
-	 * The base directory containing all resources.
-	 *
-	 * @property {String}
-	 */
-	this.basePath = basePath;
-
-	/**
-	 * The name used for resource files.
-	 *
-	 * @property {String}
-	 */
-	this.fileName = fileName;
-
-	/**
-	 * Contains references to all resources that have already been registered
-	 * with {@link #add}.
-	 */
-	this.registered = {};
-
-	/**
-	 * Contains references to all resources that have already been loaded
-	 * with {@link #load}.
-	 */
-	this.loaded = {};
-
-	/**
-	 * Contains references to all resources that have already been registered
-	 * with {@link #addExternal}.
-	 */
-	this.externals = {};
-
-	/**
-	 * @private
-	 */
-	this._ = {
-		// List of callbacks waiting for plugins to be loaded.
-		waitingList: {}
-	};
-};
-
-CKEDITOR.resourceManager.prototype = {
-	/**
-	 * Registers a resource.
-	 *
-	 *		CKEDITOR.plugins.add( 'sample', { ... plugin definition ... } );
-	 *
-	 * @param {String} name The resource name.
-	 * @param {Object} [definition] The resource definition.
-	 * @see CKEDITOR.pluginDefinition
-	 */
-	add: function( name, definition ) {
-		if ( this.registered[ name ] )
-			throw '[CKEDITOR.resourceManager.add] The resource name "' + name + '" is already registered.';
-
-		var resource = this.registered[ name ] = definition || {};
-		resource.name = name;
-		resource.path = this.getPath( name );
-
-		CKEDITOR.fire( name + CKEDITOR.tools.capitalize( this.fileName ) + 'Ready', resource );
-
-		return this.get( name );
-	},
-
-	/**
-	 * Gets the definition of a specific resource.
-	 *
-	 *		var definition = CKEDITOR.plugins.get( 'sample' );
-	 *
-	 * @param {String} name The resource name.
-	 * @returns {Object} The registered object.
-	 */
-	get: function( name ) {
-		return this.registered[ name ] || null;
-	},
-
-	/**
-	 * Get the folder path for a specific loaded resource.
-	 *
-	 *		alert( CKEDITOR.plugins.getPath( 'sample' ) ); // '<editor path>/plugins/sample/'
-	 *
-	 * @param {String} name The resource name.
-	 * @returns {String}
-	 */
-	getPath: function( name ) {
-		var external = this.externals[ name ];
-		return CKEDITOR.getUrl( ( external && external.dir ) || this.basePath + name + '/' );
-	},
-
-	/**
-	 * Get the file path for a specific loaded resource.
-	 *
-	 *		alert( CKEDITOR.plugins.getFilePath( 'sample' ) ); // '<editor path>/plugins/sample/plugin.js'
-	 *
-	 * @param {String} name The resource name.
-	 * @returns {String}
-	 */
-	getFilePath: function( name ) {
-		var external = this.externals[ name ];
-		return CKEDITOR.getUrl( this.getPath( name ) + ( external ? external.file : this.fileName + '.js' ) );
-	},
-
-	/**
-	 * Registers one or more resources to be loaded from an external path
-	 * instead of the core base path.
-	 *
-	 *		// Loads a plugin from '/myplugin/samples/plugin.js'.
-	 *		CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/' );
-	 *
-	 *		// Loads a plugin from '/myplugin/samples/my_plugin.js'.
-	 *		CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/', 'my_plugin.js' );
-	 *
-	 *		// Loads a plugin from '/myplugin/samples/my_plugin.js'.
-	 *		CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/my_plugin.js', '' );
-	 *
-	 * @param {String} names The resource names, separated by commas.
-	 * @param {String} path The path of the folder containing the resource.
-	 * @param {String} [fileName] The resource file name. If not provided, the
-	 * default name is used. If provided with a empty string, will implicitly indicates that `path` argument
-	 * is already the full path.
-	 */
-	addExternal: function( names, path, fileName ) {
-		names = names.split( ',' );
-		for ( var i = 0; i < names.length; i++ ) {
-			var name = names[ i ];
-
-			// If "fileName" is not provided, we assume that it may be available
-			// in "path". Try to extract it in this case.
-			if ( !fileName ) {
-				path = path.replace( /[^\/]+$/, function( match ) {
-					fileName = match;
-					return '';
-				} );
-			}
-
-			this.externals[ name ] = {
-				dir: path,
-
-				// Use the default file name if there is no "fileName" and it
-				// was not found in "path".
-				file: fileName || ( this.fileName + '.js' )
-			};
-		}
-	},
-
-	/**
-	 * Loads one or more resources.
-	 *
-	 *		CKEDITOR.plugins.load( 'myplugin', function( plugins ) {
-	 *			alert( plugins[ 'myplugin' ] ); // object
-	 *		} );
-	 *
-	 * @param {String/Array} name The name of the resource to load. It may be a
-	 * string with a single resource name, or an array with several names.
-	 * @param {Function} callback A function to be called when all resources
-	 * are loaded. The callback will receive an array containing all loaded names.
-	 * @param {Object} [scope] The scope object to be used for the callback call.
-	 */
-	load: function( names, callback, scope ) {
-		// Ensure that we have an array of names.
-		if ( !CKEDITOR.tools.isArray( names ) )
-			names = names ? [ names ] : [];
-
-		var loaded = this.loaded,
-			registered = this.registered,
-			urls = [],
-			urlsNames = {},
-			resources = {};
-
-		// Loop through all names.
-		for ( var i = 0; i < names.length; i++ ) {
-			var name = names[ i ];
-
-			if ( !name )
-				continue;
-
-			// If not available yet.
-			if ( !loaded[ name ] && !registered[ name ] ) {
-				var url = this.getFilePath( name );
-				urls.push( url );
-				if ( !( url in urlsNames ) )
-					urlsNames[ url ] = [];
-				urlsNames[ url ].push( name );
-			} else
-				resources[ name ] = this.get( name );
-		}
-
-		CKEDITOR.scriptLoader.load( urls, function( completed, failed ) {
-			if ( failed.length ) {
-				throw '[CKEDITOR.resourceManager.load] Resource name "' + urlsNames[ failed[ 0 ] ].join( ',' )
-					+ '" was not found at "' + failed[ 0 ] + '".';
-			}
-
-			for ( var i = 0; i < completed.length; i++ ) {
-				var nameList = urlsNames[ completed[ i ] ];
-				for ( var j = 0; j < nameList.length; j++ ) {
-					var name = nameList[ j ];
-					resources[ name ] = this.get( name );
-
-					loaded[ name ] = 1;
-				}
-			}
-
-			callback.call( scope, resources );
-		}, this );
-	}
-};

+ 0 - 202
htdocs/includes/ckeditor/ckeditor/_source/core/scriptloader.js

@@ -1,202 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.scriptLoader} object, used to load scripts
- *		asynchronously.
- */
-
-/**
- * Load scripts asynchronously.
- *
- * @class
- * @singleton
- */
-CKEDITOR.scriptLoader = ( function() {
-	var uniqueScripts = {},
-		waitingList = {};
-
-	return {
-		/**
-		 * Loads one or more external script checking if not already loaded
-		 * previously by this function.
-		 *
-		 *		CKEDITOR.scriptLoader.load( '/myscript.js' );
-		 *
-		 *		CKEDITOR.scriptLoader.load( '/myscript.js', function( success ) {
-		 *			// Alerts true if the script has been properly loaded.
-		 *			// HTTP error 404 should return false.
-		 *			alert( success );
-		 *		} );
-		 *
-		 *		CKEDITOR.scriptLoader.load( [ '/myscript1.js', '/myscript2.js' ], function( completed, failed ) {
-		 *			alert( 'Number of scripts loaded: ' + completed.length );
-		 *			alert( 'Number of failures: ' + failed.length );
-		 *		} );
-		 *
-		 * @param {String/Array} scriptUrl One or more URLs pointing to the
-		 * scripts to be loaded.
-		 * @param {Function} [callback] A function to be called when the script
-		 * is loaded and executed. If a string is passed to `scriptUrl`, a
-		 * boolean parameter is passed to the callback, indicating the
-		 * success of the load. If an array is passed instead, two arrays
-		 * parameters are passed to the callback - the first contains the
-		 * URLs that have been properly loaded and the second the failed ones.
-		 * @param {Object} [scope] The scope (`this` reference) to be used for
-		 * the callback call. Defaults to {@link CKEDITOR}.
-		 * @param {Boolean} [showBusy] Changes the cursor of the document while
-		 * the script is loaded.
-		 */
-		load: function( scriptUrl, callback, scope, showBusy ) {
-			var isString = ( typeof scriptUrl == 'string' );
-
-			if ( isString )
-				scriptUrl = [ scriptUrl ];
-
-			if ( !scope )
-				scope = CKEDITOR;
-
-			var scriptCount = scriptUrl.length,
-				completed = [],
-				failed = [];
-
-			var doCallback = function( success ) {
-					if ( callback ) {
-						if ( isString )
-							callback.call( scope, success );
-						else
-							callback.call( scope, completed, failed );
-					}
-				};
-
-			if ( scriptCount === 0 ) {
-				doCallback( true );
-				return;
-			}
-
-			var checkLoaded = function( url, success ) {
-					( success ? completed : failed ).push( url );
-
-					if ( --scriptCount <= 0 ) {
-						showBusy && CKEDITOR.document.getDocumentElement().removeStyle( 'cursor' );
-						doCallback( success );
-					}
-				};
-
-			var onLoad = function( url, success ) {
-					// Mark this script as loaded.
-					uniqueScripts[ url ] = 1;
-
-					// Get the list of callback checks waiting for this file.
-					var waitingInfo = waitingList[ url ];
-					delete waitingList[ url ];
-
-					// Check all callbacks waiting for this file.
-					for ( var i = 0; i < waitingInfo.length; i++ )
-						waitingInfo[ i ]( url, success );
-				};
-
-			var loadScript = function( url ) {
-					if ( uniqueScripts[ url ] ) {
-						checkLoaded( url, true );
-						return;
-					}
-
-					var waitingInfo = waitingList[ url ] || ( waitingList[ url ] = [] );
-					waitingInfo.push( checkLoaded );
-
-					// Load it only for the first request.
-					if ( waitingInfo.length > 1 )
-						return;
-
-					// Create the <script> element.
-					var script = new CKEDITOR.dom.element( 'script' );
-					script.setAttributes( {
-						type: 'text/javascript',
-						src: url } );
-
-					if ( callback ) {
-						if ( CKEDITOR.env.ie && CKEDITOR.env.version < 11 ) {
-							// FIXME: For IE, we are not able to return false on error (like 404).
-							script.$.onreadystatechange = function() {
-								if ( script.$.readyState == 'loaded' || script.$.readyState == 'complete' ) {
-									script.$.onreadystatechange = null;
-									onLoad( url, true );
-								}
-							};
-						} else {
-							script.$.onload = function() {
-								// Some browsers, such as Safari, may call the onLoad function
-								// immediately. Which will break the loading sequence. (#3661)
-								setTimeout( function() {
-									onLoad( url, true );
-								}, 0 );
-							};
-
-							// FIXME: Opera and Safari will not fire onerror.
-							script.$.onerror = function() {
-								onLoad( url, false );
-							};
-						}
-					}
-
-					// Append it to <head>.
-					script.appendTo( CKEDITOR.document.getHead() );
-
-					CKEDITOR.fire( 'download', url ); // %REMOVE_LINE%
-				};
-
-			showBusy && CKEDITOR.document.getDocumentElement().setStyle( 'cursor', 'wait' );
-			for ( var i = 0; i < scriptCount; i++ ) {
-				loadScript( scriptUrl[ i ] );
-			}
-		},
-
-		/**
-		 * Loads a script in a queue, so only one is loaded at the same time.
-		 *
-		 * @since 4.1.2
-		 * @param {String} scriptUrl URL pointing to the script to be loaded.
-		 * @param {Function} [callback] A function to be called when the script
-		 * is loaded and executed. A boolean parameter is passed to the callback,
-		 * indicating the success of the load.
-		 *
-		 * @see CKEDITOR.scriptLoader#load
-		 */
-		queue: ( function() {
-			var pending = [];
-
-			// Loads the very first script from queue and removes it.
-			function loadNext() {
-				var script;
-
-				if ( ( script = pending[ 0 ] ) )
-					this.load( script.scriptUrl, script.callback, CKEDITOR, 0 );
-			}
-
-			return function( scriptUrl, callback ) {
-				var that = this;
-
-				// This callback calls the standard callback for the script
-				// and loads the very next script from pending list.
-				function callbackWrapper() {
-					callback && callback.apply( this, arguments );
-
-					// Removed the just loaded script from the queue.
-					pending.shift();
-
-					loadNext.call( that );
-				}
-
-				// Let's add this script to the queue
-				pending.push( { scriptUrl: scriptUrl, callback: callbackWrapper } );
-
-				// If the queue was empty, then start loading.
-				if ( pending.length == 1 )
-					loadNext.call( this );
-			};
-		} )()
-	};
-} )();

+ 0 - 2224
htdocs/includes/ckeditor/ckeditor/_source/core/selection.js

@@ -1,2224 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-( function() {
-	// #### checkSelectionChange : START
-
-	// The selection change check basically saves the element parent tree of
-	// the current node and check it on successive requests. If there is any
-	// change on the tree, then the selectionChange event gets fired.
-	function checkSelectionChange() {
-		// A possibly available fake-selection.
-		var sel = this._.fakeSelection,
-			realSel;
-
-		if ( sel ) {
-			realSel = this.getSelection( 1 );
-
-			// If real (not locked/stored) selection was moved from hidden container,
-			// then the fake-selection must be invalidated.
-			if ( !realSel || !realSel.isHidden() ) {
-				// Remove the cache from fake-selection references in use elsewhere.
-				sel.reset();
-
-				// Have the code using the native selection.
-				sel = 0;
-			}
-		}
-
-		// If not fake-selection is available then get the native selection.
-		if ( !sel ) {
-			sel = realSel || this.getSelection( 1 );
-
-			// Editor may have no selection at all.
-			if ( !sel || sel.getType() == CKEDITOR.SELECTION_NONE )
-				return;
-		}
-
-		this.fire( 'selectionCheck', sel );
-
-		var currentPath = this.elementPath();
-		if ( !currentPath.compare( this._.selectionPreviousPath ) ) {
-			// Cache the active element, which we'll eventually lose on Webkit.
-			if ( CKEDITOR.env.webkit )
-				this._.previousActive = this.document.getActive();
-
-			this._.selectionPreviousPath = currentPath;
-			this.fire( 'selectionChange', { selection: sel, path: currentPath } );
-		}
-	}
-
-	var checkSelectionChangeTimer, checkSelectionChangeTimeoutPending;
-
-	function checkSelectionChangeTimeout() {
-		// Firing the "OnSelectionChange" event on every key press started to
-		// be too slow. This function guarantees that there will be at least
-		// 200ms delay between selection checks.
-
-		checkSelectionChangeTimeoutPending = true;
-
-		if ( checkSelectionChangeTimer )
-			return;
-
-		checkSelectionChangeTimeoutExec.call( this );
-
-		checkSelectionChangeTimer = CKEDITOR.tools.setTimeout( checkSelectionChangeTimeoutExec, 200, this );
-	}
-
-	function checkSelectionChangeTimeoutExec() {
-		checkSelectionChangeTimer = null;
-
-		if ( checkSelectionChangeTimeoutPending ) {
-			// Call this with a timeout so the browser properly moves the
-			// selection after the mouseup. It happened that the selection was
-			// being moved after the mouseup when clicking inside selected text
-			// with Firefox.
-			CKEDITOR.tools.setTimeout( checkSelectionChange, 0, this );
-
-			checkSelectionChangeTimeoutPending = false;
-		}
-	}
-
-	// #### checkSelectionChange : END
-
-	var isVisible = CKEDITOR.dom.walker.invisible( 1 );
-	function rangeRequiresFix( range ) {
-		function isTextCt( node, isAtEnd ) {
-			if ( !node || node.type == CKEDITOR.NODE_TEXT )
-				return false;
-
-			var testRng = range.clone();
-			return testRng[ 'moveToElementEdit' + ( isAtEnd ? 'End' : 'Start' ) ]( node );
-		}
-
-		// Range root must be the editable element, it's to avoid creating filler char
-		// on any temporary internal selection.
-		if ( !( range.root instanceof CKEDITOR.editable ) )
-			return false;
-
-		var ct = range.startContainer;
-
-		var previous = range.getPreviousNode( isVisible, null, ct ),
-			next = range.getNextNode( isVisible, null, ct );
-
-		// Any adjacent text container may absorb the cursor, e.g.
-		// <p><strong>text</strong>^foo</p>
-		// <p>foo^<strong>text</strong></p>
-		// <div>^<p>foo</p></div>
-		if ( isTextCt( previous ) || isTextCt( next, 1 ) )
-			return true;
-
-		// Empty block/inline element is also affected. <span>^</span>, <p>^</p> (#7222)
-		if ( !( previous || next ) && !( ct.type == CKEDITOR.NODE_ELEMENT && ct.isBlockBoundary() && ct.getBogus() ) )
-			return true;
-
-		return false;
-	}
-
-	function createFillingChar( element ) {
-		removeFillingChar( element, false );
-
-		var fillingChar = element.getDocument().createText( '\u200B' );
-		element.setCustomData( 'cke-fillingChar', fillingChar );
-
-		return fillingChar;
-	}
-
-	function getFillingChar( element ) {
-		return element.getCustomData( 'cke-fillingChar' );
-	}
-
-	// Checks if a filling char has been used, eventualy removing it (#1272).
-	function checkFillingChar( element ) {
-		var fillingChar = getFillingChar( element );
-		if ( fillingChar ) {
-			// Use this flag to avoid removing the filling char right after
-			// creating it.
-			if ( fillingChar.getCustomData( 'ready' ) )
-				removeFillingChar( element );
-			else
-				fillingChar.setCustomData( 'ready', 1 );
-		}
-	}
-
-	function removeFillingChar( element, keepSelection ) {
-		var fillingChar = element && element.removeCustomData( 'cke-fillingChar' );
-		if ( fillingChar ) {
-
-			// Text selection position might get mangled by
-			// subsequent dom modification, save it now for restoring. (#8617)
-			if ( keepSelection !== false )
-			{
-				var bm,
-					doc = element.getDocument(),
-					sel = doc.getSelection().getNative(),
-					// Be error proof.
-					range = sel && sel.type != 'None' && sel.getRangeAt( 0 );
-
-				if ( fillingChar.getLength() > 1 && range && range.intersectsNode( fillingChar.$ ) ) {
-					bm = [ sel.anchorOffset, sel.focusOffset ];
-
-					// Anticipate the offset change brought by the removed char.
-					var startAffected = sel.anchorNode == fillingChar.$ && sel.anchorOffset > 0,
-						endAffected = sel.focusNode == fillingChar.$ && sel.focusOffset > 0;
-					startAffected && bm[ 0 ]--;
-					endAffected && bm[ 1 ]--;
-
-					// Revert the bookmark order on reverse selection.
-					isReversedSelection( sel ) && bm.unshift( bm.pop() );
-				}
-			}
-
-			// We can't simply remove the filling node because the user
-			// will actually enlarge it when typing, so we just remove the
-			// invisible char from it.
-			fillingChar.setText( replaceFillingChar( fillingChar.getText() ) );
-
-			// Restore the bookmark.
-			if ( bm ) {
-				var rng = sel.getRangeAt( 0 );
-				rng.setStart( rng.startContainer, bm[ 0 ] );
-				rng.setEnd( rng.startContainer, bm[ 1 ] );
-				sel.removeAllRanges();
-				sel.addRange( rng );
-			}
-		}
-	}
-
-	function replaceFillingChar( html ) {
-		return html.replace( /\u200B( )?/g, function( match ) {
-			// #10291 if filling char is followed by a space replace it with nbsp.
-			return match[ 1 ] ? '\xa0' : '';
-		} );
-	}
-
-	function isReversedSelection( sel ) {
-		if ( !sel.isCollapsed ) {
-			var range = sel.getRangeAt( 0 );
-			// Potentially alter an reversed selection range.
-			range.setStart( sel.anchorNode, sel.anchorOffset );
-			range.setEnd( sel.focusNode, sel.focusOffset );
-			return range.collapsed;
-		}
-	}
-
-	// Read the comments in selection constructor.
-	function fixInitialSelection( root, nativeSel, doFocus ) {
-		// It may happen that setting proper selection will
-		// cause focus to be fired (even without actually focusing root).
-		// Cancel it because focus shouldn't be fired when retriving selection. (#10115)
-		var listener = root.on( 'focus', function( evt ) {
-			evt.cancel();
-		}, null, null, -100 );
-
-		// FF && Webkit.
-		if ( !CKEDITOR.env.ie ) {
-			var range = new CKEDITOR.dom.range( root );
-			range.moveToElementEditStart( root );
-
-			var nativeRange = root.getDocument().$.createRange();
-			nativeRange.setStart( range.startContainer.$, range.startOffset );
-			nativeRange.collapse( 1 );
-
-			nativeSel.removeAllRanges();
-			nativeSel.addRange( nativeRange );
-		}
-		else {
-			// IE in specific case may also fire selectionchange.
-			// We cannot block bubbling selectionchange, so at least we
-			// can prevent from falling into inf recursion caused by fix for #9699
-			// (see wysiwygarea plugin).
-			// http://dev.ckeditor.com/ticket/10438#comment:13
-			var listener2 = root.getDocument().on( 'selectionchange', function( evt ) {
-				evt.cancel();
-			}, null, null, -100 );
-		}
-
-		doFocus && root.focus();
-
-		listener.removeListener();
-		listener2 && listener2.removeListener();
-	}
-
-	// Creates cke_hidden_sel container and puts real selection there.
-	function hideSelection( editor ) {
-		var style = CKEDITOR.env.ie ? 'display:none' : 'position:fixed;top:0;left:-1000px',
-			hiddenEl = CKEDITOR.dom.element.createFromHtml(
-				'<div data-cke-hidden-sel="1" data-cke-temp="1" style="' + style + '">&nbsp;</div>',
-				editor.document );
-
-		editor.fire( 'lockSnapshot' );
-
-		editor.editable().append( hiddenEl );
-
-			// Always use real selection to avoid overriding locked one (http://dev.ckeditor.com/ticket/11104#comment:13).
-		var sel = editor.getSelection( 1 ),
-			range = editor.createRange(),
-			// Cancel selectionchange fired by selectRanges - prevent from firing selectionChange.
-			listener = sel.root.on( 'selectionchange', function( evt ) {
-				evt.cancel();
-			}, null, null, 0 );
-
-		range.setStartAt( hiddenEl, CKEDITOR.POSITION_AFTER_START );
-		range.setEndAt( hiddenEl, CKEDITOR.POSITION_BEFORE_END );
-		sel.selectRanges( [ range ] );
-
-		listener.removeListener();
-
-		editor.fire( 'unlockSnapshot' );
-
-		// Set this value at the end, so reset() executed by selectRanges()
-		// will clean up old hidden selection container.
-		editor._.hiddenSelectionContainer = hiddenEl;
-	}
-
-	function removeHiddenSelectionContainer( editor ) {
-		var hiddenEl = editor._.hiddenSelectionContainer;
-
-		if ( hiddenEl ) {
-			editor.fire( 'lockSnapshot' );
-			hiddenEl.remove();
-			editor.fire( 'unlockSnapshot' );
-		}
-
-		delete editor._.hiddenSelectionContainer;
-	}
-
-	// Object containing keystroke handlers for fake selection.
-	var fakeSelectionDefaultKeystrokeHandlers = ( function() {
-		function leave( right ) {
-			return function( evt ) {
-				var range = evt.editor.createRange();
-
-				// Move selection only if there's a editable place for it.
-				// It no, then do nothing (keystroke will be blocked, widget selection kept).
-				if ( range.moveToClosestEditablePosition( evt.selected, right ) )
-					evt.editor.getSelection().selectRanges( [ range ] );
-
-				// Prevent default.
-				return false;
-			};
-		}
-
-		function del( right ) {
-			return function( evt ) {
-				var editor = evt.editor,
-					range = editor.createRange(),
-					found;
-
-				// If haven't found place for caret on the default side,
-				// try to find it on the other side.
-				if ( !( found = range.moveToClosestEditablePosition( evt.selected, right ) ) )
-					found = range.moveToClosestEditablePosition( evt.selected, !right );
-
-				if ( found )
-					editor.getSelection().selectRanges( [ range ] );
-
-				// Save the state before removing selected element.
-				editor.fire( 'saveSnapshot' );
-
-				evt.selected.remove();
-
-				// Haven't found any editable space before removing element,
-				// try to place the caret anywhere (most likely, in empty editable).
-				if ( !found ) {
-					range.moveToElementEditablePosition( editor.editable() );
-					editor.getSelection().selectRanges( [ range ] );
-				}
-
-				editor.fire( 'saveSnapshot' );
-
-				// Prevent default.
-				return false;
-			};
-		}
-
-		var leaveLeft = leave(),
-			leaveRight = leave( 1 );
-
-		return {
-			37: leaveLeft,		// LEFT
-			38: leaveLeft,		// UP
-			39: leaveRight,		// RIGHT
-			40: leaveRight,		// DOWN
-			8: del(),			// BACKSPACE
-			46: del( 1 )		// DELETE
-		};
-	} )();
-
-	// Handle left, right, delete and backspace keystrokes next to non-editable elements
-	// by faking selection on them.
-	function getOnKeyDownListener( editor ) {
-		var keystrokes = { 37: 1, 39: 1, 8: 1, 46: 1 };
-
-		return function( evt ) {
-			var keystroke = evt.data.getKeystroke();
-
-			// Handle only left/right/del/bspace keys.
-			if ( !keystrokes[ keystroke ] )
-				return;
-
-			var sel = editor.getSelection(),
-				ranges = sel.getRanges(),
-				range = ranges[ 0 ];
-
-			// Handle only single range and it has to be collapsed.
-			if ( ranges.length != 1 || !range.collapsed )
-				return;
-
-			var next = range[ keystroke < 38 ? 'getPreviousEditableNode' : 'getNextEditableNode' ]();
-
-			if ( next && next.type == CKEDITOR.NODE_ELEMENT && next.getAttribute( 'contenteditable' ) == 'false' ) {
-				editor.getSelection().fake( next );
-				evt.data.preventDefault();
-				evt.cancel();
-			}
-		};
-	}
-
-	// If fake selection should be applied this function will return instance of
-	// CKEDITOR.dom.element which should gain fake selection.
-	function getNonEditableFakeSelectionReceiver( ranges ) {
-		var enclosedNode, shrinkedNode, clone, range;
-
-		if ( ranges.length == 1 && !( range = ranges[ 0 ] ).collapsed &&
-			( enclosedNode = range.getEnclosedNode() ) && enclosedNode.type == CKEDITOR.NODE_ELEMENT ) {
-			// So far we can't say that enclosed element is non-editable. Before checking,
-			// we'll shrink range (clone). Shrinking will stop on non-editable range, or
-			// innermost element (#11114).
-			clone = range.clone();
-			clone.shrink( CKEDITOR.SHRINK_ELEMENT, true );
-
-			// If shrinked range still encloses an element, check this one (shrink stops only on non-editable elements).
-			if ( ( shrinkedNode = clone.getEnclosedNode() ) && shrinkedNode.type == CKEDITOR.NODE_ELEMENT )
-				enclosedNode = shrinkedNode;
-
-			if ( enclosedNode.getAttribute( 'contenteditable' ) == 'false' )
-				return enclosedNode;
-		}
-	}
-
-	// Fix ranges which may end after hidden selection container.
-	// Note: this function may only be used if hidden selection container
-	// is not in DOM any more.
-	function fixRangesAfterHiddenSelectionContainer( ranges, root ) {
-		var range;
-		for ( var i = 0; i < ranges.length; ++i ) {
-			range = ranges[ i ];
-			if ( range.endContainer.equals( root ) ) {
-				// We can use getChildCount() because hidden selection container is not in DOM.
-				range.endOffset = Math.min( range.endOffset, root.getChildCount() );
-			}
-		}
-	}
-
-	// Extract only editable part or ranges.
-	// Note: this function modifies ranges list!
-	// @param {CKEDITOR.dom.rangeList} ranges
-	function extractEditableRanges( ranges ) {
-		for ( var i = 0; i < ranges.length; i++ ) {
-			var range = ranges[ i ];
-
-			// Drop range spans inside one ready-only node.
-			var parent = range.getCommonAncestor();
-			if ( parent.isReadOnly() )
-				ranges.splice( i, 1 );
-
-			if ( range.collapsed )
-				continue;
-
-			// Range may start inside a non-editable element,
-			// replace the range start after it.
-			if ( range.startContainer.isReadOnly() ) {
-				var current = range.startContainer,
-					isElement;
-
-				while ( current ) {
-					isElement = current.type == CKEDITOR.NODE_ELEMENT;
-
-					if ( ( isElement && current.is( 'body' ) ) || !current.isReadOnly() )
-						break;
-
-					if ( isElement && current.getAttribute( 'contentEditable' ) == 'false' )
-						range.setStartAfter( current );
-
-					current = current.getParent();
-				}
-			}
-
-			var startContainer = range.startContainer,
-				endContainer = range.endContainer,
-				startOffset = range.startOffset,
-				endOffset = range.endOffset,
-				walkerRange = range.clone();
-
-			// Enlarge range start/end with text node to avoid walker
-			// being DOM destructive, it doesn't interfere our checking
-			// of elements below as well.
-			if ( startContainer && startContainer.type == CKEDITOR.NODE_TEXT ) {
-				if ( startOffset >= startContainer.getLength() )
-					walkerRange.setStartAfter( startContainer );
-				else
-					walkerRange.setStartBefore( startContainer );
-			}
-
-			if ( endContainer && endContainer.type == CKEDITOR.NODE_TEXT ) {
-				if ( !endOffset )
-					walkerRange.setEndBefore( endContainer );
-				else
-					walkerRange.setEndAfter( endContainer );
-			}
-
-			// Looking for non-editable element inside the range.
-			var walker = new CKEDITOR.dom.walker( walkerRange );
-			walker.evaluator = function( node ) {
-				if ( node.type == CKEDITOR.NODE_ELEMENT && node.isReadOnly() ) {
-					var newRange = range.clone();
-					range.setEndBefore( node );
-
-					// Drop collapsed range around read-only elements,
-					// it make sure the range list empty when selecting
-					// only non-editable elements.
-					if ( range.collapsed )
-						ranges.splice( i--, 1 );
-
-					// Avoid creating invalid range.
-					if ( !( node.getPosition( walkerRange.endContainer ) & CKEDITOR.POSITION_CONTAINS ) ) {
-						newRange.setStartAfter( node );
-						if ( !newRange.collapsed )
-							ranges.splice( i + 1, 0, newRange );
-					}
-
-					return true;
-				}
-
-				return false;
-			};
-
-			walker.next();
-		}
-
-		return ranges;
-	}
-
-	// Setup all editor instances for the necessary selection hooks.
-	CKEDITOR.on( 'instanceCreated', function( ev ) {
-		var editor = ev.editor;
-
-		editor.on( 'contentDom', function() {
-			var doc = editor.document,
-				outerDoc = CKEDITOR.document,
-				editable = editor.editable(),
-				body = doc.getBody(),
-				html = doc.getDocumentElement();
-
-			var isInline = editable.isInline();
-
-			var restoreSel,
-				lastSel;
-
-			// Give the editable an initial selection on first focus,
-			// put selection at a consistent position at the start
-			// of the contents. (#9507)
-			if ( CKEDITOR.env.gecko ) {
-				editable.attachListener( editable, 'focus', function( evt ) {
-					evt.removeListener();
-
-					if ( restoreSel !== 0 ) {
-						var nativ = editor.getSelection().getNative();
-						// Do it only if the native selection is at an unwanted
-						// place (at the very start of the editable). #10119
-						if ( nativ && nativ.isCollapsed && nativ.anchorNode == editable.$ ) {
-							var rng = editor.createRange();
-							rng.moveToElementEditStart( editable );
-							rng.select();
-						}
-					}
-				}, null, null, -2 );
-			}
-
-			// Plays the magic here to restore/save dom selection on editable focus/blur.
-			editable.attachListener( editable, CKEDITOR.env.webkit ? 'DOMFocusIn' : 'focus', function() {
-				// On Webkit we use DOMFocusIn which is fired more often than focus - e.g. when moving from main editable
-				// to nested editable (or the opposite). Unlock selection all, but restore only when it was locked
-				// for the same active element, what will e.g. mean restoring after displaying dialog.
-				if ( restoreSel && CKEDITOR.env.webkit )
-					restoreSel = editor._.previousActive && editor._.previousActive.equals( doc.getActive() );
-
-				editor.unlockSelection( restoreSel );
-				restoreSel = 0;
-			}, null, null, -1 );
-
-			// Disable selection restoring when clicking in.
-			editable.attachListener( editable, 'mousedown', function() {
-				restoreSel = 0;
-			} );
-
-			// Browsers could loose the selection once the editable lost focus,
-			// in such case we need to reproduce it by saving a locked selection
-			// and restoring it upon focus gain.
-			if ( CKEDITOR.env.ie || CKEDITOR.env.opera || isInline ) {
-				// Save a cloned version of current selection.
-				function saveSel() {
-					lastSel = new CKEDITOR.dom.selection( editor.getSelection() );
-					lastSel.lock();
-				}
-
-				// For old IEs, we can retrieve the last correct DOM selection upon the "beforedeactivate" event.
-				// For the rest, a more frequent check is required for each selection change made.
-				if ( isMSSelection )
-					editable.attachListener( editable, 'beforedeactivate', saveSel, null, null, -1 );
-				else
-					editable.attachListener( editor, 'selectionCheck', saveSel, null, null, -1 );
-
-				// Lock the selection and mark it to be restored.
-				// On Webkit we use DOMFocusOut which is fired more often than blur. I.e. it will also be
-				// fired when nested editable is blurred.
-				editable.attachListener( editable, CKEDITOR.env.webkit ? 'DOMFocusOut' : 'blur', function() {
-					editor.lockSelection( lastSel );
-					restoreSel = 1;
-				}, null, null, -1 );
-
-				// Disable selection restoring when clicking in.
-				editable.attachListener( editable, 'mousedown', function() {
-					restoreSel = 0;
-				} );
-			}
-
-			// The following selection-related fixes only apply to classic (`iframe`-based) editable.
-			if ( CKEDITOR.env.ie && !isInline ) {
-				var scroll;
-				editable.attachListener( editable, 'mousedown', function( evt ) {
-					// IE scrolls document to top on right mousedown
-					// when editor has no focus, remember this scroll
-					// position and revert it before context menu opens. (#5778)
-					if ( evt.data.$.button == 2 ) {
-						var sel = editor.document.getSelection();
-						if ( !sel || sel.getType() == CKEDITOR.SELECTION_NONE )
-							scroll = editor.window.getScrollPosition();
-					}
-				} );
-
-				editable.attachListener( editable, 'mouseup', function( evt ) {
-					// Restore recorded scroll position when needed on right mouseup.
-					if ( evt.data.$.button == 2 && scroll ) {
-						editor.document.$.documentElement.scrollLeft = scroll.x;
-						editor.document.$.documentElement.scrollTop = scroll.y;
-					}
-					scroll = null;
-				} );
-
-				// When content doc is in standards mode, IE doesn't focus the editor when
-				// clicking at the region below body (on html element) content, we emulate
-				// the normal behavior on old IEs. (#1659, #7932)
-				if ( doc.$.compatMode != 'BackCompat' ) {
-					if ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) {
-						function moveRangeToPoint( range, x, y ) {
-							// Error prune in IE7. (#9034, #9110)
-							try { range.moveToPoint( x, y ); } catch ( e ) {}
-						}
-
-						html.on( 'mousedown', function( evt ) {
-							evt = evt.data;
-
-							// Expand the text range along with mouse move.
-							function onHover( evt ) {
-								evt = evt.data.$;
-								if ( textRng ) {
-									// Read the current cursor.
-									var rngEnd = body.$.createTextRange();
-
-									moveRangeToPoint( rngEnd, evt.x, evt.y );
-
-									// Handle drag directions.
-									textRng.setEndPoint(
-										startRng.compareEndPoints( 'StartToStart', rngEnd ) < 0 ?
-										'EndToEnd' : 'StartToStart', rngEnd );
-
-									// Update selection with new range.
-									textRng.select();
-								}
-							}
-
-							function removeListeners() {
-								outerDoc.removeListener( 'mouseup', onSelectEnd );
-								html.removeListener( 'mouseup', onSelectEnd );
-							}
-
-							function onSelectEnd() {
-
-								html.removeListener( 'mousemove', onHover );
-								removeListeners();
-
-								// Make it in effect on mouse up. (#9022)
-								textRng.select();
-							}
-
-
-							// We're sure that the click happens at the region
-							// below body, but not on scrollbar.
-							if ( evt.getTarget().is( 'html' ) &&
-									 evt.$.y < html.$.clientHeight &&
-									 evt.$.x < html.$.clientWidth ) {
-								// Start to build the text range.
-								var textRng = body.$.createTextRange();
-								moveRangeToPoint( textRng, evt.$.x, evt.$.y );
-
-								// Records the dragging start of the above text range.
-								var startRng = textRng.duplicate();
-
-								html.on( 'mousemove', onHover );
-								outerDoc.on( 'mouseup', onSelectEnd );
-								html.on( 'mouseup', onSelectEnd );
-							}
-						} );
-					}
-
-					// It's much simpler for IE8+, we just need to reselect the reported range.
-					// This hack does not work on IE>=11 because there's no old selection&range APIs.
-					if ( CKEDITOR.env.version > 7 && CKEDITOR.env.version < 11 ) {
-						html.on( 'mousedown', function( evt ) {
-							if ( evt.data.getTarget().is( 'html' ) ) {
-								// Limit the text selection mouse move inside of editable. (#9715)
-								outerDoc.on( 'mouseup', onSelectEnd );
-								html.on( 'mouseup', onSelectEnd );
-							}
-
-						} );
-
-						function removeListeners() {
-							outerDoc.removeListener( 'mouseup', onSelectEnd );
-							html.removeListener( 'mouseup', onSelectEnd );
-						}
-
-						function onSelectEnd() {
-							removeListeners();
-
-							// The event is not fired when clicking on the scrollbars,
-							// so we can safely check the following to understand
-							// whether the empty space following <body> has been clicked.
-								var sel = CKEDITOR.document.$.selection,
-									range = sel.createRange();
-								// The selection range is reported on host, but actually it should applies to the content doc.
-								if ( sel.type != 'None' && range.parentElement().ownerDocument == doc.$ )
-									range.select();
-						}
-					}
-				}
-			}
-
-			// We check the selection change:
-			// 1. Upon "selectionchange" event from the editable element. (which might be faked event fired by our code)
-			// 2. After the accomplish of keyboard and mouse events.
-			editable.attachListener( editable, 'selectionchange', checkSelectionChange, editor );
-			editable.attachListener( editable, 'keyup', checkSelectionChangeTimeout, editor );
-			// Always fire the selection change on focus gain.
-			// On Webkit do this on DOMFocusIn, because the selection is unlocked on it too and
-			// we need synchronization between those listeners to not lost cached editor._.previousActive property
-			// (which is updated on selectionCheck).
-			editable.attachListener( editable, CKEDITOR.env.webkit ? 'DOMFocusIn' : 'focus', function() {
-				editor.forceNextSelectionCheck();
-				editor.selectionChange( 1 );
-			} );
-
-			// #9699: On Webkit&Gecko in inline editor and on Opera in classic (`iframe`-based) editor we have to check selection
-			// when it was changed by dragging and releasing mouse button outside editable. Dragging (mousedown)
-			// has to be initialized in editable, but for mouseup we listen on document element.
-			// On Opera, listening on document element, helps even if mouse button is released outside iframe.
-			if ( isInline ? ( CKEDITOR.env.webkit || CKEDITOR.env.gecko ) : CKEDITOR.env.opera ) {
-				var mouseDown;
-				editable.attachListener( editable, 'mousedown', function() {
-					mouseDown = 1;
-				} );
-				editable.attachListener( doc.getDocumentElement(), 'mouseup', function() {
-					if ( mouseDown )
-						checkSelectionChangeTimeout.call( editor );
-					mouseDown = 0;
-				} );
-			}
-			// In all other cases listen on simple mouseup over editable, as we did before #9699.
-			//
-			// Use document instead of editable in non-IEs for observing mouseup
-			// since editable won't fire the event if selection process started within iframe and ended out
-			// of the editor (#9851).
-			else
-				editable.attachListener( CKEDITOR.env.ie ? editable : doc.getDocumentElement(), 'mouseup', checkSelectionChangeTimeout, editor );
-
-			if ( CKEDITOR.env.webkit ) {
-				// Before keystroke is handled by editor, check to remove the filling char.
-				editable.attachListener( doc, 'keydown', function( evt ) {
-					var key = evt.data.getKey();
-					// Remove the filling char before some keys get
-					// executed, so they'll not get blocked by it.
-					switch ( key ) {
-						case 13: // ENTER
-						case 33: // PAGEUP
-						case 34: // PAGEDOWN
-						case 35: // HOME
-						case 36: // END
-						case 37: // LEFT-ARROW
-						case 39: // RIGHT-ARROW
-						case 8: // BACKSPACE
-						case 45: // INS
-						case 46: // DEl
-							removeFillingChar( editable );
-					}
-
-				}, null, null, -1 );
-			}
-
-			// Automatically select non-editable element when navigating into
-			// it by left/right or backspace/del keys.
-			editable.attachListener( editable, 'keydown', getOnKeyDownListener( editor ), null, null, -1 );
-		} );
-
-		// Clear the cached range path before unload. (#7174)
-		editor.on( 'contentDomUnload', editor.forceNextSelectionCheck, editor );
-		// Check selection change on data reload.
-		editor.on( 'dataReady', function() {
-			// Clean up fake selection after setting data.
-			delete editor._.fakeSelection;
-			delete editor._.hiddenSelectionContainer;
-
-			editor.selectionChange( 1 );
-		} );
-		// When loaded data are ready check whether hidden selection container was not loaded.
-		editor.on( 'loadSnapshot', function() {
-			// TODO replace with el.find() which will be introduced in #9764,
-			// because it may happen that hidden sel container won't be the last element.
-			var el = editor.editable().getLast( function( node ) {
-				return node.type == CKEDITOR.NODE_ELEMENT;
-			} );
-
-			if ( el && el.hasAttribute( 'data-cke-hidden-sel' ) )
-				el.remove();
-		}, null, null, 100 );
-
-		function clearSelection() {
-			var sel = editor.getSelection();
-			sel && sel.removeAllRanges();
-		}
-
-		// Clear dom selection before editable destroying to fix some browser
-		// craziness.
-
-		// IE9 might cease to work if there's an object selection inside the iframe (#7639).
-		CKEDITOR.env.ie9Compat && editor.on( 'beforeDestroy', clearSelection, null, null, 9 );
-		// Webkit's selection will mess up after the data loading.
-		CKEDITOR.env.webkit && editor.on( 'setData', clearSelection );
-
-		// Invalidate locked selection when unloading DOM (e.g. after setData). (#9521)
-		editor.on( 'contentDomUnload', function() {
-			editor.unlockSelection();
-		} );
-
-		editor.on( 'key', function( evt ) {
-			if ( editor.mode != 'wysiwyg' )
-				return;
-
-			var sel = editor.getSelection();
-			if ( !sel.isFake )
-				return;
-
-			var handler = fakeSelectionDefaultKeystrokeHandlers[ evt.data.keyCode ];
-			if ( handler )
-				return handler( { editor: editor, selected: sel.getSelectedElement(), selection: sel, keyEvent: evt } );
-		} );
-	} );
-
-	CKEDITOR.on( 'instanceReady', function( evt ) {
-		var editor = evt.editor;
-
-		// On WebKit only, we need a special "filling" char on some situations
-		// (#1272). Here we set the events that should invalidate that char.
-		if ( CKEDITOR.env.webkit ) {
-			editor.on( 'selectionChange', function() {
-				checkFillingChar( editor.editable() );
-			}, null, null, -1 );
-			editor.on( 'beforeSetMode', function() {
-				removeFillingChar( editor.editable() );
-			}, null, null, -1 );
-
-			var fillingCharBefore, resetSelection;
-
-			function beforeData() {
-				var editable = editor.editable();
-				if ( !editable )
-					return;
-
-				var fillingChar = getFillingChar( editable );
-
-				if ( fillingChar ) {
-					// If cursor is right blinking by side of the filler node, save it for restoring,
-					// as the following text substitution will blind it. (#7437)
-					var sel = editor.document.$.defaultView.getSelection();
-					if ( sel.type == 'Caret' && sel.anchorNode == fillingChar.$ )
-						resetSelection = 1;
-
-					fillingCharBefore = fillingChar.getText();
-					fillingChar.setText( replaceFillingChar( fillingCharBefore ) );
-				}
-			}
-
-			function afterData() {
-				var editable = editor.editable();
-				if ( !editable )
-					return;
-
-				var fillingChar = getFillingChar( editable );
-
-				if ( fillingChar ) {
-					fillingChar.setText( fillingCharBefore );
-
-					if ( resetSelection ) {
-						editor.document.$.defaultView.getSelection().setPosition( fillingChar.$, fillingChar.getLength() );
-						resetSelection = 0;
-					}
-				}
-			}
-
-			editor.on( 'beforeUndoImage', beforeData );
-			editor.on( 'afterUndoImage', afterData );
-			editor.on( 'beforeGetData', beforeData, null, null, 0 );
-			editor.on( 'getData', afterData );
-		}
-	} );
-
-	/**
-	 * Check the selection change in editor and potentially fires
-	 * the {@link CKEDITOR.editor#event-selectionChange} event.
-	 *
-	 * @method
-	 * @member CKEDITOR.editor
-	 * @param {Boolean} [checkNow=false] Force the check to happen immediately
-	 * instead of coming with a timeout delay (default).
-	 */
-	CKEDITOR.editor.prototype.selectionChange = function( checkNow ) {
-		( checkNow ? checkSelectionChange : checkSelectionChangeTimeout ).call( this );
-	};
-
-	/**
-	 * Retrieve the editor selection in scope of editable element.
-	 *
-	 * **Note:** Since the native browser selection provides only one single
-	 * selection at a time per document, so if editor's editable element has lost focus,
-	 * this method will return a null value unless the {@link CKEDITOR.editor#lockSelection}
-	 * has been called beforehand so the saved selection is retrieved.
-	 *
-	 *		var selection = CKEDITOR.instances.editor1.getSelection();
-	 *		alert( selection.getType() );
-	 *
-	 * @method
-	 * @member CKEDITOR.editor
-	 * @param {Boolean} forceRealSelection Return real selection, instead of saved or fake one.
-	 * @returns {CKEDITOR.dom.selection} A selection object or null if not available for the moment.
-	 */
-	CKEDITOR.editor.prototype.getSelection = function( forceRealSelection ) {
-
-		// Check if there exists a locked or fake selection.
-		if ( ( this._.savedSelection || this._.fakeSelection ) && !forceRealSelection )
-			return this._.savedSelection || this._.fakeSelection;
-
-		// Editable element might be absent or editor might not be in a wysiwyg mode.
-		var editable = this.editable();
-		return editable && this.mode == 'wysiwyg' ? new CKEDITOR.dom.selection( editable ) : null;
-	};
-
-	/**
-	 * Locks the selection made in the editor in order to make it possible to
-	 * manipulate it without browser interference. A locked selection is
-	 * cached and remains unchanged until it is released with the
-	 * {@link CKEDITOR.editor#unlockSelection} method.
-	 *
-	 * @method
-	 * @member CKEDITOR.editor
-	 * @param {CKEDITOR.dom.selection} [sel] Specify the selection to be locked.
-	 * @returns {Boolean} `true` if selection was locked.
-	 */
-	CKEDITOR.editor.prototype.lockSelection = function( sel ) {
-		sel = sel || this.getSelection( 1 );
-		if ( sel.getType() != CKEDITOR.SELECTION_NONE ) {
-			!sel.isLocked && sel.lock();
-			this._.savedSelection = sel;
-			return true;
-		}
-		return false;
-	};
-
-	/**
-	 * Unlocks the selection made in the editor and locked with the
-	 * {@link CKEDITOR.editor#unlockSelection} method. An unlocked selection
-	 * is no longer cached and can be changed.
-	 *
-	 * @method
-	 * @member CKEDITOR.editor
-	 * @param {Boolean} [restore] If set to `true`, the selection is
-	 * restored back to the selection saved earlier by using the
-	 * {@link CKEDITOR.dom.selection#lock} method.
-	 */
-	CKEDITOR.editor.prototype.unlockSelection = function( restore ) {
-		var sel = this._.savedSelection;
-		if ( sel ) {
-			sel.unlock( restore );
-			delete this._.savedSelection;
-			return true;
-		}
-
-		return false;
-	};
-
-	/**
-	 * @method
-	 * @member CKEDITOR.editor
-	 * @todo
-	 */
-	CKEDITOR.editor.prototype.forceNextSelectionCheck = function() {
-		delete this._.selectionPreviousPath;
-	};
-
-	/**
-	 * Gets the current selection in context of the document's body element.
-	 *
-	 *		var selection = CKEDITOR.instances.editor1.document.getSelection();
-	 *		alert( selection.getType() );
-	 *
-	 * @method
-	 * @member CKEDITOR.dom.document
-	 * @returns {CKEDITOR.dom.selection} A selection object.
-	 */
-	CKEDITOR.dom.document.prototype.getSelection = function() {
-		return new CKEDITOR.dom.selection( this );
-	};
-
-	/**
-	 * Select this range as the only one with {@link CKEDITOR.dom.selection#selectRanges}.
-	 *
-	 * @method
-	 * @returns {CKEDITOR.dom.selection}
-	 * @member CKEDITOR.dom.range
-	 */
-	CKEDITOR.dom.range.prototype.select = function() {
-		var sel = this.root instanceof CKEDITOR.editable ? this.root.editor.getSelection() : new CKEDITOR.dom.selection( this.root );
-
-		sel.selectRanges( [ this ] );
-
-		return sel;
-	};
-
-	/**
-	 * No selection.
-	 *
-	 *		if ( editor.getSelection().getType() == CKEDITOR.SELECTION_NONE )
-	 *			alert( 'Nothing is selected' );
-	 *
-	 * @readonly
-	 * @property {Number} [=1]
-	 * @member CKEDITOR
-	 */
-	CKEDITOR.SELECTION_NONE = 1;
-
-	/**
-	 * A text or a collapsed selection.
-	 *
-	 *		if ( editor.getSelection().getType() == CKEDITOR.SELECTION_TEXT )
-	 *			alert( 'A text is selected' );
-	 *
-	 * @readonly
-	 * @property {Number} [=2]
-	 * @member CKEDITOR
-	 */
-	CKEDITOR.SELECTION_TEXT = 2;
-
-	/**
-	 * Element selection.
-	 *
-	 *		if ( editor.getSelection().getType() == CKEDITOR.SELECTION_ELEMENT )
-	 *			alert( 'An element is selected' );
-	 *
-	 * @readonly
-	 * @property {Number} [=3]
-	 * @member CKEDITOR
-	 */
-	CKEDITOR.SELECTION_ELEMENT = 3;
-
-	var isMSSelection = typeof window.getSelection != 'function',
-		nextRev = 1;
-
-	/**
-	 * Manipulates the selection within a DOM element. If the current browser selection
-	 * spans outside of the element, an empty selection object is returned.
-	 *
-	 * Despite the fact that selection's constructor allows to create selection instances,
-	 * usually it's better to get selection from the editor instance:
-	 *
-	 *		var sel = editor.getSelection();
-	 *
-	 * See {@link CKEDITOR.editor#getSelection}.
-	 *
-	 * @class
-	 * @constructor Creates a selection class instance.
-	 *
-	 *		// Selection scoped in document.
-	 *		var sel = new CKEDITOR.dom.selection( CKEDITOR.document );
-	 *
-	 *		// Selection scoped in element with 'editable' id.
-	 *		var sel = new CKEDITOR.dom.selection( CKEDITOR.document.getById( 'editable' ) );
-	 *
-	 *		// Cloning selection.
-	 *		var clone = new CKEDITOR.dom.selection( sel );
-	 *
-	 * @param {CKEDITOR.dom.document/CKEDITOR.dom.element/CKEDITOR.dom.selection} target
-	 * The DOM document/element that the DOM selection is restrained to. Only selection which spans
-	 * within the target element is considered as valid.
-	 *
-	 * If {@link CKEDITOR.dom.selection} is passed, then its clone will be created.
-	 */
-	CKEDITOR.dom.selection = function( target ) {
-		// Target is a selection - clone it.
-		if ( target instanceof CKEDITOR.dom.selection ) {
-			var selection = target;
-			target = target.root;
-		}
-
-		var isElement = target instanceof CKEDITOR.dom.element,
-			root;
-
-		this.rev = selection ? selection.rev : nextRev++;
-		this.document = target instanceof CKEDITOR.dom.document ? target : target.getDocument();
-		this.root = root = isElement ? target : this.document.getBody();
-		this.isLocked = 0;
-		this._ = {
-			cache: {}
-		};
-
-		// Clone selection.
-		if ( selection ) {
-			CKEDITOR.tools.extend( this._.cache, selection._.cache );
-			this.isFake = selection.isFake;
-			this.isLocked = selection.isLocked;
-			return this;
-		}
-
-		// On WebKit, it may happen that we've already have focus
-		// on the editable element while still having no selection
-		// available. We normalize it here by replicating the
-		// behavior of other browsers.
-		//
-		// Webkit's condition covers also the case when editable hasn't been focused
-		// at all. Thanks to this hack Webkit always has selection in the right place.
-		//
-		// On FF and IE we only fix the first case, when editable was activated
-		// but the selection is broken - usually this happens after setData if editor was focused.
-
-		var sel = isMSSelection ? this.document.$.selection : this.document.getWindow().$.getSelection();
-
-		if ( CKEDITOR.env.webkit ) {
-			if ( sel.type == 'None' && this.document.getActive().equals( root ) || sel.type == 'Caret' && sel.anchorNode.nodeType == CKEDITOR.NODE_DOCUMENT )
-				fixInitialSelection( root, sel );
-		}
-		else if ( CKEDITOR.env.gecko ) {
-			if ( sel && this.document.getActive().equals( root ) &&
-				sel.anchorNode && sel.anchorNode.nodeType == CKEDITOR.NODE_DOCUMENT )
-				fixInitialSelection( root, sel, true );
-		}
-		else if ( CKEDITOR.env.ie ) {
-			var active;
-
-			// IE8,9 throw unspecified error when trying to access document.$.activeElement.
-			try {
-				active = this.document.getActive();
-			} catch ( e ) {}
-
-			// IEs 9+.
-			if ( !isMSSelection ) {
-				var anchorNode = sel && sel.anchorNode;
-
-				if ( anchorNode )
-					anchorNode = new CKEDITOR.dom.node( anchorNode );
-
-				if ( active && active.equals( this.document.getDocumentElement() ) &&
-					anchorNode && ( root.equals( anchorNode ) || root.contains( anchorNode ) ) )
-					fixInitialSelection( root, null, true );
-			}
-			// IEs 7&8.
-			else if ( sel.type == 'None' && active && active.equals( this.document.getDocumentElement() ) )
-				fixInitialSelection( root, null, true );
-		}
-
-		// Check whether browser focus is really inside of the editable element.
-
-		var nativeSel = this.getNative(),
-			rangeParent,
-			range;
-
-		if ( nativeSel ) {
-			if ( nativeSel.getRangeAt ) {
-				range = nativeSel.rangeCount && nativeSel.getRangeAt( 0 );
-				rangeParent = range && new CKEDITOR.dom.node( range.commonAncestorContainer );
-			}
-			// For old IEs.
-			else {
-				// Sometimes, mostly when selection is close to the table or hr,
-				// IE throws "Unspecified error".
-				try {
-					range = nativeSel.createRange();
-				} catch ( err ) {}
-				rangeParent = range && CKEDITOR.dom.element.get( range.item && range.item( 0 ) || range.parentElement() );
-			}
-		}
-
-		// Selection out of concerned range, empty the selection.
-		// TODO check whether this condition cannot be reverted to its old
-		// form (commented out) after we closed #10438.
-		//if ( !( rangeParent && ( root.equals( rangeParent ) || root.contains( rangeParent ) ) ) ) {
-		if ( !(
-			rangeParent &&
-			( rangeParent.type == CKEDITOR.NODE_ELEMENT || rangeParent.type == CKEDITOR.NODE_TEXT ) &&
-			( this.root.equals( rangeParent ) || this.root.contains( rangeParent ) )
-		) ) {
-
-			this._.cache.type = CKEDITOR.SELECTION_NONE;
-			this._.cache.startElement = null;
-			this._.cache.selectedElement = null;
-			this._.cache.selectedText = '';
-			this._.cache.ranges = new CKEDITOR.dom.rangeList();
-		}
-
-		return this;
-	};
-
-	var styleObjectElements = { img: 1, hr: 1, li: 1, table: 1, tr: 1, td: 1, th: 1, embed: 1, object: 1, ol: 1, ul: 1,
-			a: 1, input: 1, form: 1, select: 1, textarea: 1, button: 1, fieldset: 1, thead: 1, tfoot: 1 };
-
-	CKEDITOR.dom.selection.prototype = {
-		/**
-		 * Gets the native selection object from the browser.
-		 *
-		 *		var selection = editor.getSelection().getNative();
-		 *
-		 * @returns {Object} The native browser selection object.
-		 */
-		getNative: function() {
-			if ( this._.cache.nativeSel !== undefined )
-				return this._.cache.nativeSel;
-
-			return ( this._.cache.nativeSel = isMSSelection ? this.document.$.selection : this.document.getWindow().$.getSelection() );
-		},
-
-		/**
-		 * Gets the type of the current selection. The following values are
-		 * available:
-		 *
-		 * * {@link CKEDITOR#SELECTION_NONE} (1): No selection.
-		 * * {@link CKEDITOR#SELECTION_TEXT} (2): A text or a collapsed selection is selected.
-		 * * {@link CKEDITOR#SELECTION_ELEMENT} (3): An element is selected.
-		 *
-		 * Example:
-		 *
-		 *		if ( editor.getSelection().getType() == CKEDITOR.SELECTION_TEXT )
-		 *			alert( 'A text is selected' );
-		 *
-		 * @method
-		 * @returns {Number} One of the following constant values: {@link CKEDITOR#SELECTION_NONE},
-		 * {@link CKEDITOR#SELECTION_TEXT} or {@link CKEDITOR#SELECTION_ELEMENT}.
-		 */
-		getType: isMSSelection ?
-		function() {
-			var cache = this._.cache;
-			if ( cache.type )
-				return cache.type;
-
-			var type = CKEDITOR.SELECTION_NONE;
-
-			try {
-				var sel = this.getNative(),
-					ieType = sel.type;
-
-				if ( ieType == 'Text' )
-					type = CKEDITOR.SELECTION_TEXT;
-
-				if ( ieType == 'Control' )
-					type = CKEDITOR.SELECTION_ELEMENT;
-
-				// It is possible that we can still get a text range
-				// object even when type == 'None' is returned by IE.
-				// So we'd better check the object returned by
-				// createRange() rather than by looking at the type.
-				if ( sel.createRange().parentElement() )
-					type = CKEDITOR.SELECTION_TEXT;
-			} catch ( e ) {}
-
-			return ( cache.type = type );
-		} : function() {
-			var cache = this._.cache;
-			if ( cache.type )
-				return cache.type;
-
-			var type = CKEDITOR.SELECTION_TEXT;
-
-			var sel = this.getNative();
-
-			if ( !( sel && sel.rangeCount ) )
-				type = CKEDITOR.SELECTION_NONE;
-			else if ( sel.rangeCount == 1 ) {
-				// Check if the actual selection is a control (IMG,
-				// TABLE, HR, etc...).
-
-				var range = sel.getRangeAt( 0 ),
-					startContainer = range.startContainer;
-
-				if ( startContainer == range.endContainer && startContainer.nodeType == 1 && ( range.endOffset - range.startOffset ) == 1 && styleObjectElements[ startContainer.childNodes[ range.startOffset ].nodeName.toLowerCase() ] )
-					type = CKEDITOR.SELECTION_ELEMENT;
-
-			}
-
-			return ( cache.type = type );
-		},
-
-		/**
-		 * Retrieves the {@link CKEDITOR.dom.range} instances that represent the current selection.
-		 *
-		 * Note: Some browsers return multiple ranges even for a continuous selection. Firefox, for example, returns
-		 * one range for each table cell when one or more table rows are selected.
-		 *
-		 *		var ranges = selection.getRanges();
-		 *		alert( ranges.length );
-		 *
-		 * @method
-		 * @param {Boolean} [onlyEditables] If set to `true`, this function retrives editable ranges only.
-		 * @returns {Array} Range instances that represent the current selection.
-		 */
-		getRanges: ( function() {
-			var func = isMSSelection ? ( function() {
-				function getNodeIndex( node ) {
-					return new CKEDITOR.dom.node( node ).getIndex();
-				}
-
-				// Finds the container and offset for a specific boundary
-				// of an IE range.
-				var getBoundaryInformation = function( range, start ) {
-						// Creates a collapsed range at the requested boundary.
-						range = range.duplicate();
-						range.collapse( start );
-
-						// Gets the element that encloses the range entirely.
-						var parent = range.parentElement(),
-							doc = parent.ownerDocument;
-
-						// Empty parent element, e.g. <i>^</i>
-						if ( !parent.hasChildNodes() )
-							return { container: parent, offset: 0 };
-
-						var siblings = parent.children,
-							child, sibling,
-							testRange = range.duplicate(),
-							startIndex = 0,
-							endIndex = siblings.length - 1,
-							index = -1,
-							position, distance, container;
-
-						// Binary search over all element childs to test the range to see whether
-						// range is right on the boundary of one element.
-						while ( startIndex <= endIndex ) {
-							index = Math.floor( ( startIndex + endIndex ) / 2 );
-							child = siblings[ index ];
-							testRange.moveToElementText( child );
-							position = testRange.compareEndPoints( 'StartToStart', range );
-
-							if ( position > 0 )
-								endIndex = index - 1;
-							else if ( position < 0 )
-								startIndex = index + 1;
-							else
-								return { container: parent, offset: getNodeIndex( child ) };
-						}
-
-						// All childs are text nodes,
-						// or to the right hand of test range are all text nodes. (#6992)
-						if ( index == -1 || index == siblings.length - 1 && position < 0 ) {
-							// Adapt test range to embrace the entire parent contents.
-							testRange.moveToElementText( parent );
-							testRange.setEndPoint( 'StartToStart', range );
-
-							// IE report line break as CRLF with range.text but
-							// only LF with textnode.nodeValue, normalize them to avoid
-							// breaking character counting logic below. (#3949)
-							distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length;
-
-							siblings = parent.childNodes;
-
-							// Actual range anchor right beside test range at the boundary of text node.
-							if ( !distance ) {
-								child = siblings[ siblings.length - 1 ];
-
-								if ( child.nodeType != CKEDITOR.NODE_TEXT )
-									return { container: parent, offset: siblings.length };
-								else
-									return { container: child, offset: child.nodeValue.length };
-							}
-
-							// Start the measuring until distance overflows, meanwhile count the text nodes.
-							var i = siblings.length;
-							while ( distance > 0 && i > 0 ) {
-								sibling = siblings[ --i ];
-								if ( sibling.nodeType == CKEDITOR.NODE_TEXT ) {
-									container = sibling;
-									distance -= sibling.nodeValue.length;
-								}
-							}
-
-							return { container: container, offset: -distance };
-						}
-						// Test range was one offset beyond OR behind the anchored text node.
-						else {
-							// Adapt one side of test range to the actual range
-							// for measuring the offset between them.
-							testRange.collapse( position > 0 ? true : false );
-							testRange.setEndPoint( position > 0 ? 'StartToStart' : 'EndToStart', range );
-
-							// IE report line break as CRLF with range.text but
-							// only LF with textnode.nodeValue, normalize them to avoid
-							// breaking character counting logic below. (#3949)
-							distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length;
-
-							// Actual range anchor right beside test range at the inner boundary of text node.
-							if ( !distance )
-								return { container: parent, offset: getNodeIndex( child ) + ( position > 0 ? 0 : 1 ) };
-
-							// Start the measuring until distance overflows, meanwhile count the text nodes.
-							while ( distance > 0 ) {
-								try {
-									sibling = child[ position > 0 ? 'previousSibling' : 'nextSibling' ];
-									if ( sibling.nodeType == CKEDITOR.NODE_TEXT ) {
-										distance -= sibling.nodeValue.length;
-										container = sibling;
-									}
-									child = sibling;
-								}
-								// Measurement in IE could be somtimes wrong because of <select> element. (#4611)
-								catch ( e ) {
-									return { container: parent, offset: getNodeIndex( child ) };
-								}
-							}
-
-							return { container: container, offset: position > 0 ? -distance : container.nodeValue.length + distance };
-						}
-					};
-
-				return function() {
-					// IE doesn't have range support (in the W3C way), so we
-					// need to do some magic to transform selections into
-					// CKEDITOR.dom.range instances.
-
-					var sel = this.getNative(),
-						nativeRange = sel && sel.createRange(),
-						type = this.getType(),
-						range;
-
-					if ( !sel )
-						return [];
-
-					if ( type == CKEDITOR.SELECTION_TEXT ) {
-						range = new CKEDITOR.dom.range( this.root );
-
-						var boundaryInfo = getBoundaryInformation( nativeRange, true );
-						range.setStart( new CKEDITOR.dom.node( boundaryInfo.container ), boundaryInfo.offset );
-
-						boundaryInfo = getBoundaryInformation( nativeRange );
-						range.setEnd( new CKEDITOR.dom.node( boundaryInfo.container ), boundaryInfo.offset );
-
-						// Correct an invalid IE range case on empty list item. (#5850)
-						if ( range.endContainer.getPosition( range.startContainer ) & CKEDITOR.POSITION_PRECEDING && range.endOffset <= range.startContainer.getIndex() )
-							range.collapse();
-
-						return [ range ];
-					} else if ( type == CKEDITOR.SELECTION_ELEMENT ) {
-						var retval = [];
-
-						for ( var i = 0; i < nativeRange.length; i++ ) {
-							var element = nativeRange.item( i ),
-								parentElement = element.parentNode,
-								j = 0;
-
-							range = new CKEDITOR.dom.range( this.root );
-
-							for ( ; j < parentElement.childNodes.length && parentElement.childNodes[ j ] != element; j++ ) {
-								/*jsl:pass*/
-							}
-
-							range.setStart( new CKEDITOR.dom.node( parentElement ), j );
-							range.setEnd( new CKEDITOR.dom.node( parentElement ), j + 1 );
-							retval.push( range );
-						}
-
-						return retval;
-					}
-
-					return [];
-				};
-			} )() : function() {
-
-					// On browsers implementing the W3C range, we simply
-					// tranform the native ranges in CKEDITOR.dom.range
-					// instances.
-
-					var ranges = [],
-						range,
-						sel = this.getNative();
-
-					if ( !sel )
-						return ranges;
-
-					for ( var i = 0; i < sel.rangeCount; i++ ) {
-						var nativeRange = sel.getRangeAt( i );
-
-						range = new CKEDITOR.dom.range( this.root );
-
-						range.setStart( new CKEDITOR.dom.node( nativeRange.startContainer ), nativeRange.startOffset );
-						range.setEnd( new CKEDITOR.dom.node( nativeRange.endContainer ), nativeRange.endOffset );
-						ranges.push( range );
-					}
-					return ranges;
-				};
-
-			return function( onlyEditables ) {
-				var cache = this._.cache,
-					ranges = cache.ranges;
-
-				if ( !ranges )
-					cache.ranges = ranges = new CKEDITOR.dom.rangeList( func.call( this ) );
-
-				if ( !onlyEditables )
-					return ranges;
-
-				// Split range into multiple by read-only nodes.
-				// Clone ranges array to avoid changing cached ranges (#11493).
-				return extractEditableRanges( new CKEDITOR.dom.rangeList( ranges.slice() ) );
-			};
-		} )(),
-
-		/**
-		 * Gets the DOM element in which the selection starts.
-		 *
-		 *		var element = editor.getSelection().getStartElement();
-		 *		alert( element.getName() );
-		 *
-		 * @returns {CKEDITOR.dom.element} The element at the beginning of the selection.
-		 */
-		getStartElement: function() {
-			var cache = this._.cache;
-			if ( cache.startElement !== undefined )
-				return cache.startElement;
-
-			var node;
-
-			switch ( this.getType() ) {
-				case CKEDITOR.SELECTION_ELEMENT:
-					return this.getSelectedElement();
-
-				case CKEDITOR.SELECTION_TEXT:
-
-					var range = this.getRanges()[ 0 ];
-
-					if ( range ) {
-						if ( !range.collapsed ) {
-							range.optimize();
-
-							// Decrease the range content to exclude particial
-							// selected node on the start which doesn't have
-							// visual impact. ( #3231 )
-							while ( 1 ) {
-								var startContainer = range.startContainer,
-									startOffset = range.startOffset;
-								// Limit the fix only to non-block elements.(#3950)
-								if ( startOffset == ( startContainer.getChildCount ? startContainer.getChildCount() : startContainer.getLength() ) && !startContainer.isBlockBoundary() )
-									range.setStartAfter( startContainer );
-								else
-									break;
-							}
-
-							node = range.startContainer;
-
-							if ( node.type != CKEDITOR.NODE_ELEMENT )
-								return node.getParent();
-
-							node = node.getChild( range.startOffset );
-
-							if ( !node || node.type != CKEDITOR.NODE_ELEMENT )
-								node = range.startContainer;
-							else {
-								var child = node.getFirst();
-								while ( child && child.type == CKEDITOR.NODE_ELEMENT ) {
-									node = child;
-									child = child.getFirst();
-								}
-							}
-						} else {
-							node = range.startContainer;
-							if ( node.type != CKEDITOR.NODE_ELEMENT )
-								node = node.getParent();
-						}
-
-						node = node.$;
-					}
-			}
-
-			return cache.startElement = ( node ? new CKEDITOR.dom.element( node ) : null );
-		},
-
-		/**
-		 * Gets the currently selected element.
-		 *
-		 *		var element = editor.getSelection().getSelectedElement();
-		 *		alert( element.getName() );
-		 *
-		 * @returns {CKEDITOR.dom.element} The selected element. Null if no
-		 * selection is available or the selection type is not {@link CKEDITOR#SELECTION_ELEMENT}.
-		 */
-		getSelectedElement: function() {
-			var cache = this._.cache;
-			if ( cache.selectedElement !== undefined )
-				return cache.selectedElement;
-
-			var self = this;
-
-			var node = CKEDITOR.tools.tryThese(
-				// Is it native IE control type selection?
-				function() {
-					return self.getNative().createRange().item( 0 );
-				},
-				// Figure it out by checking if there's a single enclosed
-				// node of the range.
-				function() {
-					var range = self.getRanges()[ 0 ].clone(),
-						enclosed, selected;
-
-					// Check first any enclosed element, e.g. <ul>[<li><a href="#">item</a></li>]</ul>
-					for ( var i = 2; i && !( ( enclosed = range.getEnclosedNode() ) && ( enclosed.type == CKEDITOR.NODE_ELEMENT ) && styleObjectElements[ enclosed.getName() ] && ( selected = enclosed ) ); i-- ) {
-						// Then check any deep wrapped element, e.g. [<b><i><img /></i></b>]
-						range.shrink( CKEDITOR.SHRINK_ELEMENT );
-					}
-
-					return selected && selected.$;
-				}
-			);
-
-			return cache.selectedElement = ( node ? new CKEDITOR.dom.element( node ) : null );
-		},
-
-		/**
-		 * Retrieves the text contained within the range. An empty string is returned for non-text selection.
-		 *
-		 *		var text = editor.getSelection().getSelectedText();
-		 *		alert( text );
-		 *
-		 * @since 3.6.1
-		 * @returns {String} A string of text within the current selection.
-		 */
-		getSelectedText: function() {
-			var cache = this._.cache;
-			if ( cache.selectedText !== undefined )
-				return cache.selectedText;
-
-			var nativeSel = this.getNative(),
-				text = isMSSelection ? nativeSel.type == 'Control' ? '' : nativeSel.createRange().text : nativeSel.toString();
-
-			return ( cache.selectedText = text );
-		},
-
-		/**
-		 * Locks the selection made in the editor in order to make it possible to
-		 * manipulate it without browser interference. A locked selection is
-		 * cached and remains unchanged until it is released with the {@link #unlock} method.
-		 *
-		 *		editor.getSelection().lock();
-		 */
-		lock: function() {
-			// Call all cacheable function.
-			this.getRanges();
-			this.getStartElement();
-			this.getSelectedElement();
-			this.getSelectedText();
-
-			// The native selection is not available when locked.
-			this._.cache.nativeSel = null;
-
-			this.isLocked = 1;
-		},
-
-		/**
-		 * @todo
-		 */
-		unlock: function( restore ) {
-			if ( !this.isLocked )
-				return;
-
-			if ( restore ) {
-				var selectedElement = this.getSelectedElement(),
-					ranges = !selectedElement && this.getRanges(),
-					faked = this.isFake;
-			}
-
-			this.isLocked = 0;
-			this.reset();
-
-			if ( restore ) {
-				// Saved selection may be outdated (e.g. anchored in offline nodes).
-				// Avoid getting broken by such.
-				var common = selectedElement || ranges[ 0 ] && ranges[ 0 ].getCommonAncestor();
-				if ( !( common && common.getAscendant( 'body', 1 ) ) )
-					return;
-
-				if ( faked )
-					this.fake( selectedElement );
-				else if ( selectedElement )
-					this.selectElement( selectedElement );
-				else
-					this.selectRanges( ranges );
-			}
-		},
-
-		/**
-		 * Clears the selection cache.
-		 *
-		 *		editor.getSelection().reset();
-		 */
-		reset: function() {
-			this._.cache = {};
-			this.isFake = 0;
-
-			var editor = this.root.editor,
-				listener;
-
-			// Invalidate any fake selection available in the editor.
-			if ( editor && editor._.fakeSelection ) {
-				// Test whether this selection is the one that was
-				// faked or its clone.
-				if ( this.rev == editor._.fakeSelection.rev ) {
-					delete editor._.fakeSelection;
-
-					removeHiddenSelectionContainer( editor );
-				}
-				// TODO after #9786 use commented out lines instead of console.log.
-				else // %REMOVE_LINE%
-					window.console && console.log( 'Wrong selection instance resets fake selection.' ); // %REMOVE_LINE%
-				// else // %REMOVE_LINE%
-				//	CKEDITOR.debug.error( 'Wrong selection instance resets fake selection.', CKEDITOR.DEBUG_CRITICAL ); // %REMOVE_LINE%
-			}
-
-			this.rev = nextRev++;
-		},
-
-		/**
-		 * Makes the current selection of type {@link CKEDITOR#SELECTION_ELEMENT} by enclosing the specified element.
-		 *
-		 *		var element = editor.document.getById( 'sampleElement' );
-		 *		editor.getSelection().selectElement( element );
-		 *
-		 * @param {CKEDITOR.dom.element} element The element to enclose in the selection.
-		 */
-		selectElement: function( element ) {
-			var range = new CKEDITOR.dom.range( this.root );
-			range.setStartBefore( element );
-			range.setEndAfter( element );
-			this.selectRanges( [ range ] );
-		},
-
-		/**
-		 * Clears the original selection and adds the specified ranges to the document selection.
-		 *
-		 * 		// Move selection to the end of the editable element.
-		 *		var range = editor.createRange();
-		 *		range.moveToPosition( range.root, CKEDITOR.POSITION_BEFORE_END );
-		 *		editor.getSelection().selectRanges( [ ranges ] );
-		 *
-		 * @param {Array} ranges An array of {@link CKEDITOR.dom.range} instances
-		 * representing ranges to be added to the document.
-		 */
-		selectRanges: function( ranges ) {
-			var editor = this.root.editor,
-				hadHiddenSelectionContainer = editor && editor._.hiddenSelectionContainer;
-
-			this.reset();
-
-			// Check if there's a hiddenSelectionContainer in editable at some index.
-			// Some ranges may be anchored after the hiddenSelectionContainer and,
-			// once the container is removed while resetting the selection, they
-			// may need new endOffset (one element less within the range) (#11021 #11393).
-			if ( hadHiddenSelectionContainer )
-				fixRangesAfterHiddenSelectionContainer( ranges, this.root );
-
-			if ( !ranges.length )
-				return;
-
-			// Refresh the locked selection.
-			if ( this.isLocked ) {
-				// making a new DOM selection will force the focus on editable in certain situation,
-				// we have to save the currently focused element for later recovery.
-				var focused = CKEDITOR.document.getActive();
-				this.unlock();
-				this.selectRanges( ranges );
-				this.lock();
-				// Return to the previously focused element.
-				!focused.equals( this.root ) && focused.focus();
-				return;
-			}
-
-			// Handle special case - automatic fake selection on non-editable elements.
-			var receiver = getNonEditableFakeSelectionReceiver( ranges );
-
-			if ( receiver ) {
-				this.fake( receiver );
-				return;
-			}
-
-			if ( isMSSelection ) {
-				var notWhitespaces = CKEDITOR.dom.walker.whitespaces( true ),
-					fillerTextRegex = /\ufeff|\u00a0/,
-					nonCells = { table: 1, tbody: 1, tr: 1 };
-
-				if ( ranges.length > 1 ) {
-					// IE doesn't accept multiple ranges selection, so we join all into one.
-					var last = ranges[ ranges.length - 1 ];
-					ranges[ 0 ].setEnd( last.endContainer, last.endOffset );
-				}
-
-				var range = ranges[ 0 ];
-				var collapsed = range.collapsed,
-					isStartMarkerAlone, dummySpan, ieRange;
-
-				// Try to make a object selection, be careful with selecting phase element in IE
-				// will breaks the selection in non-framed environment.
-				var selected = range.getEnclosedNode();
-				if ( selected && selected.type == CKEDITOR.NODE_ELEMENT && selected.getName() in styleObjectElements && !( selected.is( 'a' ) && selected.getText() ) ) {
-					try {
-						ieRange = selected.$.createControlRange();
-						ieRange.addElement( selected.$ );
-						ieRange.select();
-						return;
-					} catch ( er ) {}
-				}
-
-				// IE doesn't support selecting the entire table row/cell, move the selection into cells, e.g.
-				// <table><tbody><tr>[<td>cell</b></td>... => <table><tbody><tr><td>[cell</td>...
-				if ( range.startContainer.type == CKEDITOR.NODE_ELEMENT && range.startContainer.getName() in nonCells || range.endContainer.type == CKEDITOR.NODE_ELEMENT && range.endContainer.getName() in nonCells )
-					range.shrink( CKEDITOR.NODE_ELEMENT, true );
-
-				var bookmark = range.createBookmark();
-
-				// Create marker tags for the start and end boundaries.
-				var startNode = bookmark.startNode;
-
-				var endNode;
-				if ( !collapsed )
-					endNode = bookmark.endNode;
-
-				// Create the main range which will be used for the selection.
-				ieRange = range.document.$.body.createTextRange();
-
-				// Position the range at the start boundary.
-				ieRange.moveToElementText( startNode.$ );
-				ieRange.moveStart( 'character', 1 );
-
-				if ( endNode ) {
-					// Create a tool range for the end.
-					var ieRangeEnd = range.document.$.body.createTextRange();
-
-					// Position the tool range at the end.
-					ieRangeEnd.moveToElementText( endNode.$ );
-
-					// Move the end boundary of the main range to match the tool range.
-					ieRange.setEndPoint( 'EndToEnd', ieRangeEnd );
-					ieRange.moveEnd( 'character', -1 );
-				} else {
-					// The isStartMarkerAlone logic comes from V2. It guarantees that the lines
-					// will expand and that the cursor will be blinking on the right place.
-					// Actually, we are using this flag just to avoid using this hack in all
-					// situations, but just on those needed.
-					var next = startNode.getNext( notWhitespaces );
-					var inPre = startNode.hasAscendant( 'pre' );
-					isStartMarkerAlone = ( !( next && next.getText && next.getText().match( fillerTextRegex ) ) // already a filler there?
-					&& ( inPre || !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) ) ) );
-
-					// Append a temporary <span>&#65279;</span> before the selection.
-					// This is needed to avoid IE destroying selections inside empty
-					// inline elements, like <b></b> (#253).
-					// It is also needed when placing the selection right after an inline
-					// element to avoid the selection moving inside of it.
-					dummySpan = range.document.createElement( 'span' );
-					dummySpan.setHtml( '&#65279;' ); // Zero Width No-Break Space (U+FEFF). See #1359.
-					dummySpan.insertBefore( startNode );
-
-					if ( isStartMarkerAlone ) {
-						// To expand empty blocks or line spaces after <br>, we need
-						// instead to have any char, which will be later deleted using the
-						// selection.
-						// \ufeff = Zero Width No-Break Space (U+FEFF). (#1359)
-						range.document.createText( '\ufeff' ).insertBefore( startNode );
-					}
-				}
-
-				// Remove the markers (reset the position, because of the changes in the DOM tree).
-				range.setStartBefore( startNode );
-				startNode.remove();
-
-				if ( collapsed ) {
-					if ( isStartMarkerAlone ) {
-						// Move the selection start to include the temporary \ufeff.
-						ieRange.moveStart( 'character', -1 );
-
-						ieRange.select();
-
-						// Remove our temporary stuff.
-						range.document.$.selection.clear();
-					} else
-						ieRange.select();
-
-					range.moveToPosition( dummySpan, CKEDITOR.POSITION_BEFORE_START );
-					dummySpan.remove();
-				} else {
-					range.setEndBefore( endNode );
-					endNode.remove();
-					ieRange.select();
-				}
-			} else {
-				var sel = this.getNative();
-
-				// getNative() returns null if iframe is "display:none" in FF. (#6577)
-				if ( !sel )
-					return;
-
-				// Opera: The above hack work around a *visually wrong* text selection that
-				// happens in certain situation. (#6874, #9447)
-				if ( CKEDITOR.env.opera ) {
-					var nativeRng = this.document.$.createRange();
-					nativeRng.selectNodeContents( this.root.$ );
-					sel.addRange( nativeRng );
-				}
-
-				this.removeAllRanges();
-
-				for ( var i = 0; i < ranges.length; i++ ) {
-					// Joining sequential ranges introduced by
-					// readonly elements protection.
-					if ( i < ranges.length - 1 ) {
-						var left = ranges[ i ],
-							right = ranges[ i + 1 ],
-							between = left.clone();
-						between.setStart( left.endContainer, left.endOffset );
-						between.setEnd( right.startContainer, right.startOffset );
-
-						// Don't confused by Firefox adjancent multi-ranges
-						// introduced by table cells selection.
-						if ( !between.collapsed ) {
-							between.shrink( CKEDITOR.NODE_ELEMENT, true );
-							var ancestor = between.getCommonAncestor(),
-								enclosed = between.getEnclosedNode();
-
-							// The following cases has to be considered:
-							// 1. <span contenteditable="false">[placeholder]</span>
-							// 2. <input contenteditable="false"  type="radio"/> (#6621)
-							if ( ancestor.isReadOnly() || enclosed && enclosed.isReadOnly() ) {
-								right.setStart( left.startContainer, left.startOffset );
-								ranges.splice( i--, 1 );
-								continue;
-							}
-						}
-					}
-
-					range = ranges[ i ];
-
-					var nativeRange = this.document.$.createRange();
-					var startContainer = range.startContainer;
-
-					// In Opera, we have some cases when a collapsed text selection cursor will be moved out of the
-					// anchor node:
-					// 1. Inside of any empty inline. (#4657)
-					// 2. In adjacent to any inline element.
-					if ( CKEDITOR.env.opera && range.collapsed && startContainer.type == CKEDITOR.NODE_ELEMENT ) {
-
-						var leftSib = startContainer.getChild( range.startOffset - 1 ),
-							rightSib = startContainer.getChild( range.startOffset );
-
-						if ( !leftSib && !rightSib && startContainer.is( CKEDITOR.dtd.$removeEmpty ) ||
-								 leftSib && leftSib.type == CKEDITOR.NODE_ELEMENT ||
-								 rightSib && rightSib.type == CKEDITOR.NODE_ELEMENT ) {
-							range.insertNode( this.document.createText( '' ) );
-							range.collapse( 1 );
-						}
-					}
-
-					if ( range.collapsed && CKEDITOR.env.webkit && rangeRequiresFix( range ) ) {
-						// Append a zero-width space so WebKit will not try to
-						// move the selection by itself (#1272).
-						var fillingChar = createFillingChar( this.root );
-						range.insertNode( fillingChar );
-
-						next = fillingChar.getNext();
-
-						// If the filling char is followed by a <br>, whithout
-						// having something before it, it'll not blink.
-						// Let's remove it in this case.
-						if ( next && !fillingChar.getPrevious() && next.type == CKEDITOR.NODE_ELEMENT && next.getName() == 'br' ) {
-							removeFillingChar( this.root );
-							range.moveToPosition( next, CKEDITOR.POSITION_BEFORE_START );
-						} else
-							range.moveToPosition( fillingChar, CKEDITOR.POSITION_AFTER_END );
-					}
-
-					nativeRange.setStart( range.startContainer.$, range.startOffset );
-
-					try {
-						nativeRange.setEnd( range.endContainer.$, range.endOffset );
-					} catch ( e ) {
-						// There is a bug in Firefox implementation (it would be too easy
-						// otherwise). The new start can't be after the end (W3C says it can).
-						// So, let's create a new range and collapse it to the desired point.
-						if ( e.toString().indexOf( 'NS_ERROR_ILLEGAL_VALUE' ) >= 0 ) {
-							range.collapse( 1 );
-							nativeRange.setEnd( range.endContainer.$, range.endOffset );
-						} else
-							throw e;
-					}
-
-					// Select the range.
-					sel.addRange( nativeRange );
-				}
-			}
-
-			this.reset();
-
-			// Fakes the IE DOM event "selectionchange" on editable.
-			this.root.fire( 'selectionchange' );
-		},
-
-		/**
-		 * Makes a "fake selection" of an element.
-		 *
-		 * A fake selection does not render UI artifacts over the selected
-		 * element. Additionally, the browser native selection system is not
-		 * aware of the fake selection. In practice, the native selection is
-		 * moved to a hidden place where no native selection UI artifacts are
-		 * displayed to the user.
-		 *
-		 * @param {CKEDITOR.dom.element} element The element to be "selected".
-		 */
-		fake: function( element ) {
-			var editor = this.root.editor;
-
-			// Cleanup after previous selection - e.g. remove hidden sel container.
-			this.reset();
-
-			hideSelection( editor );
-
-			// Set this value after executing hiseSelection, because it may
-			// cause reset() which overwrites cache.
-			var cache = this._.cache;
-
-			// Caches a range than holds the element.
-			var range = new CKEDITOR.dom.range( this.root );
-			range.setStartBefore( element );
-			range.setEndAfter( element );
-			cache.ranges = new CKEDITOR.dom.rangeList( range );
-
-			// Put this element in the cache.
-			cache.selectedElement = cache.startElement = element;
-			cache.type = CKEDITOR.SELECTION_ELEMENT;
-
-			// Properties that will not be available when isFake.
-			cache.selectedText = cache.nativeSel = null;
-
-			this.isFake = 1;
-			this.rev = nextRev++;
-
-			// Save this selection, so it can be returned by editor.getSelection().
-			editor._.fakeSelection = this;
-
-			// Fire selectionchange, just like a normal selection.
-			this.root.fire( 'selectionchange' );
-		},
-
-		/**
-		 * Checks whether selection is placed in hidden element.
-		 *
-		 * This method is to be used to verify whether fake selection
-		 * (see {@link #fake}) is still hidden.
-		 *
-		 * **Note:** this method should be executed on real selection - e.g.:
-		 *
-		 *		editor.getSelection( true ).isHidden();
-		 *
-		 * @returns {Boolean}
-		 */
-		isHidden: function() {
-			var el = this.getCommonAncestor();
-
-			if ( el && el.type == CKEDITOR.NODE_TEXT )
-				el = el.getParent();
-
-			return !!( el && el.data( 'cke-hidden-sel' ) );
-		},
-
-		/**
-		 * Creates a bookmark for each range of this selection (from {@link #getRanges})
-		 * by calling the {@link CKEDITOR.dom.range#createBookmark} method,
-		 * with extra care taken to avoid interference among those ranges. The arguments
-		 * received are the same as with the underlying range method.
-		 *
-		 *		var bookmarks = editor.getSelection().createBookmarks();
-		 *
-		 * @returns {Array} Array of bookmarks for each range.
-		 */
-		createBookmarks: function( serializable ) {
-			var bookmark = this.getRanges().createBookmarks( serializable );
-			this.isFake && ( bookmark.isFake = 1 );
-			return bookmark;
-		},
-
-		/**
-		 * Creates a bookmark for each range of this selection (from {@link #getRanges})
-		 * by calling the {@link CKEDITOR.dom.range#createBookmark2} method,
-		 * with extra care taken to avoid interference among those ranges. The arguments
-		 * received are the same as with the underlying range method.
-		 *
-		 *		var bookmarks = editor.getSelection().createBookmarks2();
-		 *
-		 * @returns {Array} Array of bookmarks for each range.
-		 */
-		createBookmarks2: function( normalized ) {
-			var bookmark = this.getRanges().createBookmarks2( normalized );
-			this.isFake && ( bookmark.isFake = 1 );
-			return bookmark;
-		},
-
-		/**
-		 * Selects the virtual ranges denoted by the bookmarks by calling {@link #selectRanges}.
-		 *
-		 *		var bookmarks = editor.getSelection().createBookmarks();
-		 *		editor.getSelection().selectBookmarks( bookmarks );
-		 *
-		 * @param {Array} bookmarks The bookmarks representing ranges to be selected.
-		 * @returns {CKEDITOR.dom.selection} This selection object, after the ranges were selected.
-		 */
-		selectBookmarks: function( bookmarks ) {
-			var ranges = [];
-			for ( var i = 0; i < bookmarks.length; i++ ) {
-				var range = new CKEDITOR.dom.range( this.root );
-				range.moveToBookmark( bookmarks[ i ] );
-				ranges.push( range );
-			}
-
-			if ( bookmarks.isFake )
-				this.fake( ranges[ 0 ].getEnclosedNode() );
-			else
-				this.selectRanges( ranges );
-
-			return this;
-		},
-
-		/**
-		 * Retrieves the common ancestor node of the first range and the last range.
-		 *
-		 *		var ancestor = editor.getSelection().getCommonAncestor();
-		 *
-		 * @returns {CKEDITOR.dom.element} The common ancestor of the selection or `null` if selection is empty.
-		 */
-		getCommonAncestor: function() {
-			var ranges = this.getRanges();
-			if ( !ranges.length )
-				return null;
-
-			var startNode = ranges[ 0 ].startContainer,
-				endNode = ranges[ ranges.length - 1 ].endContainer;
-			return startNode.getCommonAncestor( endNode );
-		},
-
-		/**
-		 * Moves the scrollbar to the starting position of the current selection.
-		 *
-		 *		editor.getSelection().scrollIntoView();
-		 */
-		scrollIntoView: function() {
-
-			// Scrolls the first range into view.
-			if ( this.type != CKEDITOR.SELECTION_NONE )
-				this.getRanges()[ 0 ].scrollIntoView();
-		},
-
-		/**
-		 * Remove all the selection ranges from the document.
-		 */
-		removeAllRanges: function() {
-			// Don't clear selection outside this selection's root (#11500).
-			if ( this.getType() == CKEDITOR.SELECTION_NONE )
-				return;
-
-			var nativ = this.getNative();
-
-			try { nativ && nativ[ isMSSelection ? 'empty' : 'removeAllRanges' ](); }
-			catch ( er ) {}
-
-			this.reset();
-		}
-	};
-
-} )();
-
-
-/**
- * Fired when selection inside editor has been changed. Note that this event
- * is fired only when selection's start element (container of a selecion start)
- * changes, not on every possible selection change. Thanks to that `selectionChange`
- * is fired less frequently, but on every context
- * (the {@link CKEDITOR.editor#elementPath elements path} holding selection's start) change.
- *
- * @event selectionChange
- * @member CKEDITOR.editor
- * @param {CKEDITOR.editor} editor This editor instance.
- * @param data
- * @param {CKEDITOR.dom.selection} data.selection
- * @param {CKEDITOR.dom.elementPath} data.path
- */
-
-/**
- * Selection's revision. This value is incremented every time new
- * selection is created or existing one is modified.
- *
- * @since 4.3
- * @readonly
- * @property {Number} rev
- */
-
-/**
- * Document in which selection is anchored.
- *
- * @readonly
- * @property {CKEDITOR.dom.document} document
- */
-
-/**
- * Selection's root element.
- *
- * @readonly
- * @property {CKEDITOR.dom.element} root
- */
-
-/**
- * Whether selection is locked (cannot be modified).
- *
- * See {@link #lock} and {@link #unlock} methods.
- *
- * @readonly
- * @property {Boolean} isLocked
- */
-
-/**
- * Whether selection is a fake selection.
- *
- * See {@link #fake} method.
- *
- * @readonly
- * @property {Boolean} isFake
- */

+ 0 - 335
htdocs/includes/ckeditor/ckeditor/_source/core/skin.js

@@ -1,335 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.skin} class that is used to manage skin parts.
- */
-
-( function() {
-	var cssLoaded = {};
-
-	function getName() {
-		return CKEDITOR.skinName.split( ',' )[ 0 ];
-	}
-
-	function getConfigPath() {
-		return CKEDITOR.getUrl( CKEDITOR.skinName.split( ',' )[ 1 ] || ( 'skins/' + getName() + '/' ) );
-	}
-
-	/**
-	 * Manages the loading of skin parts among all editor instances.
-	 *
-	 * @class
-	 * @singleton
-	 */
-	CKEDITOR.skin = {
-		/**
-		 * Returns the root path to the skin directory.
-		 *
-		 * @method
-		 * @todo
-		 */
-		path: getConfigPath,
-
-		/**
-		 * Loads a skin part into the page. Does nothing if the part has already been loaded.
-		 *
-		 * **Note:** The "editor" part is always auto loaded upon instance creation,
-		 * thus this function is mainly used to **lazy load** other parts of the skin
-		 * that do not have to be displayed until requested.
-		 *
-		 *		// Load the dialog part.
-		 *		editor.skin.loadPart( 'dialog' );
-		 *
-		 * @param {String} part The name of the skin part CSS file that resides in the skin directory.
-		 * @param {Function} fn The provided callback function which is invoked after the part is loaded.
-		 */
-		loadPart: function( part, fn ) {
-			if ( CKEDITOR.skin.name != getName() ) {
-				CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( getConfigPath() + 'skin.js' ), function() {
-					loadCss( part, fn );
-				} );
-			} else
-				loadCss( part, fn );
-		},
-
-		/**
-		 * Retrieves the real URL of a (CSS) skin part.
-		 *
-		 * @param {String} part
-		 */
-		getPath: function( part ) {
-			return CKEDITOR.getUrl( getCssPath( part ) );
-		},
-
-		/**
-		 * The list of registered icons. To add new icons to this list, use {@link #addIcon}.
-		 */
-		icons: {},
-
-		/**
-		 * Registers an icon.
-		 *
-		 * @param {String} name The icon name.
-		 * @param {String} path The path to the icon image file.
-		 * @param {Number} [offset] The vertical offset position of the icon, if
-		 * available inside a strip image.
-		 * @param {String} [bgsize] The value of the CSS "background-size" property to
-		 * use for this icon
-		 */
-		addIcon: function( name, path, offset, bgsize ) {
-			name = name.toLowerCase();
-			if ( !this.icons[ name ] ) {
-				this.icons[ name ] = {
-					path: path,
-					offset: offset || 0,
-					bgsize : bgsize || '16px'
-				};
-			}
-		},
-
-		/**
-		 * Gets the CSS background styles to be used to render a specific icon.
-		 *
-		 * @param {String} name The icon name, as registered with {@link #addIcon}.
-		 * @param {Boolean} [rtl] Indicates that the RTL version of the icon is
-		 * to be used, if available.
-		 * @param {String} [overridePath] The path to the icon image file. It
-		 * overrides the path defined by the named icon, if available, and is
-		 * used if the named icon was not registered.
-		 * @param {Number} [overrideOffset] The vertical offset position of the
-		 * icon. It overrides the offset defined by the named icon, if
-		 * available, and is used if the named icon was not registered.
-		 * @param {String} [overrideBgsize] The value of the CSS "background-size" property
-		 * to use for the icon. It overrides the value defined by the named icon,
-		 * if available, and is used if the named icon was not registered.
-		 */
-		getIconStyle: function( name, rtl, overridePath, overrideOffset, overrideBgsize ) {
-			var icon, path, offset, bgsize;
-
-			if ( name ) {
-				name = name.toLowerCase();
-				// If we're in RTL, try to get the RTL version of the icon.
-				if ( rtl )
-					icon = this.icons[ name + '-rtl' ];
-
-				// If not in LTR or no RTL version available, get the generic one.
-				if ( !icon )
-					icon = this.icons[ name ];
-			}
-
-			path = overridePath || ( icon && icon.path ) || '';
-			offset = overrideOffset || ( icon && icon.offset );
-			bgsize = overrideBgsize || ( icon && icon.bgsize ) || '16px';
-
-			return path &&
-				( 'background-image:url(' + CKEDITOR.getUrl( path ) + ');background-position:0 ' + offset + 'px;background-size:' + bgsize + ';' );
-		}
-	};
-
-	function getCssPath( part ) {
-			// Check for ua-specific version of skin part.
-			var uas = CKEDITOR.skin[ 'ua_' + part ], env = CKEDITOR.env;
-			if ( uas ) {
-
-				// Having versioned UA checked first.
-				uas = uas.split( ',' ).sort( function( a, b ) { return a > b ? -1 : 1; } );
-
-				// Loop through all ua entries, checking is any of them match the current ua.
-				for ( var i = 0, ua; i < uas.length; i++ ) {
-					ua = uas[ i ];
-
-					if ( env.ie ) {
-						if ( ( ua.replace( /^ie/, '' ) == env.version ) || ( env.quirks && ua == 'iequirks' ) )
-							ua = 'ie';
-					}
-
-					if ( env[ ua ] ) {
-						part += '_' + uas[ i ];
-						break;
-					}
-				}
-			}
-			return CKEDITOR.getUrl( getConfigPath() + part + '.css' );
-	}
-
-	function loadCss( part, callback ) {
-		// Avoid reload.
-		if ( !cssLoaded[ part ] ) {
-			CKEDITOR.document.appendStyleSheet( getCssPath( part ) );
-			cssLoaded[ part ] = 1;
-		}
-
-		// CSS loading should not be blocking.
-		callback && callback();
-	}
-
-	CKEDITOR.tools.extend( CKEDITOR.editor.prototype, {
-		/** Gets the color of the editor user interface.
-		 *
-		 *		CKEDITOR.instances.editor1.getUiColor();
-		 *
-		 * @method
-		 * @member CKEDITOR.editor
-		 * @returns {String} uiColor The editor UI color or `undefined` if the UI color is not set.
-		 */
-		getUiColor: function() {
-			return this.uiColor;
-		},
-
-		/** Sets the color of the editor user interface. This method accepts a color value in
-		 * hexadecimal notation, with a `#` character (e.g. #ffffff).
-		 *
-		 * 		CKEDITOR.instances.editor1.setUiColor( '#ff00ff' );
-		 *
-		 * @method
-		 * @member CKEDITOR.editor
-		 * @param {String} color The desired editor UI color in hexadecimal notation.
-		 */
-		setUiColor: function( color ) {
-			var uiStyle = getStylesheet( CKEDITOR.document );
-
-			return ( this.setUiColor = function( color ) {
-				var chameleon = CKEDITOR.skin.chameleon;
-
-				var replace = [ [ uiColorRegexp, color ] ];
-				this.uiColor = color;
-
-				// Update general style.
-				updateStylesheets( [ uiStyle ], chameleon( this, 'editor' ), replace );
-
-				// Update panel styles.
-				updateStylesheets( uiColorMenus, chameleon( this, 'panel' ), replace );
-			} ).call( this, color );
-		}
-	} );
-
-	var uiColorStylesheetId = 'cke_ui_color',
-		uiColorMenus = [],
-		uiColorRegexp = /\$color/g;
-
-	function getStylesheet( document ) {
-		var node = document.getById( uiColorStylesheetId );
-		if ( !node ) {
-			node = document.getHead().append( 'style' );
-			node.setAttribute( "id", uiColorStylesheetId );
-			node.setAttribute( "type", "text/css" );
-		}
-		return node;
-	}
-
-	function updateStylesheets( styleNodes, styleContent, replace ) {
-		var r, i, content;
-
-		// We have to split CSS declarations for webkit.
-		if ( CKEDITOR.env.webkit ) {
-			styleContent = styleContent.split( '}' ).slice( 0, -1 );
-			for ( i = 0; i < styleContent.length; i++ )
-				styleContent[ i ] = styleContent[ i ].split( '{' );
-		}
-
-		for ( var id = 0; id < styleNodes.length; id++ ) {
-			if ( CKEDITOR.env.webkit ) {
-				for ( i = 0; i < styleContent.length; i++ ) {
-					content = styleContent[ i ][ 1 ];
-					for ( r = 0; r < replace.length; r++ )
-						content = content.replace( replace[ r ][ 0 ], replace[ r ][ 1 ] );
-
-					styleNodes[ id ].$.sheet.addRule( styleContent[ i ][ 0 ], content );
-				}
-			} else {
-				content = styleContent;
-				for ( r = 0; r < replace.length; r++ )
-					content = content.replace( replace[ r ][ 0 ], replace[ r ][ 1 ] );
-
-				if ( CKEDITOR.env.ie && CKEDITOR.env.version < 11 )
-					styleNodes[ id ].$.styleSheet.cssText += content;
-				else
-					styleNodes[ id ].$.innerHTML += content;
-			}
-		}
-	}
-
-	CKEDITOR.on( 'instanceLoaded', function( evt ) {
-		// The chameleon feature is not for IE quirks.
-		if ( CKEDITOR.env.ie && CKEDITOR.env.quirks )
-			return;
-
-		var editor = evt.editor,
-			showCallback = function( event ) {
-				var panel = event.data[ 0 ] || event.data;
-				var iframe = panel.element.getElementsByTag( 'iframe' ).getItem( 0 ).getFrameDocument();
-
-				// Add stylesheet if missing.
-				if ( !iframe.getById( 'cke_ui_color' ) ) {
-					var node = getStylesheet( iframe );
-					uiColorMenus.push( node );
-
-					var color = editor.getUiColor();
-					// Set uiColor for new panel.
-					if ( color )
-						updateStylesheets( [ node ], CKEDITOR.skin.chameleon( editor, 'panel' ), [ [ uiColorRegexp, color ] ] );
-
-				}
-			};
-
-		editor.on( 'panelShow', showCallback );
-		editor.on( 'menuShow', showCallback );
-
-		// Apply UI color if specified in config.
-		if ( editor.config.uiColor )
-			editor.setUiColor( editor.config.uiColor );
-	} );
-} )();
-
-/**
- * The list of file names matching the browser user agent string from
- * {@link CKEDITOR.env}. This is used to load the skin part file in addition
- * to the "main" skin file for a particular browser.
- *
- * **Note:** For each of the defined skin parts the corresponding
- * CSS file with the same name as the user agent must exist inside
- * the skin directory.
- *
- * @property ua
- * @todo type?
- */
-
-/**
- * The name of the skin that is currently used.
- *
- * @property {String} name
- * @todo
- */
-
-/**
- * The editor skin name. Note that it is not possible to have editors with
- * different skin settings in the same page. In such case just one of the
- * skins will be used for all editors.
- *
- * This is a shortcut to {@link CKEDITOR#skinName}.
- *
- * It is possible to install skins outside the default `skin` folder in the
- * editor installation. In that case, the absolute URL path to that folder
- * should be provided, separated by a comma (`'skin_name,skin_path'`).
- *
- *		config.skin = 'moono';
- *
- *		config.skin = 'myskin,/customstuff/myskin/';
- *
- * @cfg {String} skin
- * @member CKEDITOR.config
- */
-
-/**
- * A function that supports the chameleon (skin color switch) feature, providing
- * the skin color style updates to be applied in runtime.
- *
- * **Note:** The embedded `$color` variable is to be substituted with a specific UI color.
- *
- * @method chameleon
- * @param {String} editor The editor instance that the color changes apply to.
- * @param {String} part The name of the skin part where the color changes take place.
- */

+ 0 - 1714
htdocs/includes/ckeditor/ckeditor/_source/core/style.js

@@ -1,1714 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-'use strict';
-
-/**
- * Registers a function to be called whenever the selection position changes in the
- * editing area. The current state is passed to the function. The possible
- * states are {@link CKEDITOR#TRISTATE_ON} and {@link CKEDITOR#TRISTATE_OFF}.
- *
- *		// Create a style object for the <b> element.
- *		var style = new CKEDITOR.style( { element: 'b' } );
- *		var editor = CKEDITOR.instances.editor1;
- *		editor.attachStyleStateChange( style, function( state ) {
- *			if ( state == CKEDITOR.TRISTATE_ON )
- *				alert( 'The current state for the B element is ON' );
- *			else
- *				alert( 'The current state for the B element is OFF' );
- *		} );
- *
- * @member CKEDITOR.editor
- * @param {CKEDITOR.style} style The style to be watched.
- * @param {Function} callback The function to be called.
- */
-CKEDITOR.editor.prototype.attachStyleStateChange = function( style, callback ) {
-	// Try to get the list of attached callbacks.
-	var styleStateChangeCallbacks = this._.styleStateChangeCallbacks;
-
-	// If it doesn't exist, it means this is the first call. So, let's create
-	// all the structure to manage the style checks and the callback calls.
-	if ( !styleStateChangeCallbacks ) {
-		// Create the callbacks array.
-		styleStateChangeCallbacks = this._.styleStateChangeCallbacks = [];
-
-		// Attach to the selectionChange event, so we can check the styles at
-		// that point.
-		this.on( 'selectionChange', function( ev ) {
-			// Loop throw all registered callbacks.
-			for ( var i = 0; i < styleStateChangeCallbacks.length; i++ ) {
-				var callback = styleStateChangeCallbacks[ i ];
-
-				// Check the current state for the style defined for that callback.
-				var currentState = callback.style.checkActive( ev.data.path ) ?
-					CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
-
-				// Call the callback function, passing the current state to it.
-				callback.fn.call( this, currentState );
-			}
-		} );
-	}
-
-	// Save the callback info, so it can be checked on the next occurrence of
-	// selectionChange.
-	styleStateChangeCallbacks.push( { style: style, fn: callback } );
-};
-
-CKEDITOR.STYLE_BLOCK = 1;
-CKEDITOR.STYLE_INLINE = 2;
-CKEDITOR.STYLE_OBJECT = 3;
-
-( function() {
-	var blockElements = { address: 1, div: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, p: 1,
-			pre: 1, section: 1, header: 1, footer: 1, nav: 1, article: 1, aside: 1, figure: 1,
-			dialog: 1, hgroup: 1, time: 1, meter: 1, menu: 1, command: 1, keygen: 1, output: 1,
-			progress: 1, details: 1, datagrid: 1, datalist: 1 },
-
-		objectElements = { a: 1, embed: 1, hr: 1, img: 1, li: 1, object: 1, ol: 1, table: 1, td: 1,
-			tr: 1, th: 1, ul: 1, dl: 1, dt: 1, dd: 1, form: 1, audio: 1, video: 1 };
-
-	var semicolonFixRegex = /\s*(?:;\s*|$)/,
-		varRegex = /#\((.+?)\)/g;
-
-	var notBookmark = CKEDITOR.dom.walker.bookmark( 0, 1 ),
-		nonWhitespaces = CKEDITOR.dom.walker.whitespaces( 1 );
-
-	/**
-	 * TODO...
-	 *
-	 * @class
-	 * @constructor Creates a style class instance.
-	 * @param styleDefinition
-	 * @param variablesValues
-	 * @todo
-	 */
-	CKEDITOR.style = function( styleDefinition, variablesValues ) {
-
-		// Inline style text as attribute should be converted
-		// to styles object.
-		var attrs = styleDefinition.attributes;
-		if ( attrs && attrs.style ) {
-			styleDefinition.styles = CKEDITOR.tools.extend( {},
-				styleDefinition.styles, CKEDITOR.tools.parseCssText( attrs.style ) );
-			delete attrs.style;
-		}
-
-		if ( variablesValues ) {
-			styleDefinition = CKEDITOR.tools.clone( styleDefinition );
-
-			replaceVariables( styleDefinition.attributes, variablesValues );
-			replaceVariables( styleDefinition.styles, variablesValues );
-		}
-
-		var element = this.element = styleDefinition.element ?
-			(
-				typeof styleDefinition.element == 'string' ?
-					styleDefinition.element.toLowerCase() : styleDefinition.element
-			) : '*';
-
-		this.type = styleDefinition.type ||
-			(
-				blockElements[ element ] ? CKEDITOR.STYLE_BLOCK :
-				objectElements[ element ] ? CKEDITOR.STYLE_OBJECT :
-				CKEDITOR.STYLE_INLINE
-			);
-
-		// If the 'element' property is an object with a set of possible element, it will be applied like an object style: only to existing elements
-		if ( typeof this.element == 'object' )
-			this.type = CKEDITOR.STYLE_OBJECT;
-
-		this._ = {
-			definition: styleDefinition
-		};
-	};
-
-	/**
-	 * Apply the style upon the editor's current selection.
-	 *
-	 * @member CKEDITOR.editor
-	 * @param {CKEDITOR.style} style
-	 */
-	CKEDITOR.editor.prototype.applyStyle = function( style ) {
-		if ( style.checkApplicable( this.elementPath() ) )
-			applyStyleOnSelection.call( style, this.getSelection() );
-	};
-
-	/**
-	 * Remove the style from the editor's current selection.
-	 *
-	 * @member CKEDITOR.editor
-	 * @param {CKEDITOR.style} style
-	 */
-	CKEDITOR.editor.prototype.removeStyle = function( style ) {
-		if ( style.checkApplicable( this.elementPath() ) )
-			applyStyleOnSelection.call( style, this.getSelection(), 1 );
-	};
-
-	CKEDITOR.style.prototype = {
-		/**
-		 * @param {CKEDITOR.dom.document} document
-		 * @todo
-		 */
-		apply: function( document ) {
-			applyStyleOnSelection.call( this, document.getSelection() );
-		},
-
-		/**
-		 * @param {CKEDITOR.dom.document} document
-		 * @todo
-		 */
-		remove: function( document ) {
-			applyStyleOnSelection.call( this, document.getSelection(), 1 );
-		},
-
-		/**
-		 * @param {CKEDITOR.dom.range} range
-		 * @todo
-		 */
-		applyToRange: function( range ) {
-			return ( this.applyToRange =
-			         this.type == CKEDITOR.STYLE_INLINE ? applyInlineStyle :
-			         this.type == CKEDITOR.STYLE_BLOCK ? applyBlockStyle :
-			         this.type == CKEDITOR.STYLE_OBJECT ? applyObjectStyle :
-			         null ).call( this, range );
-		},
-
-		/**
-		 * @param {CKEDITOR.dom.range} range
-		 * @todo
-		 */
-		removeFromRange: function( range ) {
-			return ( this.removeFromRange =
-			         this.type == CKEDITOR.STYLE_INLINE ? removeInlineStyle :
-			         this.type == CKEDITOR.STYLE_BLOCK ? removeBlockStyle :
-			         this.type == CKEDITOR.STYLE_OBJECT ? removeObjectStyle :
-			         null ).call( this, range );
-		},
-
-		/**
-		 * @param {CKEDITOR.dom.element} element
-		 * @todo
-		 */
-		applyToObject: function( element ) {
-			setupElement( element, this );
-		},
-
-		/**
-		 * Get the style state inside an element path.
-		 *
-		 * @param {CKEDITOR.dom.elementPath} elementPath
-		 * @returns {Boolean} `true` if the element is active in the path.
-		 */
-		checkActive: function( elementPath ) {
-			switch ( this.type ) {
-				case CKEDITOR.STYLE_BLOCK:
-					return this.checkElementRemovable( elementPath.block || elementPath.blockLimit, true );
-
-				case CKEDITOR.STYLE_OBJECT:
-				case CKEDITOR.STYLE_INLINE:
-
-					var elements = elementPath.elements;
-
-					for ( var i = 0, element; i < elements.length; i++ ) {
-						element = elements[ i ];
-
-						if ( this.type == CKEDITOR.STYLE_INLINE && ( element == elementPath.block || element == elementPath.blockLimit ) )
-							continue;
-
-						if ( this.type == CKEDITOR.STYLE_OBJECT ) {
-							var name = element.getName();
-							if ( !( typeof this.element == 'string' ? name == this.element : name in this.element ) )
-								continue;
-						}
-
-						if ( this.checkElementRemovable( element, true ) )
-							return true;
-					}
-			}
-			return false;
-		},
-
-		/**
-		 * Whether this style can be applied at the specified elements-path.
-		 *
-		 * @param {CKEDITOR.dom.elementPath} elementPath The elements-path to
-		 * 	check the style against.
-		 * @param {CKEDITOR.filter} [filter] If defined, the style will be
-		 * 	checked against this filter as well.
-		 * @returns {Boolean} `true` if this style can be applied at the element path.
-		 */
-		checkApplicable: function( elementPath, filter ) {
-			if ( filter && !filter.check( this ) )
-				return false;
-
-			switch ( this.type ) {
-				case CKEDITOR.STYLE_OBJECT:
-					return !!elementPath.contains( this.element );
-				case CKEDITOR.STYLE_BLOCK:
-					return !!elementPath.blockLimit.getDtd()[ this.element ];
-			}
-
-			return true;
-		},
-
-		/**
-		 * Check if the element matches the current style definition.
-		 *
-		 * @param {CKEDITOR.dom.element} element
-		 * @param {Boolean} fullMatch
-		 * @returns {Boolean}
-		 * @todo
-		 */
-		checkElementMatch: function( element, fullMatch ) {
-			var def = this._.definition;
-
-			if ( !element || !def.ignoreReadonly && element.isReadOnly() )
-				return false;
-
-			var attribs,
-				name = element.getName();
-
-			// If the element name is the same as the style name.
-			if ( typeof this.element == 'string' ? name == this.element : name in this.element ) {
-				// If no attributes are defined in the element.
-				if ( !fullMatch && !element.hasAttributes() )
-					return true;
-
-				attribs = getAttributesForComparison( def );
-
-				if ( attribs._length ) {
-					for ( var attName in attribs ) {
-						if ( attName == '_length' )
-							continue;
-
-						var elementAttr = element.getAttribute( attName ) || '';
-
-						// Special treatment for 'style' attribute is required.
-						if ( attName == 'style' ? compareCssText( attribs[ attName ], elementAttr ) : attribs[ attName ] == elementAttr ) {
-							if ( !fullMatch )
-								return true;
-						} else if ( fullMatch )
-							return false;
-					}
-					if ( fullMatch )
-						return true;
-				} else
-					return true;
-			}
-
-			return false;
-		},
-
-		/**
-		 * Checks if an element, or any of its attributes, is removable by the
-		 * current style definition.
-		 *
-		 * @param {CKEDITOR.dom.element} element
-		 * @param {Boolean} fullMatch
-		 * @returns {Boolean}
-		 * @todo
-		 */
-		checkElementRemovable: function( element, fullMatch ) {
-			// Check element matches the style itself.
-			if ( this.checkElementMatch( element, fullMatch ) )
-				return true;
-
-			// Check if the element matches the style overrides.
-			var override = getOverrides( this )[ element.getName() ];
-			if ( override ) {
-				var attribs, attName;
-
-				// If no attributes have been defined, remove the element.
-				if ( !( attribs = override.attributes ) )
-					return true;
-
-				for ( var i = 0; i < attribs.length; i++ ) {
-					attName = attribs[ i ][ 0 ];
-					var actualAttrValue = element.getAttribute( attName );
-					if ( actualAttrValue ) {
-						var attValue = attribs[ i ][ 1 ];
-
-						// Remove the attribute if:
-						//    - The override definition value is null;
-						//    - The override definition value is a string that
-						//      matches the attribute value exactly.
-						//    - The override definition value is a regex that
-						//      has matches in the attribute value.
-						if ( attValue === null || ( typeof attValue == 'string' && actualAttrValue == attValue ) || attValue.test( actualAttrValue ) )
-							return true;
-					}
-				}
-			}
-			return false;
-		},
-
-		/**
-		 * Builds the preview HTML based on the styles definition.
-		 *
-		 * @param label
-		 * @todo
-		 */
-		buildPreview: function( label ) {
-			var styleDefinition = this._.definition,
-				html = [],
-				elementName = styleDefinition.element;
-
-			// Avoid <bdo> in the preview.
-			if ( elementName == 'bdo' )
-				elementName = 'span';
-
-			html = [ '<', elementName ];
-
-			// Assign all defined attributes.
-			var attribs = styleDefinition.attributes;
-			if ( attribs ) {
-				for ( var att in attribs )
-					html.push( ' ', att, '="', attribs[ att ], '"' );
-			}
-
-			// Assign the style attribute.
-			var cssStyle = CKEDITOR.style.getStyleText( styleDefinition );
-			if ( cssStyle )
-				html.push( ' style="', cssStyle, '"' );
-
-			html.push( '>', ( label || styleDefinition.name ), '</', elementName, '>' );
-
-			return html.join( '' );
-		},
-
-		getDefinition: function() {
-			return this._.definition;
-		}
-	};
-
-	/**
-	 * Build the cssText based on the styles definition.
-	 *
-	 * @static
-	 * @param styleDefinition
-	 * @returns {String}
-	 * @todo
-	 */
-	CKEDITOR.style.getStyleText = function( styleDefinition ) {
-		// If we have already computed it, just return it.
-		var stylesDef = styleDefinition._ST;
-		if ( stylesDef )
-			return stylesDef;
-
-		stylesDef = styleDefinition.styles;
-
-		// Builds the StyleText.
-		var stylesText = ( styleDefinition.attributes && styleDefinition.attributes[ 'style' ] ) || '',
-			specialStylesText = '';
-
-		if ( stylesText.length )
-			stylesText = stylesText.replace( semicolonFixRegex, ';' );
-
-		for ( var style in stylesDef ) {
-			var styleVal = stylesDef[ style ],
-				text = ( style + ':' + styleVal ).replace( semicolonFixRegex, ';' );
-
-			// Some browsers don't support 'inherit' property value, leave them intact. (#5242)
-			if ( styleVal == 'inherit' )
-				specialStylesText += text;
-			else
-				stylesText += text;
-		}
-
-		// Browsers make some changes to the style when applying them. So, here
-		// we normalize it to the browser format.
-		if ( stylesText.length )
-			stylesText = CKEDITOR.tools.normalizeCssText( stylesText, true );
-
-		stylesText += specialStylesText;
-
-		// Return it, saving it to the next request.
-		return ( styleDefinition._ST = stylesText );
-	};
-
-	// Gets the parent element which blocks the styling for an element. This
-	// can be done through read-only elements (contenteditable=false) or
-	// elements with the "data-nostyle" attribute.
-	function getUnstylableParent( element, root ) {
-		var unstylable, editable;
-
-		while ( ( element = element.getParent() ) ) {
-			if ( element.equals( root ) )
-				break;
-
-			if ( element.getAttribute( 'data-nostyle' ) )
-				unstylable = element;
-			else if ( !editable ) {
-				var contentEditable = element.getAttribute( 'contentEditable' );
-
-				if ( contentEditable == 'false' )
-					unstylable = element;
-				else if ( contentEditable == 'true' )
-					editable = 1;
-			}
-		}
-
-		return unstylable;
-	}
-
-	var posPrecedingIdenticalContained =
-			CKEDITOR.POSITION_PRECEDING | CKEDITOR.POSITION_IDENTICAL | CKEDITOR.POSITION_IS_CONTAINED,
-		posFollowingIdenticalContained =
-			CKEDITOR.POSITION_FOLLOWING | CKEDITOR.POSITION_IDENTICAL | CKEDITOR.POSITION_IS_CONTAINED;
-
-	// Checks if the current node can be a child of the style element.
-	function checkIfNodeCanBeChildOfStyle( def, currentNode, lastNode, nodeName, dtd, nodeIsNoStyle, nodeIsReadonly, includeReadonly ) {
-		// Style can be applied to text node.
-		if ( !nodeName )
-			return 1;
-
-		// Style definitely cannot be applied if DTD or data-nostyle do not allow.
-		if ( !dtd[ nodeName ] || nodeIsNoStyle  )
-			return 0;
-
-		// Non-editable element cannot be styled is we shouldn't include readonly elements.
-		if ( nodeIsReadonly && !includeReadonly  )
-			return 0;
-
-		// Check that we haven't passed lastNode yet and that style's childRule allows this style on current element.
-		return checkPositionAndRule( currentNode, lastNode, def, posPrecedingIdenticalContained );
-	}
-
-	// Check if the style element can be a child of the current
-	// node parent or if the element is not defined in the DTD.
-	function checkIfStyleCanBeChildOf( def, currentParent, elementName, isUnknownElement ) {
-		return currentParent &&
-			( ( currentParent.getDtd() || CKEDITOR.dtd.span )[ elementName ] || isUnknownElement ) &&
-			( !def.parentRule || def.parentRule( currentParent ) );
-	}
-
-	function checkIfStartsRange( nodeName, currentNode, lastNode ) {
-		return (
-			!nodeName || !CKEDITOR.dtd.$removeEmpty[ nodeName ] ||
-			( currentNode.getPosition( lastNode ) | posPrecedingIdenticalContained ) == posPrecedingIdenticalContained
-		);
-	}
-
-	function checkIfTextOrReadonlyOrEmptyElement( currentNode, nodeIsReadonly ) {
-		var nodeType = currentNode.type;
-		return nodeType == CKEDITOR.NODE_TEXT || nodeIsReadonly || ( nodeType == CKEDITOR.NODE_ELEMENT && !currentNode.getChildCount() );
-	}
-
-	// Checks if position is a subset of posBitFlags and that nodeA fulfills style def rule.
-	function checkPositionAndRule( nodeA, nodeB, def, posBitFlags ) {
-		return ( nodeA.getPosition( nodeB ) | posBitFlags ) == posBitFlags &&
-			( !def.childRule || def.childRule( nodeA ) );
-	}
-
-	function applyInlineStyle( range ) {
-		var document = range.document;
-
-		if ( range.collapsed ) {
-			// Create the element to be inserted in the DOM.
-			var collapsedElement = getElement( this, document );
-
-			// Insert the empty element into the DOM at the range position.
-			range.insertNode( collapsedElement );
-
-			// Place the selection right inside the empty element.
-			range.moveToPosition( collapsedElement, CKEDITOR.POSITION_BEFORE_END );
-
-			return;
-		}
-
-		var elementName = this.element,
-			def = this._.definition,
-			isUnknownElement;
-
-		// Indicates that fully selected read-only elements are to be included in the styling range.
-		var ignoreReadonly = def.ignoreReadonly,
-			includeReadonly = ignoreReadonly || def.includeReadonly;
-
-		// If the read-only inclusion is not available in the definition, try
-		// to get it from the root data (most often it's the editable).
-		if ( includeReadonly == undefined )
-			includeReadonly = range.root.getCustomData( 'cke_includeReadonly' );
-
-		// Get the DTD definition for the element. Defaults to "span".
-		var dtd = CKEDITOR.dtd[ elementName ];
-		if ( !dtd ) {
-			isUnknownElement = true;
-			dtd = CKEDITOR.dtd.span;
-		}
-
-		// Expand the range.
-		range.enlarge( CKEDITOR.ENLARGE_INLINE, 1 );
-		range.trim();
-
-		// Get the first node to be processed and the last, which concludes the processing.
-		var boundaryNodes = range.createBookmark(),
-			firstNode = boundaryNodes.startNode,
-			lastNode = boundaryNodes.endNode,
-			currentNode = firstNode,
-			styleRange;
-
-		if ( !ignoreReadonly ) {
-			// Check if the boundaries are inside non stylable elements.
-			var root = range.getCommonAncestor(),
-				firstUnstylable = getUnstylableParent( firstNode, root ),
-				lastUnstylable = getUnstylableParent( lastNode, root );
-
-			// If the first element can't be styled, we'll start processing right
-			// after its unstylable root.
-			if ( firstUnstylable )
-				currentNode = firstUnstylable.getNextSourceNode( true );
-
-			// If the last element can't be styled, we'll stop processing on its
-			// unstylable root.
-			if ( lastUnstylable )
-				lastNode = lastUnstylable;
-		}
-
-		// Do nothing if the current node now follows the last node to be processed.
-		if ( currentNode.getPosition( lastNode ) == CKEDITOR.POSITION_FOLLOWING )
-			currentNode = 0;
-
-		while ( currentNode ) {
-			var applyStyle = false;
-
-			if ( currentNode.equals( lastNode ) ) {
-				currentNode = null;
-				applyStyle = true;
-			} else {
-				var nodeName = currentNode.type == CKEDITOR.NODE_ELEMENT ? currentNode.getName() : null,
-					nodeIsReadonly = nodeName && ( currentNode.getAttribute( 'contentEditable' ) == 'false' ),
-					nodeIsNoStyle = nodeName && currentNode.getAttribute( 'data-nostyle' );
-
-				// Skip bookmarks.
-				if ( nodeName && currentNode.data( 'cke-bookmark' ) ) {
-					currentNode = currentNode.getNextSourceNode( true );
-					continue;
-				}
-
-				// Find all nested editables of a non-editable block and apply this style inside them.
-				if ( nodeIsReadonly && includeReadonly && CKEDITOR.dtd.$block[ nodeName ] )
-					applyStyleOnNestedEditables.call( this, currentNode );
-
-				// Check if the current node can be a child of the style element.
-				if ( checkIfNodeCanBeChildOfStyle( def, currentNode, lastNode, nodeName, dtd, nodeIsNoStyle, nodeIsReadonly, includeReadonly ) ) {
-					var currentParent = currentNode.getParent();
-
-					// Check if the style element can be a child of the current
-					// node parent or if the element is not defined in the DTD.
-					if ( checkIfStyleCanBeChildOf( def, currentParent, elementName, isUnknownElement ) ) {
-						// This node will be part of our range, so if it has not
-						// been started, place its start right before the node.
-						// In the case of an element node, it will be included
-						// only if it is entirely inside the range.
-						if ( !styleRange && checkIfStartsRange( nodeName, currentNode, lastNode ) ) {
-							styleRange = range.clone();
-							styleRange.setStartBefore( currentNode );
-						}
-
-						// Non element nodes, readonly elements, or empty
-						// elements can be added completely to the range.
-						if ( checkIfTextOrReadonlyOrEmptyElement( currentNode, nodeIsReadonly ) ) {
-							var includedNode = currentNode;
-							var parentNode;
-
-							// This node is about to be included completelly, but,
-							// if this is the last node in its parent, we must also
-							// check if the parent itself can be added completelly
-							// to the range, otherwise apply the style immediately.
-							while (
-								( applyStyle = !includedNode.getNext( notBookmark ) ) &&
-								( parentNode = includedNode.getParent(), dtd[ parentNode.getName() ] ) &&
-								checkPositionAndRule( parentNode, firstNode, def, posFollowingIdenticalContained )
-							) {
-								includedNode = parentNode;
-							}
-
-							styleRange.setEndAfter( includedNode );
-
-						}
-					} else
-						applyStyle = true;
-				}
-				// Style isn't applicable to current element, so apply style to
-				// range ending at previously chosen position, or nowhere if we haven't
-				// yet started styleRange.
-				else
-					applyStyle = true;
-
-				// Get the next node to be processed.
-				// If we're currently on a non-editable element or non-styleable element,
-				// then we'll be moved to current node's sibling (or even further), so we'll
-				// avoid messing up its content.
-				currentNode = currentNode.getNextSourceNode( nodeIsNoStyle || nodeIsReadonly );
-			}
-
-			// Apply the style if we have something to which apply it.
-			if ( applyStyle && styleRange && !styleRange.collapsed ) {
-				// Build the style element, based on the style object definition.
-				var styleNode = getElement( this, document ),
-					styleHasAttrs = styleNode.hasAttributes();
-
-				// Get the element that holds the entire range.
-				var parent = styleRange.getCommonAncestor();
-
-				var removeList = {
-					styles: {},
-					attrs: {},
-					// Styles cannot be removed.
-					blockedStyles: {},
-					// Attrs cannot be removed.
-					blockedAttrs: {}
-				};
-
-				var attName, styleName, value;
-
-				// Loop through the parents, removing the redundant attributes
-				// from the element to be applied.
-				while ( styleNode && parent ) {
-					if ( parent.getName() == elementName ) {
-						for ( attName in def.attributes ) {
-							if ( removeList.blockedAttrs[ attName ] || !( value = parent.getAttribute( styleName ) ) )
-								continue;
-
-							if ( styleNode.getAttribute( attName ) == value )
-								removeList.attrs[ attName ] = 1;
-							else
-								removeList.blockedAttrs[ attName ] = 1;
-						}
-
-						for ( styleName in def.styles ) {
-							if ( removeList.blockedStyles[ styleName ] || !( value = parent.getStyle( styleName ) ) )
-								continue;
-
-							if ( styleNode.getStyle( styleName ) == value )
-								removeList.styles[ styleName ] = 1;
-							else
-								removeList.blockedStyles[ styleName ] = 1;
-						}
-					}
-
-					parent = parent.getParent();
-				}
-
-				for ( attName in removeList.attrs )
-					styleNode.removeAttribute( attName );
-
-				for ( styleName in removeList.styles )
-					styleNode.removeStyle( styleName );
-
-				if ( styleHasAttrs && !styleNode.hasAttributes() )
-					styleNode = null;
-
-				if ( styleNode ) {
-					// Move the contents of the range to the style element.
-					styleRange.extractContents().appendTo( styleNode );
-
-					// Insert it into the range position (it is collapsed after
-					// extractContents.
-					styleRange.insertNode( styleNode );
-
-					// Here we do some cleanup, removing all duplicated
-					// elements from the style element.
-					removeFromInsideElement.call( this, styleNode );
-
-					// Let's merge our new style with its neighbors, if possible.
-					styleNode.mergeSiblings();
-
-					// As the style system breaks text nodes constantly, let's normalize
-					// things for performance.
-					// With IE, some paragraphs get broken when calling normalize()
-					// repeatedly. Also, for IE, we must normalize body, not documentElement.
-					// IE is also known for having a "crash effect" with normalize().
-					// We should try to normalize with IE too in some way, somewhere.
-					if ( !CKEDITOR.env.ie )
-						styleNode.$.normalize();
-				}
-				// Style already inherit from parents, left just to clear up any internal overrides. (#5931)
-				else {
-					styleNode = new CKEDITOR.dom.element( 'span' );
-					styleRange.extractContents().appendTo( styleNode );
-					styleRange.insertNode( styleNode );
-					removeFromInsideElement.call( this, styleNode );
-					styleNode.remove( true );
-				}
-
-				// Style applied, let's release the range, so it gets
-				// re-initialization in the next loop.
-				styleRange = null;
-			}
-		}
-
-		// Remove the bookmark nodes.
-		range.moveToBookmark( boundaryNodes );
-
-		// Minimize the result range to exclude empty text nodes. (#5374)
-		range.shrink( CKEDITOR.SHRINK_TEXT );
-
-		// Get inside the remaining element if range.shrink( TEXT ) has failed because of non-editable elements inside.
-		// E.g. range.shrink( TEXT ) will not get inside:
-		// [<b><i contenteditable="false">x</i></b>]
-		// but range.shrink( ELEMENT ) will.
-		range.shrink( CKEDITOR.NODE_ELEMENT, true );
-	}
-
-	function removeInlineStyle( range ) {
-		// Make sure our range has included all "collpased" parent inline nodes so
-		// that our operation logic can be simpler.
-		range.enlarge( CKEDITOR.ENLARGE_INLINE, 1 );
-
-		var bookmark = range.createBookmark(),
-			startNode = bookmark.startNode;
-
-		if ( range.collapsed ) {
-			var startPath = new CKEDITOR.dom.elementPath( startNode.getParent(), range.root ),
-				// The topmost element in elementspatch which we should jump out of.
-				boundaryElement;
-
-
-			for ( var i = 0, element; i < startPath.elements.length && ( element = startPath.elements[ i ] ); i++ ) {
-				// 1. If it's collaped inside text nodes, try to remove the style from the whole element.
-				//
-				// 2. Otherwise if it's collapsed on element boundaries, moving the selection
-				//  outside the styles instead of removing the whole tag,
-				//  also make sure other inner styles were well preserverd.(#3309)
-				if ( element == startPath.block || element == startPath.blockLimit )
-					break;
-
-				if ( this.checkElementRemovable( element ) ) {
-					var isStart;
-
-					if ( range.collapsed && ( range.checkBoundaryOfElement( element, CKEDITOR.END ) || ( isStart = range.checkBoundaryOfElement( element, CKEDITOR.START ) ) ) ) {
-						boundaryElement = element;
-						boundaryElement.match = isStart ? 'start' : 'end';
-					} else {
-						// Before removing the style node, there may be a sibling to the style node
-						// that's exactly the same to the one to be removed. To the user, it makes
-						// no difference that they're separate entities in the DOM tree. So, merge
-						// them before removal.
-						element.mergeSiblings();
-						if ( element.is( this.element ) )
-							removeFromElement.call( this, element );
-						else
-							removeOverrides( element, getOverrides( this )[ element.getName() ] );
-					}
-				}
-			}
-
-			// Re-create the style tree after/before the boundary element,
-			// the replication start from bookmark start node to define the
-			// new range.
-			if ( boundaryElement ) {
-				var clonedElement = startNode;
-				for ( i = 0; ; i++ ) {
-					var newElement = startPath.elements[ i ];
-					if ( newElement.equals( boundaryElement ) )
-						break;
-					// Avoid copying any matched element.
-					else if ( newElement.match )
-						continue;
-					else
-						newElement = newElement.clone();
-					newElement.append( clonedElement );
-					clonedElement = newElement;
-				}
-				clonedElement[ boundaryElement.match == 'start' ? 'insertBefore' : 'insertAfter' ]( boundaryElement );
-			}
-		} else {
-			// Now our range isn't collapsed. Lets walk from the start node to the end
-			// node via DFS and remove the styles one-by-one.
-			var endNode = bookmark.endNode,
-				me = this;
-
-			breakNodes();
-
-			// Now, do the DFS walk.
-			var currentNode = startNode;
-			while ( !currentNode.equals( endNode ) ) {
-				// Need to get the next node first because removeFromElement() can remove
-				// the current node from DOM tree.
-				var nextNode = currentNode.getNextSourceNode();
-				if ( currentNode.type == CKEDITOR.NODE_ELEMENT && this.checkElementRemovable( currentNode ) ) {
-					// Remove style from element or overriding element.
-					if ( currentNode.getName() == this.element )
-						removeFromElement.call( this, currentNode );
-					else
-						removeOverrides( currentNode, getOverrides( this )[ currentNode.getName() ] );
-
-					// removeFromElement() may have merged the next node with something before
-					// the startNode via mergeSiblings(). In that case, the nextNode would
-					// contain startNode and we'll have to call breakNodes() again and also
-					// reassign the nextNode to something after startNode.
-					if ( nextNode.type == CKEDITOR.NODE_ELEMENT && nextNode.contains( startNode ) ) {
-						breakNodes();
-						nextNode = startNode.getNext();
-					}
-				}
-				currentNode = nextNode;
-			}
-		}
-
-		range.moveToBookmark( bookmark );
-		// See the comment for range.shrink in applyInlineStyle.
-		range.shrink( CKEDITOR.NODE_ELEMENT, true );
-
-		// Find out the style ancestor that needs to be broken down at startNode
-		// and endNode.
-		function breakNodes() {
-			var startPath = new CKEDITOR.dom.elementPath( startNode.getParent() ),
-				endPath = new CKEDITOR.dom.elementPath( endNode.getParent() ),
-				breakStart = null,
-				breakEnd = null;
-
-			for ( var i = 0; i < startPath.elements.length; i++ ) {
-				var element = startPath.elements[ i ];
-
-				if ( element == startPath.block || element == startPath.blockLimit )
-					break;
-
-				if ( me.checkElementRemovable( element ) )
-					breakStart = element;
-			}
-
-			for ( i = 0; i < endPath.elements.length; i++ ) {
-				element = endPath.elements[ i ];
-
-				if ( element == endPath.block || element == endPath.blockLimit )
-					break;
-
-				if ( me.checkElementRemovable( element ) )
-					breakEnd = element;
-			}
-
-			if ( breakEnd )
-				endNode.breakParent( breakEnd );
-			if ( breakStart )
-				startNode.breakParent( breakStart );
-		}
-	}
-
-	// Apply style to nested editables inside editablesContainer.
-	// @param {CKEDITOR.dom.element} editablesContainer
-	// @context CKEDITOR.style
-	function applyStyleOnNestedEditables( editablesContainer ) {
-		var editables = findNestedEditables( editablesContainer ),
-			editable,
-			l = editables.length,
-			i = 0,
-			range = l && new CKEDITOR.dom.range( editablesContainer.getDocument() );
-
-		for ( ; i < l; ++i ) {
-			editable = editables[ i ];
-			// Check if style is allowed by this editable's ACF.
-			if ( checkIfAllowedInEditable( editable, this ) ) {
-				range.selectNodeContents( editable );
-				applyInlineStyle.call( this, range );
-			}
-		}
-	}
-
-	// Finds nested editables within container. Does not return
-	// editables nested in another editable (twice).
-	function findNestedEditables( container ) {
-		var editables = [];
-
-		container.forEach( function( element ) {
-			if ( element.getAttribute( 'contenteditable' ) == 'true' ) {
-				editables.push( element );
-				return false; // Skip children.
-			}
-		}, CKEDITOR.NODE_ELEMENT, true );
-
-		return editables;
-	}
-
-	// Checks if style is allowed in this editable.
-	function checkIfAllowedInEditable( editable, style ) {
-		var filter = CKEDITOR.filter.instances[ editable.data( 'cke-filter' ) ];
-
-		return filter ? filter.check( style ) : 1;
-	}
-
-	// Checks if style is allowed by iterator's active filter.
-	function checkIfAllowedByIterator( iterator, style ) {
-		return iterator.activeFilter ? iterator.activeFilter.check( style ) : 1;
-	}
-
-	function applyObjectStyle( range ) {
-		// Selected or parent element. (#9651)
-		var start = range.getEnclosedNode() || range.getCommonAncestor( false, true ),
-			element = new CKEDITOR.dom.elementPath( start, range.root ).contains( this.element, 1 );
-
-		element && !element.isReadOnly() && setupElement( element, this );
-	}
-
-	function removeObjectStyle( range ) {
-		var parent = range.getCommonAncestor( true, true ),
-			element = new CKEDITOR.dom.elementPath( parent, range.root ).contains( this.element, 1 );
-
-		if ( !element )
-			return;
-
-		var style = this,
-			def = style._.definition,
-			attributes = def.attributes;
-
-		// Remove all defined attributes.
-		if ( attributes ) {
-			for ( var att in attributes )
-				element.removeAttribute( att, attributes[ att ] );
-		}
-
-		// Assign all defined styles.
-		if ( def.styles ) {
-			for ( var i in def.styles ) {
-				if ( def.styles.hasOwnProperty( i ) )
-					element.removeStyle( i );
-			}
-		}
-	}
-
-	function applyBlockStyle( range ) {
-		// Serializible bookmarks is needed here since
-		// elements may be merged.
-		var bookmark = range.createBookmark( true );
-
-		var iterator = range.createIterator();
-		iterator.enforceRealBlocks = true;
-
-		// make recognize <br /> tag as a separator in ENTER_BR mode (#5121)
-		if ( this._.enterMode )
-			iterator.enlargeBr = ( this._.enterMode != CKEDITOR.ENTER_BR );
-
-		var block,
-			doc = range.document,
-			previousPreBlock,
-			newBlock;
-
-		while ( ( block = iterator.getNextParagraph() ) ) {
-			if ( !block.isReadOnly() && checkIfAllowedByIterator( iterator, this ) ) {
-				newBlock = getElement( this, doc, block );
-				replaceBlock( block, newBlock );
-			}
-		}
-
-		range.moveToBookmark( bookmark );
-	}
-
-	function removeBlockStyle( range ) {
-		// Serializible bookmarks is needed here since
-		// elements may be merged.
-		var bookmark = range.createBookmark( 1 );
-
-		var iterator = range.createIterator();
-		iterator.enforceRealBlocks = true;
-		iterator.enlargeBr = this._.enterMode != CKEDITOR.ENTER_BR;
-
-		var block,
-			newBlock;
-
-		while ( ( block = iterator.getNextParagraph() ) ) {
-			if ( this.checkElementRemovable( block ) ) {
-				// <pre> get special treatment.
-				if ( block.is( 'pre' ) ) {
-					newBlock = this._.enterMode == CKEDITOR.ENTER_BR ? null :
-							range.document.createElement( this._.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' );
-
-					newBlock && block.copyAttributes( newBlock );
-					replaceBlock( block, newBlock );
-				} else
-					removeFromElement.call( this, block );
-			}
-		}
-
-		range.moveToBookmark( bookmark );
-	}
-
-	// Replace the original block with new one, with special treatment
-	// for <pre> blocks to make sure content format is well preserved, and merging/splitting adjacent
-	// when necessary. (#3188)
-	function replaceBlock( block, newBlock ) {
-		// Block is to be removed, create a temp element to
-		// save contents.
-		var removeBlock = !newBlock;
-		if ( removeBlock ) {
-			newBlock = block.getDocument().createElement( 'div' );
-			block.copyAttributes( newBlock );
-		}
-
-		var newBlockIsPre = newBlock && newBlock.is( 'pre' ),
-			blockIsPre = block.is( 'pre' ),
-			isToPre = newBlockIsPre && !blockIsPre,
-			isFromPre = !newBlockIsPre && blockIsPre;
-
-		if ( isToPre )
-			newBlock = toPre( block, newBlock );
-		else if ( isFromPre )
-			// Split big <pre> into pieces before start to convert.
-			newBlock = fromPres( removeBlock ? [ block.getHtml() ] : splitIntoPres( block ), newBlock );
-		else
-			block.moveChildren( newBlock );
-
-		newBlock.replace( block );
-
-		if ( newBlockIsPre ) {
-			// Merge previous <pre> blocks.
-			mergePre( newBlock );
-		} else if ( removeBlock )
-			removeNoAttribsElement( newBlock );
-	}
-
-	// Merge a <pre> block with a previous sibling if available.
-	function mergePre( preBlock ) {
-		var previousBlock;
-		if ( !( ( previousBlock = preBlock.getPrevious( nonWhitespaces ) ) && previousBlock.type == CKEDITOR.NODE_ELEMENT && previousBlock.is( 'pre' ) ) )
-			return;
-
-		// Merge the previous <pre> block contents into the current <pre>
-		// block.
-		//
-		// Another thing to be careful here is that currentBlock might contain
-		// a '\n' at the beginning, and previousBlock might contain a '\n'
-		// towards the end. These new lines are not normally displayed but they
-		// become visible after merging.
-		var mergedHtml = replace( previousBlock.getHtml(), /\n$/, '' ) + '\n\n' +
-			replace( preBlock.getHtml(), /^\n/, '' );
-
-		// Krugle: IE normalizes innerHTML from <pre>, breaking whitespaces.
-		if ( CKEDITOR.env.ie )
-			preBlock.$.outerHTML = '<pre>' + mergedHtml + '</pre>';
-		else
-			preBlock.setHtml( mergedHtml );
-
-		previousBlock.remove();
-	}
-
-	// Split into multiple <pre> blocks separated by double line-break.
-	function splitIntoPres( preBlock ) {
-		// Exclude the ones at header OR at tail,
-		// and ignore bookmark content between them.
-		var duoBrRegex = /(\S\s*)\n(?:\s|(<span[^>]+data-cke-bookmark.*?\/span>))*\n(?!$)/gi,
-			blockName = preBlock.getName(),
-			pres = [],
-			splitedHtml = replace( preBlock.getOuterHtml(), duoBrRegex, function( match, charBefore, bookmark ) {
-				return charBefore + '</pre>' + bookmark + '<pre>';
-			} );
-
-		splitedHtml.replace( /<pre\b.*?>([\s\S]*?)<\/pre>/gi, function( match, preContent ) {
-			pres.push( preContent );
-		} );
-		return pres;
-	}
-
-	// Wrapper function of String::replace without considering of head/tail bookmarks nodes.
-	function replace( str, regexp, replacement ) {
-		var headBookmark = '',
-			tailBookmark = '';
-
-		str = str.replace( /(^<span[^>]+data-cke-bookmark.*?\/span>)|(<span[^>]+data-cke-bookmark.*?\/span>$)/gi, function( str, m1, m2 ) {
-			m1 && ( headBookmark = m1 );
-			m2 && ( tailBookmark = m2 );
-			return '';
-		} );
-		return headBookmark + str.replace( regexp, replacement ) + tailBookmark;
-	}
-
-	// Converting a list of <pre> into blocks with format well preserved.
-	function fromPres( preHtmls, newBlock ) {
-		var docFrag;
-		if ( preHtmls.length > 1 )
-			docFrag = new CKEDITOR.dom.documentFragment( newBlock.getDocument() );
-
-		for ( var i = 0; i < preHtmls.length; i++ ) {
-			var blockHtml = preHtmls[ i ];
-
-			// 1. Trim the first and last line-breaks immediately after and before <pre>,
-			// they're not visible.
-			blockHtml = blockHtml.replace( /(\r\n|\r)/g, '\n' );
-			blockHtml = replace( blockHtml, /^[ \t]*\n/, '' );
-			blockHtml = replace( blockHtml, /\n$/, '' );
-			// 2. Convert spaces or tabs at the beginning or at the end to &nbsp;
-			blockHtml = replace( blockHtml, /^[ \t]+|[ \t]+$/g, function( match, offset, s ) {
-				if ( match.length == 1 ) // one space, preserve it
-					return '&nbsp;';
-				else if ( !offset ) // beginning of block
-					return CKEDITOR.tools.repeat( '&nbsp;', match.length - 1 ) + ' ';
-				else // end of block
-					return ' ' + CKEDITOR.tools.repeat( '&nbsp;', match.length - 1 );
-			} );
-
-			// 3. Convert \n to <BR>.
-			// 4. Convert contiguous (i.e. non-singular) spaces or tabs to &nbsp;
-			blockHtml = blockHtml.replace( /\n/g, '<br>' );
-			blockHtml = blockHtml.replace( /[ \t]{2,}/g, function( match ) {
-				return CKEDITOR.tools.repeat( '&nbsp;', match.length - 1 ) + ' ';
-			} );
-
-			if ( docFrag ) {
-				var newBlockClone = newBlock.clone();
-				newBlockClone.setHtml( blockHtml );
-				docFrag.append( newBlockClone );
-			} else
-				newBlock.setHtml( blockHtml );
-		}
-
-		return docFrag || newBlock;
-	}
-
-	// Converting from a non-PRE block to a PRE block in formatting operations.
-	function toPre( block, newBlock ) {
-		var bogus = block.getBogus();
-		bogus && bogus.remove();
-
-		// First trim the block content.
-		var preHtml = block.getHtml();
-
-		// 1. Trim head/tail spaces, they're not visible.
-		preHtml = replace( preHtml, /(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, '' );
-		// 2. Delete ANSI whitespaces immediately before and after <BR> because
-		//    they are not visible.
-		preHtml = preHtml.replace( /[ \t\r\n]*(<br[^>]*>)[ \t\r\n]*/gi, '$1' );
-		// 3. Compress other ANSI whitespaces since they're only visible as one
-		//    single space previously.
-		// 4. Convert &nbsp; to spaces since &nbsp; is no longer needed in <PRE>.
-		preHtml = preHtml.replace( /([ \t\n\r]+|&nbsp;)/g, ' ' );
-		// 5. Convert any <BR /> to \n. This must not be done earlier because
-		//    the \n would then get compressed.
-		preHtml = preHtml.replace( /<br\b[^>]*>/gi, '\n' );
-
-		// Krugle: IE normalizes innerHTML to <pre>, breaking whitespaces.
-		if ( CKEDITOR.env.ie ) {
-			var temp = block.getDocument().createElement( 'div' );
-			temp.append( newBlock );
-			newBlock.$.outerHTML = '<pre>' + preHtml + '</pre>';
-			newBlock.copyAttributes( temp.getFirst() );
-			newBlock = temp.getFirst().remove();
-		} else
-			newBlock.setHtml( preHtml );
-
-		return newBlock;
-	}
-
-	// Removes a style from an element itself, don't care about its subtree.
-	function removeFromElement( element, keepDataAttrs ) {
-		var def = this._.definition,
-			attributes = def.attributes,
-			styles = def.styles,
-			overrides = getOverrides( this )[ element.getName() ],
-			// If the style is only about the element itself, we have to remove the element.
-			removeEmpty = CKEDITOR.tools.isEmpty( attributes ) && CKEDITOR.tools.isEmpty( styles );
-
-		// Remove definition attributes/style from the elemnt.
-		for ( var attName in attributes ) {
-			// The 'class' element value must match (#1318).
-			if ( ( attName == 'class' || this._.definition.fullMatch ) && element.getAttribute( attName ) != normalizeProperty( attName, attributes[ attName ] ) )
-				continue;
-
-			// Do not touch data-* attributes (#11011) (#11258).
-			if ( keepDataAttrs && attName.slice( 0, 5 ) == 'data-' )
-				continue;
-
-			removeEmpty = element.hasAttribute( attName );
-			element.removeAttribute( attName );
-		}
-
-		for ( var styleName in styles ) {
-			// Full match style insist on having fully equivalence. (#5018)
-			if ( this._.definition.fullMatch && element.getStyle( styleName ) != normalizeProperty( styleName, styles[ styleName ], true ) )
-				continue;
-
-			removeEmpty = removeEmpty || !!element.getStyle( styleName );
-			element.removeStyle( styleName );
-		}
-
-		// Remove overrides, but don't remove the element if it's a block element
-		removeOverrides( element, overrides, blockElements[ element.getName() ] );
-
-		if ( removeEmpty ) {
-			if ( this._.definition.alwaysRemoveElement )
-				removeNoAttribsElement( element, 1 );
-			else {
-				if ( !CKEDITOR.dtd.$block[ element.getName() ] || this._.enterMode == CKEDITOR.ENTER_BR && !element.hasAttributes() )
-					removeNoAttribsElement( element );
-				else
-					element.renameNode( this._.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' );
-			}
-		}
-	}
-
-	// Removes a style from inside an element. Called on applyStyle to make cleanup
-	// before apply. During clean up this function keep data-* attribute in contrast
-	// to removeFromElement.
-	function removeFromInsideElement( element ) {
-		var def = this._.definition,
-			attribs = def.attributes,
-			styles = def.styles,
-			overrides = getOverrides( this ),
-			innerElements = element.getElementsByTag( this.element ),
-			innerElement;
-
-		for ( var i = innerElements.count(); --i >= 0; ) {
-			innerElement = innerElements.getItem( i );
-
-			// Do not remove elements which are read only (e.g. duplicates inside widgets).
-			if ( !innerElement.isReadOnly() )
-				removeFromElement.call( this, innerElement, true );
-		}
-
-		// Now remove any other element with different name that is
-		// defined to be overriden.
-		for ( var overrideElement in overrides ) {
-			if ( overrideElement != this.element ) {
-				innerElements = element.getElementsByTag( overrideElement );
-
-				for ( i = innerElements.count() - 1; i >= 0; i-- ) {
-					innerElement = innerElements.getItem( i );
-
-					// Do not remove elements which are read only (e.g. duplicates inside widgets).
-					if ( !innerElement.isReadOnly() )
-						removeOverrides( innerElement, overrides[ overrideElement ] );
-				}
-			}
-		}
-	}
-
-	// Remove overriding styles/attributes from the specific element.
-	// Note: Remove the element if no attributes remain.
-	// @param {Object} element
-	// @param {Object} overrides
-	// @param {Boolean} Don't remove the element
-	function removeOverrides( element, overrides, dontRemove ) {
-		var attributes = overrides && overrides.attributes;
-
-		if ( attributes ) {
-			for ( var i = 0; i < attributes.length; i++ ) {
-				var attName = attributes[ i ][ 0 ],
-					actualAttrValue;
-
-				if ( ( actualAttrValue = element.getAttribute( attName ) ) ) {
-					var attValue = attributes[ i ][ 1 ];
-
-					// Remove the attribute if:
-					//    - The override definition value is null ;
-					//    - The override definition valie is a string that
-					//      matches the attribute value exactly.
-					//    - The override definition value is a regex that
-					//      has matches in the attribute value.
-					if ( attValue === null || ( attValue.test && attValue.test( actualAttrValue ) ) || ( typeof attValue == 'string' && actualAttrValue == attValue ) )
-						element.removeAttribute( attName );
-				}
-			}
-		}
-
-		if ( !dontRemove )
-			removeNoAttribsElement( element );
-	}
-
-	// If the element has no more attributes, remove it.
-	function removeNoAttribsElement( element, forceRemove ) {
-		// If no more attributes remained in the element, remove it,
-		// leaving its children.
-		if ( !element.hasAttributes() || forceRemove ) {
-			if ( CKEDITOR.dtd.$block[ element.getName() ] ) {
-				var previous = element.getPrevious( nonWhitespaces ),
-					next = element.getNext( nonWhitespaces );
-
-				if ( previous && ( previous.type == CKEDITOR.NODE_TEXT || !previous.isBlockBoundary( { br: 1 } ) ) )
-					element.append( 'br', 1 );
-				if ( next && ( next.type == CKEDITOR.NODE_TEXT || !next.isBlockBoundary( { br: 1 } ) ) )
-					element.append( 'br' );
-
-				element.remove( true );
-			} else {
-				// Removing elements may open points where merging is possible,
-				// so let's cache the first and last nodes for later checking.
-				var firstChild = element.getFirst();
-				var lastChild = element.getLast();
-
-				element.remove( true );
-
-				if ( firstChild ) {
-					// Check the cached nodes for merging.
-					firstChild.type == CKEDITOR.NODE_ELEMENT && firstChild.mergeSiblings();
-
-					if ( lastChild && !firstChild.equals( lastChild ) && lastChild.type == CKEDITOR.NODE_ELEMENT )
-						lastChild.mergeSiblings();
-				}
-
-			}
-		}
-	}
-
-	function getElement( style, targetDocument, element ) {
-		var el,
-			def = style._.definition,
-			elementName = style.element;
-
-		// The "*" element name will always be a span for this function.
-		if ( elementName == '*' )
-			elementName = 'span';
-
-		// Create the element.
-		el = new CKEDITOR.dom.element( elementName, targetDocument );
-
-		// #6226: attributes should be copied before the new ones are applied
-		if ( element )
-			element.copyAttributes( el );
-
-		el = setupElement( el, style );
-
-		// Avoid ID duplication.
-		if ( targetDocument.getCustomData( 'doc_processing_style' ) && el.hasAttribute( 'id' ) )
-			el.removeAttribute( 'id' );
-		else
-			targetDocument.setCustomData( 'doc_processing_style', 1 );
-
-		return el;
-	}
-
-	function setupElement( el, style ) {
-		var def = style._.definition,
-			attributes = def.attributes,
-			styles = CKEDITOR.style.getStyleText( def );
-
-		// Assign all defined attributes.
-		if ( attributes ) {
-			for ( var att in attributes )
-				el.setAttribute( att, attributes[ att ] );
-		}
-
-		// Assign all defined styles.
-		if ( styles )
-			el.setAttribute( 'style', styles );
-
-		return el;
-	}
-
-	function replaceVariables( list, variablesValues ) {
-		for ( var item in list ) {
-			list[ item ] = list[ item ].replace( varRegex, function( match, varName ) {
-				return variablesValues[ varName ];
-			} );
-		}
-	}
-
-	// Returns an object that can be used for style matching comparison.
-	// Attributes names and values are all lowercased, and the styles get
-	// merged with the style attribute.
-	function getAttributesForComparison( styleDefinition ) {
-		// If we have already computed it, just return it.
-		var attribs = styleDefinition._AC;
-		if ( attribs )
-			return attribs;
-
-		attribs = {};
-
-		var length = 0;
-
-		// Loop through all defined attributes.
-		var styleAttribs = styleDefinition.attributes;
-		if ( styleAttribs ) {
-			for ( var styleAtt in styleAttribs ) {
-				length++;
-				attribs[ styleAtt ] = styleAttribs[ styleAtt ];
-			}
-		}
-
-		// Includes the style definitions.
-		var styleText = CKEDITOR.style.getStyleText( styleDefinition );
-		if ( styleText ) {
-			if ( !attribs[ 'style' ] )
-				length++;
-			attribs[ 'style' ] = styleText;
-		}
-
-		// Appends the "length" information to the object.
-		attribs._length = length;
-
-		// Return it, saving it to the next request.
-		return ( styleDefinition._AC = attribs );
-	}
-
-	// Get the the collection used to compare the elements and attributes,
-	// defined in this style overrides, with other element. All information in
-	// it is lowercased.
-	// @param {CKEDITOR.style} style
-	function getOverrides( style ) {
-		if ( style._.overrides )
-			return style._.overrides;
-
-		var overrides = ( style._.overrides = {} ),
-			definition = style._.definition.overrides;
-
-		if ( definition ) {
-			// The override description can be a string, object or array.
-			// Internally, well handle arrays only, so transform it if needed.
-			if ( !CKEDITOR.tools.isArray( definition ) )
-				definition = [ definition ];
-
-			// Loop through all override definitions.
-			for ( var i = 0; i < definition.length; i++ ) {
-				var override = definition[ i ],
-					elementName,
-					overrideEl,
-					attrs;
-
-				// If can be a string with the element name.
-				if ( typeof override == 'string' )
-					elementName = override.toLowerCase();
-				// Or an object.
-				else {
-					elementName = override.element ? override.element.toLowerCase() : style.element;
-					attrs = override.attributes;
-				}
-
-				// We can have more than one override definition for the same
-				// element name, so we attempt to simply append information to
-				// it if it already exists.
-				overrideEl = overrides[ elementName ] || ( overrides[ elementName ] = {} );
-
-				if ( attrs ) {
-					// The returning attributes list is an array, because we
-					// could have different override definitions for the same
-					// attribute name.
-					var overrideAttrs = ( overrideEl.attributes = overrideEl.attributes || new Array() );
-					for ( var attName in attrs ) {
-						// Each item in the attributes array is also an array,
-						// where [0] is the attribute name and [1] is the
-						// override value.
-						overrideAttrs.push( [ attName.toLowerCase(), attrs[ attName ] ] );
-					}
-				}
-			}
-		}
-
-		return overrides;
-	}
-
-	// Make the comparison of attribute value easier by standardizing it.
-	function normalizeProperty( name, value, isStyle ) {
-		var temp = new CKEDITOR.dom.element( 'span' );
-		temp[ isStyle ? 'setStyle' : 'setAttribute' ]( name, value );
-		return temp[ isStyle ? 'getStyle' : 'getAttribute' ]( name );
-	}
-
-	// Compare two bunch of styles, with the speciality that value 'inherit'
-	// is treated as a wildcard which will match any value.
-	// @param {Object/String} source
-	// @param {Object/String} target
-	function compareCssText( source, target ) {
-		if ( typeof source == 'string' )
-			source = CKEDITOR.tools.parseCssText( source );
-		if ( typeof target == 'string' )
-			target = CKEDITOR.tools.parseCssText( target, true );
-
-		for ( var name in source ) {
-			if ( !( name in target && ( target[ name ] == source[ name ] || source[ name ] == 'inherit' || target[ name ] == 'inherit' ) ) )
-				return false;
-		}
-		return true;
-	}
-
-	function applyStyleOnSelection( selection, remove ) {
-		var doc = selection.document,
-			ranges = selection.getRanges(),
-			func = remove ? this.removeFromRange : this.applyToRange,
-			range;
-
-		var iterator = ranges.createIterator();
-		while ( ( range = iterator.getNextRange() ) )
-			func.call( this, range );
-
-		selection.selectRanges( ranges );
-		doc.removeCustomData( 'doc_processing_style' );
-	}
-} )();
-
-/**
- * Generic style command. It applies a specific style when executed.
- *
- *		var boldStyle = new CKEDITOR.style( { element: 'strong' } );
- *		// Register the "bold" command, which applies the bold style.
- *		editor.addCommand( 'bold', new CKEDITOR.dialogCommand( boldStyle ) );
- *
- * @class
- * @constructor Creates a styleCommand class instance.
- * @extends CKEDITOR.commandDefinition
- * @param {CKEDITOR.style} style The style to be applied when command is executed.
- * @param {Object} [ext] Additional command definition's properties.
- */
-CKEDITOR.styleCommand = function( style, ext ) {
-	this.style = style;
-	this.allowedContent = style;
-	this.requiredContent = style;
-
-	CKEDITOR.tools.extend( this, ext, true );
-};
-
-/**
- * @param {CKEDITOR.editor} editor
- * @todo
- */
-CKEDITOR.styleCommand.prototype.exec = function( editor ) {
-	editor.focus();
-
-	if ( this.state == CKEDITOR.TRISTATE_OFF )
-		editor.applyStyle( this.style );
-	else if ( this.state == CKEDITOR.TRISTATE_ON )
-		editor.removeStyle( this.style );
-};
-
-/**
- * Manages styles registration and loading. See also {@link CKEDITOR.config#stylesSet}.
- *
- *		// The set of styles for the <b>Styles</b> combo.
- *		CKEDITOR.stylesSet.add( 'default', [
- *			// Block Styles
- *			{ name: 'Blue Title',		element: 'h3',		styles: { 'color': 'Blue' } },
- *			{ name: 'Red Title',		element: 'h3',		styles: { 'color': 'Red' } },
- *
- *			// Inline Styles
- *			{ name: 'Marker: Yellow',	element: 'span',	styles: { 'background-color': 'Yellow' } },
- *			{ name: 'Marker: Green',	element: 'span',	styles: { 'background-color': 'Lime' } },
- *
- *			// Object Styles
- *			{
- *				name: 'Image on Left',
- *				element: 'img',
- *				attributes: {
- *					style: 'padding: 5px; margin-right: 5px',
- *					border: '2',
- *					align: 'left'
- *				}
- *			}
- *		] );
- *
- * @since 3.2
- * @class
- * @singleton
- * @extends CKEDITOR.resourceManager
- */
-CKEDITOR.stylesSet = new CKEDITOR.resourceManager( '', 'stylesSet' );
-
-// Backward compatibility (#5025).
-CKEDITOR.addStylesSet = CKEDITOR.tools.bind( CKEDITOR.stylesSet.add, CKEDITOR.stylesSet );
-CKEDITOR.loadStylesSet = function( name, url, callback ) {
-	CKEDITOR.stylesSet.addExternal( name, url, '' );
-	CKEDITOR.stylesSet.load( name, callback );
-};
-
-
-/**
- * Gets the current styleSet for this instance.
- *
- *		editor.getStylesSet( function( stylesDefinitions ) {} );
- *
- * See also {@link CKEDITOR.editor#stylesSet} event.
- *
- * @param {Function} callback The function to be called with the styles data.
- * @member CKEDITOR.editor
- */
-CKEDITOR.editor.prototype.getStylesSet = function( callback ) {
-	if ( !this._.stylesDefinitions ) {
-		var editor = this,
-			// Respect the backwards compatible definition entry
-			configStyleSet = editor.config.stylesCombo_stylesSet || editor.config.stylesSet;
-
-		// The false value means that none styles should be loaded.
-		if ( configStyleSet === false ) {
-			callback( null );
-			return;
-		}
-
-		// #5352 Allow to define the styles directly in the config object
-		if ( configStyleSet instanceof Array ) {
-			editor._.stylesDefinitions = configStyleSet;
-			callback( configStyleSet );
-			return;
-		}
-
-		// Default value is 'default'.
-		if ( !configStyleSet )
-			configStyleSet = 'default';
-
-		var partsStylesSet = configStyleSet.split( ':' ),
-			styleSetName = partsStylesSet[ 0 ],
-			externalPath = partsStylesSet[ 1 ];
-
-		CKEDITOR.stylesSet.addExternal( styleSetName, externalPath ? partsStylesSet.slice( 1 ).join( ':' ) : CKEDITOR.getUrl( 'styles.js' ), '' );
-
-		CKEDITOR.stylesSet.load( styleSetName, function( stylesSet ) {
-			editor._.stylesDefinitions = stylesSet[ styleSetName ];
-			callback( editor._.stylesDefinitions );
-		} );
-	} else
-		callback( this._.stylesDefinitions );
-};
-
-/**
- * Indicates that fully selected read-only elements will be included when
- * applying the style (for inline styles only).
- *
- * @since 3.5
- * @property {Boolean} [includeReadonly=false]
- * @member CKEDITOR.style
- */
-
-/**
- * Indicates that any matches element of this style will be eventually removed
- * when calling {@link CKEDITOR.editor#removeStyle}.
- *
- * @since 4.0
- * @property {Boolean} [alwaysRemoveElement=false]
- * @member CKEDITOR.style
- */
-
-/**
- * Disables inline styling on read-only elements.
- *
- * @since 3.5
- * @cfg {Boolean} [disableReadonlyStyling=false]
- * @member CKEDITOR.config
- */
-
-/**
- * The "styles definition set" to use in the editor. They will be used in the
- * styles combo and the style selector of the div container.
- *
- * The styles may be defined in the page containing the editor, or can be
- * loaded on demand from an external file. In the second case, if this setting
- * contains only a name, the `styles.js` file will be loaded from the
- * CKEditor root folder (what ensures backward compatibility with CKEditor 4.0).
- *
- * Otherwise, this setting has the `name:url` syntax, making it
- * possible to set the URL from which loading the styles file.
- * Note that the `name` has to be equal to the name used in
- * {@link CKEDITOR.stylesSet#add} while registering styles set.
- *
- * **Note**: Since 4.1 it is possible to set `stylesSet` to `false`
- * to prevent loading any styles set.
- *
- *		// Do not load any file. Styles set is empty.
- *		config.stylesSet = false;
- *
- *		// Load the 'mystyles' styles set from styles.js file.
- *		config.stylesSet = 'mystyles';
- *
- *		// Load the 'mystyles' styles set from a relative URL.
- *		config.stylesSet = 'mystyles:/editorstyles/styles.js';
- *
- *		// Load from a full URL.
- *		config.stylesSet = 'mystyles:http://www.example.com/editorstyles/styles.js';
- *
- *		// Load from a list of definitions.
- *		config.stylesSet = [
- *			{ name: 'Strong Emphasis', element: 'strong' },
- *			{ name: 'Emphasis', element: 'em' },
- *			...
- *		];
- *
- * @since 3.3
- * @cfg {String/Array/Boolean} [stylesSet='default']
- * @member CKEDITOR.config
- */

+ 0 - 69
htdocs/includes/ckeditor/ckeditor/_source/core/template.js

@@ -1,69 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.template} class, which represents
- * an UI template for an editor instance.
- */
-
-( function() {
-	var cache = {},
-		rePlaceholder = /{([^}]+)}/g,
-		reQuote = /'/g,
-		reEscapableChars = /([\\'])/g,
-		reNewLine = /\n/g,
-		reCarriageReturn = /\r/g;
-
-	/**
-	 * Lightweight template used to build the output string from variables.
-	 *
-	 *		// HTML template for presenting a label UI.
-	 *		var tpl = new CKEDITOR.template( '<div class="{cls}">{label}</div>' );
-	 *		alert( tpl.output( { cls: 'cke-label', label: 'foo'} ) ); // '<div class="cke-label">foo</div>'
-	 *
-	 * @class
-	 * @constructor Creates a template class instance.
-	 * @param {String} source The template source.
-	 */
-	CKEDITOR.template = function( source ) {
-		// Builds an optimized function body for the output() method, focused on performance.
-		// For example, if we have this "source":
-		//	'<div style="{style}">{editorName}</div>'
-		// ... the resulting function body will be (apart from the "buffer" handling):
-		//	return [ '<div style="', data['style'] == undefined ? '{style}' : data['style'], '">', data['editorName'] == undefined ? '{editorName}' : data['editorName'], '</div>' ].join('');
-
-		// Try to read from the cache.
-		if ( cache[ source ] )
-			this.output = cache[ source ];
-		else {
-			var fn = source
-				// Escape chars like slash "\" or single quote "'".
-				.replace( reEscapableChars, '\\$1' )
-				.replace( reNewLine, '\\n' )
-				.replace( reCarriageReturn, '\\r' )
-				// Inject the template keys replacement.
-				.replace( rePlaceholder, function( m, key ) {
-					return "',data['" + key + "']==undefined?'{" + key + "}':data['" + key + "'],'";
-				} );
-
-			fn = "return buffer?buffer.push('" + fn + "'):['" + fn + "'].join('');";
-			this.output = cache[ source ] = Function( 'data', 'buffer', fn );
-		}
-	};
-} )();
-
-/**
- * Processes the template, filling its variables with the provided data.
- *
- * @method output
- * @param {Object} data An object containing properties which values will be
- * used to fill the template variables. The property names must match the
- * template variables names. Variables without matching properties will be
- * kept untouched.
- * @param {Array} [buffer] An array into which the output data will be pushed into.
- * The number of entries appended to the array is unknown.
- * @returns {String/Number} If `buffer` has not been provided, the processed
- * template output data, otherwise the new length of `buffer`.
- */

+ 0 - 1123
htdocs/includes/ckeditor/ckeditor/_source/core/tools.js

@@ -1,1123 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.tools} object, which contains
- *		utility functions.
- */
-
-( function() {
-	var functions = [],
-		cssVendorPrefix =
-			CKEDITOR.env.gecko ? '-moz-' :
-			CKEDITOR.env.webkit ? '-webkit-' :
-			CKEDITOR.env.opera ? '-o-' :
-			CKEDITOR.env.ie ? '-ms-' :
-			'';
-
-	CKEDITOR.on( 'reset', function() {
-		functions = [];
-	} );
-
-	/**
-	 * Utility functions.
-	 *
-	 * @class
-	 * @singleton
-	 */
-	CKEDITOR.tools = {
-		/**
-		 * Compares the elements of two arrays.
-		 *
-		 *		var a = [ 1, 'a', 3 ];
-		 *		var b = [ 1, 3, 'a' ];
-		 *		var c = [ 1, 'a', 3 ];
-		 *		var d = [ 1, 'a', 3, 4 ];
-		 *
-		 *		alert( CKEDITOR.tools.arrayCompare( a, b ) );  // false
-		 *		alert( CKEDITOR.tools.arrayCompare( a, c ) );  // true
-		 *		alert( CKEDITOR.tools.arrayCompare( a, d ) );  // false
-		 *
-		 * @param {Array} arrayA An array to be compared.
-		 * @param {Array} arrayB The other array to be compared.
-		 * @returns {Boolean} `true` if the arrays have the same length and
-		 * their elements match.
-		 */
-		arrayCompare: function( arrayA, arrayB ) {
-			if ( !arrayA && !arrayB )
-				return true;
-
-			if ( !arrayA || !arrayB || arrayA.length != arrayB.length )
-				return false;
-
-			for ( var i = 0; i < arrayA.length; i++ ) {
-				if ( arrayA[ i ] != arrayB[ i ] )
-					return false;
-			}
-
-			return true;
-		},
-
-		/**
-		 * Creates a deep copy of an object.
-		 *
-		 * **Note**: Recursive references are not supported.
-		 *
-		 *		var obj = {
-		 *			name: 'John',
-		 *			cars: {
-		 *				Mercedes: { color: 'blue' },
-		 *				Porsche: { color: 'red' }
-		 *			}
-		 *		};
-		 *		var clone = CKEDITOR.tools.clone( obj );
-		 *		clone.name = 'Paul';
-		 *		clone.cars.Porsche.color = 'silver';
-		 *
-		 *		alert( obj.name );					// 'John'
-		 *		alert( clone.name );				// 'Paul'
-		 *		alert( obj.cars.Porsche.color );	// 'red'
-		 *		alert( clone.cars.Porsche.color );	// 'silver'
-		 *
-		 * @param {Object} object The object to be cloned.
-		 * @returns {Object} The object clone.
-		 */
-		clone: function( obj ) {
-			var clone;
-
-			// Array.
-			if ( obj && ( obj instanceof Array ) ) {
-				clone = [];
-
-				for ( var i = 0; i < obj.length; i++ )
-					clone[ i ] = CKEDITOR.tools.clone( obj[ i ] );
-
-				return clone;
-			}
-
-			// "Static" types.
-			if ( obj === null || ( typeof( obj ) != 'object' ) || ( obj instanceof String ) || ( obj instanceof Number ) || ( obj instanceof Boolean ) || ( obj instanceof Date ) || ( obj instanceof RegExp ) )
-				return obj;
-
-			// Objects.
-			clone = new obj.constructor();
-
-			for ( var propertyName in obj ) {
-				var property = obj[ propertyName ];
-				clone[ propertyName ] = CKEDITOR.tools.clone( property );
-			}
-
-			return clone;
-		},
-
-		/**
-		 * Turns the first letter of a string to upper-case.
-		 *
-		 * @param {String} str
-		 * @param {Boolean} [keepCase] Keep the case of 2nd to last letter.
-		 * @returns {String}
-		 */
-		capitalize: function( str, keepCase ) {
-			return str.charAt( 0 ).toUpperCase() + ( keepCase ? str.slice( 1 ) : str.slice( 1 ).toLowerCase() );
-		},
-
-		/**
-		 * Copies the properties from one object to another. By default, properties
-		 * already present in the target object **are not** overwritten.
-		 *
-		 *		// Create the sample object.
-		 *		var myObject = {
-		 *			prop1: true
-		 *		};
-		 *
-		 *		// Extend the above object with two properties.
-		 *		CKEDITOR.tools.extend( myObject, {
-		 *			prop2: true,
-		 *			prop3: true
-		 *		} );
-		 *
-		 *		// Alert 'prop1', 'prop2' and 'prop3'.
-		 *		for ( var p in myObject )
-		 *			alert( p );
-		 *
-		 * @param {Object} target The object to be extended.
-		 * @param {Object...} source The object(s) from properties will be
-		 * copied. Any number of objects can be passed to this function.
-		 * @param {Boolean} [overwrite] If `true` is specified, it indicates that
-		 * properties already present in the target object could be
-		 * overwritten by subsequent objects.
-		 * @param {Object} [properties] Only properties within the specified names
-		 * list will be received from the source object.
-		 * @returns {Object} The extended object (target).
-		 */
-		extend: function( target ) {
-			var argsLength = arguments.length,
-				overwrite, propertiesList;
-
-			if ( typeof( overwrite = arguments[ argsLength - 1 ] ) == 'boolean' )
-				argsLength--;
-			else if ( typeof( overwrite = arguments[ argsLength - 2 ] ) == 'boolean' ) {
-				propertiesList = arguments[ argsLength - 1 ];
-				argsLength -= 2;
-			}
-			for ( var i = 1; i < argsLength; i++ ) {
-				var source = arguments[ i ];
-				for ( var propertyName in source ) {
-					// Only copy existed fields if in overwrite mode.
-					if ( overwrite === true || target[ propertyName ] == undefined ) {
-						// Only copy  specified fields if list is provided.
-						if ( !propertiesList || ( propertyName in propertiesList ) )
-							target[ propertyName ] = source[ propertyName ];
-
-					}
-				}
-			}
-
-			return target;
-		},
-
-		/**
-		 * Creates an object which is an instance of a class whose prototype is a
-		 * predefined object. All properties defined in the source object are
-		 * automatically inherited by the resulting object, including future
-		 * changes to it.
-		 *
-		 * @param {Object} source The source object to be used as the prototype for
-		 * the final object.
-		 * @returns {Object} The resulting copy.
-		 */
-		prototypedCopy: function( source ) {
-			var copy = function() {};
-			copy.prototype = source;
-			return new copy();
-		},
-
-		/**
-		 * Makes fast (shallow) copy of an object.
-		 * This method is faster than {@link #clone} which does
-		 * a deep copy of an object (including arrays).
-		 *
-		 * @since 4.1
-		 * @param {Object} source The object to be copied.
-		 * @returns {Object} Copy of `source`.
-		 */
-		copy: function( source ) {
-			var obj = {},
-				name;
-
-			for ( name in source )
-				obj[ name ] = source[ name ];
-
-			return obj;
-		},
-
-		/**
-		 * Checks if an object is an Array.
-		 *
-		 *		alert( CKEDITOR.tools.isArray( [] ) );		// true
-		 *		alert( CKEDITOR.tools.isArray( 'Test' ) );	// false
-		 *
-		 * @param {Object} object The object to be checked.
-		 * @returns {Boolean} `true` if the object is an Array, otherwise `false`.
-		 */
-		isArray: function( object ) {
-			return Object.prototype.toString.call( object ) == '[object Array]';
-		},
-
-		/**
-		 * Whether the object contains no properties of its own.
-		 *
-		 * @param object
-		 * @returns {Boolean}
-		 */
-		isEmpty: function( object ) {
-			for ( var i in object ) {
-				if ( object.hasOwnProperty( i ) )
-					return false;
-			}
-			return true;
-		},
-
-		/**
-		 * Generates an object or a string containing vendor-specific and vendor-free CSS properties.
-		 *
-		 *		CKEDITOR.tools.cssVendorPrefix( 'border-radius', '0', true );
-		 *		// On Firefox: '-moz-border-radius:0;border-radius:0'
-		 *		// On Chrome: '-webkit-border-radius:0;border-radius:0'
-		 *
-		 * @param {String} property The CSS property name.
-		 * @param {String} value The CSS value.
-		 * @param {Boolean} [asString=false] If `true`, then the returned value will be a CSS string.
-		 * @returns {Object/String} The object containing CSS properties or its stringified version.
-		 */
-		cssVendorPrefix: function( property, value, asString ) {
-			if ( asString )
-				return cssVendorPrefix + property + ':' + value + ';' + property + ':' + value;
-
-			var ret = {};
-			ret[ property ] = value;
-			ret[ cssVendorPrefix + property ] = value;
-
-			return ret;
-		},
-
-		/**
-		 * Transforms a CSS property name to its relative DOM style name.
-		 *
-		 *		alert( CKEDITOR.tools.cssStyleToDomStyle( 'background-color' ) );	// 'backgroundColor'
-		 *		alert( CKEDITOR.tools.cssStyleToDomStyle( 'float' ) );				// 'cssFloat'
-		 *
-		 * @method
-		 * @param {String} cssName The CSS property name.
-		 * @returns {String} The transformed name.
-		 */
-		cssStyleToDomStyle: ( function() {
-			var test = document.createElement( 'div' ).style;
-
-			var cssFloat = ( typeof test.cssFloat != 'undefined' ) ? 'cssFloat' : ( typeof test.styleFloat != 'undefined' ) ? 'styleFloat' : 'float';
-
-			return function( cssName ) {
-				if ( cssName == 'float' )
-					return cssFloat;
-				else {
-					return cssName.replace( /-./g, function( match ) {
-						return match.substr( 1 ).toUpperCase();
-					} );
-				}
-			};
-		} )(),
-
-		/**
-		 * Builds a HTML snippet from a set of `<style>/<link>`.
-		 *
-		 * @param {String/Array} css Each of which are URLs (absolute) of a CSS file or
-		 * a trunk of style text.
-		 * @returns {String}
-		 */
-		buildStyleHtml: function( css ) {
-			css = [].concat( css );
-			var item,
-				retval = [];
-			for ( var i = 0; i < css.length; i++ ) {
-				if ( ( item = css[ i ] ) ) {
-					// Is CSS style text ?
-					if ( /@import|[{}]/.test( item ) )
-						retval.push( '<style>' + item + '</style>' );
-					else
-						retval.push( '<link type="text/css" rel=stylesheet href="' + item + '">' );
-				}
-			}
-			return retval.join( '' );
-		},
-
-		/**
-		 * Replaces special HTML characters in a string with their relative HTML
-		 * entity values.
-		 *
-		 *		alert( CKEDITOR.tools.htmlEncode( 'A > B & C < D' ) ); // 'A &gt; B &amp; C &lt; D'
-		 *
-		 * @param {String} text The string to be encoded.
-		 * @returns {String} The encoded string.
-		 */
-		htmlEncode: function( text ) {
-			return String( text ).replace( /&/g, '&amp;' ).replace( />/g, '&gt;' ).replace( /</g, '&lt;' );
-		},
-
-		/**
-		 * Replaces special HTML characters in HTMLElement attribute with their relative HTML entity values.
-		 *
-		 *		element.setAttribute( 'title', '<a " b >' );
-		 *		alert( CKEDITOR.tools.htmlEncodeAttr( element.getAttribute( 'title' ) ); // '&gt;a &quot; b &lt;'
-		 *
-		 * @param {String} The attribute value to be encoded.
-		 * @returns {String} The encoded value.
-		 */
-		htmlEncodeAttr: function( text ) {
-			return text.replace( /"/g, '&quot;' ).replace( /</g, '&lt;' ).replace( />/g, '&gt;' );
-		},
-
-		/**
-		 * Replace HTML entities previously encoded by
-		 * {@link #htmlEncodeAttr htmlEncodeAttr} back to their plain character
-		 * representation.
-		 *
-		 *		alert( CKEDITOR.tools.htmlDecodeAttr( '&gt;a &quot; b &lt;' ); // '<a " b >'
-		 *
-		 * @param {String} text The text to be decoded.
-		 * @returns {String} The decoded text.
-		 */
-		htmlDecodeAttr: function( text ) {
-			return text.replace( /&quot;/g, '"' ).replace( /&lt;/g, '<' ).replace( /&gt;/g, '>' );
-		},
-
-		/**
-		 * Gets a unique number for this CKEDITOR execution session. It returns
-		 * consecutive numbers starting from 1.
-		 *
-		 *		alert( CKEDITOR.tools.getNextNumber() ); // (e.g.) 1
-		 *		alert( CKEDITOR.tools.getNextNumber() ); // 2
-		 *
-		 * @method
-		 * @returns {Number} A unique number.
-		 */
-		getNextNumber: ( function() {
-			var last = 0;
-			return function() {
-				return ++last;
-			};
-		} )(),
-
-		/**
-		 * Gets a unique ID for CKEditor interface elements. It returns a
-		 * string with the "cke_" prefix and a consecutive number.
-		 *
-		 *		alert( CKEDITOR.tools.getNextId() ); // (e.g.) 'cke_1'
-		 *		alert( CKEDITOR.tools.getNextId() ); // 'cke_2'
-		 *
-		 * @returns {String} A unique ID.
-		 */
-		getNextId: function() {
-			return 'cke_' + this.getNextNumber();
-		},
-
-		/**
-		 * Creates a function override.
-		 *
-		 *		var obj = {
-		 *			myFunction: function( name ) {
-		 *				alert( 'Name: ' + name );
-		 *			}
-		 *		};
-		 *
-		 *		obj.myFunction = CKEDITOR.tools.override( obj.myFunction, function( myFunctionOriginal ) {
-		 *			return function( name ) {
-		 *				alert( 'Overriden name: ' + name );
-		 *				myFunctionOriginal.call( this, name );
-		 *			};
-		 *		} );
-		 *
-		 * @param {Function} originalFunction The function to be overridden.
-		 * @param {Function} functionBuilder A function that returns the new
-		 * function. The original function reference will be passed to this function.
-		 * @returns {Function} The new function.
-		 */
-		override: function( originalFunction, functionBuilder ) {
-			var newFn = functionBuilder( originalFunction );
-			newFn.prototype = originalFunction.prototype;
-			return newFn;
-		},
-
-		/**
-		 * Executes a function after specified delay.
-		 *
-		 *		CKEDITOR.tools.setTimeout( function() {
-		 *			alert( 'Executed after 2 seconds' );
-		 *		}, 2000 );
-		 *
-		 * @param {Function} func The function to be executed.
-		 * @param {Number} [milliseconds=0] The amount of time (in millisecods) to wait
-		 * to fire the function execution.
-		 * @param {Object} [scope=window] The object to store the function execution scope
-		 * (the `this` object).
-		 * @param {Object/Array} [args] A single object, or an array of objects, to
-		 * pass as argument to the function.
-		 * @param {Object} [ownerWindow=window] The window that will be used to set the
-		 * timeout.
-		 * @returns {Object} A value that can be used to cancel the function execution.
-		 */
-		setTimeout: function( func, milliseconds, scope, args, ownerWindow ) {
-			if ( !ownerWindow )
-				ownerWindow = window;
-
-			if ( !scope )
-				scope = ownerWindow;
-
-			return ownerWindow.setTimeout( function() {
-				if ( args )
-					func.apply( scope, [].concat( args ) );
-				else
-					func.apply( scope );
-			}, milliseconds || 0 );
-		},
-
-		/**
-		 * Removes spaces from the start and the end of a string. The following
-		 * characters are removed: space, tab, line break, line feed.
-		 *
-		 *		alert( CKEDITOR.tools.trim( '  example ' ); // 'example'
-		 *
-		 * @method
-		 * @param {String} str The text from which the spaces will be removed.
-		 * @returns {String} The modified string without the boundary spaces.
-		 */
-		trim: ( function() {
-			// We are not using \s because we don't want "non-breaking spaces" to be caught.
-			var trimRegex = /(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g;
-			return function( str ) {
-				return str.replace( trimRegex, '' );
-			};
-		} )(),
-
-		/**
-		 * Removes spaces from the start (left) of a string. The following
-		 * characters are removed: space, tab, line break, line feed.
-		 *
-		 *		alert( CKEDITOR.tools.ltrim( '  example ' ); // 'example '
-		 *
-		 * @method
-		 * @param {String} str The text from which the spaces will be removed.
-		 * @returns {String} The modified string excluding the removed spaces.
-		 */
-		ltrim: ( function() {
-			// We are not using \s because we don't want "non-breaking spaces" to be caught.
-			var trimRegex = /^[ \t\n\r]+/g;
-			return function( str ) {
-				return str.replace( trimRegex, '' );
-			};
-		} )(),
-
-		/**
-		 * Removes spaces from the end (right) of a string. The following
-		 * characters are removed: space, tab, line break, line feed.
-		 *
-		 *		alert( CKEDITOR.tools.ltrim( '  example ' ); // '  example'
-		 *
-		 * @method
-		 * @param {String} str The text from which spaces will be removed.
-		 * @returns {String} The modified string excluding the removed spaces.
-		 */
-		rtrim: ( function() {
-			// We are not using \s because we don't want "non-breaking spaces" to be caught.
-			var trimRegex = /[ \t\n\r]+$/g;
-			return function( str ) {
-				return str.replace( trimRegex, '' );
-			};
-		} )(),
-
-		/**
-		 * Returns the index of an element in an array.
-		 *
-		 *		var letters = [ 'a', 'b', 0, 'c', false ];
-		 *		alert( CKEDITOR.tools.indexOf( letters, '0' ) );		// -1 because 0 !== '0'
-		 *		alert( CKEDITOR.tools.indexOf( letters, false ) );		// 4 because 0 !== false
-		 *
-		 * @param {Array} array The array to be searched.
-		 * @param {Object/Function} value The element to be found. This can be an
-		 * evaluation function which receives a single parameter call for
-		 * each entry in the array, returning `true` if the entry matches.
-		 * @returns {Number} The (zero-based) index of the first entry that matches
-		 * the entry, or `-1` if not found.
-		 */
-		indexOf: function( array, value ) {
-			if ( typeof value == 'function' ) {
-				for ( var i = 0, len = array.length; i < len; i++ ) {
-					if ( value( array[ i ] ) )
-						return i;
-				}
-			} else if ( array.indexOf )
-				return array.indexOf( value );
-			else {
-				for ( i = 0, len = array.length; i < len; i++ ) {
-					if ( array[ i ] === value )
-						return i;
-				}
-			}
-			return -1;
-		},
-
-		/**
-		 * Returns the index of an element in an array.
-		 *
-		 *		var obj = { prop: true };
-		 *		var letters = [ 'a', 'b', 0, obj, false ];
-		 *
-		 *		alert( CKEDITOR.tools.indexOf( letters, '0' ) ); // null
-		 *		alert( CKEDITOR.tools.indexOf( letters, function( value ) {
-		 *			// Return true when passed value has property 'prop'.
-		 *			return value && 'prop' in value;
-		 *		} ) );											// obj
-		 *
-		 * @param {Array} array The array to be searched.
-		 * @param {Object/Function} value The element to be found. Can be an
-		 * evaluation function which receives a single parameter call for
-		 * each entry in the array, returning `true` if the entry matches.
-		 * @returns Object The value that was found in an array.
-		 */
-		search: function( array, value ) {
-			var index = CKEDITOR.tools.indexOf( array, value );
-			return index >= 0 ? array[ index ] : null;
-		},
-
-		/**
-		 * Creates a function that will always execute in the context of a
-		 * specified object.
-		 *
-		 *		var obj = { text: 'My Object' };
-		 *
-		 *		function alertText() {
-		 *			alert( this.text );
-		 *		}
-		 *
-		 *		var newFunc = CKEDITOR.tools.bind( alertText, obj );
-		 *		newFunc(); // Alerts 'My Object'.
-		 *
-		 * @param {Function} func The function to be executed.
-		 * @param {Object} obj The object to which the execution context will be bound.
-		 * @returns {Function} The function that can be used to execute the
-		 * `func` function in the context of `obj`.
-		 */
-		bind: function( func, obj ) {
-			return function() {
-				return func.apply( obj, arguments );
-			};
-		},
-
-		/**
-		 * Class creation based on prototype inheritance which supports of the
-		 * following features:
-		 *
-		 * * Static fields
-		 * * Private fields
-		 * * Public (prototype) fields
-		 * * Chainable base class constructor
-		 *
-		 * @param {Object} definition The class definition object.
-		 * @returns {Function} A class-like JavaScript function.
-		 */
-		createClass: function( definition ) {
-			var $ = definition.$,
-				baseClass = definition.base,
-				privates = definition.privates || definition._,
-				proto = definition.proto,
-				statics = definition.statics;
-
-			// Create the constructor, if not present in the definition.
-			!$ && ( $ = function() {
-				baseClass && this.base.apply( this, arguments );
-			} );
-
-			if ( privates ) {
-				var originalConstructor = $;
-				$ = function() {
-					// Create (and get) the private namespace.
-					var _ = this._ || ( this._ = {} );
-
-					// Make some magic so "this" will refer to the main
-					// instance when coding private functions.
-					for ( var privateName in privates ) {
-						var priv = privates[ privateName ];
-
-						_[ privateName ] = ( typeof priv == 'function' ) ? CKEDITOR.tools.bind( priv, this ) : priv;
-					}
-
-					originalConstructor.apply( this, arguments );
-				};
-			}
-
-			if ( baseClass ) {
-				$.prototype = this.prototypedCopy( baseClass.prototype );
-				$.prototype.constructor = $;
-				// Super references.
-				$.base = baseClass;
-				$.baseProto = baseClass.prototype;
-				// Super constructor.
-				$.prototype.base = function() {
-					this.base = baseClass.prototype.base;
-					baseClass.apply( this, arguments );
-					this.base = arguments.callee;
-				};
-			}
-
-			if ( proto )
-				this.extend( $.prototype, proto, true );
-
-			if ( statics )
-				this.extend( $, statics, true );
-
-			return $;
-		},
-
-		/**
-		 * Creates a function reference that can be called later using
-		 * {@link #callFunction}. This approach is especially useful to
-		 * make DOM attribute function calls to JavaScript-defined functions.
-		 *
-		 *		var ref = CKEDITOR.tools.addFunction( function() {
-		 *			alert( 'Hello!');
-		 *		} );
-		 *		CKEDITOR.tools.callFunction( ref ); // 'Hello!'
-		 *
-		 * @param {Function} fn The function to be executed on call.
-		 * @param {Object} [scope] The object to have the context on `fn` execution.
-		 * @returns {Number} A unique reference to be used in conjuction with
-		 * {@link #callFunction}.
-		 */
-		addFunction: function( fn, scope ) {
-			return functions.push( function() {
-				return fn.apply( scope || this, arguments );
-			} ) - 1;
-		},
-
-		/**
-		 * Removes the function reference created with {@link #addFunction}.
-		 *
-		 * @param {Number} ref The function reference created with
-		 * {@link #addFunction}.
-		 */
-		removeFunction: function( ref ) {
-			functions[ ref ] = null;
-		},
-
-		/**
-		 * Executes a function based on the reference created with {@link #addFunction}.
-		 *
-		 *		var ref = CKEDITOR.tools.addFunction( function() {
-		 *			alert( 'Hello!');
-		 *		} );
-		 *		CKEDITOR.tools.callFunction( ref ); // 'Hello!'
-		 *
-		 * @param {Number} ref The function reference created with {@link #addFunction}.
-		 * @param {Mixed} params Any number of parameters to be passed to the executed function.
-		 * @returns {Mixed} The return value of the function.
-		 */
-		callFunction: function( ref ) {
-			var fn = functions[ ref ];
-			return fn && fn.apply( window, Array.prototype.slice.call( arguments, 1 ) );
-		},
-
-		/**
-		 * Appends the `px` length unit to the size value if it is missing.
-		 *
-		 *		var cssLength = CKEDITOR.tools.cssLength;
-		 *		cssLength( 42 );		// '42px'
-		 *		cssLength( '42' );		// '42px'
-		 *		cssLength( '42px' );	// '42px'
-		 *		cssLength( '42%' );		// '42%'
-		 *		cssLength( 'bold' );	// 'bold'
-		 *		cssLength( false );		// ''
-		 *		cssLength( NaN );		// ''
-		 *
-		 * @method
-		 * @param {Number/String/Boolean} length
-		 */
-		cssLength: ( function() {
-			var pixelRegex = /^-?\d+\.?\d*px$/,
-				lengthTrimmed;
-
-			return function( length ) {
-				lengthTrimmed = CKEDITOR.tools.trim( length + '' ) + 'px';
-
-				if ( pixelRegex.test( lengthTrimmed ) )
-					return lengthTrimmed;
-				else
-					return length || '';
-			};
-		} )(),
-
-		/**
-		 * Converts the specified CSS length value to the calculated pixel length inside this page.
-		 *
-		 * **Note:** Percentage-based value is left intact.
-		 *
-		 * @method
-		 * @param {String} cssLength CSS length value.
-		 */
-		convertToPx: ( function() {
-			var calculator;
-
-			return function( cssLength ) {
-				if ( !calculator ) {
-					calculator = CKEDITOR.dom.element.createFromHtml( '<div style="position:absolute;left:-9999px;' +
-						'top:-9999px;margin:0px;padding:0px;border:0px;"' +
-						'></div>', CKEDITOR.document );
-					CKEDITOR.document.getBody().append( calculator );
-				}
-
-				if ( !( /%$/ ).test( cssLength ) ) {
-					calculator.setStyle( 'width', cssLength );
-					return calculator.$.clientWidth;
-				}
-
-				return cssLength;
-			};
-		} )(),
-
-		/**
-		 * String specified by `str` repeats `times` times.
-		 *
-		 * @param {String} str
-		 * @param {Number} times
-		 * @returns {String}
-		 */
-		repeat: function( str, times ) {
-			return new Array( times + 1 ).join( str );
-		},
-
-		/**
-		 * Returns the first successfully executed return value of a function that
-		 * does not throw any exception.
-		 *
-		 * @param {Function...} fn
-		 * @returns {Mixed}
-		 */
-		tryThese: function() {
-			var returnValue;
-			for ( var i = 0, length = arguments.length; i < length; i++ ) {
-				var lambda = arguments[ i ];
-				try {
-					returnValue = lambda();
-					break;
-				} catch ( e ) {}
-			}
-			return returnValue;
-		},
-
-		/**
-		 * Generates a combined key from a series of params.
-		 *
-		 *		var key = CKEDITOR.tools.genKey( 'key1', 'key2', 'key3' );
-		 *		alert( key ); // 'key1-key2-key3'.
-		 *
-		 * @param {String} subKey One or more strings used as subkeys.
-		 * @returns {String}
-		 */
-		genKey: function() {
-			return Array.prototype.slice.call( arguments ).join( '-' );
-		},
-
-		/**
-		 * Creates a "deferred" function which will not run immediately,
-		 * but rather runs as soon as the interpreter’s call stack is empty.
-		 * Behaves much like `window.setTimeout` with a delay.
-		 *
-		 * **Note:** The return value of the original function will be lost.
-		 *
-		 * @param {Function} fn The callee function.
-		 * @returns {Function} The new deferred function.
-		 */
-		defer: function( fn ) {
-			return function() {
-				var args = arguments,
-					self = this;
-				window.setTimeout( function() {
-					fn.apply( self, args );
-				}, 0 );
-			};
-		},
-
-		/**
-		 * Normalizes CSS data in order to avoid differences in the style attribute.
-		 *
-		 * @param {String} styleText The style data to be normalized.
-		 * @param {Boolean} [nativeNormalize=false] Parse the data using the browser.
-		 * @returns {String} The normalized value.
-		 */
-		normalizeCssText: function( styleText, nativeNormalize ) {
-			var props = [],
-				name,
-				parsedProps = CKEDITOR.tools.parseCssText( styleText, true, nativeNormalize );
-
-			for ( name in parsedProps )
-				props.push( name + ':' + parsedProps[ name ] );
-
-			props.sort();
-
-			return props.length ? ( props.join( ';' ) + ';' ) : '';
-		},
-
-		/**
-		 * Finds and converts `rgb(x,x,x)` color definition to hexadecimal notation.
-		 *
-		 * @param {String} styleText The style data (or just a string containing RGB colors) to be converted.
-		 * @returns {String} The style data with RGB colors converted to hexadecimal equivalents.
-		 */
-		convertRgbToHex: function( styleText ) {
-			return styleText.replace( /(?:rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\))/gi, function( match, red, green, blue ) {
-				var color = [ red, green, blue ];
-				// Add padding zeros if the hex value is less than 0x10.
-				for ( var i = 0; i < 3; i++ )
-					color[ i ] = ( '0' + parseInt( color[ i ], 10 ).toString( 16 ) ).slice( -2 );
-				return '#' + color.join( '' );
-			} );
-		},
-
-		/**
-		 * Turns inline style text properties into one hash.
-		 *
-		 * @param {String} styleText The style data to be parsed.
-		 * @param {Boolean} [normalize=false] Normalize properties and values
-		 * (e.g. trim spaces, convert to lower case).
-		 * @param {Boolean} [nativeNormalize=false] Parse the data using the browser.
-		 * @returns {Object} The object containing parsed properties.
-		 */
-		parseCssText: function( styleText, normalize, nativeNormalize ) {
-			var retval = {};
-
-			if ( nativeNormalize ) {
-				// Injects the style in a temporary span object, so the browser parses it,
-				// retrieving its final format.
-				var temp = new CKEDITOR.dom.element( 'span' );
-				temp.setAttribute( 'style', styleText );
-				styleText = CKEDITOR.tools.convertRgbToHex( temp.getAttribute( 'style' ) || '' );
-			}
-
-			// IE will leave a single semicolon when failed to parse the style text. (#3891)
-			if ( !styleText || styleText == ';' )
-				return retval;
-
-			styleText.replace( /&quot;/g, '"' ).replace( /\s*([^:;\s]+)\s*:\s*([^;]+)\s*(?=;|$)/g, function( match, name, value ) {
-				if ( normalize ) {
-					name = name.toLowerCase();
-					// Normalize font-family property, ignore quotes and being case insensitive. (#7322)
-					// http://www.w3.org/TR/css3-fonts/#font-family-the-font-family-property
-					if ( name == 'font-family' )
-						value = value.toLowerCase().replace( /["']/g, '' ).replace( /\s*,\s*/g, ',' );
-					value = CKEDITOR.tools.trim( value );
-				}
-
-				retval[ name ] = value;
-			} );
-			return retval;
-		},
-
-		/**
-		 * Serializes the `style name => value` hash to a style text.
-		 *
-		 *		var styleObj = CKEDITOR.tools.parseCssText( 'color: red; border: none' );
-		 *		console.log( styleObj.color ); // -> 'red'
-		 *		CKEDITOR.tools.writeCssText( styleObj ); // -> 'color:red; border:none'
-		 *		CKEDITOR.tools.writeCssText( styleObj, true ); // -> 'border:none; color:red'
-		 *
-		 * @since 4.1
-		 * @param {Object} styles The object contaning style properties.
-		 * @param {Boolean} [sort] Whether to sort CSS properties.
-		 * @returns {String} The serialized style text.
-		 */
-		writeCssText: function( styles, sort ) {
-			var name,
-				stylesArr = [];
-
-			for ( name in styles )
-				stylesArr.push( name + ':' + styles[ name ] );
-
-			if ( sort )
-				stylesArr.sort();
-
-			return stylesArr.join( '; ' );
-		},
-
-		/**
-		 * Compares two objects.
-		 *
-		 * **Note:** This method performs shallow, non-strict comparison.
-		 *
-		 * @since 4.1
-		 * @param {Object} left
-		 * @param {Object} right
-		 * @param {Boolean} [onlyLeft] Check only the properties that are present in the `left` object.
-		 * @returns {Boolean} Whether objects are identical.
-		 */
-		objectCompare: function( left, right, onlyLeft ) {
-			var name;
-
-			if ( !left && !right )
-				return true;
-			if ( !left || !right )
-				return false;
-
-			for ( name in left ) {
-				if ( left[ name ] != right[ name ] )
-					return false;
-
-			}
-
-			if ( !onlyLeft ) {
-				for ( name in right ) {
-					if ( left[ name ] != right[ name ] )
-						return false;
-				}
-			}
-
-			return true;
-		},
-
-		/**
-		 * Returns an array of passed object's keys.
-		 *
-		 *		console.log( CKEDITOR.tools.objectKeys( { foo: 1, bar: false } );
-		 *		// -> [ 'foo', 'bar' ]
-		 *
-		 * @since 4.1
-		 * @param {Object} obj
-		 * @returns {Array} Object's keys.
-		 */
-		objectKeys: function( obj ) {
-			var keys = [];
-			for ( var i in obj )
-				keys.push( i );
-
-			return keys;
-		},
-
-		/**
-		 * Converts an array to an object by rewriting array items
-		 * to object properties.
-		 *
-		 *		var arr = [ 'foo', 'bar', 'foo' ];
-		 *		console.log( CKEDITOR.tools.convertArrayToObject( arr ) );
-		 *		// -> { foo: true, bar: true }
-		 *		console.log( CKEDITOR.tools.convertArrayToObject( arr, 1 ) );
-		 *		// -> { foo: 1, bar: 1 }
-		 *
-		 * @since 4.1
-		 * @param {Array} arr The array to be converted to an object.
-		 * @param [fillWith=true] Set each property of an object to `fillWith` value.
-		 */
-		convertArrayToObject: function( arr, fillWith ) {
-			var obj = {};
-
-			if ( arguments.length == 1 )
-				fillWith = true;
-
-			for ( var i = 0, l = arr.length; i < l; ++i )
-				obj[ arr[ i ] ] = fillWith;
-
-			return obj;
-		},
-
-		/**
-		 * Tries to fix the `document.domain` of the current document to match the
-		 * parent window domain, avoiding "Same Origin" policy issues.
-		 * This is an Internet Explorer only requirement.
-		 *
-		 * @since 4.1.2
-		 * @returns {Boolean} `true` if the current domain is already good or if
-		 * it has been fixed successfully.
-		 */
-		fixDomain: function() {
-			var domain;
-
-			while ( 1 ) {
-				try {
-					// Try to access the parent document. It throws
-					// "access denied" if restricted by the "Same Origin" policy.
-					domain = window.parent.document.domain;
-					break;
-				} catch ( e ) {
-					// Calculate the value to set to document.domain.
-					domain = domain ?
-
-						// If it is not the first pass, strip one part of the
-						// name. E.g.  "test.example.com"  => "example.com"
-						domain.replace( /.+?(?:\.|$)/, '' ) :
-
-						// In the first pass, we'll handle the
-						// "document.domain = document.domain" case.
-						document.domain;
-
-					// Stop here if there is no more domain parts available.
-					if ( !domain )
-						break;
-
-					document.domain = domain;
-				}
-			}
-
-			return !!domain;
-		},
-
-		/**
-		 * Buffers `input` events (or any `input` calls)
-		 * and triggers `output` not more often than once per `minInterval`.
-		 *
-		 *		var buffer = CKEDITOR.tools.eventsBuffer( 200, function() {
-		 *			console.log( 'foo!' );
-		 *		} );
-		 *
-		 *		buffer.input();
-		 *		// 'foo!' logged immediately.
-		 *		buffer.input();
-		 *		// Nothing logged.
-		 *		buffer.input();
-		 *		// Nothing logged.
-		 *		// ... after 200ms a single 'foo!' will be logged.
-		 *
-		 * Can be easily used with events:
-		 *
-		 *		var buffer = CKEDITOR.tools.eventsBuffer( 200, function() {
-		 *			console.log( 'foo!' );
-		 *		} );
-		 *
-		 *		editor.on( 'key', buffer.input );
-		 *		// Note: There is no need to bind buffer as a context.
-		 *
-		 * @since 4.2.1
-		 * @param {Number} minInterval Minimum interval between `output` calls in milliseconds.
-		 * @param {Function} output Function that will be executed as `output`.
-		 * @returns {Object}
-		 * @returns {Function} return.input Buffer's input method.
-		 * @returns {Function} return.reset Resets buffered events &mdash; `output` will not be executed
-		 * until next `input` is triggered.
-		 */
-		eventsBuffer: function( minInterval, output ) {
-			var scheduled,
-				lastOutput = 0;
-
-			function triggerOutput() {
-				lastOutput = ( new Date() ).getTime();
-				scheduled = false;
-				output();
-			}
-
-			return {
-				input: function() {
-					if ( scheduled )
-						return;
-
-					var diff = ( new Date() ).getTime() - lastOutput;
-
-					// If less than minInterval passed after last check,
-					// schedule next for minInterval after previous one.
-					if ( diff < minInterval )
-						scheduled = setTimeout( triggerOutput, minInterval - diff );
-					else
-						triggerOutput();
-				},
-
-				reset: function() {
-					if ( scheduled )
-						clearTimeout( scheduled );
-
-					scheduled = lastOutput = 0;
-				}
-			};
-		},
-
-		/**
-		 * Enable HTML5 elements for older browsers (IE8) in passed document.
-		 *
-		 * In IE8 this method can be also executed on document fragment.
-		 *
-		 * **Note:** This method has to be used in the `<head>` section of the document.
-		 *
-		 * @since 4.3
-		 * @param {Object} doc Native `Document` or `DocumentFragment` in which elements will be enabled.
-		 * @param {Boolean} [withAppend] Whether to append created elements to the `doc`.
-		 */
-		enableHtml5Elements: function( doc, withAppend ) {
-			var els = 'abbr,article,aside,audio,bdi,canvas,data,datalist,details,figcaption,figure,footer,header,hgroup,mark,meter,nav,output,progress,section,summary,time,video'.split( ',' ),
-				i = els.length,
-				el;
-
-			while ( i-- ) {
-				el = doc.createElement( els[ i ] );
-				if ( withAppend )
-					doc.appendChild( el );
-			}
-		}
-	};
-} )();
-
-// PACKAGER_RENAME( CKEDITOR.tools )

+ 0 - 168
htdocs/includes/ckeditor/ckeditor/_source/core/ui.js

@@ -1,168 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * Contains UI features related to an editor instance.
- *
- * @class
- * @mixins CKEDITOR.event
- * @constructor Creates an ui class instance.
- * @param {CKEDITOR.editor} editor The editor instance.
- */
-CKEDITOR.ui = function( editor ) {
-	if ( editor.ui )
-		return editor.ui;
-
-	this.items = {};
-	this.instances = {};
-	this.editor = editor;
-
-	/**
-	 * Object used to hold private stuff.
-	 *
-	 * @private
-	 */
-	this._ = {
-		handlers: {}
-	};
-
-	return this;
-};
-
-// PACKAGER_RENAME( CKEDITOR.ui )
-
-CKEDITOR.ui.prototype = {
-	/**
-	 * Adds a UI item to the items collection. These items can be later used in
-	 * the interface.
-	 *
-	 *		// Add a new button named 'MyBold'.
-	 *		editorInstance.ui.add( 'MyBold', CKEDITOR.UI_BUTTON, {
-	 *			label: 'My Bold',
-	 *			command: 'bold'
-	 *		} );
-	 *
-	 * @param {String} name The UI item name.
-	 * @param {Object} type The item type.
-	 * @param {Object} definition The item definition. The properties of this
-	 * object depend on the item type.
-	 */
-	add: function( name, type, definition ) {
-		// Compensate the unique name of this ui item to definition.
-		definition.name = name.toLowerCase();
-
-		var item = this.items[ name ] = {
-			type: type,
-			// The name of {@link CKEDITOR.command} which associate with this UI.
-			command: definition.command || null,
-			args: Array.prototype.slice.call( arguments, 2 )
-		};
-
-		CKEDITOR.tools.extend( item, definition );
-	},
-
-	/**
-	 * Retrieve the created ui objects by name.
-	 *
-	 * @param {String} name The name of the UI definition.
-	 */
-	get: function( name ) {
-		return this.instances[ name ];
-	},
-
-	/**
-	 * Gets a UI object.
-	 *
-	 * @param {String} name The UI item hame.
-	 * @returns {Object} The UI element.
-	 */
-	create: function( name ) {
-		var item = this.items[ name ],
-			handler = item && this._.handlers[ item.type ],
-			command = item && item.command && this.editor.getCommand( item.command );
-
-		var result = handler && handler.create.apply( this, item.args );
-
-		this.instances[ name ] = result;
-
-		// Add reference inside command object.
-		if ( command )
-			command.uiItems.push( result );
-
-		if ( result && !result.type )
-			result.type = item.type;
-
-		return result;
-	},
-
-	/**
-	 * Adds a handler for a UI item type. The handler is responsible for
-	 * transforming UI item definitions in UI objects.
-	 *
-	 * @param {Object} type The item type.
-	 * @param {Object} handler The handler definition.
-	 */
-	addHandler: function( type, handler ) {
-		this._.handlers[ type ] = handler;
-	},
-
-	/**
-	 * Returns the unique DOM element that represents one editor's UI part, as
-	 * the editor UI is made completely decoupled from DOM (no DOM reference hold),
-	 * this method is mainly used to retrieve the rendered DOM part by name.
-	 *
-	 *		// Hide the bottom space in the UI.
-	 *		var bottom = editor.ui.getSpace( 'bottom' );
-	 *		bottom.setStyle( 'display', 'none' );
-	 *
-	 * @param {String} name The space name.
-	 * @returns {CKEDITOR.dom.element} The element that represents the space.
-	 */
-	space: function( name ) {
-		return CKEDITOR.document.getById( this.spaceId( name ) );
-	},
-
-	/**
-	 * Generate the HTML ID from a specific UI space name.
-	 *
-	 * @param name
-	 * @todo param and return types?
-	 */
-	spaceId: function( name ) {
-		return this.editor.id + '_' + name;
-	}
-};
-
-CKEDITOR.event.implementOn( CKEDITOR.ui );
-
-/**
- * Internal event fired when a new UI element is ready.
- *
- * @event ready
- * @param {Object} data The new element.
- */
-
-/**
- * Virtual class which just illustrates the features of handler objects to be
- * passed to the {@link CKEDITOR.ui#addHandler} function.
- * This class is not really part of the API, so don't call its constructor.
- *
- * @class CKEDITOR.ui.handlerDefinition
- */
-
-/**
- * Transforms an item definition into an UI item object.
- *
- *		editorInstance.ui.addHandler( CKEDITOR.UI_BUTTON, {
- *			create: function( definition ) {
- *				return new CKEDITOR.ui.button( definition );
- *			}
- *		} );
- *
- * @method create
- * @param {Object} definition The item definition.
- * @returns {Object} The UI element.
- * @todo We lack the "UI element" abstract super class.
- */

+ 0 - 63
htdocs/includes/ckeditor/ckeditor/_source/lang/_translationstatus.txt

@@ -1,63 +0,0 @@
-Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
-For licensing, see LICENSE.md or http://ckeditor.com/license
-
-af.js      Found: 62 Missing: 4
-ar.js      Found: 51 Missing: 15
-bg.js      Found: 58 Missing: 8
-bn.js      Found: 40 Missing: 26
-bs.js      Found: 29 Missing: 37
-ca.js      Found: 61 Missing: 5
-cs.js      Found: 66 Missing: 0
-cy.js      Found: 66 Missing: 0
-da.js      Found: 66 Missing: 0
-de.js      Found: 66 Missing: 0
-el.js      Found: 59 Missing: 7
-en-au.js   Found: 38 Missing: 28
-en-ca.js   Found: 37 Missing: 29
-en-gb.js   Found: 61 Missing: 5
-eo.js      Found: 66 Missing: 0
-es.js      Found: 66 Missing: 0
-et.js      Found: 66 Missing: 0
-eu.js      Found: 48 Missing: 18
-fa.js      Found: 66 Missing: 0
-fi.js      Found: 66 Missing: 0
-fo.js      Found: 66 Missing: 0
-fr-ca.js   Found: 42 Missing: 24
-fr.js      Found: 66 Missing: 0
-gl.js      Found: 40 Missing: 26
-gu.js      Found: 66 Missing: 0
-he.js      Found: 66 Missing: 0
-hi.js      Found: 43 Missing: 23
-hr.js      Found: 66 Missing: 0
-hu.js      Found: 63 Missing: 3
-is.js      Found: 41 Missing: 25
-it.js      Found: 66 Missing: 0
-ja.js      Found: 62 Missing: 4
-ka.js      Found: 62 Missing: 4
-km.js      Found: 40 Missing: 26
-ko.js      Found: 40 Missing: 26
-lt.js      Found: 66 Missing: 0
-lv.js      Found: 40 Missing: 26
-mk.js      Found: 0 Missing: 66
-mn.js      Found: 40 Missing: 26
-ms.js      Found: 39 Missing: 27
-nb.js      Found: 66 Missing: 0
-nl.js      Found: 65 Missing: 1
-no.js      Found: 66 Missing: 0
-pl.js      Found: 66 Missing: 0
-pt-br.js   Found: 66 Missing: 0
-pt.js      Found: 52 Missing: 14
-ro.js      Found: 61 Missing: 5
-ru.js      Found: 66 Missing: 0
-sk.js      Found: 49 Missing: 17
-sl.js      Found: 48 Missing: 18
-sr-latn.js Found: 40 Missing: 26
-sr.js      Found: 40 Missing: 26
-sv.js      Found: 62 Missing: 4
-th.js      Found: 40 Missing: 26
-tr.js      Found: 66 Missing: 0
-ug.js      Found: 66 Missing: 0
-uk.js      Found: 66 Missing: 0
-vi.js      Found: 66 Missing: 0
-zh-cn.js   Found: 66 Missing: 0
-zh.js      Found: 58 Missing: 8

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/af.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Afrikaans language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'af' ] = {
-	// ARIA description.
-	editor: 'Teksverwerker',
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Druk op ALT 0 vir hulp',
-
-		browseServer: 'Blaai op bediener',
-		url: 'URL',
-		protocol: 'Protokol',
-		upload: 'Oplaai',
-		uploadSubmit: 'Stuur na bediener',
-		image: 'Afbeelding',
-		flash: 'Flash',
-		form: 'Vorm',
-		checkbox: 'Merkhokkie',
-		radio: 'Radioknoppie',
-		textField: 'Teksveld',
-		textarea: 'Teks-area',
-		hiddenField: 'Blinde veld',
-		button: 'Knop',
-		select: 'Keuseveld',
-		imageButton: 'Afbeeldingsknop',
-		notSet: '<geen instelling>',
-		id: 'Id',
-		name: 'Naam',
-		langDir: 'Skryfrigting',
-		langDirLtr: 'Links na regs (LTR)',
-		langDirRtl: 'Regs na links (RTL)',
-		langCode: 'Taalkode',
-		longDescr: 'Lang beskrywing URL',
-		cssClass: 'CSS klasse',
-		advisoryTitle: 'Aanbevole titel',
-		cssStyle: 'Styl',
-		ok: 'OK',
-		cancel: 'Kanselleer',
-		close: 'Sluit',
-		preview: 'Voorbeeld',
-		resize: 'Sleep om te herskaal',
-		generalTab: 'Algemeen',
-		advancedTab: 'Gevorderd',
-		validateNumberFailed: 'Hierdie waarde is nie \'n getal nie.',
-		confirmNewPage: 'Alle wysiginge sal verlore gaan. Is u seker dat u \'n nuwe bladsy wil laai?',
-		confirmCancel: 'Sommige opsies is gewysig. Is u seker dat u hierdie dialoogvenster wil sluit?',
-		options: 'Opsies',
-		target: 'Doel',
-		targetNew: 'Nuwe venster (_blank)',
-		targetTop: 'Boonste venster (_top)',
-		targetSelf: 'Selfde venster (_self)',
-		targetParent: 'Oorspronklike venster (_parent)',
-		langDirLTR: 'Links na Regs (LTR)',
-		langDirRTL: 'Regs na Links (RTL)',
-		styles: 'Styl',
-		cssClasses: 'CSS klasse',
-		width: 'Breedte',
-		height: 'Hoogte',
-		align: 'Oplyn',
-		alignLeft: 'Links',
-		alignRight: 'Regs',
-		alignCenter: 'Sentreer',
-		alignTop: 'Bo',
-		alignMiddle: 'Middel',
-		alignBottom: 'Onder',
-		invalidValue	: 'Invalid value.', // MISSING
-		invalidHeight: 'Hoogte moet \'n getal wees',
-		invalidWidth: 'Breedte moet \'n getal wees.',
-		invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
-		invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
-		invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
-		cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, nie beskikbaar nie</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/ar.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Arabic language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'ar' ] = {
-	// ARIA description.
-	editor: 'محرر النص الغني',
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'إضغط على ALT + 0 للحصول على المساعدة.',
-
-		browseServer: 'تصفح',
-		url: 'الرابط',
-		protocol: 'البروتوكول',
-		upload: 'رفع',
-		uploadSubmit: 'أرسل',
-		image: 'صورة',
-		flash: 'فلاش',
-		form: 'نموذج',
-		checkbox: 'خانة إختيار',
-		radio: 'زر اختيار',
-		textField: 'مربع نص',
-		textarea: 'مساحة نصية',
-		hiddenField: 'إدراج حقل خفي',
-		button: 'زر ضغط',
-		select: 'اختار',
-		imageButton: 'زر صورة',
-		notSet: '<بدون تحديد>',
-		id: 'الرقم',
-		name: 'إسم',
-		langDir: 'إتجاه النص',
-		langDirLtr: 'اليسار لليمين (LTR)',
-		langDirRtl: 'اليمين لليسار (RTL)',
-		langCode: 'رمز اللغة',
-		longDescr: 'الوصف التفصيلى',
-		cssClass: 'فئات التنسيق',
-		advisoryTitle: 'عنوان التقرير',
-		cssStyle: 'نمط',
-		ok: 'موافق',
-		cancel: 'إلغاء الأمر',
-		close: 'أغلق',
-		preview: 'استعراض',
-		resize: 'تغيير الحجم',
-		generalTab: 'عام',
-		advancedTab: 'متقدم',
-		validateNumberFailed: 'لايوجد نتيجة',
-		confirmNewPage: 'ستفقد أي متغييرات اذا لم تقم بحفظها اولا. هل أنت متأكد أنك تريد صفحة جديدة؟',
-		confirmCancel: 'بعض الخيارات قد تغيرت. هل أنت متأكد من إغلاق مربع النص؟',
-		options: 'خيارات',
-		target: 'هدف الرابط',
-		targetNew: 'نافذة جديدة',
-		targetTop: 'النافذة الأعلى',
-		targetSelf: 'داخل النافذة',
-		targetParent: 'النافذة الأم',
-		langDirLTR: 'اليسار لليمين (LTR)',
-		langDirRTL: 'اليمين لليسار (RTL)',
-		styles: 'نمط',
-		cssClasses: 'فئات التنسيق',
-		width: 'العرض',
-		height: 'الإرتفاع',
-		align: 'محاذاة',
-		alignLeft: 'يسار',
-		alignRight: 'يمين',
-		alignCenter: 'وسط',
-		alignTop: 'أعلى',
-		alignMiddle: 'وسط',
-		alignBottom: 'أسفل',
-		invalidValue	: 'قيمة غير مفبولة.',
-		invalidHeight: 'الارتفاع يجب أن يكون عدداً.',
-		invalidWidth: 'العرض يجب أن يكون عدداً.',
-		invalidCssLength: 'قيمة الخانة المخصصة لـ "%1" يجب أن تكون رقما موجبا، باستخدام أو من غير استخدام وحدة CSS قياس مقبولة (px, %, in, cm, mm, em, ex, pt, or pc).',
-		invalidHtmlLength: 'قيمة الخانة المخصصة لـ "%1" يجب أن تكون رقما موجبا، باستخدام أو من غير استخدام وحدة HTML قياس مقبولة (px or %).',
-		invalidInlineStyle: 'قيمة الخانة المخصصة لـ  Inline Style يجب أن تختوي على مجموع واحد أو أكثر بالشكل التالي: "name : value", مفصولة بفاصلة منقزطة.',
-		cssLengthTooltip: 'أدخل رقما للقيمة بالبكسل أو رقما بوحدة CSS مقبولة (px, %, in, cm, mm, em, ex, pt, or pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, غير متاح</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/bg.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Bulgarian language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'bg' ] = {
-	// ARIA description.
-	editor: 'Текстов редактор за форматиран текст',
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'натиснете ALT 0 за помощ',
-
-		browseServer: 'Избор от сървъра',
-		url: 'URL',
-		protocol: 'Протокол',
-		upload: 'Качване',
-		uploadSubmit: 'Изпращане към сървъра',
-		image: 'Снимка',
-		flash: 'Флаш',
-		form: 'Форма',
-		checkbox: 'Поле за избор',
-		radio: 'Радио бутон',
-		textField: 'Текстово поле',
-		textarea: 'Текстова зона',
-		hiddenField: 'Скрито поле',
-		button: 'Бутон',
-		select: 'Поле за избор',
-		imageButton: 'Бутон за снимка',
-		notSet: '<не е избрано>',
-		id: 'ID',
-		name: 'Име',
-		langDir: 'Посока на езика',
-		langDirLtr: 'Ляво на дясно (ЛнД)',
-		langDirRtl: 'Дясно на ляво (ДнЛ)',
-		langCode: 'Код на езика',
-		longDescr: 'Уеб адрес за дълго описание',
-		cssClass: 'Класове за CSS',
-		advisoryTitle: 'Препоръчително заглавие',
-		cssStyle: 'Стил',
-		ok: 'ОК',
-		cancel: 'Отказ',
-		close: 'Затвори',
-		preview: 'Преглед',
-		resize: 'Влачете за да оразмерите',
-		generalTab: 'Общи',
-		advancedTab: 'Разширено',
-		validateNumberFailed: 'Тази стойност не е число',
-		confirmNewPage: 'Всички незапазени промени ще бъдат изгубени. Сигурни ли сте, че желаете да заредите нова страница?',
-		confirmCancel: 'Някои от опциите са променени. Сигурни ли сте, че желаете да затворите прозореца?',
-		options: 'Опции',
-		target: 'Цел',
-		targetNew: 'Нов прозорец (_blank)',
-		targetTop: 'Горна позиция (_top)',
-		targetSelf: 'Текущия прозорец (_self)',
-		targetParent: 'Основен прозорец (_parent)',
-		langDirLTR: 'Ляво на дясно (ЛнД)',
-		langDirRTL: 'Дясно на ляво (ДнЛ)',
-		styles: 'Стил',
-		cssClasses: 'Класове за CSS',
-		width: 'Ширина',
-		height: 'Височина',
-		align: 'Подравняване',
-		alignLeft: 'Ляво',
-		alignRight: 'Дясно',
-		alignCenter: 'Център',
-		alignTop: 'Горе',
-		alignMiddle: 'По средата',
-		alignBottom: 'Долу',
-		invalidValue	: 'Невалидна стойност.',
-		invalidHeight: 'Височината трябва да е число.',
-		invalidWidth: 'Ширина требе да е число.',
-		invalidCssLength: 'Стойността на полето "%1" трябва да бъде положително число с или без валидна CSS измервателна единица (px, %, in, cm, mm, em, ex, pt, или pc).',
-		invalidHtmlLength: 'Стойността на полето "%1" трябва да бъде положително число с или без валидна HTML измервателна единица (px или %).',
-		invalidInlineStyle: 'Стойността на стилa трябва да съдържат една или повече двойки във формат "name : value", разделени с двоеточие.',
-		cssLengthTooltip: 'Въведете числена стойност в пиксели или друга валидна CSS единица (px, %, in, cm, mm, em, ex, pt, или pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, недостъпно</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/bn.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Bengali/Bangla language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'bn' ] = {
-	// ARIA description.
-	editor: 'Rich Text Editor', // MISSING
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Press ALT 0 for help', // MISSING
-
-		browseServer: 'ব্রাউজ সার্ভার',
-		url: 'URL',
-		protocol: 'প্রোটোকল',
-		upload: 'আপলোড',
-		uploadSubmit: 'ইহাকে সার্ভারে প্রেরন কর',
-		image: 'ছবির লেবেল যুক্ত কর',
-		flash: 'ফ্লাশ লেবেল যুক্ত কর',
-		form: 'ফর্ম',
-		checkbox: 'চেক বাক্স',
-		radio: 'রেডিও বাটন',
-		textField: 'টেক্সট ফীল্ড',
-		textarea: 'টেক্সট এরিয়া',
-		hiddenField: 'গুপ্ত ফীল্ড',
-		button: 'বাটন',
-		select: 'বাছাই ফীল্ড',
-		imageButton: 'ছবির বাটন',
-		notSet: '<সেট নেই>',
-		id: 'আইডি',
-		name: 'নাম',
-		langDir: 'ভাষা লেখার দিক',
-		langDirLtr: 'বাম থেকে ডান (LTR)',
-		langDirRtl: 'ডান থেকে বাম (RTL)',
-		langCode: 'ভাষা কোড',
-		longDescr: 'URL এর লম্বা বর্ণনা',
-		cssClass: 'স্টাইল-শীট ক্লাস',
-		advisoryTitle: 'পরামর্শ শীর্ষক',
-		cssStyle: 'স্টাইল',
-		ok: 'ওকে',
-		cancel: 'বাতিল',
-		close: 'Close', // MISSING
-		preview: 'প্রিভিউ',
-		resize: 'Resize', // MISSING
-		generalTab: 'General', // MISSING
-		advancedTab: 'এডভান্সড',
-		validateNumberFailed: 'This value is not a number.', // MISSING
-		confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
-		confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
-		options: 'Options', // MISSING
-		target: 'টার্গেট',
-		targetNew: 'New Window (_blank)', // MISSING
-		targetTop: 'Topmost Window (_top)', // MISSING
-		targetSelf: 'Same Window (_self)', // MISSING
-		targetParent: 'Parent Window (_parent)', // MISSING
-		langDirLTR: 'বাম থেকে ডান (LTR)',
-		langDirRTL: 'ডান থেকে বাম (RTL)',
-		styles: 'স্টাইল',
-		cssClasses: 'স্টাইল-শীট ক্লাস',
-		width: 'প্রস্থ',
-		height: 'দৈর্ঘ্য',
-		align: 'এলাইন',
-		alignLeft: 'বামে',
-		alignRight: 'ডানে',
-		alignCenter: 'মাঝখানে',
-		alignTop: 'উপর',
-		alignMiddle: 'মধ্য',
-		alignBottom: 'নীচে',
-		invalidValue	: 'Invalid value.', // MISSING
-		invalidHeight: 'Height must be a number.', // MISSING
-		invalidWidth: 'Width must be a number.', // MISSING
-		invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
-		invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
-		invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
-		cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, unavailable</span>' // MISSING
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/bs.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Bosnian language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'bs' ] = {
-	// ARIA description.
-	editor: 'Rich Text Editor', // MISSING
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Press ALT 0 for help', // MISSING
-
-		browseServer: 'Browse Server', // MISSING
-		url: 'URL',
-		protocol: 'Protokol',
-		upload: 'Šalji',
-		uploadSubmit: 'Šalji na server',
-		image: 'Slika',
-		flash: 'Flash', // MISSING
-		form: 'Form', // MISSING
-		checkbox: 'Checkbox', // MISSING
-		radio: 'Radio Button', // MISSING
-		textField: 'Text Field', // MISSING
-		textarea: 'Textarea', // MISSING
-		hiddenField: 'Hidden Field', // MISSING
-		button: 'Button',
-		select: 'Selection Field', // MISSING
-		imageButton: 'Image Button', // MISSING
-		notSet: '<nije podešeno>',
-		id: 'Id',
-		name: 'Naziv',
-		langDir: 'Smjer pisanja',
-		langDirLtr: 'S lijeva na desno (LTR)',
-		langDirRtl: 'S desna na lijevo (RTL)',
-		langCode: 'Jezièni kôd',
-		longDescr: 'Dugaèki opis URL-a',
-		cssClass: 'Klase CSS stilova',
-		advisoryTitle: 'Advisory title',
-		cssStyle: 'Stil',
-		ok: 'OK',
-		cancel: 'Odustani',
-		close: 'Close', // MISSING
-		preview: 'Prikaži',
-		resize: 'Resize', // MISSING
-		generalTab: 'General', // MISSING
-		advancedTab: 'Naprednije',
-		validateNumberFailed: 'This value is not a number.', // MISSING
-		confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
-		confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
-		options: 'Options', // MISSING
-		target: 'Prozor',
-		targetNew: 'New Window (_blank)', // MISSING
-		targetTop: 'Topmost Window (_top)', // MISSING
-		targetSelf: 'Same Window (_self)', // MISSING
-		targetParent: 'Parent Window (_parent)', // MISSING
-		langDirLTR: 'S lijeva na desno (LTR)',
-		langDirRTL: 'S desna na lijevo (RTL)',
-		styles: 'Stil',
-		cssClasses: 'Klase CSS stilova',
-		width: 'Širina',
-		height: 'Visina',
-		align: 'Poravnanje',
-		alignLeft: 'Lijevo',
-		alignRight: 'Desno',
-		alignCenter: 'Centar',
-		alignTop: 'Vrh',
-		alignMiddle: 'Sredina',
-		alignBottom: 'Dno',
-		invalidValue	: 'Invalid value.', // MISSING
-		invalidHeight: 'Height must be a number.', // MISSING
-		invalidWidth: 'Width must be a number.', // MISSING
-		invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
-		invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
-		invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
-		cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, unavailable</span>' // MISSING
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/ca.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Catalan language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'ca' ] = {
-	// ARIA description.
-	editor: 'Editor de text enriquit',
-	editorPanel: 'Panell de l\'editor de text enriquit',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Premeu ALT 0 per ajuda',
-
-		browseServer: 'Veure servidor',
-		url: 'URL',
-		protocol: 'Protocol',
-		upload: 'Puja',
-		uploadSubmit: 'Envia-la al servidor',
-		image: 'Imatge',
-		flash: 'Flash',
-		form: 'Formulari',
-		checkbox: 'Casella de verificació',
-		radio: 'Botó d\'opció',
-		textField: 'Camp de text',
-		textarea: 'Àrea de text',
-		hiddenField: 'Camp ocult',
-		button: 'Botó',
-		select: 'Camp de selecció',
-		imageButton: 'Botó d\'imatge',
-		notSet: '<no definit>',
-		id: 'Id',
-		name: 'Nom',
-		langDir: 'Direcció de l\'idioma',
-		langDirLtr: 'D\'esquerra a dreta (LTR)',
-		langDirRtl: 'De dreta a esquerra (RTL)',
-		langCode: 'Codi d\'idioma',
-		longDescr: 'Descripció llarga de la URL',
-		cssClass: 'Classes del full d\'estil',
-		advisoryTitle: 'Títol consultiu',
-		cssStyle: 'Estil',
-		ok: 'D\'acord',
-		cancel: 'Cancel·la',
-		close: 'Tanca',
-		preview: 'Previsualitza',
-		resize: 'Arrossegueu per redimensionar',
-		generalTab: 'General',
-		advancedTab: 'Avançat',
-		validateNumberFailed: 'Aquest valor no és un número.',
-		confirmNewPage: 'Els canvis en aquest contingut que no es desin es perdran. Esteu segur que voleu carregar una pàgina nova?',
-		confirmCancel: 'Algunes opcions s\'han canviat. Esteu segur que voleu tancar el quadre de diàleg?',
-		options: 'Opcions',
-		target: 'Destí',
-		targetNew: 'Nova finestra (_blank)',
-		targetTop: 'Finestra superior (_top)',
-		targetSelf: 'Mateixa finestra (_self)',
-		targetParent: 'Finestra pare (_parent)',
-		langDirLTR: 'D\'esquerra a dreta (LTR)',
-		langDirRTL: 'De dreta a esquerra (RTL)',
-		styles: 'Estil',
-		cssClasses: 'Classes del full d\'estil',
-		width: 'Amplada',
-		height: 'Alçada',
-		align: 'Alineació',
-		alignLeft: 'Ajusta a l\'esquerra',
-		alignRight: 'Ajusta a la dreta',
-		alignCenter: 'Centre',
-		alignTop: 'Superior',
-		alignMiddle: 'Centre',
-		alignBottom: 'Inferior',
-		invalidValue	: 'Valor no vàlid.',
-		invalidHeight: 'L\'alçada ha de ser un número.',
-		invalidWidth: 'L\'amplada ha de ser un número.',
-		invalidCssLength: 'El valor especificat per als "%1" camps ha de ser un número positiu amb o sense unitat de mesura vàlida de CSS (px, %, in, cm, mm, em, ex, pt o pc).',
-		invalidHtmlLength: 'El valor especificat per als "%1" camps ha de ser un número positiu amb o sense unitat de mesura vàlida d\'HTML (px o %).',
-		invalidInlineStyle: 'El valor especificat per l\'estil en línia ha de constar d\'una o més tuples amb el format "name: value", separats per punt i coma.',
-		cssLengthTooltip: 'Introduïu un número per un valor en píxels o un número amb una unitat vàlida de CSS (px, %, in, cm, mm, em, ex, pt o pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, no disponible</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/cs.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Czech language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'cs' ] = {
-	// ARIA description.
-	editor: 'Textový editor',
-	editorPanel: 'Panel textového editoru',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Stiskněte ALT 0 pro nápovědu',
-
-		browseServer: 'Vybrat na serveru',
-		url: 'URL',
-		protocol: 'Protokol',
-		upload: 'Odeslat',
-		uploadSubmit: 'Odeslat na server',
-		image: 'Obrázek',
-		flash: 'Flash',
-		form: 'Formulář',
-		checkbox: 'Zaškrtávací políčko',
-		radio: 'Přepínač',
-		textField: 'Textové pole',
-		textarea: 'Textová oblast',
-		hiddenField: 'Skryté pole',
-		button: 'Tlačítko',
-		select: 'Seznam',
-		imageButton: 'Obrázkové tlačítko',
-		notSet: '<nenastaveno>',
-		id: 'Id',
-		name: 'Jméno',
-		langDir: 'Směr jazyka',
-		langDirLtr: 'Zleva doprava (LTR)',
-		langDirRtl: 'Zprava doleva (RTL)',
-		langCode: 'Kód jazyka',
-		longDescr: 'Dlouhý popis URL',
-		cssClass: 'Třída stylu',
-		advisoryTitle: 'Pomocný titulek',
-		cssStyle: 'Styl',
-		ok: 'OK',
-		cancel: 'Zrušit',
-		close: 'Zavřít',
-		preview: 'Náhled',
-		resize: 'Uchopit pro změnu velikosti',
-		generalTab: 'Obecné',
-		advancedTab: 'Rozšířené',
-		validateNumberFailed: 'Zadaná hodnota není číselná.',
-		confirmNewPage: 'Jakékoliv neuložené změny obsahu budou ztraceny. Skutečně chcete otevřít novou stránku?',
-		confirmCancel: 'Některá z nastavení byla změněna. Skutečně chcete zavřít dialogové okno?',
-		options: 'Nastavení',
-		target: 'Cíl',
-		targetNew: 'Nové okno (_blank)',
-		targetTop: 'Okno nejvyšší úrovně (_top)',
-		targetSelf: 'Stejné okno (_self)',
-		targetParent: 'Rodičovské okno (_parent)',
-		langDirLTR: 'Zleva doprava (LTR)',
-		langDirRTL: 'Zprava doleva (RTL)',
-		styles: 'Styly',
-		cssClasses: 'Třídy stylů',
-		width: 'Šířka',
-		height: 'Výška',
-		align: 'Zarovnání',
-		alignLeft: 'Vlevo',
-		alignRight: 'Vpravo',
-		alignCenter: 'Na střed',
-		alignTop: 'Nahoru',
-		alignMiddle: 'Na střed',
-		alignBottom: 'Dolů',
-		invalidValue	: 'Neplatná hodnota.',
-		invalidHeight: 'Zadaná výška musí být číslo.',
-		invalidWidth: 'Šířka musí být číslo.',
-		invalidCssLength: 'Hodnota určená pro pole "%1" musí být kladné číslo bez nebo s platnou jednotkou míry CSS (px, %, in, cm, mm, em, ex, pt, nebo pc).',
-		invalidHtmlLength: 'Hodnota určená pro pole "%1" musí být kladné číslo bez nebo s platnou jednotkou míry HTML (px nebo %).',
-		invalidInlineStyle: 'Hodnota určená pro řádkový styl se musí skládat z jedné nebo více n-tic ve formátu "název : hodnota", oddělené středníky',
-		cssLengthTooltip: 'Zadejte číslo jako hodnotu v pixelech nebo číslo s platnou jednotkou CSS (px, %, v cm, mm, em, ex, pt, nebo pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, nedostupné</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/cy.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Welsh language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'cy' ] = {
-	// ARIA description.
-	editor: 'Golygydd Testun Cyfoethog',
-	editorPanel: 'Panel Golygydd Testun Cyfoethog',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Gwasgwch ALT 0 am gymorth',
-
-		browseServer: 'Pori\'r Gweinydd',
-		url: 'URL',
-		protocol: 'Protocol',
-		upload: 'Lanlwytho',
-		uploadSubmit: 'Anfon i\'r Gweinydd',
-		image: 'Delwedd',
-		flash: 'Flash',
-		form: 'Ffurflen',
-		checkbox: 'Blwch ticio',
-		radio: 'Botwm Radio',
-		textField: 'Maes Testun',
-		textarea: 'Ardal Testun',
-		hiddenField: 'Maes Cudd',
-		button: 'Botwm',
-		select: 'Maes Dewis',
-		imageButton: 'Botwm Delwedd',
-		notSet: '<heb osod>',
-		id: 'Id',
-		name: 'Name',
-		langDir: 'Cyfeiriad Iaith',
-		langDirLtr: 'Chwith i\'r Dde (LTR)',
-		langDirRtl: 'Dde i\'r Chwith (RTL)',
-		langCode: 'Cod Iaith',
-		longDescr: 'URL Disgrifiad Hir',
-		cssClass: 'Dosbarthiadau Dalen Arddull',
-		advisoryTitle: 'Teitl Cynghorol',
-		cssStyle: 'Arddull',
-		ok: 'Iawn',
-		cancel: 'Diddymu',
-		close: 'Cau',
-		preview: 'Rhagolwg',
-		resize: 'Ailfeintio',
-		generalTab: 'Cyffredinol',
-		advancedTab: 'Uwch',
-		validateNumberFailed: '\'Dyw\'r gwerth hwn ddim yn rhif.',
-		confirmNewPage: 'Byddwch chi\'n colli unrhyw newidiadau i\'r cynnwys sydd heb eu cadw. Ydych am barhau i lwytho tudalen newydd?',
-		confirmCancel: 'Cafodd rhai o\'r opsiynau eu newid. Ydych chi wir am gau\'r deialog?',
-		options: 'Opsiynau',
-		target: 'Targed',
-		targetNew: 'Ffenest Newydd (_blank)',
-		targetTop: 'Ffenest ar y Brig (_top)',
-		targetSelf: 'Yr un Ffenest (_self)',
-		targetParent: 'Ffenest y Rhiant (_parent)',
-		langDirLTR: 'Chwith i\'r Dde (LTR)',
-		langDirRTL: 'Dde i\'r Chwith (RTL)',
-		styles: 'Arddull',
-		cssClasses: 'Dosbarthiadau Dalen Arddull',
-		width: 'Lled',
-		height: 'Uchder',
-		align: 'Alinio',
-		alignLeft: 'Chwith',
-		alignRight: 'Dde',
-		alignCenter: 'Canol',
-		alignTop: 'Brig',
-		alignMiddle: 'Canol',
-		alignBottom: 'Gwaelod',
-		invalidValue	: 'Gwerth annilys.',
-		invalidHeight: 'Mae\'n rhaid i\'r uchder fod yn rhif.',
-		invalidWidth: 'Mae\'n rhaid i\'r lled fod yn rhif.',
-		invalidCssLength: 'Mae\'n rhaid i\'r gwerth ar gyfer maes "%1" fod yn rhif positif gyda neu heb uned fesuriad CSS dilys (px, %, in, cm, mm, em, ex, pt, neu pc).',
-		invalidHtmlLength: 'Mae\'n rhaid i\'r gwerth ar gyfer maes "%1" fod yn rhif positif gyda neu heb uned fesuriad HTML dilys (px neu %).',
-		invalidInlineStyle: 'Mae\'n rhaid i\'r gwerth ar gyfer arddull mewn-llinell gynnwys un set neu fwy ar y fformat "enw : gwerth", wedi\'u gwahanu gyda hanner colon.',
-		cssLengthTooltip: 'Rhowch rif am werth mewn picsel neu rhif gydag uned CSS dilys (px, %, in, cm, mm, em, pt neu pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, ddim ar gael</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/da.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Danish language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'da' ] = {
-	// ARIA description.
-	editor: 'Rich Text Editor',
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Tryk ALT 0 for hjælp',
-
-		browseServer: 'Gennemse...',
-		url: 'URL',
-		protocol: 'Protokol',
-		upload: 'Upload',
-		uploadSubmit: 'Upload',
-		image: 'Indsæt billede',
-		flash: 'Indsæt Flash',
-		form: 'Indsæt formular',
-		checkbox: 'Indsæt afkrydsningsfelt',
-		radio: 'Indsæt alternativknap',
-		textField: 'Indsæt tekstfelt',
-		textarea: 'Indsæt tekstboks',
-		hiddenField: 'Indsæt skjult felt',
-		button: 'Indsæt knap',
-		select: 'Indsæt liste',
-		imageButton: 'Indsæt billedknap',
-		notSet: '<intet valgt>',
-		id: 'Id',
-		name: 'Navn',
-		langDir: 'Tekstretning',
-		langDirLtr: 'Fra venstre mod højre (LTR)',
-		langDirRtl: 'Fra højre mod venstre (RTL)',
-		langCode: 'Sprogkode',
-		longDescr: 'Udvidet beskrivelse',
-		cssClass: 'Typografiark (CSS)',
-		advisoryTitle: 'Titel',
-		cssStyle: 'Typografi (CSS)',
-		ok: 'OK',
-		cancel: 'Annullér',
-		close: 'Luk',
-		preview: 'Forhåndsvisning',
-		resize: 'Træk for at skalere',
-		generalTab: 'Generelt',
-		advancedTab: 'Avanceret',
-		validateNumberFailed: 'Værdien er ikke et tal.',
-		confirmNewPage: 'Alt indhold, der ikke er blevet gemt, vil gå tabt. Er du sikker på, at du vil indlæse en ny side?',
-		confirmCancel: 'Nogle af indstillingerne er blevet ændret. Er du sikker på, at du vil lukke vinduet?',
-		options: 'Vis muligheder',
-		target: 'Mål',
-		targetNew: 'Nyt vindue (_blank)',
-		targetTop: 'Øverste vindue (_top)',
-		targetSelf: 'Samme vindue (_self)',
-		targetParent: 'Samme vindue (_parent)',
-		langDirLTR: 'Venstre til højre (LTR)',
-		langDirRTL: 'Højre til venstre (RTL)',
-		styles: 'Style',
-		cssClasses: 'Stylesheetklasser',
-		width: 'Bredde',
-		height: 'Højde',
-		align: 'Justering',
-		alignLeft: 'Venstre',
-		alignRight: 'Højre',
-		alignCenter: 'Centreret',
-		alignTop: 'Øverst',
-		alignMiddle: 'Centreret',
-		alignBottom: 'Nederst',
-		invalidValue	: 'Invalid value.', // MISSING
-		invalidHeight: 'Højde skal være et tal.',
-		invalidWidth: 'Bredde skal være et tal.',
-		invalidCssLength: 'Værdien specificeret for "%1" feltet skal være et positivt nummer med eller uden en CSS måleenhed  (px, %, in, cm, mm, em, ex, pt, eller pc).',
-		invalidHtmlLength: 'Værdien specificeret for "%1" feltet skal være et positivt nummer med eller uden en CSS måleenhed  (px eller %).',
-		invalidInlineStyle: 'Værdien specificeret for inline style skal indeholde en eller flere elementer med et format som "name:value", separeret af semikoloner',
-		cssLengthTooltip: 'Indsæt en numerisk værdi i pixel eller nummer med en gyldig CSS værdi (px, %, in, cm, mm, em, ex, pt, eller pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, ikke tilgængelig</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/de.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * German language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'de' ] = {
-	// ARIA description.
-	editor: 'WYSIWYG-Editor',
-	editorPanel: 'WYSIWYG-Editor-Leiste',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Drücken Sie ALT 0 für Hilfe',
-
-		browseServer: 'Server durchsuchen',
-		url: 'URL',
-		protocol: 'Protokoll',
-		upload: 'Hochladen',
-		uploadSubmit: 'Zum Server senden',
-		image: 'Bild',
-		flash: 'Flash',
-		form: 'Formular',
-		checkbox: 'Checkbox',
-		radio: 'Radiobutton',
-		textField: 'Textfeld einzeilig',
-		textarea: 'Textfeld mehrzeilig',
-		hiddenField: 'Verstecktes Feld',
-		button: 'Klickbutton',
-		select: 'Auswahlfeld',
-		imageButton: 'Bildbutton',
-		notSet: '<nichts>',
-		id: 'ID',
-		name: 'Name',
-		langDir: 'Schreibrichtung',
-		langDirLtr: 'Links nach Rechts (LTR)',
-		langDirRtl: 'Rechts nach Links (RTL)',
-		langCode: 'Sprachenkürzel',
-		longDescr: 'Langform URL',
-		cssClass: 'Stylesheet Klasse',
-		advisoryTitle: 'Titel Beschreibung',
-		cssStyle: 'Style',
-		ok: 'OK',
-		cancel: 'Abbrechen',
-		close: 'Schließen',
-		preview: 'Vorschau',
-		resize: 'Zum Vergrößern ziehen',
-		generalTab: 'Allgemein',
-		advancedTab: 'Erweitert',
-		validateNumberFailed: 'Dieser Wert ist keine Nummer.',
-		confirmNewPage: 'Alle nicht gespeicherten Änderungen gehen verlohren. Sind Sie sicher die neue Seite zu laden?',
-		confirmCancel: 'Einige Optionen wurden geändert. Wollen Sie den Dialog dennoch schließen?',
-		options: 'Optionen',
-		target: 'Zielseite',
-		targetNew: 'Neues Fenster (_blank)',
-		targetTop: 'Oberstes Fenster (_top)',
-		targetSelf: 'Gleiches Fenster (_self)',
-		targetParent: 'Oberes Fenster (_parent)',
-		langDirLTR: 'Links nach Rechts (LNR)',
-		langDirRTL: 'Rechts nach Links (RNL)',
-		styles: 'Style',
-		cssClasses: 'Stylesheet Klasse',
-		width: 'Breite',
-		height: 'Höhe',
-		align: 'Ausrichtung',
-		alignLeft: 'Links',
-		alignRight: 'Rechts',
-		alignCenter: 'Zentriert',
-		alignTop: 'Oben',
-		alignMiddle: 'Mitte',
-		alignBottom: 'Unten',
-		invalidValue	: 'Ungültiger Wert.',
-		invalidHeight: 'Höhe muss eine Zahl sein.',
-		invalidWidth: 'Breite muss eine Zahl sein.',
-		invalidCssLength: 'Wert spezifiziert für "%1" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekte CSS Messeinheit (px, %, in, cm, mm, em, ex, pt oder pc).',
-		invalidHtmlLength: 'Wert spezifiziert für "%1" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekte HTML Messeinheit (px oder %).',
-		invalidInlineStyle: 'Wert spezifiziert für inline Stilart muss enthalten ein oder mehr Tupels mit dem Format "Name : Wert" getrennt mit Semikolons.',
-		cssLengthTooltip: 'Gebe eine Zahl ein für ein Wert in pixels oder eine Zahl mit einer korrekten CSS Messeinheit (px, %, in, cm, mm, em, ex, pt oder pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, nicht verfügbar</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/el.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Greek language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'el' ] = {
-	// ARIA description.
-	editor: 'Επεξεργαστής Πλούσιου Κειμένου',
-	editorPanel: 'Πίνακας Επεξεργαστή Πλούσιου Κειμένου',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Πατήστε το ALT 0 για βοήθεια',
-
-		browseServer: 'Εξερεύνηση Διακομιστή',
-		url: 'URL',
-		protocol: 'Πρωτόκολλο',
-		upload: 'Αποστολή',
-		uploadSubmit: 'Αποστολή στον Διακομιστή',
-		image: 'Εικόνα',
-		flash: 'Flash',
-		form: 'Φόρμα',
-		checkbox: 'Κουτί Επιλογής',
-		radio: 'Κουμπί Επιλογής',
-		textField: 'Πεδίο Κειμένου',
-		textarea: 'Περιοχή Κειμένου',
-		hiddenField: 'Κρυφό Πεδίο',
-		button: 'Κουμπί',
-		select: 'Πεδίο Επιλογής',
-		imageButton: 'Κουμπί Εικόνας',
-		notSet: '<δεν έχει ρυθμιστεί>',
-		id: 'Id',
-		name: 'Όνομα',
-		langDir: 'Κατεύθυνση Κειμένου',
-		langDirLtr: 'Αριστερά προς Δεξιά (LTR)',
-		langDirRtl: 'Δεξιά προς Αριστερά (RTL)',
-		langCode: 'Κωδικός Γλώσσας',
-		longDescr: 'Αναλυτική Περιγραφή URL',
-		cssClass: 'Κλάσεις Φύλλων Στυλ',
-		advisoryTitle: 'Ενδεικτικός Τίτλος',
-		cssStyle: 'Μορφή Κειμένου',
-		ok: 'OK',
-		cancel: 'Ακύρωση',
-		close: 'Κλείσιμο',
-		preview: 'Προεπισκόπηση',
-		resize: 'Αλλαγή Μεγέθους',
-		generalTab: 'Γενικά',
-		advancedTab: 'Για Προχωρημένους',
-		validateNumberFailed: 'Αυτή η τιμή δεν είναι αριθμός.',
-		confirmNewPage: 'Οι όποιες αλλαγές στο περιεχόμενο θα χαθούν. Είσαστε σίγουροι ότι θέλετε να φορτώσετε μια νέα σελίδα;',
-		confirmCancel: 'Μερικές επιλογές έχουν αλλάξει. Είσαστε σίγουροι ότι θέλετε να κλείσετε το παράθυρο διαλόγου;',
-		options: 'Επιλογές',
-		target: 'Προορισμός',
-		targetNew: 'Νέο Παράθυρο (_blank)',
-		targetTop: 'Αρχική Περιοχή (_top)',
-		targetSelf: 'Ίδιο Παράθυρο (_self)',
-		targetParent: 'Γονεϊκό Παράθυρο (_parent)',
-		langDirLTR: 'Αριστερά προς Δεξιά (LTR)',
-		langDirRTL: 'Δεξιά προς Αριστερά (RTL)',
-		styles: 'Μορφή',
-		cssClasses: 'Κλάσεις Φύλλων Στυλ',
-		width: 'Πλάτος',
-		height: 'Ύψος',
-		align: 'Στοίχιση',
-		alignLeft: 'Αριστερά',
-		alignRight: 'Δεξιά',
-		alignCenter: 'Κέντρο',
-		alignTop: 'Πάνω',
-		alignMiddle: 'Μέση',
-		alignBottom: 'Κάτω',
-		invalidValue	: 'Μη έγκυρη τιμή.',
-		invalidHeight: 'Το ύψος πρέπει να είναι ένας αριθμός.',
-		invalidWidth: 'Το πλάτος πρέπει να είναι ένας αριθμός.',
-		invalidCssLength: 'Η τιμή που ορίζεται για το πεδίο "%1" πρέπει να είναι ένας θετικός αριθμός με ή χωρίς μια έγκυρη μονάδα μέτρησης CSS (px, %, in, cm, mm, em, ex, pt, ή pc).',
-		invalidHtmlLength: 'Η τιμή που ορίζεται για το πεδίο "%1" πρέπει να είναι ένας θετικός αριθμός με ή χωρίς μια έγκυρη μονάδα μέτρησης HTML (px ή %).',
-		invalidInlineStyle: 'Η τιμή για το εν σειρά στυλ πρέπει να περιέχει ένα ή περισσότερα ζεύγη με την μορφή "όνομα: τιμή" διαχωρισμένα με Ελληνικό ερωτηματικό.',
-		cssLengthTooltip: 'Εισάγεται μια τιμή σε pixel ή έναν αριθμό μαζί με μια έγκυρη μονάδα μέτρησης CSS (px, %, in, cm, mm, em, ex, pt, ή pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, δεν είναι διαθέσιμο</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/en-au.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * English (Australia) language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'en-au' ] = {
-	// ARIA description.
-	editor: 'Rich Text Editor',
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Press ALT 0 for help', // MISSING
-
-		browseServer: 'Browse Server',
-		url: 'URL',
-		protocol: 'Protocol',
-		upload: 'Upload',
-		uploadSubmit: 'Send it to the Server',
-		image: 'Image',
-		flash: 'Flash',
-		form: 'Form',
-		checkbox: 'Checkbox',
-		radio: 'Radio Button',
-		textField: 'Text Field',
-		textarea: 'Textarea',
-		hiddenField: 'Hidden Field',
-		button: 'Button',
-		select: 'Selection Field',
-		imageButton: 'Image Button',
-		notSet: '<not set>',
-		id: 'Id',
-		name: 'Name',
-		langDir: 'Language Direction',
-		langDirLtr: 'Left to Right (LTR)',
-		langDirRtl: 'Right to Left (RTL)',
-		langCode: 'Language Code',
-		longDescr: 'Long Description URL',
-		cssClass: 'Stylesheet Classes',
-		advisoryTitle: 'Advisory Title',
-		cssStyle: 'Style',
-		ok: 'OK',
-		cancel: 'Cancel',
-		close: 'Close', // MISSING
-		preview: 'Preview',
-		resize: 'Resize', // MISSING
-		generalTab: 'General',
-		advancedTab: 'Advanced',
-		validateNumberFailed: 'This value is not a number.',
-		confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
-		confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?',
-		options: 'Options', // MISSING
-		target: 'Target',
-		targetNew: 'New Window (_blank)', // MISSING
-		targetTop: 'Topmost Window (_top)', // MISSING
-		targetSelf: 'Same Window (_self)', // MISSING
-		targetParent: 'Parent Window (_parent)', // MISSING
-		langDirLTR: 'Left to Right (LTR)',
-		langDirRTL: 'Right to Left (RTL)',
-		styles: 'Style',
-		cssClasses: 'Stylesheet Classes',
-		width: 'Width', // MISSING
-		height: 'Height', // MISSING
-		align: 'Align',
-		alignLeft: 'Left', // MISSING
-		alignRight: 'Right', // MISSING
-		alignCenter: 'Centre',
-		alignTop: 'Top', // MISSING
-		alignMiddle: 'Middle', // MISSING
-		alignBottom: 'Bottom', // MISSING
-		invalidValue	: 'Invalid value.', // MISSING
-		invalidHeight: 'Height must be a number.', // MISSING
-		invalidWidth: 'Width must be a number.', // MISSING
-		invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
-		invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
-		invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
-		cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, unavailable</span>' // MISSING
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/en-ca.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * English (Canadian) language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'en-ca' ] = {
-	// ARIA description.
-	editor: 'Rich Text Editor', // MISSING
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Press ALT 0 for help', // MISSING
-
-		browseServer: 'Browse Server',
-		url: 'URL',
-		protocol: 'Protocol',
-		upload: 'Upload',
-		uploadSubmit: 'Send it to the Server',
-		image: 'Image',
-		flash: 'Flash',
-		form: 'Form',
-		checkbox: 'Checkbox',
-		radio: 'Radio Button',
-		textField: 'Text Field',
-		textarea: 'Textarea',
-		hiddenField: 'Hidden Field',
-		button: 'Button',
-		select: 'Selection Field',
-		imageButton: 'Image Button',
-		notSet: '<not set>',
-		id: 'Id',
-		name: 'Name',
-		langDir: 'Language Direction',
-		langDirLtr: 'Left to Right (LTR)',
-		langDirRtl: 'Right to Left (RTL)',
-		langCode: 'Language Code',
-		longDescr: 'Long Description URL',
-		cssClass: 'Stylesheet Classes',
-		advisoryTitle: 'Advisory Title',
-		cssStyle: 'Style',
-		ok: 'OK',
-		cancel: 'Cancel',
-		close: 'Close', // MISSING
-		preview: 'Preview',
-		resize: 'Resize', // MISSING
-		generalTab: 'General',
-		advancedTab: 'Advanced',
-		validateNumberFailed: 'This value is not a number.',
-		confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
-		confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?',
-		options: 'Options', // MISSING
-		target: 'Target',
-		targetNew: 'New Window (_blank)', // MISSING
-		targetTop: 'Topmost Window (_top)', // MISSING
-		targetSelf: 'Same Window (_self)', // MISSING
-		targetParent: 'Parent Window (_parent)', // MISSING
-		langDirLTR: 'Left to Right (LTR)',
-		langDirRTL: 'Right to Left (RTL)',
-		styles: 'Style',
-		cssClasses: 'Stylesheet Classes',
-		width: 'Width', // MISSING
-		height: 'Height', // MISSING
-		align: 'Align',
-		alignLeft: 'Left', // MISSING
-		alignRight: 'Right', // MISSING
-		alignCenter: 'Centre',
-		alignTop: 'Top', // MISSING
-		alignMiddle: 'Middle', // MISSING
-		alignBottom: 'Bottom', // MISSING
-		invalidValue	: 'Invalid value.', // MISSING
-		invalidHeight: 'Height must be a number.', // MISSING
-		invalidWidth: 'Width must be a number.', // MISSING
-		invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
-		invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
-		invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
-		cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, unavailable</span>' // MISSING
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/en-gb.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * English (United Kingdom) language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'en-gb' ] = {
-	// ARIA description.
-	editor: 'Rich Text Editor',
-	editorPanel: 'Rich Text Editor panel',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Press ALT 0 for help',
-
-		browseServer: 'Browse Server',
-		url: 'URL',
-		protocol: 'Protocol',
-		upload: 'Upload',
-		uploadSubmit: 'Send it to the Server',
-		image: 'Image',
-		flash: 'Flash',
-		form: 'Form',
-		checkbox: 'Checkbox',
-		radio: 'Radio Button',
-		textField: 'Text Field',
-		textarea: 'Textarea',
-		hiddenField: 'Hidden Field',
-		button: 'Button',
-		select: 'Selection Field',
-		imageButton: 'Image Button',
-		notSet: '<not set>',
-		id: 'Id',
-		name: 'Name',
-		langDir: 'Language Direction',
-		langDirLtr: 'Left to Right (LTR)',
-		langDirRtl: 'Right to Left (RTL)',
-		langCode: 'Language Code',
-		longDescr: 'Long Description URL',
-		cssClass: 'Stylesheet Classes',
-		advisoryTitle: 'Advisory Title',
-		cssStyle: 'Style',
-		ok: 'OK',
-		cancel: 'Cancel',
-		close: 'Close',
-		preview: 'Preview',
-		resize: 'Drag to resize',
-		generalTab: 'General',
-		advancedTab: 'Advanced',
-		validateNumberFailed: 'This value is not a number.',
-		confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
-		confirmCancel: 'You have changed some options. Are you sure you want to close the dialogue window?',
-		options: 'Options',
-		target: 'Target',
-		targetNew: 'New Window (_blank)',
-		targetTop: 'Topmost Window (_top)',
-		targetSelf: 'Same Window (_self)',
-		targetParent: 'Parent Window (_parent)',
-		langDirLTR: 'Left to Right (LTR)',
-		langDirRTL: 'Right to Left (RTL)',
-		styles: 'Style',
-		cssClasses: 'Stylesheet Classes',
-		width: 'Width',
-		height: 'Height',
-		align: 'Align',
-		alignLeft: 'Left',
-		alignRight: 'Right',
-		alignCenter: 'Centre',
-		alignTop: 'Top',
-		alignMiddle: 'Middle',
-		alignBottom: 'Bottom',
-		invalidValue	: 'Invalid value.',
-		invalidHeight: 'Height must be a number.',
-		invalidWidth: 'Width must be a number.',
-		invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).',
-		invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).',
-		invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.',
-		cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, unavailable</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/en.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object for the English
- *		language. This is the base file for all translations.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'en' ] = {
-	// ARIA description.
-	editor: 'Rich Text Editor',
-	editorPanel: 'Rich Text Editor panel',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Press ALT 0 for help',
-
-		browseServer: 'Browse Server',
-		url: 'URL',
-		protocol: 'Protocol',
-		upload: 'Upload',
-		uploadSubmit: 'Send it to the Server',
-		image: 'Image',
-		flash: 'Flash',
-		form: 'Form',
-		checkbox: 'Checkbox',
-		radio: 'Radio Button',
-		textField: 'Text Field',
-		textarea: 'Textarea',
-		hiddenField: 'Hidden Field',
-		button: 'Button',
-		select: 'Selection Field',
-		imageButton: 'Image Button',
-		notSet: '<not set>',
-		id: 'Id',
-		name: 'Name',
-		langDir: 'Language Direction',
-		langDirLtr: 'Left to Right (LTR)',
-		langDirRtl: 'Right to Left (RTL)',
-		langCode: 'Language Code',
-		longDescr: 'Long Description URL',
-		cssClass: 'Stylesheet Classes',
-		advisoryTitle: 'Advisory Title',
-		cssStyle: 'Style',
-		ok: 'OK',
-		cancel: 'Cancel',
-		close: 'Close',
-		preview: 'Preview',
-		resize: 'Resize',
-		generalTab: 'General',
-		advancedTab: 'Advanced',
-		validateNumberFailed: 'This value is not a number.',
-		confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
-		confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?',
-		options: 'Options',
-		target: 'Target',
-		targetNew: 'New Window (_blank)',
-		targetTop: 'Topmost Window (_top)',
-		targetSelf: 'Same Window (_self)',
-		targetParent: 'Parent Window (_parent)',
-		langDirLTR: 'Left to Right (LTR)',
-		langDirRTL: 'Right to Left (RTL)',
-		styles: 'Style',
-		cssClasses: 'Stylesheet Classes',
-		width: 'Width',
-		height: 'Height',
-		align: 'Alignment',
-		alignLeft: 'Left',
-		alignRight: 'Right',
-		alignCenter: 'Center',
-		alignTop: 'Top',
-		alignMiddle: 'Middle',
-		alignBottom: 'Bottom',
-		invalidValue	: 'Invalid value.',
-		invalidHeight: 'Height must be a number.',
-		invalidWidth: 'Width must be a number.',
-		invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).',
-		invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).',
-		invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.',
-		cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, unavailable</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/eo.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Esperanto language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'eo' ] = {
-	// ARIA description.
-	editor: 'Redaktilo por Riĉiga Teksto',
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Premu ALT 0 por helpilo',
-
-		browseServer: 'Foliumi en la Servilo',
-		url: 'URL',
-		protocol: 'Protokolo',
-		upload: 'Alŝuti',
-		uploadSubmit: 'Sendu al Servilo',
-		image: 'Bildo',
-		flash: 'Flaŝo',
-		form: 'Formularo',
-		checkbox: 'Markobutono',
-		radio: 'Radiobutono',
-		textField: 'Teksta kampo',
-		textarea: 'Teksta Areo',
-		hiddenField: 'Kaŝita Kampo',
-		button: 'Butono',
-		select: 'Elekta Kampo',
-		imageButton: 'Bildbutono',
-		notSet: '<Defaŭlta>',
-		id: 'Id',
-		name: 'Nomo',
-		langDir: 'Skribdirekto',
-		langDirLtr: 'De maldekstro dekstren (LTR)',
-		langDirRtl: 'De dekstro maldekstren (RTL)',
-		langCode: 'Lingva Kodo',
-		longDescr: 'URL de Longa Priskribo',
-		cssClass: 'Klasoj de Stilfolioj',
-		advisoryTitle: 'Priskriba Titolo',
-		cssStyle: 'Stilo',
-		ok: 'Akcepti',
-		cancel: 'Rezigni',
-		close: 'Fermi',
-		preview: 'Vidigi Aspekton',
-		resize: 'Movigi por ŝanĝi la grandon',
-		generalTab: 'Ĝenerala',
-		advancedTab: 'Speciala',
-		validateNumberFailed: 'Tiu valoro ne estas nombro.',
-		confirmNewPage: 'La neregistritaj ŝanĝoj estas perdotaj. Ĉu vi certas, ke vi volas ŝargi novan paĝon?',
-		confirmCancel: 'Iuj opcioj esta ŝanĝitaj. Ĉu vi certas, ke vi volas fermi la dialogon?',
-		options: 'Opcioj',
-		target: 'Celo',
-		targetNew: 'Nova Fenestro (_blank)',
-		targetTop: 'Supra Fenestro (_top)',
-		targetSelf: 'Sama Fenestro (_self)',
-		targetParent: 'Patra Fenestro (_parent)',
-		langDirLTR: 'De maldekstro dekstren (LTR)',
-		langDirRTL: 'De dekstro maldekstren (RTL)',
-		styles: 'Stilo',
-		cssClasses: 'Stilfoliaj Klasoj',
-		width: 'Larĝo',
-		height: 'Alto',
-		align: 'Ĝisrandigo',
-		alignLeft: 'Maldekstre',
-		alignRight: 'Dekstre',
-		alignCenter: 'Centre',
-		alignTop: 'Supre',
-		alignMiddle: 'Centre',
-		alignBottom: 'Malsupre',
-		invalidValue	: 'Nevalida Valoro',
-		invalidHeight: 'Alto devas esti nombro.',
-		invalidWidth: 'Larĝo devas esti nombro.',
-		invalidCssLength: 'La valoro indikita por la "%1" kampo devas esti pozitiva nombro kun aŭ sen valida CSSmezurunuo (px, %, in, cm, mm, em, ex, pt, or pc).',
-		invalidHtmlLength: 'La valoro indikita por la "%1" kampo devas esti pozitiva nombro kun aŭ sen valida HTMLmezurunuo (px or %).',
-		invalidInlineStyle: 'La valoro indikita por la enlinia stilo devas konsisti el unu aŭ pluraj elementoj kun la formato de "nomo : valoro", apartigitaj per punktokomoj.',
-		cssLengthTooltip: 'Entajpu nombron por rastrumera valoro aŭ nombron kun valida CSSunuo (px, %, in, cm, mm, em, ex, pt, or pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, nehavebla</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/es.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Spanish language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'es' ] = {
-	// ARIA description.
-	editor: 'Editor de texto enriquecido',
-	editorPanel: 'Panel del Editor de Texto Enriquecido',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Pulse ALT 0 para ayuda',
-
-		browseServer: 'Ver Servidor',
-		url: 'URL',
-		protocol: 'Protocolo',
-		upload: 'Cargar',
-		uploadSubmit: 'Enviar al Servidor',
-		image: 'Imagen',
-		flash: 'Flash',
-		form: 'Formulario',
-		checkbox: 'Casilla de Verificación',
-		radio: 'Botones de Radio',
-		textField: 'Campo de Texto',
-		textarea: 'Area de Texto',
-		hiddenField: 'Campo Oculto',
-		button: 'Botón',
-		select: 'Campo de Selección',
-		imageButton: 'Botón Imagen',
-		notSet: '<No definido>',
-		id: 'Id',
-		name: 'Nombre',
-		langDir: 'Orientación',
-		langDirLtr: 'Izquierda a Derecha (LTR)',
-		langDirRtl: 'Derecha a Izquierda (RTL)',
-		langCode: 'Cód. de idioma',
-		longDescr: 'Descripción larga URL',
-		cssClass: 'Clases de hojas de estilo',
-		advisoryTitle: 'Título',
-		cssStyle: 'Estilo',
-		ok: 'Aceptar',
-		cancel: 'Cancelar',
-		close: 'Cerrar',
-		preview: 'Previsualización',
-		resize: 'Arrastre para redimensionar',
-		generalTab: 'General',
-		advancedTab: 'Avanzado',
-		validateNumberFailed: 'El valor no es un número.',
-		confirmNewPage: 'Cualquier cambio que no se haya guardado se perderá.\r\n¿Está seguro de querer crear una nueva página?',
-		confirmCancel: 'Algunas de las opciones se han cambiado.\r\n¿Está seguro de querer cerrar el diálogo?',
-		options: 'Opciones',
-		target: 'Destino',
-		targetNew: 'Nueva ventana (_blank)',
-		targetTop: 'Ventana principal (_top)',
-		targetSelf: 'Misma ventana (_self)',
-		targetParent: 'Ventana padre (_parent)',
-		langDirLTR: 'Izquierda a derecha (LTR)',
-		langDirRTL: 'Derecha a izquierda (RTL)',
-		styles: 'Estilos',
-		cssClasses: 'Clase de la hoja de estilos',
-		width: 'Anchura',
-		height: 'Altura',
-		align: 'Alineación',
-		alignLeft: 'Izquierda',
-		alignRight: 'Derecha',
-		alignCenter: 'Centrado',
-		alignTop: 'Tope',
-		alignMiddle: 'Centro',
-		alignBottom: 'Pie',
-		invalidValue	: 'Valor no válido',
-		invalidHeight: 'Altura debe ser un número.',
-		invalidWidth: 'Anchura debe ser un número.',
-		invalidCssLength: 'El valor especificado para el campo "%1" debe ser un número positivo, incluyendo optionalmente una unidad de medida CSS válida (px, %, in, cm, mm, em, ex, pt, o pc).',
-		invalidHtmlLength: 'El valor especificado para el campo "%1" debe ser un número positivo, incluyendo optionalmente una unidad de medida HTML válida (px o %).',
-		invalidInlineStyle: 'El valor especificado para el estilo debe consistir en uno o más pares con el formato "nombre: valor", separados por punto y coma.',
-		cssLengthTooltip: 'Introduca un número para el valor en pixels o un número con una unidad de medida CSS válida (px, %, in, cm, mm, em, ex, pt, o pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, no disponible</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/et.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Estonian language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'et' ] = {
-	// ARIA description.
-	editor: 'Rikkalik tekstiredaktor',
-	editorPanel: 'Rikkaliku tekstiredaktori paneel',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Abi saamiseks vajuta ALT 0',
-
-		browseServer: 'Serveri sirvimine',
-		url: 'URL',
-		protocol: 'Protokoll',
-		upload: 'Laadi üles',
-		uploadSubmit: 'Saada serverisse',
-		image: 'Pilt',
-		flash: 'Flash',
-		form: 'Vorm',
-		checkbox: 'Märkeruut',
-		radio: 'Raadionupp',
-		textField: 'Tekstilahter',
-		textarea: 'Tekstiala',
-		hiddenField: 'Varjatud lahter',
-		button: 'Nupp',
-		select: 'Valiklahter',
-		imageButton: 'Piltnupp',
-		notSet: '<määramata>',
-		id: 'ID',
-		name: 'Nimi',
-		langDir: 'Keele suund',
-		langDirLtr: 'Vasakult paremale (LTR)',
-		langDirRtl: 'Paremalt vasakule (RTL)',
-		langCode: 'Keele kood',
-		longDescr: 'Pikk kirjeldus URL',
-		cssClass: 'Stiilistiku klassid',
-		advisoryTitle: 'Soovituslik pealkiri',
-		cssStyle: 'Laad',
-		ok: 'Olgu',
-		cancel: 'Loobu',
-		close: 'Sulge',
-		preview: 'Eelvaade',
-		resize: 'Suuruse muutmiseks lohista',
-		generalTab: 'Üldine',
-		advancedTab: 'Täpsemalt',
-		validateNumberFailed: 'See väärtus pole number.',
-		confirmNewPage: 'Kõik salvestamata muudatused lähevad kaotsi. Kas oled kindel, et tahad laadida uue lehe?',
-		confirmCancel: 'Mõned valikud on muudetud. Kas oled kindel, et tahad dialoogi sulgeda?',
-		options: 'Valikud',
-		target: 'Sihtkoht',
-		targetNew: 'Uus aken (_blank)',
-		targetTop: 'Kõige ülemine aken (_top)',
-		targetSelf: 'Sama aken (_self)',
-		targetParent: 'Vanemaken (_parent)',
-		langDirLTR: 'Vasakult paremale (LTR)',
-		langDirRTL: 'Paremalt vasakule (RTL)',
-		styles: 'Stiili',
-		cssClasses: 'Stiililehe klassid',
-		width: 'Laius',
-		height: 'Kõrgus',
-		align: 'Joondus',
-		alignLeft: 'Vasak',
-		alignRight: 'Paremale',
-		alignCenter: 'Kesk',
-		alignTop: 'Üles',
-		alignMiddle: 'Keskele',
-		alignBottom: 'Alla',
-		invalidValue	: 'Vigane väärtus.',
-		invalidHeight: 'Kõrgus peab olema number.',
-		invalidWidth: 'Laius peab olema number.',
-		invalidCssLength: '"%1" välja jaoks määratud väärtus peab olema positiivne täisarv CSS ühikuga (px, %, in, cm, mm, em, ex, pt või pc) või ilma.',
-		invalidHtmlLength: '"%1" välja jaoks määratud väärtus peab olema positiivne täisarv HTML ühikuga (px või %) või ilma.',
-		invalidInlineStyle: 'Reasisese stiili määrangud peavad koosnema paarisväärtustest (tuples), mis on semikoolonitega eraldatult järgnevas vormingus: "nimi : väärtus".',
-		cssLengthTooltip: 'Sisesta väärtus pikslites või number koos sobiva CSS-i ühikuga (px, %, in, cm, mm, em, ex, pt või pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, pole saadaval</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/eu.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Basque language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'eu' ] = {
-	// ARIA description.
-	editor: 'Testu Aberastuko Editorea',
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'ALT 0 sakatu laguntza jasotzeko',
-
-		browseServer: 'Zerbitzaria arakatu',
-		url: 'URL',
-		protocol: 'Protokoloa',
-		upload: 'Gora kargatu',
-		uploadSubmit: 'Zerbitzarira bidali',
-		image: 'Irudia',
-		flash: 'Flasha',
-		form: 'Formularioa',
-		checkbox: 'Kontrol-laukia',
-		radio: 'Aukera-botoia',
-		textField: 'Testu Eremua',
-		textarea: 'Testu-area',
-		hiddenField: 'Ezkutuko Eremua',
-		button: 'Botoia',
-		select: 'Hautespen Eremua',
-		imageButton: 'Irudi Botoia',
-		notSet: '<Ezarri gabe>',
-		id: 'Id',
-		name: 'Izena',
-		langDir: 'Hizkuntzaren Norabidea',
-		langDirLtr: 'Ezkerretik Eskumara(LTR)',
-		langDirRtl: 'Eskumatik Ezkerrera (RTL)',
-		langCode: 'Hizkuntza Kodea',
-		longDescr: 'URL Deskribapen Luzea',
-		cssClass: 'Estilo-orriko Klaseak',
-		advisoryTitle: 'Izenburua',
-		cssStyle: 'Estiloa',
-		ok: 'Ados',
-		cancel: 'Utzi',
-		close: 'Itxi',
-		preview: 'Aurrebista',
-		resize: 'Arrastatu tamaina aldatzeko',
-		generalTab: 'Orokorra',
-		advancedTab: 'Aurreratua',
-		validateNumberFailed: 'Balio hau ez da zenbaki bat.',
-		confirmNewPage: 'Eduki honetan gorde gabe dauden aldaketak galduko dira. Ziur zaude orri berri bat kargatu nahi duzula?',
-		confirmCancel: 'Aukera batzuk aldatu egin dira. Ziur zaude elkarrizketa-koadroa itxi nahi duzula?',
-		options: 'Aukerak',
-		target: 'Target (Helburua)',
-		targetNew: 'Leiho Berria (_blank)',
-		targetTop: 'Goieneko Leihoan (_top)',
-		targetSelf: 'Leiho Berdinean (_self)',
-		targetParent: 'Leiho Gurasoan (_parent)',
-		langDirLTR: 'Ezkerretik Eskumara(LTR)',
-		langDirRTL: 'Eskumatik Ezkerrera (RTL)',
-		styles: 'Estiloa',
-		cssClasses: 'Estilo-orriko Klaseak',
-		width: 'Zabalera',
-		height: 'Altuera',
-		align: 'Lerrokatu',
-		alignLeft: 'Ezkerrera',
-		alignRight: 'Eskuman',
-		alignCenter: 'Erdian',
-		alignTop: 'Goian',
-		alignMiddle: 'Erdian',
-		alignBottom: 'Behean',
-		invalidValue	: 'Balio ezegokia.',
-		invalidHeight: 'Altuera zenbaki bat izan behar da.',
-		invalidWidth: 'Zabalera zenbaki bat izan behar da.',
-		invalidCssLength: '"%1" eremurako zehaztutako balioa zenbaki positibo bat izan behar du, aukeran CSS neurri unitate batekin (px, %, in, cm, mm, em, ex, pt edo pc).',
-		invalidHtmlLength: '"%1" eremurako zehaztutako balioa zenbaki positibo bat izan behar du, aukeran HTML neurri unitate batekin (px edo %).',
-		invalidInlineStyle: 'Lerroko estiloan zehazten dena tupla "name : value" formatuko eta puntu eta komaz bereiztutako tupla bat edo gehiago izan behar dira.',
-		cssLengthTooltip: 'Zenbakia bakarrik zehazten bada pixeletan egongo da. CSS neurri unitatea ere zehaztu ahal da (px, %, in, cm, mm, em, ex, pt, edo pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, erabilezina</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/fa.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object for the
- * Persian language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'fa' ] = {
-	// ARIA description.
-	editor: 'ویرایشگر متن کامل',
-	editorPanel: 'پنل ویرایشگر متن غنی',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'کلید Alt+0 را برای راهنمایی بفشارید',
-
-		browseServer: 'فهرست​نمایی سرور',
-		url: 'URL',
-		protocol: 'پروتکل',
-		upload: 'آپلود',
-		uploadSubmit: 'به سرور بفرست',
-		image: 'تصویر',
-		flash: 'فلش',
-		form: 'فرم',
-		checkbox: 'چک‌باکس',
-		radio: 'دکمه‌ی رادیویی',
-		textField: 'فیلد متنی',
-		textarea: 'ناحیهٴ متنی',
-		hiddenField: 'فیلد پنهان',
-		button: 'دکمه',
-		select: 'فیلد انتخاب چند گزینه​ای',
-		imageButton: 'دکمه‌ی تصویری',
-		notSet: '<تعین نشده>',
-		id: 'شناسه',
-		name: 'نام',
-		langDir: 'جهت​نمای زبان',
-		langDirLtr: 'چپ به راست',
-		langDirRtl: 'راست به چپ',
-		langCode: 'کد زبان',
-		longDescr: 'URL توصیف طولانی',
-		cssClass: 'کلاس​های شیوه​نامه (Stylesheet)',
-		advisoryTitle: 'عنوان کمکی',
-		cssStyle: 'شیوه (style)',
-		ok: 'پذیرش',
-		cancel: 'انصراف',
-		close: 'بستن',
-		preview: 'پیش‌نمایش',
-		resize: 'تغییر اندازه',
-		generalTab: 'عمومی',
-		advancedTab: 'پیشرفته',
-		validateNumberFailed: 'این مقدار یک عدد نیست.',
-		confirmNewPage: 'هر تغییر ایجاد شده​ی ذخیره نشده از بین خواهد رفت. آیا اطمینان دارید که قصد بارگیری صفحه جدیدی را دارید؟',
-		confirmCancel: 'برخی از گزینه‌ها تغییر کرده‌اند. آیا واقعا قصد بستن این پنجره را دارید؟',
-		options: 'گزینه​ها',
-		target: 'نحوه باز کردن',
-		targetNew: 'پنجره جدید',
-		targetTop: 'بالاترین پنجره',
-		targetSelf: 'همان پنجره',
-		targetParent: 'پنجره والد',
-		langDirLTR: 'چپ به راست',
-		langDirRTL: 'راست به چپ',
-		styles: 'سبک',
-		cssClasses: 'کلاس‌های شیوه‌نامه',
-		width: 'عرض',
-		height: 'طول',
-		align: 'چینش',
-		alignLeft: 'چپ',
-		alignRight: 'راست',
-		alignCenter: 'مرکز',
-		alignTop: 'بالا',
-		alignMiddle: 'وسط',
-		alignBottom: 'پائین',
-		invalidValue	: 'مقدار نامعتبر.',
-		invalidHeight: 'ارتفاع باید یک عدد باشد.',
-		invalidWidth: 'عرض باید یک عدد باشد.',
-		invalidCssLength: 'عدد تعیین شده برای فیلد "%1" باید یک عدد مثبت با یا بدون یک واحد اندازه گیری CSS معتبر باشد (px, %, in, cm, mm, em, ex, pt, or pc).',
-		invalidHtmlLength: 'عدد تعیین شده برای فیلد "%1" باید یک عدد مثبت با یا بدون یک واحد اندازه گیری HTML معتبر باشد (px or %).',
-		invalidInlineStyle: 'عدد تعیین شده برای سبک درون​خطی -Inline Style- باید دارای یک یا چند چندتایی با شکلی شبیه "name : value" که باید با یک ";" از هم جدا شوند.',
-		cssLengthTooltip: 'یک عدد برای یک مقدار بر حسب پیکسل و یا یک عدد با یک واحد CSS معتبر وارد کنید (px, %, in, cm, mm, em, ex, pt, or pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">، غیر قابل دسترس</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/fi.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object for the
- * Finnish language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'fi' ] = {
-	// ARIA description.
-	editor: 'Rikastekstieditori',
-	editorPanel: 'Rikastekstieditoripaneeli',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Paina ALT 0 nähdäksesi ohjeen',
-
-		browseServer: 'Selaa palvelinta',
-		url: 'Osoite',
-		protocol: 'Protokolla',
-		upload: 'Lisää tiedosto',
-		uploadSubmit: 'Lähetä palvelimelle',
-		image: 'Kuva',
-		flash: 'Flash-animaatio',
-		form: 'Lomake',
-		checkbox: 'Valintaruutu',
-		radio: 'Radiopainike',
-		textField: 'Tekstikenttä',
-		textarea: 'Tekstilaatikko',
-		hiddenField: 'Piilokenttä',
-		button: 'Painike',
-		select: 'Valintakenttä',
-		imageButton: 'Kuvapainike',
-		notSet: '<ei asetettu>',
-		id: 'Tunniste',
-		name: 'Nimi',
-		langDir: 'Kielen suunta',
-		langDirLtr: 'Vasemmalta oikealle (LTR)',
-		langDirRtl: 'Oikealta vasemmalle (RTL)',
-		langCode: 'Kielikoodi',
-		longDescr: 'Pitkän kuvauksen URL',
-		cssClass: 'Tyyliluokat',
-		advisoryTitle: 'Avustava otsikko',
-		cssStyle: 'Tyyli',
-		ok: 'OK',
-		cancel: 'Peruuta',
-		close: 'Sulje',
-		preview: 'Esikatselu',
-		resize: 'Raahaa muuttaaksesi kokoa',
-		generalTab: 'Yleinen',
-		advancedTab: 'Lisäominaisuudet',
-		validateNumberFailed: 'Arvon pitää olla numero.',
-		confirmNewPage: 'Kaikki tallentamattomat muutokset tähän sisältöön menetetään. Oletko varma, että haluat ladata uuden sivun?',
-		confirmCancel: 'Jotkut asetuksista on muuttuneet. Oletko varma, että haluat sulkea valintaikkunan?',
-		options: 'Asetukset',
-		target: 'Kohde',
-		targetNew: 'Uusi ikkuna (_blank)',
-		targetTop: 'Päällimmäinen ikkuna (_top)',
-		targetSelf: 'Sama ikkuna (_self)',
-		targetParent: 'Ylemmän tason ikkuna (_parent)',
-		langDirLTR: 'Vasemmalta oikealle (LTR)',
-		langDirRTL: 'Oikealta vasemmalle (RTL)',
-		styles: 'Tyyli',
-		cssClasses: 'Tyylitiedoston luokat',
-		width: 'Leveys',
-		height: 'Korkeus',
-		align: 'Kohdistus',
-		alignLeft: 'Vasemmalle',
-		alignRight: 'Oikealle',
-		alignCenter: 'Keskelle',
-		alignTop: 'Ylös',
-		alignMiddle: 'Keskelle',
-		alignBottom: 'Alas',
-		invalidValue	: 'Virheellinen arvo.',
-		invalidHeight: 'Korkeuden täytyy olla numero.',
-		invalidWidth: 'Leveyden täytyy olla numero.',
-		invalidCssLength: 'Kentän "%1" arvon täytyy olla positiivinen luku CSS mittayksikön (px, %, in, cm, mm, em, ex, pt tai pc) kanssa tai ilman.',
-		invalidHtmlLength: 'Kentän "%1" arvon täytyy olla positiivinen luku HTML mittayksikön (px tai %) kanssa tai ilman.',
-		invalidInlineStyle: 'Tyylille annetun arvon täytyy koostua yhdestä tai useammasta "nimi : arvo" parista, jotka ovat eroteltuna toisistaan puolipisteillä.',
-		cssLengthTooltip: 'Anna numeroarvo pikseleinä tai numeroarvo CSS mittayksikön kanssa (px, %, in, cm, mm, em, ex, pt, tai pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, ei saatavissa</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/fo.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Faroese language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'fo' ] = {
-	// ARIA description.
-	editor: 'Rich Text Editor',
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Trýst ALT og 0 fyri vegleiðing',
-
-		browseServer: 'Ambætarakagi',
-		url: 'URL',
-		protocol: 'Protokoll',
-		upload: 'Send til ambætaran',
-		uploadSubmit: 'Send til ambætaran',
-		image: 'Myndir',
-		flash: 'Flash',
-		form: 'Formur',
-		checkbox: 'Flugubein',
-		radio: 'Radioknøttur',
-		textField: 'Tekstteigur',
-		textarea: 'Tekstumráði',
-		hiddenField: 'Fjaldur teigur',
-		button: 'Knøttur',
-		select: 'Valskrá',
-		imageButton: 'Myndaknøttur',
-		notSet: '<ikki sett>',
-		id: 'Id',
-		name: 'Navn',
-		langDir: 'Tekstkós',
-		langDirLtr: 'Frá vinstru til høgru (LTR)',
-		langDirRtl: 'Frá høgru til vinstru (RTL)',
-		langCode: 'Málkoda',
-		longDescr: 'Víðkað URL frágreiðing',
-		cssClass: 'Typografi klassar',
-		advisoryTitle: 'Vegleiðandi heiti',
-		cssStyle: 'Typografi',
-		ok: 'Góðkent',
-		cancel: 'Avlýst',
-		close: 'Lat aftur',
-		preview: 'Frumsýn',
-		resize: 'Drag fyri at broyta stødd',
-		generalTab: 'Generelt',
-		advancedTab: 'Fjølbroytt',
-		validateNumberFailed: 'Hetta er ikki eitt tal.',
-		confirmNewPage: 'Allar ikki goymdar broytingar í hesum innihaldið hvørva. Skal nýggj síða lesast kortini?',
-		confirmCancel: 'Nakrir valmøguleikar eru broyttir. Ert tú vísur í, at dialogurin skal latast aftur?',
-		options: 'Options',
-		target: 'Target',
-		targetNew: 'Nýtt vindeyga (_blank)',
-		targetTop: 'Vindeyga ovast (_top)',
-		targetSelf: 'Sama vindeyga (_self)',
-		targetParent: 'Upphavligt vindeyga (_parent)',
-		langDirLTR: 'Frá vinstru til høgru (LTR)',
-		langDirRTL: 'Frá høgru til vinstru (RTL)',
-		styles: 'Style',
-		cssClasses: 'Stylesheet Classes',
-		width: 'Breidd',
-		height: 'Hædd',
-		align: 'Justering',
-		alignLeft: 'Vinstra',
-		alignRight: 'Høgra',
-		alignCenter: 'Miðsett',
-		alignTop: 'Ovast',
-		alignMiddle: 'Miðja',
-		alignBottom: 'Botnur',
-		invalidValue	: 'Invalid value.', // MISSING
-		invalidHeight: 'Hædd má vera eitt tal.',
-		invalidWidth: 'Breidd má vera eitt tal.',
-		invalidCssLength: 'Virðið sett í "%1" feltið má vera eitt positivt tal, við ella uttan gyldugum CSS mátieind (px, %, in, cm, mm, em, ex, pt, ella pc).',
-		invalidHtmlLength: 'Virðið sett í "%1" feltiðield má vera eitt positivt tal, við ella uttan gyldugum CSS mátieind (px ella %).',
-		invalidInlineStyle: 'Virði specifiserað fyri inline style má hava eitt ella fleiri pør (tuples) skrivað sum "name : value", hvørt parið sundurskilt við semi-colon.',
-		cssLengthTooltip: 'Skriva eitt tal fyri eitt virði í pixels ella eitt tal við gyldigum CSS eind (px, %, in, cm, mm, em, ex, pt, ella pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, ikki tøkt</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/fr-ca.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * Canadian French language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'fr-ca' ] = {
-	// ARIA description.
-	editor: 'Éditeur de texte enrichi',
-	editorPanel: 'Rich Text Editor panel', // MISSING
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Appuyez sur 0 pour de l\'aide',
-
-		browseServer: 'Parcourir le serveur',
-		url: 'URL',
-		protocol: 'Protocole',
-		upload: 'Envoyer',
-		uploadSubmit: 'Envoyer au serveur',
-		image: 'Image',
-		flash: 'Animation Flash',
-		form: 'Formulaire',
-		checkbox: 'Case à cocher',
-		radio: 'Bouton radio',
-		textField: 'Champ texte',
-		textarea: 'Zone de texte',
-		hiddenField: 'Champ caché',
-		button: 'Bouton',
-		select: 'Liste déroulante',
-		imageButton: 'Bouton image',
-		notSet: '<Par défaut>',
-		id: 'Id',
-		name: 'Nom',
-		langDir: 'Sens d\'écriture',
-		langDirLtr: 'De gauche à droite (LTR)',
-		langDirRtl: 'De droite à gauche (RTL)',
-		langCode: 'Code langue',
-		longDescr: 'URL de description longue',
-		cssClass: 'Classes CSS',
-		advisoryTitle: 'Titre',
-		cssStyle: 'Style',
-		ok: 'OK',
-		cancel: 'Annuler',
-		close: 'Fermer',
-		preview: 'Aperçu',
-		resize: 'Redimensionner',
-		generalTab: 'Général',
-		advancedTab: 'Avancé',
-		validateNumberFailed: 'Cette valeur n\'est pas un nombre.',
-		confirmNewPage: 'Les changements non sauvegardés seront perdus. Êtes-vous certain de vouloir charger une nouvelle page?',
-		confirmCancel: 'Certaines options ont été modifiées.  Êtes-vous certain de vouloir fermer?',
-		options: 'Options',
-		target: 'Cible',
-		targetNew: 'Nouvelle fenêtre (_blank)',
-		targetTop: 'Fenêtre supérieur (_top)',
-		targetSelf: 'Cette fenêtre (_self)',
-		targetParent: 'Fenêtre parent (_parent)',
-		langDirLTR: 'De gauche à droite (LTR)',
-		langDirRTL: 'De droite à gauche (RTL)',
-		styles: 'Style',
-		cssClasses: 'Classe CSS',
-		width: 'Largeur',
-		height: 'Hauteur',
-		align: 'Alignement',
-		alignLeft: 'Gauche',
-		alignRight: 'Droite',
-		alignCenter: 'Centré',
-		alignTop: 'Haut',
-		alignMiddle: 'Milieu',
-		alignBottom: 'Bas',
-		invalidValue	: 'Valeur invalide.',
-		invalidHeight: 'La hauteur doit être un nombre.',
-		invalidWidth: 'La largeur doit être un nombre.',
-		invalidCssLength: 'La valeur spécifiée pour le champ "%1" doit être un nombre positif avec ou sans unité de mesure CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).',
-		invalidHtmlLength: 'La valeur spécifiée pour le champ "%1" doit être un nombre positif avec ou sans unité de mesure HTML valide (px ou %).',
-		invalidInlineStyle: 'La valeur spécifiée pour le style intégré doit être composée d\'un ou plusieurs couples de valeur au format "nom : valeur", separés par des points-virgules.',
-		cssLengthTooltip: 'Entrer un nombre pour la valeur en pixel ou un nombre avec une unité CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, indisponible</span>'
-	}
-};

+ 0 - 98
htdocs/includes/ckeditor/ckeditor/_source/lang/fr.js

@@ -1,98 +0,0 @@
-/**
- * @license Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or http://ckeditor.com/license
- */
-
-/**
- * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
- * French language.
- */
-
-/**#@+
-   @type String
-   @example
-*/
-
-/**
- * Contains the dictionary of language entries.
- * @namespace
- */
-CKEDITOR.lang[ 'fr' ] = {
-	// ARIA description.
-	editor: 'Éditeur de Texte Enrichi',
-	editorPanel: 'Tableau de bord de l\'éditeur de texte enrichi',
-
-	// Common messages and labels.
-	common: {
-		// Screenreader titles. Please note that screenreaders are not always capable
-		// of reading non-English words. So be careful while translating it.
-		editorHelp: 'Appuyez sur ALT-0 pour l\'aide',
-
-		browseServer: 'Explorer le serveur',
-		url: 'URL',
-		protocol: 'Protocole',
-		upload: 'Envoyer',
-		uploadSubmit: 'Envoyer sur le serveur',
-		image: 'Image',
-		flash: 'Flash',
-		form: 'Formulaire',
-		checkbox: 'Case à cocher',
-		radio: 'Bouton Radio',
-		textField: 'Champ texte',
-		textarea: 'Zone de texte',
-		hiddenField: 'Champ caché',
-		button: 'Bouton',
-		select: 'Liste déroulante',
-		imageButton: 'Bouton image',
-		notSet: '<non défini>',
-		id: 'Id',
-		name: 'Nom',
-		langDir: 'Sens d\'écriture',
-		langDirLtr: 'Gauche à droite (LTR)',
-		langDirRtl: 'Droite à gauche (RTL)',
-		langCode: 'Code de langue',
-		longDescr: 'URL de description longue (longdesc => malvoyant)',
-		cssClass: 'Classe CSS',
-		advisoryTitle: 'Description (title)',
-		cssStyle: 'Style',
-		ok: 'OK',
-		cancel: 'Annuler',
-		close: 'Fermer',
-		preview: 'Aperçu',
-		resize: 'Déplacer pour modifier la taille',
-		generalTab: 'Général',
-		advancedTab: 'Avancé',
-		validateNumberFailed: 'Cette valeur n\'est pas un nombre.',
-		confirmNewPage: 'Les changements non sauvegardés seront perdus. Êtes-vous sûr de vouloir charger une nouvelle page?',
-		confirmCancel: 'Certaines options ont été modifiées. Êtes-vous sûr de vouloir fermer?',
-		options: 'Options',
-		target: 'Cible (Target)',
-		targetNew: 'Nouvelle fenêtre (_blank)',
-		targetTop: 'Fenêtre supérieure (_top)',
-		targetSelf: 'Même fenêtre (_self)',
-		targetParent: 'Fenêtre parent (_parent)',
-		langDirLTR: 'Gauche à Droite (LTR)',
-		langDirRTL: 'Droite à Gauche (RTL)',
-		styles: 'Style',
-		cssClasses: 'Classes de style',
-		width: 'Largeur',
-		height: 'Hauteur',
-		align: 'Alignement',
-		alignLeft: 'Gauche',
-		alignRight: 'Droite',
-		alignCenter: 'Centré',
-		alignTop: 'Haut',
-		alignMiddle: 'Milieu',
-		alignBottom: 'Bas',
-		invalidValue	: 'Valeur incorrecte.',
-		invalidHeight: 'La hauteur doit être un nombre.',
-		invalidWidth: 'La largeur doit être un nombre.',
-		invalidCssLength: 'La valeur spécifiée pour le champ "%1" doit être un nombre positif avec ou sans unité de mesure CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).',
-		invalidHtmlLength: 'La valeur spécifiée pour le champ "%1" doit être un nombre positif avec ou sans unité de mesure HTML valide (px ou %).',
-		invalidInlineStyle: 'La valeur spécifiée pour le style inline doit être composée d\'un ou plusieurs couples de valeur au format "nom : valeur", separés par des points-virgules.',
-		cssLengthTooltip: 'Entrer un nombre pour une valeur en pixels ou un nombre avec une unité de mesure CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).',
-
-		// Put the voice-only part of the label in the span.
-		unavailable: '%1<span class="cke_accessibility">, Indisponible</span>'
-	}
-};

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác