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,1853 @@
1
+ /**
2
+ * DOMUtils.js
3
+ *
4
+ * Released under LGPL License.
5
+ * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
6
+ *
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
+ */
10
+
11
+ /**
12
+ * Utility class for various DOM manipulation and retrieval functions.
13
+ *
14
+ * @class tinymce.dom.DOMUtils
15
+ * @example
16
+ * // Add a class to an element by id in the page
17
+ * tinymce.DOM.addClass('someid', 'someclass');
18
+ *
19
+ * // Add a class to an element by id inside the editor
20
+ * tinymce.activeEditor.dom.addClass('someid', 'someclass');
21
+ */
22
+ define("tinymce/dom/DOMUtils", [
23
+ "tinymce/dom/Sizzle",
24
+ "tinymce/dom/DomQuery",
25
+ "tinymce/html/Styles",
26
+ "tinymce/dom/EventUtils",
27
+ "tinymce/dom/TreeWalker",
28
+ "tinymce/dom/Range",
29
+ "tinymce/html/Entities",
30
+ "tinymce/Env",
31
+ "tinymce/util/Tools",
32
+ "tinymce/dom/StyleSheetLoader"
33
+ ], function(Sizzle, $, Styles, EventUtils, TreeWalker, Range, Entities, Env, Tools, StyleSheetLoader) {
34
+ // Shorten names
35
+ var each = Tools.each, is = Tools.is, grep = Tools.grep, trim = Tools.trim;
36
+ var isIE = Env.ie;
37
+ var simpleSelectorRe = /^([a-z0-9],?)+$/i;
38
+ var whiteSpaceRegExp = /^[ \t\r\n]*$/;
39
+
40
+ function setupAttrHooks(domUtils, settings) {
41
+ var attrHooks = {}, keepValues = settings.keep_values, keepUrlHook;
42
+
43
+ keepUrlHook = {
44
+ set: function($elm, value, name) {
45
+ if (settings.url_converter) {
46
+ value = settings.url_converter.call(settings.url_converter_scope || domUtils, value, name, $elm[0]);
47
+ }
48
+
49
+ $elm.attr('data-mce-' + name, value).attr(name, value);
50
+ },
51
+
52
+ get: function($elm, name) {
53
+ return $elm.attr('data-mce-' + name) || $elm.attr(name);
54
+ }
55
+ };
56
+
57
+ attrHooks = {
58
+ style: {
59
+ set: function($elm, value) {
60
+ if (value !== null && typeof value === 'object') {
61
+ $elm.css(value);
62
+ return;
63
+ }
64
+
65
+ if (keepValues) {
66
+ $elm.attr('data-mce-style', value);
67
+ }
68
+
69
+ $elm.attr('style', value);
70
+ },
71
+
72
+ get: function($elm) {
73
+ var value = $elm.attr('data-mce-style') || $elm.attr('style');
74
+
75
+ value = domUtils.serializeStyle(domUtils.parseStyle(value), $elm[0].nodeName);
76
+
77
+ return value;
78
+ }
79
+ }
80
+ };
81
+
82
+ if (keepValues) {
83
+ attrHooks.href = attrHooks.src = keepUrlHook;
84
+ }
85
+
86
+ return attrHooks;
87
+ }
88
+
89
+ function updateInternalStyleAttr(domUtils, $elm) {
90
+ var value = $elm.attr('style');
91
+
92
+ value = domUtils.serializeStyle(domUtils.parseStyle(value), $elm[0].nodeName);
93
+
94
+ if (!value) {
95
+ value = null;
96
+ }
97
+
98
+ $elm.attr('data-mce-style', value);
99
+ }
100
+
101
+ function nodeIndex(node, normalized) {
102
+ var idx = 0, lastNodeType, nodeType;
103
+
104
+ if (node) {
105
+ for (lastNodeType = node.nodeType, node = node.previousSibling; node; node = node.previousSibling) {
106
+ nodeType = node.nodeType;
107
+
108
+ // Normalize text nodes
109
+ if (normalized && nodeType == 3) {
110
+ if (nodeType == lastNodeType || !node.nodeValue.length) {
111
+ continue;
112
+ }
113
+ }
114
+ idx++;
115
+ lastNodeType = nodeType;
116
+ }
117
+ }
118
+
119
+ return idx;
120
+ }
121
+
122
+ /**
123
+ * Constructs a new DOMUtils instance. Consult the Wiki for more details on settings etc for this class.
124
+ *
125
+ * @constructor
126
+ * @method DOMUtils
127
+ * @param {Document} doc Document reference to bind the utility class to.
128
+ * @param {settings} settings Optional settings collection.
129
+ */
130
+ function DOMUtils(doc, settings) {
131
+ var self = this, blockElementsMap;
132
+
133
+ self.doc = doc;
134
+ self.win = window;
135
+ self.files = {};
136
+ self.counter = 0;
137
+ self.stdMode = !isIE || doc.documentMode >= 8;
138
+ self.boxModel = !isIE || doc.compatMode == "CSS1Compat" || self.stdMode;
139
+ self.styleSheetLoader = new StyleSheetLoader(doc);
140
+ self.boundEvents = [];
141
+ self.settings = settings = settings || {};
142
+ self.schema = settings.schema;
143
+ self.styles = new Styles({
144
+ url_converter: settings.url_converter,
145
+ url_converter_scope: settings.url_converter_scope
146
+ }, settings.schema);
147
+
148
+ self.fixDoc(doc);
149
+ self.events = settings.ownEvents ? new EventUtils(settings.proxy) : EventUtils.Event;
150
+ self.attrHooks = setupAttrHooks(self, settings);
151
+ blockElementsMap = settings.schema ? settings.schema.getBlockElements() : {};
152
+ self.$ = $.overrideDefaults(function() {
153
+ return {
154
+ context: doc,
155
+ element: self.getRoot()
156
+ };
157
+ });
158
+
159
+ /**
160
+ * Returns true/false if the specified element is a block element or not.
161
+ *
162
+ * @method isBlock
163
+ * @param {Node/String} node Element/Node to check.
164
+ * @return {Boolean} True/False state if the node is a block element or not.
165
+ */
166
+ self.isBlock = function(node) {
167
+ // Fix for #5446
168
+ if (!node) {
169
+ return false;
170
+ }
171
+
172
+ // This function is called in module pattern style since it might be executed with the wrong this scope
173
+ var type = node.nodeType;
174
+
175
+ // If it's a node then check the type and use the nodeName
176
+ if (type) {
177
+ return !!(type === 1 && blockElementsMap[node.nodeName]);
178
+ }
179
+
180
+ return !!blockElementsMap[node];
181
+ };
182
+ }
183
+
184
+ DOMUtils.prototype = {
185
+ $$: function(elm) {
186
+ if (typeof elm == 'string') {
187
+ elm = this.get(elm);
188
+ }
189
+
190
+ return this.$(elm);
191
+ },
192
+
193
+ root: null,
194
+
195
+ fixDoc: function(doc) {
196
+ var settings = this.settings, name;
197
+
198
+ if (isIE && settings.schema) {
199
+ // Add missing HTML 4/5 elements to IE
200
+ ('abbr article aside audio canvas ' +
201
+ 'details figcaption figure footer ' +
202
+ 'header hgroup mark menu meter nav ' +
203
+ 'output progress section summary ' +
204
+ 'time video').replace(/\w+/g, function(name) {
205
+ doc.createElement(name);
206
+ });
207
+
208
+ // Create all custom elements
209
+ for (name in settings.schema.getCustomElements()) {
210
+ doc.createElement(name);
211
+ }
212
+ }
213
+ },
214
+
215
+ clone: function(node, deep) {
216
+ var self = this, clone, doc;
217
+
218
+ // TODO: Add feature detection here in the future
219
+ if (!isIE || node.nodeType !== 1 || deep) {
220
+ return node.cloneNode(deep);
221
+ }
222
+
223
+ doc = self.doc;
224
+
225
+ // Make a HTML5 safe shallow copy
226
+ if (!deep) {
227
+ clone = doc.createElement(node.nodeName);
228
+
229
+ // Copy attribs
230
+ each(self.getAttribs(node), function(attr) {
231
+ self.setAttrib(clone, attr.nodeName, self.getAttrib(node, attr.nodeName));
232
+ });
233
+
234
+ return clone;
235
+ }
236
+
237
+ return clone.firstChild;
238
+ },
239
+
240
+ /**
241
+ * Returns the root node of the document. This is normally the body but might be a DIV. Parents like getParent will not
242
+ * go above the point of this root node.
243
+ *
244
+ * @method getRoot
245
+ * @return {Element} Root element for the utility class.
246
+ */
247
+ getRoot: function() {
248
+ var self = this;
249
+
250
+ return self.settings.root_element || self.doc.body;
251
+ },
252
+
253
+ /**
254
+ * Returns the viewport of the window.
255
+ *
256
+ * @method getViewPort
257
+ * @param {Window} win Optional window to get viewport of.
258
+ * @return {Object} Viewport object with fields x, y, w and h.
259
+ */
260
+ getViewPort: function(win) {
261
+ var doc, rootElm;
262
+
263
+ win = !win ? this.win : win;
264
+ doc = win.document;
265
+ rootElm = this.boxModel ? doc.documentElement : doc.body;
266
+
267
+ // Returns viewport size excluding scrollbars
268
+ return {
269
+ x: win.pageXOffset || rootElm.scrollLeft,
270
+ y: win.pageYOffset || rootElm.scrollTop,
271
+ w: win.innerWidth || rootElm.clientWidth,
272
+ h: win.innerHeight || rootElm.clientHeight
273
+ };
274
+ },
275
+
276
+ /**
277
+ * Returns the rectangle for a specific element.
278
+ *
279
+ * @method getRect
280
+ * @param {Element/String} elm Element object or element ID to get rectangle from.
281
+ * @return {object} Rectangle for specified element object with x, y, w, h fields.
282
+ */
283
+ getRect: function(elm) {
284
+ var self = this, pos, size;
285
+
286
+ elm = self.get(elm);
287
+ pos = self.getPos(elm);
288
+ size = self.getSize(elm);
289
+
290
+ return {
291
+ x: pos.x, y: pos.y,
292
+ w: size.w, h: size.h
293
+ };
294
+ },
295
+
296
+ /**
297
+ * Returns the size dimensions of the specified element.
298
+ *
299
+ * @method getSize
300
+ * @param {Element/String} elm Element object or element ID to get rectangle from.
301
+ * @return {object} Rectangle for specified element object with w, h fields.
302
+ */
303
+ getSize: function(elm) {
304
+ var self = this, w, h;
305
+
306
+ elm = self.get(elm);
307
+ w = self.getStyle(elm, 'width');
308
+ h = self.getStyle(elm, 'height');
309
+
310
+ // Non pixel value, then force offset/clientWidth
311
+ if (w.indexOf('px') === -1) {
312
+ w = 0;
313
+ }
314
+
315
+ // Non pixel value, then force offset/clientWidth
316
+ if (h.indexOf('px') === -1) {
317
+ h = 0;
318
+ }
319
+
320
+ return {
321
+ w: parseInt(w, 10) || elm.offsetWidth || elm.clientWidth,
322
+ h: parseInt(h, 10) || elm.offsetHeight || elm.clientHeight
323
+ };
324
+ },
325
+
326
+ /**
327
+ * Returns a node by the specified selector function. This function will
328
+ * loop through all parent nodes and call the specified function for each node.
329
+ * If the function then returns true indicating that it has found what it was looking for, the loop execution will then end
330
+ * and the node it found will be returned.
331
+ *
332
+ * @method getParent
333
+ * @param {Node/String} node DOM node to search parents on or ID string.
334
+ * @param {function} selector Selection function or CSS selector to execute on each node.
335
+ * @param {Node} root Optional root element, never go below this point.
336
+ * @return {Node} DOM Node or null if it wasn't found.
337
+ */
338
+ getParent: function(node, selector, root) {
339
+ return this.getParents(node, selector, root, false);
340
+ },
341
+
342
+ /**
343
+ * Returns a node list of all parents matching the specified selector function or pattern.
344
+ * If the function then returns true indicating that it has found what it was looking for and that node will be collected.
345
+ *
346
+ * @method getParents
347
+ * @param {Node/String} node DOM node to search parents on or ID string.
348
+ * @param {function} selector Selection function to execute on each node or CSS pattern.
349
+ * @param {Node} root Optional root element, never go below this point.
350
+ * @return {Array} Array of nodes or null if it wasn't found.
351
+ */
352
+ getParents: function(node, selector, root, collect) {
353
+ var self = this, selectorVal, result = [];
354
+
355
+ node = self.get(node);
356
+ collect = collect === undefined;
357
+
358
+ // Default root on inline mode
359
+ root = root || (self.getRoot().nodeName != 'BODY' ? self.getRoot().parentNode : null);
360
+
361
+ // Wrap node name as func
362
+ if (is(selector, 'string')) {
363
+ selectorVal = selector;
364
+
365
+ if (selector === '*') {
366
+ selector = function(node) {
367
+ return node.nodeType == 1;
368
+ };
369
+ } else {
370
+ selector = function(node) {
371
+ return self.is(node, selectorVal);
372
+ };
373
+ }
374
+ }
375
+
376
+ while (node) {
377
+ if (node == root || !node.nodeType || node.nodeType === 9) {
378
+ break;
379
+ }
380
+
381
+ if (!selector || selector(node)) {
382
+ if (collect) {
383
+ result.push(node);
384
+ } else {
385
+ return node;
386
+ }
387
+ }
388
+
389
+ node = node.parentNode;
390
+ }
391
+
392
+ return collect ? result : null;
393
+ },
394
+
395
+ /**
396
+ * Returns the specified element by ID or the input element if it isn't a string.
397
+ *
398
+ * @method get
399
+ * @param {String/Element} n Element id to look for or element to just pass though.
400
+ * @return {Element} Element matching the specified id or null if it wasn't found.
401
+ */
402
+ get: function(elm) {
403
+ var name;
404
+
405
+ if (elm && this.doc && typeof elm == 'string') {
406
+ name = elm;
407
+ elm = this.doc.getElementById(elm);
408
+
409
+ // IE and Opera returns meta elements when they match the specified input ID, but getElementsByName seems to do the trick
410
+ if (elm && elm.id !== name) {
411
+ return this.doc.getElementsByName(name)[1];
412
+ }
413
+ }
414
+
415
+ return elm;
416
+ },
417
+
418
+ /**
419
+ * Returns the next node that matches selector or function
420
+ *
421
+ * @method getNext
422
+ * @param {Node} node Node to find siblings from.
423
+ * @param {String/function} selector Selector CSS expression or function.
424
+ * @return {Node} Next node item matching the selector or null if it wasn't found.
425
+ */
426
+ getNext: function(node, selector) {
427
+ return this._findSib(node, selector, 'nextSibling');
428
+ },
429
+
430
+ /**
431
+ * Returns the previous node that matches selector or function
432
+ *
433
+ * @method getPrev
434
+ * @param {Node} node Node to find siblings from.
435
+ * @param {String/function} selector Selector CSS expression or function.
436
+ * @return {Node} Previous node item matching the selector or null if it wasn't found.
437
+ */
438
+ getPrev: function(node, selector) {
439
+ return this._findSib(node, selector, 'previousSibling');
440
+ },
441
+
442
+ // #ifndef jquery
443
+
444
+ /**
445
+ * Selects specific elements by a CSS level 3 pattern. For example "div#a1 p.test".
446
+ * This function is optimized for the most common patterns needed in TinyMCE but it also performs well enough
447
+ * on more complex patterns.
448
+ *
449
+ * @method select
450
+ * @param {String} selector CSS level 3 pattern to select/find elements by.
451
+ * @param {Object} scope Optional root element/scope element to search in.
452
+ * @return {Array} Array with all matched elements.
453
+ * @example
454
+ * // Adds a class to all paragraphs in the currently active editor
455
+ * tinymce.activeEditor.dom.addClass(tinymce.activeEditor.dom.select('p'), 'someclass');
456
+ *
457
+ * // Adds a class to all spans that have the test class in the currently active editor
458
+ * tinymce.activeEditor.dom.addClass(tinymce.activeEditor.dom.select('span.test'), 'someclass')
459
+ */
460
+ select: function(selector, scope) {
461
+ var self = this;
462
+
463
+ /*eslint new-cap:0 */
464
+ return Sizzle(selector, self.get(scope) || self.settings.root_element || self.doc, []);
465
+ },
466
+
467
+ /**
468
+ * Returns true/false if the specified element matches the specified css pattern.
469
+ *
470
+ * @method is
471
+ * @param {Node/NodeList} elm DOM node to match or an array of nodes to match.
472
+ * @param {String} selector CSS pattern to match the element against.
473
+ */
474
+ is: function(elm, selector) {
475
+ var i;
476
+
477
+ // If it isn't an array then try to do some simple selectors instead of Sizzle for to boost performance
478
+ if (elm.length === undefined) {
479
+ // Simple all selector
480
+ if (selector === '*') {
481
+ return elm.nodeType == 1;
482
+ }
483
+
484
+ // Simple selector just elements
485
+ if (simpleSelectorRe.test(selector)) {
486
+ selector = selector.toLowerCase().split(/,/);
487
+ elm = elm.nodeName.toLowerCase();
488
+
489
+ for (i = selector.length - 1; i >= 0; i--) {
490
+ if (selector[i] == elm) {
491
+ return true;
492
+ }
493
+ }
494
+
495
+ return false;
496
+ }
497
+ }
498
+
499
+ // Is non element
500
+ if (elm.nodeType && elm.nodeType != 1) {
501
+ return false;
502
+ }
503
+
504
+ var elms = elm.nodeType ? [elm] : elm;
505
+
506
+ /*eslint new-cap:0 */
507
+ return Sizzle(selector, elms[0].ownerDocument || elms[0], null, elms).length > 0;
508
+ },
509
+
510
+ // #endif
511
+
512
+ /**
513
+ * Adds the specified element to another element or elements.
514
+ *
515
+ * @method add
516
+ * @param {String/Element/Array} parentElm Element id string, DOM node element or array of ids or elements to add to.
517
+ * @param {String/Element} name Name of new element to add or existing element to add.
518
+ * @param {Object} attrs Optional object collection with arguments to add to the new element(s).
519
+ * @param {String} html Optional inner HTML contents to add for each element.
520
+ * @param {Boolean} create Optional flag if the element should be created or added.
521
+ * @return {Element/Array} Element that got created, or an array of created elements if multiple input elements
522
+ * were passed in.
523
+ * @example
524
+ * // Adds a new paragraph to the end of the active editor
525
+ * tinymce.activeEditor.dom.add(tinymce.activeEditor.getBody(), 'p', {title: 'my title'}, 'Some content');
526
+ */
527
+ add: function(parentElm, name, attrs, html, create) {
528
+ var self = this;
529
+
530
+ return this.run(parentElm, function(parentElm) {
531
+ var newElm;
532
+
533
+ newElm = is(name, 'string') ? self.doc.createElement(name) : name;
534
+ self.setAttribs(newElm, attrs);
535
+
536
+ if (html) {
537
+ if (html.nodeType) {
538
+ newElm.appendChild(html);
539
+ } else {
540
+ self.setHTML(newElm, html);
541
+ }
542
+ }
543
+
544
+ return !create ? parentElm.appendChild(newElm) : newElm;
545
+ });
546
+ },
547
+
548
+ /**
549
+ * Creates a new element.
550
+ *
551
+ * @method create
552
+ * @param {String} name Name of new element.
553
+ * @param {Object} attrs Optional object name/value collection with element attributes.
554
+ * @param {String} html Optional HTML string to set as inner HTML of the element.
555
+ * @return {Element} HTML DOM node element that got created.
556
+ * @example
557
+ * // Adds an element where the caret/selection is in the active editor
558
+ * var el = tinymce.activeEditor.dom.create('div', {id: 'test', 'class': 'myclass'}, 'some content');
559
+ * tinymce.activeEditor.selection.setNode(el);
560
+ */
561
+ create: function(name, attrs, html) {
562
+ return this.add(this.doc.createElement(name), name, attrs, html, 1);
563
+ },
564
+
565
+ /**
566
+ * Creates HTML string for element. The element will be closed unless an empty inner HTML string is passed in.
567
+ *
568
+ * @method createHTML
569
+ * @param {String} name Name of new element.
570
+ * @param {Object} attrs Optional object name/value collection with element attributes.
571
+ * @param {String} html Optional HTML string to set as inner HTML of the element.
572
+ * @return {String} String with new HTML element, for example: <a href="#">test</a>.
573
+ * @example
574
+ * // Creates a html chunk and inserts it at the current selection/caret location
575
+ * tinymce.activeEditor.selection.setContent(tinymce.activeEditor.dom.createHTML('a', {href: 'test.html'}, 'some line'));
576
+ */
577
+ createHTML: function(name, attrs, html) {
578
+ var outHtml = '', key;
579
+
580
+ outHtml += '<' + name;
581
+
582
+ for (key in attrs) {
583
+ if (attrs.hasOwnProperty(key) && attrs[key] !== null && typeof attrs[key] != 'undefined') {
584
+ outHtml += ' ' + key + '="' + this.encode(attrs[key]) + '"';
585
+ }
586
+ }
587
+
588
+ // A call to tinymce.is doesn't work for some odd reason on IE9 possible bug inside their JS runtime
589
+ if (typeof html != "undefined") {
590
+ return outHtml + '>' + html + '</' + name + '>';
591
+ }
592
+
593
+ return outHtml + ' />';
594
+ },
595
+
596
+ /**
597
+ * Creates a document fragment out of the specified HTML string.
598
+ *
599
+ * @method createFragment
600
+ * @param {String} html Html string to create fragment from.
601
+ * @return {DocumentFragment} Document fragment node.
602
+ */
603
+ createFragment: function(html) {
604
+ var frag, node, doc = this.doc, container;
605
+
606
+ container = doc.createElement("div");
607
+ frag = doc.createDocumentFragment();
608
+
609
+ if (html) {
610
+ container.innerHTML = html;
611
+ }
612
+
613
+ while ((node = container.firstChild)) {
614
+ frag.appendChild(node);
615
+ }
616
+
617
+ return frag;
618
+ },
619
+
620
+ /**
621
+ * Removes/deletes the specified element(s) from the DOM.
622
+ *
623
+ * @method remove
624
+ * @param {String/Element/Array} node ID of element or DOM element object or array containing multiple elements/ids.
625
+ * @param {Boolean} keepChildren Optional state to keep children or not. If set to true all children will be
626
+ * placed at the location of the removed element.
627
+ * @return {Element/Array} HTML DOM element that got removed, or an array of removed elements if multiple input elements
628
+ * were passed in.
629
+ * @example
630
+ * // Removes all paragraphs in the active editor
631
+ * tinymce.activeEditor.dom.remove(tinymce.activeEditor.dom.select('p'));
632
+ *
633
+ * // Removes an element by id in the document
634
+ * tinymce.DOM.remove('mydiv');
635
+ */
636
+ remove: function(node, keepChildren) {
637
+ node = this.$$(node);
638
+
639
+ if (keepChildren) {
640
+ node.each(function() {
641
+ var child;
642
+
643
+ while ((child = this.firstChild)) {
644
+ if (child.nodeType == 3 && child.data.length === 0) {
645
+ this.removeChild(child);
646
+ } else {
647
+ this.parentNode.insertBefore(child, this);
648
+ }
649
+ }
650
+ }).remove();
651
+ } else {
652
+ node.remove();
653
+ }
654
+
655
+ return node.length > 1 ? node.toArray() : node[0];
656
+ },
657
+
658
+ /**
659
+ * Sets the CSS style value on a HTML element. The name can be a camelcase string
660
+ * or the CSS style name like background-color.
661
+ *
662
+ * @method setStyle
663
+ * @param {String/Element/Array} elm HTML element/Array of elements to set CSS style value on.
664
+ * @param {String} name Name of the style value to set.
665
+ * @param {String} value Value to set on the style.
666
+ * @example
667
+ * // Sets a style value on all paragraphs in the currently active editor
668
+ * tinymce.activeEditor.dom.setStyle(tinymce.activeEditor.dom.select('p'), 'background-color', 'red');
669
+ *
670
+ * // Sets a style value to an element by id in the current document
671
+ * tinymce.DOM.setStyle('mydiv', 'background-color', 'red');
672
+ */
673
+ setStyle: function(elm, name, value) {
674
+ elm = this.$$(elm).css(name, value);
675
+
676
+ if (this.settings.update_styles) {
677
+ updateInternalStyleAttr(this, elm);
678
+ }
679
+ },
680
+
681
+ /**
682
+ * Returns the current style or runtime/computed value of an element.
683
+ *
684
+ * @method getStyle
685
+ * @param {String/Element} elm HTML element or element id string to get style from.
686
+ * @param {String} name Style name to return.
687
+ * @param {Boolean} computed Computed style.
688
+ * @return {String} Current style or computed style value of an element.
689
+ */
690
+ getStyle: function(elm, name, computed) {
691
+ elm = this.$$(elm);
692
+
693
+ if (computed) {
694
+ return elm.css(name);
695
+ }
696
+
697
+ // Camelcase it, if needed
698
+ name = name.replace(/-(\D)/g, function(a, b) {
699
+ return b.toUpperCase();
700
+ });
701
+
702
+ if (name == 'float') {
703
+ name = Env.ie && Env.ie < 12 ? 'styleFloat' : 'cssFloat';
704
+ }
705
+
706
+ return elm[0] && elm[0].style ? elm[0].style[name] : undefined;
707
+ },
708
+
709
+ /**
710
+ * Sets multiple styles on the specified element(s).
711
+ *
712
+ * @method setStyles
713
+ * @param {Element/String/Array} elm DOM element, element id string or array of elements/ids to set styles on.
714
+ * @param {Object} styles Name/Value collection of style items to add to the element(s).
715
+ * @example
716
+ * // Sets styles on all paragraphs in the currently active editor
717
+ * tinymce.activeEditor.dom.setStyles(tinymce.activeEditor.dom.select('p'), {'background-color': 'red', 'color': 'green'});
718
+ *
719
+ * // Sets styles to an element by id in the current document
720
+ * tinymce.DOM.setStyles('mydiv', {'background-color': 'red', 'color': 'green'});
721
+ */
722
+ setStyles: function(elm, styles) {
723
+ elm = this.$$(elm).css(styles);
724
+
725
+ if (this.settings.update_styles) {
726
+ updateInternalStyleAttr(this, elm);
727
+ }
728
+ },
729
+
730
+ /**
731
+ * Removes all attributes from an element or elements.
732
+ *
733
+ * @method removeAllAttribs
734
+ * @param {Element/String/Array} e DOM element, element id string or array of elements/ids to remove attributes from.
735
+ */
736
+ removeAllAttribs: function(e) {
737
+ return this.run(e, function(e) {
738
+ var i, attrs = e.attributes;
739
+ for (i = attrs.length - 1; i >= 0; i--) {
740
+ e.removeAttributeNode(attrs.item(i));
741
+ }
742
+ });
743
+ },
744
+
745
+ /**
746
+ * Sets the specified attribute of an element or elements.
747
+ *
748
+ * @method setAttrib
749
+ * @param {Element/String/Array} elm DOM element, element id string or array of elements/ids to set attribute on.
750
+ * @param {String} name Name of attribute to set.
751
+ * @param {String} value Value to set on the attribute - if this value is falsy like null, 0 or '' it will remove
752
+ * the attribute instead.
753
+ * @example
754
+ * // Sets class attribute on all paragraphs in the active editor
755
+ * tinymce.activeEditor.dom.setAttrib(tinymce.activeEditor.dom.select('p'), 'class', 'myclass');
756
+ *
757
+ * // Sets class attribute on a specific element in the current page
758
+ * tinymce.dom.setAttrib('mydiv', 'class', 'myclass');
759
+ */
760
+ setAttrib: function(elm, name, value) {
761
+ var self = this, originalValue, hook, settings = self.settings;
762
+
763
+ if (value === '') {
764
+ value = null;
765
+ }
766
+
767
+ elm = self.$$(elm);
768
+ originalValue = elm.attr(name);
769
+
770
+ if (!elm.length) {
771
+ return;
772
+ }
773
+
774
+ hook = self.attrHooks[name];
775
+ if (hook && hook.set) {
776
+ hook.set(elm, value, name);
777
+ } else {
778
+ elm.attr(name, value);
779
+ }
780
+
781
+ if (originalValue != value && settings.onSetAttrib) {
782
+ settings.onSetAttrib({
783
+ attrElm: elm,
784
+ attrName: name,
785
+ attrValue: value
786
+ });
787
+ }
788
+ },
789
+
790
+ /**
791
+ * Sets two or more specified attributes of an element or elements.
792
+ *
793
+ * @method setAttribs
794
+ * @param {Element/String/Array} elm DOM element, element id string or array of elements/ids to set attributes on.
795
+ * @param {Object} attrs Name/Value collection of attribute items to add to the element(s).
796
+ * @example
797
+ * // Sets class and title attributes on all paragraphs in the active editor
798
+ * tinymce.activeEditor.dom.setAttribs(tinymce.activeEditor.dom.select('p'), {'class': 'myclass', title: 'some title'});
799
+ *
800
+ * // Sets class and title attributes on a specific element in the current page
801
+ * tinymce.DOM.setAttribs('mydiv', {'class': 'myclass', title: 'some title'});
802
+ */
803
+ setAttribs: function(elm, attrs) {
804
+ var self = this;
805
+
806
+ self.$$(elm).each(function(i, node) {
807
+ each(attrs, function(value, name) {
808
+ self.setAttrib(node, name, value);
809
+ });
810
+ });
811
+ },
812
+
813
+ /**
814
+ * Returns the specified attribute by name.
815
+ *
816
+ * @method getAttrib
817
+ * @param {String/Element} elm Element string id or DOM element to get attribute from.
818
+ * @param {String} name Name of attribute to get.
819
+ * @param {String} defaultVal Optional default value to return if the attribute didn't exist.
820
+ * @return {String} Attribute value string, default value or null if the attribute wasn't found.
821
+ */
822
+ getAttrib: function(elm, name, defaultVal) {
823
+ var self = this, hook, value;
824
+
825
+ elm = self.$$(elm);
826
+
827
+ if (elm.length) {
828
+ hook = self.attrHooks[name];
829
+
830
+ if (hook && hook.get) {
831
+ value = hook.get(elm, name);
832
+ } else {
833
+ value = elm.attr(name);
834
+ }
835
+ }
836
+
837
+ if (typeof value == 'undefined') {
838
+ value = defaultVal || '';
839
+ }
840
+
841
+ return value;
842
+ },
843
+
844
+ /**
845
+ * Returns the absolute x, y position of a node. The position will be returned in an object with x, y fields.
846
+ *
847
+ * @method getPos
848
+ * @param {Element/String} elm HTML element or element id to get x, y position from.
849
+ * @param {Element} rootElm Optional root element to stop calculations at.
850
+ * @return {object} Absolute position of the specified element object with x, y fields.
851
+ */
852
+ getPos: function(elm, rootElm) {
853
+ var self = this, x = 0, y = 0, offsetParent, doc = self.doc, body = doc.body, pos;
854
+
855
+ elm = self.get(elm);
856
+ rootElm = rootElm || body;
857
+
858
+ if (elm) {
859
+ // Use getBoundingClientRect if it exists since it's faster than looping offset nodes
860
+ // Fallback to offsetParent calculations if the body isn't static better since it stops at the body root
861
+ if (rootElm === body && elm.getBoundingClientRect && $(body).css('position') === 'static') {
862
+ pos = elm.getBoundingClientRect();
863
+ rootElm = self.boxModel ? doc.documentElement : body;
864
+
865
+ // Add scroll offsets from documentElement or body since IE with the wrong box model will use d.body and so do WebKit
866
+ // Also remove the body/documentelement clientTop/clientLeft on IE 6, 7 since they offset the position
867
+ x = pos.left + (doc.documentElement.scrollLeft || body.scrollLeft) - rootElm.clientLeft;
868
+ y = pos.top + (doc.documentElement.scrollTop || body.scrollTop) - rootElm.clientTop;
869
+
870
+ return {x: x, y: y};
871
+ }
872
+
873
+ offsetParent = elm;
874
+ while (offsetParent && offsetParent != rootElm && offsetParent.nodeType) {
875
+ x += offsetParent.offsetLeft || 0;
876
+ y += offsetParent.offsetTop || 0;
877
+ offsetParent = offsetParent.offsetParent;
878
+ }
879
+
880
+ offsetParent = elm.parentNode;
881
+ while (offsetParent && offsetParent != rootElm && offsetParent.nodeType) {
882
+ x -= offsetParent.scrollLeft || 0;
883
+ y -= offsetParent.scrollTop || 0;
884
+ offsetParent = offsetParent.parentNode;
885
+ }
886
+ }
887
+
888
+ return {x: x, y: y};
889
+ },
890
+
891
+ /**
892
+ * Parses the specified style value into an object collection. This parser will also
893
+ * merge and remove any redundant items that browsers might have added. It will also convert non-hex
894
+ * colors to hex values. Urls inside the styles will also be converted to absolute/relative based on settings.
895
+ *
896
+ * @method parseStyle
897
+ * @param {String} cssText Style value to parse, for example: border:1px solid red;.
898
+ * @return {Object} Object representation of that style, for example: {border: '1px solid red'}
899
+ */
900
+ parseStyle: function(cssText) {
901
+ return this.styles.parse(cssText);
902
+ },
903
+
904
+ /**
905
+ * Serializes the specified style object into a string.
906
+ *
907
+ * @method serializeStyle
908
+ * @param {Object} styles Object to serialize as string, for example: {border: '1px solid red'}
909
+ * @param {String} name Optional element name.
910
+ * @return {String} String representation of the style object, for example: border: 1px solid red.
911
+ */
912
+ serializeStyle: function(styles, name) {
913
+ return this.styles.serialize(styles, name);
914
+ },
915
+
916
+ /**
917
+ * Adds a style element at the top of the document with the specified cssText content.
918
+ *
919
+ * @method addStyle
920
+ * @param {String} cssText CSS Text style to add to top of head of document.
921
+ */
922
+ addStyle: function(cssText) {
923
+ var self = this, doc = self.doc, head, styleElm;
924
+
925
+ // Prevent inline from loading the same styles twice
926
+ if (self !== DOMUtils.DOM && doc === document) {
927
+ var addedStyles = DOMUtils.DOM.addedStyles;
928
+
929
+ addedStyles = addedStyles || [];
930
+ if (addedStyles[cssText]) {
931
+ return;
932
+ }
933
+
934
+ addedStyles[cssText] = true;
935
+ DOMUtils.DOM.addedStyles = addedStyles;
936
+ }
937
+
938
+ // Create style element if needed
939
+ styleElm = doc.getElementById('mceDefaultStyles');
940
+ if (!styleElm) {
941
+ styleElm = doc.createElement('style');
942
+ styleElm.id = 'mceDefaultStyles';
943
+ styleElm.type = 'text/css';
944
+
945
+ head = doc.getElementsByTagName('head')[0];
946
+ if (head.firstChild) {
947
+ head.insertBefore(styleElm, head.firstChild);
948
+ } else {
949
+ head.appendChild(styleElm);
950
+ }
951
+ }
952
+
953
+ // Append style data to old or new style element
954
+ if (styleElm.styleSheet) {
955
+ styleElm.styleSheet.cssText += cssText;
956
+ } else {
957
+ styleElm.appendChild(doc.createTextNode(cssText));
958
+ }
959
+ },
960
+
961
+ /**
962
+ * Imports/loads the specified CSS file into the document bound to the class.
963
+ *
964
+ * @method loadCSS
965
+ * @param {String} url URL to CSS file to load.
966
+ * @example
967
+ * // Loads a CSS file dynamically into the current document
968
+ * tinymce.DOM.loadCSS('somepath/some.css');
969
+ *
970
+ * // Loads a CSS file into the currently active editor instance
971
+ * tinymce.activeEditor.dom.loadCSS('somepath/some.css');
972
+ *
973
+ * // Loads a CSS file into an editor instance by id
974
+ * tinymce.get('someid').dom.loadCSS('somepath/some.css');
975
+ *
976
+ * // Loads multiple CSS files into the current document
977
+ * tinymce.DOM.loadCSS('somepath/some.css,somepath/someother.css');
978
+ */
979
+ loadCSS: function(url) {
980
+ var self = this, doc = self.doc, head;
981
+
982
+ // Prevent inline from loading the same CSS file twice
983
+ if (self !== DOMUtils.DOM && doc === document) {
984
+ DOMUtils.DOM.loadCSS(url);
985
+ return;
986
+ }
987
+
988
+ if (!url) {
989
+ url = '';
990
+ }
991
+
992
+ head = doc.getElementsByTagName('head')[0];
993
+
994
+ each(url.split(','), function(url) {
995
+ var link;
996
+
997
+ url = Tools._addCacheSuffix(url);
998
+
999
+ if (self.files[url]) {
1000
+ return;
1001
+ }
1002
+
1003
+ self.files[url] = true;
1004
+ link = self.create('link', {rel: 'stylesheet', href: url});
1005
+
1006
+ // IE 8 has a bug where dynamically loading stylesheets would produce a 1 item remaining bug
1007
+ // This fix seems to resolve that issue by recalcing the document once a stylesheet finishes loading
1008
+ // It's ugly but it seems to work fine.
1009
+ if (isIE && doc.documentMode && doc.recalc) {
1010
+ link.onload = function() {
1011
+ if (doc.recalc) {
1012
+ doc.recalc();
1013
+ }
1014
+
1015
+ link.onload = null;
1016
+ };
1017
+ }
1018
+
1019
+ head.appendChild(link);
1020
+ });
1021
+ },
1022
+
1023
+ /**
1024
+ * Adds a class to the specified element or elements.
1025
+ *
1026
+ * @method addClass
1027
+ * @param {String/Element/Array} elm Element ID string or DOM element or array with elements or IDs.
1028
+ * @param {String} cls Class name to add to each element.
1029
+ * @return {String/Array} String with new class value or array with new class values for all elements.
1030
+ * @example
1031
+ * // Adds a class to all paragraphs in the active editor
1032
+ * tinymce.activeEditor.dom.addClass(tinymce.activeEditor.dom.select('p'), 'myclass');
1033
+ *
1034
+ * // Adds a class to a specific element in the current page
1035
+ * tinymce.DOM.addClass('mydiv', 'myclass');
1036
+ */
1037
+ addClass: function(elm, cls) {
1038
+ this.$$(elm).addClass(cls);
1039
+ },
1040
+
1041
+ /**
1042
+ * Removes a class from the specified element or elements.
1043
+ *
1044
+ * @method removeClass
1045
+ * @param {String/Element/Array} elm Element ID string or DOM element or array with elements or IDs.
1046
+ * @param {String} cls Class name to remove from each element.
1047
+ * @return {String/Array} String of remaining class name(s), or an array of strings if multiple input elements
1048
+ * were passed in.
1049
+ * @example
1050
+ * // Removes a class from all paragraphs in the active editor
1051
+ * tinymce.activeEditor.dom.removeClass(tinymce.activeEditor.dom.select('p'), 'myclass');
1052
+ *
1053
+ * // Removes a class from a specific element in the current page
1054
+ * tinymce.DOM.removeClass('mydiv', 'myclass');
1055
+ */
1056
+ removeClass: function(elm, cls) {
1057
+ this.toggleClass(elm, cls, false);
1058
+ },
1059
+
1060
+ /**
1061
+ * Returns true if the specified element has the specified class.
1062
+ *
1063
+ * @method hasClass
1064
+ * @param {String/Element} elm HTML element or element id string to check CSS class on.
1065
+ * @param {String} cls CSS class to check for.
1066
+ * @return {Boolean} true/false if the specified element has the specified class.
1067
+ */
1068
+ hasClass: function(elm, cls) {
1069
+ return this.$$(elm).hasClass(cls);
1070
+ },
1071
+
1072
+ /**
1073
+ * Toggles the specified class on/off.
1074
+ *
1075
+ * @method toggleClass
1076
+ * @param {Element} elm Element to toggle class on.
1077
+ * @param {[type]} cls Class to toggle on/off.
1078
+ * @param {[type]} state Optional state to set.
1079
+ */
1080
+ toggleClass: function(elm, cls, state) {
1081
+ this.$$(elm).toggleClass(cls, state).each(function() {
1082
+ if (this.className === '') {
1083
+ $(this).attr('class', null);
1084
+ }
1085
+ });
1086
+ },
1087
+
1088
+ /**
1089
+ * Shows the specified element(s) by ID by setting the "display" style.
1090
+ *
1091
+ * @method show
1092
+ * @param {String/Element/Array} elm ID of DOM element or DOM element or array with elements or IDs to show.
1093
+ */
1094
+ show: function(elm) {
1095
+ this.$$(elm).show();
1096
+ },
1097
+
1098
+ /**
1099
+ * Hides the specified element(s) by ID by setting the "display" style.
1100
+ *
1101
+ * @method hide
1102
+ * @param {String/Element/Array} elm ID of DOM element or DOM element or array with elements or IDs to hide.
1103
+ * @example
1104
+ * // Hides an element by id in the document
1105
+ * tinymce.DOM.hide('myid');
1106
+ */
1107
+ hide: function(elm) {
1108
+ this.$$(elm).hide();
1109
+ },
1110
+
1111
+ /**
1112
+ * Returns true/false if the element is hidden or not by checking the "display" style.
1113
+ *
1114
+ * @method isHidden
1115
+ * @param {String/Element} elm Id or element to check display state on.
1116
+ * @return {Boolean} true/false if the element is hidden or not.
1117
+ */
1118
+ isHidden: function(elm) {
1119
+ return this.$$(elm).css('display') == 'none';
1120
+ },
1121
+
1122
+ /**
1123
+ * Returns a unique id. This can be useful when generating elements on the fly.
1124
+ * This method will not check if the element already exists.
1125
+ *
1126
+ * @method uniqueId
1127
+ * @param {String} prefix Optional prefix to add in front of all ids - defaults to "mce_".
1128
+ * @return {String} Unique id.
1129
+ */
1130
+ uniqueId: function(prefix) {
1131
+ return (!prefix ? 'mce_' : prefix) + (this.counter++);
1132
+ },
1133
+
1134
+ /**
1135
+ * Sets the specified HTML content inside the element or elements. The HTML will first be processed. This means
1136
+ * URLs will get converted, hex color values fixed etc. Check processHTML for details.
1137
+ *
1138
+ * @method setHTML
1139
+ * @param {Element/String/Array} elm DOM element, element id string or array of elements/ids to set HTML inside of.
1140
+ * @param {String} html HTML content to set as inner HTML of the element.
1141
+ * @example
1142
+ * // Sets the inner HTML of all paragraphs in the active editor
1143
+ * tinymce.activeEditor.dom.setHTML(tinymce.activeEditor.dom.select('p'), 'some inner html');
1144
+ *
1145
+ * // Sets the inner HTML of an element by id in the document
1146
+ * tinymce.DOM.setHTML('mydiv', 'some inner html');
1147
+ */
1148
+ setHTML: function(elm, html) {
1149
+ elm = this.$$(elm);
1150
+
1151
+ if (isIE) {
1152
+ elm.each(function(i, target) {
1153
+ if (target.canHaveHTML === false) {
1154
+ return;
1155
+ }
1156
+
1157
+ // Remove all child nodes, IE keeps empty text nodes in DOM
1158
+ while (target.firstChild) {
1159
+ target.removeChild(target.firstChild);
1160
+ }
1161
+
1162
+ try {
1163
+ // IE will remove comments from the beginning
1164
+ // unless you padd the contents with something
1165
+ target.innerHTML = '<br>' + html;
1166
+ target.removeChild(target.firstChild);
1167
+ } catch (ex) {
1168
+ // IE sometimes produces an unknown runtime error on innerHTML if it's a div inside a p
1169
+ $('<div>').html('<br>' + html).contents().slice(1).appendTo(target);
1170
+ }
1171
+
1172
+ return html;
1173
+ });
1174
+ } else {
1175
+ elm.html(html);
1176
+ }
1177
+ },
1178
+
1179
+ /**
1180
+ * Returns the outer HTML of an element.
1181
+ *
1182
+ * @method getOuterHTML
1183
+ * @param {String/Element} elm Element ID or element object to get outer HTML from.
1184
+ * @return {String} Outer HTML string.
1185
+ * @example
1186
+ * tinymce.DOM.getOuterHTML(editorElement);
1187
+ * tinymce.activeEditor.getOuterHTML(tinymce.activeEditor.getBody());
1188
+ */
1189
+ getOuterHTML: function(elm) {
1190
+ elm = this.get(elm);
1191
+
1192
+ // Older FF doesn't have outerHTML 3.6 is still used by some orgaizations
1193
+ return elm.nodeType == 1 && "outerHTML" in elm ? elm.outerHTML : $('<div>').append($(elm).clone()).html();
1194
+ },
1195
+
1196
+ /**
1197
+ * Sets the specified outer HTML on an element or elements.
1198
+ *
1199
+ * @method setOuterHTML
1200
+ * @param {Element/String/Array} elm DOM element, element id string or array of elements/ids to set outer HTML on.
1201
+ * @param {Object} html HTML code to set as outer value for the element.
1202
+ * @example
1203
+ * // Sets the outer HTML of all paragraphs in the active editor
1204
+ * tinymce.activeEditor.dom.setOuterHTML(tinymce.activeEditor.dom.select('p'), '<div>some html</div>');
1205
+ *
1206
+ * // Sets the outer HTML of an element by id in the document
1207
+ * tinymce.DOM.setOuterHTML('mydiv', '<div>some html</div>');
1208
+ */
1209
+ setOuterHTML: function(elm, html) {
1210
+ var self = this;
1211
+
1212
+ self.$$(elm).each(function() {
1213
+ try {
1214
+ // Older FF doesn't have outerHTML 3.6 is still used by some organizations
1215
+ if ("outerHTML" in this) {
1216
+ this.outerHTML = html;
1217
+ return;
1218
+ }
1219
+ } catch (ex) {
1220
+ // Ignore
1221
+ }
1222
+
1223
+ // OuterHTML for IE it sometimes produces an "unknown runtime error"
1224
+ self.remove($(this).html(html), true);
1225
+ });
1226
+ },
1227
+
1228
+ /**
1229
+ * Entity decodes a string. This method decodes any HTML entities, such as &aring;.
1230
+ *
1231
+ * @method decode
1232
+ * @param {String} s String to decode entities on.
1233
+ * @return {String} Entity decoded string.
1234
+ */
1235
+ decode: Entities.decode,
1236
+
1237
+ /**
1238
+ * Entity encodes a string. This method encodes the most common entities, such as <>"&.
1239
+ *
1240
+ * @method encode
1241
+ * @param {String} text String to encode with entities.
1242
+ * @return {String} Entity encoded string.
1243
+ */
1244
+ encode: Entities.encodeAllRaw,
1245
+
1246
+ /**
1247
+ * Inserts an element after the reference element.
1248
+ *
1249
+ * @method insertAfter
1250
+ * @param {Element} node Element to insert after the reference.
1251
+ * @param {Element/String/Array} referenceNode Reference element, element id or array of elements to insert after.
1252
+ * @return {Element/Array} Element that got added or an array with elements.
1253
+ */
1254
+ insertAfter: function(node, referenceNode) {
1255
+ referenceNode = this.get(referenceNode);
1256
+
1257
+ return this.run(node, function(node) {
1258
+ var parent, nextSibling;
1259
+
1260
+ parent = referenceNode.parentNode;
1261
+ nextSibling = referenceNode.nextSibling;
1262
+
1263
+ if (nextSibling) {
1264
+ parent.insertBefore(node, nextSibling);
1265
+ } else {
1266
+ parent.appendChild(node);
1267
+ }
1268
+
1269
+ return node;
1270
+ });
1271
+ },
1272
+
1273
+ /**
1274
+ * Replaces the specified element or elements with the new element specified. The new element will
1275
+ * be cloned if multiple input elements are passed in.
1276
+ *
1277
+ * @method replace
1278
+ * @param {Element} newElm New element to replace old ones with.
1279
+ * @param {Element/String/Array} oldElm Element DOM node, element id or array of elements or ids to replace.
1280
+ * @param {Boolean} keepChildren Optional keep children state, if set to true child nodes from the old object will be added
1281
+ * to new ones.
1282
+ */
1283
+ replace: function(newElm, oldElm, keepChildren) {
1284
+ var self = this;
1285
+
1286
+ return self.run(oldElm, function(oldElm) {
1287
+ if (is(oldElm, 'array')) {
1288
+ newElm = newElm.cloneNode(true);
1289
+ }
1290
+
1291
+ if (keepChildren) {
1292
+ each(grep(oldElm.childNodes), function(node) {
1293
+ newElm.appendChild(node);
1294
+ });
1295
+ }
1296
+
1297
+ return oldElm.parentNode.replaceChild(newElm, oldElm);
1298
+ });
1299
+ },
1300
+
1301
+ /**
1302
+ * Renames the specified element and keeps its attributes and children.
1303
+ *
1304
+ * @method rename
1305
+ * @param {Element} elm Element to rename.
1306
+ * @param {String} name Name of the new element.
1307
+ * @return {Element} New element or the old element if it needed renaming.
1308
+ */
1309
+ rename: function(elm, name) {
1310
+ var self = this, newElm;
1311
+
1312
+ if (elm.nodeName != name.toUpperCase()) {
1313
+ // Rename block element
1314
+ newElm = self.create(name);
1315
+
1316
+ // Copy attribs to new block
1317
+ each(self.getAttribs(elm), function(attrNode) {
1318
+ self.setAttrib(newElm, attrNode.nodeName, self.getAttrib(elm, attrNode.nodeName));
1319
+ });
1320
+
1321
+ // Replace block
1322
+ self.replace(newElm, elm, 1);
1323
+ }
1324
+
1325
+ return newElm || elm;
1326
+ },
1327
+
1328
+ /**
1329
+ * Find the common ancestor of two elements. This is a shorter method than using the DOM Range logic.
1330
+ *
1331
+ * @method findCommonAncestor
1332
+ * @param {Element} a Element to find common ancestor of.
1333
+ * @param {Element} b Element to find common ancestor of.
1334
+ * @return {Element} Common ancestor element of the two input elements.
1335
+ */
1336
+ findCommonAncestor: function(a, b) {
1337
+ var ps = a, pe;
1338
+
1339
+ while (ps) {
1340
+ pe = b;
1341
+
1342
+ while (pe && ps != pe) {
1343
+ pe = pe.parentNode;
1344
+ }
1345
+
1346
+ if (ps == pe) {
1347
+ break;
1348
+ }
1349
+
1350
+ ps = ps.parentNode;
1351
+ }
1352
+
1353
+ if (!ps && a.ownerDocument) {
1354
+ return a.ownerDocument.documentElement;
1355
+ }
1356
+
1357
+ return ps;
1358
+ },
1359
+
1360
+ /**
1361
+ * Parses the specified RGB color value and returns a hex version of that color.
1362
+ *
1363
+ * @method toHex
1364
+ * @param {String} rgbVal RGB string value like rgb(1,2,3)
1365
+ * @return {String} Hex version of that RGB value like #FF00FF.
1366
+ */
1367
+ toHex: function(rgbVal) {
1368
+ return this.styles.toHex(Tools.trim(rgbVal));
1369
+ },
1370
+
1371
+ /**
1372
+ * Executes the specified function on the element by id or dom element node or array of elements/id.
1373
+ *
1374
+ * @method run
1375
+ * @param {String/Element/Array} elm ID or DOM element object or array with ids or elements.
1376
+ * @param {function} func Function to execute for each item.
1377
+ * @param {Object} scope Optional scope to execute the function in.
1378
+ * @return {Object/Array} Single object, or an array of objects if multiple input elements were passed in.
1379
+ */
1380
+ run: function(elm, func, scope) {
1381
+ var self = this, result;
1382
+
1383
+ if (typeof elm === 'string') {
1384
+ elm = self.get(elm);
1385
+ }
1386
+
1387
+ if (!elm) {
1388
+ return false;
1389
+ }
1390
+
1391
+ scope = scope || this;
1392
+ if (!elm.nodeType && (elm.length || elm.length === 0)) {
1393
+ result = [];
1394
+
1395
+ each(elm, function(elm, i) {
1396
+ if (elm) {
1397
+ if (typeof elm == 'string') {
1398
+ elm = self.get(elm);
1399
+ }
1400
+
1401
+ result.push(func.call(scope, elm, i));
1402
+ }
1403
+ });
1404
+
1405
+ return result;
1406
+ }
1407
+
1408
+ return func.call(scope, elm);
1409
+ },
1410
+
1411
+ /**
1412
+ * Returns a NodeList with attributes for the element.
1413
+ *
1414
+ * @method getAttribs
1415
+ * @param {HTMLElement/string} elm Element node or string id to get attributes from.
1416
+ * @return {NodeList} NodeList with attributes.
1417
+ */
1418
+ getAttribs: function(elm) {
1419
+ var attrs;
1420
+
1421
+ elm = this.get(elm);
1422
+
1423
+ if (!elm) {
1424
+ return [];
1425
+ }
1426
+
1427
+ if (isIE) {
1428
+ attrs = [];
1429
+
1430
+ // Object will throw exception in IE
1431
+ if (elm.nodeName == 'OBJECT') {
1432
+ return elm.attributes;
1433
+ }
1434
+
1435
+ // IE doesn't keep the selected attribute if you clone option elements
1436
+ if (elm.nodeName === 'OPTION' && this.getAttrib(elm, 'selected')) {
1437
+ attrs.push({specified: 1, nodeName: 'selected'});
1438
+ }
1439
+
1440
+ // It's crazy that this is faster in IE but it's because it returns all attributes all the time
1441
+ var attrRegExp = /<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi;
1442
+ elm.cloneNode(false).outerHTML.replace(attrRegExp, '').replace(/[\w:\-]+/gi, function(a) {
1443
+ attrs.push({specified: 1, nodeName: a});
1444
+ });
1445
+
1446
+ return attrs;
1447
+ }
1448
+
1449
+ return elm.attributes;
1450
+ },
1451
+
1452
+ /**
1453
+ * Returns true/false if the specified node is to be considered empty or not.
1454
+ *
1455
+ * @example
1456
+ * tinymce.DOM.isEmpty(node, {img: true});
1457
+ * @method isEmpty
1458
+ * @param {Object} elements Optional name/value object with elements that are automatically treated as non-empty elements.
1459
+ * @return {Boolean} true/false if the node is empty or not.
1460
+ */
1461
+ isEmpty: function(node, elements) {
1462
+ var self = this, i, attributes, type, walker, name, brCount = 0;
1463
+
1464
+ node = node.firstChild;
1465
+ if (node) {
1466
+ walker = new TreeWalker(node, node.parentNode);
1467
+ elements = elements || (self.schema ? self.schema.getNonEmptyElements() : null);
1468
+
1469
+ do {
1470
+ type = node.nodeType;
1471
+
1472
+ if (type === 1) {
1473
+ // Ignore bogus elements
1474
+ if (node.getAttribute('data-mce-bogus')) {
1475
+ continue;
1476
+ }
1477
+
1478
+ // Keep empty elements like <img />
1479
+ name = node.nodeName.toLowerCase();
1480
+ if (elements && elements[name]) {
1481
+ // Ignore single BR elements in blocks like <p><br /></p> or <p><span><br /></span></p>
1482
+ if (name === 'br') {
1483
+ brCount++;
1484
+ continue;
1485
+ }
1486
+
1487
+ return false;
1488
+ }
1489
+
1490
+ // Keep elements with data-bookmark attributes or name attribute like <a name="1"></a>
1491
+ attributes = self.getAttribs(node);
1492
+ i = attributes.length;
1493
+ while (i--) {
1494
+ name = attributes[i].nodeName;
1495
+ if (name === "name" || name === 'data-mce-bookmark') {
1496
+ return false;
1497
+ }
1498
+ }
1499
+ }
1500
+
1501
+ // Keep comment nodes
1502
+ if (type == 8) {
1503
+ return false;
1504
+ }
1505
+
1506
+ // Keep non whitespace text nodes
1507
+ if ((type === 3 && !whiteSpaceRegExp.test(node.nodeValue))) {
1508
+ return false;
1509
+ }
1510
+ } while ((node = walker.next()));
1511
+ }
1512
+
1513
+ return brCount <= 1;
1514
+ },
1515
+
1516
+ /**
1517
+ * Creates a new DOM Range object. This will use the native DOM Range API if it's
1518
+ * available. If it's not, it will fall back to the custom TinyMCE implementation.
1519
+ *
1520
+ * @method createRng
1521
+ * @return {DOMRange} DOM Range object.
1522
+ * @example
1523
+ * var rng = tinymce.DOM.createRng();
1524
+ * alert(rng.startContainer + "," + rng.startOffset);
1525
+ */
1526
+ createRng: function() {
1527
+ var doc = this.doc;
1528
+
1529
+ return doc.createRange ? doc.createRange() : new Range(this);
1530
+ },
1531
+
1532
+ /**
1533
+ * Returns the index of the specified node within its parent.
1534
+ *
1535
+ * @method nodeIndex
1536
+ * @param {Node} node Node to look for.
1537
+ * @param {boolean} normalized Optional true/false state if the index is what it would be after a normalization.
1538
+ * @return {Number} Index of the specified node.
1539
+ */
1540
+ nodeIndex: nodeIndex,
1541
+
1542
+ /**
1543
+ * Splits an element into two new elements and places the specified split
1544
+ * element or elements between the new ones. For example splitting the paragraph at the bold element in
1545
+ * this example <p>abc<b>abc</b>123</p> would produce <p>abc</p><b>abc</b><p>123</p>.
1546
+ *
1547
+ * @method split
1548
+ * @param {Element} parentElm Parent element to split.
1549
+ * @param {Element} splitElm Element to split at.
1550
+ * @param {Element} replacementElm Optional replacement element to replace the split element with.
1551
+ * @return {Element} Returns the split element or the replacement element if that is specified.
1552
+ */
1553
+ split: function(parentElm, splitElm, replacementElm) {
1554
+ var self = this, r = self.createRng(), bef, aft, pa;
1555
+
1556
+ // W3C valid browsers tend to leave empty nodes to the left/right side of the contents - this makes sense
1557
+ // but we don't want that in our code since it serves no purpose for the end user
1558
+ // For example splitting this html at the bold element:
1559
+ // <p>text 1<span><b>CHOP</b></span>text 2</p>
1560
+ // would produce:
1561
+ // <p>text 1<span></span></p><b>CHOP</b><p><span></span>text 2</p>
1562
+ // this function will then trim off empty edges and produce:
1563
+ // <p>text 1</p><b>CHOP</b><p>text 2</p>
1564
+ function trimNode(node) {
1565
+ var i, children = node.childNodes, type = node.nodeType;
1566
+
1567
+ function surroundedBySpans(node) {
1568
+ var previousIsSpan = node.previousSibling && node.previousSibling.nodeName == 'SPAN';
1569
+ var nextIsSpan = node.nextSibling && node.nextSibling.nodeName == 'SPAN';
1570
+ return previousIsSpan && nextIsSpan;
1571
+ }
1572
+
1573
+ if (type == 1 && node.getAttribute('data-mce-type') == 'bookmark') {
1574
+ return;
1575
+ }
1576
+
1577
+ for (i = children.length - 1; i >= 0; i--) {
1578
+ trimNode(children[i]);
1579
+ }
1580
+
1581
+ if (type != 9) {
1582
+ // Keep non whitespace text nodes
1583
+ if (type == 3 && node.nodeValue.length > 0) {
1584
+ // If parent element isn't a block or there isn't any useful contents for example "<p> </p>"
1585
+ // Also keep text nodes with only spaces if surrounded by spans.
1586
+ // eg. "<p><span>a</span> <span>b</span></p>" should keep space between a and b
1587
+ var trimmedLength = trim(node.nodeValue).length;
1588
+ if (!self.isBlock(node.parentNode) || trimmedLength > 0 || trimmedLength === 0 && surroundedBySpans(node)) {
1589
+ return;
1590
+ }
1591
+ } else if (type == 1) {
1592
+ // If the only child is a bookmark then move it up
1593
+ children = node.childNodes;
1594
+
1595
+ // TODO fix this complex if
1596
+ if (children.length == 1 && children[0] && children[0].nodeType == 1 &&
1597
+ children[0].getAttribute('data-mce-type') == 'bookmark') {
1598
+ node.parentNode.insertBefore(children[0], node);
1599
+ }
1600
+
1601
+ // Keep non empty elements or img, hr etc
1602
+ if (children.length || /^(br|hr|input|img)$/i.test(node.nodeName)) {
1603
+ return;
1604
+ }
1605
+ }
1606
+
1607
+ self.remove(node);
1608
+ }
1609
+
1610
+ return node;
1611
+ }
1612
+
1613
+ if (parentElm && splitElm) {
1614
+ // Get before chunk
1615
+ r.setStart(parentElm.parentNode, self.nodeIndex(parentElm));
1616
+ r.setEnd(splitElm.parentNode, self.nodeIndex(splitElm));
1617
+ bef = r.extractContents();
1618
+
1619
+ // Get after chunk
1620
+ r = self.createRng();
1621
+ r.setStart(splitElm.parentNode, self.nodeIndex(splitElm) + 1);
1622
+ r.setEnd(parentElm.parentNode, self.nodeIndex(parentElm) + 1);
1623
+ aft = r.extractContents();
1624
+
1625
+ // Insert before chunk
1626
+ pa = parentElm.parentNode;
1627
+ pa.insertBefore(trimNode(bef), parentElm);
1628
+
1629
+ // Insert middle chunk
1630
+ if (replacementElm) {
1631
+ pa.insertBefore(replacementElm, parentElm);
1632
+ //pa.replaceChild(replacementElm, splitElm);
1633
+ } else {
1634
+ pa.insertBefore(splitElm, parentElm);
1635
+ }
1636
+
1637
+ // Insert after chunk
1638
+ pa.insertBefore(trimNode(aft), parentElm);
1639
+ self.remove(parentElm);
1640
+
1641
+ return replacementElm || splitElm;
1642
+ }
1643
+ },
1644
+
1645
+ /**
1646
+ * Adds an event handler to the specified object.
1647
+ *
1648
+ * @method bind
1649
+ * @param {Element/Document/Window/Array} target Target element to bind events to.
1650
+ * handler to or an array of elements/ids/documents.
1651
+ * @param {String} name Name of event handler to add, for example: click.
1652
+ * @param {function} func Function to execute when the event occurs.
1653
+ * @param {Object} scope Optional scope to execute the function in.
1654
+ * @return {function} Function callback handler the same as the one passed in.
1655
+ */
1656
+ bind: function(target, name, func, scope) {
1657
+ var self = this;
1658
+
1659
+ if (Tools.isArray(target)) {
1660
+ var i = target.length;
1661
+
1662
+ while (i--) {
1663
+ target[i] = self.bind(target[i], name, func, scope);
1664
+ }
1665
+
1666
+ return target;
1667
+ }
1668
+
1669
+ // Collect all window/document events bound by editor instance
1670
+ if (self.settings.collect && (target === self.doc || target === self.win)) {
1671
+ self.boundEvents.push([target, name, func, scope]);
1672
+ }
1673
+
1674
+ return self.events.bind(target, name, func, scope || self);
1675
+ },
1676
+
1677
+ /**
1678
+ * Removes the specified event handler by name and function from an element or collection of elements.
1679
+ *
1680
+ * @method unbind
1681
+ * @param {Element/Document/Window/Array} target Target element to unbind events on.
1682
+ * @param {String} name Event handler name, for example: "click"
1683
+ * @param {function} func Function to remove.
1684
+ * @return {bool/Array} Bool state of true if the handler was removed, or an array of states if multiple input elements
1685
+ * were passed in.
1686
+ */
1687
+ unbind: function(target, name, func) {
1688
+ var self = this, i;
1689
+
1690
+ if (Tools.isArray(target)) {
1691
+ i = target.length;
1692
+
1693
+ while (i--) {
1694
+ target[i] = self.unbind(target[i], name, func);
1695
+ }
1696
+
1697
+ return target;
1698
+ }
1699
+
1700
+ // Remove any bound events matching the input
1701
+ if (self.boundEvents && (target === self.doc || target === self.win)) {
1702
+ i = self.boundEvents.length;
1703
+
1704
+ while (i--) {
1705
+ var item = self.boundEvents[i];
1706
+
1707
+ if (target == item[0] && (!name || name == item[1]) && (!func || func == item[2])) {
1708
+ this.events.unbind(item[0], item[1], item[2]);
1709
+ }
1710
+ }
1711
+ }
1712
+
1713
+ return this.events.unbind(target, name, func);
1714
+ },
1715
+
1716
+ /**
1717
+ * Fires the specified event name with object on target.
1718
+ *
1719
+ * @method fire
1720
+ * @param {Node/Document/Window} target Target element or object to fire event on.
1721
+ * @param {String} name Name of the event to fire.
1722
+ * @param {Object} evt Event object to send.
1723
+ * @return {Event} Event object.
1724
+ */
1725
+ fire: function(target, name, evt) {
1726
+ return this.events.fire(target, name, evt);
1727
+ },
1728
+
1729
+ // Returns the content editable state of a node
1730
+ getContentEditable: function(node) {
1731
+ var contentEditable;
1732
+
1733
+ // Check type
1734
+ if (!node || node.nodeType != 1) {
1735
+ return null;
1736
+ }
1737
+
1738
+ // Check for fake content editable
1739
+ contentEditable = node.getAttribute("data-mce-contenteditable");
1740
+ if (contentEditable && contentEditable !== "inherit") {
1741
+ return contentEditable;
1742
+ }
1743
+
1744
+ // Check for real content editable
1745
+ return node.contentEditable !== "inherit" ? node.contentEditable : null;
1746
+ },
1747
+
1748
+ getContentEditableParent: function(node) {
1749
+ var root = this.getRoot(), state = null;
1750
+
1751
+ for (; node && node !== root; node = node.parentNode) {
1752
+ state = this.getContentEditable(node);
1753
+
1754
+ if (state !== null) {
1755
+ break;
1756
+ }
1757
+ }
1758
+
1759
+ return state;
1760
+ },
1761
+
1762
+ /**
1763
+ * Destroys all internal references to the DOM to solve IE leak issues.
1764
+ *
1765
+ * @method destroy
1766
+ */
1767
+ destroy: function() {
1768
+ var self = this;
1769
+
1770
+ // Unbind all events bound to window/document by editor instance
1771
+ if (self.boundEvents) {
1772
+ var i = self.boundEvents.length;
1773
+
1774
+ while (i--) {
1775
+ var item = self.boundEvents[i];
1776
+ this.events.unbind(item[0], item[1], item[2]);
1777
+ }
1778
+
1779
+ self.boundEvents = null;
1780
+ }
1781
+
1782
+ // Restore sizzle document to window.document
1783
+ // Since the current document might be removed producing "Permission denied" on IE see #6325
1784
+ if (Sizzle.setDocument) {
1785
+ Sizzle.setDocument();
1786
+ }
1787
+
1788
+ self.win = self.doc = self.root = self.events = self.frag = null;
1789
+ },
1790
+
1791
+ isChildOf: function(node, parent) {
1792
+ while (node) {
1793
+ if (parent === node) {
1794
+ return true;
1795
+ }
1796
+
1797
+ node = node.parentNode;
1798
+ }
1799
+
1800
+ return false;
1801
+ },
1802
+
1803
+ // #ifdef debug
1804
+
1805
+ dumpRng: function(r) {
1806
+ return (
1807
+ 'startContainer: ' + r.startContainer.nodeName +
1808
+ ', startOffset: ' + r.startOffset +
1809
+ ', endContainer: ' + r.endContainer.nodeName +
1810
+ ', endOffset: ' + r.endOffset
1811
+ );
1812
+ },
1813
+
1814
+ // #endif
1815
+
1816
+ _findSib: function(node, selector, name) {
1817
+ var self = this, func = selector;
1818
+
1819
+ if (node) {
1820
+ // If expression make a function of it using is
1821
+ if (typeof func == 'string') {
1822
+ func = function(node) {
1823
+ return self.is(node, selector);
1824
+ };
1825
+ }
1826
+
1827
+ // Loop all siblings
1828
+ for (node = node[name]; node; node = node[name]) {
1829
+ if (func(node)) {
1830
+ return node;
1831
+ }
1832
+ }
1833
+ }
1834
+
1835
+ return null;
1836
+ }
1837
+ };
1838
+
1839
+ /**
1840
+ * Instance of DOMUtils for the current document.
1841
+ *
1842
+ * @static
1843
+ * @property DOM
1844
+ * @type tinymce.dom.DOMUtils
1845
+ * @example
1846
+ * // Example of how to add a class to some element by id
1847
+ * tinymce.DOM.addClass('someid', 'someclass');
1848
+ */
1849
+ DOMUtils.DOM = new DOMUtils(document);
1850
+ DOMUtils.nodeIndex = nodeIndex;
1851
+
1852
+ return DOMUtils;
1853
+ });