ckeditor-rails 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (347) hide show
  1. data/README.md +10 -4
  2. data/ckeditor-rails.gemspec +1 -1
  3. data/lib/ckeditor-rails/version.rb +1 -1
  4. data/vendor/assets/ckeditor/ckeditor/INSTALL.html +92 -92
  5. data/vendor/assets/ckeditor/ckeditor/_samples/adobeair/application.xml +32 -32
  6. data/vendor/assets/ckeditor/ckeditor/_samples/adobeair/run.bat +9 -9
  7. data/vendor/assets/ckeditor/ckeditor/_samples/adobeair/sample.html +45 -45
  8. data/vendor/assets/ckeditor/ckeditor/_samples/ajax.html +98 -98
  9. data/vendor/assets/ckeditor/ckeditor/_samples/api.html +192 -192
  10. data/vendor/assets/ckeditor/ckeditor/_samples/api_dialog.html +198 -198
  11. data/vendor/assets/ckeditor/ckeditor/_samples/api_dialog/my_dialog.js +28 -28
  12. data/vendor/assets/ckeditor/ckeditor/_samples/asp/advanced.asp +105 -105
  13. data/vendor/assets/ckeditor/ckeditor/_samples/asp/events.asp +136 -136
  14. data/vendor/assets/ckeditor/ckeditor/_samples/asp/index.html +103 -103
  15. data/vendor/assets/ckeditor/ckeditor/_samples/asp/replace.asp +72 -72
  16. data/vendor/assets/ckeditor/ckeditor/_samples/asp/replaceall.asp +77 -77
  17. data/vendor/assets/ckeditor/ckeditor/_samples/asp/sample_posteddata.asp +46 -46
  18. data/vendor/assets/ckeditor/ckeditor/_samples/asp/standalone.asp +72 -72
  19. data/vendor/assets/ckeditor/ckeditor/_samples/assets/_posteddata.php +59 -59
  20. data/vendor/assets/ckeditor/ckeditor/_samples/assets/output_xhtml.css +204 -204
  21. data/vendor/assets/ckeditor/ckeditor/_samples/assets/parsesample.css +70 -70
  22. data/vendor/assets/ckeditor/ckeditor/_samples/assets/swfobject.js +18 -18
  23. data/vendor/assets/ckeditor/ckeditor/_samples/autogrow.html +107 -107
  24. data/vendor/assets/ckeditor/ckeditor/_samples/bbcode.html +125 -125
  25. data/vendor/assets/ckeditor/ckeditor/_samples/devtools.html +94 -94
  26. data/vendor/assets/ckeditor/ckeditor/_samples/divreplace.html +154 -154
  27. data/vendor/assets/ckeditor/ckeditor/_samples/enterkey.html +115 -115
  28. data/vendor/assets/ckeditor/ckeditor/_samples/fullpage.html +82 -82
  29. data/vendor/assets/ckeditor/ckeditor/_samples/index.html +116 -116
  30. data/vendor/assets/ckeditor/ckeditor/_samples/jqueryadapter.html +99 -99
  31. data/vendor/assets/ckeditor/ckeditor/_samples/output_for_flash.html +275 -275
  32. data/vendor/assets/ckeditor/ckeditor/_samples/output_html.html +285 -285
  33. data/vendor/assets/ckeditor/ckeditor/_samples/output_xhtml.html +177 -177
  34. data/vendor/assets/ckeditor/ckeditor/_samples/php/advanced.php +120 -120
  35. data/vendor/assets/ckeditor/ckeditor/_samples/php/events.php +153 -153
  36. data/vendor/assets/ckeditor/ckeditor/_samples/php/index.html +47 -47
  37. data/vendor/assets/ckeditor/ckeditor/_samples/php/replace.php +87 -87
  38. data/vendor/assets/ckeditor/ckeditor/_samples/php/replaceall.php +88 -88
  39. data/vendor/assets/ckeditor/ckeditor/_samples/php/standalone.php +83 -83
  40. data/vendor/assets/ckeditor/ckeditor/_samples/placeholder.html +81 -81
  41. data/vendor/assets/ckeditor/ckeditor/_samples/readonly.html +91 -91
  42. data/vendor/assets/ckeditor/ckeditor/_samples/replacebyclass.html +64 -64
  43. data/vendor/assets/ckeditor/ckeditor/_samples/replacebycode.html +97 -97
  44. data/vendor/assets/ckeditor/ckeditor/_samples/sample.css +163 -163
  45. data/vendor/assets/ckeditor/ckeditor/_samples/sample.js +65 -65
  46. data/vendor/assets/ckeditor/ckeditor/_samples/sample_posteddata.php +21 -21
  47. data/vendor/assets/ckeditor/ckeditor/_samples/sharedspaces.html +153 -153
  48. data/vendor/assets/ckeditor/ckeditor/_samples/skins.html +110 -110
  49. data/vendor/assets/ckeditor/ckeditor/_samples/stylesheetparser.html +93 -93
  50. data/vendor/assets/ckeditor/ckeditor/_samples/tableresize.html +115 -115
  51. data/vendor/assets/ckeditor/ckeditor/_samples/ui_color.html +129 -129
  52. data/vendor/assets/ckeditor/ckeditor/_samples/ui_languages.html +134 -134
  53. data/vendor/assets/ckeditor/ckeditor/_source/adapters/jquery.js +306 -306
  54. data/vendor/assets/ckeditor/ckeditor/_source/core/_bootstrap.js +87 -87
  55. data/vendor/assets/ckeditor/ckeditor/_source/core/ckeditor.js +141 -141
  56. data/vendor/assets/ckeditor/ckeditor/_source/core/ckeditor_base.js +227 -227
  57. data/vendor/assets/ckeditor/ckeditor/_source/core/ckeditor_basic.js +238 -238
  58. data/vendor/assets/ckeditor/ckeditor/_source/core/command.js +209 -209
  59. data/vendor/assets/ckeditor/ckeditor/_source/core/commanddefinition.js +129 -129
  60. data/vendor/assets/ckeditor/ckeditor/_source/core/config.js +431 -431
  61. data/vendor/assets/ckeditor/ckeditor/_source/core/dataprocessor.js +65 -65
  62. data/vendor/assets/ckeditor/ckeditor/_source/core/dom.js +20 -20
  63. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/comment.js +32 -32
  64. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/document.js +251 -251
  65. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/documentfragment.js +49 -49
  66. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/domobject.js +258 -258
  67. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/element.js +1681 -1681
  68. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/elementpath.js +119 -119
  69. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/event.js +145 -145
  70. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/node.js +695 -695
  71. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/nodelist.js +26 -26
  72. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/range.js +2032 -2032
  73. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/rangelist.js +213 -213
  74. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/text.js +128 -128
  75. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/walker.js +462 -462
  76. data/vendor/assets/ckeditor/ckeditor/_source/core/dom/window.js +96 -96
  77. data/vendor/assets/ckeditor/ckeditor/_source/core/dtd.js +266 -266
  78. data/vendor/assets/ckeditor/ckeditor/_source/core/editor.js +1059 -1059
  79. data/vendor/assets/ckeditor/ckeditor/_source/core/editor_basic.js +186 -186
  80. data/vendor/assets/ckeditor/ckeditor/_source/core/env.js +291 -291
  81. data/vendor/assets/ckeditor/ckeditor/_source/core/event.js +342 -342
  82. data/vendor/assets/ckeditor/ckeditor/_source/core/eventInfo.js +120 -120
  83. data/vendor/assets/ckeditor/ckeditor/_source/core/focusmanager.js +152 -152
  84. data/vendor/assets/ckeditor/ckeditor/_source/core/htmlparser.js +224 -224
  85. data/vendor/assets/ckeditor/ckeditor/_source/core/htmlparser/basicwriter.js +145 -145
  86. data/vendor/assets/ckeditor/ckeditor/_source/core/htmlparser/cdata.js +43 -43
  87. data/vendor/assets/ckeditor/ckeditor/_source/core/htmlparser/comment.js +60 -60
  88. data/vendor/assets/ckeditor/ckeditor/_source/core/htmlparser/element.js +308 -308
  89. data/vendor/assets/ckeditor/ckeditor/_source/core/htmlparser/filter.js +288 -288
  90. data/vendor/assets/ckeditor/ckeditor/_source/core/htmlparser/fragment.js +497 -497
  91. data/vendor/assets/ckeditor/ckeditor/_source/core/htmlparser/text.js +55 -55
  92. data/vendor/assets/ckeditor/ckeditor/_source/core/lang.js +157 -157
  93. data/vendor/assets/ckeditor/ckeditor/_source/core/loader.js +240 -240
  94. data/vendor/assets/ckeditor/ckeditor/_source/core/plugindefinition.js +83 -83
  95. data/vendor/assets/ckeditor/ckeditor/_source/core/plugins.js +103 -103
  96. data/vendor/assets/ckeditor/ckeditor/_source/core/resourcemanager.js +238 -238
  97. data/vendor/assets/ckeditor/ckeditor/_source/core/scriptloader.js +180 -180
  98. data/vendor/assets/ckeditor/ckeditor/_source/core/skins.js +184 -184
  99. data/vendor/assets/ckeditor/ckeditor/_source/core/themes.js +19 -19
  100. data/vendor/assets/ckeditor/ckeditor/_source/core/tools.js +763 -763
  101. data/vendor/assets/ckeditor/ckeditor/_source/core/ui.js +128 -128
  102. data/vendor/assets/ckeditor/ckeditor/_source/lang/_languages.js +84 -84
  103. data/vendor/assets/ckeditor/ckeditor/_source/lang/_translationstatus.txt +61 -61
  104. data/vendor/assets/ckeditor/ckeditor/_source/lang/af.js +812 -812
  105. data/vendor/assets/ckeditor/ckeditor/_source/lang/ar.js +812 -812
  106. data/vendor/assets/ckeditor/ckeditor/_source/lang/bg.js +812 -812
  107. data/vendor/assets/ckeditor/ckeditor/_source/lang/bn.js +812 -812
  108. data/vendor/assets/ckeditor/ckeditor/_source/lang/bs.js +812 -812
  109. data/vendor/assets/ckeditor/ckeditor/_source/lang/ca.js +812 -812
  110. data/vendor/assets/ckeditor/ckeditor/_source/lang/cs.js +812 -812
  111. data/vendor/assets/ckeditor/ckeditor/_source/lang/cy.js +812 -812
  112. data/vendor/assets/ckeditor/ckeditor/_source/lang/da.js +812 -812
  113. data/vendor/assets/ckeditor/ckeditor/_source/lang/de.js +812 -812
  114. data/vendor/assets/ckeditor/ckeditor/_source/lang/el.js +812 -812
  115. data/vendor/assets/ckeditor/ckeditor/_source/lang/en-au.js +812 -812
  116. data/vendor/assets/ckeditor/ckeditor/_source/lang/en-ca.js +812 -812
  117. data/vendor/assets/ckeditor/ckeditor/_source/lang/en-gb.js +812 -812
  118. data/vendor/assets/ckeditor/ckeditor/_source/lang/en.js +812 -812
  119. data/vendor/assets/ckeditor/ckeditor/_source/lang/eo.js +812 -812
  120. data/vendor/assets/ckeditor/ckeditor/_source/lang/es.js +812 -812
  121. data/vendor/assets/ckeditor/ckeditor/_source/lang/et.js +812 -812
  122. data/vendor/assets/ckeditor/ckeditor/_source/lang/eu.js +812 -812
  123. data/vendor/assets/ckeditor/ckeditor/_source/lang/fa.js +812 -812
  124. data/vendor/assets/ckeditor/ckeditor/_source/lang/fi.js +812 -812
  125. data/vendor/assets/ckeditor/ckeditor/_source/lang/fo.js +812 -812
  126. data/vendor/assets/ckeditor/ckeditor/_source/lang/fr-ca.js +812 -812
  127. data/vendor/assets/ckeditor/ckeditor/_source/lang/fr.js +812 -812
  128. data/vendor/assets/ckeditor/ckeditor/_source/lang/gl.js +812 -812
  129. data/vendor/assets/ckeditor/ckeditor/_source/lang/gu.js +812 -812
  130. data/vendor/assets/ckeditor/ckeditor/_source/lang/he.js +812 -812
  131. data/vendor/assets/ckeditor/ckeditor/_source/lang/hi.js +812 -812
  132. data/vendor/assets/ckeditor/ckeditor/_source/lang/hr.js +812 -812
  133. data/vendor/assets/ckeditor/ckeditor/_source/lang/hu.js +812 -812
  134. data/vendor/assets/ckeditor/ckeditor/_source/lang/is.js +812 -812
  135. data/vendor/assets/ckeditor/ckeditor/_source/lang/it.js +812 -812
  136. data/vendor/assets/ckeditor/ckeditor/_source/lang/ja.js +812 -812
  137. data/vendor/assets/ckeditor/ckeditor/_source/lang/ka.js +812 -812
  138. data/vendor/assets/ckeditor/ckeditor/_source/lang/km.js +812 -812
  139. data/vendor/assets/ckeditor/ckeditor/_source/lang/ko.js +812 -812
  140. data/vendor/assets/ckeditor/ckeditor/_source/lang/lt.js +812 -812
  141. data/vendor/assets/ckeditor/ckeditor/_source/lang/lv.js +812 -812
  142. data/vendor/assets/ckeditor/ckeditor/_source/lang/mn.js +812 -812
  143. data/vendor/assets/ckeditor/ckeditor/_source/lang/ms.js +812 -812
  144. data/vendor/assets/ckeditor/ckeditor/_source/lang/nb.js +812 -812
  145. data/vendor/assets/ckeditor/ckeditor/_source/lang/nl.js +812 -812
  146. data/vendor/assets/ckeditor/ckeditor/_source/lang/no.js +812 -812
  147. data/vendor/assets/ckeditor/ckeditor/_source/lang/pl.js +812 -812
  148. data/vendor/assets/ckeditor/ckeditor/_source/lang/pt-br.js +811 -811
  149. data/vendor/assets/ckeditor/ckeditor/_source/lang/pt.js +812 -812
  150. data/vendor/assets/ckeditor/ckeditor/_source/lang/ro.js +812 -812
  151. data/vendor/assets/ckeditor/ckeditor/_source/lang/ru.js +812 -812
  152. data/vendor/assets/ckeditor/ckeditor/_source/lang/sk.js +812 -812
  153. data/vendor/assets/ckeditor/ckeditor/_source/lang/sl.js +812 -812
  154. data/vendor/assets/ckeditor/ckeditor/_source/lang/sr-latn.js +812 -812
  155. data/vendor/assets/ckeditor/ckeditor/_source/lang/sr.js +812 -812
  156. data/vendor/assets/ckeditor/ckeditor/_source/lang/sv.js +811 -811
  157. data/vendor/assets/ckeditor/ckeditor/_source/lang/th.js +812 -812
  158. data/vendor/assets/ckeditor/ckeditor/_source/lang/tr.js +811 -811
  159. data/vendor/assets/ckeditor/ckeditor/_source/lang/uk.js +812 -812
  160. data/vendor/assets/ckeditor/ckeditor/_source/lang/vi.js +812 -812
  161. data/vendor/assets/ckeditor/ckeditor/_source/lang/zh-cn.js +812 -812
  162. data/vendor/assets/ckeditor/ckeditor/_source/lang/zh.js +812 -812
  163. data/vendor/assets/ckeditor/ckeditor/_source/plugins/a11yhelp/dialogs/a11yhelp.js +222 -222
  164. data/vendor/assets/ckeditor/ckeditor/_source/plugins/a11yhelp/lang/en.js +108 -108
  165. data/vendor/assets/ckeditor/ckeditor/_source/plugins/a11yhelp/lang/he.js +216 -216
  166. data/vendor/assets/ckeditor/ckeditor/_source/plugins/a11yhelp/plugin.js +47 -47
  167. data/vendor/assets/ckeditor/ckeditor/_source/plugins/about/dialogs/about.js +76 -76
  168. data/vendor/assets/ckeditor/ckeditor/_source/plugins/about/plugin.js +24 -24
  169. data/vendor/assets/ckeditor/ckeditor/_source/plugins/adobeair/plugin.js +228 -228
  170. data/vendor/assets/ckeditor/ckeditor/_source/plugins/ajax/plugin.js +152 -152
  171. data/vendor/assets/ckeditor/ckeditor/_source/plugins/autogrow/plugin.js +88 -88
  172. data/vendor/assets/ckeditor/ckeditor/_source/plugins/basicstyles/plugin.js +101 -101
  173. data/vendor/assets/ckeditor/ckeditor/_source/plugins/bbcode/plugin.js +931 -931
  174. data/vendor/assets/ckeditor/ckeditor/_source/plugins/bidi/plugin.js +334 -334
  175. data/vendor/assets/ckeditor/ckeditor/_source/plugins/blockquote/plugin.js +305 -305
  176. data/vendor/assets/ckeditor/ckeditor/_source/plugins/button/plugin.js +290 -290
  177. data/vendor/assets/ckeditor/ckeditor/_source/plugins/clipboard/dialogs/paste.js +223 -223
  178. data/vendor/assets/ckeditor/ckeditor/_source/plugins/clipboard/plugin.js +453 -453
  179. data/vendor/assets/ckeditor/ckeditor/_source/plugins/colorbutton/plugin.js +294 -294
  180. data/vendor/assets/ckeditor/ckeditor/_source/plugins/colordialog/dialogs/colordialog.js +340 -340
  181. data/vendor/assets/ckeditor/ckeditor/_source/plugins/colordialog/plugin.js +15 -15
  182. data/vendor/assets/ckeditor/ckeditor/_source/plugins/contextmenu/plugin.js +177 -177
  183. data/vendor/assets/ckeditor/ckeditor/_source/plugins/devtools/lang/en.js +16 -16
  184. data/vendor/assets/ckeditor/ckeditor/_source/plugins/devtools/plugin.js +173 -173
  185. data/vendor/assets/ckeditor/ckeditor/_source/plugins/dialog/dialogDefinition.js +1166 -1166
  186. data/vendor/assets/ckeditor/ckeditor/_source/plugins/dialog/plugin.js +3289 -3289
  187. data/vendor/assets/ckeditor/ckeditor/_source/plugins/dialogadvtab/plugin.js +207 -207
  188. data/vendor/assets/ckeditor/ckeditor/_source/plugins/dialogui/plugin.js +1541 -1541
  189. data/vendor/assets/ckeditor/ckeditor/_source/plugins/div/dialogs/div.js +535 -535
  190. data/vendor/assets/ckeditor/ckeditor/_source/plugins/div/plugin.js +121 -121
  191. data/vendor/assets/ckeditor/ckeditor/_source/plugins/docprops/dialogs/docprops.js +686 -686
  192. data/vendor/assets/ckeditor/ckeditor/_source/plugins/docprops/plugin.js +22 -22
  193. data/vendor/assets/ckeditor/ckeditor/_source/plugins/domiterator/plugin.js +361 -361
  194. data/vendor/assets/ckeditor/ckeditor/_source/plugins/editingblock/plugin.js +275 -275
  195. data/vendor/assets/ckeditor/ckeditor/_source/plugins/elementspath/plugin.js +218 -218
  196. data/vendor/assets/ckeditor/ckeditor/_source/plugins/enterkey/plugin.js +413 -413
  197. data/vendor/assets/ckeditor/ckeditor/_source/plugins/entities/plugin.js +250 -250
  198. data/vendor/assets/ckeditor/ckeditor/_source/plugins/fakeobjects/plugin.js +175 -175
  199. data/vendor/assets/ckeditor/ckeditor/_source/plugins/filebrowser/plugin.js +524 -524
  200. data/vendor/assets/ckeditor/ckeditor/_source/plugins/find/dialogs/find.js +903 -903
  201. data/vendor/assets/ckeditor/ckeditor/_source/plugins/find/plugin.js +47 -47
  202. data/vendor/assets/ckeditor/ckeditor/_source/plugins/flash/dialogs/flash.js +673 -673
  203. data/vendor/assets/ckeditor/ckeditor/_source/plugins/flash/plugin.js +154 -154
  204. data/vendor/assets/ckeditor/ckeditor/_source/plugins/floatpanel/plugin.js +428 -428
  205. data/vendor/assets/ckeditor/ckeditor/_source/plugins/font/plugin.js +234 -234
  206. data/vendor/assets/ckeditor/ckeditor/_source/plugins/format/plugin.js +197 -197
  207. data/vendor/assets/ckeditor/ckeditor/_source/plugins/forms/dialogs/button.js +118 -118
  208. data/vendor/assets/ckeditor/ckeditor/_source/plugins/forms/dialogs/checkbox.js +153 -153
  209. data/vendor/assets/ckeditor/ckeditor/_source/plugins/forms/dialogs/form.js +177 -177
  210. data/vendor/assets/ckeditor/ckeditor/_source/plugins/forms/dialogs/hiddenfield.js +100 -100
  211. data/vendor/assets/ckeditor/ckeditor/_source/plugins/forms/dialogs/radio.js +135 -135
  212. data/vendor/assets/ckeditor/ckeditor/_source/plugins/forms/dialogs/select.js +558 -558
  213. data/vendor/assets/ckeditor/ckeditor/_source/plugins/forms/dialogs/textarea.js +114 -114
  214. data/vendor/assets/ckeditor/ckeditor/_source/plugins/forms/dialogs/textfield.js +199 -199
  215. data/vendor/assets/ckeditor/ckeditor/_source/plugins/forms/plugin.js +288 -288
  216. data/vendor/assets/ckeditor/ckeditor/_source/plugins/horizontalrule/plugin.js +48 -48
  217. data/vendor/assets/ckeditor/ckeditor/_source/plugins/htmldataprocessor/plugin.js +595 -595
  218. data/vendor/assets/ckeditor/ckeditor/_source/plugins/htmlwriter/plugin.js +319 -319
  219. data/vendor/assets/ckeditor/ckeditor/_source/plugins/iframe/dialogs/iframe.js +229 -229
  220. data/vendor/assets/ckeditor/ckeditor/_source/plugins/iframe/plugin.js +87 -87
  221. data/vendor/assets/ckeditor/ckeditor/_source/plugins/iframedialog/plugin.js +188 -188
  222. data/vendor/assets/ckeditor/ckeditor/_source/plugins/image/dialogs/image.js +1406 -1406
  223. data/vendor/assets/ckeditor/ckeditor/_source/plugins/image/plugin.js +81 -81
  224. data/vendor/assets/ckeditor/ckeditor/_source/plugins/indent/plugin.js +461 -461
  225. data/vendor/assets/ckeditor/ckeditor/_source/plugins/justify/plugin.js +253 -253
  226. data/vendor/assets/ckeditor/ckeditor/_source/plugins/keystrokes/plugin.js +225 -225
  227. data/vendor/assets/ckeditor/ckeditor/_source/plugins/link/dialogs/anchor.js +144 -144
  228. data/vendor/assets/ckeditor/ckeditor/_source/plugins/link/dialogs/link.js +1424 -1424
  229. data/vendor/assets/ckeditor/ckeditor/_source/plugins/link/plugin.js +374 -374
  230. data/vendor/assets/ckeditor/ckeditor/_source/plugins/list/plugin.js +734 -734
  231. data/vendor/assets/ckeditor/ckeditor/_source/plugins/listblock/plugin.js +268 -268
  232. data/vendor/assets/ckeditor/ckeditor/_source/plugins/liststyle/dialogs/liststyle.js +225 -225
  233. data/vendor/assets/ckeditor/ckeditor/_source/plugins/liststyle/plugin.js +66 -66
  234. data/vendor/assets/ckeditor/ckeditor/_source/plugins/maximize/plugin.js +352 -352
  235. data/vendor/assets/ckeditor/ckeditor/_source/plugins/menu/plugin.js +541 -541
  236. data/vendor/assets/ckeditor/ckeditor/_source/plugins/menubutton/plugin.js +98 -98
  237. data/vendor/assets/ckeditor/ckeditor/_source/plugins/newpage/plugin.js +54 -54
  238. data/vendor/assets/ckeditor/ckeditor/_source/plugins/pagebreak/plugin.js +164 -164
  239. data/vendor/assets/ckeditor/ckeditor/_source/plugins/panel/plugin.js +403 -403
  240. data/vendor/assets/ckeditor/ckeditor/_source/plugins/panelbutton/plugin.js +144 -144
  241. data/vendor/assets/ckeditor/ckeditor/_source/plugins/pastefromword/filter/default.js +1367 -1367
  242. data/vendor/assets/ckeditor/ckeditor/_source/plugins/pastefromword/plugin.js +141 -141
  243. data/vendor/assets/ckeditor/ckeditor/_source/plugins/pastetext/dialogs/pastetext.js +67 -67
  244. data/vendor/assets/ckeditor/ckeditor/_source/plugins/pastetext/plugin.js +98 -98
  245. data/vendor/assets/ckeditor/ckeditor/_source/plugins/placeholder/dialogs/placeholder.js +71 -71
  246. data/vendor/assets/ckeditor/ckeditor/_source/plugins/placeholder/lang/en.js +16 -16
  247. data/vendor/assets/ckeditor/ckeditor/_source/plugins/placeholder/lang/he.js +16 -16
  248. data/vendor/assets/ckeditor/ckeditor/_source/plugins/placeholder/plugin.js +171 -171
  249. data/vendor/assets/ckeditor/ckeditor/_source/plugins/popup/plugin.js +64 -64
  250. data/vendor/assets/ckeditor/ckeditor/_source/plugins/preview/plugin.js +109 -109
  251. data/vendor/assets/ckeditor/ckeditor/_source/plugins/print/plugin.js +42 -42
  252. data/vendor/assets/ckeditor/ckeditor/_source/plugins/removeformat/plugin.js +185 -185
  253. data/vendor/assets/ckeditor/ckeditor/_source/plugins/resize/plugin.js +168 -168
  254. data/vendor/assets/ckeditor/ckeditor/_source/plugins/richcombo/plugin.js +381 -381
  255. data/vendor/assets/ckeditor/ckeditor/_source/plugins/save/plugin.js +56 -56
  256. data/vendor/assets/ckeditor/ckeditor/_source/plugins/scayt/dialogs/options.js +537 -537
  257. data/vendor/assets/ckeditor/ckeditor/_source/plugins/scayt/dialogs/toolbar.css +71 -71
  258. data/vendor/assets/ckeditor/ckeditor/_source/plugins/scayt/plugin.js +964 -964
  259. data/vendor/assets/ckeditor/ckeditor/_source/plugins/selection/plugin.js +1601 -1601
  260. data/vendor/assets/ckeditor/ckeditor/_source/plugins/showblocks/plugin.js +160 -160
  261. data/vendor/assets/ckeditor/ckeditor/_source/plugins/showborders/plugin.js +207 -207
  262. data/vendor/assets/ckeditor/ckeditor/_source/plugins/smiley/dialogs/smiley.js +224 -224
  263. data/vendor/assets/ckeditor/ckeditor/_source/plugins/smiley/plugin.js +94 -94
  264. data/vendor/assets/ckeditor/ckeditor/_source/plugins/sourcearea/plugin.js +209 -209
  265. data/vendor/assets/ckeditor/ckeditor/_source/plugins/specialchar/dialogs/specialchar.js +350 -350
  266. data/vendor/assets/ckeditor/ckeditor/_source/plugins/specialchar/lang/en.js +89 -89
  267. data/vendor/assets/ckeditor/ckeditor/_source/plugins/specialchar/plugin.js +70 -70
  268. data/vendor/assets/ckeditor/ckeditor/_source/plugins/styles/plugin.js +1696 -1696
  269. data/vendor/assets/ckeditor/ckeditor/_source/plugins/styles/styles/default.js +88 -88
  270. data/vendor/assets/ckeditor/ckeditor/_source/plugins/stylescombo/plugin.js +218 -218
  271. data/vendor/assets/ckeditor/ckeditor/_source/plugins/stylesheetparser/plugin.js +148 -148
  272. data/vendor/assets/ckeditor/ckeditor/_source/plugins/tab/plugin.js +367 -367
  273. data/vendor/assets/ckeditor/ckeditor/_source/plugins/table/dialogs/table.js +602 -602
  274. data/vendor/assets/ckeditor/ckeditor/_source/plugins/table/plugin.js +78 -78
  275. data/vendor/assets/ckeditor/ckeditor/_source/plugins/tableresize/plugin.js +443 -443
  276. data/vendor/assets/ckeditor/ckeditor/_source/plugins/tabletools/dialogs/tableCell.js +525 -525
  277. data/vendor/assets/ckeditor/ckeditor/_source/plugins/tabletools/plugin.js +1194 -1194
  278. data/vendor/assets/ckeditor/ckeditor/_source/plugins/templates/dialogs/templates.js +234 -234
  279. data/vendor/assets/ckeditor/ckeditor/_source/plugins/templates/plugin.js +99 -99
  280. data/vendor/assets/ckeditor/ckeditor/_source/plugins/templates/templates/default.js +94 -94
  281. data/vendor/assets/ckeditor/ckeditor/_source/plugins/toolbar/plugin.js +545 -545
  282. data/vendor/assets/ckeditor/ckeditor/_source/plugins/uicolor/dialogs/uicolor.js +205 -205
  283. data/vendor/assets/ckeditor/ckeditor/_source/plugins/uicolor/lang/en.js +15 -15
  284. data/vendor/assets/ckeditor/ckeditor/_source/plugins/uicolor/lang/he.js +15 -15
  285. data/vendor/assets/ckeditor/ckeditor/_source/plugins/uicolor/plugin.js +37 -37
  286. data/vendor/assets/ckeditor/ckeditor/_source/plugins/uicolor/yui/assets/yui.css +15 -15
  287. data/vendor/assets/ckeditor/ckeditor/_source/plugins/uicolor/yui/yui.js +71 -71
  288. data/vendor/assets/ckeditor/ckeditor/_source/plugins/undo/plugin.js +580 -580
  289. data/vendor/assets/ckeditor/ckeditor/_source/plugins/wsc/dialogs/ciframe.html +49 -49
  290. data/vendor/assets/ckeditor/ckeditor/_source/plugins/wsc/dialogs/tmpFrameset.html +52 -52
  291. data/vendor/assets/ckeditor/ckeditor/_source/plugins/wsc/dialogs/wsc.css +82 -82
  292. data/vendor/assets/ckeditor/ckeditor/_source/plugins/wsc/dialogs/wsc.js +192 -192
  293. data/vendor/assets/ckeditor/ckeditor/_source/plugins/wsc/plugin.js +33 -33
  294. data/vendor/assets/ckeditor/ckeditor/_source/plugins/wysiwygarea/plugin.js +1351 -1351
  295. data/vendor/assets/ckeditor/ckeditor/_source/plugins/xml/plugin.js +170 -170
  296. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/dialog.css +943 -943
  297. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/editor.css +25 -25
  298. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/elementspath.css +73 -73
  299. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/icons.css +366 -366
  300. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/mainui.css +203 -203
  301. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/menu.css +232 -232
  302. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/panel.css +217 -217
  303. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/presets.css +49 -49
  304. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/reset.css +84 -84
  305. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/richcombo.css +287 -287
  306. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/skin.js +236 -236
  307. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/templates.css +88 -88
  308. data/vendor/assets/ckeditor/ckeditor/_source/skins/kama/toolbar.css +407 -407
  309. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/dialog.css +844 -844
  310. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/editor.css +25 -25
  311. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/elementspath.css +74 -74
  312. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/icons.css +363 -363
  313. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/mainui.css +153 -153
  314. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/menu.css +229 -229
  315. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/panel.css +212 -212
  316. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/presets.css +49 -49
  317. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/reset.css +84 -84
  318. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/richcombo.css +309 -309
  319. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/skin.js +74 -74
  320. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/templates.css +87 -87
  321. data/vendor/assets/ckeditor/ckeditor/_source/skins/office2003/toolbar.css +522 -522
  322. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/dialog.css +861 -861
  323. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/editor.css +25 -25
  324. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/elementspath.css +74 -74
  325. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/icons.css +363 -363
  326. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/mainui.css +162 -162
  327. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/menu.css +232 -232
  328. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/panel.css +212 -212
  329. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/presets.css +50 -50
  330. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/reset.css +84 -84
  331. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/richcombo.css +302 -302
  332. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/skin.js +70 -70
  333. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/templates.css +87 -87
  334. data/vendor/assets/ckeditor/ckeditor/_source/skins/v2/toolbar.css +465 -465
  335. data/vendor/assets/ckeditor/ckeditor/_source/themes/default/theme.js +395 -395
  336. data/vendor/assets/ckeditor/ckeditor/adapters/jquery.js +6 -6
  337. data/vendor/assets/ckeditor/ckeditor/ckeditor.asp +955 -955
  338. data/vendor/assets/ckeditor/ckeditor/ckeditor.pack +211 -211
  339. data/vendor/assets/ckeditor/ckeditor/ckeditor.php +29 -29
  340. data/vendor/assets/ckeditor/ckeditor/ckeditor_basic.js +8 -8
  341. data/vendor/assets/ckeditor/ckeditor/ckeditor_basic_source.js +20 -20
  342. data/vendor/assets/ckeditor/ckeditor/ckeditor_php4.php +566 -566
  343. data/vendor/assets/ckeditor/ckeditor/ckeditor_php5.php +556 -556
  344. data/vendor/assets/ckeditor/ckeditor/config.js +11 -11
  345. data/vendor/assets/ckeditor/ckeditor/contents.css +25 -25
  346. data/vendor/assets/ckeditor/ckeditor/themes/default/theme.js +8 -8
  347. metadata +7 -9
@@ -1,734 +1,734 @@
1
- /*
2
- Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.html or http://ckeditor.com/license
4
- */
5
-
6
- /**
7
- * @file Insert and remove numbered and bulleted lists.
8
- */
9
-
10
- (function()
11
- {
12
- var listNodeNames = { ol : 1, ul : 1 },
13
- emptyTextRegex = /^[\n\r\t ]*$/;
14
-
15
- var whitespaces = CKEDITOR.dom.walker.whitespaces(),
16
- bookmarks = CKEDITOR.dom.walker.bookmark(),
17
- nonEmpty = function( node ){ return !( whitespaces( node ) || bookmarks( node ) ); };
18
-
19
- CKEDITOR.plugins.list = {
20
- /*
21
- * Convert a DOM list tree into a data structure that is easier to
22
- * manipulate. This operation should be non-intrusive in the sense that it
23
- * does not change the DOM tree, with the exception that it may add some
24
- * markers to the list item nodes when database is specified.
25
- */
26
- listToArray : function( listNode, database, baseArray, baseIndentLevel, grandparentNode )
27
- {
28
- if ( !listNodeNames[ listNode.getName() ] )
29
- return [];
30
-
31
- if ( !baseIndentLevel )
32
- baseIndentLevel = 0;
33
- if ( !baseArray )
34
- baseArray = [];
35
-
36
- // Iterate over all list items to and look for inner lists.
37
- for ( var i = 0, count = listNode.getChildCount() ; i < count ; i++ )
38
- {
39
- var listItem = listNode.getChild( i );
40
-
41
- // Fixing malformed nested lists by moving it into a previous list item. (#6236)
42
- if( listItem.type == CKEDITOR.NODE_ELEMENT && listItem.getName() in CKEDITOR.dtd.$list )
43
- CKEDITOR.plugins.list.listToArray( listItem, database, baseArray, baseIndentLevel + 1 );
44
-
45
- // It may be a text node or some funny stuff.
46
- if ( listItem.$.nodeName.toLowerCase() != 'li' )
47
- continue;
48
-
49
- var itemObj = { 'parent' : listNode, indent : baseIndentLevel, element : listItem, contents : [] };
50
- if ( !grandparentNode )
51
- {
52
- itemObj.grandparent = listNode.getParent();
53
- if ( itemObj.grandparent && itemObj.grandparent.$.nodeName.toLowerCase() == 'li' )
54
- itemObj.grandparent = itemObj.grandparent.getParent();
55
- }
56
- else
57
- itemObj.grandparent = grandparentNode;
58
-
59
- if ( database )
60
- CKEDITOR.dom.element.setMarker( database, listItem, 'listarray_index', baseArray.length );
61
- baseArray.push( itemObj );
62
-
63
- for ( var j = 0, itemChildCount = listItem.getChildCount(), child; j < itemChildCount ; j++ )
64
- {
65
- child = listItem.getChild( j );
66
- if ( child.type == CKEDITOR.NODE_ELEMENT && listNodeNames[ child.getName() ] )
67
- // Note the recursion here, it pushes inner list items with
68
- // +1 indentation in the correct order.
69
- CKEDITOR.plugins.list.listToArray( child, database, baseArray, baseIndentLevel + 1, itemObj.grandparent );
70
- else
71
- itemObj.contents.push( child );
72
- }
73
- }
74
- return baseArray;
75
- },
76
-
77
- // Convert our internal representation of a list back to a DOM forest.
78
- arrayToList : function( listArray, database, baseIndex, paragraphMode, dir )
79
- {
80
- if ( !baseIndex )
81
- baseIndex = 0;
82
- if ( !listArray || listArray.length < baseIndex + 1 )
83
- return null;
84
- var doc = listArray[ baseIndex ].parent.getDocument(),
85
- retval = new CKEDITOR.dom.documentFragment( doc ),
86
- rootNode = null,
87
- currentIndex = baseIndex,
88
- indentLevel = Math.max( listArray[ baseIndex ].indent, 0 ),
89
- currentListItem = null,
90
- orgDir,
91
- paragraphName = ( paragraphMode == CKEDITOR.ENTER_P ? 'p' : 'div' );
92
- while ( 1 )
93
- {
94
- var item = listArray[ currentIndex ];
95
-
96
- orgDir = item.element.getDirection( 1 );
97
-
98
- if ( item.indent == indentLevel )
99
- {
100
- if ( !rootNode || listArray[ currentIndex ].parent.getName() != rootNode.getName() )
101
- {
102
- rootNode = listArray[ currentIndex ].parent.clone( false, 1 );
103
- dir && rootNode.setAttribute( 'dir', dir );
104
- retval.append( rootNode );
105
- }
106
- currentListItem = rootNode.append( item.element.clone( 0, 1 ) );
107
-
108
- if ( orgDir != rootNode.getDirection( 1 ) )
109
- currentListItem.setAttribute( 'dir', orgDir );
110
- else
111
- currentListItem.removeAttribute( 'dir' );
112
-
113
- for ( var i = 0 ; i < item.contents.length ; i++ )
114
- currentListItem.append( item.contents[i].clone( 1, 1 ) );
115
- currentIndex++;
116
- }
117
- else if ( item.indent == Math.max( indentLevel, 0 ) + 1 )
118
- {
119
- // Maintain original direction (#6861).
120
- var currDir = listArray[ currentIndex - 1 ].element.getDirection( 1 ),
121
- listData = CKEDITOR.plugins.list.arrayToList( listArray, null, currentIndex, paragraphMode,
122
- currDir != orgDir ? orgDir: null );
123
-
124
- // If the next block is an <li> with another list tree as the first
125
- // child, we'll need to append a filler (<br>/NBSP) or the list item
126
- // wouldn't be editable. (#6724)
127
- if ( !currentListItem.getChildCount() && CKEDITOR.env.ie && !( doc.$.documentMode > 7 ))
128
- currentListItem.append( doc.createText( '\xa0' ) );
129
- currentListItem.append( listData.listNode );
130
- currentIndex = listData.nextIndex;
131
- }
132
- else if ( item.indent == -1 && !baseIndex && item.grandparent )
133
- {
134
- if ( listNodeNames[ item.grandparent.getName() ] )
135
- currentListItem = item.element.clone( false, true );
136
- else
137
- {
138
- // Create completely new blocks here.
139
- if ( dir || item.element.hasAttributes() || paragraphMode != CKEDITOR.ENTER_BR )
140
- {
141
- currentListItem = doc.createElement( paragraphName );
142
- item.element.copyAttributes( currentListItem, { type:1, value:1 } );
143
-
144
- // There might be a case where there are no attributes in the element after all
145
- // (i.e. when "type" or "value" are the only attributes set). In this case, if enterMode = BR,
146
- // the current item should be a fragment.
147
- if ( !dir && paragraphMode == CKEDITOR.ENTER_BR && !currentListItem.hasAttributes() )
148
- currentListItem = new CKEDITOR.dom.documentFragment( doc );
149
- }
150
- else
151
- currentListItem = new CKEDITOR.dom.documentFragment( doc );
152
- }
153
-
154
- if ( currentListItem.type == CKEDITOR.NODE_ELEMENT )
155
- {
156
- if ( item.grandparent.getDirection( 1 ) != orgDir )
157
- currentListItem.setAttribute( 'dir', orgDir );
158
- else
159
- currentListItem.removeAttribute( 'dir' );
160
- }
161
-
162
- for ( i = 0 ; i < item.contents.length ; i++ )
163
- currentListItem.append( item.contents[i].clone( 1, 1 ) );
164
-
165
- if ( currentListItem.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT
166
- && currentIndex != listArray.length - 1 )
167
- {
168
- var last = currentListItem.getLast();
169
- if ( last && last.type == CKEDITOR.NODE_ELEMENT
170
- && last.getAttribute( 'type' ) == '_moz' )
171
- {
172
- last.remove();
173
- }
174
-
175
- if ( !( last = currentListItem.getLast( nonEmpty )
176
- && last.type == CKEDITOR.NODE_ELEMENT
177
- && last.getName() in CKEDITOR.dtd.$block ) )
178
- {
179
- currentListItem.append( doc.createElement( 'br' ) );
180
- }
181
- }
182
-
183
- if ( currentListItem.type == CKEDITOR.NODE_ELEMENT &&
184
- currentListItem.getName() == paragraphName &&
185
- currentListItem.$.firstChild )
186
- {
187
- currentListItem.trim();
188
- var firstChild = currentListItem.getFirst();
189
- if ( firstChild.type == CKEDITOR.NODE_ELEMENT && firstChild.isBlockBoundary() )
190
- {
191
- var tmp = new CKEDITOR.dom.documentFragment( doc );
192
- currentListItem.moveChildren( tmp );
193
- currentListItem = tmp;
194
- }
195
- }
196
-
197
- var currentListItemName = currentListItem.$.nodeName.toLowerCase();
198
- if ( !CKEDITOR.env.ie && ( currentListItemName == 'div' || currentListItemName == 'p' ) )
199
- currentListItem.appendBogus();
200
- retval.append( currentListItem );
201
- rootNode = null;
202
- currentIndex++;
203
- }
204
- else
205
- return null;
206
-
207
- if ( listArray.length <= currentIndex || Math.max( listArray[ currentIndex ].indent, 0 ) < indentLevel )
208
- break;
209
- }
210
-
211
- // Clear marker attributes for the new list tree made of cloned nodes, if any.
212
- if ( database )
213
- {
214
- var currentNode = retval.getFirst();
215
- while ( currentNode )
216
- {
217
- if ( currentNode.type == CKEDITOR.NODE_ELEMENT )
218
- CKEDITOR.dom.element.clearMarkers( database, currentNode );
219
- currentNode = currentNode.getNextSourceNode();
220
- }
221
- }
222
-
223
- return { listNode : retval, nextIndex : currentIndex };
224
- }
225
- };
226
-
227
- function onSelectionChange( evt )
228
- {
229
- if ( evt.editor.readOnly )
230
- return null;
231
-
232
- var path = evt.data.path,
233
- blockLimit = path.blockLimit,
234
- elements = path.elements,
235
- element,
236
- i;
237
-
238
- // Grouping should only happen under blockLimit.(#3940).
239
- for ( i = 0 ; i < elements.length && ( element = elements[ i ] )
240
- && !element.equals( blockLimit ); i++ )
241
- {
242
- if ( listNodeNames[ elements[ i ].getName() ] )
243
- return this.setState( this.type == elements[ i ].getName() ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );
244
- }
245
-
246
- return this.setState( CKEDITOR.TRISTATE_OFF );
247
- }
248
-
249
- function changeListType( editor, groupObj, database, listsCreated )
250
- {
251
- // This case is easy...
252
- // 1. Convert the whole list into a one-dimensional array.
253
- // 2. Change the list type by modifying the array.
254
- // 3. Recreate the whole list by converting the array to a list.
255
- // 4. Replace the original list with the recreated list.
256
- var listArray = CKEDITOR.plugins.list.listToArray( groupObj.root, database ),
257
- selectedListItems = [];
258
-
259
- for ( var i = 0 ; i < groupObj.contents.length ; i++ )
260
- {
261
- var itemNode = groupObj.contents[i];
262
- itemNode = itemNode.getAscendant( 'li', true );
263
- if ( !itemNode || itemNode.getCustomData( 'list_item_processed' ) )
264
- continue;
265
- selectedListItems.push( itemNode );
266
- CKEDITOR.dom.element.setMarker( database, itemNode, 'list_item_processed', true );
267
- }
268
-
269
- var root = groupObj.root,
270
- fakeParent = root.getDocument().createElement( this.type );
271
- // Copy all attributes, except from 'start' and 'type'.
272
- root.copyAttributes( fakeParent, { start : 1, type : 1 } );
273
- // The list-style-type property should be ignored.
274
- fakeParent.removeStyle( 'list-style-type' );
275
-
276
- for ( i = 0 ; i < selectedListItems.length ; i++ )
277
- {
278
- var listIndex = selectedListItems[i].getCustomData( 'listarray_index' );
279
- listArray[listIndex].parent = fakeParent;
280
- }
281
- var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode );
282
- var child, length = newList.listNode.getChildCount();
283
- for ( i = 0 ; i < length && ( child = newList.listNode.getChild( i ) ) ; i++ )
284
- {
285
- if ( child.getName() == this.type )
286
- listsCreated.push( child );
287
- }
288
- newList.listNode.replace( groupObj.root );
289
- }
290
-
291
- var headerTagRegex = /^h[1-6]$/;
292
-
293
- function createList( editor, groupObj, listsCreated )
294
- {
295
- var contents = groupObj.contents,
296
- doc = groupObj.root.getDocument(),
297
- listContents = [];
298
-
299
- // It is possible to have the contents returned by DomRangeIterator to be the same as the root.
300
- // e.g. when we're running into table cells.
301
- // In such a case, enclose the childNodes of contents[0] into a <div>.
302
- if ( contents.length == 1 && contents[0].equals( groupObj.root ) )
303
- {
304
- var divBlock = doc.createElement( 'div' );
305
- contents[0].moveChildren && contents[0].moveChildren( divBlock );
306
- contents[0].append( divBlock );
307
- contents[0] = divBlock;
308
- }
309
-
310
- // Calculate the common parent node of all content blocks.
311
- var commonParent = groupObj.contents[0].getParent();
312
- for ( var i = 0 ; i < contents.length ; i++ )
313
- commonParent = commonParent.getCommonAncestor( contents[i].getParent() );
314
-
315
- var useComputedState = editor.config.useComputedState,
316
- listDir, explicitDirection;
317
-
318
- useComputedState = useComputedState === undefined || useComputedState;
319
-
320
- // We want to insert things that are in the same tree level only, so calculate the contents again
321
- // by expanding the selected blocks to the same tree level.
322
- for ( i = 0 ; i < contents.length ; i++ )
323
- {
324
- var contentNode = contents[i],
325
- parentNode;
326
- while ( ( parentNode = contentNode.getParent() ) )
327
- {
328
- if ( parentNode.equals( commonParent ) )
329
- {
330
- listContents.push( contentNode );
331
-
332
- // Determine the lists's direction.
333
- if ( !explicitDirection && contentNode.getDirection() )
334
- explicitDirection = 1;
335
-
336
- var itemDir = contentNode.getDirection( useComputedState );
337
-
338
- if ( listDir !== null )
339
- {
340
- // If at least one LI have a different direction than current listDir, we can't have listDir.
341
- if ( listDir && listDir != itemDir )
342
- listDir = null;
343
- else
344
- listDir = itemDir;
345
- }
346
-
347
- break;
348
- }
349
- contentNode = parentNode;
350
- }
351
- }
352
-
353
- if ( listContents.length < 1 )
354
- return;
355
-
356
- // Insert the list to the DOM tree.
357
- var insertAnchor = listContents[ listContents.length - 1 ].getNext(),
358
- listNode = doc.createElement( this.type );
359
-
360
- listsCreated.push( listNode );
361
-
362
- var contentBlock, listItem;
363
-
364
- while ( listContents.length )
365
- {
366
- contentBlock = listContents.shift();
367
- listItem = doc.createElement( 'li' );
368
-
369
- // Preserve preformat block and heading structure when converting to list item. (#5335) (#5271)
370
- if ( contentBlock.is( 'pre' ) || headerTagRegex.test( contentBlock.getName() ) )
371
- contentBlock.appendTo( listItem );
372
- else
373
- {
374
- contentBlock.copyAttributes( listItem );
375
- // Remove direction attribute after it was merged into list root. (#7657)
376
- if ( listDir && contentBlock.getDirection() )
377
- {
378
- listItem.removeStyle( 'direction' );
379
- listItem.removeAttribute( 'dir' );
380
- }
381
- contentBlock.moveChildren( listItem );
382
- contentBlock.remove();
383
- }
384
-
385
- listItem.appendTo( listNode );
386
- }
387
-
388
- // Apply list root dir only if it has been explicitly declared.
389
- if ( listDir && explicitDirection )
390
- listNode.setAttribute( 'dir', listDir );
391
-
392
- if ( insertAnchor )
393
- listNode.insertBefore( insertAnchor );
394
- else
395
- listNode.appendTo( commonParent );
396
- }
397
-
398
- function removeList( editor, groupObj, database )
399
- {
400
- // This is very much like the change list type operation.
401
- // Except that we're changing the selected items' indent to -1 in the list array.
402
- var listArray = CKEDITOR.plugins.list.listToArray( groupObj.root, database ),
403
- selectedListItems = [];
404
-
405
- for ( var i = 0 ; i < groupObj.contents.length ; i++ )
406
- {
407
- var itemNode = groupObj.contents[i];
408
- itemNode = itemNode.getAscendant( 'li', true );
409
- if ( !itemNode || itemNode.getCustomData( 'list_item_processed' ) )
410
- continue;
411
- selectedListItems.push( itemNode );
412
- CKEDITOR.dom.element.setMarker( database, itemNode, 'list_item_processed', true );
413
- }
414
-
415
- var lastListIndex = null;
416
- for ( i = 0 ; i < selectedListItems.length ; i++ )
417
- {
418
- var listIndex = selectedListItems[i].getCustomData( 'listarray_index' );
419
- listArray[listIndex].indent = -1;
420
- lastListIndex = listIndex;
421
- }
422
-
423
- // After cutting parts of the list out with indent=-1, we still have to maintain the array list
424
- // model's nextItem.indent <= currentItem.indent + 1 invariant. Otherwise the array model of the
425
- // list cannot be converted back to a real DOM list.
426
- for ( i = lastListIndex + 1 ; i < listArray.length ; i++ )
427
- {
428
- if ( listArray[i].indent > listArray[i-1].indent + 1 )
429
- {
430
- var indentOffset = listArray[i-1].indent + 1 - listArray[i].indent;
431
- var oldIndent = listArray[i].indent;
432
- while ( listArray[i] && listArray[i].indent >= oldIndent )
433
- {
434
- listArray[i].indent += indentOffset;
435
- i++;
436
- }
437
- i--;
438
- }
439
- }
440
-
441
- var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode,
442
- groupObj.root.getAttribute( 'dir' ) );
443
-
444
- // Compensate <br> before/after the list node if the surrounds are non-blocks.(#3836)
445
- var docFragment = newList.listNode, boundaryNode, siblingNode;
446
- function compensateBrs( isStart )
447
- {
448
- if ( ( boundaryNode = docFragment[ isStart ? 'getFirst' : 'getLast' ]() )
449
- && !( boundaryNode.is && boundaryNode.isBlockBoundary() )
450
- && ( siblingNode = groupObj.root[ isStart ? 'getPrevious' : 'getNext' ]
451
- ( CKEDITOR.dom.walker.whitespaces( true ) ) )
452
- && !( siblingNode.is && siblingNode.isBlockBoundary( { br : 1 } ) ) )
453
- editor.document.createElement( 'br' )[ isStart ? 'insertBefore' : 'insertAfter' ]( boundaryNode );
454
- }
455
- compensateBrs( true );
456
- compensateBrs();
457
-
458
- docFragment.replace( groupObj.root );
459
- }
460
-
461
- function listCommand( name, type )
462
- {
463
- this.name = name;
464
- this.type = type;
465
- }
466
-
467
- listCommand.prototype = {
468
- exec : function( editor )
469
- {
470
- var doc = editor.document,
471
- config = editor.config,
472
- selection = editor.getSelection(),
473
- ranges = selection && selection.getRanges( true );
474
-
475
- // There should be at least one selected range.
476
- if ( !ranges || ranges.length < 1 )
477
- return;
478
-
479
- // Midas lists rule #1 says we can create a list even in an empty document.
480
- // But DOM iterator wouldn't run if the document is really empty.
481
- // So create a paragraph if the document is empty and we're going to create a list.
482
- if ( this.state == CKEDITOR.TRISTATE_OFF )
483
- {
484
- var body = doc.getBody();
485
- if ( !body.getFirst( nonEmpty ) )
486
- {
487
- config.enterMode == CKEDITOR.ENTER_BR ?
488
- body.appendBogus() :
489
- ranges[ 0 ].fixBlock( 1, config.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' );
490
-
491
- selection.selectRanges( ranges );
492
- }
493
- // Maybe a single range there enclosing the whole list,
494
- // turn on the list state manually(#4129).
495
- else
496
- {
497
- var range = ranges.length == 1 && ranges[ 0 ],
498
- enclosedNode = range && range.getEnclosedNode();
499
- if ( enclosedNode && enclosedNode.is
500
- && this.type == enclosedNode.getName() )
501
- this.setState( CKEDITOR.TRISTATE_ON );
502
- }
503
- }
504
-
505
- var bookmarks = selection.createBookmarks( true );
506
-
507
- // Group the blocks up because there are many cases where multiple lists have to be created,
508
- // or multiple lists have to be cancelled.
509
- var listGroups = [],
510
- database = {},
511
- rangeIterator = ranges.createIterator(),
512
- index = 0;
513
-
514
- while ( ( range = rangeIterator.getNextRange() ) && ++index )
515
- {
516
- var boundaryNodes = range.getBoundaryNodes(),
517
- startNode = boundaryNodes.startNode,
518
- endNode = boundaryNodes.endNode;
519
-
520
- if ( startNode.type == CKEDITOR.NODE_ELEMENT && startNode.getName() == 'td' )
521
- range.setStartAt( boundaryNodes.startNode, CKEDITOR.POSITION_AFTER_START );
522
-
523
- if ( endNode.type == CKEDITOR.NODE_ELEMENT && endNode.getName() == 'td' )
524
- range.setEndAt( boundaryNodes.endNode, CKEDITOR.POSITION_BEFORE_END );
525
-
526
- var iterator = range.createIterator(),
527
- block;
528
-
529
- iterator.forceBrBreak = ( this.state == CKEDITOR.TRISTATE_OFF );
530
-
531
- while ( ( block = iterator.getNextParagraph() ) )
532
- {
533
- // Avoid duplicate blocks get processed across ranges.
534
- if( block.getCustomData( 'list_block' ) )
535
- continue;
536
- else
537
- CKEDITOR.dom.element.setMarker( database, block, 'list_block', 1 );
538
-
539
- var path = new CKEDITOR.dom.elementPath( block ),
540
- pathElements = path.elements,
541
- pathElementsCount = pathElements.length,
542
- listNode = null,
543
- processedFlag = 0,
544
- blockLimit = path.blockLimit,
545
- element;
546
-
547
- // First, try to group by a list ancestor.
548
- for ( var i = pathElementsCount - 1; i >= 0 && ( element = pathElements[ i ] ); i-- )
549
- {
550
- if ( listNodeNames[ element.getName() ]
551
- && blockLimit.contains( element ) ) // Don't leak outside block limit (#3940).
552
- {
553
- // If we've encountered a list inside a block limit
554
- // The last group object of the block limit element should
555
- // no longer be valid. Since paragraphs after the list
556
- // should belong to a different group of paragraphs before
557
- // the list. (Bug #1309)
558
- blockLimit.removeCustomData( 'list_group_object_' + index );
559
-
560
- var groupObj = element.getCustomData( 'list_group_object' );
561
- if ( groupObj )
562
- groupObj.contents.push( block );
563
- else
564
- {
565
- groupObj = { root : element, contents : [ block ] };
566
- listGroups.push( groupObj );
567
- CKEDITOR.dom.element.setMarker( database, element, 'list_group_object', groupObj );
568
- }
569
- processedFlag = 1;
570
- break;
571
- }
572
- }
573
-
574
- if ( processedFlag )
575
- continue;
576
-
577
- // No list ancestor? Group by block limit, but don't mix contents from different ranges.
578
- var root = blockLimit;
579
- if ( root.getCustomData( 'list_group_object_' + index ) )
580
- root.getCustomData( 'list_group_object_' + index ).contents.push( block );
581
- else
582
- {
583
- groupObj = { root : root, contents : [ block ] };
584
- CKEDITOR.dom.element.setMarker( database, root, 'list_group_object_' + index, groupObj );
585
- listGroups.push( groupObj );
586
- }
587
- }
588
- }
589
-
590
- // Now we have two kinds of list groups, groups rooted at a list, and groups rooted at a block limit element.
591
- // We either have to build lists or remove lists, for removing a list does not makes sense when we are looking
592
- // at the group that's not rooted at lists. So we have three cases to handle.
593
- var listsCreated = [];
594
- while ( listGroups.length > 0 )
595
- {
596
- groupObj = listGroups.shift();
597
- if ( this.state == CKEDITOR.TRISTATE_OFF )
598
- {
599
- if ( listNodeNames[ groupObj.root.getName() ] )
600
- changeListType.call( this, editor, groupObj, database, listsCreated );
601
- else
602
- createList.call( this, editor, groupObj, listsCreated );
603
- }
604
- else if ( this.state == CKEDITOR.TRISTATE_ON && listNodeNames[ groupObj.root.getName() ] )
605
- removeList.call( this, editor, groupObj, database );
606
- }
607
-
608
- // For all new lists created, merge adjacent, same type lists.
609
- for ( i = 0 ; i < listsCreated.length ; i++ )
610
- {
611
- listNode = listsCreated[i];
612
- var mergeSibling, listCommand = this;
613
- ( mergeSibling = function( rtl ){
614
-
615
- var sibling = listNode[ rtl ?
616
- 'getPrevious' : 'getNext' ]( CKEDITOR.dom.walker.whitespaces( true ) );
617
- if ( sibling && sibling.getName &&
618
- sibling.getName() == listCommand.type )
619
- {
620
- sibling.remove();
621
- // Move children order by merge direction.(#3820)
622
- sibling.moveChildren( listNode, rtl );
623
- }
624
- } )();
625
- mergeSibling( 1 );
626
- }
627
-
628
- // Clean up, restore selection and update toolbar button states.
629
- CKEDITOR.dom.element.clearAllMarkers( database );
630
- selection.selectBookmarks( bookmarks );
631
- editor.focus();
632
- }
633
- };
634
-
635
- var dtd = CKEDITOR.dtd;
636
- var tailNbspRegex = /[\t\r\n ]*(?:&nbsp;|\xa0)$/;
637
-
638
- function indexOfFirstChildElement( element, tagNameList )
639
- {
640
- var child,
641
- children = element.children,
642
- length = children.length;
643
-
644
- for ( var i = 0 ; i < length ; i++ )
645
- {
646
- child = children[ i ];
647
- if ( child.name && ( child.name in tagNameList ) )
648
- return i;
649
- }
650
-
651
- return length;
652
- }
653
-
654
- function getExtendNestedListFilter( isHtmlFilter )
655
- {
656
- // An element filter function that corrects nested list start in an empty
657
- // list item for better displaying/outputting. (#3165)
658
- return function( listItem )
659
- {
660
- var children = listItem.children,
661
- firstNestedListIndex = indexOfFirstChildElement( listItem, dtd.$list ),
662
- firstNestedList = children[ firstNestedListIndex ],
663
- nodeBefore = firstNestedList && firstNestedList.previous,
664
- tailNbspmatch;
665
-
666
- if ( nodeBefore
667
- && ( nodeBefore.name && nodeBefore.name == 'br'
668
- || nodeBefore.value && ( tailNbspmatch = nodeBefore.value.match( tailNbspRegex ) ) ) )
669
- {
670
- var fillerNode = nodeBefore;
671
-
672
- // Always use 'nbsp' as filler node if we found a nested list appear
673
- // in front of a list item.
674
- if ( !( tailNbspmatch && tailNbspmatch.index ) && fillerNode == children[ 0 ] )
675
- children[ 0 ] = ( isHtmlFilter || CKEDITOR.env.ie ) ?
676
- new CKEDITOR.htmlParser.text( '\xa0' ) :
677
- new CKEDITOR.htmlParser.element( 'br', {} );
678
-
679
- // Otherwise the filler is not needed anymore.
680
- else if ( fillerNode.name == 'br' )
681
- children.splice( firstNestedListIndex - 1, 1 );
682
- else
683
- fillerNode.value = fillerNode.value.replace( tailNbspRegex, '' );
684
- }
685
-
686
- };
687
- }
688
-
689
- var defaultListDataFilterRules = { elements : {} };
690
- for ( var i in dtd.$listItem )
691
- defaultListDataFilterRules.elements[ i ] = getExtendNestedListFilter();
692
-
693
- var defaultListHtmlFilterRules = { elements : {} };
694
- for ( i in dtd.$listItem )
695
- defaultListHtmlFilterRules.elements[ i ] = getExtendNestedListFilter( true );
696
-
697
- CKEDITOR.plugins.add( 'list',
698
- {
699
- init : function( editor )
700
- {
701
- // Register commands.
702
- var numberedListCommand = editor.addCommand( 'numberedlist', new listCommand( 'numberedlist', 'ol' ) ),
703
- bulletedListCommand = editor.addCommand( 'bulletedlist', new listCommand( 'bulletedlist', 'ul' ) );
704
-
705
- // Register the toolbar button.
706
- editor.ui.addButton( 'NumberedList',
707
- {
708
- label : editor.lang.numberedlist,
709
- command : 'numberedlist'
710
- } );
711
- editor.ui.addButton( 'BulletedList',
712
- {
713
- label : editor.lang.bulletedlist,
714
- command : 'bulletedlist'
715
- } );
716
-
717
- // Register the state changing handlers.
718
- editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, numberedListCommand ) );
719
- editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, bulletedListCommand ) );
720
- },
721
-
722
- afterInit : function ( editor )
723
- {
724
- var dataProcessor = editor.dataProcessor;
725
- if ( dataProcessor )
726
- {
727
- dataProcessor.dataFilter.addRules( defaultListDataFilterRules );
728
- dataProcessor.htmlFilter.addRules( defaultListHtmlFilterRules );
729
- }
730
- },
731
-
732
- requires : [ 'domiterator' ]
733
- } );
734
- })();
1
+ /*
2
+ Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3
+ For licensing, see LICENSE.html or http://ckeditor.com/license
4
+ */
5
+
6
+ /**
7
+ * @file Insert and remove numbered and bulleted lists.
8
+ */
9
+
10
+ (function()
11
+ {
12
+ var listNodeNames = { ol : 1, ul : 1 },
13
+ emptyTextRegex = /^[\n\r\t ]*$/;
14
+
15
+ var whitespaces = CKEDITOR.dom.walker.whitespaces(),
16
+ bookmarks = CKEDITOR.dom.walker.bookmark(),
17
+ nonEmpty = function( node ){ return !( whitespaces( node ) || bookmarks( node ) ); };
18
+
19
+ CKEDITOR.plugins.list = {
20
+ /*
21
+ * Convert a DOM list tree into a data structure that is easier to
22
+ * manipulate. This operation should be non-intrusive in the sense that it
23
+ * does not change the DOM tree, with the exception that it may add some
24
+ * markers to the list item nodes when database is specified.
25
+ */
26
+ listToArray : function( listNode, database, baseArray, baseIndentLevel, grandparentNode )
27
+ {
28
+ if ( !listNodeNames[ listNode.getName() ] )
29
+ return [];
30
+
31
+ if ( !baseIndentLevel )
32
+ baseIndentLevel = 0;
33
+ if ( !baseArray )
34
+ baseArray = [];
35
+
36
+ // Iterate over all list items to and look for inner lists.
37
+ for ( var i = 0, count = listNode.getChildCount() ; i < count ; i++ )
38
+ {
39
+ var listItem = listNode.getChild( i );
40
+
41
+ // Fixing malformed nested lists by moving it into a previous list item. (#6236)
42
+ if( listItem.type == CKEDITOR.NODE_ELEMENT && listItem.getName() in CKEDITOR.dtd.$list )
43
+ CKEDITOR.plugins.list.listToArray( listItem, database, baseArray, baseIndentLevel + 1 );
44
+
45
+ // It may be a text node or some funny stuff.
46
+ if ( listItem.$.nodeName.toLowerCase() != 'li' )
47
+ continue;
48
+
49
+ var itemObj = { 'parent' : listNode, indent : baseIndentLevel, element : listItem, contents : [] };
50
+ if ( !grandparentNode )
51
+ {
52
+ itemObj.grandparent = listNode.getParent();
53
+ if ( itemObj.grandparent && itemObj.grandparent.$.nodeName.toLowerCase() == 'li' )
54
+ itemObj.grandparent = itemObj.grandparent.getParent();
55
+ }
56
+ else
57
+ itemObj.grandparent = grandparentNode;
58
+
59
+ if ( database )
60
+ CKEDITOR.dom.element.setMarker( database, listItem, 'listarray_index', baseArray.length );
61
+ baseArray.push( itemObj );
62
+
63
+ for ( var j = 0, itemChildCount = listItem.getChildCount(), child; j < itemChildCount ; j++ )
64
+ {
65
+ child = listItem.getChild( j );
66
+ if ( child.type == CKEDITOR.NODE_ELEMENT && listNodeNames[ child.getName() ] )
67
+ // Note the recursion here, it pushes inner list items with
68
+ // +1 indentation in the correct order.
69
+ CKEDITOR.plugins.list.listToArray( child, database, baseArray, baseIndentLevel + 1, itemObj.grandparent );
70
+ else
71
+ itemObj.contents.push( child );
72
+ }
73
+ }
74
+ return baseArray;
75
+ },
76
+
77
+ // Convert our internal representation of a list back to a DOM forest.
78
+ arrayToList : function( listArray, database, baseIndex, paragraphMode, dir )
79
+ {
80
+ if ( !baseIndex )
81
+ baseIndex = 0;
82
+ if ( !listArray || listArray.length < baseIndex + 1 )
83
+ return null;
84
+ var doc = listArray[ baseIndex ].parent.getDocument(),
85
+ retval = new CKEDITOR.dom.documentFragment( doc ),
86
+ rootNode = null,
87
+ currentIndex = baseIndex,
88
+ indentLevel = Math.max( listArray[ baseIndex ].indent, 0 ),
89
+ currentListItem = null,
90
+ orgDir,
91
+ paragraphName = ( paragraphMode == CKEDITOR.ENTER_P ? 'p' : 'div' );
92
+ while ( 1 )
93
+ {
94
+ var item = listArray[ currentIndex ];
95
+
96
+ orgDir = item.element.getDirection( 1 );
97
+
98
+ if ( item.indent == indentLevel )
99
+ {
100
+ if ( !rootNode || listArray[ currentIndex ].parent.getName() != rootNode.getName() )
101
+ {
102
+ rootNode = listArray[ currentIndex ].parent.clone( false, 1 );
103
+ dir && rootNode.setAttribute( 'dir', dir );
104
+ retval.append( rootNode );
105
+ }
106
+ currentListItem = rootNode.append( item.element.clone( 0, 1 ) );
107
+
108
+ if ( orgDir != rootNode.getDirection( 1 ) )
109
+ currentListItem.setAttribute( 'dir', orgDir );
110
+ else
111
+ currentListItem.removeAttribute( 'dir' );
112
+
113
+ for ( var i = 0 ; i < item.contents.length ; i++ )
114
+ currentListItem.append( item.contents[i].clone( 1, 1 ) );
115
+ currentIndex++;
116
+ }
117
+ else if ( item.indent == Math.max( indentLevel, 0 ) + 1 )
118
+ {
119
+ // Maintain original direction (#6861).
120
+ var currDir = listArray[ currentIndex - 1 ].element.getDirection( 1 ),
121
+ listData = CKEDITOR.plugins.list.arrayToList( listArray, null, currentIndex, paragraphMode,
122
+ currDir != orgDir ? orgDir: null );
123
+
124
+ // If the next block is an <li> with another list tree as the first
125
+ // child, we'll need to append a filler (<br>/NBSP) or the list item
126
+ // wouldn't be editable. (#6724)
127
+ if ( !currentListItem.getChildCount() && CKEDITOR.env.ie && !( doc.$.documentMode > 7 ))
128
+ currentListItem.append( doc.createText( '\xa0' ) );
129
+ currentListItem.append( listData.listNode );
130
+ currentIndex = listData.nextIndex;
131
+ }
132
+ else if ( item.indent == -1 && !baseIndex && item.grandparent )
133
+ {
134
+ if ( listNodeNames[ item.grandparent.getName() ] )
135
+ currentListItem = item.element.clone( false, true );
136
+ else
137
+ {
138
+ // Create completely new blocks here.
139
+ if ( dir || item.element.hasAttributes() || paragraphMode != CKEDITOR.ENTER_BR )
140
+ {
141
+ currentListItem = doc.createElement( paragraphName );
142
+ item.element.copyAttributes( currentListItem, { type:1, value:1 } );
143
+
144
+ // There might be a case where there are no attributes in the element after all
145
+ // (i.e. when "type" or "value" are the only attributes set). In this case, if enterMode = BR,
146
+ // the current item should be a fragment.
147
+ if ( !dir && paragraphMode == CKEDITOR.ENTER_BR && !currentListItem.hasAttributes() )
148
+ currentListItem = new CKEDITOR.dom.documentFragment( doc );
149
+ }
150
+ else
151
+ currentListItem = new CKEDITOR.dom.documentFragment( doc );
152
+ }
153
+
154
+ if ( currentListItem.type == CKEDITOR.NODE_ELEMENT )
155
+ {
156
+ if ( item.grandparent.getDirection( 1 ) != orgDir )
157
+ currentListItem.setAttribute( 'dir', orgDir );
158
+ else
159
+ currentListItem.removeAttribute( 'dir' );
160
+ }
161
+
162
+ for ( i = 0 ; i < item.contents.length ; i++ )
163
+ currentListItem.append( item.contents[i].clone( 1, 1 ) );
164
+
165
+ if ( currentListItem.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT
166
+ && currentIndex != listArray.length - 1 )
167
+ {
168
+ var last = currentListItem.getLast();
169
+ if ( last && last.type == CKEDITOR.NODE_ELEMENT
170
+ && last.getAttribute( 'type' ) == '_moz' )
171
+ {
172
+ last.remove();
173
+ }
174
+
175
+ if ( !( last = currentListItem.getLast( nonEmpty )
176
+ && last.type == CKEDITOR.NODE_ELEMENT
177
+ && last.getName() in CKEDITOR.dtd.$block ) )
178
+ {
179
+ currentListItem.append( doc.createElement( 'br' ) );
180
+ }
181
+ }
182
+
183
+ if ( currentListItem.type == CKEDITOR.NODE_ELEMENT &&
184
+ currentListItem.getName() == paragraphName &&
185
+ currentListItem.$.firstChild )
186
+ {
187
+ currentListItem.trim();
188
+ var firstChild = currentListItem.getFirst();
189
+ if ( firstChild.type == CKEDITOR.NODE_ELEMENT && firstChild.isBlockBoundary() )
190
+ {
191
+ var tmp = new CKEDITOR.dom.documentFragment( doc );
192
+ currentListItem.moveChildren( tmp );
193
+ currentListItem = tmp;
194
+ }
195
+ }
196
+
197
+ var currentListItemName = currentListItem.$.nodeName.toLowerCase();
198
+ if ( !CKEDITOR.env.ie && ( currentListItemName == 'div' || currentListItemName == 'p' ) )
199
+ currentListItem.appendBogus();
200
+ retval.append( currentListItem );
201
+ rootNode = null;
202
+ currentIndex++;
203
+ }
204
+ else
205
+ return null;
206
+
207
+ if ( listArray.length <= currentIndex || Math.max( listArray[ currentIndex ].indent, 0 ) < indentLevel )
208
+ break;
209
+ }
210
+
211
+ // Clear marker attributes for the new list tree made of cloned nodes, if any.
212
+ if ( database )
213
+ {
214
+ var currentNode = retval.getFirst();
215
+ while ( currentNode )
216
+ {
217
+ if ( currentNode.type == CKEDITOR.NODE_ELEMENT )
218
+ CKEDITOR.dom.element.clearMarkers( database, currentNode );
219
+ currentNode = currentNode.getNextSourceNode();
220
+ }
221
+ }
222
+
223
+ return { listNode : retval, nextIndex : currentIndex };
224
+ }
225
+ };
226
+
227
+ function onSelectionChange( evt )
228
+ {
229
+ if ( evt.editor.readOnly )
230
+ return null;
231
+
232
+ var path = evt.data.path,
233
+ blockLimit = path.blockLimit,
234
+ elements = path.elements,
235
+ element,
236
+ i;
237
+
238
+ // Grouping should only happen under blockLimit.(#3940).
239
+ for ( i = 0 ; i < elements.length && ( element = elements[ i ] )
240
+ && !element.equals( blockLimit ); i++ )
241
+ {
242
+ if ( listNodeNames[ elements[ i ].getName() ] )
243
+ return this.setState( this.type == elements[ i ].getName() ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );
244
+ }
245
+
246
+ return this.setState( CKEDITOR.TRISTATE_OFF );
247
+ }
248
+
249
+ function changeListType( editor, groupObj, database, listsCreated )
250
+ {
251
+ // This case is easy...
252
+ // 1. Convert the whole list into a one-dimensional array.
253
+ // 2. Change the list type by modifying the array.
254
+ // 3. Recreate the whole list by converting the array to a list.
255
+ // 4. Replace the original list with the recreated list.
256
+ var listArray = CKEDITOR.plugins.list.listToArray( groupObj.root, database ),
257
+ selectedListItems = [];
258
+
259
+ for ( var i = 0 ; i < groupObj.contents.length ; i++ )
260
+ {
261
+ var itemNode = groupObj.contents[i];
262
+ itemNode = itemNode.getAscendant( 'li', true );
263
+ if ( !itemNode || itemNode.getCustomData( 'list_item_processed' ) )
264
+ continue;
265
+ selectedListItems.push( itemNode );
266
+ CKEDITOR.dom.element.setMarker( database, itemNode, 'list_item_processed', true );
267
+ }
268
+
269
+ var root = groupObj.root,
270
+ fakeParent = root.getDocument().createElement( this.type );
271
+ // Copy all attributes, except from 'start' and 'type'.
272
+ root.copyAttributes( fakeParent, { start : 1, type : 1 } );
273
+ // The list-style-type property should be ignored.
274
+ fakeParent.removeStyle( 'list-style-type' );
275
+
276
+ for ( i = 0 ; i < selectedListItems.length ; i++ )
277
+ {
278
+ var listIndex = selectedListItems[i].getCustomData( 'listarray_index' );
279
+ listArray[listIndex].parent = fakeParent;
280
+ }
281
+ var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode );
282
+ var child, length = newList.listNode.getChildCount();
283
+ for ( i = 0 ; i < length && ( child = newList.listNode.getChild( i ) ) ; i++ )
284
+ {
285
+ if ( child.getName() == this.type )
286
+ listsCreated.push( child );
287
+ }
288
+ newList.listNode.replace( groupObj.root );
289
+ }
290
+
291
+ var headerTagRegex = /^h[1-6]$/;
292
+
293
+ function createList( editor, groupObj, listsCreated )
294
+ {
295
+ var contents = groupObj.contents,
296
+ doc = groupObj.root.getDocument(),
297
+ listContents = [];
298
+
299
+ // It is possible to have the contents returned by DomRangeIterator to be the same as the root.
300
+ // e.g. when we're running into table cells.
301
+ // In such a case, enclose the childNodes of contents[0] into a <div>.
302
+ if ( contents.length == 1 && contents[0].equals( groupObj.root ) )
303
+ {
304
+ var divBlock = doc.createElement( 'div' );
305
+ contents[0].moveChildren && contents[0].moveChildren( divBlock );
306
+ contents[0].append( divBlock );
307
+ contents[0] = divBlock;
308
+ }
309
+
310
+ // Calculate the common parent node of all content blocks.
311
+ var commonParent = groupObj.contents[0].getParent();
312
+ for ( var i = 0 ; i < contents.length ; i++ )
313
+ commonParent = commonParent.getCommonAncestor( contents[i].getParent() );
314
+
315
+ var useComputedState = editor.config.useComputedState,
316
+ listDir, explicitDirection;
317
+
318
+ useComputedState = useComputedState === undefined || useComputedState;
319
+
320
+ // We want to insert things that are in the same tree level only, so calculate the contents again
321
+ // by expanding the selected blocks to the same tree level.
322
+ for ( i = 0 ; i < contents.length ; i++ )
323
+ {
324
+ var contentNode = contents[i],
325
+ parentNode;
326
+ while ( ( parentNode = contentNode.getParent() ) )
327
+ {
328
+ if ( parentNode.equals( commonParent ) )
329
+ {
330
+ listContents.push( contentNode );
331
+
332
+ // Determine the lists's direction.
333
+ if ( !explicitDirection && contentNode.getDirection() )
334
+ explicitDirection = 1;
335
+
336
+ var itemDir = contentNode.getDirection( useComputedState );
337
+
338
+ if ( listDir !== null )
339
+ {
340
+ // If at least one LI have a different direction than current listDir, we can't have listDir.
341
+ if ( listDir && listDir != itemDir )
342
+ listDir = null;
343
+ else
344
+ listDir = itemDir;
345
+ }
346
+
347
+ break;
348
+ }
349
+ contentNode = parentNode;
350
+ }
351
+ }
352
+
353
+ if ( listContents.length < 1 )
354
+ return;
355
+
356
+ // Insert the list to the DOM tree.
357
+ var insertAnchor = listContents[ listContents.length - 1 ].getNext(),
358
+ listNode = doc.createElement( this.type );
359
+
360
+ listsCreated.push( listNode );
361
+
362
+ var contentBlock, listItem;
363
+
364
+ while ( listContents.length )
365
+ {
366
+ contentBlock = listContents.shift();
367
+ listItem = doc.createElement( 'li' );
368
+
369
+ // Preserve preformat block and heading structure when converting to list item. (#5335) (#5271)
370
+ if ( contentBlock.is( 'pre' ) || headerTagRegex.test( contentBlock.getName() ) )
371
+ contentBlock.appendTo( listItem );
372
+ else
373
+ {
374
+ contentBlock.copyAttributes( listItem );
375
+ // Remove direction attribute after it was merged into list root. (#7657)
376
+ if ( listDir && contentBlock.getDirection() )
377
+ {
378
+ listItem.removeStyle( 'direction' );
379
+ listItem.removeAttribute( 'dir' );
380
+ }
381
+ contentBlock.moveChildren( listItem );
382
+ contentBlock.remove();
383
+ }
384
+
385
+ listItem.appendTo( listNode );
386
+ }
387
+
388
+ // Apply list root dir only if it has been explicitly declared.
389
+ if ( listDir && explicitDirection )
390
+ listNode.setAttribute( 'dir', listDir );
391
+
392
+ if ( insertAnchor )
393
+ listNode.insertBefore( insertAnchor );
394
+ else
395
+ listNode.appendTo( commonParent );
396
+ }
397
+
398
+ function removeList( editor, groupObj, database )
399
+ {
400
+ // This is very much like the change list type operation.
401
+ // Except that we're changing the selected items' indent to -1 in the list array.
402
+ var listArray = CKEDITOR.plugins.list.listToArray( groupObj.root, database ),
403
+ selectedListItems = [];
404
+
405
+ for ( var i = 0 ; i < groupObj.contents.length ; i++ )
406
+ {
407
+ var itemNode = groupObj.contents[i];
408
+ itemNode = itemNode.getAscendant( 'li', true );
409
+ if ( !itemNode || itemNode.getCustomData( 'list_item_processed' ) )
410
+ continue;
411
+ selectedListItems.push( itemNode );
412
+ CKEDITOR.dom.element.setMarker( database, itemNode, 'list_item_processed', true );
413
+ }
414
+
415
+ var lastListIndex = null;
416
+ for ( i = 0 ; i < selectedListItems.length ; i++ )
417
+ {
418
+ var listIndex = selectedListItems[i].getCustomData( 'listarray_index' );
419
+ listArray[listIndex].indent = -1;
420
+ lastListIndex = listIndex;
421
+ }
422
+
423
+ // After cutting parts of the list out with indent=-1, we still have to maintain the array list
424
+ // model's nextItem.indent <= currentItem.indent + 1 invariant. Otherwise the array model of the
425
+ // list cannot be converted back to a real DOM list.
426
+ for ( i = lastListIndex + 1 ; i < listArray.length ; i++ )
427
+ {
428
+ if ( listArray[i].indent > listArray[i-1].indent + 1 )
429
+ {
430
+ var indentOffset = listArray[i-1].indent + 1 - listArray[i].indent;
431
+ var oldIndent = listArray[i].indent;
432
+ while ( listArray[i] && listArray[i].indent >= oldIndent )
433
+ {
434
+ listArray[i].indent += indentOffset;
435
+ i++;
436
+ }
437
+ i--;
438
+ }
439
+ }
440
+
441
+ var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode,
442
+ groupObj.root.getAttribute( 'dir' ) );
443
+
444
+ // Compensate <br> before/after the list node if the surrounds are non-blocks.(#3836)
445
+ var docFragment = newList.listNode, boundaryNode, siblingNode;
446
+ function compensateBrs( isStart )
447
+ {
448
+ if ( ( boundaryNode = docFragment[ isStart ? 'getFirst' : 'getLast' ]() )
449
+ && !( boundaryNode.is && boundaryNode.isBlockBoundary() )
450
+ && ( siblingNode = groupObj.root[ isStart ? 'getPrevious' : 'getNext' ]
451
+ ( CKEDITOR.dom.walker.whitespaces( true ) ) )
452
+ && !( siblingNode.is && siblingNode.isBlockBoundary( { br : 1 } ) ) )
453
+ editor.document.createElement( 'br' )[ isStart ? 'insertBefore' : 'insertAfter' ]( boundaryNode );
454
+ }
455
+ compensateBrs( true );
456
+ compensateBrs();
457
+
458
+ docFragment.replace( groupObj.root );
459
+ }
460
+
461
+ function listCommand( name, type )
462
+ {
463
+ this.name = name;
464
+ this.type = type;
465
+ }
466
+
467
+ listCommand.prototype = {
468
+ exec : function( editor )
469
+ {
470
+ var doc = editor.document,
471
+ config = editor.config,
472
+ selection = editor.getSelection(),
473
+ ranges = selection && selection.getRanges( true );
474
+
475
+ // There should be at least one selected range.
476
+ if ( !ranges || ranges.length < 1 )
477
+ return;
478
+
479
+ // Midas lists rule #1 says we can create a list even in an empty document.
480
+ // But DOM iterator wouldn't run if the document is really empty.
481
+ // So create a paragraph if the document is empty and we're going to create a list.
482
+ if ( this.state == CKEDITOR.TRISTATE_OFF )
483
+ {
484
+ var body = doc.getBody();
485
+ if ( !body.getFirst( nonEmpty ) )
486
+ {
487
+ config.enterMode == CKEDITOR.ENTER_BR ?
488
+ body.appendBogus() :
489
+ ranges[ 0 ].fixBlock( 1, config.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' );
490
+
491
+ selection.selectRanges( ranges );
492
+ }
493
+ // Maybe a single range there enclosing the whole list,
494
+ // turn on the list state manually(#4129).
495
+ else
496
+ {
497
+ var range = ranges.length == 1 && ranges[ 0 ],
498
+ enclosedNode = range && range.getEnclosedNode();
499
+ if ( enclosedNode && enclosedNode.is
500
+ && this.type == enclosedNode.getName() )
501
+ this.setState( CKEDITOR.TRISTATE_ON );
502
+ }
503
+ }
504
+
505
+ var bookmarks = selection.createBookmarks( true );
506
+
507
+ // Group the blocks up because there are many cases where multiple lists have to be created,
508
+ // or multiple lists have to be cancelled.
509
+ var listGroups = [],
510
+ database = {},
511
+ rangeIterator = ranges.createIterator(),
512
+ index = 0;
513
+
514
+ while ( ( range = rangeIterator.getNextRange() ) && ++index )
515
+ {
516
+ var boundaryNodes = range.getBoundaryNodes(),
517
+ startNode = boundaryNodes.startNode,
518
+ endNode = boundaryNodes.endNode;
519
+
520
+ if ( startNode.type == CKEDITOR.NODE_ELEMENT && startNode.getName() == 'td' )
521
+ range.setStartAt( boundaryNodes.startNode, CKEDITOR.POSITION_AFTER_START );
522
+
523
+ if ( endNode.type == CKEDITOR.NODE_ELEMENT && endNode.getName() == 'td' )
524
+ range.setEndAt( boundaryNodes.endNode, CKEDITOR.POSITION_BEFORE_END );
525
+
526
+ var iterator = range.createIterator(),
527
+ block;
528
+
529
+ iterator.forceBrBreak = ( this.state == CKEDITOR.TRISTATE_OFF );
530
+
531
+ while ( ( block = iterator.getNextParagraph() ) )
532
+ {
533
+ // Avoid duplicate blocks get processed across ranges.
534
+ if( block.getCustomData( 'list_block' ) )
535
+ continue;
536
+ else
537
+ CKEDITOR.dom.element.setMarker( database, block, 'list_block', 1 );
538
+
539
+ var path = new CKEDITOR.dom.elementPath( block ),
540
+ pathElements = path.elements,
541
+ pathElementsCount = pathElements.length,
542
+ listNode = null,
543
+ processedFlag = 0,
544
+ blockLimit = path.blockLimit,
545
+ element;
546
+
547
+ // First, try to group by a list ancestor.
548
+ for ( var i = pathElementsCount - 1; i >= 0 && ( element = pathElements[ i ] ); i-- )
549
+ {
550
+ if ( listNodeNames[ element.getName() ]
551
+ && blockLimit.contains( element ) ) // Don't leak outside block limit (#3940).
552
+ {
553
+ // If we've encountered a list inside a block limit
554
+ // The last group object of the block limit element should
555
+ // no longer be valid. Since paragraphs after the list
556
+ // should belong to a different group of paragraphs before
557
+ // the list. (Bug #1309)
558
+ blockLimit.removeCustomData( 'list_group_object_' + index );
559
+
560
+ var groupObj = element.getCustomData( 'list_group_object' );
561
+ if ( groupObj )
562
+ groupObj.contents.push( block );
563
+ else
564
+ {
565
+ groupObj = { root : element, contents : [ block ] };
566
+ listGroups.push( groupObj );
567
+ CKEDITOR.dom.element.setMarker( database, element, 'list_group_object', groupObj );
568
+ }
569
+ processedFlag = 1;
570
+ break;
571
+ }
572
+ }
573
+
574
+ if ( processedFlag )
575
+ continue;
576
+
577
+ // No list ancestor? Group by block limit, but don't mix contents from different ranges.
578
+ var root = blockLimit;
579
+ if ( root.getCustomData( 'list_group_object_' + index ) )
580
+ root.getCustomData( 'list_group_object_' + index ).contents.push( block );
581
+ else
582
+ {
583
+ groupObj = { root : root, contents : [ block ] };
584
+ CKEDITOR.dom.element.setMarker( database, root, 'list_group_object_' + index, groupObj );
585
+ listGroups.push( groupObj );
586
+ }
587
+ }
588
+ }
589
+
590
+ // Now we have two kinds of list groups, groups rooted at a list, and groups rooted at a block limit element.
591
+ // We either have to build lists or remove lists, for removing a list does not makes sense when we are looking
592
+ // at the group that's not rooted at lists. So we have three cases to handle.
593
+ var listsCreated = [];
594
+ while ( listGroups.length > 0 )
595
+ {
596
+ groupObj = listGroups.shift();
597
+ if ( this.state == CKEDITOR.TRISTATE_OFF )
598
+ {
599
+ if ( listNodeNames[ groupObj.root.getName() ] )
600
+ changeListType.call( this, editor, groupObj, database, listsCreated );
601
+ else
602
+ createList.call( this, editor, groupObj, listsCreated );
603
+ }
604
+ else if ( this.state == CKEDITOR.TRISTATE_ON && listNodeNames[ groupObj.root.getName() ] )
605
+ removeList.call( this, editor, groupObj, database );
606
+ }
607
+
608
+ // For all new lists created, merge adjacent, same type lists.
609
+ for ( i = 0 ; i < listsCreated.length ; i++ )
610
+ {
611
+ listNode = listsCreated[i];
612
+ var mergeSibling, listCommand = this;
613
+ ( mergeSibling = function( rtl ){
614
+
615
+ var sibling = listNode[ rtl ?
616
+ 'getPrevious' : 'getNext' ]( CKEDITOR.dom.walker.whitespaces( true ) );
617
+ if ( sibling && sibling.getName &&
618
+ sibling.getName() == listCommand.type )
619
+ {
620
+ sibling.remove();
621
+ // Move children order by merge direction.(#3820)
622
+ sibling.moveChildren( listNode, rtl );
623
+ }
624
+ } )();
625
+ mergeSibling( 1 );
626
+ }
627
+
628
+ // Clean up, restore selection and update toolbar button states.
629
+ CKEDITOR.dom.element.clearAllMarkers( database );
630
+ selection.selectBookmarks( bookmarks );
631
+ editor.focus();
632
+ }
633
+ };
634
+
635
+ var dtd = CKEDITOR.dtd;
636
+ var tailNbspRegex = /[\t\r\n ]*(?:&nbsp;|\xa0)$/;
637
+
638
+ function indexOfFirstChildElement( element, tagNameList )
639
+ {
640
+ var child,
641
+ children = element.children,
642
+ length = children.length;
643
+
644
+ for ( var i = 0 ; i < length ; i++ )
645
+ {
646
+ child = children[ i ];
647
+ if ( child.name && ( child.name in tagNameList ) )
648
+ return i;
649
+ }
650
+
651
+ return length;
652
+ }
653
+
654
+ function getExtendNestedListFilter( isHtmlFilter )
655
+ {
656
+ // An element filter function that corrects nested list start in an empty
657
+ // list item for better displaying/outputting. (#3165)
658
+ return function( listItem )
659
+ {
660
+ var children = listItem.children,
661
+ firstNestedListIndex = indexOfFirstChildElement( listItem, dtd.$list ),
662
+ firstNestedList = children[ firstNestedListIndex ],
663
+ nodeBefore = firstNestedList && firstNestedList.previous,
664
+ tailNbspmatch;
665
+
666
+ if ( nodeBefore
667
+ && ( nodeBefore.name && nodeBefore.name == 'br'
668
+ || nodeBefore.value && ( tailNbspmatch = nodeBefore.value.match( tailNbspRegex ) ) ) )
669
+ {
670
+ var fillerNode = nodeBefore;
671
+
672
+ // Always use 'nbsp' as filler node if we found a nested list appear
673
+ // in front of a list item.
674
+ if ( !( tailNbspmatch && tailNbspmatch.index ) && fillerNode == children[ 0 ] )
675
+ children[ 0 ] = ( isHtmlFilter || CKEDITOR.env.ie ) ?
676
+ new CKEDITOR.htmlParser.text( '\xa0' ) :
677
+ new CKEDITOR.htmlParser.element( 'br', {} );
678
+
679
+ // Otherwise the filler is not needed anymore.
680
+ else if ( fillerNode.name == 'br' )
681
+ children.splice( firstNestedListIndex - 1, 1 );
682
+ else
683
+ fillerNode.value = fillerNode.value.replace( tailNbspRegex, '' );
684
+ }
685
+
686
+ };
687
+ }
688
+
689
+ var defaultListDataFilterRules = { elements : {} };
690
+ for ( var i in dtd.$listItem )
691
+ defaultListDataFilterRules.elements[ i ] = getExtendNestedListFilter();
692
+
693
+ var defaultListHtmlFilterRules = { elements : {} };
694
+ for ( i in dtd.$listItem )
695
+ defaultListHtmlFilterRules.elements[ i ] = getExtendNestedListFilter( true );
696
+
697
+ CKEDITOR.plugins.add( 'list',
698
+ {
699
+ init : function( editor )
700
+ {
701
+ // Register commands.
702
+ var numberedListCommand = editor.addCommand( 'numberedlist', new listCommand( 'numberedlist', 'ol' ) ),
703
+ bulletedListCommand = editor.addCommand( 'bulletedlist', new listCommand( 'bulletedlist', 'ul' ) );
704
+
705
+ // Register the toolbar button.
706
+ editor.ui.addButton( 'NumberedList',
707
+ {
708
+ label : editor.lang.numberedlist,
709
+ command : 'numberedlist'
710
+ } );
711
+ editor.ui.addButton( 'BulletedList',
712
+ {
713
+ label : editor.lang.bulletedlist,
714
+ command : 'bulletedlist'
715
+ } );
716
+
717
+ // Register the state changing handlers.
718
+ editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, numberedListCommand ) );
719
+ editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, bulletedListCommand ) );
720
+ },
721
+
722
+ afterInit : function ( editor )
723
+ {
724
+ var dataProcessor = editor.dataProcessor;
725
+ if ( dataProcessor )
726
+ {
727
+ dataProcessor.dataFilter.addRules( defaultListDataFilterRules );
728
+ dataProcessor.htmlFilter.addRules( defaultListHtmlFilterRules );
729
+ }
730
+ },
731
+
732
+ requires : [ 'domiterator' ]
733
+ } );
734
+ })();