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,142 @@
1
+ /**
2
+ * Inline development version. Only to be used while developing since it uses document.write to load scripts.
3
+ */
4
+
5
+ /*jshint smarttabs:true, undef:true, latedef:true, curly:true, bitwise:true, camelcase:true */
6
+ /*globals $code */
7
+
8
+ (function(exports) {
9
+ "use strict";
10
+
11
+ var html = "", baseDir;
12
+ var modules = {}, exposedModules = [], moduleCount = 0;
13
+
14
+ var scripts = document.getElementsByTagName('script');
15
+ for (var i = 0; i < scripts.length; i++) {
16
+ var src = scripts[i].src;
17
+
18
+ if (src.indexOf('/plugin.dev.js') != -1) {
19
+ baseDir = src.substring(0, src.lastIndexOf('/'));
20
+ }
21
+ }
22
+
23
+ function require(ids, callback) {
24
+ var module, defs = [];
25
+
26
+ for (var i = 0; i < ids.length; ++i) {
27
+ module = modules[ids[i]] || resolve(ids[i]);
28
+ if (!module) {
29
+ throw 'module definition dependecy not found: ' + ids[i];
30
+ }
31
+
32
+ defs.push(module);
33
+ }
34
+
35
+ callback.apply(null, defs);
36
+ }
37
+
38
+ function resolve(id) {
39
+ if (exports.privateModules && id in exports.privateModules) {
40
+ return;
41
+ }
42
+
43
+ var target = exports;
44
+ var fragments = id.split(/[.\/]/);
45
+
46
+ for (var fi = 0; fi < fragments.length; ++fi) {
47
+ if (!target[fragments[fi]]) {
48
+ return;
49
+ }
50
+
51
+ target = target[fragments[fi]];
52
+ }
53
+
54
+ return target;
55
+ }
56
+
57
+ function register(id) {
58
+ var target = exports;
59
+ var fragments = id.split(/[.\/]/);
60
+
61
+ for (var fi = 0; fi < fragments.length - 1; ++fi) {
62
+ if (target[fragments[fi]] === undefined) {
63
+ target[fragments[fi]] = {};
64
+ }
65
+
66
+ target = target[fragments[fi]];
67
+ }
68
+
69
+ target[fragments[fragments.length - 1]] = modules[id];
70
+ }
71
+
72
+ function define(id, dependencies, definition) {
73
+ var privateModules, i;
74
+
75
+ if (typeof id !== 'string') {
76
+ throw 'invalid module definition, module id must be defined and be a string';
77
+ }
78
+
79
+ if (dependencies === undefined) {
80
+ throw 'invalid module definition, dependencies must be specified';
81
+ }
82
+
83
+ if (definition === undefined) {
84
+ throw 'invalid module definition, definition function must be specified';
85
+ }
86
+
87
+ require(dependencies, function() {
88
+ modules[id] = definition.apply(null, arguments);
89
+ });
90
+
91
+ if (--moduleCount === 0) {
92
+ for (i = 0; i < exposedModules.length; i++) {
93
+ register(exposedModules[i]);
94
+ }
95
+ }
96
+
97
+ // Expose private modules for unit tests
98
+ if (exports.AMDLC_TESTS) {
99
+ privateModules = exports.privateModules || {};
100
+
101
+ for (id in modules) {
102
+ privateModules[id] = modules[id];
103
+ }
104
+
105
+ for (i = 0; i < exposedModules.length; i++) {
106
+ delete privateModules[exposedModules[i]];
107
+ }
108
+
109
+ exports.privateModules = privateModules;
110
+ }
111
+
112
+ }
113
+
114
+ function expose(ids) {
115
+ exposedModules = ids;
116
+ }
117
+
118
+ function writeScripts() {
119
+ document.write(html);
120
+ }
121
+
122
+ function load(path) {
123
+ html += '<script type="text/javascript" src="' + baseDir + '/' + path + '"></script>\n';
124
+ moduleCount++;
125
+ }
126
+
127
+ // Expose globally
128
+ exports.define = define;
129
+ exports.require = require;
130
+
131
+ expose(["tinymce/pasteplugin/Utils"]);
132
+
133
+ load('classes/Utils.js');
134
+ load('classes/Clipboard.js');
135
+ load('classes/WordFilter.js');
136
+ load('classes/Quirks.js');
137
+ load('classes/Plugin.js');
138
+
139
+ writeScripts();
140
+ })(this);
141
+
142
+ // $hash: 5787da1099d51e5cb929609a9eef96d1
@@ -0,0 +1,1708 @@
1
+ /**
2
+ * Compiled inline version. (Library mode)
3
+ */
4
+
5
+ /*jshint smarttabs:true, undef:true, latedef:true, curly:true, bitwise:true, camelcase:true */
6
+ /*globals $code */
7
+
8
+ (function(exports, undefined) {
9
+ "use strict";
10
+
11
+ var modules = {};
12
+
13
+ function require(ids, callback) {
14
+ var module, defs = [];
15
+
16
+ for (var i = 0; i < ids.length; ++i) {
17
+ module = modules[ids[i]] || resolve(ids[i]);
18
+ if (!module) {
19
+ throw 'module definition dependecy not found: ' + ids[i];
20
+ }
21
+
22
+ defs.push(module);
23
+ }
24
+
25
+ callback.apply(null, defs);
26
+ }
27
+
28
+ function define(id, dependencies, definition) {
29
+ if (typeof id !== 'string') {
30
+ throw 'invalid module definition, module id must be defined and be a string';
31
+ }
32
+
33
+ if (dependencies === undefined) {
34
+ throw 'invalid module definition, dependencies must be specified';
35
+ }
36
+
37
+ if (definition === undefined) {
38
+ throw 'invalid module definition, definition function must be specified';
39
+ }
40
+
41
+ require(dependencies, function() {
42
+ modules[id] = definition.apply(null, arguments);
43
+ });
44
+ }
45
+
46
+ function defined(id) {
47
+ return !!modules[id];
48
+ }
49
+
50
+ function resolve(id) {
51
+ var target = exports;
52
+ var fragments = id.split(/[.\/]/);
53
+
54
+ for (var fi = 0; fi < fragments.length; ++fi) {
55
+ if (!target[fragments[fi]]) {
56
+ return;
57
+ }
58
+
59
+ target = target[fragments[fi]];
60
+ }
61
+
62
+ return target;
63
+ }
64
+
65
+ function expose(ids) {
66
+ var i, target, id, fragments, privateModules;
67
+
68
+ for (i = 0; i < ids.length; i++) {
69
+ target = exports;
70
+ id = ids[i];
71
+ fragments = id.split(/[.\/]/);
72
+
73
+ for (var fi = 0; fi < fragments.length - 1; ++fi) {
74
+ if (target[fragments[fi]] === undefined) {
75
+ target[fragments[fi]] = {};
76
+ }
77
+
78
+ target = target[fragments[fi]];
79
+ }
80
+
81
+ target[fragments[fragments.length - 1]] = modules[id];
82
+ }
83
+
84
+ // Expose private modules for unit tests
85
+ if (exports.AMDLC_TESTS) {
86
+ privateModules = exports.privateModules || {};
87
+
88
+ for (id in modules) {
89
+ privateModules[id] = modules[id];
90
+ }
91
+
92
+ for (i = 0; i < ids.length; i++) {
93
+ delete privateModules[ids[i]];
94
+ }
95
+
96
+ exports.privateModules = privateModules;
97
+ }
98
+ }
99
+
100
+ // Included from: js/tinymce/plugins/paste/classes/Utils.js
101
+
102
+ /**
103
+ * Utils.js
104
+ *
105
+ * Released under LGPL License.
106
+ * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
107
+ *
108
+ * License: http://www.tinymce.com/license
109
+ * Contributing: http://www.tinymce.com/contributing
110
+ */
111
+
112
+ /**
113
+ * This class contails various utility functions for the paste plugin.
114
+ *
115
+ * @class tinymce.pasteplugin.Utils
116
+ */
117
+ define("tinymce/pasteplugin/Utils", [
118
+ "tinymce/util/Tools",
119
+ "tinymce/html/DomParser",
120
+ "tinymce/html/Schema"
121
+ ], function(Tools, DomParser, Schema) {
122
+ function filter(content, items) {
123
+ Tools.each(items, function(v) {
124
+ if (v.constructor == RegExp) {
125
+ content = content.replace(v, '');
126
+ } else {
127
+ content = content.replace(v[0], v[1]);
128
+ }
129
+ });
130
+
131
+ return content;
132
+ }
133
+
134
+ /**
135
+ * Gets the innerText of the specified element. It will handle edge cases
136
+ * and works better than textContent on Gecko.
137
+ *
138
+ * @param {String} html HTML string to get text from.
139
+ * @return {String} String of text with line feeds.
140
+ */
141
+ function innerText(html) {
142
+ var schema = new Schema(), domParser = new DomParser({}, schema), text = '';
143
+ var shortEndedElements = schema.getShortEndedElements();
144
+ var ignoreElements = Tools.makeMap('script noscript style textarea video audio iframe object', ' ');
145
+ var blockElements = schema.getBlockElements();
146
+
147
+ function walk(node) {
148
+ var name = node.name, currentNode = node;
149
+
150
+ if (name === 'br') {
151
+ text += '\n';
152
+ return;
153
+ }
154
+
155
+ // img/input/hr
156
+ if (shortEndedElements[name]) {
157
+ text += ' ';
158
+ }
159
+
160
+ // Ingore script, video contents
161
+ if (ignoreElements[name]) {
162
+ text += ' ';
163
+ return;
164
+ }
165
+
166
+ if (node.type == 3) {
167
+ text += node.value;
168
+ }
169
+
170
+ // Walk all children
171
+ if (!node.shortEnded) {
172
+ if ((node = node.firstChild)) {
173
+ do {
174
+ walk(node);
175
+ } while ((node = node.next));
176
+ }
177
+ }
178
+
179
+ // Add \n or \n\n for blocks or P
180
+ if (blockElements[name] && currentNode.next) {
181
+ text += '\n';
182
+
183
+ if (name == 'p') {
184
+ text += '\n';
185
+ }
186
+ }
187
+ }
188
+
189
+ html = filter(html, [
190
+ /<!\[[^\]]+\]>/g // Conditional comments
191
+ ]);
192
+
193
+ walk(domParser.parse(html));
194
+
195
+ return text;
196
+ }
197
+
198
+ /**
199
+ * Trims the specified HTML by removing all WebKit fragments, all elements wrapping the body trailing BR elements etc.
200
+ *
201
+ * @param {String} html Html string to trim contents on.
202
+ * @return {String} Html contents that got trimmed.
203
+ */
204
+ function trimHtml(html) {
205
+ function trimSpaces(all, s1, s2) {
206
+ // WebKit &nbsp; meant to preserve multiple spaces but instead inserted around all inline tags,
207
+ // including the spans with inline styles created on paste
208
+ if (!s1 && !s2) {
209
+ return ' ';
210
+ }
211
+
212
+ return '\u00a0';
213
+ }
214
+
215
+ html = filter(html, [
216
+ /^[\s\S]*<body[^>]*>\s*|\s*<\/body[^>]*>[\s\S]*$/g, // Remove anything but the contents within the BODY element
217
+ /<!--StartFragment-->|<!--EndFragment-->/g, // Inner fragments (tables from excel on mac)
218
+ [/( ?)<span class="Apple-converted-space">\u00a0<\/span>( ?)/g, trimSpaces],
219
+ /<br class="Apple-interchange-newline">/g,
220
+ /<br>$/i // Trailing BR elements
221
+ ]);
222
+
223
+ return html;
224
+ }
225
+
226
+ // TODO: Should be in some global class
227
+ function createIdGenerator(prefix) {
228
+ var count = 0;
229
+
230
+ return function() {
231
+ return prefix + (count++);
232
+ };
233
+ }
234
+
235
+ return {
236
+ filter: filter,
237
+ innerText: innerText,
238
+ trimHtml: trimHtml,
239
+ createIdGenerator: createIdGenerator
240
+ };
241
+ });
242
+
243
+ // Included from: js/tinymce/plugins/paste/classes/Clipboard.js
244
+
245
+ /**
246
+ * Clipboard.js
247
+ *
248
+ * Released under LGPL License.
249
+ * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
250
+ *
251
+ * License: http://www.tinymce.com/license
252
+ * Contributing: http://www.tinymce.com/contributing
253
+ */
254
+
255
+ /**
256
+ * This class contains logic for getting HTML contents out of the clipboard.
257
+ *
258
+ * We need to make a lot of ugly hacks to get the contents out of the clipboard since
259
+ * the W3C Clipboard API is broken in all browsers that have it: Gecko/WebKit/Blink.
260
+ * We might rewrite this the way those API:s stabilize. Browsers doesn't handle pasting
261
+ * from applications like Word the same way as it does when pasting into a contentEditable area
262
+ * so we need to do lots of extra work to try to get to this clipboard data.
263
+ *
264
+ * Current implementation steps:
265
+ * 1. On keydown with paste keys Ctrl+V or Shift+Insert create
266
+ * a paste bin element and move focus to that element.
267
+ * 2. Wait for the browser to fire a "paste" event and get the contents out of the paste bin.
268
+ * 3. Check if the paste was successful if true, process the HTML.
269
+ * (4). If the paste was unsuccessful use IE execCommand, Clipboard API, document.dataTransfer old WebKit API etc.
270
+ *
271
+ * @class tinymce.pasteplugin.Clipboard
272
+ * @private
273
+ */
274
+ define("tinymce/pasteplugin/Clipboard", [
275
+ "tinymce/Env",
276
+ "tinymce/dom/RangeUtils",
277
+ "tinymce/util/VK",
278
+ "tinymce/pasteplugin/Utils",
279
+ "tinymce/util/Delay"
280
+ ], function(Env, RangeUtils, VK, Utils, Delay) {
281
+ return function(editor) {
282
+ var self = this, pasteBinElm, lastRng, keyboardPasteTimeStamp = 0, draggingInternally = false;
283
+ var pasteBinDefaultContent = '%MCEPASTEBIN%', keyboardPastePlainTextState;
284
+ var mceInternalUrlPrefix = 'data:text/mce-internal,';
285
+ var uniqueId = Utils.createIdGenerator("mceclip");
286
+
287
+ /**
288
+ * Pastes the specified HTML. This means that the HTML is filtered and then
289
+ * inserted at the current selection in the editor. It will also fire paste events
290
+ * for custom user filtering.
291
+ *
292
+ * @param {String} html HTML code to paste into the current selection.
293
+ */
294
+ function pasteHtml(html) {
295
+ var args, dom = editor.dom;
296
+
297
+ args = editor.fire('BeforePastePreProcess', {content: html}); // Internal event used by Quirks
298
+ args = editor.fire('PastePreProcess', args);
299
+ html = args.content;
300
+
301
+ if (!args.isDefaultPrevented()) {
302
+ // User has bound PastePostProcess events then we need to pass it through a DOM node
303
+ // This is not ideal but we don't want to let the browser mess up the HTML for example
304
+ // some browsers add &nbsp; to P tags etc
305
+ if (editor.hasEventListeners('PastePostProcess') && !args.isDefaultPrevented()) {
306
+ // We need to attach the element to the DOM so Sizzle selectors work on the contents
307
+ var tempBody = dom.add(editor.getBody(), 'div', {style: 'display:none'}, html);
308
+ args = editor.fire('PastePostProcess', {node: tempBody});
309
+ dom.remove(tempBody);
310
+ html = args.node.innerHTML;
311
+ }
312
+
313
+ if (!args.isDefaultPrevented()) {
314
+ editor.insertContent(html, {merge: editor.settings.paste_merge_formats !== false, data: {paste: true}});
315
+ }
316
+ }
317
+ }
318
+
319
+ /**
320
+ * Pastes the specified text. This means that the plain text is processed
321
+ * and converted into BR and P elements. It will fire paste events for custom filtering.
322
+ *
323
+ * @param {String} text Text to paste as the current selection location.
324
+ */
325
+ function pasteText(text) {
326
+ text = editor.dom.encode(text).replace(/\r\n/g, '\n');
327
+
328
+ var startBlock = editor.dom.getParent(editor.selection.getStart(), editor.dom.isBlock);
329
+
330
+ // Create start block html for example <p attr="value">
331
+ var forcedRootBlockName = editor.settings.forced_root_block;
332
+ var forcedRootBlockStartHtml;
333
+ if (forcedRootBlockName) {
334
+ forcedRootBlockStartHtml = editor.dom.createHTML(forcedRootBlockName, editor.settings.forced_root_block_attrs);
335
+ forcedRootBlockStartHtml = forcedRootBlockStartHtml.substr(0, forcedRootBlockStartHtml.length - 3) + '>';
336
+ }
337
+
338
+ if ((startBlock && /^(PRE|DIV)$/.test(startBlock.nodeName)) || !forcedRootBlockName) {
339
+ text = Utils.filter(text, [
340
+ [/\n/g, "<br>"]
341
+ ]);
342
+ } else {
343
+ text = Utils.filter(text, [
344
+ [/\n\n/g, "</p>" + forcedRootBlockStartHtml],
345
+ [/^(.*<\/p>)(<p>)$/, forcedRootBlockStartHtml + '$1'],
346
+ [/\n/g, "<br />"]
347
+ ]);
348
+
349
+ if (text.indexOf('<p>') != -1) {
350
+ text = forcedRootBlockStartHtml + text;
351
+ }
352
+ }
353
+
354
+ pasteHtml(text);
355
+ }
356
+
357
+ /**
358
+ * Creates a paste bin element as close as possible to the current caret location and places the focus inside that element
359
+ * so that when the real paste event occurs the contents gets inserted into this element
360
+ * instead of the current editor selection element.
361
+ */
362
+ function createPasteBin() {
363
+ var dom = editor.dom, body = editor.getBody();
364
+ var viewport = editor.dom.getViewPort(editor.getWin()), scrollTop = viewport.y, top = 20;
365
+ var scrollContainer;
366
+
367
+ lastRng = editor.selection.getRng();
368
+
369
+ if (editor.inline) {
370
+ scrollContainer = editor.selection.getScrollContainer();
371
+
372
+ // Can't always rely on scrollTop returning a useful value.
373
+ // It returns 0 if the browser doesn't support scrollTop for the element or is non-scrollable
374
+ if (scrollContainer && scrollContainer.scrollTop > 0) {
375
+ scrollTop = scrollContainer.scrollTop;
376
+ }
377
+ }
378
+
379
+ /**
380
+ * Returns the rect of the current caret if the caret is in an empty block before a
381
+ * BR we insert a temporary invisible character that we get the rect this way we always get a proper rect.
382
+ *
383
+ * TODO: This might be useful in core.
384
+ */
385
+ function getCaretRect(rng) {
386
+ var rects, textNode, node, container = rng.startContainer;
387
+
388
+ rects = rng.getClientRects();
389
+ if (rects.length) {
390
+ return rects[0];
391
+ }
392
+
393
+ if (!rng.collapsed || container.nodeType != 1) {
394
+ return;
395
+ }
396
+
397
+ node = container.childNodes[lastRng.startOffset];
398
+
399
+ // Skip empty whitespace nodes
400
+ while (node && node.nodeType == 3 && !node.data.length) {
401
+ node = node.nextSibling;
402
+ }
403
+
404
+ if (!node) {
405
+ return;
406
+ }
407
+
408
+ // Check if the location is |<br>
409
+ // TODO: Might need to expand this to say |<table>
410
+ if (node.tagName == 'BR') {
411
+ textNode = dom.doc.createTextNode('\uFEFF');
412
+ node.parentNode.insertBefore(textNode, node);
413
+
414
+ rng = dom.createRng();
415
+ rng.setStartBefore(textNode);
416
+ rng.setEndAfter(textNode);
417
+
418
+ rects = rng.getClientRects();
419
+ dom.remove(textNode);
420
+ }
421
+
422
+ if (rects.length) {
423
+ return rects[0];
424
+ }
425
+ }
426
+
427
+ // Calculate top cordinate this is needed to avoid scrolling to top of document
428
+ // We want the paste bin to be as close to the caret as possible to avoid scrolling
429
+ if (lastRng.getClientRects) {
430
+ var rect = getCaretRect(lastRng);
431
+
432
+ if (rect) {
433
+ // Client rects gets us closes to the actual
434
+ // caret location in for example a wrapped paragraph block
435
+ top = scrollTop + (rect.top - dom.getPos(body).y);
436
+ } else {
437
+ top = scrollTop;
438
+
439
+ // Check if we can find a closer location by checking the range element
440
+ var container = lastRng.startContainer;
441
+ if (container) {
442
+ if (container.nodeType == 3 && container.parentNode != body) {
443
+ container = container.parentNode;
444
+ }
445
+
446
+ if (container.nodeType == 1) {
447
+ top = dom.getPos(container, scrollContainer || body).y;
448
+ }
449
+ }
450
+ }
451
+ }
452
+
453
+ // Create a pastebin
454
+ pasteBinElm = dom.add(editor.getBody(), 'div', {
455
+ id: "mcepastebin",
456
+ contentEditable: true,
457
+ "data-mce-bogus": "all",
458
+ style: 'position: absolute; top: ' + top + 'px;' +
459
+ 'width: 10px; height: 10px; overflow: hidden; opacity: 0'
460
+ }, pasteBinDefaultContent);
461
+
462
+ // Move paste bin out of sight since the controlSelection rect gets displayed otherwise on IE and Gecko
463
+ if (Env.ie || Env.gecko) {
464
+ dom.setStyle(pasteBinElm, 'left', dom.getStyle(body, 'direction', true) == 'rtl' ? 0xFFFF : -0xFFFF);
465
+ }
466
+
467
+ // Prevent focus events from bubbeling fixed FocusManager issues
468
+ dom.bind(pasteBinElm, 'beforedeactivate focusin focusout', function(e) {
469
+ e.stopPropagation();
470
+ });
471
+
472
+ pasteBinElm.focus();
473
+ editor.selection.select(pasteBinElm, true);
474
+ }
475
+
476
+ /**
477
+ * Removes the paste bin if it exists.
478
+ */
479
+ function removePasteBin() {
480
+ if (pasteBinElm) {
481
+ var pasteBinClone;
482
+
483
+ // WebKit/Blink might clone the div so
484
+ // lets make sure we remove all clones
485
+ // TODO: Man o man is this ugly. WebKit is the new IE! Remove this if they ever fix it!
486
+ while ((pasteBinClone = editor.dom.get('mcepastebin'))) {
487
+ editor.dom.remove(pasteBinClone);
488
+ editor.dom.unbind(pasteBinClone);
489
+ }
490
+
491
+ if (lastRng) {
492
+ editor.selection.setRng(lastRng);
493
+ }
494
+ }
495
+
496
+ pasteBinElm = lastRng = null;
497
+ }
498
+
499
+ /**
500
+ * Returns the contents of the paste bin as a HTML string.
501
+ *
502
+ * @return {String} Get the contents of the paste bin.
503
+ */
504
+ function getPasteBinHtml() {
505
+ var html = '', pasteBinClones, i, clone, cloneHtml;
506
+
507
+ // Since WebKit/Chrome might clone the paste bin when pasting
508
+ // for example: <img style="float: right"> we need to check if any of them contains some useful html.
509
+ // TODO: Man o man is this ugly. WebKit is the new IE! Remove this if they ever fix it!
510
+ pasteBinClones = editor.dom.select('div[id=mcepastebin]');
511
+ for (i = 0; i < pasteBinClones.length; i++) {
512
+ clone = pasteBinClones[i];
513
+
514
+ // Pasting plain text produces pastebins in pastebinds makes sence right!?
515
+ if (clone.firstChild && clone.firstChild.id == 'mcepastebin') {
516
+ clone = clone.firstChild;
517
+ }
518
+
519
+ cloneHtml = clone.innerHTML;
520
+ if (html != pasteBinDefaultContent) {
521
+ html += cloneHtml;
522
+ }
523
+ }
524
+
525
+ return html;
526
+ }
527
+
528
+ /**
529
+ * Gets various content types out of a datatransfer object.
530
+ *
531
+ * @param {DataTransfer} dataTransfer Event fired on paste.
532
+ * @return {Object} Object with mime types and data for those mime types.
533
+ */
534
+ function getDataTransferItems(dataTransfer) {
535
+ var items = {};
536
+
537
+ if (dataTransfer) {
538
+ // Use old WebKit/IE API
539
+ if (dataTransfer.getData) {
540
+ var legacyText = dataTransfer.getData('Text');
541
+ if (legacyText && legacyText.length > 0) {
542
+ if (legacyText.indexOf(mceInternalUrlPrefix) == -1) {
543
+ items['text/plain'] = legacyText;
544
+ }
545
+ }
546
+ }
547
+
548
+ if (dataTransfer.types) {
549
+ for (var i = 0; i < dataTransfer.types.length; i++) {
550
+ var contentType = dataTransfer.types[i];
551
+ items[contentType] = dataTransfer.getData(contentType);
552
+ }
553
+ }
554
+ }
555
+
556
+ return items;
557
+ }
558
+
559
+ /**
560
+ * Gets various content types out of the Clipboard API. It will also get the
561
+ * plain text using older IE and WebKit API:s.
562
+ *
563
+ * @param {ClipboardEvent} clipboardEvent Event fired on paste.
564
+ * @return {Object} Object with mime types and data for those mime types.
565
+ */
566
+ function getClipboardContent(clipboardEvent) {
567
+ return getDataTransferItems(clipboardEvent.clipboardData || editor.getDoc().dataTransfer);
568
+ }
569
+
570
+ function hasHtmlOrText(content) {
571
+ return hasContentType(content, 'text/html') || hasContentType(content, 'text/plain');
572
+ }
573
+
574
+ /**
575
+ * Checks if the clipboard contains image data if it does it will take that data
576
+ * and convert it into a data url image and paste that image at the caret location.
577
+ *
578
+ * @param {ClipboardEvent} e Paste/drop event object.
579
+ * @param {DOMRange} rng Rng object to move selection to.
580
+ * @return {Boolean} true/false if the image data was found or not.
581
+ */
582
+ function pasteImageData(e, rng) {
583
+ var dataTransfer = e.clipboardData || e.dataTransfer;
584
+
585
+ function getBase64FromUri(uri) {
586
+ var idx;
587
+
588
+ idx = uri.indexOf(',');
589
+ if (idx !== -1) {
590
+ return uri.substr(idx + 1);
591
+ }
592
+
593
+ return null;
594
+ }
595
+
596
+ function processItems(items) {
597
+ var i, item, reader, hadImage = false;
598
+
599
+ function pasteImage(reader, blob) {
600
+ if (rng) {
601
+ editor.selection.setRng(rng);
602
+ rng = null;
603
+ }
604
+
605
+ var blobCache = editor.editorUpload.blobCache;
606
+ var blobInfo = blobCache.create(uniqueId(), blob, getBase64FromUri(reader.result));
607
+ blobCache.add(blobInfo);
608
+
609
+ pasteHtml('<img src="' + blobInfo.blobUri() + '">');
610
+ }
611
+
612
+ if (items) {
613
+ for (i = 0; i < items.length; i++) {
614
+ item = items[i];
615
+
616
+ if (/^image\/(jpeg|png|gif|bmp)$/.test(item.type)) {
617
+ var blob = item.getAsFile ? item.getAsFile() : item;
618
+
619
+ reader = new FileReader();
620
+ reader.onload = pasteImage.bind(null, reader, blob);
621
+ reader.readAsDataURL(blob);
622
+
623
+ e.preventDefault();
624
+ hadImage = true;
625
+ }
626
+ }
627
+ }
628
+
629
+ return hadImage;
630
+ }
631
+
632
+ if (editor.settings.paste_data_images && dataTransfer) {
633
+ return processItems(dataTransfer.items) || processItems(dataTransfer.files);
634
+ }
635
+ }
636
+
637
+ /**
638
+ * Chrome on Android doesn't support proper clipboard access so we have no choice but to allow the browser default behavior.
639
+ *
640
+ * @param {Event} e Paste event object to check if it contains any data.
641
+ * @return {Boolean} true/false if the clipboard is empty or not.
642
+ */
643
+ function isBrokenAndroidClipboardEvent(e) {
644
+ var clipboardData = e.clipboardData;
645
+
646
+ return navigator.userAgent.indexOf('Android') != -1 && clipboardData && clipboardData.items && clipboardData.items.length === 0;
647
+ }
648
+
649
+ function getCaretRangeFromEvent(e) {
650
+ return RangeUtils.getCaretRangeFromPoint(e.clientX, e.clientY, editor.getDoc());
651
+ }
652
+
653
+ function hasContentType(clipboardContent, mimeType) {
654
+ return mimeType in clipboardContent && clipboardContent[mimeType].length > 0;
655
+ }
656
+
657
+ function isKeyboardPasteEvent(e) {
658
+ return (VK.metaKeyPressed(e) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45);
659
+ }
660
+
661
+ function registerEventHandlers() {
662
+ editor.on('keydown', function(e) {
663
+ function removePasteBinOnKeyUp(e) {
664
+ // Ctrl+V or Shift+Insert
665
+ if (isKeyboardPasteEvent(e) && !e.isDefaultPrevented()) {
666
+ removePasteBin();
667
+ }
668
+ }
669
+
670
+ // Ctrl+V or Shift+Insert
671
+ if (isKeyboardPasteEvent(e) && !e.isDefaultPrevented()) {
672
+ keyboardPastePlainTextState = e.shiftKey && e.keyCode == 86;
673
+
674
+ // Edge case on Safari on Mac where it doesn't handle Cmd+Shift+V correctly
675
+ // it fires the keydown but no paste or keyup so we are left with a paste bin
676
+ if (keyboardPastePlainTextState && Env.webkit && navigator.userAgent.indexOf('Version/') != -1) {
677
+ return;
678
+ }
679
+
680
+ // Prevent undoManager keydown handler from making an undo level with the pastebin in it
681
+ e.stopImmediatePropagation();
682
+
683
+ keyboardPasteTimeStamp = new Date().getTime();
684
+
685
+ // IE doesn't support Ctrl+Shift+V and it doesn't even produce a paste event
686
+ // so lets fake a paste event and let IE use the execCommand/dataTransfer methods
687
+ if (Env.ie && keyboardPastePlainTextState) {
688
+ e.preventDefault();
689
+ editor.fire('paste', {ieFake: true});
690
+ return;
691
+ }
692
+
693
+ removePasteBin();
694
+ createPasteBin();
695
+
696
+ // Remove pastebin if we get a keyup and no paste event
697
+ // For example pasting a file in IE 11 will not produce a paste event
698
+ editor.once('keyup', removePasteBinOnKeyUp);
699
+ editor.once('paste', function() {
700
+ editor.off('keyup', removePasteBinOnKeyUp);
701
+ });
702
+ }
703
+ });
704
+
705
+ function insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode) {
706
+ var content;
707
+
708
+ // Grab HTML from Clipboard API or paste bin as a fallback
709
+ if (hasContentType(clipboardContent, 'text/html')) {
710
+ content = clipboardContent['text/html'];
711
+ } else {
712
+ content = getPasteBinHtml();
713
+
714
+ // If paste bin is empty try using plain text mode
715
+ // since that is better than nothing right
716
+ if (content == pasteBinDefaultContent) {
717
+ plainTextMode = true;
718
+ }
719
+ }
720
+
721
+ content = Utils.trimHtml(content);
722
+
723
+ // WebKit has a nice bug where it clones the paste bin if you paste from for example notepad
724
+ // so we need to force plain text mode in this case
725
+ if (pasteBinElm && pasteBinElm.firstChild && pasteBinElm.firstChild.id === 'mcepastebin') {
726
+ plainTextMode = true;
727
+ }
728
+
729
+ removePasteBin();
730
+
731
+ // If we got nothing from clipboard API and pastebin then we could try the last resort: plain/text
732
+ if (!content.length) {
733
+ plainTextMode = true;
734
+ }
735
+
736
+ // Grab plain text from Clipboard API or convert existing HTML to plain text
737
+ if (plainTextMode) {
738
+ // Use plain text contents from Clipboard API unless the HTML contains paragraphs then
739
+ // we should convert the HTML to plain text since works better when pasting HTML/Word contents as plain text
740
+ if (hasContentType(clipboardContent, 'text/plain') && content.indexOf('</p>') == -1) {
741
+ content = clipboardContent['text/plain'];
742
+ } else {
743
+ content = Utils.innerText(content);
744
+ }
745
+ }
746
+
747
+ // If the content is the paste bin default HTML then it was
748
+ // impossible to get the cliboard data out.
749
+ if (content == pasteBinDefaultContent) {
750
+ if (!isKeyBoardPaste) {
751
+ editor.windowManager.alert('Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents.');
752
+ }
753
+
754
+ return;
755
+ }
756
+
757
+ if (plainTextMode) {
758
+ pasteText(content);
759
+ } else {
760
+ pasteHtml(content);
761
+ }
762
+ }
763
+
764
+ var getLastRng = function() {
765
+ return lastRng || editor.selection.getRng();
766
+ };
767
+
768
+ editor.on('paste', function(e) {
769
+ // Getting content from the Clipboard can take some time
770
+ var clipboardTimer = new Date().getTime();
771
+ var clipboardContent = getClipboardContent(e);
772
+ var clipboardDelay = new Date().getTime() - clipboardTimer;
773
+
774
+ var isKeyBoardPaste = (new Date().getTime() - keyboardPasteTimeStamp - clipboardDelay) < 1000;
775
+ var plainTextMode = self.pasteFormat == "text" || keyboardPastePlainTextState;
776
+
777
+ keyboardPastePlainTextState = false;
778
+
779
+ if (e.isDefaultPrevented() || isBrokenAndroidClipboardEvent(e)) {
780
+ removePasteBin();
781
+ return;
782
+ }
783
+
784
+ if (!hasHtmlOrText(clipboardContent) && pasteImageData(e, getLastRng())) {
785
+ removePasteBin();
786
+ return;
787
+ }
788
+
789
+ // Not a keyboard paste prevent default paste and try to grab the clipboard contents using different APIs
790
+ if (!isKeyBoardPaste) {
791
+ e.preventDefault();
792
+ }
793
+
794
+ // Try IE only method if paste isn't a keyboard paste
795
+ if (Env.ie && (!isKeyBoardPaste || e.ieFake)) {
796
+ createPasteBin();
797
+
798
+ editor.dom.bind(pasteBinElm, 'paste', function(e) {
799
+ e.stopPropagation();
800
+ });
801
+
802
+ editor.getDoc().execCommand('Paste', false, null);
803
+ clipboardContent["text/html"] = getPasteBinHtml();
804
+ }
805
+
806
+ // If clipboard API has HTML then use that directly
807
+ if (hasContentType(clipboardContent, 'text/html')) {
808
+ e.preventDefault();
809
+ insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode);
810
+ } else {
811
+ Delay.setEditorTimeout(editor, function() {
812
+ insertClipboardContent(clipboardContent, isKeyBoardPaste, plainTextMode);
813
+ }, 0);
814
+ }
815
+ });
816
+
817
+ editor.on('dragstart dragend', function(e) {
818
+ draggingInternally = e.type == 'dragstart';
819
+ });
820
+
821
+ editor.on('drop', function(e) {
822
+ var dropContent, rng;
823
+
824
+ rng = getCaretRangeFromEvent(e);
825
+
826
+ if (e.isDefaultPrevented() || draggingInternally) {
827
+ return;
828
+ }
829
+
830
+ dropContent = getDataTransferItems(e.dataTransfer);
831
+
832
+ if (!hasHtmlOrText(dropContent) && pasteImageData(e, rng)) {
833
+ return;
834
+ }
835
+
836
+ if (rng && editor.settings.paste_filter_drop !== false) {
837
+ var content = dropContent['mce-internal'] || dropContent['text/html'] || dropContent['text/plain'];
838
+
839
+ if (content) {
840
+ e.preventDefault();
841
+
842
+ editor.undoManager.transact(function() {
843
+ if (dropContent['mce-internal']) {
844
+ editor.execCommand('Delete');
845
+ }
846
+
847
+ editor.selection.setRng(rng);
848
+
849
+ content = Utils.trimHtml(content);
850
+
851
+ if (!dropContent['text/html']) {
852
+ pasteText(content);
853
+ } else {
854
+ pasteHtml(content);
855
+ }
856
+ });
857
+ }
858
+ }
859
+ });
860
+
861
+ editor.on('dragover dragend', function(e) {
862
+ if (editor.settings.paste_data_images) {
863
+ e.preventDefault();
864
+ }
865
+ });
866
+ }
867
+
868
+ self.pasteHtml = pasteHtml;
869
+ self.pasteText = pasteText;
870
+
871
+ editor.on('preInit', function() {
872
+ registerEventHandlers();
873
+
874
+ // Remove all data images from paste for example from Gecko
875
+ // except internal images like video elements
876
+ editor.parser.addNodeFilter('img', function(nodes, name, args) {
877
+ function isPasteInsert(args) {
878
+ return args.data && args.data.paste === true;
879
+ }
880
+
881
+ function remove(node) {
882
+ if (!node.attr('data-mce-object') && src !== Env.transparentSrc) {
883
+ node.remove();
884
+ }
885
+ }
886
+
887
+ function isWebKitFakeUrl(src) {
888
+ return src.indexOf("webkit-fake-url") === 0;
889
+ }
890
+
891
+ function isDataUri(src) {
892
+ return src.indexOf("data:") === 0;
893
+ }
894
+
895
+ if (!editor.settings.paste_data_images && isPasteInsert(args)) {
896
+ var i = nodes.length;
897
+
898
+ while (i--) {
899
+ var src = nodes[i].attributes.map.src;
900
+
901
+ if (!src) {
902
+ continue;
903
+ }
904
+
905
+ // Safari on Mac produces webkit-fake-url see: https://bugs.webkit.org/show_bug.cgi?id=49141
906
+ if (isWebKitFakeUrl(src)) {
907
+ remove(nodes[i]);
908
+ } else if (!editor.settings.allow_html_data_urls && isDataUri(src)) {
909
+ remove(nodes[i]);
910
+ }
911
+ }
912
+ }
913
+ });
914
+ });
915
+ };
916
+ });
917
+
918
+ // Included from: js/tinymce/plugins/paste/classes/WordFilter.js
919
+
920
+ /**
921
+ * WordFilter.js
922
+ *
923
+ * Released under LGPL License.
924
+ * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
925
+ *
926
+ * License: http://www.tinymce.com/license
927
+ * Contributing: http://www.tinymce.com/contributing
928
+ */
929
+
930
+ /**
931
+ * This class parses word HTML into proper TinyMCE markup.
932
+ *
933
+ * @class tinymce.pasteplugin.WordFilter
934
+ * @private
935
+ */
936
+ define("tinymce/pasteplugin/WordFilter", [
937
+ "tinymce/util/Tools",
938
+ "tinymce/html/DomParser",
939
+ "tinymce/html/Schema",
940
+ "tinymce/html/Serializer",
941
+ "tinymce/html/Node",
942
+ "tinymce/pasteplugin/Utils"
943
+ ], function(Tools, DomParser, Schema, Serializer, Node, Utils) {
944
+ /**
945
+ * Checks if the specified content is from any of the following sources: MS Word/Office 365/Google docs.
946
+ */
947
+ function isWordContent(content) {
948
+ return (
949
+ (/<font face="Times New Roman"|class="?Mso|style="[^"]*\bmso-|style='[^'']*\bmso-|w:WordDocument/i).test(content) ||
950
+ (/class="OutlineElement/).test(content) ||
951
+ (/id="?docs\-internal\-guid\-/.test(content))
952
+ );
953
+ }
954
+
955
+ /**
956
+ * Checks if the specified text starts with "1. " or "a. " etc.
957
+ */
958
+ function isNumericList(text) {
959
+ var found, patterns;
960
+
961
+ patterns = [
962
+ /^[IVXLMCD]{1,2}\.[ \u00a0]/, // Roman upper case
963
+ /^[ivxlmcd]{1,2}\.[ \u00a0]/, // Roman lower case
964
+ /^[a-z]{1,2}[\.\)][ \u00a0]/, // Alphabetical a-z
965
+ /^[A-Z]{1,2}[\.\)][ \u00a0]/, // Alphabetical A-Z
966
+ /^[0-9]+\.[ \u00a0]/, // Numeric lists
967
+ /^[\u3007\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d]+\.[ \u00a0]/, // Japanese
968
+ /^[\u58f1\u5f10\u53c2\u56db\u4f0d\u516d\u4e03\u516b\u4e5d\u62fe]+\.[ \u00a0]/ // Chinese
969
+ ];
970
+
971
+ text = text.replace(/^[\u00a0 ]+/, '');
972
+
973
+ Tools.each(patterns, function(pattern) {
974
+ if (pattern.test(text)) {
975
+ found = true;
976
+ return false;
977
+ }
978
+ });
979
+
980
+ return found;
981
+ }
982
+
983
+ function isBulletList(text) {
984
+ return /^[\s\u00a0]*[\u2022\u00b7\u00a7\u25CF]\s*/.test(text);
985
+ }
986
+
987
+ function WordFilter(editor) {
988
+ var settings = editor.settings;
989
+
990
+ editor.on('BeforePastePreProcess', function(e) {
991
+ var content = e.content, retainStyleProperties, validStyles;
992
+
993
+ // Remove google docs internal guid markers
994
+ content = content.replace(/<b[^>]+id="?docs-internal-[^>]*>/gi, '');
995
+ content = content.replace(/<br class="?Apple-interchange-newline"?>/gi, '');
996
+
997
+ retainStyleProperties = settings.paste_retain_style_properties;
998
+ if (retainStyleProperties) {
999
+ validStyles = Tools.makeMap(retainStyleProperties.split(/[, ]/));
1000
+ }
1001
+
1002
+ /**
1003
+ * Converts fake bullet and numbered lists to real semantic OL/UL.
1004
+ *
1005
+ * @param {tinymce.html.Node} node Root node to convert children of.
1006
+ */
1007
+ function convertFakeListsToProperLists(node) {
1008
+ var currentListNode, prevListNode, lastLevel = 1;
1009
+
1010
+ function getText(node) {
1011
+ var txt = '';
1012
+
1013
+ if (node.type === 3) {
1014
+ return node.value;
1015
+ }
1016
+
1017
+ if ((node = node.firstChild)) {
1018
+ do {
1019
+ txt += getText(node);
1020
+ } while ((node = node.next));
1021
+ }
1022
+
1023
+ return txt;
1024
+ }
1025
+
1026
+ function trimListStart(node, regExp) {
1027
+ if (node.type === 3) {
1028
+ if (regExp.test(node.value)) {
1029
+ node.value = node.value.replace(regExp, '');
1030
+ return false;
1031
+ }
1032
+ }
1033
+
1034
+ if ((node = node.firstChild)) {
1035
+ do {
1036
+ if (!trimListStart(node, regExp)) {
1037
+ return false;
1038
+ }
1039
+ } while ((node = node.next));
1040
+ }
1041
+
1042
+ return true;
1043
+ }
1044
+
1045
+ function removeIgnoredNodes(node) {
1046
+ if (node._listIgnore) {
1047
+ node.remove();
1048
+ return;
1049
+ }
1050
+
1051
+ if ((node = node.firstChild)) {
1052
+ do {
1053
+ removeIgnoredNodes(node);
1054
+ } while ((node = node.next));
1055
+ }
1056
+ }
1057
+
1058
+ function convertParagraphToLi(paragraphNode, listName, start) {
1059
+ var level = paragraphNode._listLevel || lastLevel;
1060
+
1061
+ // Handle list nesting
1062
+ if (level != lastLevel) {
1063
+ if (level < lastLevel) {
1064
+ // Move to parent list
1065
+ if (currentListNode) {
1066
+ currentListNode = currentListNode.parent.parent;
1067
+ }
1068
+ } else {
1069
+ // Create new list
1070
+ prevListNode = currentListNode;
1071
+ currentListNode = null;
1072
+ }
1073
+ }
1074
+
1075
+ if (!currentListNode || currentListNode.name != listName) {
1076
+ prevListNode = prevListNode || currentListNode;
1077
+ currentListNode = new Node(listName, 1);
1078
+
1079
+ if (start > 1) {
1080
+ currentListNode.attr('start', '' + start);
1081
+ }
1082
+
1083
+ paragraphNode.wrap(currentListNode);
1084
+ } else {
1085
+ currentListNode.append(paragraphNode);
1086
+ }
1087
+
1088
+ paragraphNode.name = 'li';
1089
+
1090
+ // Append list to previous list if it exists
1091
+ if (level > lastLevel && prevListNode) {
1092
+ prevListNode.lastChild.append(currentListNode);
1093
+ }
1094
+
1095
+ lastLevel = level;
1096
+
1097
+ // Remove start of list item "1. " or "&middot; " etc
1098
+ removeIgnoredNodes(paragraphNode);
1099
+ trimListStart(paragraphNode, /^\u00a0+/);
1100
+ trimListStart(paragraphNode, /^\s*([\u2022\u00b7\u00a7\u25CF]|\w+\.)/);
1101
+ trimListStart(paragraphNode, /^\u00a0+/);
1102
+ }
1103
+
1104
+ // Build a list of all root level elements before we start
1105
+ // altering them in the loop below.
1106
+ var elements = [], child = node.firstChild;
1107
+ while (typeof child !== 'undefined' && child !== null) {
1108
+ elements.push(child);
1109
+
1110
+ child = child.walk();
1111
+ if (child !== null) {
1112
+ while (typeof child !== 'undefined' && child.parent !== node) {
1113
+ child = child.walk();
1114
+ }
1115
+ }
1116
+ }
1117
+
1118
+ for (var i = 0; i < elements.length; i++) {
1119
+ node = elements[i];
1120
+
1121
+ if (node.name == 'p' && node.firstChild) {
1122
+ // Find first text node in paragraph
1123
+ var nodeText = getText(node);
1124
+
1125
+ // Detect unordered lists look for bullets
1126
+ if (isBulletList(nodeText)) {
1127
+ convertParagraphToLi(node, 'ul');
1128
+ continue;
1129
+ }
1130
+
1131
+ // Detect ordered lists 1., a. or ixv.
1132
+ if (isNumericList(nodeText)) {
1133
+ // Parse OL start number
1134
+ var matches = /([0-9]+)\./.exec(nodeText);
1135
+ var start = 1;
1136
+ if (matches) {
1137
+ start = parseInt(matches[1], 10);
1138
+ }
1139
+
1140
+ convertParagraphToLi(node, 'ol', start);
1141
+ continue;
1142
+ }
1143
+
1144
+ // Convert paragraphs marked as lists but doesn't look like anything
1145
+ if (node._listLevel) {
1146
+ convertParagraphToLi(node, 'ul', 1);
1147
+ continue;
1148
+ }
1149
+
1150
+ currentListNode = null;
1151
+ } else {
1152
+ // If the root level element isn't a p tag which can be
1153
+ // processed by convertParagraphToLi, it interrupts the
1154
+ // lists, causing a new list to start instead of having
1155
+ // elements from the next list inserted above this tag.
1156
+ prevListNode = currentListNode;
1157
+ currentListNode = null;
1158
+ }
1159
+ }
1160
+ }
1161
+
1162
+ function filterStyles(node, styleValue) {
1163
+ var outputStyles = {}, matches, styles = editor.dom.parseStyle(styleValue);
1164
+
1165
+ Tools.each(styles, function(value, name) {
1166
+ // Convert various MS styles to W3C styles
1167
+ switch (name) {
1168
+ case 'mso-list':
1169
+ // Parse out list indent level for lists
1170
+ matches = /\w+ \w+([0-9]+)/i.exec(styleValue);
1171
+ if (matches) {
1172
+ node._listLevel = parseInt(matches[1], 10);
1173
+ }
1174
+
1175
+ // Remove these nodes <span style="mso-list:Ignore">o</span>
1176
+ // Since the span gets removed we mark the text node and the span
1177
+ if (/Ignore/i.test(value) && node.firstChild) {
1178
+ node._listIgnore = true;
1179
+ node.firstChild._listIgnore = true;
1180
+ }
1181
+
1182
+ break;
1183
+
1184
+ case "horiz-align":
1185
+ name = "text-align";
1186
+ break;
1187
+
1188
+ case "vert-align":
1189
+ name = "vertical-align";
1190
+ break;
1191
+
1192
+ case "font-color":
1193
+ case "mso-foreground":
1194
+ name = "color";
1195
+ break;
1196
+
1197
+ case "mso-background":
1198
+ case "mso-highlight":
1199
+ name = "background";
1200
+ break;
1201
+
1202
+ case "font-weight":
1203
+ case "font-style":
1204
+ if (value != "normal") {
1205
+ outputStyles[name] = value;
1206
+ }
1207
+ return;
1208
+
1209
+ case "mso-element":
1210
+ // Remove track changes code
1211
+ if (/^(comment|comment-list)$/i.test(value)) {
1212
+ node.remove();
1213
+ return;
1214
+ }
1215
+
1216
+ break;
1217
+ }
1218
+
1219
+ if (name.indexOf('mso-comment') === 0) {
1220
+ node.remove();
1221
+ return;
1222
+ }
1223
+
1224
+ // Never allow mso- prefixed names
1225
+ if (name.indexOf('mso-') === 0) {
1226
+ return;
1227
+ }
1228
+
1229
+ // Output only valid styles
1230
+ if (retainStyleProperties == "all" || (validStyles && validStyles[name])) {
1231
+ outputStyles[name] = value;
1232
+ }
1233
+ });
1234
+
1235
+ // Convert bold style to "b" element
1236
+ if (/(bold)/i.test(outputStyles["font-weight"])) {
1237
+ delete outputStyles["font-weight"];
1238
+ node.wrap(new Node("b", 1));
1239
+ }
1240
+
1241
+ // Convert italic style to "i" element
1242
+ if (/(italic)/i.test(outputStyles["font-style"])) {
1243
+ delete outputStyles["font-style"];
1244
+ node.wrap(new Node("i", 1));
1245
+ }
1246
+
1247
+ // Serialize the styles and see if there is something left to keep
1248
+ outputStyles = editor.dom.serializeStyle(outputStyles, node.name);
1249
+ if (outputStyles) {
1250
+ return outputStyles;
1251
+ }
1252
+
1253
+ return null;
1254
+ }
1255
+
1256
+ if (settings.paste_enable_default_filters === false) {
1257
+ return;
1258
+ }
1259
+
1260
+ // Detect is the contents is Word junk HTML
1261
+ if (isWordContent(e.content)) {
1262
+ e.wordContent = true; // Mark it for other processors
1263
+
1264
+ // Remove basic Word junk
1265
+ content = Utils.filter(content, [
1266
+ // Word comments like conditional comments etc
1267
+ /<!--[\s\S]+?-->/gi,
1268
+
1269
+ // Remove comments, scripts (e.g., msoShowComment), XML tag, VML content,
1270
+ // MS Office namespaced tags, and a few other tags
1271
+ /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,
1272
+
1273
+ // Convert <s> into <strike> for line-though
1274
+ [/<(\/?)s>/gi, "<$1strike>"],
1275
+
1276
+ // Replace nsbp entites to char since it's easier to handle
1277
+ [/&nbsp;/gi, "\u00a0"],
1278
+
1279
+ // Convert <span style="mso-spacerun:yes">___</span> to string of alternating
1280
+ // breaking/non-breaking spaces of same length
1281
+ [/<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi,
1282
+ function(str, spaces) {
1283
+ return (spaces.length > 0) ?
1284
+ spaces.replace(/./, " ").slice(Math.floor(spaces.length / 2)).split("").join("\u00a0") : "";
1285
+ }
1286
+ ]
1287
+ ]);
1288
+
1289
+ var validElements = settings.paste_word_valid_elements;
1290
+ if (!validElements) {
1291
+ validElements = (
1292
+ '-strong/b,-em/i,-u,-span,-p,-ol,-ul,-li,-h1,-h2,-h3,-h4,-h5,-h6,' +
1293
+ '-p/div,-a[href|name],sub,sup,strike,br,del,table[width],tr,' +
1294
+ 'td[colspan|rowspan|width],th[colspan|rowspan|width],thead,tfoot,tbody'
1295
+ );
1296
+ }
1297
+
1298
+ // Setup strict schema
1299
+ var schema = new Schema({
1300
+ valid_elements: validElements,
1301
+ valid_children: '-li[p]'
1302
+ });
1303
+
1304
+ // Add style/class attribute to all element rules since the user might have removed them from
1305
+ // paste_word_valid_elements config option and we need to check them for properties
1306
+ Tools.each(schema.elements, function(rule) {
1307
+ /*eslint dot-notation:0*/
1308
+ if (!rule.attributes["class"]) {
1309
+ rule.attributes["class"] = {};
1310
+ rule.attributesOrder.push("class");
1311
+ }
1312
+
1313
+ if (!rule.attributes.style) {
1314
+ rule.attributes.style = {};
1315
+ rule.attributesOrder.push("style");
1316
+ }
1317
+ });
1318
+
1319
+ // Parse HTML into DOM structure
1320
+ var domParser = new DomParser({}, schema);
1321
+
1322
+ // Filter styles to remove "mso" specific styles and convert some of them
1323
+ domParser.addAttributeFilter('style', function(nodes) {
1324
+ var i = nodes.length, node;
1325
+
1326
+ while (i--) {
1327
+ node = nodes[i];
1328
+ node.attr('style', filterStyles(node, node.attr('style')));
1329
+
1330
+ // Remove pointess spans
1331
+ if (node.name == 'span' && node.parent && !node.attributes.length) {
1332
+ node.unwrap();
1333
+ }
1334
+ }
1335
+ });
1336
+
1337
+ // Check the class attribute for comments or del items and remove those
1338
+ domParser.addAttributeFilter('class', function(nodes) {
1339
+ var i = nodes.length, node, className;
1340
+
1341
+ while (i--) {
1342
+ node = nodes[i];
1343
+
1344
+ className = node.attr('class');
1345
+ if (/^(MsoCommentReference|MsoCommentText|msoDel)$/i.test(className)) {
1346
+ node.remove();
1347
+ }
1348
+
1349
+ node.attr('class', null);
1350
+ }
1351
+ });
1352
+
1353
+ // Remove all del elements since we don't want the track changes code in the editor
1354
+ domParser.addNodeFilter('del', function(nodes) {
1355
+ var i = nodes.length;
1356
+
1357
+ while (i--) {
1358
+ nodes[i].remove();
1359
+ }
1360
+ });
1361
+
1362
+ // Keep some of the links and anchors
1363
+ domParser.addNodeFilter('a', function(nodes) {
1364
+ var i = nodes.length, node, href, name;
1365
+
1366
+ while (i--) {
1367
+ node = nodes[i];
1368
+ href = node.attr('href');
1369
+ name = node.attr('name');
1370
+
1371
+ if (href && href.indexOf('#_msocom_') != -1) {
1372
+ node.remove();
1373
+ continue;
1374
+ }
1375
+
1376
+ if (href && href.indexOf('file://') === 0) {
1377
+ href = href.split('#')[1];
1378
+ if (href) {
1379
+ href = '#' + href;
1380
+ }
1381
+ }
1382
+
1383
+ if (!href && !name) {
1384
+ node.unwrap();
1385
+ } else {
1386
+ // Remove all named anchors that aren't specific to TOC, Footnotes or Endnotes
1387
+ if (name && !/^_?(?:toc|edn|ftn)/i.test(name)) {
1388
+ node.unwrap();
1389
+ continue;
1390
+ }
1391
+
1392
+ node.attr({
1393
+ href: href,
1394
+ name: name
1395
+ });
1396
+ }
1397
+ }
1398
+ });
1399
+
1400
+ // Parse into DOM structure
1401
+ var rootNode = domParser.parse(content);
1402
+
1403
+ // Process DOM
1404
+ if (settings.paste_convert_word_fake_lists !== false) {
1405
+ convertFakeListsToProperLists(rootNode);
1406
+ }
1407
+
1408
+ // Serialize DOM back to HTML
1409
+ e.content = new Serializer({
1410
+ validate: settings.validate
1411
+ }, schema).serialize(rootNode);
1412
+ }
1413
+ });
1414
+ }
1415
+
1416
+ WordFilter.isWordContent = isWordContent;
1417
+
1418
+ return WordFilter;
1419
+ });
1420
+
1421
+ // Included from: js/tinymce/plugins/paste/classes/Quirks.js
1422
+
1423
+ /**
1424
+ * Quirks.js
1425
+ *
1426
+ * Released under LGPL License.
1427
+ * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
1428
+ *
1429
+ * License: http://www.tinymce.com/license
1430
+ * Contributing: http://www.tinymce.com/contributing
1431
+ */
1432
+
1433
+ /**
1434
+ * This class contains various fixes for browsers. These issues can not be feature
1435
+ * detected since we have no direct control over the clipboard. However we might be able
1436
+ * to remove some of these fixes once the browsers gets updated/fixed.
1437
+ *
1438
+ * @class tinymce.pasteplugin.Quirks
1439
+ * @private
1440
+ */
1441
+ define("tinymce/pasteplugin/Quirks", [
1442
+ "tinymce/Env",
1443
+ "tinymce/util/Tools",
1444
+ "tinymce/pasteplugin/WordFilter",
1445
+ "tinymce/pasteplugin/Utils"
1446
+ ], function(Env, Tools, WordFilter, Utils) {
1447
+ "use strict";
1448
+
1449
+ return function(editor) {
1450
+ function addPreProcessFilter(filterFunc) {
1451
+ editor.on('BeforePastePreProcess', function(e) {
1452
+ e.content = filterFunc(e.content);
1453
+ });
1454
+ }
1455
+
1456
+ /**
1457
+ * Removes BR elements after block elements. IE9 has a nasty bug where it puts a BR element after each
1458
+ * block element when pasting from word. This removes those elements.
1459
+ *
1460
+ * This:
1461
+ * <p>a</p><br><p>b</p>
1462
+ *
1463
+ * Becomes:
1464
+ * <p>a</p><p>b</p>
1465
+ */
1466
+ function removeExplorerBrElementsAfterBlocks(html) {
1467
+ // Only filter word specific content
1468
+ if (!WordFilter.isWordContent(html)) {
1469
+ return html;
1470
+ }
1471
+
1472
+ // Produce block regexp based on the block elements in schema
1473
+ var blockElements = [];
1474
+
1475
+ Tools.each(editor.schema.getBlockElements(), function(block, blockName) {
1476
+ blockElements.push(blockName);
1477
+ });
1478
+
1479
+ var explorerBlocksRegExp = new RegExp(
1480
+ '(?:<br>&nbsp;[\\s\\r\\n]+|<br>)*(<\\/?(' + blockElements.join('|') + ')[^>]*>)(?:<br>&nbsp;[\\s\\r\\n]+|<br>)*',
1481
+ 'g'
1482
+ );
1483
+
1484
+ // Remove BR:s from: <BLOCK>X</BLOCK><BR>
1485
+ html = Utils.filter(html, [
1486
+ [explorerBlocksRegExp, '$1']
1487
+ ]);
1488
+
1489
+ // IE9 also adds an extra BR element for each soft-linefeed and it also adds a BR for each word wrap break
1490
+ html = Utils.filter(html, [
1491
+ [/<br><br>/g, '<BR><BR>'], // Replace multiple BR elements with uppercase BR to keep them intact
1492
+ [/<br>/g, ' '], // Replace single br elements with space since they are word wrap BR:s
1493
+ [/<BR><BR>/g, '<br>'] // Replace back the double brs but into a single BR
1494
+ ]);
1495
+
1496
+ return html;
1497
+ }
1498
+
1499
+ /**
1500
+ * WebKit has a nasty bug where the all computed styles gets added to style attributes when copy/pasting contents.
1501
+ * This fix solves that by simply removing the whole style attribute.
1502
+ *
1503
+ * The paste_webkit_styles option can be set to specify what to keep:
1504
+ * paste_webkit_styles: "none" // Keep no styles
1505
+ * paste_webkit_styles: "all", // Keep all of them
1506
+ * paste_webkit_styles: "font-weight color" // Keep specific ones
1507
+ *
1508
+ * @param {String} content Content that needs to be processed.
1509
+ * @return {String} Processed contents.
1510
+ */
1511
+ function removeWebKitStyles(content) {
1512
+ // Passthrough all styles from Word and let the WordFilter handle that junk
1513
+ if (WordFilter.isWordContent(content)) {
1514
+ return content;
1515
+ }
1516
+
1517
+ // Filter away styles that isn't matching the target node
1518
+ var webKitStyles = editor.settings.paste_webkit_styles;
1519
+
1520
+ if (editor.settings.paste_remove_styles_if_webkit === false || webKitStyles == "all") {
1521
+ return content;
1522
+ }
1523
+
1524
+ if (webKitStyles) {
1525
+ webKitStyles = webKitStyles.split(/[, ]/);
1526
+ }
1527
+
1528
+ // Keep specific styles that doesn't match the current node computed style
1529
+ if (webKitStyles) {
1530
+ var dom = editor.dom, node = editor.selection.getNode();
1531
+
1532
+ content = content.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi, function(all, before, value, after) {
1533
+ var inputStyles = dom.parseStyle(value, 'span'), outputStyles = {};
1534
+
1535
+ if (webKitStyles === "none") {
1536
+ return before + after;
1537
+ }
1538
+
1539
+ for (var i = 0; i < webKitStyles.length; i++) {
1540
+ var inputValue = inputStyles[webKitStyles[i]], currentValue = dom.getStyle(node, webKitStyles[i], true);
1541
+
1542
+ if (/color/.test(webKitStyles[i])) {
1543
+ inputValue = dom.toHex(inputValue);
1544
+ currentValue = dom.toHex(currentValue);
1545
+ }
1546
+
1547
+ if (currentValue != inputValue) {
1548
+ outputStyles[webKitStyles[i]] = inputValue;
1549
+ }
1550
+ }
1551
+
1552
+ outputStyles = dom.serializeStyle(outputStyles, 'span');
1553
+ if (outputStyles) {
1554
+ return before + ' style="' + outputStyles + '"' + after;
1555
+ }
1556
+
1557
+ return before + after;
1558
+ });
1559
+ } else {
1560
+ // Remove all external styles
1561
+ content = content.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi, '$1$3');
1562
+ }
1563
+
1564
+ // Keep internal styles
1565
+ content = content.replace(/(<[^>]+) data-mce-style="([^"]+)"([^>]*>)/gi, function(all, before, value, after) {
1566
+ return before + ' style="' + value + '"' + after;
1567
+ });
1568
+
1569
+ return content;
1570
+ }
1571
+
1572
+ // Sniff browsers and apply fixes since we can't feature detect
1573
+ if (Env.webkit) {
1574
+ addPreProcessFilter(removeWebKitStyles);
1575
+ }
1576
+
1577
+ if (Env.ie) {
1578
+ addPreProcessFilter(removeExplorerBrElementsAfterBlocks);
1579
+ }
1580
+ };
1581
+ });
1582
+
1583
+ // Included from: js/tinymce/plugins/paste/classes/Plugin.js
1584
+
1585
+ /**
1586
+ * Plugin.js
1587
+ *
1588
+ * Released under LGPL License.
1589
+ * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
1590
+ *
1591
+ * License: http://www.tinymce.com/license
1592
+ * Contributing: http://www.tinymce.com/contributing
1593
+ */
1594
+
1595
+ /**
1596
+ * This class contains the tinymce plugin logic for the paste plugin.
1597
+ *
1598
+ * @class tinymce.pasteplugin.Plugin
1599
+ * @private
1600
+ */
1601
+ define("tinymce/pasteplugin/Plugin", [
1602
+ "tinymce/PluginManager",
1603
+ "tinymce/pasteplugin/Clipboard",
1604
+ "tinymce/pasteplugin/WordFilter",
1605
+ "tinymce/pasteplugin/Quirks"
1606
+ ], function(PluginManager, Clipboard, WordFilter, Quirks) {
1607
+ var userIsInformed;
1608
+
1609
+ PluginManager.add('paste', function(editor) {
1610
+ var self = this, clipboard, settings = editor.settings;
1611
+
1612
+ function isUserInformedAboutPlainText() {
1613
+ return userIsInformed || editor.settings.paste_plaintext_inform === false;
1614
+ }
1615
+
1616
+ function togglePlainTextPaste() {
1617
+ if (clipboard.pasteFormat == "text") {
1618
+ this.active(false);
1619
+ clipboard.pasteFormat = "html";
1620
+ editor.fire('PastePlainTextToggle', {state: false});
1621
+ } else {
1622
+ clipboard.pasteFormat = "text";
1623
+ this.active(true);
1624
+
1625
+ if (!isUserInformedAboutPlainText()) {
1626
+ var message = editor.translate('Paste is now in plain text mode. Contents will now ' +
1627
+ 'be pasted as plain text until you toggle this option off.');
1628
+
1629
+ editor.notificationManager.open({
1630
+ text: message,
1631
+ type: 'info'
1632
+ });
1633
+
1634
+ userIsInformed = true;
1635
+ editor.fire('PastePlainTextToggle', {state: true});
1636
+ }
1637
+ }
1638
+
1639
+ editor.focus();
1640
+ }
1641
+
1642
+ self.clipboard = clipboard = new Clipboard(editor);
1643
+ self.quirks = new Quirks(editor);
1644
+ self.wordFilter = new WordFilter(editor);
1645
+
1646
+ if (editor.settings.paste_as_text) {
1647
+ self.clipboard.pasteFormat = "text";
1648
+ }
1649
+
1650
+ if (settings.paste_preprocess) {
1651
+ editor.on('PastePreProcess', function(e) {
1652
+ settings.paste_preprocess.call(self, self, e);
1653
+ });
1654
+ }
1655
+
1656
+ if (settings.paste_postprocess) {
1657
+ editor.on('PastePostProcess', function(e) {
1658
+ settings.paste_postprocess.call(self, self, e);
1659
+ });
1660
+ }
1661
+
1662
+ editor.addCommand('mceInsertClipboardContent', function(ui, value) {
1663
+ if (value.content) {
1664
+ self.clipboard.pasteHtml(value.content);
1665
+ }
1666
+
1667
+ if (value.text) {
1668
+ self.clipboard.pasteText(value.text);
1669
+ }
1670
+ });
1671
+
1672
+ // Block all drag/drop events
1673
+ if (editor.paste_block_drop) {
1674
+ editor.on('dragend dragover draggesture dragdrop drop drag', function(e) {
1675
+ e.preventDefault();
1676
+ e.stopPropagation();
1677
+ });
1678
+ }
1679
+
1680
+ // Prevent users from dropping data images on Gecko
1681
+ if (!editor.settings.paste_data_images) {
1682
+ editor.on('drop', function(e) {
1683
+ var dataTransfer = e.dataTransfer;
1684
+
1685
+ if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
1686
+ e.preventDefault();
1687
+ }
1688
+ });
1689
+ }
1690
+
1691
+ editor.addButton('pastetext', {
1692
+ icon: 'pastetext',
1693
+ tooltip: 'Paste as text',
1694
+ onclick: togglePlainTextPaste,
1695
+ active: self.clipboard.pasteFormat == "text"
1696
+ });
1697
+
1698
+ editor.addMenuItem('pastetext', {
1699
+ text: 'Paste as text',
1700
+ selectable: true,
1701
+ active: clipboard.pasteFormat,
1702
+ onclick: togglePlainTextPaste
1703
+ });
1704
+ });
1705
+ });
1706
+
1707
+ expose(["tinymce/pasteplugin/Utils"]);
1708
+ })(this);