integral 1.0.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (637) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +11 -49
  3. data/Rakefile +1 -1
  4. data/app/assets/images/integral/defaults/no_image_available.jpg +0 -0
  5. data/app/assets/images/logo.png +0 -0
  6. data/app/assets/javascripts/ckeditor/my_config.js.erb +26 -18
  7. data/app/assets/javascripts/ckeditor/plugins/autoembed/lang/lv.js +8 -0
  8. data/app/assets/javascripts/ckeditor/plugins/autoembed/plugin.js +1 -1
  9. data/app/assets/javascripts/ckeditor/plugins/autogrow/plugin.js +14 -14
  10. data/app/assets/javascripts/ckeditor/plugins/autogrow/samples/autogrow.html +8 -8
  11. data/app/assets/javascripts/ckeditor/plugins/codemirror/css/codemirror.min.css +1 -1
  12. data/app/assets/javascripts/ckeditor/plugins/codemirror/icons/autoformat.png +0 -0
  13. data/app/assets/javascripts/ckeditor/plugins/codemirror/icons/searchcode.png +0 -0
  14. data/app/assets/javascripts/ckeditor/plugins/codemirror/icons/uncommentselectedrange.png +0 -0
  15. data/app/assets/javascripts/ckeditor/plugins/codemirror/images/autocomplete.png +0 -0
  16. data/app/assets/javascripts/ckeditor/plugins/codemirror/images/autoformat.png +0 -0
  17. data/app/assets/javascripts/ckeditor/plugins/codemirror/images/commentselectedrange.png +0 -0
  18. data/app/assets/javascripts/ckeditor/plugins/codemirror/images/searchcode.png +0 -0
  19. data/app/assets/javascripts/ckeditor/plugins/codemirror/images/uncommentselectedrange.png +0 -0
  20. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/beautify.min.js +2 -2
  21. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.addons.min.js +2 -2
  22. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.addons.search.min.js +1 -1
  23. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.min.js +1 -6
  24. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.bbcodemixed.min.js +1 -1
  25. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.handlebars.min.js +1 -0
  26. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.htmlmixed.min.js +2 -2
  27. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.javascript.min.js +1 -1
  28. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.php.min.js +3 -3
  29. data/app/assets/javascripts/ckeditor/plugins/codemirror/js/codemirror.mode.twig.min.js +1 -1
  30. data/app/assets/javascripts/ckeditor/plugins/codemirror/lang/bg.js +7 -7
  31. data/app/assets/javascripts/ckeditor/plugins/codemirror/plugin.js +231 -217
  32. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/darcula.css +46 -0
  33. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/gruvbox-dark.css +34 -0
  34. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/idea.css +42 -0
  35. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/lesser-dark.css +1 -1
  36. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/lucario.css +37 -0
  37. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/monokai.css +5 -0
  38. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/oceanic-next.css +44 -0
  39. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/shadowfox.css +52 -0
  40. data/app/assets/javascripts/ckeditor/plugins/codemirror/theme/ssms.css +16 -0
  41. data/app/assets/javascripts/ckeditor/plugins/embedbase/lang/ar.js +15 -0
  42. data/app/assets/javascripts/ckeditor/plugins/embedbase/lang/lv.js +15 -0
  43. data/app/assets/javascripts/ckeditor/plugins/embedbase/plugin.js +1 -1
  44. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/copywidget.png +0 -0
  45. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/editwidget.png +0 -0
  46. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/hidpi/copywidget.png +0 -0
  47. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/hidpi/editwidget.png +0 -0
  48. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/hidpi/removewidget.png +0 -0
  49. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/hidpi/widget.png +0 -0
  50. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/removewidget.png +0 -0
  51. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/icons/widget.png +0 -0
  52. data/app/assets/javascripts/ckeditor/plugins/foundation-callout/plugin.js +86 -0
  53. data/app/assets/javascripts/ckeditor/plugins/image2/dev/assets/image1.jpg +0 -0
  54. data/app/assets/javascripts/ckeditor/plugins/image2/dev/assets/image2.jpg +0 -0
  55. data/app/assets/javascripts/ckeditor/plugins/image2/dev/contents.css +35 -0
  56. data/app/assets/javascripts/ckeditor/plugins/image2/dev/image2.html +339 -0
  57. data/app/assets/javascripts/ckeditor/plugins/image2/dialogs/image2.js +553 -0
  58. data/app/assets/javascripts/ckeditor/plugins/image2/icons/hidpi/image.png +0 -0
  59. data/app/assets/javascripts/ckeditor/plugins/image2/icons/image.png +0 -0
  60. data/app/assets/javascripts/ckeditor/plugins/image2/lang/af.js +21 -0
  61. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ar.js +21 -0
  62. data/app/assets/javascripts/ckeditor/plugins/image2/lang/az.js +21 -0
  63. data/app/assets/javascripts/ckeditor/plugins/image2/lang/bg.js +21 -0
  64. data/app/assets/javascripts/ckeditor/plugins/image2/lang/bn.js +21 -0
  65. data/app/assets/javascripts/ckeditor/plugins/image2/lang/bs.js +21 -0
  66. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ca.js +21 -0
  67. data/app/assets/javascripts/ckeditor/plugins/image2/lang/cs.js +21 -0
  68. data/app/assets/javascripts/ckeditor/plugins/image2/lang/cy.js +21 -0
  69. data/app/assets/javascripts/ckeditor/plugins/image2/lang/da.js +21 -0
  70. data/app/assets/javascripts/ckeditor/plugins/image2/lang/de-ch.js +21 -0
  71. data/app/assets/javascripts/ckeditor/plugins/image2/lang/de.js +21 -0
  72. data/app/assets/javascripts/ckeditor/plugins/image2/lang/el.js +21 -0
  73. data/app/assets/javascripts/ckeditor/plugins/image2/lang/en-au.js +21 -0
  74. data/app/assets/javascripts/ckeditor/plugins/image2/lang/en-ca.js +21 -0
  75. data/app/assets/javascripts/ckeditor/plugins/image2/lang/en-gb.js +21 -0
  76. data/app/assets/javascripts/ckeditor/plugins/image2/lang/en.js +21 -0
  77. data/app/assets/javascripts/ckeditor/plugins/image2/lang/eo.js +21 -0
  78. data/app/assets/javascripts/ckeditor/plugins/image2/lang/es-mx.js +21 -0
  79. data/app/assets/javascripts/ckeditor/plugins/image2/lang/es.js +21 -0
  80. data/app/assets/javascripts/ckeditor/plugins/image2/lang/et.js +21 -0
  81. data/app/assets/javascripts/ckeditor/plugins/image2/lang/eu.js +21 -0
  82. data/app/assets/javascripts/ckeditor/plugins/image2/lang/fa.js +21 -0
  83. data/app/assets/javascripts/ckeditor/plugins/image2/lang/fi.js +21 -0
  84. data/app/assets/javascripts/ckeditor/plugins/image2/lang/fo.js +21 -0
  85. data/app/assets/javascripts/ckeditor/plugins/image2/lang/fr-ca.js +21 -0
  86. data/app/assets/javascripts/ckeditor/plugins/image2/lang/fr.js +21 -0
  87. data/app/assets/javascripts/ckeditor/plugins/image2/lang/gl.js +21 -0
  88. data/app/assets/javascripts/ckeditor/plugins/image2/lang/gu.js +21 -0
  89. data/app/assets/javascripts/ckeditor/plugins/image2/lang/he.js +21 -0
  90. data/app/assets/javascripts/ckeditor/plugins/image2/lang/hi.js +21 -0
  91. data/app/assets/javascripts/ckeditor/plugins/image2/lang/hr.js +21 -0
  92. data/app/assets/javascripts/ckeditor/plugins/image2/lang/hu.js +21 -0
  93. data/app/assets/javascripts/ckeditor/plugins/image2/lang/id.js +21 -0
  94. data/app/assets/javascripts/ckeditor/plugins/image2/lang/is.js +21 -0
  95. data/app/assets/javascripts/ckeditor/plugins/image2/lang/it.js +21 -0
  96. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ja.js +21 -0
  97. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ka.js +21 -0
  98. data/app/assets/javascripts/ckeditor/plugins/image2/lang/km.js +21 -0
  99. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ko.js +21 -0
  100. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ku.js +21 -0
  101. data/app/assets/javascripts/ckeditor/plugins/image2/lang/lt.js +21 -0
  102. data/app/assets/javascripts/ckeditor/plugins/image2/lang/lv.js +21 -0
  103. data/app/assets/javascripts/ckeditor/plugins/image2/lang/mk.js +21 -0
  104. data/app/assets/javascripts/ckeditor/plugins/image2/lang/mn.js +21 -0
  105. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ms.js +21 -0
  106. data/app/assets/javascripts/ckeditor/plugins/image2/lang/nb.js +21 -0
  107. data/app/assets/javascripts/ckeditor/plugins/image2/lang/nl.js +21 -0
  108. data/app/assets/javascripts/ckeditor/plugins/image2/lang/no.js +21 -0
  109. data/app/assets/javascripts/ckeditor/plugins/image2/lang/oc.js +21 -0
  110. data/app/assets/javascripts/ckeditor/plugins/image2/lang/pl.js +21 -0
  111. data/app/assets/javascripts/ckeditor/plugins/image2/lang/pt-br.js +21 -0
  112. data/app/assets/javascripts/ckeditor/plugins/image2/lang/pt.js +21 -0
  113. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ro.js +21 -0
  114. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ru.js +21 -0
  115. data/app/assets/javascripts/ckeditor/plugins/image2/lang/si.js +21 -0
  116. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sk.js +21 -0
  117. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sl.js +21 -0
  118. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sq.js +21 -0
  119. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sr-latn.js +21 -0
  120. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sr.js +21 -0
  121. data/app/assets/javascripts/ckeditor/plugins/image2/lang/sv.js +21 -0
  122. data/app/assets/javascripts/ckeditor/plugins/image2/lang/th.js +21 -0
  123. data/app/assets/javascripts/ckeditor/plugins/image2/lang/tr.js +21 -0
  124. data/app/assets/javascripts/ckeditor/plugins/image2/lang/tt.js +21 -0
  125. data/app/assets/javascripts/ckeditor/plugins/image2/lang/ug.js +21 -0
  126. data/app/assets/javascripts/ckeditor/plugins/image2/lang/uk.js +21 -0
  127. data/app/assets/javascripts/ckeditor/plugins/image2/lang/vi.js +21 -0
  128. data/app/assets/javascripts/ckeditor/plugins/image2/lang/zh-cn.js +21 -0
  129. data/app/assets/javascripts/ckeditor/plugins/image2/lang/zh.js +21 -0
  130. data/app/assets/javascripts/ckeditor/plugins/image2/plugin.js +1720 -0
  131. data/app/assets/javascripts/ckeditor/plugins/image2/samples/assets/image1.jpg +0 -0
  132. data/app/assets/javascripts/ckeditor/plugins/image2/samples/assets/image2.jpg +0 -0
  133. data/app/assets/javascripts/ckeditor/plugins/image2/samples/image2.html +68 -0
  134. data/app/assets/javascripts/ckeditor/plugins/lineutils/dev/dnd.html +4 -4
  135. data/app/assets/javascripts/ckeditor/plugins/lineutils/dev/magicfinger.html +4 -4
  136. data/app/assets/javascripts/ckeditor/plugins/lineutils/plugin.js +7 -7
  137. data/app/assets/javascripts/ckeditor/plugins/linkballoon/README.md +5 -0
  138. data/app/assets/javascripts/ckeditor/plugins/linkballoon/assets/demo.png +0 -0
  139. data/app/assets/javascripts/ckeditor/plugins/linkballoon/plugin.js +25 -0
  140. data/app/assets/javascripts/ckeditor/plugins/notification/lang/az.js +7 -0
  141. data/app/assets/javascripts/ckeditor/plugins/notification/lang/bg.js +7 -0
  142. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ca.js +7 -0
  143. data/app/assets/javascripts/ckeditor/plugins/notification/lang/cs.js +2 -2
  144. data/app/assets/javascripts/ckeditor/plugins/notification/lang/da.js +2 -2
  145. data/app/assets/javascripts/ckeditor/plugins/notification/lang/de-ch.js +2 -2
  146. data/app/assets/javascripts/ckeditor/plugins/notification/lang/de.js +2 -2
  147. data/app/assets/javascripts/ckeditor/plugins/notification/lang/en-au.js +7 -0
  148. data/app/assets/javascripts/ckeditor/plugins/notification/lang/en.js +2 -2
  149. data/app/assets/javascripts/ckeditor/plugins/notification/lang/eo.js +2 -2
  150. data/app/assets/javascripts/ckeditor/plugins/notification/lang/es-mx.js +7 -0
  151. data/app/assets/javascripts/ckeditor/plugins/notification/lang/es.js +7 -0
  152. data/app/assets/javascripts/ckeditor/plugins/notification/lang/et.js +7 -0
  153. data/app/assets/javascripts/ckeditor/plugins/notification/lang/eu.js +2 -2
  154. data/app/assets/javascripts/ckeditor/plugins/notification/lang/fa.js +7 -0
  155. data/app/assets/javascripts/ckeditor/plugins/notification/lang/fr.js +3 -3
  156. data/app/assets/javascripts/ckeditor/plugins/notification/lang/gl.js +2 -2
  157. data/app/assets/javascripts/ckeditor/plugins/notification/lang/hr.js +7 -0
  158. data/app/assets/javascripts/ckeditor/plugins/notification/lang/hu.js +7 -0
  159. data/app/assets/javascripts/ckeditor/plugins/notification/lang/id.js +2 -2
  160. data/app/assets/javascripts/ckeditor/plugins/notification/lang/it.js +2 -2
  161. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ja.js +7 -0
  162. data/app/assets/javascripts/ckeditor/plugins/notification/lang/km.js +2 -2
  163. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ko.js +2 -2
  164. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ku.js +2 -2
  165. data/app/assets/javascripts/ckeditor/plugins/notification/lang/lv.js +7 -0
  166. data/app/assets/javascripts/ckeditor/plugins/notification/lang/nb.js +2 -2
  167. data/app/assets/javascripts/ckeditor/plugins/notification/lang/nl.js +2 -2
  168. data/app/assets/javascripts/ckeditor/plugins/notification/lang/oc.js +7 -0
  169. data/app/assets/javascripts/ckeditor/plugins/notification/lang/pl.js +2 -2
  170. data/app/assets/javascripts/ckeditor/plugins/notification/lang/pt-br.js +2 -2
  171. data/app/assets/javascripts/ckeditor/plugins/notification/lang/pt.js +2 -2
  172. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ro.js +7 -0
  173. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ru.js +2 -2
  174. data/app/assets/javascripts/ckeditor/plugins/notification/lang/sk.js +7 -0
  175. data/app/assets/javascripts/ckeditor/plugins/notification/lang/sq.js +7 -0
  176. data/app/assets/javascripts/ckeditor/plugins/notification/lang/sv.js +2 -2
  177. data/app/assets/javascripts/ckeditor/plugins/notification/lang/tr.js +2 -2
  178. data/app/assets/javascripts/ckeditor/plugins/notification/lang/ug.js +2 -2
  179. data/app/assets/javascripts/ckeditor/plugins/notification/lang/uk.js +2 -2
  180. data/app/assets/javascripts/ckeditor/plugins/notification/lang/zh-cn.js +3 -3
  181. data/app/assets/javascripts/ckeditor/plugins/notification/lang/zh.js +2 -2
  182. data/app/assets/javascripts/ckeditor/plugins/notification/plugin.js +794 -784
  183. data/app/assets/javascripts/ckeditor/plugins/openlink/README.md +50 -0
  184. data/app/assets/javascripts/ckeditor/plugins/openlink/icons/hidpi/openLink.png +0 -0
  185. data/app/assets/javascripts/ckeditor/plugins/openlink/icons/openLink.png +0 -0
  186. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/bg.js +7 -0
  187. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/de.js +7 -0
  188. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/en.js +7 -0
  189. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/pl.js +7 -0
  190. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/ru.js +7 -0
  191. data/app/assets/javascripts/ckeditor/plugins/openlink/lang/uk.js +7 -0
  192. data/app/assets/javascripts/ckeditor/plugins/openlink/plugin.js +178 -0
  193. data/app/assets/javascripts/ckeditor/plugins/placeholder/dev/placeholder.html +5 -5
  194. data/app/assets/javascripts/ckeditor/plugins/placeholder/dialogs/placeholder.js +2 -2
  195. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/af.js +2 -2
  196. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ar.js +2 -2
  197. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/az.js +2 -2
  198. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/bg.js +5 -5
  199. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ca.js +2 -2
  200. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/cs.js +2 -2
  201. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/cy.js +2 -2
  202. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/da.js +2 -2
  203. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/de-ch.js +2 -2
  204. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/de.js +2 -2
  205. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/el.js +2 -2
  206. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/en-au.js +12 -0
  207. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/en-gb.js +2 -2
  208. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/en.js +2 -2
  209. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/eo.js +2 -2
  210. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/es-mx.js +2 -2
  211. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/es.js +2 -2
  212. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/et.js +2 -2
  213. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/eu.js +2 -2
  214. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/fa.js +2 -2
  215. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/fi.js +2 -2
  216. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/fr-ca.js +2 -2
  217. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/fr.js +2 -2
  218. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/gl.js +2 -2
  219. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/he.js +2 -2
  220. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/hr.js +2 -2
  221. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/hu.js +2 -2
  222. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/id.js +2 -2
  223. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/it.js +2 -2
  224. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ja.js +2 -2
  225. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/km.js +2 -2
  226. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ko.js +2 -2
  227. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ku.js +2 -2
  228. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/lv.js +5 -5
  229. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/nb.js +2 -2
  230. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/nl.js +2 -2
  231. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/no.js +2 -2
  232. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/oc.js +2 -2
  233. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/pl.js +2 -2
  234. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/pt-br.js +2 -2
  235. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/pt.js +2 -2
  236. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ro.js +12 -0
  237. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ru.js +2 -2
  238. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/si.js +2 -2
  239. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/sk.js +2 -2
  240. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/sl.js +2 -2
  241. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/sq.js +2 -2
  242. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/sv.js +2 -2
  243. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/th.js +2 -2
  244. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/tr.js +2 -2
  245. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/tt.js +2 -2
  246. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/ug.js +2 -2
  247. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/uk.js +2 -2
  248. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/vi.js +2 -2
  249. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/zh-cn.js +2 -2
  250. data/app/assets/javascripts/ckeditor/plugins/placeholder/lang/zh.js +2 -2
  251. data/app/assets/javascripts/ckeditor/plugins/placeholder/plugin.js +3 -3
  252. data/app/assets/javascripts/ckeditor/plugins/placeholder/samples/placeholder.html +6 -6
  253. data/app/assets/javascripts/ckeditor/plugins/widget/dev/assets/simplebox/dialogs/simplebox.js +4 -4
  254. data/app/assets/javascripts/ckeditor/plugins/widget/dev/assets/simplebox/plugin.js +3 -3
  255. data/app/assets/javascripts/ckeditor/plugins/widget/dev/console.js +2 -2
  256. data/app/assets/javascripts/ckeditor/plugins/widget/dev/nestedwidgets.html +2 -2
  257. data/app/assets/javascripts/ckeditor/plugins/widget/dev/widgetstyles.html +2 -2
  258. data/app/assets/javascripts/ckeditor/plugins/widget/lang/af.js +2 -2
  259. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ar.js +2 -2
  260. data/app/assets/javascripts/ckeditor/plugins/widget/lang/az.js +2 -2
  261. data/app/assets/javascripts/ckeditor/plugins/widget/lang/bg.js +3 -3
  262. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ca.js +2 -2
  263. data/app/assets/javascripts/ckeditor/plugins/widget/lang/cs.js +2 -2
  264. data/app/assets/javascripts/ckeditor/plugins/widget/lang/cy.js +2 -2
  265. data/app/assets/javascripts/ckeditor/plugins/widget/lang/da.js +2 -2
  266. data/app/assets/javascripts/ckeditor/plugins/widget/lang/de-ch.js +2 -2
  267. data/app/assets/javascripts/ckeditor/plugins/widget/lang/de.js +2 -2
  268. data/app/assets/javascripts/ckeditor/plugins/widget/lang/el.js +2 -2
  269. data/app/assets/javascripts/ckeditor/plugins/widget/lang/en-au.js +8 -0
  270. data/app/assets/javascripts/ckeditor/plugins/widget/lang/en-gb.js +2 -2
  271. data/app/assets/javascripts/ckeditor/plugins/widget/lang/en.js +2 -2
  272. data/app/assets/javascripts/ckeditor/plugins/widget/lang/eo.js +2 -2
  273. data/app/assets/javascripts/ckeditor/plugins/widget/lang/es-mx.js +2 -2
  274. data/app/assets/javascripts/ckeditor/plugins/widget/lang/es.js +2 -2
  275. data/app/assets/javascripts/ckeditor/plugins/widget/lang/et.js +8 -0
  276. data/app/assets/javascripts/ckeditor/plugins/widget/lang/eu.js +2 -2
  277. data/app/assets/javascripts/ckeditor/plugins/widget/lang/fa.js +3 -3
  278. data/app/assets/javascripts/ckeditor/plugins/widget/lang/fi.js +2 -2
  279. data/app/assets/javascripts/ckeditor/plugins/widget/lang/fr.js +2 -2
  280. data/app/assets/javascripts/ckeditor/plugins/widget/lang/gl.js +2 -2
  281. data/app/assets/javascripts/ckeditor/plugins/widget/lang/he.js +2 -2
  282. data/app/assets/javascripts/ckeditor/plugins/widget/lang/hr.js +2 -2
  283. data/app/assets/javascripts/ckeditor/plugins/widget/lang/hu.js +2 -2
  284. data/app/assets/javascripts/ckeditor/plugins/widget/lang/id.js +2 -2
  285. data/app/assets/javascripts/ckeditor/plugins/widget/lang/it.js +2 -2
  286. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ja.js +2 -2
  287. data/app/assets/javascripts/ckeditor/plugins/widget/lang/km.js +2 -2
  288. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ko.js +2 -2
  289. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ku.js +2 -2
  290. data/app/assets/javascripts/ckeditor/plugins/widget/lang/lv.js +3 -3
  291. data/app/assets/javascripts/ckeditor/plugins/widget/lang/nb.js +2 -2
  292. data/app/assets/javascripts/ckeditor/plugins/widget/lang/nl.js +2 -2
  293. data/app/assets/javascripts/ckeditor/plugins/widget/lang/no.js +2 -2
  294. data/app/assets/javascripts/ckeditor/plugins/widget/lang/oc.js +2 -2
  295. data/app/assets/javascripts/ckeditor/plugins/widget/lang/pl.js +2 -2
  296. data/app/assets/javascripts/ckeditor/plugins/widget/lang/pt-br.js +2 -2
  297. data/app/assets/javascripts/ckeditor/plugins/widget/lang/pt.js +2 -2
  298. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ro.js +8 -0
  299. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ru.js +2 -2
  300. data/app/assets/javascripts/ckeditor/plugins/widget/lang/sk.js +2 -2
  301. data/app/assets/javascripts/ckeditor/plugins/widget/lang/sl.js +2 -2
  302. data/app/assets/javascripts/ckeditor/plugins/widget/lang/sq.js +3 -3
  303. data/app/assets/javascripts/ckeditor/plugins/widget/lang/sv.js +2 -2
  304. data/app/assets/javascripts/ckeditor/plugins/widget/lang/tr.js +2 -2
  305. data/app/assets/javascripts/ckeditor/plugins/widget/lang/tt.js +2 -2
  306. data/app/assets/javascripts/ckeditor/plugins/widget/lang/ug.js +2 -2
  307. data/app/assets/javascripts/ckeditor/plugins/widget/lang/uk.js +2 -2
  308. data/app/assets/javascripts/ckeditor/plugins/widget/lang/vi.js +2 -2
  309. data/app/assets/javascripts/ckeditor/plugins/widget/lang/zh-cn.js +2 -2
  310. data/app/assets/javascripts/ckeditor/plugins/widget/lang/zh.js +2 -2
  311. data/app/assets/javascripts/ckeditor/plugins/widget/plugin.js +235 -64
  312. data/app/assets/javascripts/ckeditor/plugins/widgetselection/plugin.js +6 -11
  313. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ar.js +1 -0
  314. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/bg.js +17 -0
  315. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ca.js +1 -0
  316. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/cs.js +15 -0
  317. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/da.js +1 -0
  318. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/de.js +1 -0
  319. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/el.js +1 -0
  320. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/en.js +5 -1
  321. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/es.js +1 -0
  322. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/eu.js +17 -0
  323. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/fa.js +13 -0
  324. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/fi.js +1 -0
  325. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/fr.js +1 -0
  326. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/he.js +1 -0
  327. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/hr.js +1 -0
  328. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/hu.js +14 -0
  329. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/it.js +4 -3
  330. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ja.js +5 -5
  331. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ko.js +16 -0
  332. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/nl.js +3 -2
  333. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/no.js +1 -0
  334. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/pl.js +4 -3
  335. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/pt-br.js +1 -0
  336. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/pt.js +1 -0
  337. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ro.js +15 -0
  338. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/ru.js +2 -1
  339. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/sk.js +15 -0
  340. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/sv.js +5 -3
  341. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/tr.js +1 -0
  342. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/uk.js +17 -0
  343. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/zh-cn.js +1 -0
  344. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/zh.js +14 -0
  345. data/app/assets/javascripts/ckeditor/plugins/wordcount/plugin.js +485 -302
  346. data/app/assets/javascripts/ckeditor/plugins/wordcount/samples/maxParagraphs.html +26 -0
  347. data/app/assets/javascripts/integral/backend.js +197 -26
  348. data/app/assets/javascripts/integral/frontend.js +37 -2
  349. data/app/assets/javascripts/integral/support/character_counter.js +14 -8
  350. data/app/assets/javascripts/integral/support/confirm_modal.coffee +2 -2
  351. data/app/assets/javascripts/integral/support/date_picker.coffee +54 -59
  352. data/app/assets/javascripts/integral/support/gallery.coffee +85 -43
  353. data/app/assets/javascripts/integral/support/grid.coffee +11 -4
  354. data/app/assets/javascripts/integral/support/lib/lazysizes.js +755 -0
  355. data/app/assets/javascripts/integral/support/lib/materialize-tags.js +49 -44
  356. data/app/assets/javascripts/integral/support/list.coffee +1 -0
  357. data/app/assets/javascripts/integral/support/ls.instagram.js +57 -0
  358. data/app/assets/javascripts/integral/support/ls.twitter.js +66 -0
  359. data/app/assets/javascripts/integral/support/record_selector.coffee +3 -1
  360. data/app/assets/javascripts/integral/support/remote_form.coffee +18 -11
  361. data/app/assets/javascripts/integral/support/slug_generator.coffee +1 -0
  362. data/app/assets/stylesheets/integral/backend.sass +36 -24
  363. data/app/assets/stylesheets/integral/backend/_foundation_settings.scss +5 -6
  364. data/app/assets/stylesheets/integral/backend/dashboard-layout.scss +31 -64
  365. data/app/assets/stylesheets/integral/backend/devise.sass +2 -3
  366. data/app/assets/stylesheets/integral/backend/materialize-tags.sass +2 -1
  367. data/app/assets/stylesheets/integral/backend/modules/dropdown_pane_notifications.scss +150 -0
  368. data/app/assets/stylesheets/integral/backend/modules/dropdown_pane_profile.scss +59 -0
  369. data/app/assets/stylesheets/integral/backend/modules/timeline.scss +214 -0
  370. data/app/assets/stylesheets/integral/backend/shared.sass +121 -13
  371. data/app/assets/stylesheets/integral/frontend.scss +45 -0
  372. data/app/assets/stylesheets/integral/frontend/_foundation_settings.scss +2 -2
  373. data/app/assets/stylesheets/integral/frontend/blog.sass +155 -142
  374. data/app/assets/stylesheets/integral/frontend/layout.sass +13 -3
  375. data/app/assets/stylesheets/integral/frontend/modules/article-footer.scss +55 -0
  376. data/app/assets/stylesheets/integral/frontend/modules/article.scss +34 -0
  377. data/app/assets/stylesheets/integral/frontend/modules/horizontal-post.scss +44 -0
  378. data/app/assets/stylesheets/integral/frontend/modules/inline-articles.scss +23 -0
  379. data/app/assets/stylesheets/integral/frontend/modules/latest-post.scss +37 -0
  380. data/app/assets/stylesheets/integral/frontend/modules/list-widget.scss +50 -0
  381. data/app/assets/stylesheets/integral/frontend/modules/piped-list.scss +33 -0
  382. data/app/assets/stylesheets/integral/frontend/modules/post-tags.scss +19 -0
  383. data/app/assets/stylesheets/integral/frontend/modules/scroll-container.scss +9 -0
  384. data/app/assets/stylesheets/integral/frontend/modules/sidebar-articles.scss +42 -0
  385. data/app/assets/stylesheets/integral/frontend/modules/sidebar-tags.scss +6 -0
  386. data/app/assets/stylesheets/integral/frontend/modules/sidebar-widget.scss +47 -0
  387. data/app/assets/stylesheets/integral/frontend/modules/vertical-post.scss +31 -0
  388. data/app/assets/stylesheets/integral/frontend/share_modal.sass +0 -5
  389. data/app/assets/stylesheets/integral/support/gallery.sass +18 -2
  390. data/app/assets/stylesheets/integral/support/media-query-indicator.sass +9 -3
  391. data/app/controllers/integral/application_controller.rb +10 -3
  392. data/app/controllers/integral/backend/activities_controller.rb +31 -26
  393. data/app/controllers/integral/backend/base_controller.rb +265 -26
  394. data/app/controllers/integral/backend/categories_controller.rb +49 -0
  395. data/app/controllers/integral/backend/images_controller.rb +39 -56
  396. data/app/controllers/integral/backend/lists_controller.rb +16 -104
  397. data/app/controllers/integral/backend/notification_subscriptions_controller.rb +23 -0
  398. data/app/controllers/integral/backend/pages_controller.rb +15 -117
  399. data/app/controllers/integral/backend/posts_controller.rb +22 -108
  400. data/app/controllers/integral/backend/settings_controller.rb +7 -8
  401. data/app/controllers/integral/backend/static_pages_controller.rb +14 -0
  402. data/app/controllers/integral/backend/users_controller.rb +61 -79
  403. data/app/controllers/integral/blog_controller.rb +12 -0
  404. data/app/controllers/integral/categories_controller.rb +45 -0
  405. data/app/controllers/integral/pages_controller.rb +7 -3
  406. data/app/controllers/integral/posts_controller.rb +7 -9
  407. data/app/controllers/integral/tags_controller.rb +5 -2
  408. data/app/decorators/integral/base_decorator.rb +16 -0
  409. data/app/decorators/integral/category_decorator.rb +30 -0
  410. data/app/decorators/integral/image_decorator.rb +3 -3
  411. data/app/decorators/integral/list_decorator.rb +1 -13
  412. data/app/decorators/integral/notification/notification_decorator.rb +74 -0
  413. data/app/decorators/integral/page_decorator.rb +1 -13
  414. data/app/decorators/integral/paginating_decorator.rb +6 -0
  415. data/app/decorators/integral/post_decorator.rb +44 -4
  416. data/app/decorators/integral/user_decorator.rb +1 -13
  417. data/app/decorators/integral/version_decorator.rb +58 -15
  418. data/app/helpers/integral/application_helper.rb +7 -0
  419. data/app/helpers/integral/backend/base_helper.rb +139 -13
  420. data/app/helpers/integral/blog_helper.rb +46 -0
  421. data/app/helpers/integral/social_helper.rb +0 -23
  422. data/app/jobs/integral/application_job.rb +1 -0
  423. data/app/jobs/integral/newsletter_signup_job.rb +0 -2
  424. data/app/jobs/integral/webhook/delivery_job.rb +37 -0
  425. data/app/mailers/integral/contact_mailer.rb +4 -1
  426. data/app/mailers/integral/devise_mailer.rb +6 -0
  427. data/app/models/concerns/integral/lazy_contentable.rb +54 -0
  428. data/app/models/concerns/integral/notification/subscribable.rb +67 -0
  429. data/app/models/concerns/integral/webhook/delivery.rb +30 -0
  430. data/app/models/concerns/integral/webhook/observable.rb +23 -0
  431. data/app/models/integral/application_record.rb +9 -0
  432. data/app/models/integral/category.rb +29 -0
  433. data/app/models/integral/category_version.rb +8 -0
  434. data/app/models/integral/image.rb +40 -3
  435. data/app/models/integral/list.rb +11 -4
  436. data/app/models/integral/list_item.rb +15 -16
  437. data/app/models/integral/list_item_connection.rb +6 -0
  438. data/app/models/integral/notification/notification.rb +28 -0
  439. data/app/models/integral/notification/subscription.rb +14 -0
  440. data/app/models/integral/page.rb +32 -10
  441. data/app/models/integral/post.rb +39 -14
  442. data/app/models/integral/user.rb +51 -2
  443. data/app/models/integral/version.rb +2 -2
  444. data/app/models/integral/webhook/endpoint.rb +40 -0
  445. data/app/models/integral/webhook/event.rb +20 -0
  446. data/app/policies/integral/base_policy.rb +7 -11
  447. data/app/policies/integral/category_policy.rb +9 -0
  448. data/app/policies/integral/page_policy.rb +1 -0
  449. data/app/policies/integral/version_policy.rb +0 -8
  450. data/app/serializers/integral/post_serializer.rb +24 -0
  451. data/app/uploaders/integral/avatar_uploader.rb +1 -1
  452. data/app/views/devise/invitations/edit.haml +1 -4
  453. data/app/views/devise/mailer/invitation_instructions.inky-haml +20 -0
  454. data/app/views/devise/sessions/new.haml +2 -2
  455. data/app/views/integral/backend/activities/_activity.haml +21 -0
  456. data/app/views/integral/backend/activities/grid/_dropdown_actions.haml +1 -0
  457. data/app/views/integral/backend/activities/grid/_row_content.haml +13 -0
  458. data/app/views/integral/backend/activities/index.haml +7 -13
  459. data/app/views/integral/backend/activities/shared/_grid.haml +35 -19
  460. data/app/views/integral/backend/activities/shared/index.haml +15 -0
  461. data/app/views/integral/backend/activities/shared/{_log.haml → show.haml} +7 -7
  462. data/app/views/integral/backend/activities/show.haml +1 -1
  463. data/app/views/integral/backend/categories/_modal.haml +24 -0
  464. data/app/views/integral/backend/images/_form.haml +16 -28
  465. data/app/views/integral/backend/images/edit.haml +2 -2
  466. data/app/views/integral/backend/images/grid/_dropdown_actions.haml +5 -0
  467. data/app/views/integral/backend/images/grid/_row_content.haml +5 -0
  468. data/app/views/integral/backend/images/index.haml +11 -17
  469. data/app/views/integral/backend/images/list.haml +11 -0
  470. data/app/views/integral/backend/images/show.haml +26 -0
  471. data/app/views/integral/backend/lists/_form.haml +7 -20
  472. data/app/views/integral/backend/lists/_item_container.haml +1 -1
  473. data/app/views/integral/backend/lists/_item_modal.haml +3 -3
  474. data/app/views/integral/backend/lists/_list_item_fields.haml +3 -2
  475. data/app/views/integral/backend/lists/_manager.haml +11 -13
  476. data/app/views/integral/backend/lists/edit.haml +22 -1
  477. data/app/views/integral/backend/lists/grid/_dropdown_actions.haml +9 -0
  478. data/app/views/integral/backend/lists/grid/_row_content.haml +3 -0
  479. data/app/views/integral/backend/lists/index.haml +11 -17
  480. data/app/views/integral/backend/lists/list.haml +11 -0
  481. data/app/views/integral/backend/lists/show.haml +27 -23
  482. data/app/views/integral/backend/notifications/_notification.haml +21 -0
  483. data/app/views/integral/backend/pages/_form.haml +20 -47
  484. data/app/views/integral/backend/pages/edit.haml +18 -0
  485. data/app/views/integral/backend/pages/grid/_dropdown_actions.haml +11 -0
  486. data/app/views/integral/backend/pages/grid/_row_content.haml +5 -0
  487. data/app/views/integral/backend/pages/index.haml +11 -21
  488. data/app/views/integral/backend/pages/list.haml +15 -0
  489. data/app/views/integral/backend/pages/show.haml +32 -0
  490. data/app/views/integral/backend/posts/_form.haml +19 -51
  491. data/app/views/integral/backend/posts/edit.haml +5 -10
  492. data/app/views/integral/backend/posts/grid/_dropdown_actions.haml +10 -0
  493. data/app/views/integral/backend/posts/grid/_row_content.haml +6 -0
  494. data/app/views/integral/backend/posts/index.haml +13 -19
  495. data/app/views/integral/backend/posts/list.haml +13 -0
  496. data/app/views/integral/backend/posts/new.haml +0 -1
  497. data/app/views/integral/backend/posts/show.haml +31 -0
  498. data/app/views/integral/backend/settings/sections/_social.haml +1 -3
  499. data/app/views/integral/backend/shared/_activity_modal.haml +13 -0
  500. data/app/views/integral/backend/shared/_breadcrumbs.haml +7 -4
  501. data/app/views/integral/backend/shared/_image_preview.haml +10 -3
  502. data/app/views/integral/backend/shared/_image_selector.haml +1 -1
  503. data/app/views/integral/backend/shared/_notification_subscription_toggle.haml +22 -0
  504. data/app/views/integral/backend/shared/action_bar/_index.haml +9 -0
  505. data/app/views/integral/backend/shared/action_bar/_show.haml +3 -0
  506. data/app/views/integral/backend/shared/cards/_at_a_glance.haml +3 -3
  507. data/app/views/integral/backend/shared/cards/_categories.haml +33 -0
  508. data/app/views/integral/backend/{static_pages/_card.haml → shared/cards/_object.haml} +1 -1
  509. data/app/views/integral/backend/shared/cards/_recent_activity.haml +20 -0
  510. data/app/views/integral/backend/shared/cards/_recent_resources.haml +17 -0
  511. data/app/views/integral/backend/shared/cards/_recent_user_activity.haml +1 -0
  512. data/app/views/integral/backend/shared/cards/_top_post_authors.haml +18 -0
  513. data/app/views/integral/backend/shared/cards/_welcome.haml +24 -25
  514. data/app/views/integral/backend/shared/{_empty_grid.haml → grid/_empty.haml} +0 -0
  515. data/app/views/integral/backend/shared/grid/_form.haml +9 -0
  516. data/app/views/integral/backend/shared/grid/_grid.haml +21 -0
  517. data/app/views/integral/backend/shared/{_pagination.haml → grid/_pagination.haml} +0 -0
  518. data/app/views/integral/backend/shared/grid/_row_layout.haml +8 -0
  519. data/app/views/integral/backend/shared/record_selector/_collection.haml +1 -0
  520. data/app/views/integral/backend/shared/record_selector/_modal.haml +9 -10
  521. data/app/views/integral/backend/shared/record_selector/_record.haml +6 -4
  522. data/app/views/integral/backend/static_pages/dashboard.haml +17 -15
  523. data/app/views/integral/backend/users/_form.haml +35 -47
  524. data/app/views/integral/backend/users/edit.haml +1 -1
  525. data/app/views/integral/backend/users/grid/_dropdown_actions.haml +17 -0
  526. data/app/views/integral/backend/users/grid/_row_content.haml +8 -0
  527. data/app/views/integral/backend/users/index.haml +11 -17
  528. data/app/views/integral/backend/users/list.haml +12 -0
  529. data/app/views/integral/backend/users/show.haml +22 -19
  530. data/app/views/integral/categories/show.haml +5 -0
  531. data/app/views/integral/pages/_demo.haml +2 -2
  532. data/app/views/integral/posts/_article_footer.haml +17 -0
  533. data/app/views/integral/posts/_card.haml +11 -0
  534. data/app/views/integral/posts/_latest_post.haml +8 -0
  535. data/app/views/integral/posts/_most_read_section.haml +8 -0
  536. data/app/views/integral/posts/_post.haml +11 -0
  537. data/app/views/integral/posts/_similar_posts.haml +5 -0
  538. data/app/views/integral/posts/index.haml +7 -5
  539. data/app/views/integral/posts/templates/default.haml +35 -35
  540. data/app/views/integral/shared/_share_modal.haml +0 -3
  541. data/app/views/integral/shared/_social_list_items.haml +6 -12
  542. data/app/views/integral/shared/_subscribe_modal.haml +14 -0
  543. data/app/views/integral/shared/blog/_categories.haml +15 -0
  544. data/app/views/integral/shared/blog/_layout.haml +9 -0
  545. data/app/views/integral/shared/blog/_sidebar.haml +10 -0
  546. data/app/views/integral/shared/gallery/_placeholder.haml +2 -2
  547. data/app/views/integral/shared/gallery/_slide.haml +2 -2
  548. data/app/views/integral/shared/gallery/gallery.haml +5 -2
  549. data/app/views/integral/shared/sidebar/_item.haml +8 -0
  550. data/app/views/integral/shared/sidebar/_newsletter_signup.haml +7 -0
  551. data/app/views/integral/shared/sidebar/_popular_posts.haml +7 -0
  552. data/app/views/integral/shared/sidebar/_popular_tags.haml +7 -0
  553. data/app/views/integral/shared/sidebar/_recent_posts.haml +7 -0
  554. data/app/views/integral/tags/index.haml +2 -2
  555. data/app/views/integral/tags/show.haml +3 -6
  556. data/app/views/layouts/integral/backend.html.haml +27 -5
  557. data/app/views/layouts/integral/backend/_create_dropdown.haml +1 -30
  558. data/app/views/layouts/integral/backend/_main_menu_items.haml +1 -91
  559. data/app/views/layouts/integral/frontend.html.haml +3 -3
  560. data/config/initializers/devise.rb +1 -1
  561. data/config/locales/en.yml +131 -56
  562. data/config/routes.rb +2 -0
  563. data/db/migrate/20190414172018_create_webhook_endpoints.rb +10 -0
  564. data/db/migrate/20190929191412_add_integral_post_categories.rb +13 -0
  565. data/db/migrate/20191203090008_add_image_to_integral_categories.rb +6 -0
  566. data/db/migrate/20200401210442_create_category_versions.rb +20 -0
  567. data/db/migrate/20200407022636_create_integral_notifications.rb +25 -0
  568. data/db/migrate/20200421223602_add_status_to_integral_users.rb +5 -0
  569. data/db/seeds.rb +16 -10
  570. data/lib/generators/integral/assets_generator.rb +54 -0
  571. data/lib/generators/integral/install_generator.rb +37 -3
  572. data/lib/generators/integral/views_generator.rb +66 -0
  573. data/lib/generators/templates/app.yml +0 -1
  574. data/lib/generators/templates/integral.rb +5 -0
  575. data/lib/generators/templates/routes.rb +7 -0
  576. data/lib/generators/templates/seeds.rb +2 -0
  577. data/lib/integral.rb +4 -30
  578. data/lib/integral/acts_as_integral.rb +115 -0
  579. data/lib/integral/acts_as_listable.rb +3 -3
  580. data/lib/integral/chart_renderer/base.rb +2 -0
  581. data/lib/integral/content_renderer.rb +3 -3
  582. data/lib/integral/engine.rb +12 -2
  583. data/lib/integral/grids/activities_grid.rb +15 -2
  584. data/lib/integral/grids/lists_grid.rb +1 -0
  585. data/lib/integral/grids/posts_grid.rb +5 -1
  586. data/lib/integral/grids/users_grid.rb +5 -0
  587. data/lib/integral/list_item_renderer.rb +4 -2
  588. data/lib/integral/list_renderer.rb +6 -1
  589. data/lib/integral/middleware/page_router.rb +15 -6
  590. data/lib/integral/router.rb +41 -7
  591. data/lib/integral/version.rb +1 -1
  592. data/lib/integral/widgets/recent_posts.rb +1 -1
  593. data/lib/integral/widgets/swiper_list.rb +3 -2
  594. data/public/images/integral/demo/continous-integration.png +0 -0
  595. data/public/images/integral/demo/foundation-frontend-framework.jpg +0 -0
  596. data/public/images/integral/demo/heroku.png +0 -0
  597. data/public/images/integral/demo/integral-cms-without-hassle.jpg +0 -0
  598. data/public/images/integral/demo/integral-features-activity-tracking.jpg +0 -0
  599. data/public/images/integral/demo/integral-features-contact-form.png +0 -0
  600. data/public/images/integral/demo/integral-features-design.jpg +0 -0
  601. data/public/images/integral/demo/integral-features-dynamic-pages.jpg +0 -0
  602. data/public/images/integral/demo/integral-features-image-management.jpg +0 -0
  603. data/public/images/integral/demo/integral-features-integrated-blog.jpg +0 -0
  604. data/public/images/integral/demo/integral-features-list-management.jpg +0 -0
  605. data/public/images/integral/demo/integral-features-seo-ready.jpg +0 -0
  606. data/public/images/integral/demo/integral-features-user-management.jpg +0 -0
  607. data/public/images/integral/demo/integral-presentation.png +0 -0
  608. data/public/integral/ckeditor_demo_content.html +0 -13
  609. data/spec/factories.rb +30 -8
  610. metadata +322 -127
  611. data/app/assets/javascripts/ckeditor/plugins/wordcount/lang/jp.js +0 -13
  612. data/app/assets/javascripts/integral/support/date_picker/picker.date.js +0 -1435
  613. data/app/assets/javascripts/integral/support/date_picker/picker.js +0 -1132
  614. data/app/assets/stylesheets/integral/frontend.sass +0 -26
  615. data/app/assets/stylesheets/integral/support/date-picker.scss +0 -16
  616. data/app/assets/stylesheets/integral/support/date_picker/_default.date.scss +0 -452
  617. data/app/assets/stylesheets/integral/support/date_picker/_default.scss +0 -201
  618. data/app/assets/stylesheets/integral/support/date_picker/materialize_clockpicker.sass +0 -220
  619. data/app/assets/stylesheets/integral/wysiwyg.sass +0 -13
  620. data/app/views/devise/mailer/invitation_instructions.html.erb +0 -13
  621. data/app/views/integral/backend/activities/_grid.haml +0 -23
  622. data/app/views/integral/backend/activities/shared/_listing.haml +0 -14
  623. data/app/views/integral/backend/images/_grid.haml +0 -16
  624. data/app/views/integral/backend/lists/_grid.haml +0 -16
  625. data/app/views/integral/backend/pages/_grid.haml +0 -21
  626. data/app/views/integral/backend/pages/activities.haml +0 -2
  627. data/app/views/integral/backend/pages/activity.haml +0 -1
  628. data/app/views/integral/backend/pages/edit.html.haml +0 -15
  629. data/app/views/integral/backend/posts/_grid.haml +0 -25
  630. data/app/views/integral/backend/posts/activities.haml +0 -3
  631. data/app/views/integral/backend/posts/activity.haml +0 -1
  632. data/app/views/integral/backend/shared/_grid.haml +0 -18
  633. data/app/views/integral/backend/users/_grid.haml +0 -19
  634. data/app/views/integral/posts/_item.haml +0 -16
  635. data/app/views/integral/shared/_blog_layout.haml +0 -15
  636. data/app/views/integral/shared/_blog_sidebar.haml +0 -49
  637. data/lib/integral/slack_bot.rb +0 -45
@@ -1,6 +1,6 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'nb', {
6
6
  closed: 'Varsling lukket.'
@@ -1,6 +1,6 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'nl', {
6
6
  closed: 'Melding gesloten.'
@@ -0,0 +1,7 @@
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( 'notification', 'oc', {
6
+ closed: 'Notificacion tampada.'
7
+ } );
@@ -1,6 +1,6 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'pl', {
6
6
  closed: 'Powiadomienie zostało zamknięte.'
@@ -1,6 +1,6 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'pt-br', {
6
6
  closed: 'Notificação fechada.'
@@ -1,6 +1,6 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'pt', {
6
6
  closed: 'Notificação encerrada.'
@@ -0,0 +1,7 @@
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( 'notification', 'ro', {
6
+ closed: 'Notificare închisă.'
7
+ } );
@@ -1,6 +1,6 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'ru', {
6
6
  closed: 'Уведомление закрыто'
@@ -0,0 +1,7 @@
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( 'notification', 'sk', {
6
+ closed: 'Notifikácia zatvorená.'
7
+ } );
@@ -0,0 +1,7 @@
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( 'notification', 'sq', {
6
+ closed: 'Njoftimi është mbyllur.'
7
+ } );
@@ -1,6 +1,6 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'sv', {
6
6
  closed: 'Notifiering stängd.'
@@ -1,6 +1,6 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'tr', {
6
6
  closed: 'Uyarılar kapatıldı.'
@@ -1,6 +1,6 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'ug', {
6
6
  closed: 'ئوقتۇرۇش تاقالدى.'
@@ -1,6 +1,6 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'uk', {
6
6
  closed: 'Сповіщення закрито.'
@@ -1,7 +1,7 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'zh-cn', {
6
- closed: '通知已关闭。'
6
+ closed: '通知已关闭'
7
7
  } );
@@ -1,6 +1,6 @@
1
1
  /*
2
- Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
  CKEDITOR.plugins.setLang( 'notification', 'zh', {
6
6
  closed: '通知已關閉。'
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3
- * For licensing, see LICENSE.md or http://ckeditor.com/license
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
4
  */
5
5
 
6
6
  /**
@@ -10,914 +10,924 @@
10
10
 
11
11
  'use strict';
12
12
 
13
- CKEDITOR.plugins.add( 'notification', {
14
- lang: 'cs,da,de,de-ch,en,eo,eu,fr,gl,id,it,km,ko,ku,nb,nl,pl,pt,pt-br,ru,sv,tr,ug,uk,zh,zh-cn', // %REMOVE_LINE_CORE%
15
- requires: 'toolbar',
13
+ ( function() {
16
14
 
17
- init: function( editor ) {
18
- editor._.notificationArea = new Area( editor );
15
+ CKEDITOR.plugins.add( 'notification', {
16
+ lang: 'az,bg,ca,cs,da,de,de-ch,en,en-au,eo,es,es-mx,et,eu,fa,fr,gl,hr,hu,id,it,ja,km,ko,ku,lv,nb,nl,oc,pl,pt,pt-br,ro,ru,sk,sq,sv,tr,ug,uk,zh,zh-cn', // %REMOVE_LINE_CORE%
19
17
 
20
- // Overwrites default `editor.showNotification`.
21
- editor.showNotification = function( message, type, progressOrDuration ) {
22
- var progress, duration;
18
+ init: function( editor ) {
19
+ editor._.notificationArea = new Area( editor );
23
20
 
24
- if ( type == 'progress' ) {
25
- progress = progressOrDuration;
26
- } else {
27
- duration = progressOrDuration;
28
- }
21
+ // Overwrites default `editor.showNotification`.
22
+ editor.showNotification = function( message, type, progressOrDuration ) {
23
+ var progress, duration;
29
24
 
30
- var notification = new CKEDITOR.plugins.notification( editor, {
31
- message: message,
32
- type: type,
33
- progress: progress,
34
- duration: duration
35
- } );
25
+ if ( type == 'progress' ) {
26
+ progress = progressOrDuration;
27
+ } else {
28
+ duration = progressOrDuration;
29
+ }
36
30
 
37
- notification.show();
31
+ var notification = new CKEDITOR.plugins.notification( editor, {
32
+ message: message,
33
+ type: type,
34
+ progress: progress,
35
+ duration: duration
36
+ } );
38
37
 
39
- return notification;
40
- };
38
+ notification.show();
41
39
 
42
- // Close the last notification on ESC.
43
- editor.on( 'key', function( evt ) {
44
- if ( evt.data.keyCode == 27 ) { /* ESC */
45
- var notifications = editor._.notificationArea.notifications;
40
+ return notification;
41
+ };
46
42
 
47
- if ( !notifications.length ) {
48
- return;
49
- }
43
+ // Close the last notification on ESC.
44
+ editor.on( 'key', function( evt ) {
45
+ if ( evt.data.keyCode == 27 ) { /* ESC */
46
+ var notifications = editor._.notificationArea.notifications;
50
47
 
51
- // As long as this is not a common practice to inform screen-reader users about actions, in this case
52
- // this is the best solution (unfortunately there is no standard for accessibility for notifications).
53
- // Notification has an `alert` aria role what means that it does not get a focus nor is needed to be
54
- // closed (unlike `alertdialog`). However notification will capture ESC key so we need to inform user
55
- // why it does not do other actions.
56
- say( editor.lang.notification.closed );
48
+ if ( !notifications.length ) {
49
+ return;
50
+ }
57
51
 
58
- // Hide last.
59
- notifications[ notifications.length - 1 ].hide();
52
+ // As long as this is not a common practice to inform screen-reader users about actions, in this case
53
+ // this is the best solution (unfortunately there is no standard for accessibility for notifications).
54
+ // Notification has an `alert` aria role what means that it does not get a focus nor is needed to be
55
+ // closed (unlike `alertdialog`). However notification will capture ESC key so we need to inform user
56
+ // why it does not do other actions.
57
+ say( editor.lang.notification.closed );
60
58
 
61
- evt.cancel();
62
- }
63
- } );
59
+ // Hide last.
60
+ notifications[ notifications.length - 1 ].hide();
64
61
 
65
- // Send the message to the screen readers.
66
- function say( text ) {
67
- var message = new CKEDITOR.dom.element( 'div' );
68
- message.setStyles( {
69
- position: 'fixed',
70
- 'margin-left': '-9999px'
71
- } );
72
- message.setAttributes( {
73
- 'aria-live': 'assertive',
74
- 'aria-atomic': 'true'
62
+ evt.cancel();
63
+ }
75
64
  } );
76
- message.setText( text );
77
65
 
78
- CKEDITOR.document.getBody().append( message );
79
-
80
- setTimeout( function() {
81
- message.remove();
82
- }, 100 );
66
+ // Send the message to the screen readers.
67
+ function say( text ) {
68
+ var message = new CKEDITOR.dom.element( 'div' );
69
+ message.setStyles( {
70
+ position: 'fixed',
71
+ 'margin-left': '-9999px'
72
+ } );
73
+ message.setAttributes( {
74
+ 'aria-live': 'assertive',
75
+ 'aria-atomic': 'true'
76
+ } );
77
+ message.setText( text );
78
+
79
+ CKEDITOR.document.getBody().append( message );
80
+
81
+ setTimeout( function() {
82
+ message.remove();
83
+ }, 100 );
84
+ }
83
85
  }
84
- }
85
- } );
86
-
87
- /**
88
- * Notification class. Notifications are used to display short messages to the user. They might be used to show the result of
89
- * asynchronous actions or information about changes in the editor content. It is recommended to use them instead of
90
- * alert dialogs. They should **not** be used if a user response is required nor with dialog windows (e.g. in dialog validation).
91
- *
92
- * There are four types of notifications available, see the {@link #type} property.
93
- *
94
- * Note that the notification constructor only creates a notification instance. To show it, use the {@link #show} method:
95
- *
96
- * var notification = new CKEDITOR.plugins.notification( editor, { message: 'Foo' } );
97
- * notification.show();
98
- *
99
- * You can also use the {@link CKEDITOR.editor#showNotification} method:
100
- *
101
- * editor.showNotification( 'Foo' );
102
- *
103
- * All of the notification actions: ({@link #show}, {@link #update} and {@link #hide}) fire cancelable events
104
- * on the related {@link CKEDITOR.editor} instance so you can integrate editor notifications with your website notifications.
105
- *
106
- * Refer to the [Notifications](http://docs.ckeditor.com/#!/guide/dev_notifications) article for more information about this feature.
107
- *
108
- * @since 4.5
109
- * @class CKEDITOR.plugins.notification
110
- * @constructor Create a notification object. Call {@link #show} to show the created notification.
111
- * @param {CKEDITOR.editor} editor The editor instance.
112
- * @param {Object} options
113
- * @param {String} options.message The message displayed in the notification.
114
- * @param {String} [options.type='info'] Notification type, see {@link #type}.
115
- * @param {Number} [options.progress=0] If the type is `progress` this may be a progress from 0 to 1.
116
- * @param {Number} [options.duration] How long the notification will be visible, see {@link #duration}.
117
- */
118
- function Notification( editor, options ) {
119
- CKEDITOR.tools.extend( this, options, {
120
- editor: editor,
121
- id: 'cke-' + CKEDITOR.tools.getUniqueId(),
122
- area: editor._.notificationArea
123
86
  } );
124
87
 
125
- if ( !options.type ) {
126
- this.type = 'info';
127
- }
128
-
129
- this.element = this._createElement();
130
-
131
- // Don't allow dragging on notification (#13184).
132
- editor.plugins.clipboard && CKEDITOR.plugins.clipboard.preventDefaultDropOnElement( this.element );
133
- }
134
-
135
- /**
136
- * The editor instance.
137
- *
138
- * @readonly
139
- * @property {CKEDITOR.editor} editor
140
- */
141
-
142
- /**
143
- * Message displayed in the notification.
144
- *
145
- * @readonly
146
- * @property {String} message
147
- */
148
-
149
- /**
150
- * Notification type. There are four types available:
151
- *
152
- * * `info` (default) – Information for the user (e.g. "File is uploading.", "ACF modified content."),
153
- * * `warning` – Warning or error message (e.g. "This type of file is not supported.",
154
- * "You cannot paste the script."),
155
- * * `success` – Information that an operation finished successfully (e.g. "File uploaded.", "Data imported.").
156
- * * `progress` – Information about the progress of an operation. When the operation is done, the notification
157
- * type should be changed to `success`.
158
- *
159
- * @readonly
160
- * @property {String} type
161
- */
162
-
163
- /**
164
- * If the notification {@link #type} is `'progress'`, this is the progress from `0` to `1`.
165
- *
166
- * @readonly
167
- * @property {Number} progress
168
- */
169
-
170
- /**
171
- * Notification duration. Determines after how many milliseconds the notification should close automatically.
172
- * `0` means that the notification will not close automatically and that the user needs to close it manually.
173
- * The default value for `warning` and `progress` notifications is `0`. For `info` and `success` the value can
174
- * either be set through the {@link CKEDITOR.config#notification_duration} configuration option or equals `5000`
175
- * if the configuration option is not set.
176
- *
177
- * @readonly
178
- * @property {Number} duration
179
- */
180
-
181
- /**
182
- * Unique notification ID.
183
- *
184
- * @readonly
185
- * @property {Number} id
186
- */
187
-
188
- /**
189
- * Notification DOM element. There is one element per notification. It is created when the notification is created,
190
- * even if it is not shown. If the notification is hidden, the element is detached from the document but not deleted.
191
- * It will be reused if the notification is shown again.
192
- *
193
- * @readonly
194
- * @property {CKEDITOR.dom.element} element
195
- */
196
-
197
- /**
198
- * {@link CKEDITOR.plugins.notification.area Notification area} reference.
199
- *
200
- * @readonly
201
- * @property {CKEDITOR.plugins.notification.area} area
202
- */
203
-
204
- Notification.prototype = {
205
88
  /**
206
- * Adds the notification element to the notification area. The notification will be hidden automatically if
207
- * {@link #duration} is set.
89
+ * Notification class. Notifications are used to display short messages to the user. They might be used to show the result of
90
+ * asynchronous actions or information about changes in the editor content. It is recommended to use them instead of
91
+ * alert dialogs. They should **not** be used if a user response is required nor with dialog windows (e.g. in dialog validation).
208
92
  *
209
- * Fires the {@link CKEDITOR.editor#notificationShow} event.
210
- */
211
- show: function() {
212
- if ( this.editor.fire( 'notificationShow', { notification: this } ) === false ) {
213
- return;
214
- }
215
-
216
- this.area.add( this );
217
-
218
- this._hideAfterTimeout();
219
- },
220
-
221
- /**
222
- * Updates the notification object and element.
93
+ * There are four types of notifications available, see the {@link #type} property.
94
+ *
95
+ * Note that the notification constructor only creates a notification instance. To show it, use the {@link #show} method:
223
96
  *
224
- * Fires the {@link CKEDITOR.editor#notificationUpdate} event.
97
+ * var notification = new CKEDITOR.plugins.notification( editor, { message: 'Foo' } );
98
+ * notification.show();
225
99
  *
100
+ * You can also use the {@link CKEDITOR.editor#showNotification} method:
101
+ *
102
+ * editor.showNotification( 'Foo' );
103
+ *
104
+ * All of the notification actions: ({@link #show}, {@link #update} and {@link #hide}) fire cancelable events
105
+ * on the related {@link CKEDITOR.editor} instance so you can integrate editor notifications with your website notifications.
106
+ *
107
+ * Refer to the [Notifications](https://ckeditor.com/docs/ckeditor4/latest/guide/dev_notifications.html) article for more information about this feature.
108
+ *
109
+ * @since 4.5
110
+ * @class CKEDITOR.plugins.notification
111
+ * @constructor Create a notification object. Call {@link #show} to show the created notification.
112
+ * @param {CKEDITOR.editor} editor The editor instance.
226
113
  * @param {Object} options
227
- * @param {String} [options.message] {@link #message}
228
- * @param {String} [options.type] {@link #type}
229
- * @param {Number} [options.progress] {@link #progress}
230
- * @param {Number} [options.duration] {@link #duration}
231
- * @param {Boolean} [options.important=false] If the update is important, the notification will be shown
232
- * if it was hidden and read by screen readers.
114
+ * @param {String} options.message The message displayed in the notification.
115
+ * @param {String} [options.type='info'] Notification type, see {@link #type}.
116
+ * @param {Number} [options.progress=0] If the type is `progress` this may be a progress from 0 to 1.
117
+ * @param {Number} [options.duration] How long the notification will be visible, see {@link #duration}.
233
118
  */
234
- update: function( options ) {
235
- var show = true;
236
-
237
- if ( this.editor.fire( 'notificationUpdate', { notification: this, options: options } ) === false ) {
238
- // The idea of cancelable event is to let user create his own way of displaying notification, so if
239
- // `notificationUpdate` event will be canceled there will be no interaction with notification area, but on
240
- // the other hand the logic should work anyway so object will be updated (including `element` property).
241
- // Note: we can safely update the element's attributes below, because this element is created inside
242
- // the constructor. If the notificatinShow event was canceled as well, the element is detached from DOM.
243
- show = false;
244
- }
245
-
246
- var element = this.element,
247
- messageElement = element.findOne( '.cke_notification_message' ),
248
- progressElement = element.findOne( '.cke_notification_progress' ),
249
- type = options.type;
250
-
251
- element.removeAttribute( 'role' );
252
-
253
- // Change type to progress if `options.progress` is set.
254
- if ( options.progress && this.type != 'progress' ) {
255
- type = 'progress';
256
- }
257
-
258
- if ( type ) {
259
- element.removeClass( this._getClass() );
260
- element.removeAttribute( 'aria-label' );
261
-
262
- this.type = type;
263
-
264
- element.addClass( this._getClass() );
265
- element.setAttribute( 'aria-label', this.type );
266
-
267
- if ( this.type == 'progress' && !progressElement ) {
268
- progressElement = this._createProgressElement();
269
- progressElement.insertBefore( messageElement );
270
- } else if ( this.type != 'progress' && progressElement ) {
271
- progressElement.remove();
272
- }
273
- }
274
-
275
- if ( options.message !== undefined ) {
276
- this.message = options.message;
277
- messageElement.setHtml( this.message );
278
- }
279
-
280
- if ( options.progress !== undefined ) {
281
- this.progress = options.progress;
282
-
283
- if ( progressElement ) {
284
- progressElement.setStyle( 'width', this._getPercentageProgress() );
285
- }
286
- }
287
-
288
- if ( show && options.important ) {
289
- element.setAttribute( 'role', 'alert' );
119
+ function Notification( editor, options ) {
120
+ CKEDITOR.tools.extend( this, options, {
121
+ editor: editor,
122
+ id: 'cke-' + CKEDITOR.tools.getUniqueId(),
123
+ area: editor._.notificationArea
124
+ } );
290
125
 
291
- if ( !this.isVisible() ) {
292
- this.area.add( this );
293
- }
126
+ if ( !options.type ) {
127
+ this.type = 'info';
294
128
  }
295
129
 
296
- // Overwrite even if it is undefined.
297
- this.duration = options.duration;
130
+ this.element = this._createElement();
298
131
 
299
- this._hideAfterTimeout();
300
- },
132
+ // Don't allow dragging on notification (https://dev.ckeditor.com/ticket/13184).
133
+ editor.plugins.clipboard && CKEDITOR.plugins.clipboard.preventDefaultDropOnElement( this.element );
134
+ }
301
135
 
302
136
  /**
303
- * Removes the notification element from the notification area.
137
+ * The editor instance.
304
138
  *
305
- * Fires the {@link CKEDITOR.editor#notificationHide} event.
139
+ * @readonly
140
+ * @property {CKEDITOR.editor} editor
306
141
  */
307
- hide: function() {
308
- if ( this.editor.fire( 'notificationHide', { notification: this } ) === false ) {
309
- return;
310
- }
311
-
312
- this.area.remove( this );
313
- },
314
142
 
315
143
  /**
316
- * Returns `true` if the notification is in the notification area.
144
+ * Message displayed in the notification.
317
145
  *
318
- * @returns {Boolean} `true` if the notification is in the notification area.
146
+ * @readonly
147
+ * @property {String} message
319
148
  */
320
- isVisible: function() {
321
- return CKEDITOR.tools.indexOf( this.area.notifications, this ) >= 0;
322
- },
323
149
 
324
150
  /**
325
- * Creates the notification DOM element.
151
+ * Notification type. There are four types available:
326
152
  *
327
- * @private
328
- * @returns {CKEDITOR.dom.element} Notification DOM element.
153
+ * * `info` (default) – Information for the user (e.g. "File is uploading.", "ACF modified content."),
154
+ * * `warning` – Warning or error message (e.g. "This type of file is not supported.",
155
+ * "You cannot paste the script."),
156
+ * * `success` – Information that an operation finished successfully (e.g. "File uploaded.", "Data imported.").
157
+ * * `progress` – Information about the progress of an operation. When the operation is done, the notification
158
+ * type should be changed to `success`.
159
+ *
160
+ * @readonly
161
+ * @property {String} type
329
162
  */
330
- _createElement: function() {
331
- var notification = this,
332
- notificationElement, notificationMessageElement, notificationCloseElement,
333
- close = this.editor.lang.common.close;
334
-
335
- notificationElement = new CKEDITOR.dom.element( 'div' );
336
- notificationElement.addClass( 'cke_notification' );
337
- notificationElement.addClass( this._getClass() );
338
- notificationElement.setAttributes( {
339
- id: this.id,
340
- role: 'alert',
341
- 'aria-label': this.type
342
- } );
343
-
344
- if ( this.type == 'progress' )
345
- notificationElement.append( this._createProgressElement() );
346
-
347
- notificationMessageElement = new CKEDITOR.dom.element( 'p' );
348
- notificationMessageElement.addClass( 'cke_notification_message' );
349
- notificationMessageElement.setHtml( this.message );
350
- notificationElement.append( notificationMessageElement );
351
-
352
- notificationCloseElement = CKEDITOR.dom.element.createFromHtml(
353
- '<a class="cke_notification_close" href="javascript:void(0)" title="' + close + '" role="button" tabindex="-1">' +
354
- '<span class="cke_label">X</span>' +
355
- '</a>' );
356
- notificationElement.append( notificationCloseElement );
357
163
 
358
- notificationCloseElement.on( 'click', function() {
359
- // Focus editor on close (#12865)
360
- notification.editor.focus();
361
-
362
- notification.hide();
363
- } );
364
-
365
- return notificationElement;
366
- },
164
+ /**
165
+ * If the notification {@link #type} is `'progress'`, this is the progress from `0` to `1`.
166
+ *
167
+ * @readonly
168
+ * @property {Number} progress
169
+ */
367
170
 
368
171
  /**
369
- * Gets the notification CSS class.
172
+ * Notification duration. Determines after how many milliseconds the notification should close automatically.
173
+ * `0` means that the notification will not close automatically and that the user needs to close it manually.
174
+ * The default value for `warning` and `progress` notifications is `0`. For `info` and `success` the value can
175
+ * either be set through the {@link CKEDITOR.config#notification_duration} configuration option or equals `5000`
176
+ * if the configuration option is not set.
370
177
  *
371
- * @private
372
- * @returns {String} Notification CSS class.
178
+ * @readonly
179
+ * @property {Number} duration
373
180
  */
374
- _getClass: function() {
375
- return ( this.type == 'progress' ) ?
376
- 'cke_notification_info' :
377
- ( 'cke_notification_' + this.type );
378
- },
379
181
 
380
182
  /**
381
- * Creates a progress element for the notification element.
183
+ * Unique notification ID.
382
184
  *
383
- * @private
384
- * @returns {CKEDITOR.dom.element} Progress element for the notification element.
185
+ * @readonly
186
+ * @property {Number} id
385
187
  */
386
- _createProgressElement: function() {
387
- var element = new CKEDITOR.dom.element( 'span' );
388
- element.addClass( 'cke_notification_progress' );
389
- element.setStyle( 'width', this._getPercentageProgress() );
390
- return element;
391
- },
392
188
 
393
189
  /**
394
- * Gets the progress as a percentage (ex. `0.3` -> `30%`).
190
+ * Notification DOM element. There is one element per notification. It is created when the notification is created,
191
+ * even if it is not shown. If the notification is hidden, the element is detached from the document but not deleted.
192
+ * It will be reused if the notification is shown again.
395
193
  *
396
- * @private
397
- * @returns {String} Progress as a percentage.
194
+ * @readonly
195
+ * @property {CKEDITOR.dom.element} element
398
196
  */
399
- _getPercentageProgress: function() {
400
- return Math.round( ( this.progress || 0 ) * 100 ) + '%';
401
- },
402
197
 
403
198
  /**
404
- * Hides the notification after a timeout.
199
+ * {@link CKEDITOR.plugins.notification.area Notification area} reference.
405
200
  *
406
- * @private
201
+ * @readonly
202
+ * @property {CKEDITOR.plugins.notification.area} area
407
203
  */
408
- _hideAfterTimeout: function() {
409
- var notification = this,
410
- duration;
411
204
 
412
- if ( this._hideTimeoutId ) {
413
- clearTimeout( this._hideTimeoutId );
414
- }
205
+ Notification.prototype = {
206
+ /**
207
+ * Adds the notification element to the notification area. The notification will be hidden automatically if
208
+ * {@link #duration} is set.
209
+ *
210
+ * Fires the {@link CKEDITOR.editor#notificationShow} event.
211
+ */
212
+ show: function() {
213
+ if ( this.editor.fire( 'notificationShow', { notification: this } ) === false ) {
214
+ return;
215
+ }
415
216
 
416
- if ( typeof this.duration == 'number' ) {
417
- duration = this.duration;
418
- } else if ( this.type == 'info' || this.type == 'success' ) {
419
- duration = ( typeof this.editor.config.notification_duration == 'number' ) ?
420
- this.editor.config.notification_duration :
421
- 5000;
422
- }
217
+ this.area.add( this );
218
+
219
+ this._hideAfterTimeout();
220
+ },
221
+
222
+ /**
223
+ * Updates the notification object and element.
224
+ *
225
+ * Fires the {@link CKEDITOR.editor#notificationUpdate} event.
226
+ *
227
+ * @param {Object} options
228
+ * @param {String} [options.message] {@link #message}
229
+ * @param {String} [options.type] {@link #type}
230
+ * @param {Number} [options.progress] {@link #progress}
231
+ * @param {Number} [options.duration] {@link #duration}
232
+ * @param {Boolean} [options.important=false] If the update is important, the notification will be shown
233
+ * if it was hidden and read by screen readers.
234
+ */
235
+ update: function( options ) {
236
+ var show = true;
237
+
238
+ if ( this.editor.fire( 'notificationUpdate', { notification: this, options: options } ) === false ) {
239
+ // The idea of cancelable event is to let user create his own way of displaying notification, so if
240
+ // `notificationUpdate` event will be canceled there will be no interaction with notification area, but on
241
+ // the other hand the logic should work anyway so object will be updated (including `element` property).
242
+ // Note: we can safely update the element's attributes below, because this element is created inside
243
+ // the constructor. If the notificatinShow event was canceled as well, the element is detached from DOM.
244
+ show = false;
245
+ }
423
246
 
424
- if ( duration ) {
425
- notification._hideTimeoutId = setTimeout( function() {
426
- notification.hide();
427
- }, duration );
428
- }
429
- }
430
- };
247
+ var element = this.element,
248
+ messageElement = element.findOne( '.cke_notification_message' ),
249
+ progressElement = element.findOne( '.cke_notification_progress' ),
250
+ type = options.type;
431
251
 
432
- /**
433
- * Notification area is an area where all notifications are put. The area is laid out dynamically.
434
- * When the first notification is added, the area is shown and all listeners are added.
435
- * When the last notification is removed, the area is hidden and all listeners are removed.
436
- *
437
- * @since 4.5
438
- * @private
439
- * @class CKEDITOR.plugins.notification.area
440
- * @constructor
441
- * @param {CKEDITOR.editor} editor The editor instance.
442
- */
443
- function Area( editor ) {
444
- var that = this;
445
-
446
- this.editor = editor;
447
- this.notifications = [];
448
- this.element = this._createElement();
449
- this._uiBuffer = CKEDITOR.tools.eventsBuffer( 10, this._layout, this );
450
- this._changeBuffer = CKEDITOR.tools.eventsBuffer( 500, this._layout, this );
451
-
452
- editor.on( 'destroy', function() {
453
- that._removeListeners();
454
- that.element.remove();
455
- } );
456
- }
252
+ element.removeAttribute( 'role' );
457
253
 
458
- /**
459
- * The editor instance.
460
- *
461
- * @readonly
462
- * @property {CKEDITOR.editor} editor
463
- */
254
+ // Change type to progress if `options.progress` is set.
255
+ if ( options.progress && this.type != 'progress' ) {
256
+ type = 'progress';
257
+ }
464
258
 
465
- /**
466
- * The array of added notifications.
467
- *
468
- * @readonly
469
- * @property {Array} notifications
470
- */
259
+ if ( type ) {
260
+ element.removeClass( this._getClass() );
261
+ element.removeAttribute( 'aria-label' );
471
262
 
472
- /**
473
- * Notification area DOM element. This element is created when the area object is created. It will be attached to the document
474
- * when the first notification is added and removed when the last notification is removed.
475
- *
476
- * @readonly
477
- * @property {CKEDITOR.dom.element} element
478
- */
263
+ this.type = type;
479
264
 
480
- /**
481
- * Notification width. Cached for performance reasons.
482
- *
483
- * @private
484
- * @property {CKEDITOR.dom.element} _notificationWidth
485
- */
265
+ element.addClass( this._getClass() );
266
+ element.setAttribute( 'aria-label', this.type );
486
267
 
487
- /**
488
- * Notification margin. Cached for performance reasons.
489
- *
490
- * @private
491
- * @property {CKEDITOR.dom.element} _notificationMargin
492
- */
268
+ if ( this.type == 'progress' && !progressElement ) {
269
+ progressElement = this._createProgressElement();
270
+ progressElement.insertBefore( messageElement );
271
+ } else if ( this.type != 'progress' && progressElement ) {
272
+ progressElement.remove();
273
+ }
274
+ }
493
275
 
494
- /**
495
- * Event buffer object for UI events to optimize performance.
496
- *
497
- * @private
498
- * @property {Object} _uiBuffer
499
- */
276
+ if ( options.message !== undefined ) {
277
+ this.message = options.message;
278
+ messageElement.setHtml( this.message );
279
+ }
500
280
 
501
- /**
502
- * Event buffer object for editor change events to optimize performance.
503
- *
504
- * @private
505
- * @property {Object} _changeBuffer
506
- */
281
+ if ( options.progress !== undefined ) {
282
+ this.progress = options.progress;
507
283
 
508
- Area.prototype = {
509
- /**
510
- * Adds the notification to the notification area. If it is the first notification, the area will also be attached to
511
- * the document and listeners will be attached.
512
- *
513
- * Note that the proper way to show a notification is to call the {@link CKEDITOR.plugins.notification#show} method.
514
- *
515
- * @param {CKEDITOR.plugins.notification} notification Notification to add.
516
- */
517
- add: function( notification ) {
518
- this.notifications.push( notification );
284
+ if ( progressElement ) {
285
+ progressElement.setStyle( 'width', this._getPercentageProgress() );
286
+ }
287
+ }
519
288
 
520
- this.element.append( notification.element );
289
+ if ( show && options.important ) {
290
+ element.setAttribute( 'role', 'alert' );
521
291
 
522
- if ( this.element.getChildCount() == 1 ) {
523
- CKEDITOR.document.getBody().append( this.element );
524
- this._attachListeners();
525
- }
292
+ if ( !this.isVisible() ) {
293
+ this.area.add( this );
294
+ }
295
+ }
526
296
 
527
- this._layout();
528
- },
297
+ // Overwrite even if it is undefined.
298
+ this.duration = options.duration;
529
299
 
530
- /**
531
- * Removes the notification from the notification area. If it is the last notification, the area will also be
532
- * detached from the document and listeners will be detached.
533
- *
534
- * Note that the proper way to hide a notification is to call the {@link CKEDITOR.plugins.notification#hide} method.
535
- *
536
- * @param {CKEDITOR.plugins.notification} notification Notification to remove.
537
- */
538
- remove: function( notification ) {
539
- var i = CKEDITOR.tools.indexOf( this.notifications, notification );
300
+ this._hideAfterTimeout();
301
+ },
540
302
 
541
- if ( i < 0 ) {
542
- return;
543
- }
303
+ /**
304
+ * Removes the notification element from the notification area.
305
+ *
306
+ * Fires the {@link CKEDITOR.editor#notificationHide} event.
307
+ */
308
+ hide: function() {
309
+ if ( this.editor.fire( 'notificationHide', { notification: this } ) === false ) {
310
+ return;
311
+ }
312
+
313
+ this.area.remove( this );
314
+ },
315
+
316
+ /**
317
+ * Returns `true` if the notification is in the notification area.
318
+ *
319
+ * @returns {Boolean} `true` if the notification is in the notification area.
320
+ */
321
+ isVisible: function() {
322
+ return CKEDITOR.tools.indexOf( this.area.notifications, this ) >= 0;
323
+ },
324
+
325
+ /**
326
+ * Creates the notification DOM element.
327
+ *
328
+ * @private
329
+ * @returns {CKEDITOR.dom.element} Notification DOM element.
330
+ */
331
+ _createElement: function() {
332
+ var notification = this,
333
+ notificationElement, notificationMessageElement, notificationCloseElement,
334
+ close = this.editor.lang.common.close;
335
+
336
+ notificationElement = new CKEDITOR.dom.element( 'div' );
337
+ notificationElement.addClass( 'cke_notification' );
338
+ notificationElement.addClass( this._getClass() );
339
+ notificationElement.setAttributes( {
340
+ id: this.id,
341
+ role: 'alert',
342
+ 'aria-label': this.type
343
+ } );
544
344
 
545
- this.notifications.splice( i, 1 );
345
+ if ( this.type == 'progress' )
346
+ notificationElement.append( this._createProgressElement() );
546
347
 
547
- notification.element.remove();
348
+ notificationMessageElement = new CKEDITOR.dom.element( 'p' );
349
+ notificationMessageElement.addClass( 'cke_notification_message' );
350
+ notificationMessageElement.setHtml( this.message );
351
+ notificationElement.append( notificationMessageElement );
548
352
 
549
- if ( !this.element.getChildCount() ) {
550
- this._removeListeners();
551
- this.element.remove();
353
+ notificationCloseElement = CKEDITOR.dom.element.createFromHtml(
354
+ '<a class="cke_notification_close" href="javascript:void(0)" title="' + close + '" role="button" tabindex="-1">' +
355
+ '<span class="cke_label">X</span>' +
356
+ '</a>' );
357
+ notificationElement.append( notificationCloseElement );
358
+
359
+ notificationCloseElement.on( 'click', function() {
360
+ // Focus editor on close (https://dev.ckeditor.com/ticket/12865)
361
+ notification.editor.focus();
362
+
363
+ notification.hide();
364
+ } );
365
+
366
+ return notificationElement;
367
+ },
368
+
369
+ /**
370
+ * Gets the notification CSS class.
371
+ *
372
+ * @private
373
+ * @returns {String} Notification CSS class.
374
+ */
375
+ _getClass: function() {
376
+ return ( this.type == 'progress' ) ?
377
+ 'cke_notification_info' :
378
+ ( 'cke_notification_' + this.type );
379
+ },
380
+
381
+ /**
382
+ * Creates a progress element for the notification element.
383
+ *
384
+ * @private
385
+ * @returns {CKEDITOR.dom.element} Progress element for the notification element.
386
+ */
387
+ _createProgressElement: function() {
388
+ var element = new CKEDITOR.dom.element( 'span' );
389
+ element.addClass( 'cke_notification_progress' );
390
+ element.setStyle( 'width', this._getPercentageProgress() );
391
+ return element;
392
+ },
393
+
394
+ /**
395
+ * Gets the progress as a percentage (ex. `0.3` -> `30%`).
396
+ *
397
+ * @private
398
+ * @returns {String} Progress as a percentage.
399
+ */
400
+ _getPercentageProgress: function() {
401
+ return Math.round( ( this.progress || 0 ) * 100 ) + '%';
402
+ },
403
+
404
+ /**
405
+ * Hides the notification after a timeout.
406
+ *
407
+ * @private
408
+ */
409
+ _hideAfterTimeout: function() {
410
+ var notification = this,
411
+ duration;
412
+
413
+ if ( this._hideTimeoutId ) {
414
+ clearTimeout( this._hideTimeoutId );
415
+ }
416
+
417
+ if ( typeof this.duration == 'number' ) {
418
+ duration = this.duration;
419
+ } else if ( this.type == 'info' || this.type == 'success' ) {
420
+ duration = ( typeof this.editor.config.notification_duration == 'number' ) ?
421
+ this.editor.config.notification_duration :
422
+ 5000;
423
+ }
424
+
425
+ if ( duration ) {
426
+ notification._hideTimeoutId = setTimeout( function() {
427
+ notification.hide();
428
+ }, duration );
429
+ }
552
430
  }
553
- },
431
+ };
554
432
 
555
433
  /**
556
- * Creates the notification area element.
434
+ * Notification area is an area where all notifications are put. The area is laid out dynamically.
435
+ * When the first notification is added, the area is shown and all listeners are added.
436
+ * When the last notification is removed, the area is hidden and all listeners are removed.
557
437
  *
438
+ * @since 4.5
558
439
  * @private
559
- * @returns {CKEDITOR.dom.element} Notification area element.
440
+ * @class CKEDITOR.plugins.notification.area
441
+ * @constructor
442
+ * @param {CKEDITOR.editor} editor The editor instance.
560
443
  */
561
- _createElement: function() {
562
- var editor = this.editor,
563
- config = editor.config,
564
- notificationArea = new CKEDITOR.dom.element( 'div' );
444
+ function Area( editor ) {
445
+ var that = this;
446
+
447
+ this.editor = editor;
448
+ this.notifications = [];
449
+ this.element = this._createElement();
450
+ this._uiBuffer = CKEDITOR.tools.eventsBuffer( 10, this._layout, this );
451
+ this._changeBuffer = CKEDITOR.tools.eventsBuffer( 500, this._layout, this );
452
+
453
+ editor.on( 'destroy', function() {
454
+ that._removeListeners();
455
+ that.element.remove();
456
+ } );
457
+ }
565
458
 
566
- notificationArea.addClass( 'cke_notifications_area' );
567
- notificationArea.setAttribute( 'id', 'cke_notifications_area_' + editor.name );
568
- notificationArea.setStyle( 'z-index', config.baseFloatZIndex - 2 );
459
+ /**
460
+ * The editor instance.
461
+ *
462
+ * @readonly
463
+ * @property {CKEDITOR.editor} editor
464
+ */
569
465
 
570
- return notificationArea;
571
- },
466
+ /**
467
+ * The array of added notifications.
468
+ *
469
+ * @readonly
470
+ * @property {Array} notifications
471
+ */
572
472
 
573
473
  /**
574
- * Attaches listeners to the notification area.
474
+ * Notification area DOM element. This element is created when the area object is created. It will be attached to the document
475
+ * when the first notification is added and removed when the last notification is removed.
575
476
  *
576
- * @private
477
+ * @readonly
478
+ * @property {CKEDITOR.dom.element} element
577
479
  */
578
- _attachListeners: function() {
579
- var win = CKEDITOR.document.getWindow(),
580
- editor = this.editor;
581
480
 
582
- win.on( 'scroll', this._uiBuffer.input );
583
- win.on( 'resize', this._uiBuffer.input );
584
- editor.on( 'change', this._changeBuffer.input );
585
- editor.on( 'floatingSpaceLayout', this._layout, this, null, 20 );
586
- editor.on( 'blur', this._layout, this, null, 20 );
587
- },
481
+ /**
482
+ * Notification width. Cached for performance reasons.
483
+ *
484
+ * @private
485
+ * @property {CKEDITOR.dom.element} _notificationWidth
486
+ */
588
487
 
589
488
  /**
590
- * Detaches listeners from the notification area.
489
+ * Notification margin. Cached for performance reasons.
591
490
  *
592
491
  * @private
492
+ * @property {CKEDITOR.dom.element} _notificationMargin
593
493
  */
594
- _removeListeners: function() {
595
- var win = CKEDITOR.document.getWindow(),
596
- editor = this.editor;
597
494
 
598
- win.removeListener( 'scroll', this._uiBuffer.input );
599
- win.removeListener( 'resize', this._uiBuffer.input );
600
- editor.removeListener( 'change', this._changeBuffer.input );
601
- editor.removeListener( 'floatingSpaceLayout', this._layout );
602
- editor.removeListener( 'blur', this._layout );
603
- },
495
+ /**
496
+ * Event buffer object for UI events to optimize performance.
497
+ *
498
+ * @private
499
+ * @property {Object} _uiBuffer
500
+ */
604
501
 
605
502
  /**
606
- * Sets the position of the notification area based on the editor content, toolbar as well as
607
- * viewport position and dimensions.
503
+ * Event buffer object for editor change events to optimize performance.
608
504
  *
609
505
  * @private
506
+ * @property {Object} _changeBuffer
610
507
  */
611
- _layout: function() {
612
- var area = this.element,
613
- editor = this.editor,
614
- contentsRect = editor.ui.contentsElement.getClientRect(),
615
- contentsPos = editor.ui.contentsElement.getDocumentPosition(),
616
- top = editor.ui.space( 'top' ),
617
- topRect = top.getClientRect(),
618
- areaRect = area.getClientRect(),
619
- notification,
620
- notificationWidth = this._notificationWidth,
621
- notificationMargin = this._notificationMargin,
622
- win = CKEDITOR.document.getWindow(),
623
- scrollPos = win.getScrollPosition(),
624
- viewRect = win.getViewPaneSize(),
625
- body = CKEDITOR.document.getBody(),
626
- bodyPos = body.getDocumentPosition(),
627
- cssLength = CKEDITOR.tools.cssLength;
628
-
629
- // Cache for optimization
630
- if ( !notificationWidth || !notificationMargin ) {
631
- notification = this.element.getChild( 0 );
632
- notificationWidth = this._notificationWidth = notification.getClientRect().width;
633
- notificationMargin = this._notificationMargin =
634
- parseInt( notification.getComputedStyle( 'margin-left' ), 10 ) +
635
- parseInt( notification.getComputedStyle( 'margin-right' ), 10 );
636
- }
637
508
 
638
- // --------------------------------------- Horizontal layout ----------------------------------------
639
-
640
- // +---Viewport-------------------------------+ +---Viewport-------------------------------+
641
- // | | | |
642
- // | +---Toolbar----------------------------+ | | +---Content----------------------------+ |
643
- // | | | | | | | |
644
- // | +---Content----------------------------+ | | | | |
645
- // | | | | | +---Toolbar----------------------+ | |
646
- // | | +------Notification------+ | | | | | | |
647
- // | | | | OR | +--------------------------------+ | |
648
- // | | | | | | | |
649
- // | | | | | | +------Notification------+ | |
650
- // | | | | | | | |
651
- // | | | | | | | |
652
- // | +--------------------------------------+ | | +--------------------------------------+ |
653
- // +------------------------------------------+ +------------------------------------------+
654
- if ( top.isVisible() &&
655
- topRect.bottom > contentsRect.top &&
656
- topRect.bottom < contentsRect.bottom - areaRect.height ) {
657
- setBelowToolbar();
658
-
659
- // +---Viewport-------------------------------+
660
- // | |
661
- // | +---Content----------------------------+ |
662
- // | | | |
663
- // | | +------Notification------+ | |
664
- // | | | |
665
- // | | | |
666
- // | | | |
667
- // | +--------------------------------------+ |
668
- // | |
669
- // +------------------------------------------+
670
- } else if ( contentsRect.top > 0 ) {
671
- setTopStandard();
672
-
673
- // +---Content----------------------------+
674
- // | |
675
- // +---Viewport-------------------------------+
676
- // | | | |
677
- // | | +------Notification------+ | |
678
- // | | | |
679
- // | | | |
680
- // | | | |
681
- // | +--------------------------------------+ |
682
- // | |
683
- // +------------------------------------------+
684
- } else if ( contentsPos.y + contentsRect.height - areaRect.height > scrollPos.y ) {
685
- setTopFixed();
686
-
687
- // +---Content----------------------------+ +---Content----------------------------+
688
- // | | | |
689
- // | | | |
690
- // | | | +------Notification------+ |
691
- // | | | |
692
- // | | OR +--------------------------------------+
693
- // +---Viewport-------------------------------+
694
- // | | +------Notification------+ | | +---Viewport-------------------------------+
695
- // | | | | | |
696
- // | +--------------------------------------+ | | |
697
- // | | | |
698
- // +------------------------------------------+ +------------------------------------------+
699
- } else {
700
- setBottom();
701
- }
509
+ Area.prototype = {
510
+ /**
511
+ * Adds the notification to the notification area. If it is the first notification, the area will also be attached to
512
+ * the document and listeners will be attached.
513
+ *
514
+ * Note that the proper way to show a notification is to call the {@link CKEDITOR.plugins.notification#show} method.
515
+ *
516
+ * @param {CKEDITOR.plugins.notification} notification Notification to add.
517
+ */
518
+ add: function( notification ) {
519
+ this.notifications.push( notification );
520
+
521
+ this.element.append( notification.element );
522
+
523
+ if ( this.element.getChildCount() == 1 ) {
524
+ CKEDITOR.document.getBody().append( this.element );
525
+ this._attachListeners();
526
+ }
702
527
 
703
- function setTopStandard() {
704
- area.setStyles( {
705
- position: 'absolute',
706
- top: cssLength( contentsPos.y )
707
- } );
708
- }
528
+ this._layout();
529
+ },
530
+
531
+ /**
532
+ * Removes the notification from the notification area. If it is the last notification, the area will also be
533
+ * detached from the document and listeners will be detached.
534
+ *
535
+ * Note that the proper way to hide a notification is to call the {@link CKEDITOR.plugins.notification#hide} method.
536
+ *
537
+ * @param {CKEDITOR.plugins.notification} notification Notification to remove.
538
+ */
539
+ remove: function( notification ) {
540
+ var i = CKEDITOR.tools.indexOf( this.notifications, notification );
541
+
542
+ if ( i < 0 ) {
543
+ return;
544
+ }
709
545
 
710
- function setBelowToolbar() {
711
- area.setStyles( {
712
- position: 'fixed',
713
- top: cssLength( topRect.bottom )
714
- } );
715
- }
546
+ this.notifications.splice( i, 1 );
716
547
 
717
- function setTopFixed() {
718
- area.setStyles( {
719
- position: 'fixed',
720
- top: 0
721
- } );
722
- }
548
+ notification.element.remove();
723
549
 
724
- function setBottom() {
725
- area.setStyles( {
726
- position: 'absolute',
727
- top: cssLength( contentsPos.y + contentsRect.height - areaRect.height )
728
- } );
729
- }
550
+ if ( !this.element.getChildCount() ) {
551
+ this._removeListeners();
552
+ this.element.remove();
553
+ }
554
+ },
555
+
556
+ /**
557
+ * Creates the notification area element.
558
+ *
559
+ * @private
560
+ * @returns {CKEDITOR.dom.element} Notification area element.
561
+ */
562
+ _createElement: function() {
563
+ var editor = this.editor,
564
+ config = editor.config,
565
+ notificationArea = new CKEDITOR.dom.element( 'div' );
566
+
567
+ notificationArea.addClass( 'cke_notifications_area' );
568
+ notificationArea.setAttribute( 'id', 'cke_notifications_area_' + editor.name );
569
+ notificationArea.setStyle( 'z-index', config.baseFloatZIndex - 2 );
570
+
571
+ return notificationArea;
572
+ },
573
+
574
+ /**
575
+ * Attaches listeners to the notification area.
576
+ *
577
+ * @private
578
+ */
579
+ _attachListeners: function() {
580
+ var win = CKEDITOR.document.getWindow(),
581
+ editor = this.editor;
582
+
583
+ win.on( 'scroll', this._uiBuffer.input );
584
+ win.on( 'resize', this._uiBuffer.input );
585
+ editor.on( 'change', this._changeBuffer.input );
586
+ editor.on( 'floatingSpaceLayout', this._layout, this, null, 20 );
587
+ editor.on( 'blur', this._layout, this, null, 20 );
588
+ },
589
+
590
+ /**
591
+ * Detaches listeners from the notification area.
592
+ *
593
+ * @private
594
+ */
595
+ _removeListeners: function() {
596
+ var win = CKEDITOR.document.getWindow(),
597
+ editor = this.editor;
598
+
599
+ win.removeListener( 'scroll', this._uiBuffer.input );
600
+ win.removeListener( 'resize', this._uiBuffer.input );
601
+ editor.removeListener( 'change', this._changeBuffer.input );
602
+ editor.removeListener( 'floatingSpaceLayout', this._layout );
603
+ editor.removeListener( 'blur', this._layout );
604
+ },
605
+
606
+ /**
607
+ * Sets the position of the notification area based on the editor content, toolbar as well as
608
+ * viewport position and dimensions.
609
+ *
610
+ * @private
611
+ */
612
+ _layout: function() {
613
+ var area = this.element,
614
+ editor = this.editor,
615
+ contentsRect = editor.ui.contentsElement.getClientRect(),
616
+ contentsPos = editor.ui.contentsElement.getDocumentPosition(),
617
+ top,
618
+ topRect,
619
+ areaRect = area.getClientRect(),
620
+ notification,
621
+ notificationWidth = this._notificationWidth,
622
+ notificationMargin = this._notificationMargin,
623
+ win = CKEDITOR.document.getWindow(),
624
+ scrollPos = win.getScrollPosition(),
625
+ viewRect = win.getViewPaneSize(),
626
+ body = CKEDITOR.document.getBody(),
627
+ bodyPos = body.getDocumentPosition(),
628
+ cssLength = CKEDITOR.tools.cssLength;
629
+
630
+ // Cache for optimization
631
+ if ( !notificationWidth || !notificationMargin ) {
632
+ notification = this.element.getChild( 0 );
633
+ notificationWidth = this._notificationWidth = notification.getClientRect().width;
634
+ notificationMargin = this._notificationMargin =
635
+ parseInt( notification.getComputedStyle( 'margin-left' ), 10 ) +
636
+ parseInt( notification.getComputedStyle( 'margin-right' ), 10 );
637
+ }
730
638
 
731
- // ---------------------------------------- Vertical layout -----------------------------------------
639
+ // Check if toolbar exist and if so, then assign values to it (#491).
640
+ if ( editor.toolbar ) {
641
+ top = editor.ui.space( 'top' );
642
+ topRect = top.getClientRect();
643
+ }
732
644
 
733
- var leftBase = area.getStyle( 'position' ) == 'fixed' ?
734
- contentsRect.left :
735
- body.getComputedStyle( 'position' ) != 'static' ? contentsPos.x - bodyPos.x : contentsPos.x;
736
645
 
737
- // Content is narrower than notification
738
- if ( contentsRect.width < notificationWidth + notificationMargin ) {
646
+ // --------------------------------------- Horizontal layout ----------------------------------------
647
+
648
+ // +---Viewport-------------------------------+ +---Viewport-------------------------------+
649
+ // | | | |
650
+ // | +---Toolbar----------------------------+ | | +---Content----------------------------+ |
651
+ // | | | | | | | |
652
+ // | +---Content----------------------------+ | | | | |
653
+ // | | | | | +---Toolbar----------------------+ | |
654
+ // | | +------Notification------+ | | | | | | |
655
+ // | | | | OR | +--------------------------------+ | |
656
+ // | | | | | | | |
657
+ // | | | | | | +------Notification------+ | |
658
+ // | | | | | | | |
659
+ // | | | | | | | |
660
+ // | +--------------------------------------+ | | +--------------------------------------+ |
661
+ // +------------------------------------------+ +------------------------------------------+
662
+ if ( top && top.isVisible() &&
663
+ topRect.bottom > contentsRect.top &&
664
+ topRect.bottom < contentsRect.bottom - areaRect.height ) {
665
+ setBelowToolbar();
739
666
 
740
667
  // +---Viewport-------------------------------+
741
668
  // | |
742
- // | +---Content------------+ |
743
- // | | | |
744
- // | +------Notification------+ | |
745
- // | | | |
746
- // | +----------------------+ |
669
+ // | +---Content----------------------------+ |
670
+ // | | | |
671
+ // | | +------Notification------+ | |
672
+ // | | | |
673
+ // | | | |
674
+ // | | | |
675
+ // | +--------------------------------------+ |
676
+ // | |
677
+ // +------------------------------------------+
678
+ } else if ( contentsRect.top > 0 ) {
679
+ setTopStandard();
680
+
681
+ // +---Content----------------------------+
682
+ // | |
683
+ // +---Viewport-------------------------------+
684
+ // | | | |
685
+ // | | +------Notification------+ | |
686
+ // | | | |
687
+ // | | | |
688
+ // | | | |
689
+ // | +--------------------------------------+ |
747
690
  // | |
748
691
  // +------------------------------------------+
749
- if ( contentsPos.x + notificationWidth + notificationMargin > scrollPos.x + viewRect.width ) {
750
- setRight();
751
-
752
- // +---Viewport-------------------------------+ +---Viewport--------------------------+
753
- // | | | |
754
- // | +---Content------------+ | +---Content------------+ |
755
- // | | | | | | | |
756
- // | | +------Notification------+ | OR | +------Notification------+ |
757
- // | | | | | | | |
758
- // | +----------------------+ | +----------------------+ |
759
- // | | | |
760
- // +------------------------------------------+ +-------------------------------------+
692
+ } else if ( contentsPos.y + contentsRect.height - areaRect.height > scrollPos.y ) {
693
+ setTopFixed();
694
+
695
+ // +---Content----------------------------+ +---Content----------------------------+
696
+ // | | | |
697
+ // | | | |
698
+ // | | | +------Notification------+ |
699
+ // | | | |
700
+ // | | OR +--------------------------------------+
701
+ // +---Viewport-------------------------------+
702
+ // | | +------Notification------+ | | +---Viewport-------------------------------+
703
+ // | | | | | |
704
+ // | +--------------------------------------+ | | |
705
+ // | | | |
706
+ // +------------------------------------------+ +------------------------------------------+
761
707
  } else {
762
- setLeft();
708
+ setBottom();
709
+ }
710
+
711
+ function setTopStandard() {
712
+ area.setStyles( {
713
+ position: 'absolute',
714
+ top: cssLength( contentsPos.y )
715
+ } );
716
+ }
717
+
718
+ function setBelowToolbar() {
719
+ area.setStyles( {
720
+ position: 'fixed',
721
+ top: cssLength( topRect.bottom )
722
+ } );
723
+ }
724
+
725
+ function setTopFixed() {
726
+ area.setStyles( {
727
+ position: 'fixed',
728
+ top: 0
729
+ } );
763
730
  }
764
731
 
765
- // Content is wider than notification.
766
- } else {
767
-
768
- // +--+Viewport+------------------------+
769
- // | |
770
- // | +---Content-----------------------------------------+
771
- // | | | |
772
- // | | +-----+Notification+-----+ |
773
- // | | | |
774
- // | | | |
775
- // | | | |
776
- // | +---------------------------------------------------+
777
- // | |
778
- // +------------------------------------+
779
- if ( contentsPos.x + notificationWidth + notificationMargin > scrollPos.x + viewRect.width ) {
780
- setLeft();
781
-
782
- // +---Viewport-------------------------+
783
- // | |
784
- // | +---Content----------------------------------------------+
785
- // | | | |
786
- // | | +------Notification------+ | |
787
- // | | | |
788
- // | | | |
789
- // | +--------------------------------------------------------+
790
- // | |
791
- // +------------------------------------+
792
- } else if ( contentsPos.x + contentsRect.width / 2 +
793
- notificationWidth / 2 + notificationMargin > scrollPos.x + viewRect.width ) {
794
- setRightFixed();
795
-
796
- // +---Viewport-------------------------+
797
- // | |
798
- // +---Content----------------------------+ |
799
- // | | | |
800
- // | +------Notification------+ | |
801
- // | | | |
802
- // | | | |
803
- // +--------------------------------------+ |
804
- // | |
805
- // +------------------------------------+
806
- } else if ( contentsRect.left + contentsRect.width - notificationWidth - notificationMargin < 0 ) {
807
- setRight();
808
-
809
- // +---Viewport-------------------------+
810
- // | |
811
- // +---Content---------------------------------------------+ |
812
- // | | | |
813
- // | | +------Notification------+ | |
814
- // | | | |
815
- // | | | |
816
- // +-------------------------------------------------------+ |
817
- // | |
818
- // +------------------------------------+
819
- } else if ( contentsRect.left + contentsRect.width / 2 - notificationWidth / 2 < 0 ) {
820
- setLeftFixed();
821
-
822
- // +---Viewport-------------------------+
823
- // | |
824
- // | +---Content----------------------+ |
825
- // | | | |
826
- // | | +-----Notification-----+ | |
827
- // | | | |
828
- // | | | |
829
- // | +--------------------------------+ |
830
- // | |
831
- // +------------------------------------+
732
+ function setBottom() {
733
+ area.setStyles( {
734
+ position: 'absolute',
735
+ top: cssLength( contentsPos.y + contentsRect.height - areaRect.height )
736
+ } );
737
+ }
738
+
739
+ // ---------------------------------------- Vertical layout -----------------------------------------
740
+
741
+ var leftBase = area.getStyle( 'position' ) == 'fixed' ?
742
+ contentsRect.left :
743
+ body.getComputedStyle( 'position' ) != 'static' ? contentsPos.x - bodyPos.x : contentsPos.x;
744
+
745
+ // Content is narrower than notification
746
+ if ( contentsRect.width < notificationWidth + notificationMargin ) {
747
+
748
+ // +---Viewport-------------------------------+
749
+ // | |
750
+ // | +---Content------------+ |
751
+ // | | | |
752
+ // | +------Notification------+ | |
753
+ // | | | |
754
+ // | +----------------------+ |
755
+ // | |
756
+ // +------------------------------------------+
757
+ if ( contentsPos.x + notificationWidth + notificationMargin > scrollPos.x + viewRect.width ) {
758
+ setRight();
759
+
760
+ // +---Viewport-------------------------------+ +---Viewport--------------------------+
761
+ // | | | |
762
+ // | +---Content------------+ | +---Content------------+ |
763
+ // | | | | | | | |
764
+ // | | +------Notification------+ | OR | +------Notification------+ |
765
+ // | | | | | | | |
766
+ // | +----------------------+ | +----------------------+ |
767
+ // | | | |
768
+ // +------------------------------------------+ +-------------------------------------+
769
+ } else {
770
+ setLeft();
771
+ }
772
+
773
+ // Content is wider than notification.
832
774
  } else {
833
- setCenter();
775
+
776
+ // +--+Viewport+------------------------+
777
+ // | |
778
+ // | +---Content-----------------------------------------+
779
+ // | | | |
780
+ // | | +-----+Notification+-----+ |
781
+ // | | | |
782
+ // | | | |
783
+ // | | | |
784
+ // | +---------------------------------------------------+
785
+ // | |
786
+ // +------------------------------------+
787
+ if ( contentsPos.x + notificationWidth + notificationMargin > scrollPos.x + viewRect.width ) {
788
+ setLeft();
789
+
790
+ // +---Viewport-------------------------+
791
+ // | |
792
+ // | +---Content----------------------------------------------+
793
+ // | | | |
794
+ // | | +------Notification------+ | |
795
+ // | | | |
796
+ // | | | |
797
+ // | +--------------------------------------------------------+
798
+ // | |
799
+ // +------------------------------------+
800
+ } else if ( contentsPos.x + contentsRect.width / 2 +
801
+ notificationWidth / 2 + notificationMargin > scrollPos.x + viewRect.width ) {
802
+ setRightFixed();
803
+
804
+ // +---Viewport-------------------------+
805
+ // | |
806
+ // +---Content----------------------------+ |
807
+ // | | | |
808
+ // | +------Notification------+ | |
809
+ // | | | |
810
+ // | | | |
811
+ // +--------------------------------------+ |
812
+ // | |
813
+ // +------------------------------------+
814
+ } else if ( contentsRect.left + contentsRect.width - notificationWidth - notificationMargin < 0 ) {
815
+ setRight();
816
+
817
+ // +---Viewport-------------------------+
818
+ // | |
819
+ // +---Content---------------------------------------------+ |
820
+ // | | | |
821
+ // | | +------Notification------+ | |
822
+ // | | | |
823
+ // | | | |
824
+ // +-------------------------------------------------------+ |
825
+ // | |
826
+ // +------------------------------------+
827
+ } else if ( contentsRect.left + contentsRect.width / 2 - notificationWidth / 2 < 0 ) {
828
+ setLeftFixed();
829
+
830
+ // +---Viewport-------------------------+
831
+ // | |
832
+ // | +---Content----------------------+ |
833
+ // | | | |
834
+ // | | +-----Notification-----+ | |
835
+ // | | | |
836
+ // | | | |
837
+ // | +--------------------------------+ |
838
+ // | |
839
+ // +------------------------------------+
840
+ } else {
841
+ setCenter();
842
+ }
834
843
  }
835
- }
836
844
 
837
- function setLeft() {
838
- area.setStyle( 'left', cssLength( leftBase ) );
839
- }
845
+ function setLeft() {
846
+ area.setStyle( 'left', cssLength( leftBase ) );
847
+ }
840
848
 
841
- function setLeftFixed() {
842
- area.setStyle( 'left', cssLength( leftBase - contentsPos.x + scrollPos.x ) );
843
- }
849
+ function setLeftFixed() {
850
+ area.setStyle( 'left', cssLength( leftBase - contentsPos.x + scrollPos.x ) );
851
+ }
844
852
 
845
- function setCenter() {
846
- area.setStyle( 'left', cssLength( leftBase + contentsRect.width / 2 - notificationWidth / 2 - notificationMargin / 2 ) );
847
- }
853
+ function setCenter() {
854
+ area.setStyle( 'left', cssLength( leftBase + contentsRect.width / 2 - notificationWidth / 2 - notificationMargin / 2 ) );
855
+ }
848
856
 
849
- function setRight() {
850
- area.setStyle( 'left', cssLength( leftBase + contentsRect.width - notificationWidth - notificationMargin ) );
851
- }
857
+ function setRight() {
858
+ area.setStyle( 'left', cssLength( leftBase + contentsRect.width - notificationWidth - notificationMargin ) );
859
+ }
852
860
 
853
- function setRightFixed() {
854
- area.setStyle( 'left', cssLength( leftBase - contentsPos.x + scrollPos.x + viewRect.width -
855
- notificationWidth - notificationMargin ) );
861
+ function setRightFixed() {
862
+ area.setStyle( 'left', cssLength( leftBase - contentsPos.x + scrollPos.x + viewRect.width -
863
+ notificationWidth - notificationMargin ) );
864
+ }
856
865
  }
857
- }
858
- };
866
+ };
859
867
 
860
- CKEDITOR.plugins.notification = Notification;
868
+ CKEDITOR.plugins.notification = Notification;
861
869
 
862
- /**
863
- * After how many milliseconds the notification of the `info` and `success`
864
- * {@link CKEDITOR.plugins.notification#type type} should close automatically.
865
- * `0` means that notifications will not close automatically.
866
- * Note that `warning` and `progress` notifications will never close automatically.
867
- *
868
- * Refer to the [Notifications](http://docs.ckeditor.com/#!/guide/dev_notifications) article
869
- * for more information about this feature.
870
- *
871
- * @since 4.5
872
- * @cfg {Number} [notification_duration=5000]
873
- * @member CKEDITOR.config
874
- */
870
+ /**
871
+ * After how many milliseconds the notification of the `info` and `success`
872
+ * {@link CKEDITOR.plugins.notification#type type} should close automatically.
873
+ * `0` means that notifications will not close automatically.
874
+ * Note that `warning` and `progress` notifications will never close automatically.
875
+ *
876
+ * Refer to the [Notifications](https://ckeditor.com/docs/ckeditor4/latest/guide/dev_notifications.html) article
877
+ * for more information about this feature.
878
+ *
879
+ * @since 4.5
880
+ * @cfg {Number} [notification_duration=5000]
881
+ * @member CKEDITOR.config
882
+ */
875
883
 
876
- /**
877
- * Event fired when the {@link CKEDITOR.plugins.notification#show} method is called, before the
878
- * notification is shown. If this event is canceled, the notification will not be shown.
879
- *
880
- * Using this event allows you to fully customize how a notification will be shown. It may be used to integrate
881
- * the CKEditor notification system with your web page notifications.
882
- *
883
- * @since 4.5
884
- * @event notificationShow
885
- * @member CKEDITOR.editor
886
- * @param data
887
- * @param {CKEDITOR.plugins.notification} data.notification Notification which will be shown.
888
- * @param {CKEDITOR.editor} editor The editor instance.
889
- */
884
+ /**
885
+ * Event fired when the {@link CKEDITOR.plugins.notification#show} method is called, before the
886
+ * notification is shown. If this event is canceled, the notification will not be shown.
887
+ *
888
+ * Using this event allows you to fully customize how a notification will be shown. It may be used to integrate
889
+ * the CKEditor notification system with your web page notifications.
890
+ *
891
+ * @since 4.5
892
+ * @event notificationShow
893
+ * @member CKEDITOR.editor
894
+ * @param data
895
+ * @param {CKEDITOR.plugins.notification} data.notification Notification which will be shown.
896
+ * @param {CKEDITOR.editor} editor The editor instance.
897
+ */
890
898
 
891
- /**
892
- * Event fired when the {@link CKEDITOR.plugins.notification#update} method is called, before the
893
- * notification is updated. If this event is canceled, the notification will not be shown even if the update was important,
894
- * but the object will be updated anyway. Note that canceling this event does not prevent updating {@link #element}
895
- * attributes, but if {@link #notificationShow} was canceled as well, this element is detached from the DOM.
896
- *
897
- * Using this event allows you to fully customize how a notification will be updated. It may be used to integrate
898
- * the CKEditor notification system with your web page notifications.
899
- *
900
- * @since 4.5
901
- * @event notificationUpdate
902
- * @member CKEDITOR.editor
903
- * @param data
904
- * @param {CKEDITOR.plugins.notification} data.notification Notification which will be updated.
905
- * Note that it contains the data that has not been updated yet.
906
- * @param {Object} data.options Update options, see {@link CKEDITOR.plugins.notification#update}.
907
- * @param {CKEDITOR.editor} editor The editor instance.
908
- */
899
+ /**
900
+ * Event fired when the {@link CKEDITOR.plugins.notification#update} method is called, before the
901
+ * notification is updated. If this event is canceled, the notification will not be shown even if the update was important,
902
+ * but the object will be updated anyway. Note that canceling this event does not prevent updating {@link #element}
903
+ * attributes, but if {@link #notificationShow} was canceled as well, this element is detached from the DOM.
904
+ *
905
+ * Using this event allows you to fully customize how a notification will be updated. It may be used to integrate
906
+ * the CKEditor notification system with your web page notifications.
907
+ *
908
+ * @since 4.5
909
+ * @event notificationUpdate
910
+ * @member CKEDITOR.editor
911
+ * @param data
912
+ * @param {CKEDITOR.plugins.notification} data.notification Notification which will be updated.
913
+ * Note that it contains the data that has not been updated yet.
914
+ * @param {Object} data.options Update options, see {@link CKEDITOR.plugins.notification#update}.
915
+ * @param {CKEDITOR.editor} editor The editor instance.
916
+ */
909
917
 
910
- /**
911
- * Event fired when the {@link CKEDITOR.plugins.notification#hide} method is called, before the
912
- * notification is hidden. If this event is canceled, the notification will not be hidden.
913
- *
914
- * Using this event allows you to fully customize how a notification will be hidden. It may be used to integrate
915
- * the CKEditor notification system with your web page notifications.
916
- *
917
- * @since 4.5
918
- * @event notificationHide
919
- * @member CKEDITOR.editor
920
- * @param data
921
- * @param {CKEDITOR.plugins.notification} data.notification Notification which will be hidden.
922
- * @param {CKEDITOR.editor} editor The editor instance.
923
- */
918
+ /**
919
+ * Event fired when the {@link CKEDITOR.plugins.notification#hide} method is called, before the
920
+ * notification is hidden. If this event is canceled, the notification will not be hidden.
921
+ *
922
+ * Using this event allows you to fully customize how a notification will be hidden. It may be used to integrate
923
+ * the CKEditor notification system with your web page notifications.
924
+ *
925
+ * @since 4.5
926
+ * @event notificationHide
927
+ * @member CKEDITOR.editor
928
+ * @param data
929
+ * @param {CKEDITOR.plugins.notification} data.notification Notification which will be hidden.
930
+ * @param {CKEDITOR.editor} editor The editor instance.
931
+ */
932
+
933
+ } )();