fit-ui 2.7.0 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/dist/Documentation.html +3 -3
  2. package/dist/Fit.UI.css +176 -54
  3. package/dist/Fit.UI.js +736 -131
  4. package/dist/Fit.UI.min.css +1 -1
  5. package/dist/Fit.UI.min.js +1 -1
  6. package/dist/Resources/CKEditor/CHANGES.md +34 -3
  7. package/dist/Resources/CKEditor/LICENSE.md +3 -3
  8. package/dist/Resources/CKEditor/README.md +1 -1
  9. package/dist/Resources/CKEditor/adapters/jquery.js +1 -1
  10. package/dist/Resources/CKEditor/build-config.js +4 -5
  11. package/dist/Resources/CKEditor/ckeditor.js +336 -340
  12. package/dist/Resources/CKEditor/config.js +1 -1
  13. package/dist/Resources/CKEditor/contents.css +208 -208
  14. package/dist/Resources/CKEditor/lang/da.js +3 -3
  15. package/dist/Resources/CKEditor/lang/de.js +3 -3
  16. package/dist/Resources/CKEditor/lang/en.js +3 -3
  17. package/dist/Resources/CKEditor/plugins/autocomplete/skins/default.css +38 -38
  18. package/dist/Resources/CKEditor/plugins/clipboard/dialogs/paste.js +1 -1
  19. package/dist/Resources/CKEditor/plugins/dialog/dialogDefinition.js +1 -1
  20. package/dist/Resources/CKEditor/plugins/dialog/styles/dialog.css +18 -18
  21. package/dist/Resources/CKEditor/plugins/emoji/skins/default.css +237 -237
  22. package/dist/Resources/CKEditor/plugins/icons.png +0 -0
  23. package/dist/Resources/CKEditor/plugins/icons_hidpi.png +0 -0
  24. package/dist/Resources/CKEditor/plugins/link/dialogs/anchor.js +1 -1
  25. package/dist/Resources/CKEditor/plugins/link/dialogs/link.js +1 -1
  26. package/dist/Resources/CKEditor/plugins/pastefromword/filter/default.js +1 -1
  27. package/dist/Resources/CKEditor/plugins/pastetools/filter/common.js +1 -1
  28. package/dist/Resources/CKEditor/plugins/pastetools/filter/image.js +7 -7
  29. package/dist/Resources/CKEditor/skins/moono-lisa/dialog.css +5 -5
  30. package/dist/Resources/CKEditor/skins/moono-lisa/dialog_ie.css +5 -5
  31. package/dist/Resources/CKEditor/skins/moono-lisa/dialog_ie8.css +5 -5
  32. package/dist/Resources/CKEditor/skins/moono-lisa/dialog_iequirks.css +5 -5
  33. package/dist/Resources/CKEditor/skins/moono-lisa/editor.css +5 -5
  34. package/dist/Resources/CKEditor/skins/moono-lisa/editor_gecko.css +5 -5
  35. package/dist/Resources/CKEditor/skins/moono-lisa/editor_ie.css +5 -5
  36. package/dist/Resources/CKEditor/skins/moono-lisa/editor_ie8.css +5 -5
  37. package/dist/Resources/CKEditor/skins/moono-lisa/editor_iequirks.css +5 -5
  38. package/dist/Resources/CKEditor/skins/moono-lisa/icons.png +0 -0
  39. package/dist/Resources/CKEditor/skins/moono-lisa/icons_hidpi.png +0 -0
  40. package/dist/Resources/CKEditor/skins/moono-lisa/readme.md +1 -1
  41. package/dist/Resources/CKEditor/styles.js +137 -137
  42. package/dist/Resources/ckeditor_4.17.2_6f06412961d8.zip +0 -0
  43. package/package.json +1 -1
  44. package/types/index.d.ts +30 -1
  45. package/dist/Resources/CKEditor-autogrow-plugin-built-in/CHANGES.md +0 -2117
  46. package/dist/Resources/CKEditor-autogrow-plugin-built-in/LICENSE.md +0 -1436
  47. package/dist/Resources/CKEditor-autogrow-plugin-built-in/README-FitUiChanges.txt +0 -8
  48. package/dist/Resources/CKEditor-autogrow-plugin-built-in/README.md +0 -39
  49. package/dist/Resources/CKEditor-autogrow-plugin-built-in/adapters/jquery.js +0 -10
  50. package/dist/Resources/CKEditor-autogrow-plugin-built-in/build-config.js +0 -80
  51. package/dist/Resources/CKEditor-autogrow-plugin-built-in/ckeditor.js +0 -986
  52. package/dist/Resources/CKEditor-autogrow-plugin-built-in/config.js +0 -34
  53. package/dist/Resources/CKEditor-autogrow-plugin-built-in/contents.css +0 -208
  54. package/dist/Resources/CKEditor-autogrow-plugin-built-in/index.html +0 -36
  55. package/dist/Resources/CKEditor-autogrow-plugin-built-in/lang/da.js +0 -5
  56. package/dist/Resources/CKEditor-autogrow-plugin-built-in/lang/de.js +0 -5
  57. package/dist/Resources/CKEditor-autogrow-plugin-built-in/lang/en.js +0 -5
  58. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/autocomplete/skins/default.css +0 -38
  59. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/base64image/LICENSE.md +0 -1244
  60. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/base64image/README.md +0 -21
  61. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/base64image/dialogs/base64image.js +0 -766
  62. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/base64image/dialogs/base64image.original.js +0 -503
  63. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/base64image/icons/base64image.png +0 -0
  64. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/base64image/icons/hidpi/base64image.png +0 -0
  65. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/base64image/lang/da.js +0 -12
  66. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/base64image/lang/de.js +0 -12
  67. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/base64image/lang/en.js +0 -12
  68. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/base64image/plugin.js +0 -58
  69. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/base64imagepaste/plugin.js +0 -91
  70. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/clipboard/dialogs/paste.js +0 -11
  71. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/dialog/dialogDefinition.js +0 -4
  72. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/dialog/styles/dialog.css +0 -18
  73. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/dragresize/LICENSE +0 -19
  74. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/dragresize/_source.css +0 -85
  75. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/dragresize/package.json +0 -19
  76. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/dragresize/plugin.js +0 -395
  77. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/dragresize/readme.md +0 -35
  78. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/emoji/assets/iconsall.png +0 -0
  79. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/emoji/assets/iconsall.svg +0 -58
  80. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/emoji/emoji.json +0 -1
  81. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/emoji/skins/default.css +0 -237
  82. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/icons.png +0 -0
  83. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/icons_hidpi.png +0 -0
  84. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/link/dialogs/anchor.js +0 -8
  85. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/link/dialogs/link.js +0 -30
  86. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/link/images/anchor.png +0 -0
  87. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/link/images/hidpi/anchor.png +0 -0
  88. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/pastefromword/filter/default.js +0 -42
  89. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/pastetools/filter/common.js +0 -24
  90. package/dist/Resources/CKEditor-autogrow-plugin-built-in/plugins/pastetools/filter/image.js +0 -12
  91. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/dialog.css +0 -1
  92. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/dialog_ie.css +0 -1
  93. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/dialog_ie7.css +0 -1
  94. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/dialog_ie8.css +0 -1
  95. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/dialog_iequirks.css +0 -1
  96. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/dialog_opera.css +0 -1
  97. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/editor.css +0 -1
  98. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/editor_gecko.css +0 -1
  99. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/editor_ie.css +0 -1
  100. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/editor_ie7.css +0 -1
  101. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/editor_ie8.css +0 -1
  102. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/editor_iequirks.css +0 -1
  103. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/icons.png +0 -0
  104. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/icons_hidpi.png +0 -0
  105. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/images/arrow.png +0 -0
  106. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/images/close.png +0 -0
  107. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/images/hidpi/close.png +0 -0
  108. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/images/hidpi/lock-open.png +0 -0
  109. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/images/hidpi/lock.png +0 -0
  110. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/images/hidpi/refresh.png +0 -0
  111. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/images/lock-open.png +0 -0
  112. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/images/lock.png +0 -0
  113. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/images/refresh.png +0 -0
  114. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/readme.md +0 -35
  115. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/bootstrapck/skin.js +0 -10
  116. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/dialog.css +0 -5
  117. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/dialog_ie.css +0 -5
  118. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/dialog_ie8.css +0 -5
  119. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/dialog_iequirks.css +0 -5
  120. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/editor.css +0 -5
  121. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/editor_gecko.css +0 -5
  122. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/editor_ie.css +0 -5
  123. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/editor_ie8.css +0 -5
  124. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/editor_iequirks.css +0 -5
  125. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/icons.png +0 -0
  126. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/icons_hidpi.png +0 -0
  127. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/images/arrow.png +0 -0
  128. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/images/close.png +0 -0
  129. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/images/hidpi/close.png +0 -0
  130. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/images/hidpi/lock-open.png +0 -0
  131. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/images/hidpi/lock.png +0 -0
  132. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/images/hidpi/refresh.png +0 -0
  133. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/images/lock-open.png +0 -0
  134. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/images/lock.png +0 -0
  135. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/images/refresh.png +0 -0
  136. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/images/spinner.gif +0 -0
  137. package/dist/Resources/CKEditor-autogrow-plugin-built-in/skins/moono-lisa/readme.md +0 -46
  138. package/dist/Resources/CKEditor-autogrow-plugin-built-in/styles.js +0 -137
  139. package/dist/Resources/CKEditor-autogrow-plugin-built-in/vendor/promise.js +0 -13
  140. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/CHANGES.md +0 -2117
  141. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/LICENSE.md +0 -1436
  142. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/README-FitUiChanges.txt +0 -8
  143. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/README.md +0 -39
  144. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/adapters/jquery.js +0 -10
  145. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/build-config.js +0 -79
  146. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/ckeditor.js +0 -983
  147. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/config.js +0 -34
  148. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/contents.css +0 -208
  149. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/lang/da.js +0 -5
  150. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/lang/de.js +0 -5
  151. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/lang/en.js +0 -5
  152. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/autocomplete/skins/default.css +0 -38
  153. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/autogrow/plugin.js +0 -234
  154. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/base64image/LICENSE.md +0 -1244
  155. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/base64image/README.md +0 -21
  156. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/base64image/dialogs/base64image.js +0 -766
  157. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/base64image/dialogs/base64image.original.js +0 -503
  158. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/base64image/icons/base64image.png +0 -0
  159. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/base64image/icons/hidpi/base64image.png +0 -0
  160. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/base64image/lang/da.js +0 -12
  161. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/base64image/lang/de.js +0 -12
  162. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/base64image/lang/en.js +0 -12
  163. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/base64image/plugin.js +0 -58
  164. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/base64imagepaste/plugin.js +0 -91
  165. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/clipboard/dialogs/paste.js +0 -11
  166. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/dialog/dialogDefinition.js +0 -4
  167. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/dialog/styles/dialog.css +0 -18
  168. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/dragresize/LICENSE +0 -19
  169. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/dragresize/_source.css +0 -85
  170. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/dragresize/package.json +0 -19
  171. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/dragresize/plugin.js +0 -395
  172. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/dragresize/readme.md +0 -35
  173. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/emoji/assets/iconsall.png +0 -0
  174. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/emoji/assets/iconsall.svg +0 -58
  175. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/emoji/emoji.json +0 -1
  176. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/emoji/skins/default.css +0 -237
  177. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/icons.png +0 -0
  178. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/icons_hidpi.png +0 -0
  179. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/link/dialogs/anchor.js +0 -8
  180. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/link/dialogs/link.js +0 -30
  181. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/link/images/anchor.png +0 -0
  182. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/link/images/hidpi/anchor.png +0 -0
  183. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/pastefromword/filter/default.js +0 -42
  184. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/pastetools/filter/common.js +0 -24
  185. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/plugins/pastetools/filter/image.js +0 -12
  186. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/dialog.css +0 -1
  187. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/dialog_ie.css +0 -1
  188. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/dialog_ie7.css +0 -1
  189. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/dialog_ie8.css +0 -1
  190. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/dialog_iequirks.css +0 -1
  191. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/dialog_opera.css +0 -1
  192. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/editor.css +0 -1
  193. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/editor_gecko.css +0 -1
  194. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/editor_ie.css +0 -1
  195. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/editor_ie7.css +0 -1
  196. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/editor_ie8.css +0 -1
  197. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/editor_iequirks.css +0 -1
  198. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/icons.png +0 -0
  199. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/icons_hidpi.png +0 -0
  200. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/images/arrow.png +0 -0
  201. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/images/close.png +0 -0
  202. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/images/hidpi/close.png +0 -0
  203. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/images/hidpi/lock-open.png +0 -0
  204. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/images/hidpi/lock.png +0 -0
  205. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/images/hidpi/refresh.png +0 -0
  206. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/images/lock-open.png +0 -0
  207. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/images/lock.png +0 -0
  208. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/images/refresh.png +0 -0
  209. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/readme.md +0 -35
  210. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/bootstrapck/skin.js +0 -10
  211. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/dialog.css +0 -5
  212. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/dialog_ie.css +0 -5
  213. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/dialog_ie8.css +0 -5
  214. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/dialog_iequirks.css +0 -5
  215. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/editor.css +0 -5
  216. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/editor_gecko.css +0 -5
  217. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/editor_ie.css +0 -5
  218. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/editor_ie8.css +0 -5
  219. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/editor_iequirks.css +0 -5
  220. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/icons.png +0 -0
  221. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/icons_hidpi.png +0 -0
  222. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/images/arrow.png +0 -0
  223. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/images/close.png +0 -0
  224. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/images/hidpi/close.png +0 -0
  225. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/images/hidpi/lock-open.png +0 -0
  226. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/images/hidpi/lock.png +0 -0
  227. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/images/hidpi/refresh.png +0 -0
  228. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/images/lock-open.png +0 -0
  229. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/images/lock.png +0 -0
  230. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/images/refresh.png +0 -0
  231. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/images/spinner.gif +0 -0
  232. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/skins/moono-lisa/readme.md +0 -46
  233. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/styles.js +0 -137
  234. package/dist/Resources/CKEditor-autogrow-plugin-externally-loaded/vendor/promise.js +0 -13
package/dist/Fit.UI.js CHANGED
@@ -648,7 +648,7 @@ Fit._internal =
648
648
  {
649
649
  Core:
650
650
  {
651
- VersionInfo: { Major: 2, Minor: 7, Patch: 0 } // Do NOT modify format - version numbers are programmatically changed when releasing new versions - MUST be on a separate line!
651
+ VersionInfo: { Major: 2, Minor: 8, Patch: 1 } // Do NOT modify format - version numbers are programmatically changed when releasing new versions - MUST be on a separate line!
652
652
  }
653
653
  };
654
654
 
@@ -3223,7 +3223,10 @@ Fit.Controls.ControlBase = function(controlId)
3223
3223
  }
3224
3224
 
3225
3225
  /// <function container="Fit.Controls.ControlBase" name="Focused" access="public" returns="boolean">
3226
- /// <description> Get/set value indicating whether control has focus </description>
3226
+ /// <description>
3227
+ /// Get/set value indicating whether control has focus.
3228
+ /// Control must be rooted in DOM and be visible for control to gain focus.
3229
+ /// </description>
3227
3230
  /// <param name="value" type="boolean" default="undefined"> If defined, True assigns focus, False removes focus (blur) </param>
3228
3231
  /// </function>
3229
3232
  this.Focused = function(val)
@@ -4141,6 +4144,11 @@ Fit.Controls.ControlBase = function(controlId)
4141
4144
  if (me === null) // Disposed while focused (e.g. from an onscroll event handler)
4142
4145
  return;
4143
4146
 
4147
+ // Make sure OnBlur does not fire unless OnFocus was fired first. This prevents OnBlur from firing
4148
+ // if a disabled control allow some elements to gain focus such as links via tab navigation.
4149
+ if (hasFocus === false)
4150
+ return;
4151
+
4144
4152
  if (focusStateLocked === true)
4145
4153
  return;
4146
4154
 
@@ -4480,7 +4488,7 @@ Fit.Controls.DirtyCheckAll = function(scope)
4480
4488
  // visible when interacting with controls on the screen.
4481
4489
  // </member>
4482
4490
  // </container>
4483
- Fit._internal.ControlBase.ReduceDocumentRootPollution = true;
4491
+ Fit._internal.ControlBase.ReduceDocumentRootPollution = false;
4484
4492
  /// <container name="Fit.Cookies">
4485
4493
  /// Cookie functionality.
4486
4494
  /// Set/Get/Remove functions can be invoked as static members, or an instance of Fit.Cookies
@@ -11388,6 +11396,7 @@ Fit.Controls.Button = function(controlId)
11388
11396
  }
11389
11397
  else
11390
11398
  {
11399
+ me.Focused(false);
11391
11400
  Fit.Dom.Attribute(element, "tabindex", null);
11392
11401
  }
11393
11402
 
@@ -11812,6 +11821,7 @@ Fit.Controls.CheckBox = function(ctlId)
11812
11821
  }
11813
11822
  else
11814
11823
  {
11824
+ me.Focused(false);
11815
11825
  Fit.Dom.Attribute(me.GetDomElement(), "tabindex", null);
11816
11826
  }
11817
11827
 
@@ -14011,6 +14021,12 @@ Fit.Controls.DatePicker = function(ctlId)
14011
14021
 
14012
14022
  datepicker.datepicker("show");
14013
14023
 
14024
+ // Allow light dismissable panels/callouts to prevent close/dismiss
14025
+ // when interacting with calendar widget hosted outside of panels/callouts,
14026
+ // by detecting the presence of a data-disable-light-dismiss="true" attribute.
14027
+ var calendarWidget = document.getElementById("fitui-datepicker-div");
14028
+ Fit.Dom.Data(calendarWidget, "disable-light-dismiss", "true");
14029
+
14014
14030
  moveCalenderWidgetLocally();
14015
14031
 
14016
14032
  if (focused === inputTime)
@@ -20982,6 +20998,11 @@ Fit.Controls.FilePicker = function(ctlId)
20982
20998
  {
20983
20999
  me._internal.Data("enabled", val.toString());
20984
21000
 
21001
+ if (val === false)
21002
+ {
21003
+ me.Focused(false);
21004
+ }
21005
+
20985
21006
  if (inputs.length === 0) // Modern control
20986
21007
  {
20987
21008
  input.disabled = !val;
@@ -21618,12 +21639,26 @@ Fit.Controls.Input = function(ctlId)
21618
21639
  var input = null;
21619
21640
  var cmdResize = null;
21620
21641
  var designEditor = null;
21642
+ var designEditorDom = null; // DOM elements within CKEditor which we rely on - some <div> elements become <span> elements in older browsers
21643
+ /*{
21644
+ OuterContainer: null, // <div class="cke">
21645
+ InnerContainer: null, // <div class="cke_inner">
21646
+ Top: null, // <span class="cke_top">
21647
+ Content: null, // <div class="cke_contents">
21648
+ Editable: null, // <div class="cke_editable">
21649
+ Bottom: null // <span class="cke_bottom">
21650
+ }*/
21621
21651
  var designEditorDirty = false;
21622
21652
  var designEditorDirtyPending = false;
21623
21653
  var designEditorConfig = null;
21654
+ var designEditorReloadConfig = null;
21624
21655
  var designEditorRestoreButtonState = null;
21625
21656
  var designEditorSuppressPaste = false;
21626
21657
  var designEditorSuppressOnResize = false;
21658
+ var designEditorMustReloadWhenReady = false;
21659
+ var designEditorMustDisposeWhenReady = false;
21660
+ var designEditorUpdateSizeDebouncer = -1;
21661
+ var designEditorActiveToolbarPanel = null; // { DomElement: HTMLElement, UnlockFocusStateIfEmojiPanelIsClosed: function, CloseEmojiPanel: function }
21627
21662
  //var htmlWrappedInParagraph = false;
21628
21663
  var wasAutoChangedToMultiLineMode = false; // Used to revert to single line if multi line was automatically enabled along with DesignMode(true), Maximizable(true), or Resizable(true)
21629
21664
  var minimizeHeight = -1;
@@ -21632,13 +21667,13 @@ Fit.Controls.Input = function(ctlId)
21632
21667
  var maximizeHeightConfigured = -1;
21633
21668
  var resizable = Fit.Controls.InputResizing.Disabled;
21634
21669
  var nativeResizableAvailable = false; // Updated in init()
21635
- var mutationObserverId = -1;
21636
- var rootedEventId = -1;
21637
- var createWhenReadyIntervalId = -1;
21670
+ var mutationObserverId = -1; // Specific to DesignMode
21671
+ var rootedEventId = -1; // Specific to DesignMode
21672
+ var createWhenReadyIntervalId = -1; // Specific to DesignMode
21638
21673
  var isIe8 = (Fit.Browser.GetInfo().Name === "MSIE" && Fit.Browser.GetInfo().Version === 8);
21639
21674
  var debounceOnChangeTimeout = -1;
21640
21675
  var debouncedOnChange = null;
21641
- var imageBlobUrls = [];
21676
+ var imageBlobUrls = []; // Specific to DesignMode
21642
21677
 
21643
21678
  // ============================================
21644
21679
  // Init
@@ -21671,7 +21706,7 @@ Fit.Controls.Input = function(ctlId)
21671
21706
  // Scroll to bottom if nearby, to make sure text does not collide with maximize button.
21672
21707
  // Extra padding-bottom is added inside control to allow for spacing between text and maximize button.
21673
21708
 
21674
- var scrollContainer = designEditor !== null ? designEditor.container.$.querySelector("div.cke_editable") : input;
21709
+ var scrollContainer = designEditorDom && designEditorDom.Editable || input;
21675
21710
  var autoScrollToBottom = scrollContainer.scrollTop + scrollContainer.clientHeight > scrollContainer.scrollHeight - 15; // True when at bottom or very close (15px buffer)
21676
21711
 
21677
21712
  if (autoScrollToBottom === true)
@@ -21701,7 +21736,6 @@ Fit.Controls.Input = function(ctlId)
21701
21736
  me._internal.Data("maximized", "false");
21702
21737
  me._internal.Data("resizable", resizable.toLowerCase());
21703
21738
  me._internal.Data("resized", "false");
21704
- me._internal.Data("autogrow", "false");
21705
21739
  me._internal.Data("designmode", "false");
21706
21740
 
21707
21741
  Fit.Internationalization.OnLocaleChanged(localize);
@@ -21719,18 +21753,22 @@ Fit.Controls.Input = function(ctlId)
21719
21753
  }
21720
21754
 
21721
21755
  fireOnChange(); // Only fires OnChange if value has actually changed
21756
+ });
21722
21757
 
21723
- // Restore editor's toolbar buttons in case they were temporarily disabled
21724
-
21725
- if (designEditor !== null)
21726
- {
21727
- restoreDesignEditorButtons();
21728
- }
21758
+ me.OnFocus(function()
21759
+ {
21760
+ restoreHiddenToolbarInDesignEditor(); // Make toolbar appear if currently hidden
21761
+ updateDesignEditorPlaceholder(true); // Clear placeholder text
21762
+ });
21763
+ me.OnBlur(function()
21764
+ {
21765
+ restoreDesignEditorButtons(); // Restore (enable) editor's toolbar buttons in case they were temporarily disabled
21766
+ updateDesignEditorPlaceholder(); // Show placeholder text if control value is empty
21729
21767
  });
21730
21768
 
21731
21769
  Fit.Events.AddHandler(me.GetDomElement(), "paste", true, function(e)
21732
21770
  {
21733
- if (designEditor !== null && designEditorSuppressPaste === true)
21771
+ if (me.DesignMode() === true && designEditorSuppressPaste === true)
21734
21772
  {
21735
21773
  Fit.Events.Stop(e);
21736
21774
  }
@@ -21758,14 +21796,27 @@ Fit.Controls.Input = function(ctlId)
21758
21796
  {
21759
21797
  me._internal.Data("enabled", val === true ? "true" : "false");
21760
21798
 
21799
+ if (val === false)
21800
+ {
21801
+ me.Focused(false);
21802
+ }
21803
+
21761
21804
  input.disabled = val === false;
21762
21805
 
21763
- if (designEditor !== null && designEditor._isReadyForInteraction === true) // ReadOnly mode will be set when instance is ready, if not ready at this time
21806
+ if (designModeEnabledAndReady() === true) // ReadOnly mode will be set when instance is ready, if not ready at this time
21764
21807
  {
21765
21808
  designEditor.setReadOnly(input.disabled);
21766
21809
 
21767
- // Unfortunately there is no API for changing the tabIndex
21768
- designEditor.container.$.querySelector("[contenteditable]").tabIndex = input.disabled === true ? -1 : 0;
21810
+ // Set tabindex to allow or disallow focus. Unfortunately there is no editor API for changing the tabindex.
21811
+ // Preventing focus is only possible by nullifying DOM attribute (these does not work: delete elm.tabIndex; elm.tabIndex = null|undefined|-1).
21812
+ Fit.Dom.Attribute(designEditorDom.Editable, "tabindex", input.disabled === true ? null : "0");
21813
+
21814
+ // Prevent control from losing focus when HTML editor is initialized,
21815
+ // e.g. if Design Mode is enabled when ordinary input control gains focus.
21816
+ // This also prevents control from losing focus if toolbar is clicked without
21817
+ // hitting a button. A value of -1 makes it focusable, but keeps it out of
21818
+ // tab flow (keyboard navigation). Also set when DesignMode(true) is called.
21819
+ Fit.Dom.Attribute(me.GetDomElement(), "tabindex", input.disabled !== true && me.DesignMode() === true ? "-1" : null); // Remove tabindex used to prevent control from losing focus when clicking toolbar buttons, as it will allow control to gain focus when clicked using the mouse
21769
21820
  }
21770
21821
 
21771
21822
  me._internal.UpdateInternalState();
@@ -21780,7 +21831,19 @@ Fit.Controls.Input = function(ctlId)
21780
21831
  {
21781
21832
  Fit.Validation.ExpectBoolean(focus, true);
21782
21833
 
21783
- var elm = ((designEditor !== null) ? designEditor : input); // Notice: designEditor is an instance of CKEditor, not a DOM element
21834
+ elm = input;
21835
+
21836
+ if (me.DesignMode() === true)
21837
+ {
21838
+ if (designModeEnabledAndReady() === true)
21839
+ {
21840
+ elm = designEditor; // Notice: designEditor is an instance of CKEditor, not a DOM element, but it does expose a focus() function
21841
+ }
21842
+ else
21843
+ {
21844
+ elm = me.GetDomElement(); // Editor not loaded yet - focus control container temporarily - focus is later moved to editable area once instanceReady handler is invoked
21845
+ }
21846
+ }
21784
21847
 
21785
21848
  if (Fit.Validation.IsSet(focus) === true)
21786
21849
  {
@@ -21797,7 +21860,7 @@ Fit.Controls.Input = function(ctlId)
21797
21860
  }
21798
21861
  else // Remove focus
21799
21862
  {
21800
- if (designEditor !== null)
21863
+ if (designModeEnabledAndReady() === true)
21801
21864
  {
21802
21865
  if (Fit._internal.Controls.Input.ActiveEditorForDialog === me)
21803
21866
  {
@@ -21841,6 +21904,11 @@ Fit.Controls.Input = function(ctlId)
21841
21904
  }
21842
21905
  else
21843
21906
  {
21907
+ if (designEditorActiveToolbarPanel !== null)
21908
+ {
21909
+ designEditorActiveToolbarPanel.CloseEmojiPanel(); // Returns focus to editor and nullifies designEditorActiveToolbarPanel
21910
+ }
21911
+
21844
21912
  // Make sure this control is focused so that one control instance can not
21845
21913
  // be used to accidentially remove focus from another control instance.
21846
21914
  if (Fit.Dom.Contained(me.GetDomElement(), Fit.Dom.GetFocused()) === true)
@@ -21857,7 +21925,7 @@ Fit.Controls.Input = function(ctlId)
21857
21925
  }
21858
21926
  }
21859
21927
 
21860
- if (designEditor !== null)
21928
+ if (me.DesignMode() === true)
21861
21929
  {
21862
21930
  // If a dialog is open and it belongs to this control instance, and focus is found within dialog, then control is considered having focus.
21863
21931
  // However, if <body> is focused while dialog is open, control is also considered to have focus, since dialog temporarily assigns focus to
@@ -21865,7 +21933,12 @@ Fit.Controls.Input = function(ctlId)
21865
21933
  if (Fit._internal.Controls.Input.ActiveEditorForDialog === me && (Fit.Dom.Contained(Fit._internal.Controls.Input.ActiveDialogForEditor.getElement().$, Fit.Dom.GetFocused()) === true || Fit.Dom.GetFocused() === document.body))
21866
21934
  return true;
21867
21935
 
21868
- return Fit.Dom.Contained(me.GetDomElement(), Fit.Dom.GetFocused());
21936
+ // If a toolbar dialog/callout is open and contains the element currently having focus, then control is considered having focus.
21937
+ // If the dialog/callout contains an iframe in which an element has focus, then the iframe is considered focused in the main window.
21938
+ if (designEditorActiveToolbarPanel !== null && Fit.Dom.Contained(designEditorActiveToolbarPanel.DomElement, Fit.Dom.GetFocused()) === true)
21939
+ return true;
21940
+
21941
+ return Fit.Dom.GetFocused() === me.GetDomElement() || Fit.Dom.Contained(me.GetDomElement(), Fit.Dom.GetFocused());
21869
21942
  }
21870
21943
 
21871
21944
  return (Fit.Dom.GetFocused() === elm);
@@ -21889,7 +21962,7 @@ Fit.Controls.Input = function(ctlId)
21889
21962
  /*if (val.indexOf("<p>") === 0)
21890
21963
  htmlWrappedInParagraph = true; // Indicates that val is comparable with value from CKEditor which wraps content in paragraphs*/
21891
21964
 
21892
- if (designEditor !== null)
21965
+ if (designModeEnabledAndReady() === true)
21893
21966
  {
21894
21967
  // NOTICE: Invalid HTML is removed, so an all invalid HTML string will be discarded
21895
21968
  // by the editor, resulting in the editor's getData() function returning an empty string.
@@ -21900,6 +21973,8 @@ Fit.Controls.Input = function(ctlId)
21900
21973
  {
21901
21974
  CKEDITOR.instances[me.GetId() + "_DesignMode"].setData(val);
21902
21975
  });
21976
+
21977
+ updateDesignEditorPlaceholder();
21903
21978
  }
21904
21979
  else
21905
21980
  {
@@ -21930,7 +22005,7 @@ Fit.Controls.Input = function(ctlId)
21930
22005
  me._internal.FireOnChange();
21931
22006
  }
21932
22007
 
21933
- if (designEditor !== null)
22008
+ if (designModeEnabledAndReady() === true)
21934
22009
  {
21935
22010
  // If user has not changed value, then return the value initially set.
21936
22011
  // CKEditor may change (optimize) HTML when applied, but we always want
@@ -21963,7 +22038,7 @@ Fit.Controls.Input = function(ctlId)
21963
22038
  // See documentation on ControlBase
21964
22039
  this.UserValue = Fit.Core.CreateOverride(this.UserValue, function(val)
21965
22040
  {
21966
- if (Fit.Validation.IsSet(val) === true && designEditor !== null)
22041
+ if (Fit.Validation.IsSet(val) === true && me.DesignMode() === true)
21967
22042
  {
21968
22043
  designEditorDirtyPending = true;
21969
22044
  }
@@ -21974,7 +22049,7 @@ Fit.Controls.Input = function(ctlId)
21974
22049
  // See documentation on ControlBase
21975
22050
  this.IsDirty = function()
21976
22051
  {
21977
- if (designEditor !== null)
22052
+ if (me.DesignMode() === true)
21978
22053
  {
21979
22054
  // Never do value comparison in DesignMode.
21980
22055
  // A value such as "Hello world" could have been provided,
@@ -22008,6 +22083,38 @@ Fit.Controls.Input = function(ctlId)
22008
22083
  {
22009
22084
  // This will destroy control - it will no longer work!
22010
22085
 
22086
+ if (me.DesignMode() === true && designModeEnabledAndReady() === false) // DesignMode is enabled but editor is not done loading/initializing
22087
+ {
22088
+ // WARNING: This has the potential to leak memory if editor never loads and resumes task of disposing control!
22089
+ designEditorMustDisposeWhenReady = true;
22090
+
22091
+ // Editor was disposed while loading/initializing.
22092
+ // Postpone destruction of control to make sure we can clean up resources
22093
+ // reliably once editor is ready. We know that CKEditor does not dispose properly
22094
+ // unless fully loaded (it may leave an instance on the global CKEDITOR object or even fail).
22095
+ Fit.Browser.Debug("WARNING: Attempting to dispose Input control '" + me.GetId() + "' while initializing DesignMode! Control will be disposed later.");
22096
+
22097
+ // Do not keep control in user interface when disposed.
22098
+ // Mount control in document root and move it off screen (outside visible
22099
+ // viewport area). CKEditor will fail initialization if not mounted in DOM.
22100
+ me.Render(document.body);
22101
+ me.GetDomElement().style.position = "fixed";
22102
+ me.GetDomElement().style.left = "0px";
22103
+ me.GetDomElement().style.bottom = "-100px";
22104
+ me.GetDomElement().style.maxHeight = "100px";
22105
+
22106
+ // Detect memory leak
22107
+ /* setTimeout(function()
22108
+ {
22109
+ if (me !== null)
22110
+ {
22111
+ Fit.Browser.Debug("WARNING: Input in DesignMode was not properly disposed in time - potential memory leak detected");
22112
+ }
22113
+ }, 5000); // Usually the load time for an editor is barely measurable, so 5 seconds seems sufficient */
22114
+
22115
+ return;
22116
+ }
22117
+
22011
22118
  var curVal = designEditorConfig !== null && designEditorConfig.Plugins && designEditorConfig.Plugins.Images && designEditorConfig.Plugins.Images.RevokeBlobUrlsOnDispose === "UnreferencedOnly" ? me.Value() : null;
22012
22119
 
22013
22120
  if (Fit._internal.Controls.Input.ActiveEditorForDialog === me)
@@ -22051,11 +22158,16 @@ Fit.Controls.Input = function(ctlId)
22051
22158
  // Fit._internal.Controls.Input.ActiveDialogForEditor;
22052
22159
  // Fit._internal.Controls.Input.ActiveDialogForEditorCanceled;
22053
22160
 
22054
- designEditor.destroy();
22161
+ destroyDesignEditorInstance(); // Destroys editor and stops related mutation observers, timers, etc.
22055
22162
  }
22056
22163
 
22057
22164
  Fit.Internationalization.RemoveOnLocaleChanged(localize);
22058
22165
 
22166
+ /*if (designEditorUpdateSizeDebouncer !== -1)
22167
+ {
22168
+ clearTimeout(designEditorUpdateSizeDebouncer);
22169
+ }
22170
+
22059
22171
  if (mutationObserverId !== -1)
22060
22172
  {
22061
22173
  Fit.Events.RemoveMutationObserver(mutationObserverId);
@@ -22069,7 +22181,7 @@ Fit.Controls.Input = function(ctlId)
22069
22181
  if (createWhenReadyIntervalId !== -1)
22070
22182
  {
22071
22183
  clearInterval(createWhenReadyIntervalId);
22072
- }
22184
+ }*/
22073
22185
 
22074
22186
  if (debouncedOnChange !== null)
22075
22187
  {
@@ -22094,7 +22206,7 @@ Fit.Controls.Input = function(ctlId)
22094
22206
  });
22095
22207
  }
22096
22208
 
22097
- me = orgVal = preVal = input = cmdResize = designEditor = designEditorDirty = designEditorDirtyPending = designEditorConfig = designEditorRestoreButtonState = designEditorSuppressPaste = designEditorSuppressOnResize /*= htmlWrappedInParagraph*/ = wasAutoChangedToMultiLineMode = minimizeHeight = maximizeHeight = minMaxUnit = maximizeHeightConfigured = resizable = nativeResizableAvailable = mutationObserverId = rootedEventId = createWhenReadyIntervalId = isIe8 = debounceOnChangeTimeout = debouncedOnChange = imageBlobUrls = null;
22209
+ me = orgVal = preVal = input = cmdResize = designEditor = designEditorDom = designEditorDirty = designEditorDirtyPending = designEditorConfig = designEditorReloadConfig = designEditorRestoreButtonState = designEditorSuppressPaste = designEditorSuppressOnResize = designEditorMustReloadWhenReady = designEditorMustDisposeWhenReady = designEditorUpdateSizeDebouncer = designEditorActiveToolbarPanel /*= htmlWrappedInParagraph*/ = wasAutoChangedToMultiLineMode = minimizeHeight = maximizeHeight = minMaxUnit = maximizeHeightConfigured = resizable = nativeResizableAvailable = mutationObserverId = rootedEventId = createWhenReadyIntervalId = isIe8 = debounceOnChangeTimeout = debouncedOnChange = imageBlobUrls = null;
22098
22210
 
22099
22211
  base();
22100
22212
  });
@@ -22132,20 +22244,37 @@ Fit.Controls.Input = function(ctlId)
22132
22244
  }
22133
22245
 
22134
22246
  me._internal.Data("resized", "false");
22135
- me._internal.Data("autogrow", "false");
22247
+ me._internal.Data("autogrow", me.DesignMode() === true ? "false" : null);
22136
22248
 
22137
- if (val === -1 && designEditor !== null) // Enable auto grow
22249
+ var autoGrowEnabled = false;
22250
+ if (val === -1 && designModeEnabledAndReady() === true) // Enable auto grow if editor is loaded and ready - otherwise enabled in instanceReady handler
22138
22251
  {
22139
22252
  // A value of -1 is used to reset control height (assume default height).
22140
22253
  // In DesignMode we want the control height to adjust to the content of the editor in this case.
22141
22254
  // The editor's ability to adjust to the HTML content is handled in updateDesignEditorSize() below.
22142
22255
  // Auto grow can also be enabled using configuration object passed to DesignMode(true, config).
22143
22256
  me._internal.Data("autogrow", "true"); // Make control container adjust to editor's height
22257
+ autoGrowEnabled = true;
22258
+ }
22259
+
22260
+ var hideToolbarAgain = false;
22261
+ if (isToolbarHiddenInDesignEditor() === true)
22262
+ {
22263
+ // If in DesignMode, temporarily restore toolbar to allow update to height.
22264
+ // When toolbar is hidden, a fixed height is set on the editable area which
22265
+ // prevent changes to control height.
22266
+ restoreHiddenToolbarInDesignEditor();
22267
+ hideToolbarAgain = true;
22144
22268
  }
22145
22269
 
22146
22270
  var h = base(val, unit);
22147
22271
  updateDesignEditorSize();
22148
22272
 
22273
+ if (hideToolbarAgain === true)
22274
+ {
22275
+ hideToolbarInDesignMode();
22276
+ }
22277
+
22149
22278
  // Calculate new maximize height if control is maximizable
22150
22279
  if (me.Maximizable() === true && suppressMinMax !== true)
22151
22280
  {
@@ -22154,7 +22283,7 @@ Fit.Controls.Input = function(ctlId)
22154
22283
  minMaxUnit = h.Unit;
22155
22284
  }
22156
22285
 
22157
- if (val === -1 && designEditor !== null) // Auto grow enabled
22286
+ if (autoGrowEnabled === true) // Repaint in case auto grow was enabled above
22158
22287
  {
22159
22288
  repaint();
22160
22289
  }
@@ -22178,6 +22307,7 @@ Fit.Controls.Input = function(ctlId)
22178
22307
  if (Fit.Validation.IsSet(val) === true)
22179
22308
  {
22180
22309
  input.placeholder = val;
22310
+ updateDesignEditorPlaceholder();
22181
22311
  }
22182
22312
 
22183
22313
  return (input.placeholder ? input.placeholder : "");
@@ -22291,6 +22421,12 @@ Fit.Controls.Input = function(ctlId)
22291
22421
 
22292
22422
  if (Fit.Validation.IsSet(val) === true)
22293
22423
  {
22424
+ if (me.DesignMode() === true && designModeEnabledAndReady() === false)
22425
+ {
22426
+ console.error("MultiLine(boolean) is not allowed for Input control '" + me.GetId() + "' while DesignMode editor is initializing!");
22427
+ return false; // Return current un-modified state - Input control is not in MultiLine mode when DesignMode is enabled
22428
+ }
22429
+
22294
22430
  if (me.DesignMode() === true)
22295
22431
  me.DesignMode(false);
22296
22432
 
@@ -22385,7 +22521,7 @@ Fit.Controls.Input = function(ctlId)
22385
22521
  }
22386
22522
  }
22387
22523
 
22388
- return (input.tagName === "TEXTAREA" && designEditor === null);
22524
+ return (input.tagName === "TEXTAREA" && me.DesignMode() === false);
22389
22525
  }
22390
22526
 
22391
22527
  /// <function container="Fit.Controls.Input" name="Resizable" access="public" returns="Fit.Controls.InputResizing">
@@ -22413,7 +22549,7 @@ Fit.Controls.Input = function(ctlId)
22413
22549
  //Fit.Browser.Log("Maximizable disabled as Resizable was enabled!");
22414
22550
  }
22415
22551
 
22416
- if (me.MultiLine() === false && designEditor === null)
22552
+ if (me.MultiLine() === false && me.DesignMode() === false)
22417
22553
  {
22418
22554
  me.MultiLine(true);
22419
22555
  wasAutoChangedToMultiLineMode = true;
@@ -22481,7 +22617,7 @@ Fit.Controls.Input = function(ctlId)
22481
22617
  //Fit.Browser.Log("Resizable disabled as Maximizable was enabled!");
22482
22618
  }
22483
22619
 
22484
- if (me.MultiLine() === false && designEditor === null)
22620
+ if (me.MultiLine() === false && me.DesignMode() === false)
22485
22621
  {
22486
22622
  me.MultiLine(true);
22487
22623
  wasAutoChangedToMultiLineMode = true;
@@ -22550,7 +22686,7 @@ Fit.Controls.Input = function(ctlId)
22550
22686
  {
22551
22687
  Fit.Validation.ExpectBoolean(val, true);
22552
22688
 
22553
- var autoGrowEnabled = me.Height().Value === -1 && designEditor !== null;
22689
+ var autoGrowEnabled = me.Height().Value === -1 && me.DesignMode() === true;
22554
22690
 
22555
22691
  if (Fit.Validation.IsSet(val) === true && me.Maximizable() === true && autoGrowEnabled === false)
22556
22692
  {
@@ -22615,10 +22751,13 @@ Fit.Controls.Input = function(ctlId)
22615
22751
  /// <member name="Links" type="boolean" default="undefined"> Enable links (defaults to True) </member>
22616
22752
  /// <member name="Emojis" type="boolean" default="undefined"> Enable emoji button (defaults to False) </member>
22617
22753
  /// <member name="Images" type="boolean" default="undefined"> Enable image button (defaults to false) </member>
22754
+ /// <member name="Position" type="'Top' | 'Bottom'" default="undefined"> Toolbar position (defaults to Top) </member>
22755
+ /// <member name="Sticky" type="boolean" default="undefined"> Make toolbar stick to edge of scroll container on supported browsers when scrolling (defaults to False) </member>
22756
+ /// <member name="HideInitially" type="boolean" default="undefined"> Hide toolbar until control gains focus (defaults to False) </member>
22618
22757
  /// </container>
22619
22758
 
22620
22759
  /// <container name="Fit.Controls.InputTypeDefs.DesignModeConfigInfoPanel">
22621
- /// <description> Information panel at the bottom of the editor </description>
22760
+ /// <description> Information panel at the top or bottom of the editor, depending on the location of the toolbar </description>
22622
22761
  /// <member name="Text" type="string" default="undefined"> Text to display </member>
22623
22762
  /// <member name="Alignment" type="'Left' | 'Center' | 'Right'" default="undefined"> Text alignment - defaults to Center </member>
22624
22763
  /// </container>
@@ -22740,6 +22879,7 @@ Fit.Controls.Input = function(ctlId)
22740
22879
  /// <member name="Enabled" type="boolean"> Flag indicating whether auto grow feature is enabled or not - on by default if no height is set, or if Height(-1) is set </member>
22741
22880
  /// <member name="MinimumHeight" type="{ Value: number, Unit?: Fit.TypeDefs.CssUnit }" default="undefined"> Minimum height of editable area </member>
22742
22881
  /// <member name="MaximumHeight" type="{ Value: number, Unit?: Fit.TypeDefs.CssUnit }" default="undefined"> Maximum height of editable area </member>
22882
+ /// <member name="PreventResizeBeyondMaximumHeight" type="boolean" default="undefined"> Prevent user from resizing editor beyond maximum height (see MaximumHeight property - defaults to False) </member>
22743
22883
  /// </container>
22744
22884
 
22745
22885
  /// <container name="Fit.Controls.InputTypeDefs.DesignModeConfig">
@@ -22779,6 +22919,9 @@ Fit.Controls.Input = function(ctlId)
22779
22919
  Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Links, true);
22780
22920
  Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Emojis, true);
22781
22921
  Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Images, true);
22922
+ Fit.Validation.ExpectStringValue(((editorConfig || {}).Toolbar || {}).Position, true);
22923
+ Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Sticky, true);
22924
+ Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).HideInitially, true);
22782
22925
  Fit.Validation.ExpectObject((editorConfig || {}).InfoPanel, true);
22783
22926
  Fit.Validation.ExpectString(((editorConfig || {}).InfoPanel || {}).Text, true);
22784
22927
  Fit.Validation.ExpectString(((editorConfig || {}).InfoPanel || {}).Alignment, true);
@@ -22791,6 +22934,7 @@ Fit.Controls.Input = function(ctlId)
22791
22934
  Fit.Validation.ExpectObject(((editorConfig || {}).AutoGrow || {}).MaximumHeight, true);
22792
22935
  Fit.Validation.ExpectNumber((((editorConfig || {}).AutoGrow || {}).MaximumHeight || {}).Value, true);
22793
22936
  Fit.Validation.ExpectStringValue((((editorConfig || {}).AutoGrow || {}).MaximumHeight || {}).Unit, true);
22937
+ Fit.Validation.ExpectBoolean(((editorConfig || {}).AutoGrow || {}).PreventResizeBeyondMaximumHeight, true);
22794
22938
 
22795
22939
  if (editorConfig && editorConfig.Tags)
22796
22940
  {
@@ -22815,12 +22959,9 @@ Fit.Controls.Input = function(ctlId)
22815
22959
  if (Fit._internal.Controls.Input.ActiveEditorForDialog === me && Fit._internal.Controls.Input.ActiveEditorForDialogDisabledPostponed === true)
22816
22960
  designMode = false; // Not considered in Design Mode if scheduled to be disabled (postponed because a dialog is currently loading)
22817
22961
 
22818
- if (val === true && designMode === false)
22962
+ if ((val === true && designMode === false) || (val === true && Fit.Validation.IsSet(editorConfig) === true && Fit.Core.IsEqual(editorConfig, designEditorConfig) === false))
22819
22963
  {
22820
- if (Fit.Validation.IsSet(editorConfig) === true)
22821
- {
22822
- designEditorConfig = editorConfig;
22823
- }
22964
+ var configUpdated = designMode === true; // Already in DesignMode which means editorConfig was changed
22824
22965
 
22825
22966
  if (Fit._internal.Controls.Input.ActiveEditorForDialog === me)
22826
22967
  {
@@ -22828,7 +22969,22 @@ Fit.Controls.Input = function(ctlId)
22828
22969
  // for dialog to finish loading, so DesignMode can be disabled (scheduled).
22829
22970
  // Remove flag responsible for disabling DesignMode so it remains an editor.
22830
22971
  delete Fit._internal.Controls.Input.ActiveEditorForDialogDisabledPostponed;
22831
- return;
22972
+
22973
+ if (configUpdated === false)
22974
+ {
22975
+ return true;
22976
+ }
22977
+ }
22978
+
22979
+ if (configUpdated === true)
22980
+ {
22981
+ reloadEditor(false, Fit.Core.Clone(editorConfig)); // Clone to prevent external code from making changes later
22982
+ return true;
22983
+ }
22984
+
22985
+ if (Fit.Validation.IsSet(editorConfig) === true)
22986
+ {
22987
+ designEditorConfig = Fit.Core.Clone(editorConfig); // Clone to prevent external code from making changes later
22832
22988
  }
22833
22989
 
22834
22990
  if (me.MultiLine() === false)
@@ -22837,6 +22993,27 @@ Fit.Controls.Input = function(ctlId)
22837
22993
  wasAutoChangedToMultiLineMode = true;
22838
22994
  }
22839
22995
 
22996
+ me._internal.Data("designmode", "true");
22997
+ me._internal.Data("toolbar", designEditorConfig !== null && designEditorConfig.Toolbar && designEditorConfig.Toolbar.HideInitially === true ? "false" : "true");
22998
+ me._internal.Data("toolbar-position", designEditorConfig !== null && designEditorConfig.Toolbar && designEditorConfig.Toolbar.Position === "Bottom" ? "bottom" : "top");
22999
+ me._internal.Data("toolbar-sticky", designEditorConfig !== null && designEditorConfig.Toolbar && designEditorConfig.Toolbar.Sticky === true ? "true" : "false");
23000
+
23001
+ // Prevent control from losing focus when HTML editor is initialized,
23002
+ // e.g. if Design Mode is enabled when ordinary input control gains focus.
23003
+ // This also prevents control from losing focus if toolbar is clicked without
23004
+ // hitting a button. A value of -1 makes it focusable, but keeps it out of
23005
+ // tab flow (keyboard navigation). Also set when Enabled(true) is called.
23006
+ me.GetDomElement().tabIndex = -1; // TabIndex is removed if DesignMode is disabled (DesignMode(false)) or if control is disabled (Enabled(false))
23007
+
23008
+ if (me.Focused() === true)
23009
+ {
23010
+ // Move focus from input to control's outer container (tabindex
23011
+ // set above) to keep focus while editor is loading/initializing.
23012
+ // Focus is moved to editor once initialization is complete - see
23013
+ // instanceReady handler.
23014
+ me.GetDomElement().focus();
23015
+ }
23016
+
22840
23017
  input.id = me.GetId() + "_DesignMode";
22841
23018
 
22842
23019
  if (window.CKEDITOR === undefined)
@@ -22936,6 +23113,21 @@ Fit.Controls.Input = function(ctlId)
22936
23113
  return;
22937
23114
  }
22938
23115
 
23116
+ // Allow light dismissable panels/callouts to prevent close/dismiss
23117
+ // when interacting with editor dialogs hosted outside of these panels/callouts,
23118
+ // by detecting the presence of the data-disable-light-dismiss="true" attribute.
23119
+
23120
+ var ckeDialogElement = this.getElement().$;
23121
+ Fit.Dom.Data(ckeDialogElement, "disable-light-dismiss", "true");
23122
+
23123
+ var bgModalLayer = document.querySelector("div.cke_dialog_background_cover"); // Shared among instances
23124
+ if (bgModalLayer !== null) // Better safe than sorry
23125
+ {
23126
+ Fit.Dom.Data(bgModalLayer, "disable-light-dismiss", "true");
23127
+ }
23128
+
23129
+ // Reduce pollution of document root
23130
+
22939
23131
  if (Fit._internal.ControlBase.ReduceDocumentRootPollution === true)
22940
23132
  {
22941
23133
  // Move dialog to control - otherwise placed in the root of the document where it pollutes,
@@ -22955,6 +23147,41 @@ Fit.Controls.Input = function(ctlId)
22955
23147
  // 2nd+ time dialog is opened it remains invisible - make it appear and position it
22956
23148
  ckeDialogElement.style.display = !CKEDITOR.env.ie || CKEDITOR.env.edge ? "flex" : ""; // https://github.com/ckeditor/ckeditor4/blob/8b208d05d1338d046cdc8f971c9faf21604dd75d/plugins/dialog/plugin.js#L152
22957
23149
  this.layout(); // 'this' is the dialog instance - layout() positions dialog
23150
+
23151
+ // Temporarily move modal background layer next to control to ensure it is part of same
23152
+ // stacking context as control and dialog. Otherwise it might stay on top of a panel containing
23153
+ // the editor, if that panel has position:fixed (which creates a separate stacking context)
23154
+ // and a lower z-index than the background layer.
23155
+ // Be aware that the background layer also has position:fixed so it will "escape" a parent
23156
+ // container that also has position:fixed, still making it stretch from the upper left corner
23157
+ // of the screen to the lower right corner of the screen. However, if a parent is using
23158
+ // CSS transform, it will prevent the background layer from escaping, instead positioning it
23159
+ // and making it stretch from the upper left corner of the container using transform, to the
23160
+ // lower right corner of that container.
23161
+ // Also be aware that the use of transform will cause minor problems when moving/dragging dialog,
23162
+ // although that is not related to remounting of the background layer.
23163
+ var bgModalLayer = document.querySelector("div.cke_dialog_background_cover");
23164
+ if (bgModalLayer !== null) // Better safe than sorry
23165
+ {
23166
+ Fit.Dom.InsertAfter(Fit._internal.Controls.Input.ActiveEditorForDialog.GetDomElement(), bgModalLayer);
23167
+ }
23168
+
23169
+ if (ev.sender.definition.title === "Image")
23170
+ {
23171
+ // Hide image resize handles placed in the root of the document.
23172
+ // When the modal background layer above is rooted next to the control,
23173
+ // it becomes impossible to ensure the resize handles remains hidden behind
23174
+ // the background layer, since the control may be part of a stacking context
23175
+ // different from the one containing the image resize handles (document root).
23176
+ // It would require dynamic z-index values to achieve this. Therefore the
23177
+ // resize handles are temporarily hidden instead.
23178
+
23179
+ var imageResizeHandlersContainer = document.querySelector("#ckimgrsz");
23180
+ if (imageResizeHandlersContainer !== null) // Better safe than sorry
23181
+ {
23182
+ imageResizeHandlersContainer.style.display = "none";
23183
+ }
23184
+ }
22958
23185
  }
22959
23186
  });
22960
23187
 
@@ -22970,6 +23197,29 @@ Fit.Controls.Input = function(ctlId)
22970
23197
  delete Fit._internal.Controls.Input.ActiveDialogForEditor;
22971
23198
  delete Fit._internal.Controls.Input.ActiveDialogForEditorCanceled;
22972
23199
 
23200
+ if (Fit._internal.ControlBase.ReduceDocumentRootPollution === true)
23201
+ {
23202
+ // Return modal background layer to document root - it was temporarily moved
23203
+ // next to control to ensure it works properly with current stacking context.
23204
+ // See comments regarding this in dialog "show" handler registered above.
23205
+ // The background layer will not work for other editor instances if not moved back.
23206
+ var bgModalLayer = document.querySelector("div.cke_dialog_background_cover");
23207
+ if (bgModalLayer !== null) // Better safe than sorry
23208
+ {
23209
+ Fit.Dom.Add(document.body, bgModalLayer);
23210
+ }
23211
+
23212
+ // Allow image resize handlers to show up again (hidden in "show" handler registered above)
23213
+ if (ev.sender.definition.title === "Image")
23214
+ {
23215
+ var imageResizeHandlersContainer = document.querySelector("#ckimgrsz");
23216
+ if (imageResizeHandlersContainer !== null) // Better safe than sorry
23217
+ {
23218
+ imageResizeHandlersContainer.style.display = "";
23219
+ }
23220
+ }
23221
+ }
23222
+
22973
23223
  // Disable focus lock - let ControlBase handle OnFocus and OnBlur automatically again.
22974
23224
  // This is done postponed since unlocking it immediately will cause OnFocus to fire when
22975
23225
  // dialog returns focus to the editor.
@@ -23056,32 +23306,31 @@ Fit.Controls.Input = function(ctlId)
23056
23306
 
23057
23307
  var enableAutoGrow = me.Height().Value === -1 || (designEditorConfig !== null && designEditorConfig.AutoGrow && designEditorConfig.AutoGrow.Enabled === true);
23058
23308
 
23059
- if (enableAutoGrow === true && me.Height().Value !== -1)
23060
- {
23061
- me.Height(-1);
23062
- }
23063
-
23064
23309
  if (enableAutoGrow === true && me.Maximizable() === true)
23065
23310
  {
23066
- // Maximize button is disabled (using CSS) when auto grow is enabled, but we make sure to "minimize"
23067
- // control so maximize button returns to its initial state, in case control was maximized prior to
23068
- // enabling DesignMode with auto grow. Otherwise the button indicates that the control is maximized,
23069
- // and so does calls to Maximized() which will incorrectly return True.
23311
+ // Maximize button is disabled when auto grow is enabled, but we make sure to "minimize" control
23312
+ // so maximize button returns to its initial state, in case control was maximized prior to enabling
23313
+ // DesignMode with auto grow. Otherwise the button indicates that the control is maximized, and so
23314
+ // does calls to Maximized() which will incorrectly return True.
23070
23315
  me.Maximized(false);
23071
23316
  }
23072
23317
 
23073
- me._internal.Data("designmode", "true");
23074
23318
  repaint();
23075
23319
  }
23076
23320
  else if (val === false && designMode === true)
23077
23321
  {
23322
+ if (designModeEnabledAndReady() === false)
23323
+ {
23324
+ console.error("DesignMode(false) is not allowed for Input control '" + me.GetId() + "' while DesignMode editor is initializing!");
23325
+ return true; // Return current un-modified state - DesignMode remains enabled
23326
+ }
23327
+
23078
23328
  var focused = me.Focused();
23079
23329
 
23080
23330
  if (Fit._internal.Controls.Input.ActiveEditorForDialog === me)
23081
23331
  {
23082
23332
  if (Fit._internal.Controls.Input.ActiveDialogForEditor !== null)
23083
23333
  {
23084
- focused = true; // Always considered focused when a dialog is open - Focused() returns False which is actually the truth
23085
23334
  Fit._internal.Controls.Input.ActiveDialogForEditor.hide(); // Fires dialog's OnHide event
23086
23335
  }
23087
23336
  else
@@ -23104,23 +23353,29 @@ Fit.Controls.Input = function(ctlId)
23104
23353
  }
23105
23354
  }, 5000); // Usually the load time for a dialog is barely measurable, so 5 seconds seems sufficient */
23106
23355
 
23107
- return;
23356
+ return true; // Return current un-modified state - DesignMode remains enabled until dialog is done loading
23108
23357
  }
23109
23358
  }
23110
23359
 
23360
+ if (designEditorActiveToolbarPanel !== null)
23361
+ {
23362
+ designEditorActiveToolbarPanel.CloseEmojiPanel();
23363
+ }
23364
+
23111
23365
  // Destroy editor - content is automatically synchronized to input control.
23112
23366
  // Calling destroy() fires OnHide for any dialog currently open, which in turn
23113
23367
  // disables locked focus state and returns focus to the control.
23114
- if (designEditor !== null) // Will be null if DesignMode is being disabled while CKEditor resources are loading, in which case editor has not yet been created - e.g. DesignMode(true); DesignMode(false);
23115
- {
23116
- designEditor.destroy();
23117
- designEditor = null;
23118
- }
23368
+ destroyDesignEditorInstance();
23119
23369
 
23120
23370
  me._internal.Data("designmode", "false");
23121
- me._internal.Data("autogrow", "false");
23122
23371
  Fit.Dom.Data(me.GetDomElement(), "resized", "false");
23123
23372
 
23373
+ // Remove DesignMode specific data attributes
23374
+ me._internal.Data("autogrow", null);
23375
+ me._internal.Data("toolbar", null);
23376
+ me._internal.Data("toolbar-position", null);
23377
+ me._internal.Data("toolbar-sticky", null);
23378
+
23124
23379
  revertToSingleLineIfNecessary();
23125
23380
 
23126
23381
  // Remove tabindex used to prevent control from losing focus when clicking toolbar buttons
@@ -23406,22 +23661,39 @@ Fit.Controls.Input = function(ctlId)
23406
23661
  item.name = item.Title;
23407
23662
  });
23408
23663
 
23409
- resolve(items);
23664
+ resolve(items); // Opens context menu immediately if array contain elements, unless user managed to add a space after the search value while waiting for a response, in which case the context menu will not be opened
23410
23665
 
23411
- if (items.length > 0 && Fit._internal.ControlBase.ReduceDocumentRootPollution === true)
23666
+ if (items.length > 0)
23412
23667
  {
23413
- // Calling resolve(..) above immediately opens the context menu from which
23414
- // a tag can be selected. However, it is placed in the root of the document
23415
- // where it pollutes the global scope. Move it next to the Fit.UI control.
23416
- // We do not mount it within the Fit.UI control as it could cause Fit.UI styles
23417
- // to take effect on the context menu.
23668
+ // Calling resolve(..) above immediately opens the context menu from which a tag can be selected
23418
23669
 
23419
23670
  // Get the autocomplete context menu currently open. There can be only one
23420
23671
  // such menu open at any time. Each editor can declare multiple autocomplete
23421
23672
  // context menus since each tag marker is associated with its own context menu.
23422
23673
  var ctm = document.querySelector("ul.cke_autocomplete_opened");
23423
- ctm.style.position = "fixed"; // Has position:absolute by default, but this may be affected by a positioned container (offsetParent) - downside: it no longer sticks to the editor when scrolling
23424
- Fit.Dom.InsertAfter(me.GetDomElement(), ctm);
23674
+
23675
+ if (ctm !== null) // Null if user managed to enter a space after tag search value, before response was received - in this case resolve(..) above will not open the context menu
23676
+ {
23677
+ // Allow light dismissable panels/callouts to prevent close/dismiss
23678
+ // when interacting with tags context menu hosted outside of these panels/callouts,
23679
+ // by detecting the presence of the data-disable-light-dismiss="true" attribute.
23680
+ Fit.Dom.Data(ctm, "disable-light-dismiss", "true");
23681
+
23682
+ if (Fit._internal.ControlBase.ReduceDocumentRootPollution === true)
23683
+ {
23684
+ // Tags context menu is placed in the root of the document where
23685
+ // it pollutes the global scope. Move it next to the Fit.UI control.
23686
+ // We do not mount it within the Fit.UI control as it could cause Fit.UI styles
23687
+ // to take effect on the context menu.
23688
+
23689
+ // Has position:absolute by default, but this may be affected by a positioned
23690
+ // container (offsetParent), so we change it to position:fixed. Downside:
23691
+ // It no longer sticks to the editor when scrolling. However, if a container has CSS
23692
+ // transform set, the context menu's position will be affected and become inaccurate.
23693
+ ctm.style.position = "fixed";
23694
+ Fit.Dom.InsertAfter(me.GetDomElement(), ctm);
23695
+ }
23696
+ }
23425
23697
  }
23426
23698
  };
23427
23699
 
@@ -23517,19 +23789,6 @@ Fit.Controls.Input = function(ctlId)
23517
23789
  });
23518
23790
  }
23519
23791
 
23520
- // Prevent control from losing focus when HTML editor is initialized,
23521
- // e.g. if Design Mode is enabled when ordinary input control gains focus.
23522
- // This also prevents control from losing focus if toolbar is clicked without
23523
- // hitting a button. A value of -1 makes it focusable, but keeps it out of
23524
- // tab flow (keyboard navigation).
23525
- me.GetDomElement().tabIndex = -1; // TabIndex is removed if DesignMode is disabled
23526
-
23527
- var focused = me.Focused();
23528
- if (focused === true)
23529
- {
23530
- me.GetDomElement().focus(); // Outer container is focusable - tabIndex set above
23531
- }
23532
-
23533
23792
  var onImageAdded = function(args)
23534
23793
  {
23535
23794
  if (args.type === "blob")
@@ -23568,6 +23827,8 @@ Fit.Controls.Input = function(ctlId)
23568
23827
 
23569
23828
  designEditor = CKEDITOR.replace(me.GetId() + "_DesignMode",
23570
23829
  {
23830
+ toolbarLocation: designEditorConfig !== null && designEditorConfig.Toolbar && designEditorConfig.Toolbar.Position === "Bottom" ? "bottom" : "top",
23831
+ uiColor: Fit._internal.Controls.Input.Editor.Skin === "moono-lisa" || Fit._internal.Controls.Input.Editor.Skin === null ? "#FFFFFF" : undefined,
23571
23832
  //allowedContent: true, // http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules and http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent
23572
23833
  extraAllowedContent: "a[data-tag-type,data-tag-id,data-tag-data]", // https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-extraAllowedContent
23573
23834
  language: lang,
@@ -23577,7 +23838,7 @@ Fit.Controls.Input = function(ctlId)
23577
23838
  title: "",
23578
23839
  width: "100%", // Assume width of container
23579
23840
  height: me.Height().Value > -1 ? me.Height().Value + me.Height().Unit : "100%", // Height of content area - toolbar and bottom panel takes up additional space - once editor is loaded, the outer dimensions are accurately set using updateDesignEditorSize() - a height of 100% enables auto grow
23580
- startupFocus: focused === true ? "end" : false,
23841
+ startupFocus: me.Focused() === true ? "end" : false, // Doesn't work when editor is hidden while initializing to avoid flickering - focus is set again when editor is made visible in instanceReady handler, at which point it will place cursor at the end of the editor if startupFocus is set to "end"
23581
23842
  extraPlugins: plugins.join(","),
23582
23843
  clipboard_handleImages: false, // Disable native support for image pasting - allow base64imagepaste plugin to handle image data if loaded
23583
23844
  base64image: // Custom property used by base64image plugin if loaded
@@ -23595,72 +23856,189 @@ Fit.Controls.Input = function(ctlId)
23595
23856
  toolbar: toolbar,
23596
23857
  removeButtons: "", // Set to empty string to prevent CKEditor from removing buttons such as Underline
23597
23858
  mentions: mentions,
23859
+ emoji_minChars: 9999, // Impossible requirement to number of search characters to "disable" emoji auto complete menu - we cannot make it work properly with light dismissable panels/callouts since we have no event available for registering the data-disable-light-dismiss="true" attribute, and it's not very useful in any case
23598
23860
  on:
23599
23861
  {
23600
23862
  instanceReady: function()
23601
23863
  {
23602
- Fit.Dom.Data(designEditor.container.$, "skin", CKEDITOR.config.skin); // Add e.g. data-skin="bootstrapck" to editor - used in Input.css
23603
-
23604
- // Enabled state might have been changed while loading.
23605
- // Unfortunately there is no API for changing the tabIndex.
23606
- designEditor.setReadOnly(me.Enabled() === false);
23607
- designEditor.container.$.querySelector("[contenteditable]").tabIndex = me.Enabled() === false ? -1 : 0;
23864
+ designEditorDom = // Object assignment will make designModeEnabledAndReady() return True, so it must be assigned immediately
23865
+ {
23866
+ OuterContainer: designEditor.container.$,
23867
+ InnerContainer: designEditor.container.$.querySelector(".cke_inner"),
23868
+ Top: designEditor.container.$.querySelector(".cke_top"), // Null if toolbar is placed at the bottom
23869
+ Content: designEditor.container.$.querySelector(".cke_contents"),
23870
+ Editable: designEditor.container.$.querySelector(".cke_editable"),
23871
+ Bottom: designEditor.container.$.querySelector(".cke_bottom") // Only exist if editor is resizable or toolbar is placed at the bottom
23872
+ }
23608
23873
 
23609
- if (focused === true)
23874
+ // Make sure expected DOM elements are present, so we do not have to perform null checks anywhere else in the code.
23875
+ // Notice that designEditorDom.Top is null if toolbar is placed at the bottom, and designEditorDom.Bottom is null
23876
+ // unless toolbar is placed at the bottom, or editor is resizable, which adds a resize handled in the lower right corner.
23877
+ if (designEditorDom.InnerContainer === null || designEditorDom.Content === null || designEditorDom.Editable === null || (designEditorDom.Top === null && designEditorDom.Bottom === null))
23610
23878
  {
23611
- me.Focused(true); // Focus actual input area rather than outer container temporarily focused further up
23879
+ throw "One or more editor DOM elements are missing"; // This should only happen if CKEditor changes its DOM structure
23612
23880
  }
23613
23881
 
23614
- var maximized = me.Maximized(); // Call to Height(..) below will minimize control
23882
+ if (designEditorMustDisposeWhenReady === true)
23883
+ {
23884
+ Fit.Browser.Debug("WARNING: Input control '" + me.GetId() + "' was disposed while initializing DesignMode - now resuming disposal");
23885
+ me.Dispose();
23886
+ return;
23887
+ }
23615
23888
 
23616
- if (maximized === true)
23889
+ if (designEditorMustReloadWhenReady === true)
23617
23890
  {
23618
- me.Maximized(false); // Minimize to allow editor to initially assume normal height - maximized again afterwards
23891
+ Fit.Browser.Debug("WARNING: Editor for Input control '" + me.GetId() + "' finished loading, but properties affecting editor has changed while initializing - reloading to adjust to changes");
23892
+ reloadEditor(true);
23893
+ return;
23619
23894
  }
23620
23895
 
23896
+ updateDesignEditorPlaceholder(); // Show/hide placeholder - value might have been set/removed while initializing editor
23897
+
23898
+ Fit.Dom.Data(designEditorDom.OuterContainer, "skin", CKEDITOR.config.skin); // Add e.g. data-skin="bootstrapck" to editor - used in Input.css
23899
+
23900
+ // Enabled state might have been changed while loading.
23901
+ // Unfortunately there is no API for changing the tabIndex.
23902
+ // Similar logic is found in Enabled(..) function.
23903
+ designEditor.setReadOnly(me.Enabled() === false);
23904
+ Fit.Dom.Attribute(designEditorDom.Editable, "tabindex", me.Enabled() === false ? null : "0"); // Preventing focus is only possible by nullifying DOM attribute (these does not work: delete elm.tabIndex; elm.tabIndex = null|undefined|-1)
23905
+
23621
23906
  if (me.Height().Value === -1 || (designEditorConfig !== null && designEditorConfig.AutoGrow && designEditorConfig.AutoGrow.Enabled === true))
23622
23907
  {
23623
- // Enable auto grow
23908
+ // Enable auto grow - this is done late to allow an initial static height on the outer control which prevents "flickering" while loading
23624
23909
 
23625
- if (me.Height().Value !== -1) // Enable auto grow if not already enabled
23626
- {
23627
- me.Height(-1);
23628
- }
23910
+ me.Height(-1); // Make sure auto grow is enabled since it is unlikely external code has done so explicitely by calling Height(-1)
23629
23911
 
23630
23912
  // Make necessary adjustments to editor DOM for auto grow's min/max height to work
23631
23913
 
23632
- var editorContainer = designEditor.container.$;
23633
- var editableDiv = editorContainer.querySelector("div.cke_wysiwyg_div");
23634
- editableDiv.style.minHeight = config.AutoGrow && config.AutoGrow.MinimumHeight ? config.AutoGrow.MinimumHeight.Value + (config.AutoGrow.MinimumHeight.Unit || "px") : ""; // NOTICE: Minimum height of editable area, not control
23635
- editableDiv.style.maxHeight = config.AutoGrow && config.AutoGrow.MaximumHeight ? config.AutoGrow.MaximumHeight.Value + (config.AutoGrow.MaximumHeight.Unit || "px") : ""; // NOTICE: Maximum height of editable area, not control
23636
- }
23914
+ var editableDiv = designEditorDom.Editable;
23915
+ editableDiv.style.minHeight = designEditorConfig !== null && designEditorConfig.AutoGrow && designEditorConfig.AutoGrow.MinimumHeight ? designEditorConfig.AutoGrow.MinimumHeight.Value + (designEditorConfig.AutoGrow.MinimumHeight.Unit || "px") : ""; // NOTICE: Minimum height of editable area, not control
23916
+ editableDiv.style.maxHeight = designEditorConfig !== null && designEditorConfig.AutoGrow && designEditorConfig.AutoGrow.MaximumHeight ? designEditorConfig.AutoGrow.MaximumHeight.Value + (designEditorConfig.AutoGrow.MaximumHeight.Unit || "px") : ""; // NOTICE: Maximum height of editable area, not control
23637
23917
 
23638
- if (maximized === true)
23639
- {
23640
- me.Maximized(true);
23918
+ // Restrict resizing:
23919
+ // Make sure user cannot resize editor beyond max height of editable area.
23920
+ // Editable area will not "follow" since it is restricted using maxHeight set above.
23921
+ // If we do not want resizing to be restricted, then unset minHeight and maxHeight set
23922
+ // above, when resizing occur (see CKEditor's resize event handler).
23923
+ if (editableDiv.style.maxHeight !== "" && designEditorConfig.AutoGrow.PreventResizeBeyondMaximumHeight === true)
23924
+ {
23925
+ var contents = designEditorDom.Content;
23926
+ contents.style.maxHeight = editableDiv.style.maxHeight;
23927
+ }
23641
23928
  }
23642
23929
 
23643
- if (config.InfoPanel && config.InfoPanel.Text)
23930
+ if (designEditorConfig !== null && designEditorConfig.InfoPanel && designEditorConfig.InfoPanel.Text)
23644
23931
  {
23645
23932
  var infoPanel = document.createElement("div");
23646
23933
  infoPanel.className = "FitUiControlInputInfoPanel";
23647
- infoPanel.innerHTML = config.InfoPanel.Text;
23648
- infoPanel.style.cssText = "text-align: " + (config.InfoPanel.Alignment ? config.InfoPanel.Alignment.toLowerCase() : "center");
23934
+ infoPanel.innerHTML = designEditorConfig.InfoPanel.Text;
23935
+ infoPanel.style.cssText = "text-align: " + (designEditorConfig.InfoPanel.Alignment ? designEditorConfig.InfoPanel.Alignment.toLowerCase() : "center");
23936
+
23937
+ if (designEditorConfig !== null && designEditorConfig.Toolbar && designEditorConfig.Toolbar.Position === "Bottom")
23938
+ {
23939
+ Fit.Dom.InsertBefore(designEditorDom.Content, infoPanel);
23940
+ }
23941
+ else
23942
+ {
23943
+ Fit.Dom.InsertAfter(designEditorDom.Content, infoPanel);
23944
+ }
23945
+ }
23946
+
23947
+ // Register necessary events with emoji panel when opened
23649
23948
 
23650
- var ckEditorInner = designEditor.container.$.querySelector(".cke_inner"); // Div in modern browsers, span in legacy IE
23651
- var ckEditorBottom = designEditor.container.$.querySelector(".cke_inner span.cke_bottom"); // Only present if resize handle is enable
23949
+ var emojiButton = designEditor.container.$.querySelector("a.cke_button__emojipanel");
23652
23950
 
23653
- if (ckEditorInner !== null)
23951
+ if (emojiButton !== null) // Better safe than sorry
23952
+ {
23953
+ Fit.Events.AddHandler(emojiButton, "click", function(e)
23654
23954
  {
23655
- if (ckEditorBottom !== null)
23955
+ // Make sure OnFocus fires before locking focus state
23956
+
23957
+ if (me.Focused() === false)
23656
23958
  {
23657
- Fit.Dom.InsertBefore(ckEditorBottom, infoPanel);
23959
+ // Control not focused - make sure OnFocus fires when emoji button is clicked,
23960
+ // and make sure ControlBase internally considers itself focused, so there is
23961
+ // no risk of OnFocus being fired twice without OnBlur firing in between,
23962
+ // when focus state is unlocked, and focus is perhaps re-assigned to another
23963
+ // DOM element within the control, which will be the case if the design editor
23964
+ // is switched back to an ordinary input field (e.g. using DesignMode(false)).
23965
+ me.Focused(true);
23658
23966
  }
23659
- else
23967
+
23968
+ // Prevent control from firing OnBlur when emoji dialog is opened.
23969
+ // Notice that locking the focus state will also prevent OnFocus
23970
+ // from being fired automatically.
23971
+ me._internal.FocusStateLocked(true);
23972
+
23973
+ setTimeout(function() // Postpone - emoji panel is made visible after click event
23660
23974
  {
23661
- Fit.Dom.Add(ckEditorInner, infoPanel);
23662
- }
23663
- }
23975
+ // Allow light dismissable panels/callouts to prevent close/dismiss
23976
+ // when interacting with emoji widget hosted outside of panels/callouts,
23977
+ // by detecting the presence of a data-disable-light-dismiss="true" attribute.
23978
+ var emojiPanel = document.querySelector("div.cke_emoji-panel"); // Shared among instances
23979
+
23980
+ if (emojiPanel !== null) // Better safe than sorry
23981
+ {
23982
+ Fit.Dom.Data(emojiPanel, "disable-light-dismiss", "true");
23983
+
23984
+ emojiPanel._associatedFitUiControl = me;
23985
+
23986
+ designEditorActiveToolbarPanel =
23987
+ {
23988
+ DomElement: emojiPanel,
23989
+ UnlockFocusStateIfEmojiPanelIsClosed: function() // Function called regularly via interval timer while emoji panel is open to make sure focus state is unlocked when emoji panel is closed, e.g. by pressing ESC, clicking outside of emoji panel, or by choosing an emoji
23990
+ {
23991
+ if (designModeEnabledAndReady() === false /* No longer in DesignMode */ || Fit.Dom.IsVisible(emojiPanel) === false /* Emoji panel closed */ || emojiPanel._associatedFitUiControl !== me /* Emoji panel now opened from another editor */)
23992
+ {
23993
+ designEditorActiveToolbarPanel = null;
23994
+
23995
+ // Disable focus lock - let ControlBase handle OnFocus and OnBlur automatically again
23996
+ me._internal.FocusStateLocked(false);
23997
+
23998
+ // Fire OnBlur in case user changed focus while emoji panel was open.
23999
+ // OnBlur does not fire automatically when focus state is locked.
24000
+ if (me.Focused() === false)
24001
+ {
24002
+ me._internal.FireOnBlur();
24003
+ }
24004
+ }
24005
+ },
24006
+ CloseEmojiPanel: function()
24007
+ {
24008
+ if (emojiPanel._associatedFitUiControl === me && Fit.Dom.IsVisible(emojiPanel) === true && Fit.Dom.Contained(emojiPanel, Fit.Dom.GetFocused()) === true)
24009
+ {
24010
+ designEditor.focus();
24011
+ designEditorActiveToolbarPanel.UnlockFocusStateIfEmojiPanelIsClosed();
24012
+ }
24013
+ }
24014
+ }
24015
+ }
24016
+
24017
+ var checkClosedId = setInterval(function()
24018
+ {
24019
+ // Invoke cleanup function regularly to make sure
24020
+ // focus lock is relased when emoji panel is closed,
24021
+ // and to fire OnBlur if another control was focused
24022
+ // while emoji panel was open.
24023
+
24024
+ if (me === null)
24025
+ {
24026
+ clearInterval(checkClosedId);
24027
+ return;
24028
+ }
24029
+
24030
+ if (designEditorActiveToolbarPanel !== null)
24031
+ {
24032
+ designEditorActiveToolbarPanel.UnlockFocusStateIfEmojiPanelIsClosed(); // Nullfies designEditorActiveToolbarPanel if emoji panel is closed
24033
+ }
24034
+
24035
+ if (designEditorActiveToolbarPanel === null)
24036
+ {
24037
+ clearInterval(checkClosedId);
24038
+ }
24039
+ }, 250);
24040
+ }, 0);
24041
+ });
23664
24042
  }
23665
24043
 
23666
24044
  // DISABLED: Doesn't work! Emoji panel contains an iFrame. When it is re-mounted
@@ -23694,14 +24072,40 @@ Fit.Controls.Input = function(ctlId)
23694
24072
  }
23695
24073
  }*/
23696
24074
 
23697
- designEditor._isReadyForInteraction = true;
23698
-
23699
24075
  // Make editor assume configured width and height.
23700
24076
  // Notice that using config.width and config.height
23701
24077
  // (https://ckeditor.com/docs/ckeditor4/latest/features/size.html)
23702
24078
  // results in editor becoming too high since the toolbar height is not
23703
24079
  // substracted. This problem does not occur when using updateDesignEditorSize().
23704
- updateDesignEditorSize(); // Important: Make sure designEditor._isReadyForInteraction is set first (see above)
24080
+ updateDesignEditorSize();
24081
+
24082
+ if (me.Focused() === false)
24083
+ {
24084
+ // Hide editor toolbar if configured to do so
24085
+ hideToolbarInDesignMode();
24086
+ }
24087
+ else
24088
+ {
24089
+ // Remove placeholder if initially focused
24090
+ updateDesignEditorPlaceholder(true);
24091
+ }
24092
+
24093
+ // Make editor visible - postpone to allow editor to first calculate auto grow height
24094
+ // so the user will not see the chrome (borders) of the editor increase its height.
24095
+ setTimeout(function()
24096
+ {
24097
+ designEditorDom.OuterContainer.style.visibility = "visible";
24098
+
24099
+ // Because editor is hidden while initializing, startupFocus
24100
+ // (https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-startupFocus)
24101
+ // won't be able to place focus in the editor. We resolve this by assigning focus again
24102
+ // once editor is visible (visibility set above). Because startupFocus was set, it will
24103
+ // place focus at the end of the editor as expected.
24104
+ if (me.Focused() === true)
24105
+ {
24106
+ designEditor.focus();
24107
+ }
24108
+ }, 0);
23705
24109
  },
23706
24110
  change: function() // CKEditor bug: not fired in Opera 12 (possibly other old versions as well)
23707
24111
  {
@@ -23726,16 +24130,43 @@ Fit.Controls.Input = function(ctlId)
23726
24130
  {
23727
24131
  if (designEditorSuppressOnResize === false) // Only set data-resized="true" when resized using resize handle
23728
24132
  {
24133
+ // Disable Min/Max height configured with auto grow feature so user can resize it freely, unless PreventResizeBeyondMaximumHeight is enabled
24134
+ if (designEditorConfig !== null && designEditorConfig.AutoGrow && designEditorConfig.AutoGrow.Enabled === true && designEditorConfig.AutoGrow.PreventResizeBeyondMaximumHeight !== true)
24135
+ {
24136
+ var editableDiv = designEditorDom.Editable;
24137
+ editableDiv.style.minHeight = "";
24138
+ editableDiv.style.maxHeight = "";
24139
+
24140
+ var contents = designEditorDom.Content;
24141
+ contents.style.maxHeight = "";
24142
+ }
24143
+
23729
24144
  me._internal.Data("resized", "true");
23730
24145
  repaint();
23731
24146
  }
23732
24147
  },
23733
24148
  selectionChange: function(ev)
23734
24149
  {
23735
- // Disable/enable toolbar buttons, depending on whether a tag/mention is selected
23736
-
23737
24150
  var elm = ev.data.selection.getStartElement().$;
23738
24151
 
24152
+ // Allow light dismissable panels/callouts to prevent close/dismiss
24153
+ // when interacting with image resize handles hosted outside of panels/callouts,
24154
+ // by detecting the presence of a data-disable-light-dismiss="true" attribute.
24155
+
24156
+ if (elm.tagName === "IMG")
24157
+ {
24158
+ setTimeout(function() // Postpone - wait for image resize plugin to add image resize handles
24159
+ {
24160
+ var imageResizeHandlesContainer = document.querySelector("#ckimgrsz");
24161
+ if (imageResizeHandlesContainer !== null) // Better safe than sorry
24162
+ {
24163
+ Fit.Dom.Data(imageResizeHandlesContainer, "disable-light-dismiss", "true");
24164
+ }
24165
+ }, 0);
24166
+ }
24167
+
24168
+ // Disable/enable toolbar buttons, depending on whether a tag/mention is selected
24169
+
23739
24170
  if (elm.tagName === "A" && Fit.Dom.Data(elm, "tag-id") !== null)
23740
24171
  {
23741
24172
  designEditorSuppressPaste = true;
@@ -23915,9 +24346,15 @@ Fit.Controls.Input = function(ctlId)
23915
24346
 
23916
24347
  function updateDesignEditorSize()
23917
24348
  {
23918
- if (designEditor !== null)
24349
+ if (me.DesignMode() === true)
23919
24350
  {
23920
- if (designEditor._isReadyForInteraction !== true)
24351
+ if (designEditorUpdateSizeDebouncer !== -1)
24352
+ {
24353
+ clearTimeout(designEditorUpdateSizeDebouncer);
24354
+ designEditorUpdateSizeDebouncer = -1;
24355
+ }
24356
+
24357
+ if (designModeEnabledAndReady() === false)
23921
24358
  {
23922
24359
  // Postpone, editor is not ready yet.
23923
24360
  // This may happen when editor is created and Width(..) is
@@ -23926,7 +24363,12 @@ Fit.Controls.Input = function(ctlId)
23926
24363
  // This is a problem because CKEditor uses setTimeout(..) to for instance
23927
24364
  // allow early registration of events, and because resources are loaded
23928
24365
  // in an async. manner.
23929
- setTimeout(updateDesignEditorSize, 100);
24366
+ designEditorUpdateSizeDebouncer = setTimeout(function()
24367
+ {
24368
+ designEditorUpdateSizeDebouncer = -1;
24369
+ updateDesignEditorSize();
24370
+ }, 100);
24371
+
23930
24372
  return;
23931
24373
  }
23932
24374
 
@@ -23969,6 +24411,97 @@ Fit.Controls.Input = function(ctlId)
23969
24411
  }
23970
24412
  }
23971
24413
 
24414
+ function isToolbarHiddenInDesignEditor() // Returns True if editor is fully loaded and toolbar is hidden
24415
+ {
24416
+ var toolbarContainer = designModeEnabledAndReady() === true ? designEditorDom.Top || designEditorDom.Bottom : null; // Top is null if editor is placed at the bottom
24417
+ return (toolbarContainer !== null && toolbarContainer.style.display === "none");
24418
+ }
24419
+
24420
+ function hideToolbarInDesignMode() // Editor must be fully loaded before calling this function!
24421
+ {
24422
+ if (designEditorConfig !== null && designEditorConfig.Toolbar && designEditorConfig.Toolbar.HideInitially === true)
24423
+ {
24424
+ var toolbarContainer = designEditorDom.Top || designEditorDom.Bottom; // Top is null if editor is placed at the bottom
24425
+
24426
+ if (toolbarContainer.style.display === "none")
24427
+ {
24428
+ return; // Already hidden
24429
+ }
24430
+
24431
+ // Prevent editor from increasing its height when toolbar is shown.
24432
+ // This is not ideal. We use the top/bottom's (toolbar's) height but it might change
24433
+ // if window is resized, which will cause buttons to "word wrap". But that is
24434
+ // acceptable. In this case the editor might change dimensions when toolbar is
24435
+ // shown and static height on content area is removed in OnFocus handler registered
24436
+ // in init().
24437
+
24438
+ var content = designEditorDom.Editable;
24439
+ content.style.height = toolbarContainer.offsetHeight + content.offsetHeight + "px";
24440
+
24441
+ // Hide toolbar
24442
+
24443
+ toolbarContainer.style.display = "none";
24444
+
24445
+ // Make editable area adjust to take up space previously consumed by toolbar
24446
+ updateDesignEditorSize();
24447
+ }
24448
+ }
24449
+
24450
+ function restoreHiddenToolbarInDesignEditor()
24451
+ {
24452
+ if (designModeEnabledAndReady() === true && designEditorConfig !== null && designEditorConfig.Toolbar && designEditorConfig.Toolbar.HideInitially === true)
24453
+ {
24454
+ // Toolbar has been initially hidden - make it appear again
24455
+
24456
+ var toolbarContainer = designEditorDom.Top || designEditorDom.Bottom; // Top is null if editor is placed at the bottom
24457
+
24458
+ if (toolbarContainer.style.display === "")
24459
+ {
24460
+ return; // Already restored - no longer hidden
24461
+ }
24462
+
24463
+ toolbarContainer.style.display = "";
24464
+
24465
+ // Hiding the toolbar will cause the editor to decrease its height, while displaying the toolbar again
24466
+ // will cause it to increase its height. To avoid this "flickering" a fixed height (toolbar height + content height)
24467
+ // was applied when toolbar was hidden. But now that the toolbar is once again visible, we remove the fixed height
24468
+ // again - otherwise resizing and auto grow will not work.
24469
+
24470
+ var content = designEditorDom.Editable;
24471
+ content.style.height = "";
24472
+
24473
+ me._internal.Data("toolbar", "true");
24474
+
24475
+ // Update size of editable area in case auto grow is not enabled, in which case
24476
+ // toolbar will now have taken up space outside of control's container (overflowing).
24477
+ // Make editable area fit control container again.
24478
+ updateDesignEditorSize();
24479
+ }
24480
+ }
24481
+
24482
+ function updateDesignEditorPlaceholder(clearPlaceholder)
24483
+ {
24484
+ Fit.Validation.ExpectBoolean(clearPlaceholder, true);
24485
+
24486
+ if (designModeEnabledAndReady() === true)
24487
+ {
24488
+ if (Fit.Browser.GetBrowser() === "MSIE" && Fit.Browser.GetVersion() < 10)
24489
+ {
24490
+ // Native support for placeholders (using the real placeholder attribute) was
24491
+ // introduced in IE10, so we want to ensure consistent behaviour for all controls,
24492
+ // as e.g. Input and DatePicker uses the native placeholder implementation.
24493
+ return;
24494
+ }
24495
+
24496
+ // WARNING: Retrieving value from editor is expensive! Do not
24497
+ // call updateDesignEditorPlaceholder() too often (e.g. OnChange).
24498
+ // Simply make sure placeholder is updated OnFocus and OnBlur.
24499
+
24500
+ var val = clearPlaceholder !== true && me.Value() === "" ? me.Placeholder() : "";
24501
+ Fit.Dom.Data(designEditorDom.Editable, "placeholder", val || null);
24502
+ }
24503
+ }
24504
+
23972
24505
  function revertToSingleLineIfNecessary()
23973
24506
  {
23974
24507
  if (wasAutoChangedToMultiLineMode === true && me.Maximizable() === false && me.Resizable() === Fit.Controls.InputResizing.Disabled && me.DesignMode() === false)
@@ -24008,8 +24541,22 @@ Fit.Controls.Input = function(ctlId)
24008
24541
  }
24009
24542
  }
24010
24543
 
24011
- function reloadEditor()
24544
+ function reloadEditor(force, reloadConfig)
24012
24545
  {
24546
+ Fit.Validation.ExpectBoolean(force, true);
24547
+ Fit.Validation.ExpectObject(reloadConfig, true); // Not validated further, as it has already been validated in DesignMode(..)
24548
+
24549
+ if (force !== true && (designModeEnabledAndReady() === false || designEditorMustReloadWhenReady === true))
24550
+ {
24551
+ // Attempting to reload editor while initializing - postpone until editor is fully loaded,
24552
+ // since we cannot guarantee reliable behavior with CKEditor if it's disposed while loading.
24553
+ designEditorMustReloadWhenReady = true;
24554
+ designEditorReloadConfig = reloadConfig || designEditorReloadConfig;
24555
+ return;
24556
+ }
24557
+
24558
+ designEditorMustReloadWhenReady = false;
24559
+
24013
24560
  // Disabling DesignMode brings it back to input or textarea mode.
24014
24561
  // If reverting to input mode, Height is reset, so we need to preserve that.
24015
24562
 
@@ -24019,12 +24566,70 @@ Fit.Controls.Input = function(ctlId)
24019
24566
  var currentWasAutoChangedToMultiLineMode = wasAutoChangedToMultiLineMode; // DesignMode(false) will result in wasAutoChangedToMultiLineMode being set to false if DesignMode(true) changed the control to MultiLine mode
24020
24567
 
24021
24568
  me.DesignMode(false);
24022
- me.DesignMode(true);
24569
+ me.DesignMode(true, reloadConfig || designEditorReloadConfig || undefined); // Use reloadConfig if set (and if reload was not postponed) or use designEditorReloadConfig if reload was postponed with updated editor config
24570
+ designEditorReloadConfig = null;
24023
24571
 
24024
24572
  me.Height(height.Value, height.Unit);
24025
24573
  wasAutoChangedToMultiLineMode = currentWasAutoChangedToMultiLineMode;
24026
24574
  }
24027
24575
 
24576
+ function destroyDesignEditorInstance()
24577
+ {
24578
+ // Destroying editor also fires OnHide event for any dialog currently open, which will clean up:
24579
+ // Fit._internal.Controls.Input.ActiveEditorForDialog;
24580
+ // Fit._internal.Controls.Input.ActiveEditorForDialogDestroyed;
24581
+ // Fit._internal.Controls.Input.ActiveEditorForDialogDisabledPostponed;
24582
+ // Fit._internal.Controls.Input.ActiveDialogForEditor;
24583
+ // Fit._internal.Controls.Input.ActiveDialogForEditorCanceled;
24584
+
24585
+ // Calling destroy() fires OnHide for any dialog currently open, which
24586
+ // in turn disables locked focus state and returns focus to the control.
24587
+
24588
+ designEditor.destroy();
24589
+
24590
+ designEditor = null;
24591
+ designEditorDom = null;
24592
+ designEditorDirty = false;
24593
+ designEditorDirtyPending = false;
24594
+ //designEditorConfig = null; // Do NOT nullify this! We need it, in case DesignMode is toggled!
24595
+ //designEditorReloadConfig = null; // Do NOT nullify this! We need it, in case DesignMode is reloaded!
24596
+ designEditorRestoreButtonState = null;
24597
+ designEditorSuppressPaste = false;
24598
+ designEditorSuppressOnResize = false;
24599
+ designEditorMustReloadWhenReady = false;
24600
+ designEditorMustDisposeWhenReady = false;
24601
+ designEditorActiveToolbarPanel = null;
24602
+
24603
+ if (designEditorUpdateSizeDebouncer !== -1)
24604
+ {
24605
+ clearTimeout(designEditorUpdateSizeDebouncer);
24606
+ designEditorUpdateSizeDebouncer = -1;
24607
+ }
24608
+
24609
+ if (mutationObserverId !== -1)
24610
+ {
24611
+ Fit.Events.RemoveMutationObserver(mutationObserverId);
24612
+ mutationObserverId = -1;
24613
+ }
24614
+
24615
+ if (rootedEventId !== -1)
24616
+ {
24617
+ Fit.Events.RemoveHandler(me.GetDomElement(), rootedEventId);
24618
+ rootedEventId = -1;
24619
+ }
24620
+
24621
+ if (createWhenReadyIntervalId !== -1)
24622
+ {
24623
+ clearInterval(createWhenReadyIntervalId);
24624
+ createWhenReadyIntervalId = -1;
24625
+ }
24626
+ }
24627
+
24628
+ function designModeEnabledAndReady()
24629
+ {
24630
+ return designEditorDom !== null; // Editor is fully loaded when editor DOM is made available
24631
+ }
24632
+
24028
24633
  function localize()
24029
24634
  {
24030
24635
  if (me.DesignMode() === true)