integral 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (430) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/logo.png +0 -0
  3. data/app/assets/javascripts/ckeditor/my_config.js.erb +26 -18
  4. data/app/assets/javascripts/ckeditor/plugins/autoembed/lang/lv.js +8 -0
  5. data/app/assets/javascripts/ckeditor/plugins/autoembed/plugin.js +1 -1
  6. data/app/assets/javascripts/ckeditor/plugins/autogrow/plugin.js +14 -14
  7. data/app/assets/javascripts/ckeditor/plugins/autogrow/samples/autogrow.html +8 -8
  8. data/app/assets/javascripts/ckeditor/plugins/codemirror/css/codemirror.min.css +1 -1
  9. data/app/assets/javascripts/ckeditor/plugins/codemirror/icons/autoformat.png +0 -0
  10. data/app/assets/javascripts/ckeditor/plugins/codemirror/icons/searchcode.png +0 -0
  11. data/app/assets/javascripts/ckeditor/plugins/codemirror/icons/uncommentselectedrange.png +0 -0
  12. data/app/assets/javascripts/ckeditor/plugins/codemirror/images/autocomplete.png +0 -0
  13. data/app/assets/javascripts/ckeditor/plugins/codemirror/images/autoformat.png +0 -0
  14. data/app/assets/javascripts/ckeditor/plugins/codemirror/images/commentselectedrange.png +0 -0
  15. data/app/assets/javascripts/ckeditor/plugins/codemirror/images/searchcode.png +0 -0
  16. data/app/assets/javascripts/ckeditor/plugins/codemirror/images/uncommentselectedrange.png +0 -0
  17. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/beautify.min.js +2 -2
  18. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.addons.min.js +2 -2
  19. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.addons.search.min.js +1 -1
  20. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.min.js +1 -6
  21. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.bbcodemixed.min.js +1 -1
  22. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.handlebars.min.js +1 -0
  23. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.htmlmixed.min.js +2 -2
  24. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.javascript.min.js +1 -1
  25. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.php.min.js +3 -3
  26. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.twig.min.js +1 -1
  27. data/app/assets/javascripts/ckeditor/plugins/codemirror/lang/bg.js +7 -7
  28. data/app/assets/javascripts/ckeditor/plugins/codemirror/plugin.js +231 -217
  29. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/darcula.css +46 -0
  30. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/gruvbox-dark.css +34 -0
  31. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/idea.css +42 -0
  32. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/lesser-dark.css +1 -1
  33. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/lucario.css +37 -0
  34. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/monokai.css +5 -0
  35. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/oceanic-next.css +44 -0
  36. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/shadowfox.css +52 -0
  37. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/ssms.css +16 -0
  38. data/app/assets/javascripts/ckeditor/plugins/embedbase/lang/ar.js +15 -0
  39. data/app/assets/javascripts/ckeditor/plugins/embedbase/lang/lv.js +15 -0
  40. data/app/assets/javascripts/ckeditor/plugins/embedbase/plugin.js +1 -1
  41. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/copywidget.png +0 -0
  42. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/editwidget.png +0 -0
  43. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/hidpi/copywidget.png +0 -0
  44. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/hidpi/editwidget.png +0 -0
  45. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/hidpi/removewidget.png +0 -0
  46. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/hidpi/widget.png +0 -0
  47. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/removewidget.png +0 -0
  48. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/widget.png +0 -0
  49. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/plugin.js +86 -0
  50. data/app/assets/javascripts/ckeditor/plugins/image2/dev/assets/image1.jpg +0 -0
  51. data/app/assets/javascripts/ckeditor/plugins/image2/dev/assets/image2.jpg +0 -0
  52. data/app/assets/javascripts/ckeditor/plugins/image2/dev/contents.css +35 -0
  53. data/app/assets/javascripts/ckeditor/plugins/image2/dev/image2.html +339 -0
  54. data/app/assets/javascripts/ckeditor/plugins/image2/dialogs/image2.js +553 -0
  55. data/app/assets/javascripts/ckeditor/plugins/image2/icons/hidpi/image.png +0 -0
  56. data/app/assets/javascripts/ckeditor/plugins/image2/icons/image.png +0 -0
  57. data/app/assets/javascripts/ckeditor/plugins/image2/lang/af.js +21 -0
  58. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ar.js +21 -0
  59. data/app/assets/javascripts/ckeditor/plugins/image2/lang/az.js +21 -0
  60. data/app/assets/javascripts/ckeditor/plugins/image2/lang/bg.js +21 -0
  61. data/app/assets/javascripts/ckeditor/plugins/image2/lang/bn.js +21 -0
  62. data/app/assets/javascripts/ckeditor/plugins/image2/lang/bs.js +21 -0
  63. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ca.js +21 -0
  64. data/app/assets/javascripts/ckeditor/plugins/image2/lang/cs.js +21 -0
  65. data/app/assets/javascripts/ckeditor/plugins/image2/lang/cy.js +21 -0
  66. data/app/assets/javascripts/ckeditor/plugins/image2/lang/da.js +21 -0
  67. data/app/assets/javascripts/ckeditor/plugins/image2/lang/de-ch.js +21 -0
  68. data/app/assets/javascripts/ckeditor/plugins/image2/lang/de.js +21 -0
  69. data/app/assets/javascripts/ckeditor/plugins/image2/lang/el.js +21 -0
  70. data/app/assets/javascripts/ckeditor/plugins/image2/lang/en-au.js +21 -0
  71. data/app/assets/javascripts/ckeditor/plugins/image2/lang/en-ca.js +21 -0
  72. data/app/assets/javascripts/ckeditor/plugins/image2/lang/en-gb.js +21 -0
  73. data/app/assets/javascripts/ckeditor/plugins/image2/lang/en.js +21 -0
  74. data/app/assets/javascripts/ckeditor/plugins/image2/lang/eo.js +21 -0
  75. data/app/assets/javascripts/ckeditor/plugins/image2/lang/es-mx.js +21 -0
  76. data/app/assets/javascripts/ckeditor/plugins/image2/lang/es.js +21 -0
  77. data/app/assets/javascripts/ckeditor/plugins/image2/lang/et.js +21 -0
  78. data/app/assets/javascripts/ckeditor/plugins/image2/lang/eu.js +21 -0
  79. data/app/assets/javascripts/ckeditor/plugins/image2/lang/fa.js +21 -0
  80. data/app/assets/javascripts/ckeditor/plugins/image2/lang/fi.js +21 -0
  81. data/app/assets/javascripts/ckeditor/plugins/image2/lang/fo.js +21 -0
  82. data/app/assets/javascripts/ckeditor/plugins/image2/lang/fr-ca.js +21 -0
  83. data/app/assets/javascripts/ckeditor/plugins/image2/lang/fr.js +21 -0
  84. data/app/assets/javascripts/ckeditor/plugins/image2/lang/gl.js +21 -0
  85. data/app/assets/javascripts/ckeditor/plugins/image2/lang/gu.js +21 -0
  86. data/app/assets/javascripts/ckeditor/plugins/image2/lang/he.js +21 -0
  87. data/app/assets/javascripts/ckeditor/plugins/image2/lang/hi.js +21 -0
  88. data/app/assets/javascripts/ckeditor/plugins/image2/lang/hr.js +21 -0
  89. data/app/assets/javascripts/ckeditor/plugins/image2/lang/hu.js +21 -0
  90. data/app/assets/javascripts/ckeditor/plugins/image2/lang/id.js +21 -0
  91. data/app/assets/javascripts/ckeditor/plugins/image2/lang/is.js +21 -0
  92. data/app/assets/javascripts/ckeditor/plugins/image2/lang/it.js +21 -0
  93. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ja.js +21 -0
  94. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ka.js +21 -0
  95. data/app/assets/javascripts/ckeditor/plugins/image2/lang/km.js +21 -0
  96. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ko.js +21 -0
  97. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ku.js +21 -0
  98. data/app/assets/javascripts/ckeditor/plugins/image2/lang/lt.js +21 -0
  99. data/app/assets/javascripts/ckeditor/plugins/image2/lang/lv.js +21 -0
  100. data/app/assets/javascripts/ckeditor/plugins/image2/lang/mk.js +21 -0
  101. data/app/assets/javascripts/ckeditor/plugins/image2/lang/mn.js +21 -0
  102. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ms.js +21 -0
  103. data/app/assets/javascripts/ckeditor/plugins/image2/lang/nb.js +21 -0
  104. data/app/assets/javascripts/ckeditor/plugins/image2/lang/nl.js +21 -0
  105. data/app/assets/javascripts/ckeditor/plugins/image2/lang/no.js +21 -0
  106. data/app/assets/javascripts/ckeditor/plugins/image2/lang/oc.js +21 -0
  107. data/app/assets/javascripts/ckeditor/plugins/image2/lang/pl.js +21 -0
  108. data/app/assets/javascripts/ckeditor/plugins/image2/lang/pt-br.js +21 -0
  109. data/app/assets/javascripts/ckeditor/plugins/image2/lang/pt.js +21 -0
  110. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ro.js +21 -0
  111. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ru.js +21 -0
  112. data/app/assets/javascripts/ckeditor/plugins/image2/lang/si.js +21 -0
  113. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sk.js +21 -0
  114. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sl.js +21 -0
  115. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sq.js +21 -0
  116. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sr-latn.js +21 -0
  117. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sr.js +21 -0
  118. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sv.js +21 -0
  119. data/app/assets/javascripts/ckeditor/plugins/image2/lang/th.js +21 -0
  120. data/app/assets/javascripts/ckeditor/plugins/image2/lang/tr.js +21 -0
  121. data/app/assets/javascripts/ckeditor/plugins/image2/lang/tt.js +21 -0
  122. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ug.js +21 -0
  123. data/app/assets/javascripts/ckeditor/plugins/image2/lang/uk.js +21 -0
  124. data/app/assets/javascripts/ckeditor/plugins/image2/lang/vi.js +21 -0
  125. data/app/assets/javascripts/ckeditor/plugins/image2/lang/zh-cn.js +21 -0
  126. data/app/assets/javascripts/ckeditor/plugins/image2/lang/zh.js +21 -0
  127. data/app/assets/javascripts/ckeditor/plugins/image2/plugin.js +1720 -0
  128. data/app/assets/javascripts/ckeditor/plugins/image2/samples/assets/image1.jpg +0 -0
  129. data/app/assets/javascripts/ckeditor/plugins/image2/samples/assets/image2.jpg +0 -0
  130. data/app/assets/javascripts/ckeditor/plugins/image2/samples/image2.html +68 -0
  131. data/app/assets/javascripts/ckeditor/plugins/integral-card/icons/copywidget.png +0 -0
  132. data/app/assets/javascripts/ckeditor/plugins/integral-card/icons/editwidget.png +0 -0
  133. data/app/assets/javascripts/ckeditor/plugins/integral-card/icons/hidpi/copywidget.png +0 -0
  134. data/app/assets/javascripts/ckeditor/plugins/integral-card/icons/hidpi/editwidget.png +0 -0
  135. data/app/assets/javascripts/ckeditor/plugins/integral-card/icons/hidpi/removewidget.png +0 -0
  136. data/app/assets/javascripts/ckeditor/plugins/integral-card/icons/hidpi/widget.png +0 -0
  137. data/app/assets/javascripts/ckeditor/plugins/integral-card/icons/removewidget.png +0 -0
  138. data/app/assets/javascripts/ckeditor/plugins/integral-card/icons/widget.png +0 -0
  139. data/app/assets/javascripts/ckeditor/plugins/integral-card/plugin.js +86 -0
  140. data/app/assets/javascripts/ckeditor/plugins/integralrecentposts/dialogs/integralrecentposts.js +40 -0
  141. data/app/assets/javascripts/ckeditor/plugins/integralrecentposts/plugin.js +32 -0
  142. data/app/assets/javascripts/ckeditor/plugins/lineutils/dev/dnd.html +4 -4
  143. data/app/assets/javascripts/ckeditor/plugins/lineutils/dev/magicfinger.html +4 -4
  144. data/app/assets/javascripts/ckeditor/plugins/lineutils/plugin.js +7 -7
  145. data/app/assets/javascripts/ckeditor/plugins/linkballoon/README.md +5 -0
  146. data/app/assets/javascripts/ckeditor/plugins/linkballoon/assets/demo.png +0 -0
  147. data/app/assets/javascripts/ckeditor/plugins/linkballoon/plugin.js +25 -0
  148. data/app/assets/javascripts/ckeditor/plugins/notification/lang/az.js +7 -0
  149. data/app/assets/javascripts/ckeditor/plugins/notification/lang/bg.js +7 -0
  150. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ca.js +7 -0
  151. data/app/assets/javascripts/ckeditor/plugins/notification/lang/cs.js +2 -2
  152. data/app/assets/javascripts/ckeditor/plugins/notification/lang/da.js +2 -2
  153. data/app/assets/javascripts/ckeditor/plugins/notification/lang/de-ch.js +2 -2
  154. data/app/assets/javascripts/ckeditor/plugins/notification/lang/de.js +2 -2
  155. data/app/assets/javascripts/ckeditor/plugins/notification/lang/en-au.js +7 -0
  156. data/app/assets/javascripts/ckeditor/plugins/notification/lang/en.js +2 -2
  157. data/app/assets/javascripts/ckeditor/plugins/notification/lang/eo.js +2 -2
  158. data/app/assets/javascripts/ckeditor/plugins/notification/lang/es-mx.js +7 -0
  159. data/app/assets/javascripts/ckeditor/plugins/notification/lang/es.js +7 -0
  160. data/app/assets/javascripts/ckeditor/plugins/notification/lang/et.js +7 -0
  161. data/app/assets/javascripts/ckeditor/plugins/notification/lang/eu.js +2 -2
  162. data/app/assets/javascripts/ckeditor/plugins/notification/lang/fa.js +7 -0
  163. data/app/assets/javascripts/ckeditor/plugins/notification/lang/fr.js +3 -3
  164. data/app/assets/javascripts/ckeditor/plugins/notification/lang/gl.js +2 -2
  165. data/app/assets/javascripts/ckeditor/plugins/notification/lang/hr.js +7 -0
  166. data/app/assets/javascripts/ckeditor/plugins/notification/lang/hu.js +7 -0
  167. data/app/assets/javascripts/ckeditor/plugins/notification/lang/id.js +2 -2
  168. data/app/assets/javascripts/ckeditor/plugins/notification/lang/it.js +2 -2
  169. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ja.js +7 -0
  170. data/app/assets/javascripts/ckeditor/plugins/notification/lang/km.js +2 -2
  171. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ko.js +2 -2
  172. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ku.js +2 -2
  173. data/app/assets/javascripts/ckeditor/plugins/notification/lang/lv.js +7 -0
  174. data/app/assets/javascripts/ckeditor/plugins/notification/lang/nb.js +2 -2
  175. data/app/assets/javascripts/ckeditor/plugins/notification/lang/nl.js +2 -2
  176. data/app/assets/javascripts/ckeditor/plugins/notification/lang/oc.js +7 -0
  177. data/app/assets/javascripts/ckeditor/plugins/notification/lang/pl.js +2 -2
  178. data/app/assets/javascripts/ckeditor/plugins/notification/lang/pt-br.js +2 -2
  179. data/app/assets/javascripts/ckeditor/plugins/notification/lang/pt.js +2 -2
  180. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ro.js +7 -0
  181. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ru.js +2 -2
  182. data/app/assets/javascripts/ckeditor/plugins/notification/lang/sk.js +7 -0
  183. data/app/assets/javascripts/ckeditor/plugins/notification/lang/sq.js +7 -0
  184. data/app/assets/javascripts/ckeditor/plugins/notification/lang/sv.js +2 -2
  185. data/app/assets/javascripts/ckeditor/plugins/notification/lang/tr.js +2 -2
  186. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ug.js +2 -2
  187. data/app/assets/javascripts/ckeditor/plugins/notification/lang/uk.js +2 -2
  188. data/app/assets/javascripts/ckeditor/plugins/notification/lang/zh-cn.js +3 -3
  189. data/app/assets/javascripts/ckeditor/plugins/notification/lang/zh.js +2 -2
  190. data/app/assets/javascripts/ckeditor/plugins/notification/plugin.js +794 -784
  191. data/app/assets/javascripts/ckeditor/plugins/numericinput/LICENSE.md +363 -0
  192. data/app/assets/javascripts/ckeditor/plugins/numericinput/README.md +16 -0
  193. data/app/assets/javascripts/ckeditor/plugins/numericinput/plugin.js +354 -0
  194. data/app/assets/javascripts/ckeditor/plugins/openlink/README.md +50 -0
  195. data/app/assets/javascripts/ckeditor/plugins/openlink/icons/hidpi/openLink.png +0 -0
  196. data/app/assets/javascripts/ckeditor/plugins/openlink/icons/openLink.png +0 -0
  197. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/bg.js +7 -0
  198. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/de.js +7 -0
  199. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/en.js +7 -0
  200. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/pl.js +7 -0
  201. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/ru.js +7 -0
  202. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/uk.js +7 -0
  203. data/app/assets/javascripts/ckeditor/plugins/openlink/plugin.js +178 -0
  204. data/app/assets/javascripts/ckeditor/plugins/placeholder/dev/placeholder.html +5 -5
  205. data/app/assets/javascripts/ckeditor/plugins/placeholder/dialogs/placeholder.js +2 -2
  206. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/af.js +2 -2
  207. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ar.js +2 -2
  208. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/az.js +2 -2
  209. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/bg.js +5 -5
  210. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ca.js +2 -2
  211. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/cs.js +2 -2
  212. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/cy.js +2 -2
  213. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/da.js +2 -2
  214. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/de-ch.js +2 -2
  215. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/de.js +2 -2
  216. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/el.js +2 -2
  217. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/en-au.js +12 -0
  218. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/en-gb.js +2 -2
  219. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/en.js +2 -2
  220. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/eo.js +2 -2
  221. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/es-mx.js +2 -2
  222. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/es.js +2 -2
  223. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/et.js +2 -2
  224. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/eu.js +2 -2
  225. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/fa.js +2 -2
  226. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/fi.js +2 -2
  227. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/fr-ca.js +2 -2
  228. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/fr.js +2 -2
  229. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/gl.js +2 -2
  230. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/he.js +2 -2
  231. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/hr.js +2 -2
  232. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/hu.js +2 -2
  233. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/id.js +2 -2
  234. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/it.js +2 -2
  235. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ja.js +2 -2
  236. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/km.js +2 -2
  237. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ko.js +2 -2
  238. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ku.js +2 -2
  239. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/lv.js +5 -5
  240. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/nb.js +2 -2
  241. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/nl.js +2 -2
  242. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/no.js +2 -2
  243. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/oc.js +2 -2
  244. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/pl.js +2 -2
  245. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/pt-br.js +2 -2
  246. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/pt.js +2 -2
  247. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ro.js +12 -0
  248. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ru.js +2 -2
  249. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/si.js +2 -2
  250. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/sk.js +2 -2
  251. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/sl.js +2 -2
  252. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/sq.js +2 -2
  253. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/sv.js +2 -2
  254. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/th.js +2 -2
  255. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/tr.js +2 -2
  256. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/tt.js +2 -2
  257. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ug.js +2 -2
  258. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/uk.js +2 -2
  259. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/vi.js +2 -2
  260. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/zh-cn.js +2 -2
  261. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/zh.js +2 -2
  262. data/app/assets/javascripts/ckeditor/plugins/placeholder/plugin.js +3 -3
  263. data/app/assets/javascripts/ckeditor/plugins/placeholder/samples/placeholder.html +6 -6
  264. data/app/assets/javascripts/ckeditor/plugins/widget/dev/assets/simplebox/dialogs/simplebox.js +4 -4
  265. data/app/assets/javascripts/ckeditor/plugins/widget/dev/assets/simplebox/plugin.js +3 -3
  266. data/app/assets/javascripts/ckeditor/plugins/widget/dev/console.js +2 -2
  267. data/app/assets/javascripts/ckeditor/plugins/widget/dev/nestedwidgets.html +2 -2
  268. data/app/assets/javascripts/ckeditor/plugins/widget/dev/widgetstyles.html +2 -2
  269. data/app/assets/javascripts/ckeditor/plugins/widget/lang/af.js +2 -2
  270. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ar.js +2 -2
  271. data/app/assets/javascripts/ckeditor/plugins/widget/lang/az.js +2 -2
  272. data/app/assets/javascripts/ckeditor/plugins/widget/lang/bg.js +3 -3
  273. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ca.js +2 -2
  274. data/app/assets/javascripts/ckeditor/plugins/widget/lang/cs.js +2 -2
  275. data/app/assets/javascripts/ckeditor/plugins/widget/lang/cy.js +2 -2
  276. data/app/assets/javascripts/ckeditor/plugins/widget/lang/da.js +2 -2
  277. data/app/assets/javascripts/ckeditor/plugins/widget/lang/de-ch.js +2 -2
  278. data/app/assets/javascripts/ckeditor/plugins/widget/lang/de.js +2 -2
  279. data/app/assets/javascripts/ckeditor/plugins/widget/lang/el.js +2 -2
  280. data/app/assets/javascripts/ckeditor/plugins/widget/lang/en-au.js +8 -0
  281. data/app/assets/javascripts/ckeditor/plugins/widget/lang/en-gb.js +2 -2
  282. data/app/assets/javascripts/ckeditor/plugins/widget/lang/en.js +2 -2
  283. data/app/assets/javascripts/ckeditor/plugins/widget/lang/eo.js +2 -2
  284. data/app/assets/javascripts/ckeditor/plugins/widget/lang/es-mx.js +2 -2
  285. data/app/assets/javascripts/ckeditor/plugins/widget/lang/es.js +2 -2
  286. data/app/assets/javascripts/ckeditor/plugins/widget/lang/et.js +8 -0
  287. data/app/assets/javascripts/ckeditor/plugins/widget/lang/eu.js +2 -2
  288. data/app/assets/javascripts/ckeditor/plugins/widget/lang/fa.js +3 -3
  289. data/app/assets/javascripts/ckeditor/plugins/widget/lang/fi.js +2 -2
  290. data/app/assets/javascripts/ckeditor/plugins/widget/lang/fr.js +2 -2
  291. data/app/assets/javascripts/ckeditor/plugins/widget/lang/gl.js +2 -2
  292. data/app/assets/javascripts/ckeditor/plugins/widget/lang/he.js +2 -2
  293. data/app/assets/javascripts/ckeditor/plugins/widget/lang/hr.js +2 -2
  294. data/app/assets/javascripts/ckeditor/plugins/widget/lang/hu.js +2 -2
  295. data/app/assets/javascripts/ckeditor/plugins/widget/lang/id.js +2 -2
  296. data/app/assets/javascripts/ckeditor/plugins/widget/lang/it.js +2 -2
  297. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ja.js +2 -2
  298. data/app/assets/javascripts/ckeditor/plugins/widget/lang/km.js +2 -2
  299. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ko.js +2 -2
  300. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ku.js +2 -2
  301. data/app/assets/javascripts/ckeditor/plugins/widget/lang/lv.js +3 -3
  302. data/app/assets/javascripts/ckeditor/plugins/widget/lang/nb.js +2 -2
  303. data/app/assets/javascripts/ckeditor/plugins/widget/lang/nl.js +2 -2
  304. data/app/assets/javascripts/ckeditor/plugins/widget/lang/no.js +2 -2
  305. data/app/assets/javascripts/ckeditor/plugins/widget/lang/oc.js +2 -2
  306. data/app/assets/javascripts/ckeditor/plugins/widget/lang/pl.js +2 -2
  307. data/app/assets/javascripts/ckeditor/plugins/widget/lang/pt-br.js +2 -2
  308. data/app/assets/javascripts/ckeditor/plugins/widget/lang/pt.js +2 -2
  309. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ro.js +8 -0
  310. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ru.js +2 -2
  311. data/app/assets/javascripts/ckeditor/plugins/widget/lang/sk.js +2 -2
  312. data/app/assets/javascripts/ckeditor/plugins/widget/lang/sl.js +2 -2
  313. data/app/assets/javascripts/ckeditor/plugins/widget/lang/sq.js +3 -3
  314. data/app/assets/javascripts/ckeditor/plugins/widget/lang/sv.js +2 -2
  315. data/app/assets/javascripts/ckeditor/plugins/widget/lang/tr.js +2 -2
  316. data/app/assets/javascripts/ckeditor/plugins/widget/lang/tt.js +2 -2
  317. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ug.js +2 -2
  318. data/app/assets/javascripts/ckeditor/plugins/widget/lang/uk.js +2 -2
  319. data/app/assets/javascripts/ckeditor/plugins/widget/lang/vi.js +2 -2
  320. data/app/assets/javascripts/ckeditor/plugins/widget/lang/zh-cn.js +2 -2
  321. data/app/assets/javascripts/ckeditor/plugins/widget/lang/zh.js +2 -2
  322. data/app/assets/javascripts/ckeditor/plugins/widget/plugin.js +235 -64
  323. data/app/assets/javascripts/ckeditor/plugins/widgetselection/plugin.js +6 -11
  324. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ar.js +1 -0
  325. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/bg.js +17 -0
  326. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ca.js +1 -0
  327. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/cs.js +15 -0
  328. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/da.js +1 -0
  329. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/de.js +1 -0
  330. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/el.js +1 -0
  331. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/en.js +5 -1
  332. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/es.js +1 -0
  333. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/eu.js +17 -0
  334. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/fa.js +13 -0
  335. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/fi.js +1 -0
  336. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/fr.js +1 -0
  337. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/he.js +1 -0
  338. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/hr.js +1 -0
  339. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/hu.js +14 -0
  340. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/it.js +4 -3
  341. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ja.js +5 -5
  342. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ko.js +16 -0
  343. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/nl.js +3 -2
  344. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/no.js +1 -0
  345. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/pl.js +4 -3
  346. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/pt-br.js +1 -0
  347. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/pt.js +1 -0
  348. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ro.js +15 -0
  349. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ru.js +2 -1
  350. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/sk.js +15 -0
  351. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/sv.js +5 -3
  352. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/tr.js +1 -0
  353. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/uk.js +17 -0
  354. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/zh-cn.js +1 -0
  355. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/zh.js +14 -0
  356. data/app/assets/javascripts/ckeditor/plugins/wordcount/plugin.js +485 -302
  357. data/app/assets/javascripts/ckeditor/plugins/wordcount/samples/maxParagraphs.html +26 -0
  358. data/app/assets/javascripts/integral/backend.js +10 -14
  359. data/app/assets/javascripts/integral/frontend.js +0 -2
  360. data/app/assets/javascripts/integral/support/date_picker.coffee +54 -59
  361. data/app/assets/javascripts/integral/support/grid.coffee +11 -4
  362. data/app/assets/javascripts/integral/support/remote_form.coffee +13 -9
  363. data/app/assets/stylesheets/integral/frontend.sass +0 -1
  364. data/app/controllers/integral/application_controller.rb +3 -2
  365. data/app/controllers/integral/backend/activities_controller.rb +1 -1
  366. data/app/controllers/integral/backend/base_controller.rb +160 -24
  367. data/app/controllers/integral/backend/images_controller.rb +16 -49
  368. data/app/controllers/integral/backend/lists_controller.rb +15 -85
  369. data/app/controllers/integral/backend/pages_controller.rb +13 -116
  370. data/app/controllers/integral/backend/posts_controller.rb +21 -108
  371. data/app/controllers/integral/backend/settings_controller.rb +5 -10
  372. data/app/controllers/integral/backend/static_pages_controller.rb +4 -0
  373. data/app/controllers/integral/backend/users_controller.rb +23 -66
  374. data/app/controllers/integral/pages_controller.rb +2 -2
  375. data/app/controllers/integral/posts_controller.rb +2 -6
  376. data/app/decorators/integral/image_decorator.rb +1 -1
  377. data/app/decorators/integral/list_decorator.rb +1 -1
  378. data/app/decorators/integral/page_decorator.rb +1 -1
  379. data/app/decorators/integral/paginating_decorator.rb +6 -0
  380. data/app/decorators/integral/post_decorator.rb +34 -1
  381. data/app/decorators/integral/user_decorator.rb +1 -1
  382. data/app/decorators/integral/version_decorator.rb +1 -1
  383. data/app/helpers/integral/application_helper.rb +7 -0
  384. data/app/helpers/integral/blog_helper.rb +29 -0
  385. data/app/helpers/integral/social_helper.rb +0 -23
  386. data/app/models/integral/list.rb +1 -2
  387. data/app/models/integral/page.rb +1 -1
  388. data/app/models/integral/post.rb +1 -1
  389. data/app/models/integral/user.rb +6 -0
  390. data/app/policies/integral/base_policy.rb +1 -1
  391. data/app/views/devise/sessions/new.haml +2 -2
  392. data/app/views/integral/backend/images/_form.haml +8 -8
  393. data/app/views/integral/backend/images/edit.haml +10 -2
  394. data/app/views/integral/backend/lists/_child_fields.haml +1 -1
  395. data/app/views/integral/backend/lists/_form.haml +1 -1
  396. data/app/views/integral/backend/lists/_item_container.haml +2 -2
  397. data/app/views/integral/backend/lists/_item_modal.haml +1 -1
  398. data/app/views/integral/backend/lists/_list_item_fields.haml +4 -3
  399. data/app/views/integral/backend/lists/edit.haml +15 -1
  400. data/app/views/integral/backend/pages/_form.haml +3 -3
  401. data/app/views/integral/backend/pages/activities.haml +2 -2
  402. data/app/views/integral/backend/pages/activity.haml +1 -1
  403. data/app/views/integral/backend/pages/edit.haml +20 -0
  404. data/app/views/integral/backend/posts/_form.haml +9 -5
  405. data/app/views/integral/backend/posts/activities.haml +2 -2
  406. data/app/views/integral/backend/posts/activity.haml +1 -1
  407. data/app/views/integral/backend/posts/edit.haml +8 -3
  408. data/app/views/integral/backend/settings/sections/_social.haml +1 -3
  409. data/app/views/integral/backend/users/_form.haml +4 -4
  410. data/app/views/integral/backend/users/edit.haml +1 -1
  411. data/app/views/integral/backend/users/show.haml +7 -7
  412. data/app/views/integral/posts/index.haml +2 -1
  413. data/app/views/integral/posts/templates/default.haml +1 -2
  414. data/app/views/integral/shared/_share_modal.haml +0 -3
  415. data/app/views/integral/shared/_social_list_items.haml +6 -12
  416. data/config/locales/en.yml +23 -12
  417. data/lib/generators/templates/app.yml +0 -1
  418. data/lib/integral/engine.rb +1 -0
  419. data/lib/integral/router.rb +3 -1
  420. data/lib/integral/version.rb +1 -1
  421. data/public/integral/ckeditor_demo_content.html +0 -13
  422. metadata +186 -12
  423. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/jp.js +0 -13
  424. data/app/assets/javascripts/integral/support/date_picker/picker.date.js +0 -1435
  425. data/app/assets/javascripts/integral/support/date_picker/picker.js +0 -1132
  426. data/app/assets/stylesheets/integral/support/date-picker.scss +0 -16
  427. data/app/assets/stylesheets/integral/support/date_picker/_default.date.scss +0 -452
  428. data/app/assets/stylesheets/integral/support/date_picker/_default.scss +0 -201
  429. data/app/assets/stylesheets/integral/support/date_picker/materialize_clockpicker.sass +0 -220
  430. data/app/views/integral/backend/pages/edit.html.haml +0 -15
@@ -0,0 +1,21 @@
1
+ /*
2
+ Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3
+ For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ CKEDITOR.plugins.setLang( 'image2', 'sr', {
6
+ alt: 'Алтернативни текст',
7
+ btnUpload: 'Пошаљи на сервер',
8
+ captioned: 'Captioned image', // MISSING
9
+ captionPlaceholder: 'Caption', // MISSING
10
+ infoTab: 'Инфо слике',
11
+ lockRatio: 'Закључај однос',
12
+ menu: 'Особине слика',
13
+ pathName: 'image', // MISSING
14
+ pathNameCaption: 'caption', // MISSING
15
+ resetSize: 'Ресетуј величину',
16
+ resizer: 'Click and drag to resize', // MISSING
17
+ title: 'Особине слика',
18
+ uploadTab: 'Пошаљи',
19
+ urlMissing: 'Недостаје УРЛ слике.',
20
+ altMissing: 'Alternative text is missing.' // MISSING
21
+ } );
@@ -0,0 +1,21 @@
1
+ /*
2
+ Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3
+ For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ CKEDITOR.plugins.setLang( 'image2', 'sv', {
6
+ alt: 'Alternativ text',
7
+ btnUpload: 'Skicka till server',
8
+ captioned: 'Rubricerad bild',
9
+ captionPlaceholder: 'Bildtext',
10
+ infoTab: 'Bildinformation',
11
+ lockRatio: 'Lås höjd/bredd förhållanden',
12
+ menu: 'Bildegenskaper',
13
+ pathName: 'bild',
14
+ pathNameCaption: 'rubrik',
15
+ resetSize: 'Återställ storlek',
16
+ resizer: 'Klicka och drag för att ändra storlek',
17
+ title: 'Bildegenskaper',
18
+ uploadTab: 'Ladda upp',
19
+ urlMissing: 'Bildkällans URL saknas.',
20
+ altMissing: 'Alternativ text saknas'
21
+ } );
@@ -0,0 +1,21 @@
1
+ /*
2
+ Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3
+ For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ CKEDITOR.plugins.setLang( 'image2', 'th', {
6
+ alt: 'คำประกอบรูปภาพ',
7
+ btnUpload: 'อัพโหลดไฟล์ไปเก็บไว้ที่เครื่องแม่ข่าย (เซิร์ฟเวอร์)',
8
+ captioned: 'Captioned image', // MISSING
9
+ captionPlaceholder: 'Caption', // MISSING
10
+ infoTab: 'ข้อมูลของรูปภาพ',
11
+ lockRatio: 'กำหนดอัตราส่วน กว้าง-สูง แบบคงที่',
12
+ menu: 'คุณสมบัติของ รูปภาพ',
13
+ pathName: 'image', // MISSING
14
+ pathNameCaption: 'caption', // MISSING
15
+ resetSize: 'กำหนดรูปเท่าขนาดจริง',
16
+ resizer: 'Click and drag to resize', // MISSING
17
+ title: 'คุณสมบัติของ รูปภาพ',
18
+ uploadTab: 'อัพโหลดไฟล์',
19
+ urlMissing: 'Image source URL is missing.', // MISSING
20
+ altMissing: 'Alternative text is missing.' // MISSING
21
+ } );
@@ -0,0 +1,21 @@
1
+ /*
2
+ Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3
+ For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ CKEDITOR.plugins.setLang( 'image2', 'tr', {
6
+ alt: 'Alternatif Yazı',
7
+ btnUpload: 'Sunucuya Yolla',
8
+ captioned: 'Başlıklı resim',
9
+ captionPlaceholder: 'Başlık',
10
+ infoTab: 'Resim Bilgisi',
11
+ lockRatio: 'Oranı Kilitle',
12
+ menu: 'Resim Özellikleri',
13
+ pathName: 'Resim',
14
+ pathNameCaption: 'başlık',
15
+ resetSize: 'Boyutu Başa Döndür',
16
+ resizer: 'Boyutlandırmak için, tıklayın ve sürükleyin',
17
+ title: 'Resim Özellikleri',
18
+ uploadTab: 'Karşıya Yükle',
19
+ urlMissing: 'Resmin URL kaynağı bulunamadı.',
20
+ altMissing: 'Alternatif yazı eksik.'
21
+ } );
@@ -0,0 +1,21 @@
1
+ /*
2
+ Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3
+ For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ CKEDITOR.plugins.setLang( 'image2', 'tt', {
6
+ alt: 'Альтернатив текст',
7
+ btnUpload: 'Серверга җибәрү',
8
+ captioned: 'Исеме куелган рәсем',
9
+ captionPlaceholder: 'Исем',
10
+ infoTab: 'Рәсем тасвирламасы',
11
+ lockRatio: 'Lock Ratio', // MISSING
12
+ menu: 'Рәсем үзлекләре',
13
+ pathName: 'рәсем',
14
+ pathNameCaption: 'исем',
15
+ resetSize: 'Баштагы зурлык',
16
+ resizer: 'Күчереп куер өчен басып шудырыгыз',
17
+ title: 'Рәсем үзлекләре',
18
+ uploadTab: 'Йөкләү',
19
+ urlMissing: 'Image source URL is missing.', // MISSING
20
+ altMissing: 'Alternative text is missing.' // MISSING
21
+ } );
@@ -0,0 +1,21 @@
1
+ /*
2
+ Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3
+ For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ CKEDITOR.plugins.setLang( 'image2', 'ug', {
6
+ alt: 'تېكىست ئالماشتۇر',
7
+ btnUpload: 'مۇلازىمېتىرغا يۈكلە',
8
+ captioned: 'ماۋزۇلۇق سۈرەت',
9
+ captionPlaceholder: 'ماۋزۇ',
10
+ infoTab: 'سۈرەت',
11
+ lockRatio: 'نىسبەتنى قۇلۇپلا',
12
+ menu: 'سۈرەت خاسلىقى',
13
+ pathName: 'رەسىم',
14
+ pathNameCaption: 'ماۋزۇ',
15
+ resetSize: 'ئەسلى چوڭلۇق',
16
+ resizer: 'چېكىپ تۇرۇپ سۆرەپ چوڭ كىچىكلىكىنى تەڭشىگىلى بولىدۇ',
17
+ title: 'سۈرەت خاسلىقى',
18
+ uploadTab: 'يۈكلە',
19
+ urlMissing: 'سۈرەتنىڭ ئەسلى ھۆججەت ئادرېسى كەم',
20
+ altMissing: 'باشقا تېكىست كەمچىل'
21
+ } );
@@ -0,0 +1,21 @@
1
+ /*
2
+ Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3
+ For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ CKEDITOR.plugins.setLang( 'image2', 'uk', {
6
+ alt: 'Альтернативний текст',
7
+ btnUpload: 'Надіслати на сервер',
8
+ captioned: 'Підписане зображення',
9
+ captionPlaceholder: 'Заголовок',
10
+ infoTab: 'Інформація про зображення',
11
+ lockRatio: 'Зберегти пропорції',
12
+ menu: 'Властивості зображення',
13
+ pathName: 'Зображення',
14
+ pathNameCaption: 'заголовок',
15
+ resetSize: 'Очистити поля розмірів',
16
+ resizer: 'Клікніть та потягніть для зміни розмірів',
17
+ title: 'Властивості зображення',
18
+ uploadTab: 'Надіслати',
19
+ urlMissing: 'Вкажіть URL зображення.',
20
+ altMissing: 'Alternative text is missing.' // MISSING
21
+ } );
@@ -0,0 +1,21 @@
1
+ /*
2
+ Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3
+ For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ CKEDITOR.plugins.setLang( 'image2', 'vi', {
6
+ alt: 'Chú thích ảnh',
7
+ btnUpload: 'Tải lên máy chủ',
8
+ captioned: 'Ảnh có chú thích',
9
+ captionPlaceholder: 'Nhãn',
10
+ infoTab: 'Thông tin của ảnh',
11
+ lockRatio: 'Giữ nguyên tỷ lệ',
12
+ menu: 'Thuộc tính của ảnh',
13
+ pathName: 'ảnh',
14
+ pathNameCaption: 'chú thích',
15
+ resetSize: 'Kích thước gốc',
16
+ resizer: 'Kéo rê để thay đổi kích cỡ',
17
+ title: 'Thuộc tính của ảnh',
18
+ uploadTab: 'Tải lên',
19
+ urlMissing: 'Thiếu đường dẫn hình ảnh',
20
+ altMissing: 'Alternative text is missing.' // MISSING
21
+ } );
@@ -0,0 +1,21 @@
1
+ /*
2
+ Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3
+ For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ CKEDITOR.plugins.setLang( 'image2', 'zh-cn', {
6
+ alt: '替换文本',
7
+ btnUpload: '上传到服务器',
8
+ captioned: '带标题图像',
9
+ captionPlaceholder: '标题',
10
+ infoTab: '图像信息',
11
+ lockRatio: '锁定比例',
12
+ menu: '图像属性',
13
+ pathName: '图像',
14
+ pathNameCaption: '标题',
15
+ resetSize: '原始尺寸',
16
+ resizer: '点击并拖拽以改变尺寸',
17
+ title: '图像属性',
18
+ uploadTab: '上传',
19
+ urlMissing: '缺少图像源文件地址',
20
+ altMissing: '缺少替换文本'
21
+ } );
@@ -0,0 +1,21 @@
1
+ /*
2
+ Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3
+ For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+ CKEDITOR.plugins.setLang( 'image2', 'zh', {
6
+ alt: '替代文字',
7
+ btnUpload: '傳送至伺服器',
8
+ captioned: '已加標題之圖片',
9
+ captionPlaceholder: '標題',
10
+ infoTab: '影像資訊',
11
+ lockRatio: '固定比例',
12
+ menu: '影像屬性',
13
+ pathName: '圖片',
14
+ pathNameCaption: '標題',
15
+ resetSize: '重設大小',
16
+ resizer: '拖曳以改變大小',
17
+ title: '影像屬性',
18
+ uploadTab: '上傳',
19
+ urlMissing: '遺失圖片來源之 URL ',
20
+ altMissing: '替代文字遺失。'
21
+ } );
@@ -0,0 +1,1720 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ ( function() {
9
+
10
+ var template = '<img alt="" src="" />',
11
+ templateBlock = new CKEDITOR.template(
12
+ '<figure class="{captionedClass}">' +
13
+ template +
14
+ '<figcaption>{captionPlaceholder}</figcaption>' +
15
+ '</figure>' ),
16
+ alignmentsObj = { left: 0, center: 1, right: 2 },
17
+ regexPercent = /^\s*(\d+\%)\s*$/i;
18
+
19
+ CKEDITOR.plugins.add( 'image2', {
20
+ // jscs:disable maximumLineLength
21
+ lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,es-mx,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
22
+ // jscs:enable maximumLineLength
23
+ requires: 'widget,dialog',
24
+ icons: 'image',
25
+ hidpi: true,
26
+
27
+ onLoad: function() {
28
+ CKEDITOR.addCss(
29
+ '.cke_image_nocaption{' +
30
+ // This is to remove unwanted space so resize
31
+ // wrapper is displayed property.
32
+ 'line-height:0' +
33
+ '}' +
34
+ '.cke_editable.cke_image_sw, .cke_editable.cke_image_sw *{cursor:sw-resize !important}' +
35
+ '.cke_editable.cke_image_se, .cke_editable.cke_image_se *{cursor:se-resize !important}' +
36
+ '.cke_image_resizer{' +
37
+ 'display:none;' +
38
+ 'position:absolute;' +
39
+ 'width:10px;' +
40
+ 'height:10px;' +
41
+ 'bottom:-5px;' +
42
+ 'right:-5px;' +
43
+ 'background:#000;' +
44
+ 'outline:1px solid #fff;' +
45
+ // Prevent drag handler from being misplaced (https://dev.ckeditor.com/ticket/11207).
46
+ 'line-height:0;' +
47
+ 'cursor:se-resize;' +
48
+ '}' +
49
+ '.cke_image_resizer_wrapper{' +
50
+ 'position:relative;' +
51
+ 'display:inline-block;' +
52
+ 'line-height:0;' +
53
+ '}' +
54
+ // Bottom-left corner style of the resizer.
55
+ '.cke_image_resizer.cke_image_resizer_left{' +
56
+ 'right:auto;' +
57
+ 'left:-5px;' +
58
+ 'cursor:sw-resize;' +
59
+ '}' +
60
+ '.cke_widget_wrapper:hover .cke_image_resizer,' +
61
+ '.cke_image_resizer.cke_image_resizing{' +
62
+ 'display:block' +
63
+ '}' +
64
+ // Expand widget wrapper when linked inline image.
65
+ '.cke_widget_wrapper>a{' +
66
+ 'display:inline-block' +
67
+ '}' );
68
+ },
69
+
70
+ init: function( editor ) {
71
+ // Abort when Easyimage is to be loaded since this plugins
72
+ // share the same functionality (#1791).
73
+ if ( editor.plugins.detectConflict( 'image2', [ 'easyimage' ] ) ) {
74
+ return;
75
+ }
76
+
77
+ // Adapts configuration from original image plugin. Should be removed
78
+ // when we'll rename image2 to image.
79
+ var config = editor.config,
80
+ lang = editor.lang.image2,
81
+ image = widgetDef( editor );
82
+
83
+ // Since filebrowser plugin discovers config properties by dialog (plugin?)
84
+ // names (sic!), this hack will be necessary as long as Image2 is not named
85
+ // Image. And since Image2 will never be Image, for sure some filebrowser logic
86
+ // got to be refined.
87
+ config.filebrowserImage2BrowseUrl = config.filebrowserImageBrowseUrl;
88
+ config.filebrowserImage2UploadUrl = config.filebrowserImageUploadUrl;
89
+
90
+ // Add custom elementspath names to widget definition.
91
+ image.pathName = lang.pathName;
92
+ image.editables.caption.pathName = lang.pathNameCaption;
93
+
94
+ // Register the widget.
95
+ editor.widgets.add( 'image', image );
96
+
97
+ // Add toolbar button for this plugin.
98
+ editor.ui.addButton && editor.ui.addButton( 'Image', {
99
+ label: editor.lang.common.image,
100
+ command: 'image',
101
+ toolbar: 'insert,10'
102
+ } );
103
+
104
+ // Register context menu option for editing widget.
105
+ if ( editor.contextMenu ) {
106
+ editor.addMenuGroup( 'image', 10 );
107
+
108
+ editor.addMenuItem( 'image', {
109
+ label: lang.menu,
110
+ command: 'image',
111
+ group: 'image'
112
+ } );
113
+ }
114
+
115
+ CKEDITOR.dialog.add( 'image2', this.path + 'dialogs/image2.js' );
116
+ },
117
+
118
+ afterInit: function( editor ) {
119
+ // Integrate with align commands (justify plugin).
120
+ var align = { left: 1, right: 1, center: 1, block: 1 },
121
+ integrate = alignCommandIntegrator( editor );
122
+
123
+ for ( var value in align )
124
+ integrate( value );
125
+
126
+ // Integrate with link commands (link plugin).
127
+ linkCommandIntegrator( editor );
128
+ }
129
+ } );
130
+
131
+ // Wiget states (forms) depending on alignment and configuration.
132
+ //
133
+ // Non-captioned widget (inline styles)
134
+ // ┌──────┬───────────────────────────────┬─────────────────────────────┐
135
+ // │Align │Internal form │Data │
136
+ // ├──────┼───────────────────────────────┼─────────────────────────────┤
137
+ // │none │<wrapper> │<img /> │
138
+ // │ │ <img /> │ │
139
+ // │ │</wrapper> │ │
140
+ // ├──────┼───────────────────────────────┼─────────────────────────────┤
141
+ // │left │<wrapper style=”float:left”> │<img style=”float:left” /> │
142
+ // │ │ <img /> │ │
143
+ // │ │</wrapper> │ │
144
+ // ├──────┼───────────────────────────────┼─────────────────────────────┤
145
+ // │center│<wrapper> │<p style=”text-align:center”>│
146
+ // │ │ <p style=”text-align:center”> │ <img /> │
147
+ // │ │ <img /> │</p> │
148
+ // │ │ </p> │ │
149
+ // │ │</wrapper> │ │
150
+ // ├──────┼───────────────────────────────┼─────────────────────────────┤
151
+ // │right │<wrapper style=”float:right”> │<img style=”float:right” /> │
152
+ // │ │ <img /> │ │
153
+ // │ │</wrapper> │ │
154
+ // └──────┴───────────────────────────────┴─────────────────────────────┘
155
+ //
156
+ // Non-captioned widget (config.image2_alignClasses defined)
157
+ // ┌──────┬───────────────────────────────┬─────────────────────────────┐
158
+ // │Align │Internal form │Data │
159
+ // ├──────┼───────────────────────────────┼─────────────────────────────┤
160
+ // │none │<wrapper> │<img /> │
161
+ // │ │ <img /> │ │
162
+ // │ │</wrapper> │ │
163
+ // ├──────┼───────────────────────────────┼─────────────────────────────┤
164
+ // │left │<wrapper class=”left”> │<img class=”left” /> │
165
+ // │ │ <img /> │ │
166
+ // │ │</wrapper> │ │
167
+ // ├──────┼───────────────────────────────┼─────────────────────────────┤
168
+ // │center│<wrapper> │<p class=”center”> │
169
+ // │ │ <p class=”center”> │ <img /> │
170
+ // │ │ <img /> │</p> │
171
+ // │ │ </p> │ │
172
+ // │ │</wrapper> │ │
173
+ // ├──────┼───────────────────────────────┼─────────────────────────────┤
174
+ // │right │<wrapper class=”right”> │<img class=”right” /> │
175
+ // │ │ <img /> │ │
176
+ // │ │</wrapper> │ │
177
+ // └──────┴───────────────────────────────┴─────────────────────────────┘
178
+ //
179
+ // Captioned widget (inline styles)
180
+ // ┌──────┬────────────────────────────────────────┬────────────────────────────────────────┐
181
+ // │Align │Internal form │Data │
182
+ // ├──────┼────────────────────────────────────────┼────────────────────────────────────────┤
183
+ // │none │<wrapper> │<figure /> │
184
+ // │ │ <figure /> │ │
185
+ // │ │</wrapper> │ │
186
+ // ├──────┼────────────────────────────────────────┼────────────────────────────────────────┤
187
+ // │left │<wrapper style=”float:left”> │<figure style=”float:left” /> │
188
+ // │ │ <figure /> │ │
189
+ // │ │</wrapper> │ │
190
+ // ├──────┼────────────────────────────────────────┼────────────────────────────────────────┤
191
+ // │center│<wrapper style=”text-align:center”> │<div style=”text-align:center”> │
192
+ // │ │ <figure style=”display:inline-block” />│ <figure style=”display:inline-block” />│
193
+ // │ │</wrapper> │</p> │
194
+ // ├──────┼────────────────────────────────────────┼────────────────────────────────────────┤
195
+ // │right │<wrapper style=”float:right”> │<figure style=”float:right” /> │
196
+ // │ │ <figure /> │ │
197
+ // │ │</wrapper> │ │
198
+ // └──────┴────────────────────────────────────────┴────────────────────────────────────────┘
199
+ //
200
+ // Captioned widget (config.image2_alignClasses defined)
201
+ // ┌──────┬────────────────────────────────────────┬────────────────────────────────────────┐
202
+ // │Align │Internal form │Data │
203
+ // ├──────┼────────────────────────────────────────┼────────────────────────────────────────┤
204
+ // │none │<wrapper> │<figure /> │
205
+ // │ │ <figure /> │ │
206
+ // │ │</wrapper> │ │
207
+ // ├──────┼────────────────────────────────────────┼────────────────────────────────────────┤
208
+ // │left │<wrapper class=”left”> │<figure class=”left” /> │
209
+ // │ │ <figure /> │ │
210
+ // │ │</wrapper> │ │
211
+ // ├──────┼────────────────────────────────────────┼────────────────────────────────────────┤
212
+ // │center│<wrapper class=”center”> │<div class=”center”> │
213
+ // │ │ <figure /> │ <figure /> │
214
+ // │ │</wrapper> │</p> │
215
+ // ├──────┼────────────────────────────────────────┼────────────────────────────────────────┤
216
+ // │right │<wrapper class=”right”> │<figure class=”right” /> │
217
+ // │ │ <figure /> │ │
218
+ // │ │</wrapper> │ │
219
+ // └──────┴────────────────────────────────────────┴────────────────────────────────────────┘
220
+ //
221
+ // @param {CKEDITOR.editor}
222
+ // @returns {Object}
223
+ function widgetDef( editor ) {
224
+ var alignClasses = editor.config.image2_alignClasses,
225
+ captionedClass = editor.config.image2_captionedClass;
226
+
227
+ function deflate() {
228
+ if ( this.deflated )
229
+ return;
230
+
231
+ // Remember whether widget was focused before destroyed.
232
+ if ( editor.widgets.focused == this.widget )
233
+ this.focused = true;
234
+
235
+ editor.widgets.destroy( this.widget );
236
+
237
+ // Mark widget was destroyed.
238
+ this.deflated = true;
239
+ }
240
+
241
+ function inflate() {
242
+ var editable = editor.editable(),
243
+ doc = editor.document;
244
+
245
+ // Create a new widget. This widget will be either captioned
246
+ // non-captioned, block or inline according to what is the
247
+ // new state of the widget.
248
+ if ( this.deflated ) {
249
+ this.widget = editor.widgets.initOn( this.element, 'image', this.widget.data );
250
+
251
+ // Once widget was re-created, it may become an inline element without
252
+ // block wrapper (i.e. when unaligned, end not captioned). Let's do some
253
+ // sort of autoparagraphing here (https://dev.ckeditor.com/ticket/10853).
254
+ if ( this.widget.inline && !( new CKEDITOR.dom.elementPath( this.widget.wrapper, editable ).block ) ) {
255
+ var block = doc.createElement( editor.activeEnterMode == CKEDITOR.ENTER_P ? 'p' : 'div' );
256
+ block.replace( this.widget.wrapper );
257
+ this.widget.wrapper.move( block );
258
+ }
259
+
260
+ // The focus must be transferred from the old one (destroyed)
261
+ // to the new one (just created).
262
+ if ( this.focused ) {
263
+ this.widget.focus();
264
+ delete this.focused;
265
+ }
266
+
267
+ delete this.deflated;
268
+ }
269
+
270
+ // If now widget was destroyed just update wrapper's alignment.
271
+ // According to the new state.
272
+ else {
273
+ setWrapperAlign( this.widget, alignClasses );
274
+ }
275
+ }
276
+
277
+ return {
278
+ allowedContent: getWidgetAllowedContent( editor ),
279
+
280
+ requiredContent: 'img[src,alt]',
281
+
282
+ features: getWidgetFeatures( editor ),
283
+
284
+ styleableElements: 'img figure',
285
+
286
+ // This widget converts style-driven dimensions to attributes.
287
+ contentTransformations: [
288
+ [ 'img[width]: sizeToAttribute' ]
289
+ ],
290
+
291
+ // This widget has an editable caption.
292
+ editables: {
293
+ caption: {
294
+ selector: 'figcaption',
295
+ allowedContent: 'br em strong sub sup u s; a[!href,target]'
296
+ }
297
+ },
298
+
299
+ parts: {
300
+ image: 'img',
301
+ caption: 'figcaption'
302
+ // parts#link defined in widget#init
303
+ },
304
+
305
+ // The name of this widget's dialog.
306
+ dialog: 'image2',
307
+
308
+ // Template of the widget: plain image.
309
+ template: template,
310
+
311
+ data: function() {
312
+ var features = this.features;
313
+
314
+ // Image can't be captioned when figcaption is disallowed (https://dev.ckeditor.com/ticket/11004).
315
+ if ( this.data.hasCaption && !editor.filter.checkFeature( features.caption ) )
316
+ this.data.hasCaption = false;
317
+
318
+ // Image can't be aligned when floating is disallowed (https://dev.ckeditor.com/ticket/11004).
319
+ if ( this.data.align != 'none' && !editor.filter.checkFeature( features.align ) )
320
+ this.data.align = 'none';
321
+
322
+ // Convert the internal form of the widget from the old state to the new one.
323
+ this.shiftState( {
324
+ widget: this,
325
+ element: this.element,
326
+ oldData: this.oldData,
327
+ newData: this.data,
328
+ deflate: deflate,
329
+ inflate: inflate
330
+ } );
331
+
332
+ // Update widget.parts.link since it will not auto-update unless widget
333
+ // is destroyed and re-inited.
334
+ if ( !this.data.link ) {
335
+ if ( this.parts.link )
336
+ delete this.parts.link;
337
+ } else {
338
+ if ( !this.parts.link )
339
+ this.parts.link = this.parts.image.getParent();
340
+ }
341
+
342
+ this.parts.image.setAttributes( {
343
+ src: this.data.src,
344
+
345
+ // This internal is required by the editor.
346
+ 'data-cke-saved-src': this.data.src,
347
+
348
+ alt: this.data.alt
349
+ } );
350
+
351
+ // If shifting non-captioned -> captioned, remove classes
352
+ // related to styles from <img/>.
353
+ if ( this.oldData && !this.oldData.hasCaption && this.data.hasCaption ) {
354
+ for ( var c in this.data.classes )
355
+ this.parts.image.removeClass( c );
356
+ }
357
+
358
+ // Set dimensions of the image according to gathered data.
359
+ // Do it only when the attributes are allowed (https://dev.ckeditor.com/ticket/11004).
360
+ if ( editor.filter.checkFeature( features.dimension ) )
361
+ setDimensions( this );
362
+
363
+ // Cache current data.
364
+ this.oldData = CKEDITOR.tools.extend( {}, this.data );
365
+ },
366
+
367
+ init: function() {
368
+ var helpers = CKEDITOR.plugins.image2,
369
+ image = this.parts.image,
370
+ data = {
371
+ hasCaption: !!this.parts.caption,
372
+ src: image.getAttribute( 'src' ),
373
+ alt: image.getAttribute( 'alt' ) || '',
374
+ width: image.getAttribute( 'width' ) || '',
375
+ height: image.getAttribute( 'height' ) || '',
376
+
377
+ // Lock ratio is on by default (https://dev.ckeditor.com/ticket/10833).
378
+ lock: this.ready ? helpers.checkHasNaturalRatio( image ) : true
379
+ };
380
+
381
+ // If we used 'a' in widget#parts definition, it could happen that
382
+ // selected element is a child of widget.parts#caption. Since there's no clever
383
+ // way to solve it with CSS selectors, it's done like that. (https://dev.ckeditor.com/ticket/11783).
384
+ var link = image.getAscendant( 'a' );
385
+
386
+ if ( link && this.wrapper.contains( link ) )
387
+ this.parts.link = link;
388
+
389
+ // Depending on configuration, read style/class from element and
390
+ // then remove it. Removed style/class will be set on wrapper in #data listener.
391
+ // Note: Center alignment is detected during upcast, so only left/right cases
392
+ // are checked below.
393
+ if ( !data.align ) {
394
+ var alignElement = data.hasCaption ? this.element : image;
395
+
396
+ // Read the initial left/right alignment from the class set on element.
397
+ if ( alignClasses ) {
398
+ if ( alignElement.hasClass( alignClasses[ 0 ] ) ) {
399
+ data.align = 'left';
400
+ } else if ( alignElement.hasClass( alignClasses[ 2 ] ) ) {
401
+ data.align = 'right';
402
+ }
403
+
404
+ if ( data.align ) {
405
+ alignElement.removeClass( alignClasses[ alignmentsObj[ data.align ] ] );
406
+ } else {
407
+ data.align = 'none';
408
+ }
409
+ }
410
+ // Read initial float style from figure/image and then remove it.
411
+ else {
412
+ data.align = alignElement.getStyle( 'float' ) || 'none';
413
+ alignElement.removeStyle( 'float' );
414
+ }
415
+ }
416
+
417
+ // Update data.link object with attributes if the link has been discovered.
418
+ if ( editor.plugins.link && this.parts.link ) {
419
+ data.link = helpers.getLinkAttributesParser()( editor, this.parts.link );
420
+
421
+ // Get rid of cke_widget_* classes in data. Otherwise
422
+ // they might appear in link dialog.
423
+ var advanced = data.link.advanced;
424
+ if ( advanced && advanced.advCSSClasses ) {
425
+ advanced.advCSSClasses = CKEDITOR.tools.trim( advanced.advCSSClasses.replace( /cke_\S+/, '' ) );
426
+ }
427
+ }
428
+
429
+ // Get rid of extra vertical space when there's no caption.
430
+ // It will improve the look of the resizer.
431
+ this.wrapper[ ( data.hasCaption ? 'remove' : 'add' ) + 'Class' ]( 'cke_image_nocaption' );
432
+
433
+ this.setData( data );
434
+
435
+ // Setup dynamic image resizing with mouse.
436
+ // Don't initialize resizer when dimensions are disallowed (https://dev.ckeditor.com/ticket/11004).
437
+ // Don't initialize resizer when editor.readOnly is set to true (#719).
438
+ if ( editor.filter.checkFeature( this.features.dimension ) && editor.config.image2_disableResizer !== true && editor.readOnly != true ) {
439
+ setupResizer( this );
440
+ }
441
+
442
+ this.shiftState = helpers.stateShifter( this.editor );
443
+
444
+ // Add widget editing option to its context menu.
445
+ this.on( 'contextMenu', function( evt ) {
446
+ evt.data.image = CKEDITOR.TRISTATE_OFF;
447
+
448
+ // Integrate context menu items for link.
449
+ // Note that widget may be wrapped in a link, which
450
+ // does not belong to that widget (https://dev.ckeditor.com/ticket/11814).
451
+ if ( this.parts.link || this.wrapper.getAscendant( 'a' ) )
452
+ evt.data.link = evt.data.unlink = CKEDITOR.TRISTATE_OFF;
453
+ } );
454
+
455
+ // Pass the reference to this widget to the dialog.
456
+ this.on( 'dialog', function( evt ) {
457
+ evt.data.widget = this;
458
+ }, this );
459
+ },
460
+
461
+ // Overrides default method to handle internal mutability of Image2.
462
+ // @see CKEDITOR.plugins.widget#addClass
463
+ addClass: function( className ) {
464
+ getStyleableElement( this ).addClass( className );
465
+ },
466
+
467
+ // Overrides default method to handle internal mutability of Image2.
468
+ // @see CKEDITOR.plugins.widget#hasClass
469
+ hasClass: function( className ) {
470
+ return getStyleableElement( this ).hasClass( className );
471
+ },
472
+
473
+ // Overrides default method to handle internal mutability of Image2.
474
+ // @see CKEDITOR.plugins.widget#removeClass
475
+ removeClass: function( className ) {
476
+ getStyleableElement( this ).removeClass( className );
477
+ },
478
+
479
+ // Overrides default method to handle internal mutability of Image2.
480
+ // @see CKEDITOR.plugins.widget#getClasses
481
+ getClasses: ( function() {
482
+ var classRegex = new RegExp( '^(' + [].concat( captionedClass, alignClasses ).join( '|' ) + ')$' );
483
+
484
+ return function() {
485
+ var classes = this.repository.parseElementClasses( getStyleableElement( this ).getAttribute( 'class' ) );
486
+
487
+ // Neither config.image2_captionedClass nor config.image2_alignClasses
488
+ // do not belong to style classes.
489
+ for ( var c in classes ) {
490
+ if ( classRegex.test( c ) )
491
+ delete classes[ c ];
492
+ }
493
+
494
+ return classes;
495
+ };
496
+ } )(),
497
+
498
+ upcast: upcastWidgetElement( editor ),
499
+ downcast: downcastWidgetElement( editor ),
500
+
501
+ getLabel: function() {
502
+ var label = ( this.data.alt || '' ) + ' ' + this.pathName;
503
+
504
+ return this.editor.lang.widget.label.replace( /%1/, label );
505
+ }
506
+ };
507
+ }
508
+
509
+ /**
510
+ * A set of Enhanced Image (image2) plugin helpers.
511
+ *
512
+ * @class
513
+ * @singleton
514
+ */
515
+ CKEDITOR.plugins.image2 = {
516
+ stateShifter: function( editor ) {
517
+ // Tag name used for centering non-captioned widgets.
518
+ var doc = editor.document,
519
+ alignClasses = editor.config.image2_alignClasses,
520
+ captionedClass = editor.config.image2_captionedClass,
521
+ editable = editor.editable(),
522
+
523
+ // The order that stateActions get executed. It matters!
524
+ shiftables = [ 'hasCaption', 'align', 'link' ];
525
+
526
+ // Atomic procedures, one per state variable.
527
+ var stateActions = {
528
+ align: function( shift, oldValue, newValue ) {
529
+ var el = shift.element;
530
+
531
+ // Alignment changed.
532
+ if ( shift.changed.align ) {
533
+ // No caption in the new state.
534
+ if ( !shift.newData.hasCaption ) {
535
+ // Changed to "center" (non-captioned).
536
+ if ( newValue == 'center' ) {
537
+ shift.deflate();
538
+ shift.element = wrapInCentering( editor, el );
539
+ }
540
+
541
+ // Changed to "non-center" from "center" while caption removed.
542
+ if ( !shift.changed.hasCaption && oldValue == 'center' && newValue != 'center' ) {
543
+ shift.deflate();
544
+ shift.element = unwrapFromCentering( el );
545
+ }
546
+ }
547
+ }
548
+
549
+ // Alignment remains and "center" removed caption.
550
+ else if ( newValue == 'center' && shift.changed.hasCaption && !shift.newData.hasCaption ) {
551
+ shift.deflate();
552
+ shift.element = wrapInCentering( editor, el );
553
+ }
554
+
555
+ // Finally set display for figure.
556
+ if ( !alignClasses && el.is( 'figure' ) ) {
557
+ if ( newValue == 'center' )
558
+ el.setStyle( 'display', 'inline-block' );
559
+ else
560
+ el.removeStyle( 'display' );
561
+ }
562
+ },
563
+
564
+ hasCaption: function( shift, oldValue, newValue ) {
565
+ // This action is for real state change only.
566
+ if ( !shift.changed.hasCaption )
567
+ return;
568
+
569
+ // Get <img/> or <a><img/></a> from widget. Note that widget element might itself
570
+ // be what we're looking for. Also element can be <p style="text-align:center"><a>...</a></p>.
571
+ var imageOrLink;
572
+ if ( shift.element.is( { img: 1, a: 1 } ) )
573
+ imageOrLink = shift.element;
574
+ else
575
+ imageOrLink = shift.element.findOne( 'a,img' );
576
+
577
+ // Switching hasCaption always destroys the widget.
578
+ shift.deflate();
579
+
580
+ // There was no caption, but the caption is to be added.
581
+ if ( newValue ) {
582
+ // Create new <figure> from widget template.
583
+ var figure = CKEDITOR.dom.element.createFromHtml( templateBlock.output( {
584
+ captionedClass: captionedClass,
585
+ captionPlaceholder: editor.lang.image2.captionPlaceholder
586
+ } ), doc );
587
+
588
+ // Replace element with <figure>.
589
+ replaceSafely( figure, shift.element );
590
+
591
+ // Use old <img/> or <a><img/></a> instead of the one from the template,
592
+ // so we won't lose additional attributes.
593
+ imageOrLink.replace( figure.findOne( 'img' ) );
594
+
595
+ // Update widget's element.
596
+ shift.element = figure;
597
+ }
598
+
599
+ // The caption was present, but now it's to be removed.
600
+ else {
601
+ // Unwrap <img/> or <a><img/></a> from figure.
602
+ imageOrLink.replace( shift.element );
603
+
604
+ // Update widget's element.
605
+ shift.element = imageOrLink;
606
+ }
607
+ },
608
+
609
+ link: function( shift, oldValue, newValue ) {
610
+ if ( shift.changed.link ) {
611
+ var img = shift.element.is( 'img' ) ?
612
+ shift.element : shift.element.findOne( 'img' ),
613
+ link = shift.element.is( 'a' ) ?
614
+ shift.element : shift.element.findOne( 'a' ),
615
+ // Why deflate:
616
+ // If element is <img/>, it will be wrapped into <a>,
617
+ // which becomes a new widget.element.
618
+ // If element is <a><img/></a>, it will be unlinked
619
+ // so <img/> becomes a new widget.element.
620
+ needsDeflate = ( shift.element.is( 'a' ) && !newValue ) || ( shift.element.is( 'img' ) && newValue ),
621
+ newEl;
622
+
623
+ if ( needsDeflate )
624
+ shift.deflate();
625
+
626
+ // If unlinked the image, returned element is <img>.
627
+ if ( !newValue )
628
+ newEl = unwrapFromLink( link );
629
+ else {
630
+ // If linked the image, returned element is <a>.
631
+ if ( !oldValue )
632
+ newEl = wrapInLink( img, shift.newData.link );
633
+
634
+ // Set and remove all attributes associated with this state.
635
+ var attributes = CKEDITOR.plugins.image2.getLinkAttributesGetter()( editor, newValue );
636
+
637
+ if ( !CKEDITOR.tools.isEmpty( attributes.set ) )
638
+ ( newEl || link ).setAttributes( attributes.set );
639
+
640
+ if ( attributes.removed.length )
641
+ ( newEl || link ).removeAttributes( attributes.removed );
642
+ }
643
+
644
+ if ( needsDeflate )
645
+ shift.element = newEl;
646
+ }
647
+ }
648
+ };
649
+
650
+ function wrapInCentering( editor, element ) {
651
+ var attribsAndStyles = {};
652
+
653
+ if ( alignClasses )
654
+ attribsAndStyles.attributes = { 'class': alignClasses[ 1 ] };
655
+ else
656
+ attribsAndStyles.styles = { 'text-align': 'center' };
657
+
658
+ // There's no gentle way to center inline element with CSS, so create p/div
659
+ // that wraps widget contents and does the trick either with style or class.
660
+ var center = doc.createElement(
661
+ editor.activeEnterMode == CKEDITOR.ENTER_P ? 'p' : 'div', attribsAndStyles );
662
+
663
+ // Replace element with centering wrapper.
664
+ replaceSafely( center, element );
665
+ element.move( center );
666
+
667
+ return center;
668
+ }
669
+
670
+ function unwrapFromCentering( element ) {
671
+ var imageOrLink = element.findOne( 'a,img' );
672
+
673
+ imageOrLink.replace( element );
674
+
675
+ return imageOrLink;
676
+ }
677
+
678
+ // Wraps <img/> -> <a><img/></a>.
679
+ // Returns reference to <a>.
680
+ //
681
+ // @param {CKEDITOR.dom.element} img
682
+ // @param {Object} linkData
683
+ // @returns {CKEDITOR.dom.element}
684
+ function wrapInLink( img, linkData ) {
685
+ var link = doc.createElement( 'a', {
686
+ attributes: {
687
+ href: linkData.url
688
+ }
689
+ } );
690
+
691
+ link.replace( img );
692
+ img.move( link );
693
+
694
+ return link;
695
+ }
696
+
697
+ // De-wraps <a><img/></a> -> <img/>.
698
+ // Returns the reference to <img/>
699
+ //
700
+ // @param {CKEDITOR.dom.element} link
701
+ // @returns {CKEDITOR.dom.element}
702
+ function unwrapFromLink( link ) {
703
+ var img = link.findOne( 'img' );
704
+
705
+ img.replace( link );
706
+
707
+ return img;
708
+ }
709
+
710
+ function replaceSafely( replacing, replaced ) {
711
+ if ( replaced.getParent() ) {
712
+ var range = editor.createRange();
713
+
714
+ range.moveToPosition( replaced, CKEDITOR.POSITION_BEFORE_START );
715
+
716
+ // Remove old element. Do it before insertion to avoid a case when
717
+ // element is moved from 'replaced' element before it, what creates
718
+ // a tricky case which insertElementIntorRange does not handle.
719
+ replaced.remove();
720
+
721
+ editable.insertElementIntoRange( replacing, range );
722
+ }
723
+ else {
724
+ replacing.replace( replaced );
725
+ }
726
+ }
727
+
728
+ return function( shift ) {
729
+ var name, i;
730
+
731
+ shift.changed = {};
732
+
733
+ for ( i = 0; i < shiftables.length; i++ ) {
734
+ name = shiftables[ i ];
735
+
736
+ shift.changed[ name ] = shift.oldData ?
737
+ shift.oldData[ name ] !== shift.newData[ name ] : false;
738
+ }
739
+
740
+ // Iterate over possible state variables.
741
+ for ( i = 0; i < shiftables.length; i++ ) {
742
+ name = shiftables[ i ];
743
+
744
+ stateActions[ name ]( shift,
745
+ shift.oldData ? shift.oldData[ name ] : null,
746
+ shift.newData[ name ] );
747
+ }
748
+
749
+ shift.inflate();
750
+ };
751
+ },
752
+
753
+ /**
754
+ * Checks whether the current image ratio matches the natural one
755
+ * by comparing dimensions.
756
+ *
757
+ * @param {CKEDITOR.dom.element} image
758
+ * @returns {Boolean}
759
+ */
760
+ checkHasNaturalRatio: function( image ) {
761
+ var $ = image.$,
762
+ natural = this.getNatural( image );
763
+
764
+ // The reason for two alternative comparisons is that the rounding can come from
765
+ // both dimensions, e.g. there are two cases:
766
+ // 1. height is computed as a rounded relation of the real height and the value of width,
767
+ // 2. width is computed as a rounded relation of the real width and the value of heigh.
768
+ return Math.round( $.clientWidth / natural.width * natural.height ) == $.clientHeight ||
769
+ Math.round( $.clientHeight / natural.height * natural.width ) == $.clientWidth;
770
+ },
771
+
772
+ /**
773
+ * Returns natural dimensions of the image. For modern browsers
774
+ * it uses natural(Width|Height). For old ones (IE8) it creates
775
+ * a new image and reads the dimensions.
776
+ *
777
+ * @param {CKEDITOR.dom.element} image
778
+ * @returns {Object}
779
+ */
780
+ getNatural: function( image ) {
781
+ var dimensions;
782
+
783
+ if ( image.$.naturalWidth ) {
784
+ dimensions = {
785
+ width: image.$.naturalWidth,
786
+ height: image.$.naturalHeight
787
+ };
788
+ } else {
789
+ var img = new Image();
790
+ img.src = image.getAttribute( 'src' );
791
+
792
+ dimensions = {
793
+ width: img.width,
794
+ height: img.height
795
+ };
796
+ }
797
+
798
+ return dimensions;
799
+ },
800
+
801
+ /**
802
+ * Returns an attribute getter function. Default getter comes from the Link plugin
803
+ * and is documented by {@link CKEDITOR.plugins.link#getLinkAttributes}.
804
+ *
805
+ * **Note:** It is possible to override this method and use a custom getter e.g.
806
+ * in the absence of the Link plugin.
807
+ *
808
+ * **Note:** If a custom getter is used, a data model format it produces
809
+ * must be compatible with {@link CKEDITOR.plugins.link#getLinkAttributes}.
810
+ *
811
+ * **Note:** A custom getter must understand the data model format produced by
812
+ * {@link #getLinkAttributesParser} to work correctly.
813
+ *
814
+ * @returns {Function} A function that gets (composes) link attributes.
815
+ * @since 4.5.5
816
+ */
817
+ getLinkAttributesGetter: function() {
818
+ // https://dev.ckeditor.com/ticket/13885
819
+ return CKEDITOR.plugins.link.getLinkAttributes;
820
+ },
821
+
822
+ /**
823
+ * Returns an attribute parser function. Default parser comes from the Link plugin
824
+ * and is documented by {@link CKEDITOR.plugins.link#parseLinkAttributes}.
825
+ *
826
+ * **Note:** It is possible to override this method and use a custom parser e.g.
827
+ * in the absence of the Link plugin.
828
+ *
829
+ * **Note:** If a custom parser is used, a data model format produced by the parser
830
+ * must be compatible with {@link #getLinkAttributesGetter}.
831
+ *
832
+ * **Note:** If a custom parser is used, it should be compatible with the
833
+ * {@link CKEDITOR.plugins.link#parseLinkAttributes} data model format. Otherwise the
834
+ * Link plugin dialog may not be populated correctly with parsed data. However
835
+ * as long as Enhanced Image is **not** used with the Link plugin dialog, any custom data model
836
+ * will work, being stored as an internal property of Enhanced Image widget's data only.
837
+ *
838
+ * @returns {Function} A function that parses attributes.
839
+ * @since 4.5.5
840
+ */
841
+ getLinkAttributesParser: function() {
842
+ // https://dev.ckeditor.com/ticket/13885
843
+ return CKEDITOR.plugins.link.parseLinkAttributes;
844
+ }
845
+ };
846
+
847
+ function setWrapperAlign( widget, alignClasses ) {
848
+ var wrapper = widget.wrapper,
849
+ align = widget.data.align,
850
+ hasCaption = widget.data.hasCaption;
851
+
852
+ if ( alignClasses ) {
853
+ // Remove all align classes first.
854
+ for ( var i = 3; i--; )
855
+ wrapper.removeClass( alignClasses[ i ] );
856
+
857
+ if ( align == 'center' ) {
858
+ // Avoid touching non-captioned, centered widgets because
859
+ // they have the class set on the element instead of wrapper:
860
+ //
861
+ // <div class="cke_widget_wrapper">
862
+ // <p class="center-class">
863
+ // <img />
864
+ // </p>
865
+ // </div>
866
+ if ( hasCaption ) {
867
+ wrapper.addClass( alignClasses[ 1 ] );
868
+ }
869
+ } else if ( align != 'none' ) {
870
+ wrapper.addClass( alignClasses[ alignmentsObj[ align ] ] );
871
+ }
872
+ } else {
873
+ if ( align == 'center' ) {
874
+ if ( hasCaption )
875
+ wrapper.setStyle( 'text-align', 'center' );
876
+ else
877
+ wrapper.removeStyle( 'text-align' );
878
+
879
+ wrapper.removeStyle( 'float' );
880
+ }
881
+ else {
882
+ if ( align == 'none' )
883
+ wrapper.removeStyle( 'float' );
884
+ else
885
+ wrapper.setStyle( 'float', align );
886
+
887
+ wrapper.removeStyle( 'text-align' );
888
+ }
889
+ }
890
+ }
891
+
892
+ // Returns a function that creates widgets from all <img> and
893
+ // <figure class="{config.image2_captionedClass}"> elements.
894
+ //
895
+ // @param {CKEDITOR.editor} editor
896
+ // @returns {Function}
897
+ function upcastWidgetElement( editor ) {
898
+ var isCenterWrapper = centerWrapperChecker( editor ),
899
+ captionedClass = editor.config.image2_captionedClass;
900
+
901
+ // @param {CKEDITOR.htmlParser.element} el
902
+ // @param {Object} data
903
+ return function( el, data ) {
904
+ var dimensions = { width: 1, height: 1 },
905
+ name = el.name,
906
+ image;
907
+
908
+ // https://dev.ckeditor.com/ticket/11110 Don't initialize on pasted fake objects.
909
+ if ( el.attributes[ 'data-cke-realelement' ] )
910
+ return;
911
+
912
+ // If a center wrapper is found, there are 3 possible cases:
913
+ //
914
+ // 1. <div style="text-align:center"><figure>...</figure></div>.
915
+ // In this case centering is done with a class set on widget.wrapper.
916
+ // Simply replace centering wrapper with figure (it's no longer necessary).
917
+ //
918
+ // 2. <p style="text-align:center"><img/></p>.
919
+ // Nothing to do here: <p> remains for styling purposes.
920
+ //
921
+ // 3. <div style="text-align:center"><img/></div>.
922
+ // Nothing to do here (2.) but that case is only possible in enterMode different
923
+ // than ENTER_P.
924
+ if ( isCenterWrapper( el ) ) {
925
+ if ( name == 'div' ) {
926
+ var figure = el.getFirst( 'figure' );
927
+
928
+ // Case #1.
929
+ if ( figure ) {
930
+ el.replaceWith( figure );
931
+ el = figure;
932
+ }
933
+ }
934
+ // Cases #2 and #3 (handled transparently)
935
+
936
+ // If there's a centering wrapper, save it in data.
937
+ data.align = 'center';
938
+
939
+ // Image can be wrapped in link <a><img/></a>.
940
+ image = el.getFirst( 'img' ) || el.getFirst( 'a' ).getFirst( 'img' );
941
+ }
942
+
943
+ // No center wrapper has been found.
944
+ else if ( name == 'figure' && el.hasClass( captionedClass ) ) {
945
+ image = el.getFirst( 'img' ) || el.getFirst( 'a' ).getFirst( 'img' );
946
+
947
+ // Upcast linked image like <a><img/></a>.
948
+ } else if ( isLinkedOrStandaloneImage( el ) ) {
949
+ image = el.name == 'a' ? el.children[ 0 ] : el;
950
+ }
951
+
952
+ if ( !image )
953
+ return;
954
+
955
+ // If there's an image, then cool, we got a widget.
956
+ // Now just remove dimension attributes expressed with %.
957
+ for ( var d in dimensions ) {
958
+ var dimension = image.attributes[ d ];
959
+
960
+ if ( dimension && dimension.match( regexPercent ) )
961
+ delete image.attributes[ d ];
962
+ }
963
+
964
+ return el;
965
+ };
966
+ }
967
+
968
+ // Returns a function which transforms the widget to the external format
969
+ // according to the current configuration.
970
+ //
971
+ // @param {CKEDITOR.editor}
972
+ function downcastWidgetElement( editor ) {
973
+ var alignClasses = editor.config.image2_alignClasses;
974
+
975
+ // @param {CKEDITOR.htmlParser.element} el
976
+ return function( el ) {
977
+ // In case of <a><img/></a>, <img/> is the element to hold
978
+ // inline styles or classes (image2_alignClasses).
979
+ var attrsHolder = el.name == 'a' ? el.getFirst() : el,
980
+ attrs = attrsHolder.attributes,
981
+ align = this.data.align;
982
+
983
+ // De-wrap the image from resize handle wrapper.
984
+ // Only block widgets have one.
985
+ if ( !this.inline ) {
986
+ var resizeWrapper = el.getFirst( 'span' );
987
+
988
+ if ( resizeWrapper )
989
+ resizeWrapper.replaceWith( resizeWrapper.getFirst( { img: 1, a: 1 } ) );
990
+ }
991
+
992
+ if ( align && align != 'none' ) {
993
+ var styles = CKEDITOR.tools.parseCssText( attrs.style || '' );
994
+
995
+ // When the widget is captioned (<figure>) and internally centering is done
996
+ // with widget's wrapper style/class, in the external data representation,
997
+ // <figure> must be wrapped with an element holding an style/class:
998
+ //
999
+ // <div style="text-align:center">
1000
+ // <figure class="image" style="display:inline-block">...</figure>
1001
+ // </div>
1002
+ // or
1003
+ // <div class="some-center-class">
1004
+ // <figure class="image">...</figure>
1005
+ // </div>
1006
+ //
1007
+ if ( align == 'center' && el.name == 'figure' ) {
1008
+ el = el.wrapWith( new CKEDITOR.htmlParser.element( 'div',
1009
+ alignClasses ? { 'class': alignClasses[ 1 ] } : { style: 'text-align:center' } ) );
1010
+ }
1011
+
1012
+ // If left/right, add float style to the downcasted element.
1013
+ else if ( align in { left: 1, right: 1 } ) {
1014
+ if ( alignClasses )
1015
+ attrsHolder.addClass( alignClasses[ alignmentsObj[ align ] ] );
1016
+ else
1017
+ styles[ 'float' ] = align;
1018
+ }
1019
+
1020
+ // Update element styles.
1021
+ if ( !alignClasses && !CKEDITOR.tools.isEmpty( styles ) )
1022
+ attrs.style = CKEDITOR.tools.writeCssText( styles );
1023
+ }
1024
+
1025
+ return el;
1026
+ };
1027
+ }
1028
+
1029
+ // Returns a function that checks if an element is a centering wrapper.
1030
+ //
1031
+ // @param {CKEDITOR.editor} editor
1032
+ // @returns {Function}
1033
+ function centerWrapperChecker( editor ) {
1034
+ var captionedClass = editor.config.image2_captionedClass,
1035
+ alignClasses = editor.config.image2_alignClasses,
1036
+ validChildren = { figure: 1, a: 1, img: 1 };
1037
+
1038
+ return function( el ) {
1039
+ // Wrapper must be either <div> or <p>.
1040
+ if ( !( el.name in { div: 1, p: 1 } ) )
1041
+ return false;
1042
+
1043
+ var children = el.children;
1044
+
1045
+ // Centering wrapper can have only one child.
1046
+ if ( children.length !== 1 )
1047
+ return false;
1048
+
1049
+ var child = children[ 0 ];
1050
+
1051
+ // Only <figure> or <img /> can be first (only) child of centering wrapper,
1052
+ // regardless of its type.
1053
+ if ( !( child.name in validChildren ) )
1054
+ return false;
1055
+
1056
+ // If centering wrapper is <p>, only <img /> can be the child.
1057
+ // <p style="text-align:center"><img /></p>
1058
+ if ( el.name == 'p' ) {
1059
+ if ( !isLinkedOrStandaloneImage( child ) )
1060
+ return false;
1061
+ }
1062
+ // Centering <div> can hold <img/> or <figure>, depending on enterMode.
1063
+ else {
1064
+ // If a <figure> is the first (only) child, it must have a class.
1065
+ // <div style="text-align:center"><figure>...</figure><div>
1066
+ if ( child.name == 'figure' ) {
1067
+ if ( !child.hasClass( captionedClass ) )
1068
+ return false;
1069
+ } else {
1070
+ // Centering <div> can hold <img/> or <a><img/></a> only when enterMode
1071
+ // is ENTER_(BR|DIV).
1072
+ // <div style="text-align:center"><img /></div>
1073
+ // <div style="text-align:center"><a><img /></a></div>
1074
+ if ( editor.enterMode == CKEDITOR.ENTER_P )
1075
+ return false;
1076
+
1077
+ // Regardless of enterMode, a child which is not <figure> must be
1078
+ // either <img/> or <a><img/></a>.
1079
+ if ( !isLinkedOrStandaloneImage( child ) )
1080
+ return false;
1081
+ }
1082
+ }
1083
+
1084
+ // Centering wrapper got to be... centering. If image2_alignClasses are defined,
1085
+ // check for centering class. Otherwise, check the style.
1086
+ if ( alignClasses ? el.hasClass( alignClasses[ 1 ] ) :
1087
+ CKEDITOR.tools.parseCssText( el.attributes.style || '', true )[ 'text-align' ] == 'center' )
1088
+ return true;
1089
+
1090
+ return false;
1091
+ };
1092
+ }
1093
+
1094
+ // Checks whether element is <img/> or <a><img/></a>.
1095
+ //
1096
+ // @param {CKEDITOR.htmlParser.element}
1097
+ function isLinkedOrStandaloneImage( el ) {
1098
+ if ( el.name == 'img' )
1099
+ return true;
1100
+ else if ( el.name == 'a' )
1101
+ return el.children.length == 1 && el.getFirst( 'img' );
1102
+
1103
+ return false;
1104
+ }
1105
+
1106
+ // Sets width and height of the widget image according to current widget data.
1107
+ //
1108
+ // @param {CKEDITOR.plugins.widget} widget
1109
+ function setDimensions( widget ) {
1110
+ var data = widget.data,
1111
+ dimensions = { width: data.width, height: data.height },
1112
+ image = widget.parts.image;
1113
+
1114
+ for ( var d in dimensions ) {
1115
+ if ( dimensions[ d ] )
1116
+ image.setAttribute( d, dimensions[ d ] );
1117
+ else
1118
+ image.removeAttribute( d );
1119
+ }
1120
+ }
1121
+
1122
+ // Defines all features related to drag-driven image resizing.
1123
+ //
1124
+ // @param {CKEDITOR.plugins.widget} widget
1125
+ function setupResizer( widget ) {
1126
+ var editor = widget.editor,
1127
+ editable = editor.editable(),
1128
+ doc = editor.document,
1129
+
1130
+ // Store the resizer in a widget for testing (https://dev.ckeditor.com/ticket/11004).
1131
+ resizer = widget.resizer = doc.createElement( 'span' );
1132
+
1133
+ resizer.addClass( 'cke_image_resizer' );
1134
+ resizer.setAttribute( 'title', editor.lang.image2.resizer );
1135
+ resizer.append( new CKEDITOR.dom.text( '\u200b', doc ) );
1136
+
1137
+ // Inline widgets don't need a resizer wrapper as an image spans the entire widget.
1138
+ if ( !widget.inline ) {
1139
+ var imageOrLink = widget.parts.link || widget.parts.image,
1140
+ oldResizeWrapper = imageOrLink.getParent(),
1141
+ resizeWrapper = doc.createElement( 'span' );
1142
+
1143
+ resizeWrapper.addClass( 'cke_image_resizer_wrapper' );
1144
+ resizeWrapper.append( imageOrLink );
1145
+ resizeWrapper.append( resizer );
1146
+ widget.element.append( resizeWrapper, true );
1147
+
1148
+ // Remove the old wrapper which could came from e.g. pasted HTML
1149
+ // and which could be corrupted (e.g. resizer span has been lost).
1150
+ if ( oldResizeWrapper.is( 'span' ) )
1151
+ oldResizeWrapper.remove();
1152
+ } else {
1153
+ widget.wrapper.append( resizer );
1154
+ }
1155
+
1156
+ // Calculate values of size variables and mouse offsets.
1157
+ resizer.on( 'mousedown', function( evt ) {
1158
+ var image = widget.parts.image,
1159
+
1160
+ // "factor" can be either 1 or -1. I.e.: For right-aligned images, we need to
1161
+ // subtract the difference to get proper width, etc. Without "factor",
1162
+ // resizer starts working the opposite way.
1163
+ factor = widget.data.align == 'right' ? -1 : 1,
1164
+
1165
+ // The x-coordinate of the mouse relative to the screen
1166
+ // when button gets pressed.
1167
+ startX = evt.data.$.screenX,
1168
+ startY = evt.data.$.screenY,
1169
+
1170
+ // The initial dimensions and aspect ratio of the image.
1171
+ startWidth = image.$.clientWidth,
1172
+ startHeight = image.$.clientHeight,
1173
+ ratio = startWidth / startHeight,
1174
+
1175
+ listeners = [],
1176
+
1177
+ // A class applied to editable during resizing.
1178
+ cursorClass = 'cke_image_s' + ( !~factor ? 'w' : 'e' ),
1179
+
1180
+ nativeEvt, newWidth, newHeight, updateData,
1181
+ moveDiffX, moveDiffY, moveRatio;
1182
+
1183
+ // Save the undo snapshot first: before resizing.
1184
+ editor.fire( 'saveSnapshot' );
1185
+
1186
+ // Mousemove listeners are removed on mouseup.
1187
+ attachToDocuments( 'mousemove', onMouseMove, listeners );
1188
+
1189
+ // Clean up the mousemove listener. Update widget data if valid.
1190
+ attachToDocuments( 'mouseup', onMouseUp, listeners );
1191
+
1192
+ // The entire editable will have the special cursor while resizing goes on.
1193
+ editable.addClass( cursorClass );
1194
+
1195
+ // This is to always keep the resizer element visible while resizing.
1196
+ resizer.addClass( 'cke_image_resizing' );
1197
+
1198
+ // Attaches an event to a global document if inline editor.
1199
+ // Additionally, if classic (`iframe`-based) editor, also attaches the same event to `iframe`'s document.
1200
+ function attachToDocuments( name, callback, collection ) {
1201
+ var globalDoc = CKEDITOR.document,
1202
+ listeners = [];
1203
+
1204
+ if ( !doc.equals( globalDoc ) )
1205
+ listeners.push( globalDoc.on( name, callback ) );
1206
+
1207
+ listeners.push( doc.on( name, callback ) );
1208
+
1209
+ if ( collection ) {
1210
+ for ( var i = listeners.length; i--; )
1211
+ collection.push( listeners.pop() );
1212
+ }
1213
+ }
1214
+
1215
+ // Calculate with first, and then adjust height, preserving ratio.
1216
+ function adjustToX() {
1217
+ newWidth = startWidth + factor * moveDiffX;
1218
+ newHeight = Math.round( newWidth / ratio );
1219
+ }
1220
+
1221
+ // Calculate height first, and then adjust width, preserving ratio.
1222
+ function adjustToY() {
1223
+ newHeight = startHeight - moveDiffY;
1224
+ newWidth = Math.round( newHeight * ratio );
1225
+ }
1226
+
1227
+ // This is how variables refer to the geometry.
1228
+ // Note: x corresponds to moveOffset, this is the position of mouse
1229
+ // Note: o corresponds to [startX, startY].
1230
+ //
1231
+ // +--------------+--------------+
1232
+ // | | |
1233
+ // | I | II |
1234
+ // | | |
1235
+ // +------------- o -------------+ _ _ _
1236
+ // | | | ^
1237
+ // | VI | III | | moveDiffY
1238
+ // | | x _ _ _ _ _ v
1239
+ // +--------------+---------|----+
1240
+ // | |
1241
+ // <------->
1242
+ // moveDiffX
1243
+ function onMouseMove( evt ) {
1244
+ nativeEvt = evt.data.$;
1245
+
1246
+ // This is how far the mouse is from the point the button was pressed.
1247
+ moveDiffX = nativeEvt.screenX - startX;
1248
+ moveDiffY = startY - nativeEvt.screenY;
1249
+
1250
+ // This is the aspect ratio of the move difference.
1251
+ moveRatio = Math.abs( moveDiffX / moveDiffY );
1252
+
1253
+ // Left, center or none-aligned widget.
1254
+ if ( factor == 1 ) {
1255
+ if ( moveDiffX <= 0 ) {
1256
+ // Case: IV.
1257
+ if ( moveDiffY <= 0 )
1258
+ adjustToX();
1259
+
1260
+ // Case: I.
1261
+ else {
1262
+ if ( moveRatio >= ratio )
1263
+ adjustToX();
1264
+ else
1265
+ adjustToY();
1266
+ }
1267
+ } else {
1268
+ // Case: III.
1269
+ if ( moveDiffY <= 0 ) {
1270
+ if ( moveRatio >= ratio )
1271
+ adjustToY();
1272
+ else
1273
+ adjustToX();
1274
+ }
1275
+
1276
+ // Case: II.
1277
+ else {
1278
+ adjustToY();
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ // Right-aligned widget. It mirrors behaviours, so I becomes II,
1284
+ // IV becomes III and vice-versa.
1285
+ else {
1286
+ if ( moveDiffX <= 0 ) {
1287
+ // Case: IV.
1288
+ if ( moveDiffY <= 0 ) {
1289
+ if ( moveRatio >= ratio )
1290
+ adjustToY();
1291
+ else
1292
+ adjustToX();
1293
+ }
1294
+
1295
+ // Case: I.
1296
+ else {
1297
+ adjustToY();
1298
+ }
1299
+ } else {
1300
+ // Case: III.
1301
+ if ( moveDiffY <= 0 )
1302
+ adjustToX();
1303
+
1304
+ // Case: II.
1305
+ else {
1306
+ if ( moveRatio >= ratio ) {
1307
+ adjustToX();
1308
+ } else {
1309
+ adjustToY();
1310
+ }
1311
+ }
1312
+ }
1313
+ }
1314
+
1315
+ // Don't update attributes if less than 10.
1316
+ // This is to prevent images to visually disappear.
1317
+ if ( newWidth >= 15 && newHeight >= 15 ) {
1318
+ image.setAttributes( { width: newWidth, height: newHeight } );
1319
+ updateData = true;
1320
+ } else {
1321
+ updateData = false;
1322
+ }
1323
+ }
1324
+
1325
+ function onMouseUp() {
1326
+ var l;
1327
+
1328
+ while ( ( l = listeners.pop() ) )
1329
+ l.removeListener();
1330
+
1331
+ // Restore default cursor by removing special class.
1332
+ editable.removeClass( cursorClass );
1333
+
1334
+ // This is to bring back the regular behaviour of the resizer.
1335
+ resizer.removeClass( 'cke_image_resizing' );
1336
+
1337
+ if ( updateData ) {
1338
+ widget.setData( { width: newWidth, height: newHeight } );
1339
+
1340
+ // Save another undo snapshot: after resizing.
1341
+ editor.fire( 'saveSnapshot' );
1342
+ }
1343
+
1344
+ // Don't update data twice or more.
1345
+ updateData = false;
1346
+ }
1347
+ } );
1348
+
1349
+ // Change the position of the widget resizer when data changes.
1350
+ widget.on( 'data', function() {
1351
+ resizer[ widget.data.align == 'right' ? 'addClass' : 'removeClass' ]( 'cke_image_resizer_left' );
1352
+ } );
1353
+ }
1354
+
1355
+ // Integrates widget alignment setting with justify
1356
+ // plugin's commands (execution and refreshment).
1357
+ // @param {CKEDITOR.editor} editor
1358
+ // @param {String} value 'left', 'right', 'center' or 'block'
1359
+ function alignCommandIntegrator( editor ) {
1360
+ var execCallbacks = [],
1361
+ enabled;
1362
+
1363
+ return function( value ) {
1364
+ var command = editor.getCommand( 'justify' + value );
1365
+
1366
+ // Most likely, the justify plugin isn't loaded.
1367
+ if ( !command )
1368
+ return;
1369
+
1370
+ // This command will be manually refreshed along with
1371
+ // other commands after exec.
1372
+ execCallbacks.push( function() {
1373
+ command.refresh( editor, editor.elementPath() );
1374
+ } );
1375
+
1376
+ if ( value in { right: 1, left: 1, center: 1 } ) {
1377
+ command.on( 'exec', function( evt ) {
1378
+ var widget = getFocusedWidget( editor );
1379
+
1380
+ if ( widget ) {
1381
+ widget.setData( 'align', value );
1382
+
1383
+ // Once the widget changed its align, all the align commands
1384
+ // must be refreshed: the event is to be cancelled.
1385
+ for ( var i = execCallbacks.length; i--; )
1386
+ execCallbacks[ i ]();
1387
+
1388
+ evt.cancel();
1389
+ }
1390
+ } );
1391
+ }
1392
+
1393
+ command.on( 'refresh', function( evt ) {
1394
+ var widget = getFocusedWidget( editor ),
1395
+ allowed = { right: 1, left: 1, center: 1 };
1396
+
1397
+ if ( !widget )
1398
+ return;
1399
+
1400
+ // Cache "enabled" on first use. This is because filter#checkFeature may
1401
+ // not be available during plugin's afterInit in the future — a moment when
1402
+ // alignCommandIntegrator is called.
1403
+ if ( enabled === undefined )
1404
+ enabled = editor.filter.checkFeature( editor.widgets.registered.image.features.align );
1405
+
1406
+ // Don't allow justify commands when widget alignment is disabled (https://dev.ckeditor.com/ticket/11004).
1407
+ if ( !enabled )
1408
+ this.setState( CKEDITOR.TRISTATE_DISABLED );
1409
+ else {
1410
+ this.setState(
1411
+ ( widget.data.align == value ) ? (
1412
+ CKEDITOR.TRISTATE_ON
1413
+ ) : (
1414
+ ( value in allowed ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED
1415
+ )
1416
+ );
1417
+ }
1418
+
1419
+ evt.cancel();
1420
+ } );
1421
+ };
1422
+ }
1423
+
1424
+ function linkCommandIntegrator( editor ) {
1425
+ // Nothing to integrate with if link is not loaded.
1426
+ if ( !editor.plugins.link )
1427
+ return;
1428
+
1429
+ CKEDITOR.on( 'dialogDefinition', function( evt ) {
1430
+ var dialog = evt.data;
1431
+
1432
+ if ( dialog.name == 'link' ) {
1433
+ var def = dialog.definition;
1434
+
1435
+ var onShow = def.onShow,
1436
+ onOk = def.onOk;
1437
+
1438
+ def.onShow = function() {
1439
+ var widget = getFocusedWidget( editor ),
1440
+ displayTextField = this.getContentElement( 'info', 'linkDisplayText' ).getElement().getParent().getParent();
1441
+
1442
+ // Widget cannot be enclosed in a link, i.e.
1443
+ // <a>foo<inline widget/>bar</a>
1444
+ if ( widget && ( widget.inline ? !widget.wrapper.getAscendant( 'a' ) : 1 ) ) {
1445
+ this.setupContent( widget.data.link || {} );
1446
+
1447
+ // Hide the display text in case of linking image2 widget.
1448
+ displayTextField.hide();
1449
+ } else {
1450
+ // Make sure that display text is visible, as it might be hidden by image2 integration
1451
+ // before.
1452
+ displayTextField.show();
1453
+ onShow.apply( this, arguments );
1454
+ }
1455
+ };
1456
+
1457
+ // Set widget data if linking the widget using
1458
+ // link dialog (instead of default action).
1459
+ // State shifter handles data change and takes
1460
+ // care of internal DOM structure of linked widget.
1461
+ def.onOk = function() {
1462
+ var widget = getFocusedWidget( editor );
1463
+
1464
+ // Widget cannot be enclosed in a link, i.e.
1465
+ // <a>foo<inline widget/>bar</a>
1466
+ if ( widget && ( widget.inline ? !widget.wrapper.getAscendant( 'a' ) : 1 ) ) {
1467
+ var data = {};
1468
+
1469
+ // Collect data from fields.
1470
+ this.commitContent( data );
1471
+
1472
+ // Set collected data to widget.
1473
+ widget.setData( 'link', data );
1474
+ } else {
1475
+ onOk.apply( this, arguments );
1476
+ }
1477
+ };
1478
+ }
1479
+ } );
1480
+
1481
+ // Overwrite default behaviour of unlink command.
1482
+ editor.getCommand( 'unlink' ).on( 'exec', function( evt ) {
1483
+ var widget = getFocusedWidget( editor );
1484
+
1485
+ // Override unlink only when link truly belongs to the widget.
1486
+ // If wrapped inline widget in a link, let default unlink work (https://dev.ckeditor.com/ticket/11814).
1487
+ if ( !widget || !widget.parts.link )
1488
+ return;
1489
+
1490
+ widget.setData( 'link', null );
1491
+
1492
+ // Selection (which is fake) may not change if unlinked image in focused widget,
1493
+ // i.e. if captioned image. Let's refresh command state manually here.
1494
+ this.refresh( editor, editor.elementPath() );
1495
+
1496
+ evt.cancel();
1497
+ } );
1498
+
1499
+ // Overwrite default refresh of unlink command.
1500
+ editor.getCommand( 'unlink' ).on( 'refresh', function( evt ) {
1501
+ var widget = getFocusedWidget( editor );
1502
+
1503
+ if ( !widget )
1504
+ return;
1505
+
1506
+ // Note that widget may be wrapped in a link, which
1507
+ // does not belong to that widget (https://dev.ckeditor.com/ticket/11814).
1508
+ this.setState( widget.data.link || widget.wrapper.getAscendant( 'a' ) ?
1509
+ CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );
1510
+
1511
+ evt.cancel();
1512
+ } );
1513
+ }
1514
+
1515
+ // Returns the focused widget, if of the type specific for this plugin.
1516
+ // If no widget is focused, `null` is returned.
1517
+ //
1518
+ // @param {CKEDITOR.editor}
1519
+ // @returns {CKEDITOR.plugins.widget}
1520
+ function getFocusedWidget( editor ) {
1521
+ var widget = editor.widgets.focused;
1522
+
1523
+ if ( widget && widget.name == 'image' )
1524
+ return widget;
1525
+
1526
+ return null;
1527
+ }
1528
+
1529
+ // Returns a set of widget allowedContent rules, depending
1530
+ // on configurations like config#image2_alignClasses or
1531
+ // config#image2_captionedClass.
1532
+ //
1533
+ // @param {CKEDITOR.editor}
1534
+ // @returns {Object}
1535
+ function getWidgetAllowedContent( editor ) {
1536
+ var alignClasses = editor.config.image2_alignClasses,
1537
+ rules = {
1538
+ // Widget may need <div> or <p> centering wrapper.
1539
+ div: {
1540
+ match: centerWrapperChecker( editor )
1541
+ },
1542
+ p: {
1543
+ match: centerWrapperChecker( editor )
1544
+ },
1545
+ img: {
1546
+ attributes: '!src,alt,width,height'
1547
+ },
1548
+ figure: {
1549
+ classes: '!' + editor.config.image2_captionedClass
1550
+ },
1551
+ figcaption: true
1552
+ };
1553
+
1554
+ if ( alignClasses ) {
1555
+ // Centering class from the config.
1556
+ rules.div.classes = alignClasses[ 1 ];
1557
+ rules.p.classes = rules.div.classes;
1558
+
1559
+ // Left/right classes from the config.
1560
+ rules.img.classes = alignClasses[ 0 ] + ',' + alignClasses[ 2 ];
1561
+ rules.figure.classes += ',' + rules.img.classes;
1562
+ } else {
1563
+ // Centering with text-align.
1564
+ rules.div.styles = 'text-align';
1565
+ rules.p.styles = 'text-align';
1566
+
1567
+ rules.img.styles = 'float';
1568
+ rules.figure.styles = 'float,display';
1569
+ }
1570
+
1571
+ return rules;
1572
+ }
1573
+
1574
+ // Returns a set of widget feature rules, depending
1575
+ // on editor configuration. Note that the following may not cover
1576
+ // all the possible cases since requiredContent supports a single
1577
+ // tag only.
1578
+ //
1579
+ // @param {CKEDITOR.editor}
1580
+ // @returns {Object}
1581
+ function getWidgetFeatures( editor ) {
1582
+ var alignClasses = editor.config.image2_alignClasses,
1583
+ features = {
1584
+ dimension: {
1585
+ requiredContent: 'img[width,height]'
1586
+ },
1587
+ align: {
1588
+ requiredContent: 'img' +
1589
+ ( alignClasses ? '(' + alignClasses[ 0 ] + ')' : '{float}' )
1590
+ },
1591
+ caption: {
1592
+ requiredContent: 'figcaption'
1593
+ }
1594
+ };
1595
+
1596
+ return features;
1597
+ }
1598
+
1599
+ // Returns element which is styled, considering current
1600
+ // state of the widget.
1601
+ //
1602
+ // @see CKEDITOR.plugins.widget#applyStyle
1603
+ // @param {CKEDITOR.plugins.widget} widget
1604
+ // @returns {CKEDITOR.dom.element}
1605
+ function getStyleableElement( widget ) {
1606
+ return widget.data.hasCaption ? widget.element : widget.parts.image;
1607
+ }
1608
+ } )();
1609
+
1610
+ /**
1611
+ * A CSS class applied to the `<figure>` element of a captioned image.
1612
+ *
1613
+ * Read more in the [documentation](#!/guide/dev_image2) and see the
1614
+ * [SDK sample](https://sdk.ckeditor.com/samples/image2.html).
1615
+ *
1616
+ * // Changes the class to "captionedImage".
1617
+ * config.image2_captionedClass = 'captionedImage';
1618
+ *
1619
+ * @cfg {String} [image2_captionedClass='image']
1620
+ * @member CKEDITOR.config
1621
+ */
1622
+ CKEDITOR.config.image2_captionedClass = 'image';
1623
+
1624
+ /**
1625
+ * Determines whether dimension inputs should be automatically filled when the image URL changes in the Enhanced Image
1626
+ * plugin dialog window.
1627
+ *
1628
+ * Read more in the [documentation](#!/guide/dev_image2) and see the
1629
+ * [SDK sample](https://sdk.ckeditor.com/samples/image2.html).
1630
+ *
1631
+ * config.image2_prefillDimensions = false;
1632
+ *
1633
+ * @since 4.5
1634
+ * @cfg {Boolean} [image2_prefillDimensions=true]
1635
+ * @member CKEDITOR.config
1636
+ */
1637
+
1638
+ /**
1639
+ * Disables the image resizer. By default the resizer is enabled.
1640
+ *
1641
+ * Read more in the [documentation](#!/guide/dev_image2) and see the
1642
+ * [SDK sample](https://sdk.ckeditor.com/samples/image2.html).
1643
+ *
1644
+ * config.image2_disableResizer = true;
1645
+ *
1646
+ * @since 4.5
1647
+ * @cfg {Boolean} [image2_disableResizer=false]
1648
+ * @member CKEDITOR.config
1649
+ */
1650
+
1651
+ /**
1652
+ * CSS classes applied to aligned images. Useful to take control over the way
1653
+ * the images are aligned, i.e. to customize output HTML and integrate external stylesheets.
1654
+ *
1655
+ * Classes should be defined in an array of three elements, containing left, center, and right
1656
+ * alignment classes, respectively. For example:
1657
+ *
1658
+ * config.image2_alignClasses = [ 'align-left', 'align-center', 'align-right' ];
1659
+ *
1660
+ * **Note**: Once this configuration option is set, the plugin will no longer produce inline
1661
+ * styles for alignment. It means that e.g. the following HTML will be produced:
1662
+ *
1663
+ * <img alt="My image" class="custom-center-class" src="foo.png" />
1664
+ *
1665
+ * instead of:
1666
+ *
1667
+ * <img alt="My image" style="float:left" src="foo.png" />
1668
+ *
1669
+ * **Note**: Once this configuration option is set, corresponding style definitions
1670
+ * must be supplied to the editor:
1671
+ *
1672
+ * * For {@glink guide/dev_framed classic editor} it can be done by defining additional
1673
+ * styles in the {@link CKEDITOR.config#contentsCss stylesheets loaded by the editor}. The same
1674
+ * styles must be provided on the target page where the content will be loaded.
1675
+ * * For {@glink guide/dev_inline inline editor} the styles can be defined directly
1676
+ * with `<style> ... <style>` or `<link href="..." rel="stylesheet">`, i.e. within the `<head>`
1677
+ * of the page.
1678
+ *
1679
+ * For example, considering the following configuration:
1680
+ *
1681
+ * config.image2_alignClasses = [ 'align-left', 'align-center', 'align-right' ];
1682
+ *
1683
+ * CSS rules can be defined as follows:
1684
+ *
1685
+ * .align-left {
1686
+ * float: left;
1687
+ * }
1688
+ *
1689
+ * .align-right {
1690
+ * float: right;
1691
+ * }
1692
+ *
1693
+ * .align-center {
1694
+ * text-align: center;
1695
+ * }
1696
+ *
1697
+ * .align-center > figure {
1698
+ * display: inline-block;
1699
+ * }
1700
+ *
1701
+ * Read more in the [documentation](#!/guide/dev_image2) and see the
1702
+ * [SDK sample](https://sdk.ckeditor.com/samples/image2.html).
1703
+ *
1704
+ * @since 4.4
1705
+ * @cfg {String[]} [image2_alignClasses=null]
1706
+ * @member CKEDITOR.config
1707
+ */
1708
+
1709
+ /**
1710
+ * Determines whether alternative text is required for the captioned image.
1711
+ *
1712
+ * config.image2_altRequired = true;
1713
+ *
1714
+ * Read more in the [documentation](#!/guide/dev_image2) and see the
1715
+ * [SDK sample](https://sdk.ckeditor.com/samples/image2.html).
1716
+ *
1717
+ * @since 4.6.0
1718
+ * @cfg {Boolean} [image2_altRequired=false]
1719
+ * @member CKEDITOR.config
1720
+ */