spiderfw 0.6.38 → 0.6.39

Sign up to get free protection for your applications and to get access to all the features.
Files changed (515) hide show
  1. checksums.yaml +13 -5
  2. data/CHANGELOG +23 -0
  3. data/VERSION +1 -1
  4. data/apps/core/admin/views/admin.layout.shtml +6 -0
  5. data/apps/core/auth/controllers/login_controller.rb +1 -1
  6. data/apps/core/components/assets.rb +55 -6
  7. data/apps/core/components/public/bootstrap/scss/_variables.scss +5 -2
  8. data/apps/core/components/public/bootstrap/scss/bootstrap.css +942 -236
  9. data/apps/core/components/public/bootstrap/scss/responsive.css +187 -30
  10. data/apps/core/components/public/css/tinymce/skins/lightgray/AbsoluteLayout.less +17 -0
  11. data/apps/core/components/public/css/tinymce/skins/lightgray/Animations.less +10 -0
  12. data/apps/core/components/public/css/tinymce/skins/lightgray/Button.less +172 -0
  13. data/apps/core/components/public/css/tinymce/skins/lightgray/ButtonGroup.less +71 -0
  14. data/apps/core/components/public/css/tinymce/skins/lightgray/Checkbox.less +49 -0
  15. data/apps/core/components/public/css/tinymce/skins/lightgray/ColorBox.less +6 -0
  16. data/apps/core/components/public/css/tinymce/skins/lightgray/ColorButton.less +72 -0
  17. data/apps/core/components/public/css/tinymce/skins/lightgray/ColorPicker.less +80 -0
  18. data/apps/core/components/public/css/tinymce/skins/lightgray/ComboBox.less +39 -0
  19. data/apps/core/components/public/css/tinymce/skins/lightgray/Container.less +9 -0
  20. data/apps/core/components/public/css/tinymce/skins/lightgray/Content.Inline.less +4 -0
  21. data/apps/core/components/public/css/tinymce/skins/lightgray/Content.Objects.less +166 -0
  22. data/apps/core/components/public/css/tinymce/skins/lightgray/Content.less +27 -0
  23. data/apps/core/components/public/css/tinymce/skins/lightgray/CropRect.less +54 -0
  24. data/apps/core/components/public/css/tinymce/skins/lightgray/FieldSet.less +15 -0
  25. data/apps/core/components/public/css/tinymce/skins/lightgray/FitLayout.less +9 -0
  26. data/apps/core/components/public/css/tinymce/skins/lightgray/FloatPanel.less +69 -0
  27. data/apps/core/components/public/css/tinymce/skins/lightgray/FlowLayout.less +36 -0
  28. data/apps/core/components/public/css/tinymce/skins/lightgray/Icons.Ie7.less +136 -0
  29. data/apps/core/components/public/css/tinymce/skins/lightgray/Icons.less +180 -0
  30. data/apps/core/components/public/css/tinymce/skins/lightgray/Iframe.less +6 -0
  31. data/apps/core/components/public/css/tinymce/skins/lightgray/ImagePanel.less +20 -0
  32. data/apps/core/components/public/css/tinymce/skins/lightgray/InfoBox.less +71 -0
  33. data/apps/core/components/public/css/tinymce/skins/lightgray/Label.less +38 -0
  34. data/apps/core/components/public/css/tinymce/skins/lightgray/ListBox.less +26 -0
  35. data/apps/core/components/public/css/tinymce/skins/lightgray/Menu.less +34 -0
  36. data/apps/core/components/public/css/tinymce/skins/lightgray/MenuBar.less +32 -0
  37. data/apps/core/components/public/css/tinymce/skins/lightgray/MenuButton.less +34 -0
  38. data/apps/core/components/public/css/tinymce/skins/lightgray/MenuItem.less +142 -0
  39. data/apps/core/components/public/css/tinymce/skins/lightgray/Mixins.less +54 -0
  40. data/apps/core/components/public/css/tinymce/skins/lightgray/Notification.less +144 -0
  41. data/apps/core/components/public/css/tinymce/skins/lightgray/Panel.less +7 -0
  42. data/apps/core/components/public/css/tinymce/skins/lightgray/Path.less +45 -0
  43. data/apps/core/components/public/css/tinymce/skins/lightgray/Progress.less +34 -0
  44. data/apps/core/components/public/css/tinymce/skins/lightgray/Radio.less +1 -0
  45. data/apps/core/components/public/css/tinymce/skins/lightgray/Reset.less +32 -0
  46. data/apps/core/components/public/css/tinymce/skins/lightgray/ResizeHandle.less +18 -0
  47. data/apps/core/components/public/css/tinymce/skins/lightgray/Scrollable.less +44 -0
  48. data/apps/core/components/public/css/tinymce/skins/lightgray/SelectBox.less +6 -0
  49. data/apps/core/components/public/css/tinymce/skins/lightgray/Slider.less +29 -0
  50. data/apps/core/components/public/css/tinymce/skins/lightgray/Spacer.less +5 -0
  51. data/apps/core/components/public/css/tinymce/skins/lightgray/SplitButton.less +49 -0
  52. data/apps/core/components/public/css/tinymce/skins/lightgray/StackLayout.less +5 -0
  53. data/apps/core/components/public/css/tinymce/skins/lightgray/TabPanel.less +44 -0
  54. data/apps/core/components/public/css/tinymce/skins/lightgray/TextBox.less +41 -0
  55. data/apps/core/components/public/css/tinymce/skins/lightgray/Throbber.less +19 -0
  56. data/apps/core/components/public/css/tinymce/skins/lightgray/TinyMCE.less +159 -0
  57. data/apps/core/components/public/css/tinymce/skins/lightgray/ToolTip.less +129 -0
  58. data/apps/core/components/public/css/tinymce/skins/lightgray/Variables.less +214 -0
  59. data/apps/core/components/public/css/tinymce/skins/lightgray/Window.less +127 -0
  60. data/apps/core/components/public/css/tinymce/skins/lightgray/content.inline.min.css +1 -0
  61. data/apps/core/components/public/css/tinymce/skins/lightgray/content.min.css +1 -0
  62. data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/readme.md +1 -0
  63. data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce-small.eot +0 -0
  64. data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce-small.json +1277 -0
  65. data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce-small.svg +63 -0
  66. data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce-small.ttf +0 -0
  67. data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce-small.woff +0 -0
  68. data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce.eot +0 -0
  69. data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce.json +3381 -0
  70. data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce.svg +129 -0
  71. data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce.ttf +0 -0
  72. data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce.woff +0 -0
  73. data/apps/core/components/public/css/tinymce/skins/lightgray/img/anchor.gif +0 -0
  74. data/apps/core/components/public/css/tinymce/skins/lightgray/img/loader.gif +0 -0
  75. data/apps/core/components/public/css/tinymce/skins/lightgray/img/object.gif +0 -0
  76. data/apps/core/components/public/css/tinymce/skins/lightgray/img/trans.gif +0 -0
  77. data/apps/core/components/public/css/tinymce/skins/lightgray/skin.dev.less +46 -0
  78. data/apps/core/components/public/css/tinymce/skins/lightgray/skin.ie7.dev.less +46 -0
  79. data/apps/core/components/public/css/tinymce/skins/lightgray/skin.ie7.less +2542 -0
  80. data/apps/core/components/public/css/tinymce/skins/lightgray/skin.ie7.min.css +1 -0
  81. data/apps/core/components/public/css/tinymce/skins/lightgray/skin.less +2586 -0
  82. data/apps/core/components/public/css/tinymce/skins/lightgray/skin.min.css +1 -0
  83. data/apps/core/components/public/js/bootbox_2/bootbox.js +551 -0
  84. data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-it-min.js +4 -0
  85. data/apps/core/components/public/js/spider.js +7 -3
  86. data/apps/core/components/public/js/tinymce/classes/AddOnManager.js +265 -0
  87. data/apps/core/components/public/js/tinymce/classes/Compat.js +90 -0
  88. data/apps/core/components/public/js/tinymce/classes/DragDropOverrides.js +224 -0
  89. data/apps/core/components/public/js/tinymce/classes/Editor.js +2221 -0
  90. data/apps/core/components/public/js/tinymce/classes/EditorCommands.js +1028 -0
  91. data/apps/core/components/public/js/tinymce/classes/EditorManager.js +715 -0
  92. data/apps/core/components/public/js/tinymce/classes/EditorObservable.js +204 -0
  93. data/apps/core/components/public/js/tinymce/classes/EditorUpload.js +191 -0
  94. data/apps/core/components/public/js/tinymce/classes/EnterKey.js +676 -0
  95. data/apps/core/components/public/js/tinymce/classes/Env.js +177 -0
  96. data/apps/core/components/public/js/tinymce/classes/FocusManager.js +266 -0
  97. data/apps/core/components/public/js/tinymce/classes/ForceBlocks.js +138 -0
  98. data/apps/core/components/public/js/tinymce/classes/Formatter.js +2378 -0
  99. data/apps/core/components/public/js/tinymce/classes/LegacyInput.js +82 -0
  100. data/apps/core/components/public/js/tinymce/classes/Mode.js +54 -0
  101. data/apps/core/components/public/js/tinymce/classes/NodeChange.js +154 -0
  102. data/apps/core/components/public/js/tinymce/classes/NotificationManager.js +156 -0
  103. data/apps/core/components/public/js/tinymce/classes/Register.js +34 -0
  104. data/apps/core/components/public/js/tinymce/classes/SelectionOverrides.js +810 -0
  105. data/apps/core/components/public/js/tinymce/classes/Shortcuts.js +172 -0
  106. data/apps/core/components/public/js/tinymce/classes/UndoManager.js +346 -0
  107. data/apps/core/components/public/js/tinymce/classes/WindowManager.js +278 -0
  108. data/apps/core/components/public/js/tinymce/classes/caret/CaretBookmark.js +263 -0
  109. data/apps/core/components/public/js/tinymce/classes/caret/CaretCandidate.js +86 -0
  110. data/apps/core/components/public/js/tinymce/classes/caret/CaretContainer.js +151 -0
  111. data/apps/core/components/public/js/tinymce/classes/caret/CaretPosition.js +371 -0
  112. data/apps/core/components/public/js/tinymce/classes/caret/CaretUtils.js +302 -0
  113. data/apps/core/components/public/js/tinymce/classes/caret/CaretWalker.js +215 -0
  114. data/apps/core/components/public/js/tinymce/classes/caret/FakeCaret.js +192 -0
  115. data/apps/core/components/public/js/tinymce/classes/caret/LineUtils.js +135 -0
  116. data/apps/core/components/public/js/tinymce/classes/caret/LineWalker.js +166 -0
  117. data/apps/core/components/public/js/tinymce/classes/data/Binding.js +79 -0
  118. data/apps/core/components/public/js/tinymce/classes/data/ObservableArray.js +196 -0
  119. data/apps/core/components/public/js/tinymce/classes/data/ObservableObject.js +194 -0
  120. data/apps/core/components/public/js/tinymce/classes/dom/BookmarkManager.js +456 -0
  121. data/apps/core/components/public/js/tinymce/classes/dom/ControlSelection.js +634 -0
  122. data/apps/core/components/public/js/tinymce/classes/dom/DOMUtils.js +1853 -0
  123. data/apps/core/components/public/js/tinymce/classes/dom/Dimensions.js +64 -0
  124. data/apps/core/components/public/js/tinymce/classes/dom/DomQuery.js +1578 -0
  125. data/apps/core/components/public/js/tinymce/classes/dom/ElementUtils.js +118 -0
  126. data/apps/core/components/public/js/tinymce/classes/dom/EventUtils.js +583 -0
  127. data/apps/core/components/public/js/tinymce/classes/dom/NodePath.js +50 -0
  128. data/apps/core/components/public/js/tinymce/classes/dom/NodeType.js +110 -0
  129. data/apps/core/components/public/js/tinymce/classes/dom/Range.js +785 -0
  130. data/apps/core/components/public/js/tinymce/classes/dom/RangeUtils.js +628 -0
  131. data/apps/core/components/public/js/tinymce/classes/dom/ScriptLoader.js +254 -0
  132. data/apps/core/components/public/js/tinymce/classes/dom/Selection.js +1008 -0
  133. data/apps/core/components/public/js/tinymce/classes/dom/Serializer.js +506 -0
  134. data/apps/core/components/public/js/tinymce/classes/dom/Sizzle.jQuery.js +23 -0
  135. data/apps/core/components/public/js/tinymce/classes/dom/Sizzle.js +2039 -0
  136. data/apps/core/components/public/js/tinymce/classes/dom/StyleSheetLoader.js +190 -0
  137. data/apps/core/components/public/js/tinymce/classes/dom/TreeWalker.js +127 -0
  138. data/apps/core/components/public/js/tinymce/classes/dom/TridentSelection.js +508 -0
  139. data/apps/core/components/public/js/tinymce/classes/file/BlobCache.js +72 -0
  140. data/apps/core/components/public/js/tinymce/classes/file/Conversions.js +106 -0
  141. data/apps/core/components/public/js/tinymce/classes/file/ImageScanner.js +145 -0
  142. data/apps/core/components/public/js/tinymce/classes/file/Uploader.js +193 -0
  143. data/apps/core/components/public/js/tinymce/classes/fmt/Hooks.js +66 -0
  144. data/apps/core/components/public/js/tinymce/classes/fmt/Preview.js +151 -0
  145. data/apps/core/components/public/js/tinymce/classes/geom/ClientRect.js +136 -0
  146. data/apps/core/components/public/js/tinymce/classes/geom/Rect.js +214 -0
  147. data/apps/core/components/public/js/tinymce/classes/html/DomParser.js +822 -0
  148. data/apps/core/components/public/js/tinymce/classes/html/Entities.js +268 -0
  149. data/apps/core/components/public/js/tinymce/classes/html/Node.js +496 -0
  150. data/apps/core/components/public/js/tinymce/classes/html/SaxParser.js +474 -0
  151. data/apps/core/components/public/js/tinymce/classes/html/Schema.js +1004 -0
  152. data/apps/core/components/public/js/tinymce/classes/html/Serializer.js +158 -0
  153. data/apps/core/components/public/js/tinymce/classes/html/Styles.js +363 -0
  154. data/apps/core/components/public/js/tinymce/classes/html/Writer.js +199 -0
  155. data/apps/core/components/public/js/tinymce/classes/jquery.tinymce.js +377 -0
  156. data/apps/core/components/public/js/tinymce/classes/text/ExtendingChar.js +53 -0
  157. data/apps/core/components/public/js/tinymce/classes/text/Zwsp.js +36 -0
  158. data/apps/core/components/public/js/tinymce/classes/ui/AbsoluteLayout.js +63 -0
  159. data/apps/core/components/public/js/tinymce/classes/ui/BoxUtils.js +98 -0
  160. data/apps/core/components/public/js/tinymce/classes/ui/Button.js +199 -0
  161. data/apps/core/components/public/js/tinymce/classes/ui/ButtonGroup.js +62 -0
  162. data/apps/core/components/public/js/tinymce/classes/ui/Checkbox.js +162 -0
  163. data/apps/core/components/public/js/tinymce/classes/ui/ClassList.js +149 -0
  164. data/apps/core/components/public/js/tinymce/classes/ui/Collection.js +438 -0
  165. data/apps/core/components/public/js/tinymce/classes/ui/ColorBox.js +72 -0
  166. data/apps/core/components/public/js/tinymce/classes/ui/ColorButton.js +124 -0
  167. data/apps/core/components/public/js/tinymce/classes/ui/ColorPicker.js +206 -0
  168. data/apps/core/components/public/js/tinymce/classes/ui/ComboBox.js +306 -0
  169. data/apps/core/components/public/js/tinymce/classes/ui/Container.js +506 -0
  170. data/apps/core/components/public/js/tinymce/classes/ui/Control.js +1301 -0
  171. data/apps/core/components/public/js/tinymce/classes/ui/DomUtils.js +107 -0
  172. data/apps/core/components/public/js/tinymce/classes/ui/DragHelper.js +144 -0
  173. data/apps/core/components/public/js/tinymce/classes/ui/ElementPath.js +79 -0
  174. data/apps/core/components/public/js/tinymce/classes/ui/Factory.js +105 -0
  175. data/apps/core/components/public/js/tinymce/classes/ui/FieldSet.js +59 -0
  176. data/apps/core/components/public/js/tinymce/classes/ui/FilePicker.js +85 -0
  177. data/apps/core/components/public/js/tinymce/classes/ui/FitLayout.js +48 -0
  178. data/apps/core/components/public/js/tinymce/classes/ui/FlexLayout.js +246 -0
  179. data/apps/core/components/public/js/tinymce/classes/ui/FloatPanel.js +409 -0
  180. data/apps/core/components/public/js/tinymce/classes/ui/FlowLayout.js +46 -0
  181. data/apps/core/components/public/js/tinymce/classes/ui/Form.js +157 -0
  182. data/apps/core/components/public/js/tinymce/classes/ui/FormItem.js +56 -0
  183. data/apps/core/components/public/js/tinymce/classes/ui/FormatControls.js +535 -0
  184. data/apps/core/components/public/js/tinymce/classes/ui/GridLayout.js +233 -0
  185. data/apps/core/components/public/js/tinymce/classes/ui/Iframe.js +85 -0
  186. data/apps/core/components/public/js/tinymce/classes/ui/InfoBox.js +93 -0
  187. data/apps/core/components/public/js/tinymce/classes/ui/KeyboardNavigation.js +406 -0
  188. data/apps/core/components/public/js/tinymce/classes/ui/Label.js +144 -0
  189. data/apps/core/components/public/js/tinymce/classes/ui/Layout.js +120 -0
  190. data/apps/core/components/public/js/tinymce/classes/ui/ListBox.js +152 -0
  191. data/apps/core/components/public/js/tinymce/classes/ui/Menu.js +195 -0
  192. data/apps/core/components/public/js/tinymce/classes/ui/MenuBar.js +33 -0
  193. data/apps/core/components/public/js/tinymce/classes/ui/MenuButton.js +268 -0
  194. data/apps/core/components/public/js/tinymce/classes/ui/MenuItem.js +336 -0
  195. data/apps/core/components/public/js/tinymce/classes/ui/MessageBox.js +202 -0
  196. data/apps/core/components/public/js/tinymce/classes/ui/Movable.js +200 -0
  197. data/apps/core/components/public/js/tinymce/classes/ui/Notification.js +154 -0
  198. data/apps/core/components/public/js/tinymce/classes/ui/Panel.js +67 -0
  199. data/apps/core/components/public/js/tinymce/classes/ui/PanelButton.js +114 -0
  200. data/apps/core/components/public/js/tinymce/classes/ui/Path.js +127 -0
  201. data/apps/core/components/public/js/tinymce/classes/ui/Progress.js +81 -0
  202. data/apps/core/components/public/js/tinymce/classes/ui/Radio.js +29 -0
  203. data/apps/core/components/public/js/tinymce/classes/ui/ReflowQueue.js +79 -0
  204. data/apps/core/components/public/js/tinymce/classes/ui/Resizable.js +68 -0
  205. data/apps/core/components/public/js/tinymce/classes/ui/ResizeHandle.js +86 -0
  206. data/apps/core/components/public/js/tinymce/classes/ui/Scrollable.js +141 -0
  207. data/apps/core/components/public/js/tinymce/classes/ui/SelectBox.js +106 -0
  208. data/apps/core/components/public/js/tinymce/classes/ui/Selector.js +369 -0
  209. data/apps/core/components/public/js/tinymce/classes/ui/Slider.js +161 -0
  210. data/apps/core/components/public/js/tinymce/classes/ui/Spacer.js +39 -0
  211. data/apps/core/components/public/js/tinymce/classes/ui/SplitButton.js +146 -0
  212. data/apps/core/components/public/js/tinymce/classes/ui/StackLayout.js +34 -0
  213. data/apps/core/components/public/js/tinymce/classes/ui/TabPanel.js +178 -0
  214. data/apps/core/components/public/js/tinymce/classes/ui/TextBox.js +208 -0
  215. data/apps/core/components/public/js/tinymce/classes/ui/Throbber.js +88 -0
  216. data/apps/core/components/public/js/tinymce/classes/ui/Toolbar.js +56 -0
  217. data/apps/core/components/public/js/tinymce/classes/ui/Tooltip.js +73 -0
  218. data/apps/core/components/public/js/tinymce/classes/ui/Widget.js +151 -0
  219. data/apps/core/components/public/js/tinymce/classes/ui/Window.js +474 -0
  220. data/apps/core/components/public/js/tinymce/classes/util/Arr.js +153 -0
  221. data/apps/core/components/public/js/tinymce/classes/util/Class.js +167 -0
  222. data/apps/core/components/public/js/tinymce/classes/util/Color.js +235 -0
  223. data/apps/core/components/public/js/tinymce/classes/util/Delay.js +191 -0
  224. data/apps/core/components/public/js/tinymce/classes/util/EventDispatcher.js +294 -0
  225. data/apps/core/components/public/js/tinymce/classes/util/Fun.js +87 -0
  226. data/apps/core/components/public/js/tinymce/classes/util/I18n.js +116 -0
  227. data/apps/core/components/public/js/tinymce/classes/util/JSON.js +109 -0
  228. data/apps/core/components/public/js/tinymce/classes/util/JSONP.js +38 -0
  229. data/apps/core/components/public/js/tinymce/classes/util/JSONRequest.js +110 -0
  230. data/apps/core/components/public/js/tinymce/classes/util/LocalStorage.js +213 -0
  231. data/apps/core/components/public/js/tinymce/classes/util/Observable.js +129 -0
  232. data/apps/core/components/public/js/tinymce/classes/util/Promise.js +200 -0
  233. data/apps/core/components/public/js/tinymce/classes/util/Quirks.js +1701 -0
  234. data/apps/core/components/public/js/tinymce/classes/util/Tools.js +442 -0
  235. data/apps/core/components/public/js/tinymce/classes/util/URI.js +411 -0
  236. data/apps/core/components/public/js/tinymce/classes/util/VK.js +37 -0
  237. data/apps/core/components/public/js/tinymce/classes/util/XHR.js +110 -0
  238. data/apps/core/components/public/js/tinymce/jquery.tinymce.min.js +1 -0
  239. data/apps/core/components/public/js/tinymce/langs/it.js +219 -0
  240. data/apps/core/components/public/js/tinymce/langs/readme.md +3 -0
  241. data/apps/core/components/public/js/tinymce/license.txt +504 -0
  242. data/apps/core/components/public/js/tinymce/plugins/advlist/plugin.js +97 -0
  243. data/apps/core/components/public/js/tinymce/plugins/advlist/plugin.min.js +1 -0
  244. data/apps/core/components/public/js/tinymce/plugins/anchor/plugin.js +55 -0
  245. data/apps/core/components/public/js/tinymce/plugins/anchor/plugin.min.js +1 -0
  246. data/apps/core/components/public/js/tinymce/plugins/autolink/plugin.js +204 -0
  247. data/apps/core/components/public/js/tinymce/plugins/autolink/plugin.min.js +1 -0
  248. data/apps/core/components/public/js/tinymce/plugins/autoresize/plugin.js +162 -0
  249. data/apps/core/components/public/js/tinymce/plugins/autoresize/plugin.min.js +1 -0
  250. data/apps/core/components/public/js/tinymce/plugins/autosave/plugin.js +165 -0
  251. data/apps/core/components/public/js/tinymce/plugins/autosave/plugin.min.js +1 -0
  252. data/apps/core/components/public/js/tinymce/plugins/bbcode/plugin.js +123 -0
  253. data/apps/core/components/public/js/tinymce/plugins/bbcode/plugin.min.js +1 -0
  254. data/apps/core/components/public/js/tinymce/plugins/charmap/plugin.js +450 -0
  255. data/apps/core/components/public/js/tinymce/plugins/charmap/plugin.min.js +1 -0
  256. data/apps/core/components/public/js/tinymce/plugins/code/plugin.js +60 -0
  257. data/apps/core/components/public/js/tinymce/plugins/code/plugin.min.js +1 -0
  258. data/apps/core/components/public/js/tinymce/plugins/codesample/classes/Dialog.js +121 -0
  259. data/apps/core/components/public/js/tinymce/plugins/codesample/classes/Plugin.js +95 -0
  260. data/apps/core/components/public/js/tinymce/plugins/codesample/classes/Prism.js +937 -0
  261. data/apps/core/components/public/js/tinymce/plugins/codesample/classes/Utils.js +33 -0
  262. data/apps/core/components/public/js/tinymce/plugins/codesample/css/prism.css +138 -0
  263. data/apps/core/components/public/js/tinymce/plugins/codesample/plugin.dev.js +141 -0
  264. data/apps/core/components/public/js/tinymce/plugins/codesample/plugin.js +1299 -0
  265. data/apps/core/components/public/js/tinymce/plugins/codesample/plugin.min.js +1 -0
  266. data/apps/core/components/public/js/tinymce/plugins/colorpicker/plugin.js +112 -0
  267. data/apps/core/components/public/js/tinymce/plugins/colorpicker/plugin.min.js +1 -0
  268. data/apps/core/components/public/js/tinymce/plugins/compat3x/css/dialog.css +118 -0
  269. data/apps/core/components/public/js/tinymce/plugins/compat3x/img/buttons.png +0 -0
  270. data/apps/core/components/public/js/tinymce/plugins/compat3x/img/icons.gif +0 -0
  271. data/apps/core/components/public/js/tinymce/plugins/compat3x/img/items.gif +0 -0
  272. data/apps/core/components/public/js/tinymce/plugins/compat3x/img/menu_arrow.gif +0 -0
  273. data/apps/core/components/public/js/tinymce/plugins/compat3x/img/menu_check.gif +0 -0
  274. data/apps/core/components/public/js/tinymce/plugins/compat3x/img/progress.gif +0 -0
  275. data/apps/core/components/public/js/tinymce/plugins/compat3x/img/tabs.gif +0 -0
  276. data/apps/core/components/public/js/tinymce/plugins/compat3x/plugin.js +297 -0
  277. data/apps/core/components/public/js/tinymce/plugins/compat3x/plugin.min.js +1 -0
  278. data/apps/core/components/public/js/tinymce/plugins/compat3x/tiny_mce_popup.js +542 -0
  279. data/apps/core/components/public/js/tinymce/plugins/compat3x/utils/editable_selects.js +70 -0
  280. data/apps/core/components/public/js/tinymce/plugins/compat3x/utils/form_utils.js +210 -0
  281. data/apps/core/components/public/js/tinymce/plugins/compat3x/utils/mctabs.js +164 -0
  282. data/apps/core/components/public/js/tinymce/plugins/compat3x/utils/validate.js +252 -0
  283. data/apps/core/components/public/js/tinymce/plugins/contextmenu/plugin.js +88 -0
  284. data/apps/core/components/public/js/tinymce/plugins/contextmenu/plugin.min.js +1 -0
  285. data/apps/core/components/public/js/tinymce/plugins/directionality/plugin.js +64 -0
  286. data/apps/core/components/public/js/tinymce/plugins/directionality/plugin.min.js +1 -0
  287. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-cool.gif +0 -0
  288. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-cry.gif +0 -0
  289. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-embarassed.gif +0 -0
  290. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif +0 -0
  291. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-frown.gif +0 -0
  292. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-innocent.gif +0 -0
  293. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-kiss.gif +0 -0
  294. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-laughing.gif +0 -0
  295. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-money-mouth.gif +0 -0
  296. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-sealed.gif +0 -0
  297. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-smile.gif +0 -0
  298. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-surprised.gif +0 -0
  299. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-tongue-out.gif +0 -0
  300. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-undecided.gif +0 -0
  301. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-wink.gif +0 -0
  302. data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-yell.gif +0 -0
  303. data/apps/core/components/public/js/tinymce/plugins/emoticons/plugin.js +65 -0
  304. data/apps/core/components/public/js/tinymce/plugins/emoticons/plugin.min.js +1 -0
  305. data/apps/core/components/public/js/tinymce/plugins/example/dialog.html +8 -0
  306. data/apps/core/components/public/js/tinymce/plugins/example/plugin.js +68 -0
  307. data/apps/core/components/public/js/tinymce/plugins/example/plugin.min.js +1 -0
  308. data/apps/core/components/public/js/tinymce/plugins/example_dependency/plugin.js +22 -0
  309. data/apps/core/components/public/js/tinymce/plugins/example_dependency/plugin.min.js +1 -0
  310. data/apps/core/components/public/js/tinymce/plugins/fullpage/plugin.js +490 -0
  311. data/apps/core/components/public/js/tinymce/plugins/fullpage/plugin.min.js +1 -0
  312. data/apps/core/components/public/js/tinymce/plugins/fullscreen/plugin.js +154 -0
  313. data/apps/core/components/public/js/tinymce/plugins/fullscreen/plugin.min.js +1 -0
  314. data/apps/core/components/public/js/tinymce/plugins/hr/plugin.js +30 -0
  315. data/apps/core/components/public/js/tinymce/plugins/hr/plugin.min.js +1 -0
  316. data/apps/core/components/public/js/tinymce/plugins/image/plugin.js +630 -0
  317. data/apps/core/components/public/js/tinymce/plugins/image/plugin.min.js +1 -0
  318. data/apps/core/components/public/js/tinymce/plugins/imagetools/config/bolt/atomic.js +6 -0
  319. data/apps/core/components/public/js/tinymce/plugins/imagetools/config/bolt/browser.js +6 -0
  320. data/apps/core/components/public/js/tinymce/plugins/imagetools/config/bolt/demo.js +8 -0
  321. data/apps/core/components/public/js/tinymce/plugins/imagetools/config/bolt/prod.js +6 -0
  322. data/apps/core/components/public/js/tinymce/plugins/imagetools/plugin.js +2668 -0
  323. data/apps/core/components/public/js/tinymce/plugins/imagetools/plugin.min.js +1 -0
  324. data/apps/core/components/public/js/tinymce/plugins/imagetools/src/demo/html/demo.html +16 -0
  325. data/apps/core/components/public/js/tinymce/plugins/imagetools/src/demo/js/Demo.js +92 -0
  326. data/apps/core/components/public/js/tinymce/plugins/imagetools/src/main/js/CropRect.js +214 -0
  327. data/apps/core/components/public/js/tinymce/plugins/imagetools/src/main/js/Dialog.js +485 -0
  328. data/apps/core/components/public/js/tinymce/plugins/imagetools/src/main/js/ImagePanel.js +218 -0
  329. data/apps/core/components/public/js/tinymce/plugins/imagetools/src/main/js/Plugin.js +411 -0
  330. data/apps/core/components/public/js/tinymce/plugins/imagetools/src/main/js/UndoStack.js +57 -0
  331. data/apps/core/components/public/js/tinymce/plugins/importcss/plugin.js +227 -0
  332. data/apps/core/components/public/js/tinymce/plugins/importcss/plugin.min.js +1 -0
  333. data/apps/core/components/public/js/tinymce/plugins/insertdatetime/plugin.js +121 -0
  334. data/apps/core/components/public/js/tinymce/plugins/insertdatetime/plugin.min.js +1 -0
  335. data/apps/core/components/public/js/tinymce/plugins/layer/plugin.js +225 -0
  336. data/apps/core/components/public/js/tinymce/plugins/layer/plugin.min.js +1 -0
  337. data/apps/core/components/public/js/tinymce/plugins/legacyoutput/plugin.js +211 -0
  338. data/apps/core/components/public/js/tinymce/plugins/legacyoutput/plugin.min.js +1 -0
  339. data/apps/core/components/public/js/tinymce/plugins/link/plugin.js +403 -0
  340. data/apps/core/components/public/js/tinymce/plugins/link/plugin.min.js +1 -0
  341. data/apps/core/components/public/js/tinymce/plugins/lists/plugin.js +885 -0
  342. data/apps/core/components/public/js/tinymce/plugins/lists/plugin.min.js +1 -0
  343. data/apps/core/components/public/js/tinymce/plugins/media/moxieplayer.swf +0 -0
  344. data/apps/core/components/public/js/tinymce/plugins/media/plugin.js +878 -0
  345. data/apps/core/components/public/js/tinymce/plugins/media/plugin.min.js +1 -0
  346. data/apps/core/components/public/js/tinymce/plugins/nonbreaking/plugin.js +53 -0
  347. data/apps/core/components/public/js/tinymce/plugins/nonbreaking/plugin.min.js +1 -0
  348. data/apps/core/components/public/js/tinymce/plugins/noneditable/plugin.js +101 -0
  349. data/apps/core/components/public/js/tinymce/plugins/noneditable/plugin.min.js +1 -0
  350. data/apps/core/components/public/js/tinymce/plugins/pagebreak/plugin.js +88 -0
  351. data/apps/core/components/public/js/tinymce/plugins/pagebreak/plugin.min.js +1 -0
  352. data/apps/core/components/public/js/tinymce/plugins/paste/classes/Clipboard.js +672 -0
  353. data/apps/core/components/public/js/tinymce/plugins/paste/classes/Plugin.js +121 -0
  354. data/apps/core/components/public/js/tinymce/plugins/paste/classes/Quirks.js +159 -0
  355. data/apps/core/components/public/js/tinymce/plugins/paste/classes/Utils.js +140 -0
  356. data/apps/core/components/public/js/tinymce/plugins/paste/classes/WordFilter.js +500 -0
  357. data/apps/core/components/public/js/tinymce/plugins/paste/plugin.dev.js +142 -0
  358. data/apps/core/components/public/js/tinymce/plugins/paste/plugin.js +1708 -0
  359. data/apps/core/components/public/js/tinymce/plugins/paste/plugin.min.js +1 -0
  360. data/apps/core/components/public/js/tinymce/plugins/preview/plugin.js +88 -0
  361. data/apps/core/components/public/js/tinymce/plugins/preview/plugin.min.js +1 -0
  362. data/apps/core/components/public/js/tinymce/plugins/print/plugin.js +32 -0
  363. data/apps/core/components/public/js/tinymce/plugins/print/plugin.min.js +1 -0
  364. data/apps/core/components/public/js/tinymce/plugins/save/plugin.js +98 -0
  365. data/apps/core/components/public/js/tinymce/plugins/save/plugin.min.js +1 -0
  366. data/apps/core/components/public/js/tinymce/plugins/searchreplace/plugin.js +609 -0
  367. data/apps/core/components/public/js/tinymce/plugins/searchreplace/plugin.min.js +1 -0
  368. data/apps/core/components/public/js/tinymce/plugins/spellchecker/classes/DomTextMatcher.js +480 -0
  369. data/apps/core/components/public/js/tinymce/plugins/spellchecker/classes/Plugin.js +439 -0
  370. data/apps/core/components/public/js/tinymce/plugins/spellchecker/plugin.dev.js +139 -0
  371. data/apps/core/components/public/js/tinymce/plugins/spellchecker/plugin.js +1026 -0
  372. data/apps/core/components/public/js/tinymce/plugins/spellchecker/plugin.min.js +1 -0
  373. data/apps/core/components/public/js/tinymce/plugins/tabfocus/plugin.js +120 -0
  374. data/apps/core/components/public/js/tinymce/plugins/tabfocus/plugin.min.js +1 -0
  375. data/apps/core/components/public/js/tinymce/plugins/table/classes/CellSelection.js +202 -0
  376. data/apps/core/components/public/js/tinymce/plugins/table/classes/Dialogs.js +824 -0
  377. data/apps/core/components/public/js/tinymce/plugins/table/classes/Plugin.js +599 -0
  378. data/apps/core/components/public/js/tinymce/plugins/table/classes/Quirks.js +400 -0
  379. data/apps/core/components/public/js/tinymce/plugins/table/classes/ResizeBars.js +984 -0
  380. data/apps/core/components/public/js/tinymce/plugins/table/classes/TableGrid.js +941 -0
  381. data/apps/core/components/public/js/tinymce/plugins/table/classes/Utils.js +36 -0
  382. data/apps/core/components/public/js/tinymce/plugins/table/plugin.dev.js +142 -0
  383. data/apps/core/components/public/js/tinymce/plugins/table/plugin.js +4106 -0
  384. data/apps/core/components/public/js/tinymce/plugins/table/plugin.min.js +2 -0
  385. data/apps/core/components/public/js/tinymce/plugins/template/plugin.js +270 -0
  386. data/apps/core/components/public/js/tinymce/plugins/template/plugin.min.js +1 -0
  387. data/apps/core/components/public/js/tinymce/plugins/textcolor/plugin.js +282 -0
  388. data/apps/core/components/public/js/tinymce/plugins/textcolor/plugin.min.js +1 -0
  389. data/apps/core/components/public/js/tinymce/plugins/textpattern/plugin.js +268 -0
  390. data/apps/core/components/public/js/tinymce/plugins/textpattern/plugin.min.js +1 -0
  391. data/apps/core/components/public/js/tinymce/plugins/visualblocks/css/visualblocks.css +135 -0
  392. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/address.gif +0 -0
  393. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/article.gif +0 -0
  394. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/aside.gif +0 -0
  395. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/blockquote.gif +0 -0
  396. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/div.gif +0 -0
  397. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/dl.gif +0 -0
  398. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/figure.gif +0 -0
  399. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h1.gif +0 -0
  400. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h2.gif +0 -0
  401. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h3.gif +0 -0
  402. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h4.gif +0 -0
  403. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h5.gif +0 -0
  404. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h6.gif +0 -0
  405. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/hgroup.gif +0 -0
  406. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/ol.gif +0 -0
  407. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/p.gif +0 -0
  408. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/pre.gif +0 -0
  409. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/section.gif +0 -0
  410. data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/ul.gif +0 -0
  411. data/apps/core/components/public/js/tinymce/plugins/visualblocks/plugin.js +86 -0
  412. data/apps/core/components/public/js/tinymce/plugins/visualblocks/plugin.min.js +1 -0
  413. data/apps/core/components/public/js/tinymce/plugins/visualchars/plugin.js +123 -0
  414. data/apps/core/components/public/js/tinymce/plugins/visualchars/plugin.min.js +1 -0
  415. data/apps/core/components/public/js/tinymce/plugins/wordcount/plugin.js +69 -0
  416. data/apps/core/components/public/js/tinymce/plugins/wordcount/plugin.min.js +1 -0
  417. data/apps/core/components/public/js/tinymce/skins/lightgray/AbsoluteLayout.less +17 -0
  418. data/apps/core/components/public/js/tinymce/skins/lightgray/Animations.less +10 -0
  419. data/apps/core/components/public/js/tinymce/skins/lightgray/Button.less +172 -0
  420. data/apps/core/components/public/js/tinymce/skins/lightgray/ButtonGroup.less +71 -0
  421. data/apps/core/components/public/js/tinymce/skins/lightgray/Checkbox.less +49 -0
  422. data/apps/core/components/public/js/tinymce/skins/lightgray/ColorBox.less +6 -0
  423. data/apps/core/components/public/js/tinymce/skins/lightgray/ColorButton.less +72 -0
  424. data/apps/core/components/public/js/tinymce/skins/lightgray/ColorPicker.less +80 -0
  425. data/apps/core/components/public/js/tinymce/skins/lightgray/ComboBox.less +39 -0
  426. data/apps/core/components/public/js/tinymce/skins/lightgray/Container.less +9 -0
  427. data/apps/core/components/public/js/tinymce/skins/lightgray/Content.Inline.less +4 -0
  428. data/apps/core/components/public/js/tinymce/skins/lightgray/Content.Objects.less +166 -0
  429. data/apps/core/components/public/js/tinymce/skins/lightgray/Content.less +27 -0
  430. data/apps/core/components/public/js/tinymce/skins/lightgray/CropRect.less +54 -0
  431. data/apps/core/components/public/js/tinymce/skins/lightgray/FieldSet.less +15 -0
  432. data/apps/core/components/public/js/tinymce/skins/lightgray/FitLayout.less +9 -0
  433. data/apps/core/components/public/js/tinymce/skins/lightgray/FloatPanel.less +69 -0
  434. data/apps/core/components/public/js/tinymce/skins/lightgray/FlowLayout.less +36 -0
  435. data/apps/core/components/public/js/tinymce/skins/lightgray/Icons.Ie7.less +136 -0
  436. data/apps/core/components/public/js/tinymce/skins/lightgray/Icons.less +180 -0
  437. data/apps/core/components/public/js/tinymce/skins/lightgray/Iframe.less +6 -0
  438. data/apps/core/components/public/js/tinymce/skins/lightgray/ImagePanel.less +20 -0
  439. data/apps/core/components/public/js/tinymce/skins/lightgray/InfoBox.less +71 -0
  440. data/apps/core/components/public/js/tinymce/skins/lightgray/Label.less +38 -0
  441. data/apps/core/components/public/js/tinymce/skins/lightgray/ListBox.less +26 -0
  442. data/apps/core/components/public/js/tinymce/skins/lightgray/Menu.less +34 -0
  443. data/apps/core/components/public/js/tinymce/skins/lightgray/MenuBar.less +32 -0
  444. data/apps/core/components/public/js/tinymce/skins/lightgray/MenuButton.less +34 -0
  445. data/apps/core/components/public/js/tinymce/skins/lightgray/MenuItem.less +142 -0
  446. data/apps/core/components/public/js/tinymce/skins/lightgray/Mixins.less +54 -0
  447. data/apps/core/components/public/js/tinymce/skins/lightgray/Notification.less +144 -0
  448. data/apps/core/components/public/js/tinymce/skins/lightgray/Panel.less +7 -0
  449. data/apps/core/components/public/js/tinymce/skins/lightgray/Path.less +45 -0
  450. data/apps/core/components/public/js/tinymce/skins/lightgray/Progress.less +34 -0
  451. data/apps/core/components/public/js/tinymce/skins/lightgray/Radio.less +1 -0
  452. data/apps/core/components/public/js/tinymce/skins/lightgray/Reset.less +32 -0
  453. data/apps/core/components/public/js/tinymce/skins/lightgray/ResizeHandle.less +18 -0
  454. data/apps/core/components/public/js/tinymce/skins/lightgray/Scrollable.less +44 -0
  455. data/apps/core/components/public/js/tinymce/skins/lightgray/SelectBox.less +6 -0
  456. data/apps/core/components/public/js/tinymce/skins/lightgray/Slider.less +29 -0
  457. data/apps/core/components/public/js/tinymce/skins/lightgray/Spacer.less +5 -0
  458. data/apps/core/components/public/js/tinymce/skins/lightgray/SplitButton.less +49 -0
  459. data/apps/core/components/public/js/tinymce/skins/lightgray/StackLayout.less +5 -0
  460. data/apps/core/components/public/js/tinymce/skins/lightgray/TabPanel.less +44 -0
  461. data/apps/core/components/public/js/tinymce/skins/lightgray/TextBox.less +41 -0
  462. data/apps/core/components/public/js/tinymce/skins/lightgray/Throbber.less +19 -0
  463. data/apps/core/components/public/js/tinymce/skins/lightgray/TinyMCE.less +159 -0
  464. data/apps/core/components/public/js/tinymce/skins/lightgray/ToolTip.less +129 -0
  465. data/apps/core/components/public/js/tinymce/skins/lightgray/Variables.less +214 -0
  466. data/apps/core/components/public/js/tinymce/skins/lightgray/Window.less +127 -0
  467. data/apps/core/components/public/js/tinymce/skins/lightgray/content.inline.min.css +1 -0
  468. data/apps/core/components/public/js/tinymce/skins/lightgray/content.min.css +1 -0
  469. data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/readme.md +1 -0
  470. data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce-small.eot +0 -0
  471. data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce-small.json +1277 -0
  472. data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce-small.svg +63 -0
  473. data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce-small.ttf +0 -0
  474. data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce-small.woff +0 -0
  475. data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce.eot +0 -0
  476. data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce.json +3381 -0
  477. data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce.svg +129 -0
  478. data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce.ttf +0 -0
  479. data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce.woff +0 -0
  480. data/apps/core/components/public/js/tinymce/skins/lightgray/img/anchor.gif +0 -0
  481. data/apps/core/components/public/js/tinymce/skins/lightgray/img/loader.gif +0 -0
  482. data/apps/core/components/public/js/tinymce/skins/lightgray/img/object.gif +0 -0
  483. data/apps/core/components/public/js/tinymce/skins/lightgray/img/trans.gif +0 -0
  484. data/apps/core/components/public/js/tinymce/skins/lightgray/skin.dev.less +46 -0
  485. data/apps/core/components/public/js/tinymce/skins/lightgray/skin.ie7.dev.less +46 -0
  486. data/apps/core/components/public/js/tinymce/skins/lightgray/skin.ie7.less +2542 -0
  487. data/apps/core/components/public/js/tinymce/skins/lightgray/skin.ie7.min.css +1 -0
  488. data/apps/core/components/public/js/tinymce/skins/lightgray/skin.less +2586 -0
  489. data/apps/core/components/public/js/tinymce/skins/lightgray/skin.min.css +1 -0
  490. data/apps/core/components/public/js/tinymce/themes/modern/theme.js +878 -0
  491. data/apps/core/components/public/js/tinymce/themes/modern/theme.min.js +1 -0
  492. data/apps/core/components/public/js/tinymce/tinymce.dev.js +286 -0
  493. data/apps/core/components/public/js/tinymce/tinymce.js +45811 -0
  494. data/apps/core/components/public/js/tinymce/tinymce.min.js +13 -0
  495. data/apps/core/forms/widgets/form/form.rb +3 -1
  496. data/apps/core/forms/widgets/form/form.shtml +1 -0
  497. data/apps/core/forms/widgets/inputs/search_select/search_select.rb +1 -1
  498. data/apps/core/forms/widgets/inputs/select/select.rb +1 -1
  499. data/apps/core/forms/widgets/inputs/select/select.shtml +0 -1
  500. data/apps/messenger/backends/sms/skebby.rb +1 -1
  501. data/apps/messenger/controllers/mixins/messenger_helper.rb +23 -5
  502. data/lib/spiderfw/config/options/spider.rb +1 -1
  503. data/lib/spiderfw/controller/mixins/visual.rb +2 -0
  504. data/lib/spiderfw/http/adapters/rack.rb +10 -5
  505. data/lib/spiderfw/http/http.rb +4 -2
  506. data/lib/spiderfw/model/base_model.rb +4 -4
  507. data/lib/spiderfw/model/mappers/db_mapper.rb +4 -2
  508. data/lib/spiderfw/model/storage/db/adapters/mysql.rb +2 -1
  509. data/lib/spiderfw/model/storage/db/db_storage.rb +4 -0
  510. data/lib/spiderfw/spider.rb +6 -0
  511. data/lib/spiderfw/templates/layout.rb +1 -1
  512. data/lib/spiderfw/utils/monkey/object.rb +3 -0
  513. data/spider.gemspec +6 -2
  514. metadata +539 -42
  515. data/blueprints/.DS_Store +0 -0
@@ -0,0 +1,1701 @@
1
+ /**
2
+ * Quirks.js
3
+ *
4
+ * Released under LGPL License.
5
+ * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
6
+ *
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
+ *
10
+ * @ignore-file
11
+ */
12
+
13
+ /**
14
+ * This file includes fixes for various browser quirks it's made to make it easy to add/remove browser specific fixes.
15
+ *
16
+ * @private
17
+ * @class tinymce.util.Quirks
18
+ */
19
+ define("tinymce/util/Quirks", [
20
+ "tinymce/util/VK",
21
+ "tinymce/dom/RangeUtils",
22
+ "tinymce/dom/TreeWalker",
23
+ "tinymce/dom/NodePath",
24
+ "tinymce/html/Node",
25
+ "tinymce/html/Entities",
26
+ "tinymce/Env",
27
+ "tinymce/util/Tools",
28
+ "tinymce/util/Delay",
29
+ "tinymce/caret/CaretContainer"
30
+ ], function(VK, RangeUtils, TreeWalker, NodePath, Node, Entities, Env, Tools, Delay, CaretContainer) {
31
+ return function(editor) {
32
+ var each = Tools.each, $ = editor.$;
33
+ var BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection,
34
+ settings = editor.settings, parser = editor.parser, serializer = editor.serializer;
35
+ var isGecko = Env.gecko, isIE = Env.ie, isWebKit = Env.webkit;
36
+ var mceInternalUrlPrefix = 'data:text/mce-internal,';
37
+ var mceInternalDataType = isIE ? 'Text' : 'URL';
38
+
39
+ /**
40
+ * Executes a command with a specific state this can be to enable/disable browser editing features.
41
+ */
42
+ function setEditorCommandState(cmd, state) {
43
+ try {
44
+ editor.getDoc().execCommand(cmd, false, state);
45
+ } catch (ex) {
46
+ // Ignore
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Returns current IE document mode.
52
+ */
53
+ function getDocumentMode() {
54
+ var documentMode = editor.getDoc().documentMode;
55
+
56
+ return documentMode ? documentMode : 6;
57
+ }
58
+
59
+ /**
60
+ * Returns true/false if the event is prevented or not.
61
+ *
62
+ * @private
63
+ * @param {Event} e Event object.
64
+ * @return {Boolean} true/false if the event is prevented or not.
65
+ */
66
+ function isDefaultPrevented(e) {
67
+ return e.isDefaultPrevented();
68
+ }
69
+
70
+ /**
71
+ * Sets Text/URL data on the event's dataTransfer object to a special data:text/mce-internal url.
72
+ * This is to workaround the inability to set custom contentType on IE and Safari.
73
+ * The editor's selected content is encoded into this url so drag and drop between editors will work.
74
+ *
75
+ * @private
76
+ * @param {DragEvent} e Event object
77
+ */
78
+ function setMceInteralContent(e) {
79
+ var selectionHtml, internalContent;
80
+
81
+ if (e.dataTransfer) {
82
+ if (editor.selection.isCollapsed() && e.target.tagName == 'IMG') {
83
+ selection.select(e.target);
84
+ }
85
+
86
+ selectionHtml = editor.selection.getContent();
87
+
88
+ // Safari/IE doesn't support custom dataTransfer items so we can only use URL and Text
89
+ if (selectionHtml.length > 0) {
90
+ internalContent = mceInternalUrlPrefix + escape(editor.id) + ',' + escape(selectionHtml);
91
+ e.dataTransfer.setData(mceInternalDataType, internalContent);
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Gets content of special data:text/mce-internal url on the event's dataTransfer object.
98
+ * This is to workaround the inability to set custom contentType on IE and Safari.
99
+ * The editor's selected content is encoded into this url so drag and drop between editors will work.
100
+ *
101
+ * @private
102
+ * @param {DragEvent} e Event object
103
+ * @returns {String} mce-internal content
104
+ */
105
+ function getMceInternalContent(e) {
106
+ var internalContent;
107
+
108
+ if (e.dataTransfer) {
109
+ internalContent = e.dataTransfer.getData(mceInternalDataType);
110
+
111
+ if (internalContent && internalContent.indexOf(mceInternalUrlPrefix) >= 0) {
112
+ internalContent = internalContent.substr(mceInternalUrlPrefix.length).split(',');
113
+
114
+ return {
115
+ id: unescape(internalContent[0]),
116
+ html: unescape(internalContent[1])
117
+ };
118
+ }
119
+ }
120
+
121
+ return null;
122
+ }
123
+
124
+ /**
125
+ * Inserts contents using the paste clipboard command if it's available if it isn't it will fallback
126
+ * to the core command.
127
+ *
128
+ * @private
129
+ * @param {String} content Content to insert at selection.
130
+ */
131
+ function insertClipboardContents(content) {
132
+ if (editor.queryCommandSupported('mceInsertClipboardContent')) {
133
+ editor.execCommand('mceInsertClipboardContent', false, {content: content});
134
+ } else {
135
+ editor.execCommand('mceInsertContent', false, content);
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Fixes a WebKit bug when deleting contents using backspace or delete key.
141
+ * WebKit will produce a span element if you delete across two block elements.
142
+ *
143
+ * Example:
144
+ * <h1>a</h1><p>|b</p>
145
+ *
146
+ * Will produce this on backspace:
147
+ * <h1>a<span style="<all runtime styles>">b</span></p>
148
+ *
149
+ * This fixes the backspace to produce:
150
+ * <h1>a|b</p>
151
+ *
152
+ * See bug: https://bugs.webkit.org/show_bug.cgi?id=45784
153
+ *
154
+ * This fixes the following delete scenarios:
155
+ * 1. Delete by pressing backspace key.
156
+ * 2. Delete by pressing delete key.
157
+ * 3. Delete by pressing backspace key with ctrl/cmd (Word delete).
158
+ * 4. Delete by pressing delete key with ctrl/cmd (Word delete).
159
+ * 5. Delete by drag/dropping contents inside the editor.
160
+ * 6. Delete by using Cut Ctrl+X/Cmd+X.
161
+ * 7. Delete by selecting contents and writing a character.
162
+ *
163
+ * This code is a ugly hack since writing full custom delete logic for just this bug
164
+ * fix seemed like a huge task. I hope we can remove this before the year 2030.
165
+ */
166
+ function cleanupStylesWhenDeleting() {
167
+ var doc = editor.getDoc(), dom = editor.dom, selection = editor.selection;
168
+ var MutationObserver = window.MutationObserver, olderWebKit, dragStartRng;
169
+
170
+ // Add mini polyfill for older WebKits
171
+ // TODO: Remove this when old Safari versions gets updated
172
+ if (!MutationObserver) {
173
+ olderWebKit = true;
174
+
175
+ MutationObserver = function() {
176
+ var records = [], target;
177
+
178
+ function nodeInsert(e) {
179
+ var target = e.relatedNode || e.target;
180
+ records.push({target: target, addedNodes: [target]});
181
+ }
182
+
183
+ function attrModified(e) {
184
+ var target = e.relatedNode || e.target;
185
+ records.push({target: target, attributeName: e.attrName});
186
+ }
187
+
188
+ this.observe = function(node) {
189
+ target = node;
190
+ target.addEventListener('DOMSubtreeModified', nodeInsert, false);
191
+ target.addEventListener('DOMNodeInsertedIntoDocument', nodeInsert, false);
192
+ target.addEventListener('DOMNodeInserted', nodeInsert, false);
193
+ target.addEventListener('DOMAttrModified', attrModified, false);
194
+ };
195
+
196
+ this.disconnect = function() {
197
+ target.removeEventListener('DOMSubtreeModified', nodeInsert, false);
198
+ target.removeEventListener('DOMNodeInsertedIntoDocument', nodeInsert, false);
199
+ target.removeEventListener('DOMNodeInserted', nodeInsert, false);
200
+ target.removeEventListener('DOMAttrModified', attrModified, false);
201
+ };
202
+
203
+ this.takeRecords = function() {
204
+ return records;
205
+ };
206
+ };
207
+ }
208
+
209
+ function isTrailingBr(node) {
210
+ var blockElements = dom.schema.getBlockElements(), rootNode = editor.getBody();
211
+
212
+ if (node.nodeName != 'BR') {
213
+ return false;
214
+ }
215
+
216
+ for (; node != rootNode && !blockElements[node.nodeName]; node = node.parentNode) {
217
+ if (node.nextSibling) {
218
+ return false;
219
+ }
220
+ }
221
+
222
+ return true;
223
+ }
224
+
225
+ function isSiblingsIgnoreWhiteSpace(node1, node2) {
226
+ var node;
227
+
228
+ for (node = node1.nextSibling; node && node != node2; node = node.nextSibling) {
229
+ if (node.nodeType == 3 && $.trim(node.data).length === 0) {
230
+ continue;
231
+ }
232
+
233
+ if (node !== node2) {
234
+ return false;
235
+ }
236
+ }
237
+
238
+ return node === node2;
239
+ }
240
+
241
+ function findCaretNode(node, forward, startNode) {
242
+ var walker, current, nonEmptyElements;
243
+
244
+ nonEmptyElements = dom.schema.getNonEmptyElements();
245
+
246
+ walker = new TreeWalker(startNode || node, node);
247
+
248
+ while ((current = walker[forward ? 'next' : 'prev']())) {
249
+ if (nonEmptyElements[current.nodeName] && !isTrailingBr(current)) {
250
+ return current;
251
+ }
252
+
253
+ if (current.nodeType == 3 && current.data.length > 0) {
254
+ return current;
255
+ }
256
+ }
257
+ }
258
+
259
+ function deleteRangeBetweenTextBlocks(rng) {
260
+ var startBlock, endBlock, caretNodeBefore, caretNodeAfter, textBlockElements;
261
+
262
+ if (rng.collapsed) {
263
+ return;
264
+ }
265
+
266
+ startBlock = dom.getParent(RangeUtils.getNode(rng.startContainer, rng.startOffset), dom.isBlock);
267
+ endBlock = dom.getParent(RangeUtils.getNode(rng.endContainer, rng.endOffset), dom.isBlock);
268
+ textBlockElements = editor.schema.getTextBlockElements();
269
+
270
+ if (startBlock == endBlock) {
271
+ return;
272
+ }
273
+
274
+ if (!textBlockElements[startBlock.nodeName] || !textBlockElements[endBlock.nodeName]) {
275
+ return;
276
+ }
277
+
278
+ if (dom.getContentEditable(startBlock) === "false" || dom.getContentEditable(endBlock) === "false") {
279
+ return;
280
+ }
281
+
282
+ rng.deleteContents();
283
+
284
+ caretNodeBefore = findCaretNode(startBlock, false);
285
+ caretNodeAfter = findCaretNode(endBlock, true);
286
+
287
+ if (!dom.isEmpty(endBlock)) {
288
+ $(startBlock).append(endBlock.childNodes);
289
+ }
290
+
291
+ $(endBlock).remove();
292
+
293
+ if (caretNodeBefore) {
294
+ if (caretNodeBefore.nodeType == 1) {
295
+ if (caretNodeBefore.nodeName == "BR") {
296
+ rng.setStartBefore(caretNodeBefore);
297
+ rng.setEndBefore(caretNodeBefore);
298
+ } else {
299
+ rng.setStartAfter(caretNodeBefore);
300
+ rng.setEndAfter(caretNodeBefore);
301
+ }
302
+ } else {
303
+ rng.setStart(caretNodeBefore, caretNodeBefore.data.length);
304
+ rng.setEnd(caretNodeBefore, caretNodeBefore.data.length);
305
+ }
306
+ } else if (caretNodeAfter) {
307
+ if (caretNodeAfter.nodeType == 1) {
308
+ rng.setStartBefore(caretNodeAfter);
309
+ rng.setEndBefore(caretNodeAfter);
310
+ } else {
311
+ rng.setStart(caretNodeAfter, 0);
312
+ rng.setEnd(caretNodeAfter, 0);
313
+ }
314
+ }
315
+
316
+ selection.setRng(rng);
317
+
318
+ return true;
319
+ }
320
+
321
+ function expandBetweenBlocks(rng, isForward) {
322
+ var caretNode, targetCaretNode, textBlock, targetTextBlock, container, offset;
323
+
324
+ if (!rng.collapsed) {
325
+ return rng;
326
+ }
327
+
328
+ container = rng.startContainer;
329
+ offset = rng.startOffset;
330
+
331
+ if (container.nodeType == 3) {
332
+ if (isForward) {
333
+ if (offset < container.data.length) {
334
+ return rng;
335
+ }
336
+ } else {
337
+ if (offset > 0) {
338
+ return rng;
339
+ }
340
+ }
341
+ }
342
+
343
+ caretNode = RangeUtils.getNode(rng.startContainer, rng.startOffset);
344
+ textBlock = dom.getParent(caretNode, dom.isBlock);
345
+ targetCaretNode = findCaretNode(editor.getBody(), isForward, caretNode);
346
+ targetTextBlock = dom.getParent(targetCaretNode, dom.isBlock);
347
+
348
+ if (!caretNode || !targetCaretNode) {
349
+ return rng;
350
+ }
351
+
352
+ if (targetTextBlock && textBlock != targetTextBlock) {
353
+ if (!isForward) {
354
+ if (!isSiblingsIgnoreWhiteSpace(targetTextBlock, textBlock)) {
355
+ return rng;
356
+ }
357
+
358
+ if (targetCaretNode.nodeType == 1) {
359
+ if (targetCaretNode.nodeName == "BR") {
360
+ rng.setStartBefore(targetCaretNode);
361
+ } else {
362
+ rng.setStartAfter(targetCaretNode);
363
+ }
364
+ } else {
365
+ rng.setStart(targetCaretNode, targetCaretNode.data.length);
366
+ }
367
+
368
+ if (caretNode.nodeType == 1) {
369
+ rng.setEnd(caretNode, 0);
370
+ } else {
371
+ rng.setEndBefore(caretNode);
372
+ }
373
+ } else {
374
+ if (!isSiblingsIgnoreWhiteSpace(textBlock, targetTextBlock)) {
375
+ return rng;
376
+ }
377
+
378
+ if (caretNode.nodeType == 1) {
379
+ if (caretNode.nodeName == "BR") {
380
+ rng.setStartBefore(caretNode);
381
+ } else {
382
+ rng.setStartAfter(caretNode);
383
+ }
384
+ } else {
385
+ rng.setStart(caretNode, caretNode.data.length);
386
+ }
387
+
388
+ if (targetCaretNode.nodeType == 1) {
389
+ rng.setEnd(targetCaretNode, 0);
390
+ } else {
391
+ rng.setEndBefore(targetCaretNode);
392
+ }
393
+ }
394
+ }
395
+
396
+ return rng;
397
+ }
398
+
399
+ function handleTextBlockMergeDelete(isForward) {
400
+ var rng = selection.getRng();
401
+
402
+ rng = expandBetweenBlocks(rng, isForward);
403
+
404
+ if (deleteRangeBetweenTextBlocks(rng)) {
405
+ return true;
406
+ }
407
+ }
408
+
409
+ /**
410
+ * This retains the formatting if the last character is to be deleted.
411
+ *
412
+ * Backspace on this: <p><b><i>a|</i></b></p> would become <p>|</p> in WebKit.
413
+ * With this patch: <p><b><i>|<br></i></b></p>
414
+ */
415
+ function handleLastBlockCharacterDelete(isForward, rng) {
416
+ var path, blockElm, newBlockElm, clonedBlockElm, sibling,
417
+ container, offset, br, currentFormatNodes;
418
+
419
+ function cloneTextBlockWithFormats(blockElm, node) {
420
+ currentFormatNodes = $(node).parents().filter(function(idx, node) {
421
+ return !!editor.schema.getTextInlineElements()[node.nodeName];
422
+ });
423
+
424
+ newBlockElm = blockElm.cloneNode(false);
425
+
426
+ currentFormatNodes = Tools.map(currentFormatNodes, function(formatNode) {
427
+ formatNode = formatNode.cloneNode(false);
428
+
429
+ if (newBlockElm.hasChildNodes()) {
430
+ formatNode.appendChild(newBlockElm.firstChild);
431
+ newBlockElm.appendChild(formatNode);
432
+ } else {
433
+ newBlockElm.appendChild(formatNode);
434
+ }
435
+
436
+ newBlockElm.appendChild(formatNode);
437
+
438
+ return formatNode;
439
+ });
440
+
441
+ if (currentFormatNodes.length) {
442
+ br = dom.create('br');
443
+ currentFormatNodes[0].appendChild(br);
444
+ dom.replace(newBlockElm, blockElm);
445
+
446
+ rng.setStartBefore(br);
447
+ rng.setEndBefore(br);
448
+ editor.selection.setRng(rng);
449
+
450
+ return br;
451
+ }
452
+
453
+ return null;
454
+ }
455
+
456
+ function isTextBlock(node) {
457
+ return node && editor.schema.getTextBlockElements()[node.tagName];
458
+ }
459
+
460
+ if (!rng.collapsed) {
461
+ return;
462
+ }
463
+
464
+ container = rng.startContainer;
465
+ offset = rng.startOffset;
466
+ blockElm = dom.getParent(container, dom.isBlock);
467
+ if (!isTextBlock(blockElm)) {
468
+ return;
469
+ }
470
+
471
+ if (container.nodeType == 1) {
472
+ container = container.childNodes[offset];
473
+ if (container && container.tagName != 'BR') {
474
+ return;
475
+ }
476
+
477
+ if (isForward) {
478
+ sibling = blockElm.nextSibling;
479
+ } else {
480
+ sibling = blockElm.previousSibling;
481
+ }
482
+
483
+ if (dom.isEmpty(blockElm) && isTextBlock(sibling) && dom.isEmpty(sibling)) {
484
+ if (cloneTextBlockWithFormats(blockElm, container)) {
485
+ dom.remove(sibling);
486
+ return true;
487
+ }
488
+ }
489
+ } else if (container.nodeType == 3) {
490
+ path = NodePath.create(blockElm, container);
491
+ clonedBlockElm = blockElm.cloneNode(true);
492
+ container = NodePath.resolve(clonedBlockElm, path);
493
+
494
+ if (isForward) {
495
+ if (offset >= container.data.length) {
496
+ return;
497
+ }
498
+
499
+ container.deleteData(offset, 1);
500
+ } else {
501
+ if (offset <= 0) {
502
+ return;
503
+ }
504
+
505
+ container.deleteData(offset - 1, 1);
506
+ }
507
+
508
+ if (dom.isEmpty(clonedBlockElm)) {
509
+ return cloneTextBlockWithFormats(blockElm, container);
510
+ }
511
+ }
512
+ }
513
+
514
+ function customDelete(isForward) {
515
+ var mutationObserver, rng, caretElement;
516
+
517
+ if (handleTextBlockMergeDelete(isForward)) {
518
+ return;
519
+ }
520
+
521
+ Tools.each(editor.getBody().getElementsByTagName('*'), function(elm) {
522
+ // Mark existing spans
523
+ if (elm.tagName == 'SPAN') {
524
+ elm.setAttribute('mce-data-marked', 1);
525
+ }
526
+
527
+ // Make sure all elements has a data-mce-style attribute
528
+ if (!elm.hasAttribute('data-mce-style') && elm.hasAttribute('style')) {
529
+ editor.dom.setAttrib(elm, 'style', editor.dom.getAttrib(elm, 'style'));
530
+ }
531
+ });
532
+
533
+ // Observe added nodes and style attribute changes
534
+ mutationObserver = new MutationObserver(function() {});
535
+ mutationObserver.observe(editor.getDoc(), {
536
+ childList: true,
537
+ attributes: true,
538
+ subtree: true,
539
+ attributeFilter: ['style']
540
+ });
541
+
542
+ editor.getDoc().execCommand(isForward ? 'ForwardDelete' : 'Delete', false, null);
543
+
544
+ rng = editor.selection.getRng();
545
+ caretElement = rng.startContainer.parentNode;
546
+
547
+ Tools.each(mutationObserver.takeRecords(), function(record) {
548
+ if (!dom.isChildOf(record.target, editor.getBody())) {
549
+ return;
550
+ }
551
+
552
+ // Restore style attribute to previous value
553
+ if (record.attributeName == "style") {
554
+ var oldValue = record.target.getAttribute('data-mce-style');
555
+
556
+ if (oldValue) {
557
+ record.target.setAttribute("style", oldValue);
558
+ } else {
559
+ record.target.removeAttribute("style");
560
+ }
561
+ }
562
+
563
+ // Remove all spans that aren't marked and retain selection
564
+ Tools.each(record.addedNodes, function(node) {
565
+ if (node.nodeName == "SPAN" && !node.getAttribute('mce-data-marked')) {
566
+ var offset, container;
567
+
568
+ if (node == caretElement) {
569
+ offset = rng.startOffset;
570
+ container = node.firstChild;
571
+ }
572
+
573
+ dom.remove(node, true);
574
+
575
+ if (container) {
576
+ rng.setStart(container, offset);
577
+ rng.setEnd(container, offset);
578
+ editor.selection.setRng(rng);
579
+ }
580
+ }
581
+ });
582
+ });
583
+
584
+ mutationObserver.disconnect();
585
+
586
+ // Remove any left over marks
587
+ Tools.each(editor.dom.select('span[mce-data-marked]'), function(span) {
588
+ span.removeAttribute('mce-data-marked');
589
+ });
590
+ }
591
+
592
+ editor.on('keydown', function(e) {
593
+ var isForward = e.keyCode == DELETE, isMetaOrCtrl = e.ctrlKey || e.metaKey;
594
+
595
+ if (!isDefaultPrevented(e) && (isForward || e.keyCode == BACKSPACE)) {
596
+ var rng = editor.selection.getRng(), container = rng.startContainer, offset = rng.startOffset;
597
+
598
+ // Shift+Delete is cut
599
+ if (isForward && e.shiftKey) {
600
+ return;
601
+ }
602
+
603
+ if (handleLastBlockCharacterDelete(isForward, rng)) {
604
+ e.preventDefault();
605
+ return;
606
+ }
607
+
608
+ // Ignore non meta delete in the where there is text before/after the caret
609
+ if (!isMetaOrCtrl && rng.collapsed && container.nodeType == 3) {
610
+ if (isForward ? offset < container.data.length : offset > 0) {
611
+ return;
612
+ }
613
+ }
614
+
615
+ e.preventDefault();
616
+
617
+ if (isMetaOrCtrl) {
618
+ editor.selection.getSel().modify("extend", isForward ? "forward" : "backward", e.metaKey ? "lineboundary" : "word");
619
+ }
620
+
621
+ customDelete(isForward);
622
+ }
623
+ });
624
+
625
+ // Handle case where text is deleted by typing over
626
+ editor.on('keypress', function(e) {
627
+ if (!isDefaultPrevented(e) && !selection.isCollapsed() && e.charCode > 31 && !VK.metaKeyPressed(e)) {
628
+ var rng, currentFormatNodes, fragmentNode, blockParent, caretNode, charText;
629
+
630
+ rng = editor.selection.getRng();
631
+ charText = String.fromCharCode(e.charCode);
632
+ e.preventDefault();
633
+
634
+ // Keep track of current format nodes
635
+ currentFormatNodes = $(rng.startContainer).parents().filter(function(idx, node) {
636
+ return !!editor.schema.getTextInlineElements()[node.nodeName];
637
+ });
638
+
639
+ customDelete(true);
640
+
641
+ // Check if the browser removed them
642
+ currentFormatNodes = currentFormatNodes.filter(function(idx, node) {
643
+ return !$.contains(editor.getBody(), node);
644
+ });
645
+
646
+ // Then re-add them
647
+ if (currentFormatNodes.length) {
648
+ fragmentNode = dom.createFragment();
649
+
650
+ currentFormatNodes.each(function(idx, formatNode) {
651
+ formatNode = formatNode.cloneNode(false);
652
+
653
+ if (fragmentNode.hasChildNodes()) {
654
+ formatNode.appendChild(fragmentNode.firstChild);
655
+ fragmentNode.appendChild(formatNode);
656
+ } else {
657
+ caretNode = formatNode;
658
+ fragmentNode.appendChild(formatNode);
659
+ }
660
+
661
+ fragmentNode.appendChild(formatNode);
662
+ });
663
+
664
+ caretNode.appendChild(editor.getDoc().createTextNode(charText));
665
+
666
+ // Prevent edge case where older WebKit would add an extra BR element
667
+ blockParent = dom.getParent(rng.startContainer, dom.isBlock);
668
+ if (dom.isEmpty(blockParent)) {
669
+ $(blockParent).empty().append(fragmentNode);
670
+ } else {
671
+ rng.insertNode(fragmentNode);
672
+ }
673
+
674
+ rng.setStart(caretNode.firstChild, 1);
675
+ rng.setEnd(caretNode.firstChild, 1);
676
+ editor.selection.setRng(rng);
677
+ } else {
678
+ editor.selection.setContent(charText);
679
+ }
680
+ }
681
+ });
682
+
683
+ editor.addCommand('Delete', function() {
684
+ customDelete();
685
+ });
686
+
687
+ editor.addCommand('ForwardDelete', function() {
688
+ customDelete(true);
689
+ });
690
+
691
+ // Older WebKits doesn't properly handle the clipboard so we can't add the rest
692
+ if (olderWebKit) {
693
+ return;
694
+ }
695
+
696
+ editor.on('dragstart', function(e) {
697
+ dragStartRng = selection.getRng();
698
+ setMceInteralContent(e);
699
+ });
700
+
701
+ editor.on('drop', function(e) {
702
+ if (!isDefaultPrevented(e)) {
703
+ var internalContent = getMceInternalContent(e);
704
+
705
+ if (internalContent) {
706
+ e.preventDefault();
707
+
708
+ // Safari has a weird issue where drag/dropping images sometimes
709
+ // produces a green plus icon. When this happens the caretRangeFromPoint
710
+ // will return "null" even though the x, y coordinate is correct.
711
+ // But if we detach the insert from the drop event we will get a proper range
712
+ Delay.setEditorTimeout(editor, function() {
713
+ var pointRng = RangeUtils.getCaretRangeFromPoint(e.x, e.y, doc);
714
+
715
+ if (dragStartRng) {
716
+ selection.setRng(dragStartRng);
717
+ dragStartRng = null;
718
+ }
719
+
720
+ customDelete();
721
+ selection.setRng(pointRng);
722
+ insertClipboardContents(internalContent.html);
723
+ });
724
+ }
725
+ }
726
+ });
727
+
728
+ editor.on('cut', function(e) {
729
+ if (!isDefaultPrevented(e) && e.clipboardData && !editor.selection.isCollapsed()) {
730
+ e.preventDefault();
731
+ e.clipboardData.clearData();
732
+ e.clipboardData.setData('text/html', editor.selection.getContent());
733
+ e.clipboardData.setData('text/plain', editor.selection.getContent({format: 'text'}));
734
+
735
+ // Needed delay for https://code.google.com/p/chromium/issues/detail?id=363288#c3
736
+ // Nested delete/forwardDelete not allowed on execCommand("cut")
737
+ // This is ugly but not sure how to work around it otherwise
738
+ Delay.setEditorTimeout(editor, function() {
739
+ customDelete(true);
740
+ });
741
+ }
742
+ });
743
+ }
744
+
745
+ /**
746
+ * Makes sure that the editor body becomes empty when backspace or delete is pressed in empty editors.
747
+ *
748
+ * For example:
749
+ * <p><b>|</b></p>
750
+ *
751
+ * Or:
752
+ * <h1>|</h1>
753
+ *
754
+ * Or:
755
+ * [<h1></h1>]
756
+ */
757
+ function emptyEditorWhenDeleting() {
758
+ function serializeRng(rng) {
759
+ var body = dom.create("body");
760
+ var contents = rng.cloneContents();
761
+ body.appendChild(contents);
762
+ return selection.serializer.serialize(body, {format: 'html'});
763
+ }
764
+
765
+ function allContentsSelected(rng) {
766
+ if (!rng.setStart) {
767
+ if (rng.item) {
768
+ return false;
769
+ }
770
+
771
+ var bodyRng = rng.duplicate();
772
+ bodyRng.moveToElementText(editor.getBody());
773
+ return RangeUtils.compareRanges(rng, bodyRng);
774
+ }
775
+
776
+ var selection = serializeRng(rng);
777
+
778
+ var allRng = dom.createRng();
779
+ allRng.selectNode(editor.getBody());
780
+
781
+ var allSelection = serializeRng(allRng);
782
+ return selection === allSelection;
783
+ }
784
+
785
+ editor.on('keydown', function(e) {
786
+ var keyCode = e.keyCode, isCollapsed, body;
787
+
788
+ // Empty the editor if it's needed for example backspace at <p><b>|</b></p>
789
+ if (!isDefaultPrevented(e) && (keyCode == DELETE || keyCode == BACKSPACE)) {
790
+ isCollapsed = editor.selection.isCollapsed();
791
+ body = editor.getBody();
792
+
793
+ // Selection is collapsed but the editor isn't empty
794
+ if (isCollapsed && !dom.isEmpty(body)) {
795
+ return;
796
+ }
797
+
798
+ // Selection isn't collapsed but not all the contents is selected
799
+ if (!isCollapsed && !allContentsSelected(editor.selection.getRng())) {
800
+ return;
801
+ }
802
+
803
+ // Manually empty the editor
804
+ e.preventDefault();
805
+ editor.setContent('');
806
+
807
+ if (body.firstChild && dom.isBlock(body.firstChild)) {
808
+ editor.selection.setCursorLocation(body.firstChild, 0);
809
+ } else {
810
+ editor.selection.setCursorLocation(body, 0);
811
+ }
812
+
813
+ editor.nodeChanged();
814
+ }
815
+ });
816
+ }
817
+
818
+ /**
819
+ * WebKit doesn't select all the nodes in the body when you press Ctrl+A.
820
+ * IE selects more than the contents <body>[<p>a</p>]</body> instead of <body><p>[a]</p]</body> see bug #6438
821
+ * This selects the whole body so that backspace/delete logic will delete everything
822
+ */
823
+ function selectAll() {
824
+ editor.shortcuts.add('meta+a', null, 'SelectAll');
825
+ }
826
+
827
+ /**
828
+ * WebKit has a weird issue where it some times fails to properly convert keypresses to input method keystrokes.
829
+ * The IME on Mac doesn't initialize when it doesn't fire a proper focus event.
830
+ *
831
+ * This seems to happen when the user manages to click the documentElement element then the window doesn't get proper focus until
832
+ * you enter a character into the editor.
833
+ *
834
+ * It also happens when the first focus in made to the body.
835
+ *
836
+ * See: https://bugs.webkit.org/show_bug.cgi?id=83566
837
+ */
838
+ function inputMethodFocus() {
839
+ if (!editor.settings.content_editable) {
840
+ // Case 1 IME doesn't initialize if you focus the document
841
+ // Disabled since it was interferring with the cE=false logic
842
+ // Also coultn't reproduce the issue on Safari 9
843
+ /*dom.bind(editor.getDoc(), 'focusin', function() {
844
+ selection.setRng(selection.getRng());
845
+ });*/
846
+
847
+ // Case 2 IME doesn't initialize if you click the documentElement it also doesn't properly fire the focusin event
848
+ // Needs to be both down/up due to weird rendering bug on Chrome Windows
849
+ dom.bind(editor.getDoc(), 'mousedown mouseup', function(e) {
850
+ var rng;
851
+
852
+ if (e.target == editor.getDoc().documentElement) {
853
+ rng = selection.getRng();
854
+ editor.getBody().focus();
855
+
856
+ if (e.type == 'mousedown') {
857
+ if (CaretContainer.isCaretContainer(rng.startContainer)) {
858
+ return;
859
+ }
860
+
861
+ // Edge case for mousedown, drag select and mousedown again within selection on Chrome Windows to render caret
862
+ selection.placeCaretAt(e.clientX, e.clientY);
863
+ } else {
864
+ selection.setRng(rng);
865
+ }
866
+ }
867
+ });
868
+ }
869
+ }
870
+
871
+ /**
872
+ * Backspacing in FireFox/IE from a paragraph into a horizontal rule results in a floating text node because the
873
+ * browser just deletes the paragraph - the browser fails to merge the text node with a horizontal rule so it is
874
+ * left there. TinyMCE sees a floating text node and wraps it in a paragraph on the key up event (ForceBlocks.js
875
+ * addRootBlocks), meaning the action does nothing. With this code, FireFox/IE matche the behaviour of other
876
+ * browsers.
877
+ *
878
+ * It also fixes a bug on Firefox where it's impossible to delete HR elements.
879
+ */
880
+ function removeHrOnBackspace() {
881
+ editor.on('keydown', function(e) {
882
+ if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
883
+ // Check if there is any HR elements this is faster since getRng on IE 7 & 8 is slow
884
+ if (!editor.getBody().getElementsByTagName('hr').length) {
885
+ return;
886
+ }
887
+
888
+ if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
889
+ var node = selection.getNode();
890
+ var previousSibling = node.previousSibling;
891
+
892
+ if (node.nodeName == 'HR') {
893
+ dom.remove(node);
894
+ e.preventDefault();
895
+ return;
896
+ }
897
+
898
+ if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "hr") {
899
+ dom.remove(previousSibling);
900
+ e.preventDefault();
901
+ }
902
+ }
903
+ }
904
+ });
905
+ }
906
+
907
+ /**
908
+ * Firefox 3.x has an issue where the body element won't get proper focus if you click out
909
+ * side it's rectangle.
910
+ */
911
+ function focusBody() {
912
+ // Fix for a focus bug in FF 3.x where the body element
913
+ // wouldn't get proper focus if the user clicked on the HTML element
914
+ if (!window.Range.prototype.getClientRects) { // Detect getClientRects got introduced in FF 4
915
+ editor.on('mousedown', function(e) {
916
+ if (!isDefaultPrevented(e) && e.target.nodeName === "HTML") {
917
+ var body = editor.getBody();
918
+
919
+ // Blur the body it's focused but not correctly focused
920
+ body.blur();
921
+
922
+ // Refocus the body after a little while
923
+ Delay.setEditorTimeout(editor, function() {
924
+ body.focus();
925
+ });
926
+ }
927
+ });
928
+ }
929
+ }
930
+
931
+ /**
932
+ * WebKit has a bug where it isn't possible to select image, hr or anchor elements
933
+ * by clicking on them so we need to fake that.
934
+ */
935
+ function selectControlElements() {
936
+ editor.on('click', function(e) {
937
+ var target = e.target;
938
+
939
+ // Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250
940
+ // WebKit can't even do simple things like selecting an image
941
+ // Needs to be the setBaseAndExtend or it will fail to select floated images
942
+ if (/^(IMG|HR)$/.test(target.nodeName) && dom.getContentEditableParent(target) !== "false") {
943
+ e.preventDefault();
944
+ selection.getSel().setBaseAndExtent(target, 0, target, 1);
945
+ editor.nodeChanged();
946
+ }
947
+
948
+ if (target.nodeName == 'A' && dom.hasClass(target, 'mce-item-anchor')) {
949
+ e.preventDefault();
950
+ selection.select(target);
951
+ }
952
+ });
953
+ }
954
+
955
+ /**
956
+ * Fixes a Gecko bug where the style attribute gets added to the wrong element when deleting between two block elements.
957
+ *
958
+ * Fixes do backspace/delete on this:
959
+ * <p>bla[ck</p><p style="color:red">r]ed</p>
960
+ *
961
+ * Would become:
962
+ * <p>bla|ed</p>
963
+ *
964
+ * Instead of:
965
+ * <p style="color:red">bla|ed</p>
966
+ */
967
+ function removeStylesWhenDeletingAcrossBlockElements() {
968
+ function getAttributeApplyFunction() {
969
+ var template = dom.getAttribs(selection.getStart().cloneNode(false));
970
+
971
+ return function() {
972
+ var target = selection.getStart();
973
+
974
+ if (target !== editor.getBody()) {
975
+ dom.setAttrib(target, "style", null);
976
+
977
+ each(template, function(attr) {
978
+ target.setAttributeNode(attr.cloneNode(true));
979
+ });
980
+ }
981
+ };
982
+ }
983
+
984
+ function isSelectionAcrossElements() {
985
+ return !selection.isCollapsed() &&
986
+ dom.getParent(selection.getStart(), dom.isBlock) != dom.getParent(selection.getEnd(), dom.isBlock);
987
+ }
988
+
989
+ editor.on('keypress', function(e) {
990
+ var applyAttributes;
991
+
992
+ if (!isDefaultPrevented(e) && (e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) {
993
+ applyAttributes = getAttributeApplyFunction();
994
+ editor.getDoc().execCommand('delete', false, null);
995
+ applyAttributes();
996
+ e.preventDefault();
997
+ return false;
998
+ }
999
+ });
1000
+
1001
+ dom.bind(editor.getDoc(), 'cut', function(e) {
1002
+ var applyAttributes;
1003
+
1004
+ if (!isDefaultPrevented(e) && isSelectionAcrossElements()) {
1005
+ applyAttributes = getAttributeApplyFunction();
1006
+
1007
+ Delay.setEditorTimeout(editor, function() {
1008
+ applyAttributes();
1009
+ });
1010
+ }
1011
+ });
1012
+ }
1013
+
1014
+ /**
1015
+ * Screen readers on IE needs to have the role application set on the body.
1016
+ */
1017
+ function ensureBodyHasRoleApplication() {
1018
+ document.body.setAttribute("role", "application");
1019
+ }
1020
+
1021
+ /**
1022
+ * Backspacing into a table behaves differently depending upon browser type.
1023
+ * Therefore, disable Backspace when cursor immediately follows a table.
1024
+ */
1025
+ function disableBackspaceIntoATable() {
1026
+ editor.on('keydown', function(e) {
1027
+ if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
1028
+ if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
1029
+ var previousSibling = selection.getNode().previousSibling;
1030
+ if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "table") {
1031
+ e.preventDefault();
1032
+ return false;
1033
+ }
1034
+ }
1035
+ }
1036
+ });
1037
+ }
1038
+
1039
+ /**
1040
+ * Old IE versions can't properly render BR elements in PRE tags white in contentEditable mode. So this
1041
+ * logic adds a \n before the BR so that it will get rendered.
1042
+ */
1043
+ function addNewLinesBeforeBrInPre() {
1044
+ // IE8+ rendering mode does the right thing with BR in PRE
1045
+ if (getDocumentMode() > 7) {
1046
+ return;
1047
+ }
1048
+
1049
+ // Enable display: none in area and add a specific class that hides all BR elements in PRE to
1050
+ // avoid the caret from getting stuck at the BR elements while pressing the right arrow key
1051
+ setEditorCommandState('RespectVisibilityInDesign', true);
1052
+ editor.contentStyles.push('.mceHideBrInPre pre br {display: none}');
1053
+ dom.addClass(editor.getBody(), 'mceHideBrInPre');
1054
+
1055
+ // Adds a \n before all BR elements in PRE to get them visual
1056
+ parser.addNodeFilter('pre', function(nodes) {
1057
+ var i = nodes.length, brNodes, j, brElm, sibling;
1058
+
1059
+ while (i--) {
1060
+ brNodes = nodes[i].getAll('br');
1061
+ j = brNodes.length;
1062
+ while (j--) {
1063
+ brElm = brNodes[j];
1064
+
1065
+ // Add \n before BR in PRE elements on older IE:s so the new lines get rendered
1066
+ sibling = brElm.prev;
1067
+ if (sibling && sibling.type === 3 && sibling.value.charAt(sibling.value - 1) != '\n') {
1068
+ sibling.value += '\n';
1069
+ } else {
1070
+ brElm.parent.insert(new Node('#text', 3), brElm, true).value = '\n';
1071
+ }
1072
+ }
1073
+ }
1074
+ });
1075
+
1076
+ // Removes any \n before BR elements in PRE since other browsers and in contentEditable=false mode they will be visible
1077
+ serializer.addNodeFilter('pre', function(nodes) {
1078
+ var i = nodes.length, brNodes, j, brElm, sibling;
1079
+
1080
+ while (i--) {
1081
+ brNodes = nodes[i].getAll('br');
1082
+ j = brNodes.length;
1083
+ while (j--) {
1084
+ brElm = brNodes[j];
1085
+ sibling = brElm.prev;
1086
+ if (sibling && sibling.type == 3) {
1087
+ sibling.value = sibling.value.replace(/\r?\n$/, '');
1088
+ }
1089
+ }
1090
+ }
1091
+ });
1092
+ }
1093
+
1094
+ /**
1095
+ * Moves style width/height to attribute width/height when the user resizes an image on IE.
1096
+ */
1097
+ function removePreSerializedStylesWhenSelectingControls() {
1098
+ dom.bind(editor.getBody(), 'mouseup', function() {
1099
+ var value, node = selection.getNode();
1100
+
1101
+ // Moved styles to attributes on IMG eements
1102
+ if (node.nodeName == 'IMG') {
1103
+ // Convert style width to width attribute
1104
+ if ((value = dom.getStyle(node, 'width'))) {
1105
+ dom.setAttrib(node, 'width', value.replace(/[^0-9%]+/g, ''));
1106
+ dom.setStyle(node, 'width', '');
1107
+ }
1108
+
1109
+ // Convert style height to height attribute
1110
+ if ((value = dom.getStyle(node, 'height'))) {
1111
+ dom.setAttrib(node, 'height', value.replace(/[^0-9%]+/g, ''));
1112
+ dom.setStyle(node, 'height', '');
1113
+ }
1114
+ }
1115
+ });
1116
+ }
1117
+
1118
+ /**
1119
+ * Removes a blockquote when backspace is pressed at the beginning of it.
1120
+ *
1121
+ * For example:
1122
+ * <blockquote><p>|x</p></blockquote>
1123
+ *
1124
+ * Becomes:
1125
+ * <p>|x</p>
1126
+ */
1127
+ function removeBlockQuoteOnBackSpace() {
1128
+ // Add block quote deletion handler
1129
+ editor.on('keydown', function(e) {
1130
+ var rng, container, offset, root, parent;
1131
+
1132
+ if (isDefaultPrevented(e) || e.keyCode != VK.BACKSPACE) {
1133
+ return;
1134
+ }
1135
+
1136
+ rng = selection.getRng();
1137
+ container = rng.startContainer;
1138
+ offset = rng.startOffset;
1139
+ root = dom.getRoot();
1140
+ parent = container;
1141
+
1142
+ if (!rng.collapsed || offset !== 0) {
1143
+ return;
1144
+ }
1145
+
1146
+ while (parent && parent.parentNode && parent.parentNode.firstChild == parent && parent.parentNode != root) {
1147
+ parent = parent.parentNode;
1148
+ }
1149
+
1150
+ // Is the cursor at the beginning of a blockquote?
1151
+ if (parent.tagName === 'BLOCKQUOTE') {
1152
+ // Remove the blockquote
1153
+ editor.formatter.toggle('blockquote', null, parent);
1154
+
1155
+ // Move the caret to the beginning of container
1156
+ rng = dom.createRng();
1157
+ rng.setStart(container, 0);
1158
+ rng.setEnd(container, 0);
1159
+ selection.setRng(rng);
1160
+ }
1161
+ });
1162
+ }
1163
+
1164
+ /**
1165
+ * Sets various Gecko editing options on mouse down and before a execCommand to disable inline table editing that is broken etc.
1166
+ */
1167
+ function setGeckoEditingOptions() {
1168
+ function setOpts() {
1169
+ editor._refreshContentEditable();
1170
+
1171
+ setEditorCommandState("StyleWithCSS", false);
1172
+ setEditorCommandState("enableInlineTableEditing", false);
1173
+
1174
+ if (!settings.object_resizing) {
1175
+ setEditorCommandState("enableObjectResizing", false);
1176
+ }
1177
+ }
1178
+
1179
+ if (!settings.readonly) {
1180
+ editor.on('BeforeExecCommand MouseDown', setOpts);
1181
+ }
1182
+ }
1183
+
1184
+ /**
1185
+ * Fixes a gecko link bug, when a link is placed at the end of block elements there is
1186
+ * no way to move the caret behind the link. This fix adds a bogus br element after the link.
1187
+ *
1188
+ * For example this:
1189
+ * <p><b><a href="#">x</a></b></p>
1190
+ *
1191
+ * Becomes this:
1192
+ * <p><b><a href="#">x</a></b><br></p>
1193
+ */
1194
+ function addBrAfterLastLinks() {
1195
+ function fixLinks() {
1196
+ each(dom.select('a'), function(node) {
1197
+ var parentNode = node.parentNode, root = dom.getRoot();
1198
+
1199
+ if (parentNode.lastChild === node) {
1200
+ while (parentNode && !dom.isBlock(parentNode)) {
1201
+ if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) {
1202
+ return;
1203
+ }
1204
+
1205
+ parentNode = parentNode.parentNode;
1206
+ }
1207
+
1208
+ dom.add(parentNode, 'br', {'data-mce-bogus': 1});
1209
+ }
1210
+ });
1211
+ }
1212
+
1213
+ editor.on('SetContent ExecCommand', function(e) {
1214
+ if (e.type == "setcontent" || e.command === 'mceInsertLink') {
1215
+ fixLinks();
1216
+ }
1217
+ });
1218
+ }
1219
+
1220
+ /**
1221
+ * WebKit will produce DIV elements here and there by default. But since TinyMCE uses paragraphs by
1222
+ * default we want to change that behavior.
1223
+ */
1224
+ function setDefaultBlockType() {
1225
+ if (settings.forced_root_block) {
1226
+ editor.on('init', function() {
1227
+ setEditorCommandState('DefaultParagraphSeparator', settings.forced_root_block);
1228
+ });
1229
+ }
1230
+ }
1231
+
1232
+ /**
1233
+ * Deletes the selected image on IE instead of navigating to previous page.
1234
+ */
1235
+ function deleteControlItemOnBackSpace() {
1236
+ editor.on('keydown', function(e) {
1237
+ var rng;
1238
+
1239
+ if (!isDefaultPrevented(e) && e.keyCode == BACKSPACE) {
1240
+ rng = editor.getDoc().selection.createRange();
1241
+ if (rng && rng.item) {
1242
+ e.preventDefault();
1243
+ editor.undoManager.beforeChange();
1244
+ dom.remove(rng.item(0));
1245
+ editor.undoManager.add();
1246
+ }
1247
+ }
1248
+ });
1249
+ }
1250
+
1251
+ /**
1252
+ * IE10 doesn't properly render block elements with the right height until you add contents to them.
1253
+ * This fixes that by adding a padding-right to all empty text block elements.
1254
+ * See: https://connect.microsoft.com/IE/feedback/details/743881
1255
+ */
1256
+ function renderEmptyBlocksFix() {
1257
+ var emptyBlocksCSS;
1258
+
1259
+ // IE10+
1260
+ if (getDocumentMode() >= 10) {
1261
+ emptyBlocksCSS = '';
1262
+ each('p div h1 h2 h3 h4 h5 h6'.split(' '), function(name, i) {
1263
+ emptyBlocksCSS += (i > 0 ? ',' : '') + name + ':empty';
1264
+ });
1265
+
1266
+ editor.contentStyles.push(emptyBlocksCSS + '{padding-right: 1px !important}');
1267
+ }
1268
+ }
1269
+
1270
+ /**
1271
+ * Old IE versions can't retain contents within noscript elements so this logic will store the contents
1272
+ * as a attribute and the insert that value as it's raw text when the DOM is serialized.
1273
+ */
1274
+ function keepNoScriptContents() {
1275
+ if (getDocumentMode() < 9) {
1276
+ parser.addNodeFilter('noscript', function(nodes) {
1277
+ var i = nodes.length, node, textNode;
1278
+
1279
+ while (i--) {
1280
+ node = nodes[i];
1281
+ textNode = node.firstChild;
1282
+
1283
+ if (textNode) {
1284
+ node.attr('data-mce-innertext', textNode.value);
1285
+ }
1286
+ }
1287
+ });
1288
+
1289
+ serializer.addNodeFilter('noscript', function(nodes) {
1290
+ var i = nodes.length, node, textNode, value;
1291
+
1292
+ while (i--) {
1293
+ node = nodes[i];
1294
+ textNode = nodes[i].firstChild;
1295
+
1296
+ if (textNode) {
1297
+ textNode.value = Entities.decode(textNode.value);
1298
+ } else {
1299
+ // Old IE can't retain noscript value so an attribute is used to store it
1300
+ value = node.attributes.map['data-mce-innertext'];
1301
+ if (value) {
1302
+ node.attr('data-mce-innertext', null);
1303
+ textNode = new Node('#text', 3);
1304
+ textNode.value = value;
1305
+ textNode.raw = true;
1306
+ node.append(textNode);
1307
+ }
1308
+ }
1309
+ }
1310
+ });
1311
+ }
1312
+ }
1313
+
1314
+ /**
1315
+ * IE has an issue where you can't select/move the caret by clicking outside the body if the document is in standards mode.
1316
+ */
1317
+ function fixCaretSelectionOfDocumentElementOnIe() {
1318
+ var doc = dom.doc, body = doc.body, started, startRng, htmlElm;
1319
+
1320
+ // Return range from point or null if it failed
1321
+ function rngFromPoint(x, y) {
1322
+ var rng = body.createTextRange();
1323
+
1324
+ try {
1325
+ rng.moveToPoint(x, y);
1326
+ } catch (ex) {
1327
+ // IE sometimes throws and exception, so lets just ignore it
1328
+ rng = null;
1329
+ }
1330
+
1331
+ return rng;
1332
+ }
1333
+
1334
+ // Fires while the selection is changing
1335
+ function selectionChange(e) {
1336
+ var pointRng;
1337
+
1338
+ // Check if the button is down or not
1339
+ if (e.button) {
1340
+ // Create range from mouse position
1341
+ pointRng = rngFromPoint(e.x, e.y);
1342
+
1343
+ if (pointRng) {
1344
+ // Check if pointRange is before/after selection then change the endPoint
1345
+ if (pointRng.compareEndPoints('StartToStart', startRng) > 0) {
1346
+ pointRng.setEndPoint('StartToStart', startRng);
1347
+ } else {
1348
+ pointRng.setEndPoint('EndToEnd', startRng);
1349
+ }
1350
+
1351
+ pointRng.select();
1352
+ }
1353
+ } else {
1354
+ endSelection();
1355
+ }
1356
+ }
1357
+
1358
+ // Removes listeners
1359
+ function endSelection() {
1360
+ var rng = doc.selection.createRange();
1361
+
1362
+ // If the range is collapsed then use the last start range
1363
+ if (startRng && !rng.item && rng.compareEndPoints('StartToEnd', rng) === 0) {
1364
+ startRng.select();
1365
+ }
1366
+
1367
+ dom.unbind(doc, 'mouseup', endSelection);
1368
+ dom.unbind(doc, 'mousemove', selectionChange);
1369
+ startRng = started = 0;
1370
+ }
1371
+
1372
+ // Make HTML element unselectable since we are going to handle selection by hand
1373
+ doc.documentElement.unselectable = true;
1374
+
1375
+ // Detect when user selects outside BODY
1376
+ dom.bind(doc, 'mousedown contextmenu', function(e) {
1377
+ if (e.target.nodeName === 'HTML') {
1378
+ if (started) {
1379
+ endSelection();
1380
+ }
1381
+
1382
+ // Detect vertical scrollbar, since IE will fire a mousedown on the scrollbar and have target set as HTML
1383
+ htmlElm = doc.documentElement;
1384
+ if (htmlElm.scrollHeight > htmlElm.clientHeight) {
1385
+ return;
1386
+ }
1387
+
1388
+ started = 1;
1389
+ // Setup start position
1390
+ startRng = rngFromPoint(e.x, e.y);
1391
+ if (startRng) {
1392
+ // Listen for selection change events
1393
+ dom.bind(doc, 'mouseup', endSelection);
1394
+ dom.bind(doc, 'mousemove', selectionChange);
1395
+
1396
+ dom.getRoot().focus();
1397
+ startRng.select();
1398
+ }
1399
+ }
1400
+ });
1401
+ }
1402
+
1403
+ /**
1404
+ * Fixes selection issues where the caret can be placed between two inline elements like <b>a</b>|<b>b</b>
1405
+ * this fix will lean the caret right into the closest inline element.
1406
+ */
1407
+ function normalizeSelection() {
1408
+ // Normalize selection for example <b>a</b><i>|a</i> becomes <b>a|</b><i>a</i> except for Ctrl+A since it selects everything
1409
+ editor.on('keyup focusin mouseup', function(e) {
1410
+ if (e.keyCode != 65 || !VK.metaKeyPressed(e)) {
1411
+ selection.normalize();
1412
+ }
1413
+ }, true);
1414
+ }
1415
+
1416
+ /**
1417
+ * Forces Gecko to render a broken image icon if it fails to load an image.
1418
+ */
1419
+ function showBrokenImageIcon() {
1420
+ editor.contentStyles.push(
1421
+ 'img:-moz-broken {' +
1422
+ '-moz-force-broken-image-icon:1;' +
1423
+ 'min-width:24px;' +
1424
+ 'min-height:24px' +
1425
+ '}'
1426
+ );
1427
+ }
1428
+
1429
+ /**
1430
+ * iOS has a bug where it's impossible to type if the document has a touchstart event
1431
+ * bound and the user touches the document while having the on screen keyboard visible.
1432
+ *
1433
+ * The touch event moves the focus to the parent document while having the caret inside the iframe
1434
+ * this fix moves the focus back into the iframe document.
1435
+ */
1436
+ function restoreFocusOnKeyDown() {
1437
+ if (!editor.inline) {
1438
+ editor.on('keydown', function() {
1439
+ if (document.activeElement == document.body) {
1440
+ editor.getWin().focus();
1441
+ }
1442
+ });
1443
+ }
1444
+ }
1445
+
1446
+ /**
1447
+ * IE 11 has an annoying issue where you can't move focus into the editor
1448
+ * by clicking on the white area HTML element. We used to be able to to fix this with
1449
+ * the fixCaretSelectionOfDocumentElementOnIe fix. But since M$ removed the selection
1450
+ * object it's not possible anymore. So we need to hack in a ungly CSS to force the
1451
+ * body to be at least 150px. If the user clicks the HTML element out side this 150px region
1452
+ * we simply move the focus into the first paragraph. Not ideal since you loose the
1453
+ * positioning of the caret but goot enough for most cases.
1454
+ */
1455
+ function bodyHeight() {
1456
+ if (!editor.inline) {
1457
+ editor.contentStyles.push('body {min-height: 150px}');
1458
+ editor.on('click', function(e) {
1459
+ var rng;
1460
+
1461
+ if (e.target.nodeName == 'HTML') {
1462
+ // Edge seems to only need focus if we set the range
1463
+ // the caret will become invisible and moved out of the iframe!!
1464
+ if (Env.ie > 11) {
1465
+ editor.getBody().focus();
1466
+ return;
1467
+ }
1468
+
1469
+ // Need to store away non collapsed ranges since the focus call will mess that up see #7382
1470
+ rng = editor.selection.getRng();
1471
+ editor.getBody().focus();
1472
+ editor.selection.setRng(rng);
1473
+ editor.selection.normalize();
1474
+ editor.nodeChanged();
1475
+ }
1476
+ });
1477
+ }
1478
+ }
1479
+
1480
+ /**
1481
+ * Firefox on Mac OS will move the browser back to the previous page if you press CMD+Left arrow.
1482
+ * You might then loose all your work so we need to block that behavior and replace it with our own.
1483
+ */
1484
+ function blockCmdArrowNavigation() {
1485
+ if (Env.mac) {
1486
+ editor.on('keydown', function(e) {
1487
+ if (VK.metaKeyPressed(e) && !e.shiftKey && (e.keyCode == 37 || e.keyCode == 39)) {
1488
+ e.preventDefault();
1489
+ editor.selection.getSel().modify('move', e.keyCode == 37 ? 'backward' : 'forward', 'lineboundary');
1490
+ }
1491
+ });
1492
+ }
1493
+ }
1494
+
1495
+ /**
1496
+ * Disables the autolinking in IE 9+ this is then re-enabled by the autolink plugin.
1497
+ */
1498
+ function disableAutoUrlDetect() {
1499
+ setEditorCommandState("AutoUrlDetect", false);
1500
+ }
1501
+
1502
+ /**
1503
+ * iOS 7.1 introduced two new bugs:
1504
+ * 1) It's possible to open links within a contentEditable area by clicking on them.
1505
+ * 2) If you hold down the finger it will display the link/image touch callout menu.
1506
+ */
1507
+ function tapLinksAndImages() {
1508
+ editor.on('click', function(e) {
1509
+ var elm = e.target;
1510
+
1511
+ do {
1512
+ if (elm.tagName === 'A') {
1513
+ e.preventDefault();
1514
+ return;
1515
+ }
1516
+ } while ((elm = elm.parentNode));
1517
+ });
1518
+
1519
+ editor.contentStyles.push('.mce-content-body {-webkit-touch-callout: none}');
1520
+ }
1521
+
1522
+ /**
1523
+ * iOS Safari and possible other browsers have a bug where it won't fire
1524
+ * a click event when a contentEditable is focused. This function fakes click events
1525
+ * by using touchstart/touchend and measuring the time and distance travelled.
1526
+ */
1527
+ /*
1528
+ function touchClickEvent() {
1529
+ editor.on('touchstart', function(e) {
1530
+ var elm, time, startTouch, changedTouches;
1531
+
1532
+ elm = e.target;
1533
+ time = new Date().getTime();
1534
+ changedTouches = e.changedTouches;
1535
+
1536
+ if (!changedTouches || changedTouches.length > 1) {
1537
+ return;
1538
+ }
1539
+
1540
+ startTouch = changedTouches[0];
1541
+
1542
+ editor.once('touchend', function(e) {
1543
+ var endTouch = e.changedTouches[0], args;
1544
+
1545
+ if (new Date().getTime() - time > 500) {
1546
+ return;
1547
+ }
1548
+
1549
+ if (Math.abs(startTouch.clientX - endTouch.clientX) > 5) {
1550
+ return;
1551
+ }
1552
+
1553
+ if (Math.abs(startTouch.clientY - endTouch.clientY) > 5) {
1554
+ return;
1555
+ }
1556
+
1557
+ args = {
1558
+ target: elm
1559
+ };
1560
+
1561
+ each('pageX pageY clientX clientY screenX screenY'.split(' '), function(key) {
1562
+ args[key] = endTouch[key];
1563
+ });
1564
+
1565
+ args = editor.fire('click', args);
1566
+
1567
+ if (!args.isDefaultPrevented()) {
1568
+ // iOS WebKit can't place the caret properly once
1569
+ // you bind touch events so we need to do this manually
1570
+ // TODO: Expand to the closest word? Touble tap still works.
1571
+ editor.selection.placeCaretAt(endTouch.clientX, endTouch.clientY);
1572
+ editor.nodeChanged();
1573
+ }
1574
+ });
1575
+ });
1576
+ }
1577
+ */
1578
+
1579
+ /**
1580
+ * WebKit has a bug where it will allow forms to be submitted if they are inside a contentEditable element.
1581
+ * For example this: <form><button></form>
1582
+ */
1583
+ function blockFormSubmitInsideEditor() {
1584
+ editor.on('init', function() {
1585
+ editor.dom.bind(editor.getBody(), 'submit', function(e) {
1586
+ e.preventDefault();
1587
+ });
1588
+ });
1589
+ }
1590
+
1591
+ /**
1592
+ * Sometimes WebKit/Blink generates BR elements with the Apple-interchange-newline class.
1593
+ *
1594
+ * Scenario:
1595
+ * 1) Create a table 2x2.
1596
+ * 2) Select and copy cells A2-B2.
1597
+ * 3) Paste and it will add BR element to table cell.
1598
+ */
1599
+ function removeAppleInterchangeBrs() {
1600
+ parser.addNodeFilter('br', function(nodes) {
1601
+ var i = nodes.length;
1602
+
1603
+ while (i--) {
1604
+ if (nodes[i].attr('class') == 'Apple-interchange-newline') {
1605
+ nodes[i].remove();
1606
+ }
1607
+ }
1608
+ });
1609
+ }
1610
+
1611
+ /**
1612
+ * IE cannot set custom contentType's on drag events, and also does not properly drag/drop between
1613
+ * editors. This uses a special data:text/mce-internal URL to pass data when drag/drop between editors.
1614
+ */
1615
+ function ieInternalDragAndDrop() {
1616
+ editor.on('dragstart', function(e) {
1617
+ setMceInteralContent(e);
1618
+ });
1619
+
1620
+ editor.on('drop', function(e) {
1621
+ if (!isDefaultPrevented(e)) {
1622
+ var internalContent = getMceInternalContent(e);
1623
+
1624
+ if (internalContent && internalContent.id != editor.id) {
1625
+ e.preventDefault();
1626
+
1627
+ var rng = RangeUtils.getCaretRangeFromPoint(e.x, e.y, editor.getDoc());
1628
+ selection.setRng(rng);
1629
+ insertClipboardContents(internalContent.html);
1630
+ }
1631
+ }
1632
+ });
1633
+ }
1634
+
1635
+ // All browsers
1636
+ removeBlockQuoteOnBackSpace();
1637
+ emptyEditorWhenDeleting();
1638
+
1639
+ // Windows phone will return a range like [body, 0] on mousedown so
1640
+ // it will always normalize to the wrong location
1641
+ if (!Env.windowsPhone) {
1642
+ normalizeSelection();
1643
+ }
1644
+
1645
+ // WebKit
1646
+ if (isWebKit) {
1647
+ cleanupStylesWhenDeleting();
1648
+ inputMethodFocus();
1649
+ selectControlElements();
1650
+ setDefaultBlockType();
1651
+ blockFormSubmitInsideEditor();
1652
+ disableBackspaceIntoATable();
1653
+ removeAppleInterchangeBrs();
1654
+ //touchClickEvent();
1655
+
1656
+ // iOS
1657
+ if (Env.iOS) {
1658
+ restoreFocusOnKeyDown();
1659
+ bodyHeight();
1660
+ tapLinksAndImages();
1661
+ } else {
1662
+ selectAll();
1663
+ }
1664
+ }
1665
+
1666
+ // IE
1667
+ if (isIE && Env.ie < 11) {
1668
+ removeHrOnBackspace();
1669
+ ensureBodyHasRoleApplication();
1670
+ addNewLinesBeforeBrInPre();
1671
+ removePreSerializedStylesWhenSelectingControls();
1672
+ deleteControlItemOnBackSpace();
1673
+ renderEmptyBlocksFix();
1674
+ keepNoScriptContents();
1675
+ fixCaretSelectionOfDocumentElementOnIe();
1676
+ }
1677
+
1678
+ if (Env.ie >= 11) {
1679
+ bodyHeight();
1680
+ disableBackspaceIntoATable();
1681
+ }
1682
+
1683
+ if (Env.ie) {
1684
+ selectAll();
1685
+ disableAutoUrlDetect();
1686
+ ieInternalDragAndDrop();
1687
+ }
1688
+
1689
+ // Gecko
1690
+ if (isGecko) {
1691
+ removeHrOnBackspace();
1692
+ focusBody();
1693
+ removeStylesWhenDeletingAcrossBlockElements();
1694
+ setGeckoEditingOptions();
1695
+ addBrAfterLastLinks();
1696
+ showBrokenImageIcon();
1697
+ blockCmdArrowNavigation();
1698
+ disableBackspaceIntoATable();
1699
+ }
1700
+ };
1701
+ });