contentment 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. data/README.rdoc +15 -0
  2. data/config/routes.rb +18 -0
  3. data/lib/contentment.rb +8 -0
  4. data/lib/contentment/engine.rb +16 -0
  5. data/lib/extensions/action_controller/base.rb +5 -0
  6. data/lib/generators/contentment/contentment_views_templates/contents/_preview.html.erb +9 -0
  7. data/lib/generators/contentment/contentment_views_templates/contents/edit.html.erb +56 -0
  8. data/lib/generators/contentment/contentment_views_templates/contents/index.html.erb +28 -0
  9. data/lib/generators/contentment/contentment_views_templates/contents/new.html.erb +37 -0
  10. data/lib/generators/contentment/contentment_views_templates/contents/show.html.erb +22 -0
  11. data/lib/generators/contentment/templates/content.rb +48 -0
  12. data/lib/generators/contentment/templates/contents_controller.rb +58 -0
  13. data/lib/generators/contentment/templates/migration.rb +24 -0
  14. data/lib/generators/contentment_generator.rb +46 -0
  15. data/lib/generators/contentment_views_generator.rb +15 -0
  16. data/public/javascripts/tiny_mce/langs/en.js +169 -0
  17. data/public/javascripts/tiny_mce/license.txt +504 -0
  18. data/public/javascripts/tiny_mce/plugins/advhr/css/advhr.css +5 -0
  19. data/public/javascripts/tiny_mce/plugins/advhr/editor_plugin.js +1 -0
  20. data/public/javascripts/tiny_mce/plugins/advhr/editor_plugin_src.js +57 -0
  21. data/public/javascripts/tiny_mce/plugins/advhr/js/rule.js +43 -0
  22. data/public/javascripts/tiny_mce/plugins/advhr/langs/en_dlg.js +5 -0
  23. data/public/javascripts/tiny_mce/plugins/advhr/rule.htm +62 -0
  24. data/public/javascripts/tiny_mce/plugins/advimage/css/advimage.css +13 -0
  25. data/public/javascripts/tiny_mce/plugins/advimage/editor_plugin.js +1 -0
  26. data/public/javascripts/tiny_mce/plugins/advimage/editor_plugin_src.js +50 -0
  27. data/public/javascripts/tiny_mce/plugins/advimage/image.htm +237 -0
  28. data/public/javascripts/tiny_mce/plugins/advimage/img/sample.gif +0 -0
  29. data/public/javascripts/tiny_mce/plugins/advimage/js/image.js +443 -0
  30. data/public/javascripts/tiny_mce/plugins/advimage/langs/en_dlg.js +43 -0
  31. data/public/javascripts/tiny_mce/plugins/advlink/css/advlink.css +8 -0
  32. data/public/javascripts/tiny_mce/plugins/advlink/editor_plugin.js +1 -0
  33. data/public/javascripts/tiny_mce/plugins/advlink/editor_plugin_src.js +61 -0
  34. data/public/javascripts/tiny_mce/plugins/advlink/js/advlink.js +528 -0
  35. data/public/javascripts/tiny_mce/plugins/advlink/langs/en_dlg.js +52 -0
  36. data/public/javascripts/tiny_mce/plugins/advlink/link.htm +338 -0
  37. data/public/javascripts/tiny_mce/plugins/advlist/editor_plugin.js +1 -0
  38. data/public/javascripts/tiny_mce/plugins/advlist/editor_plugin_src.js +154 -0
  39. data/public/javascripts/tiny_mce/plugins/autoresize/editor_plugin.js +1 -0
  40. data/public/javascripts/tiny_mce/plugins/autoresize/editor_plugin_src.js +117 -0
  41. data/public/javascripts/tiny_mce/plugins/autosave/editor_plugin.js +1 -0
  42. data/public/javascripts/tiny_mce/plugins/autosave/editor_plugin_src.js +422 -0
  43. data/public/javascripts/tiny_mce/plugins/autosave/langs/en.js +4 -0
  44. data/public/javascripts/tiny_mce/plugins/bbcode/editor_plugin.js +1 -0
  45. data/public/javascripts/tiny_mce/plugins/bbcode/editor_plugin_src.js +120 -0
  46. data/public/javascripts/tiny_mce/plugins/contextmenu/editor_plugin.js +1 -0
  47. data/public/javascripts/tiny_mce/plugins/contextmenu/editor_plugin_src.js +127 -0
  48. data/public/javascripts/tiny_mce/plugins/directionality/editor_plugin.js +1 -0
  49. data/public/javascripts/tiny_mce/plugins/directionality/editor_plugin_src.js +82 -0
  50. data/public/javascripts/tiny_mce/plugins/emotions/editor_plugin.js +1 -0
  51. data/public/javascripts/tiny_mce/plugins/emotions/editor_plugin_src.js +43 -0
  52. data/public/javascripts/tiny_mce/plugins/emotions/emotions.htm +40 -0
  53. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-cool.gif +0 -0
  54. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-cry.gif +0 -0
  55. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-embarassed.gif +0 -0
  56. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-foot-in-mouth.gif +0 -0
  57. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-frown.gif +0 -0
  58. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-innocent.gif +0 -0
  59. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-kiss.gif +0 -0
  60. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-laughing.gif +0 -0
  61. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-money-mouth.gif +0 -0
  62. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-sealed.gif +0 -0
  63. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-smile.gif +0 -0
  64. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-surprised.gif +0 -0
  65. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-tongue-out.gif +0 -0
  66. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-undecided.gif +0 -0
  67. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-wink.gif +0 -0
  68. data/public/javascripts/tiny_mce/plugins/emotions/img/smiley-yell.gif +0 -0
  69. data/public/javascripts/tiny_mce/plugins/emotions/js/emotions.js +22 -0
  70. data/public/javascripts/tiny_mce/plugins/emotions/langs/en_dlg.js +20 -0
  71. data/public/javascripts/tiny_mce/plugins/example/dialog.htm +27 -0
  72. data/public/javascripts/tiny_mce/plugins/example/editor_plugin.js +1 -0
  73. data/public/javascripts/tiny_mce/plugins/example/editor_plugin_src.js +84 -0
  74. data/public/javascripts/tiny_mce/plugins/example/img/example.gif +0 -0
  75. data/public/javascripts/tiny_mce/plugins/example/js/dialog.js +19 -0
  76. data/public/javascripts/tiny_mce/plugins/example/langs/en.js +3 -0
  77. data/public/javascripts/tiny_mce/plugins/example/langs/en_dlg.js +3 -0
  78. data/public/javascripts/tiny_mce/plugins/fullpage/css/fullpage.css +182 -0
  79. data/public/javascripts/tiny_mce/plugins/fullpage/editor_plugin.js +1 -0
  80. data/public/javascripts/tiny_mce/plugins/fullpage/editor_plugin_src.js +149 -0
  81. data/public/javascripts/tiny_mce/plugins/fullpage/fullpage.htm +576 -0
  82. data/public/javascripts/tiny_mce/plugins/fullpage/js/fullpage.js +471 -0
  83. data/public/javascripts/tiny_mce/plugins/fullpage/langs/en_dlg.js +85 -0
  84. data/public/javascripts/tiny_mce/plugins/fullscreen/editor_plugin.js +1 -0
  85. data/public/javascripts/tiny_mce/plugins/fullscreen/editor_plugin_src.js +148 -0
  86. data/public/javascripts/tiny_mce/plugins/fullscreen/fullscreen.htm +110 -0
  87. data/public/javascripts/tiny_mce/plugins/iespell/editor_plugin.js +1 -0
  88. data/public/javascripts/tiny_mce/plugins/iespell/editor_plugin_src.js +54 -0
  89. data/public/javascripts/tiny_mce/plugins/inlinepopups/editor_plugin.js +1 -0
  90. data/public/javascripts/tiny_mce/plugins/inlinepopups/editor_plugin_src.js +635 -0
  91. data/public/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/alert.gif +0 -0
  92. data/public/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/button.gif +0 -0
  93. data/public/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif +0 -0
  94. data/public/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif +0 -0
  95. data/public/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/corners.gif +0 -0
  96. data/public/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif +0 -0
  97. data/public/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif +0 -0
  98. data/public/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css +90 -0
  99. data/public/javascripts/tiny_mce/plugins/inlinepopups/template.htm +387 -0
  100. data/public/javascripts/tiny_mce/plugins/insertdatetime/editor_plugin.js +1 -0
  101. data/public/javascripts/tiny_mce/plugins/insertdatetime/editor_plugin_src.js +83 -0
  102. data/public/javascripts/tiny_mce/plugins/layer/editor_plugin.js +1 -0
  103. data/public/javascripts/tiny_mce/plugins/layer/editor_plugin_src.js +212 -0
  104. data/public/javascripts/tiny_mce/plugins/legacyoutput/editor_plugin.js +1 -0
  105. data/public/javascripts/tiny_mce/plugins/legacyoutput/editor_plugin_src.js +133 -0
  106. data/public/javascripts/tiny_mce/plugins/media/css/content.css +6 -0
  107. data/public/javascripts/tiny_mce/plugins/media/css/media.css +16 -0
  108. data/public/javascripts/tiny_mce/plugins/media/editor_plugin.js +1 -0
  109. data/public/javascripts/tiny_mce/plugins/media/editor_plugin_src.js +414 -0
  110. data/public/javascripts/tiny_mce/plugins/media/img/flash.gif +0 -0
  111. data/public/javascripts/tiny_mce/plugins/media/img/flv_player.swf +0 -0
  112. data/public/javascripts/tiny_mce/plugins/media/img/quicktime.gif +0 -0
  113. data/public/javascripts/tiny_mce/plugins/media/img/realmedia.gif +0 -0
  114. data/public/javascripts/tiny_mce/plugins/media/img/shockwave.gif +0 -0
  115. data/public/javascripts/tiny_mce/plugins/media/img/trans.gif +0 -0
  116. data/public/javascripts/tiny_mce/plugins/media/img/windowsmedia.gif +0 -0
  117. data/public/javascripts/tiny_mce/plugins/media/js/embed.js +73 -0
  118. data/public/javascripts/tiny_mce/plugins/media/js/media.js +630 -0
  119. data/public/javascripts/tiny_mce/plugins/media/langs/en_dlg.js +103 -0
  120. data/public/javascripts/tiny_mce/plugins/media/media.htm +822 -0
  121. data/public/javascripts/tiny_mce/plugins/nonbreaking/editor_plugin.js +1 -0
  122. data/public/javascripts/tiny_mce/plugins/nonbreaking/editor_plugin_src.js +53 -0
  123. data/public/javascripts/tiny_mce/plugins/noneditable/editor_plugin.js +1 -0
  124. data/public/javascripts/tiny_mce/plugins/noneditable/editor_plugin_src.js +90 -0
  125. data/public/javascripts/tiny_mce/plugins/pagebreak/css/content.css +1 -0
  126. data/public/javascripts/tiny_mce/plugins/pagebreak/editor_plugin.js +1 -0
  127. data/public/javascripts/tiny_mce/plugins/pagebreak/editor_plugin_src.js +77 -0
  128. data/public/javascripts/tiny_mce/plugins/pagebreak/img/pagebreak.gif +0 -0
  129. data/public/javascripts/tiny_mce/plugins/pagebreak/img/trans.gif +0 -0
  130. data/public/javascripts/tiny_mce/plugins/paste/editor_plugin.js +1 -0
  131. data/public/javascripts/tiny_mce/plugins/paste/editor_plugin_src.js +929 -0
  132. data/public/javascripts/tiny_mce/plugins/paste/js/pastetext.js +36 -0
  133. data/public/javascripts/tiny_mce/plugins/paste/js/pasteword.js +51 -0
  134. data/public/javascripts/tiny_mce/plugins/paste/langs/en_dlg.js +5 -0
  135. data/public/javascripts/tiny_mce/plugins/paste/pastetext.htm +33 -0
  136. data/public/javascripts/tiny_mce/plugins/paste/pasteword.htm +27 -0
  137. data/public/javascripts/tiny_mce/plugins/preview/editor_plugin.js +1 -0
  138. data/public/javascripts/tiny_mce/plugins/preview/editor_plugin_src.js +53 -0
  139. data/public/javascripts/tiny_mce/plugins/preview/example.html +28 -0
  140. data/public/javascripts/tiny_mce/plugins/preview/jscripts/embed.js +73 -0
  141. data/public/javascripts/tiny_mce/plugins/preview/preview.html +17 -0
  142. data/public/javascripts/tiny_mce/plugins/print/editor_plugin.js +1 -0
  143. data/public/javascripts/tiny_mce/plugins/print/editor_plugin_src.js +34 -0
  144. data/public/javascripts/tiny_mce/plugins/save/editor_plugin.js +1 -0
  145. data/public/javascripts/tiny_mce/plugins/save/editor_plugin_src.js +101 -0
  146. data/public/javascripts/tiny_mce/plugins/searchreplace/css/searchreplace.css +6 -0
  147. data/public/javascripts/tiny_mce/plugins/searchreplace/editor_plugin.js +1 -0
  148. data/public/javascripts/tiny_mce/plugins/searchreplace/editor_plugin_src.js +57 -0
  149. data/public/javascripts/tiny_mce/plugins/searchreplace/js/searchreplace.js +126 -0
  150. data/public/javascripts/tiny_mce/plugins/searchreplace/langs/en_dlg.js +16 -0
  151. data/public/javascripts/tiny_mce/plugins/searchreplace/searchreplace.htm +104 -0
  152. data/public/javascripts/tiny_mce/plugins/spellchecker/css/content.css +1 -0
  153. data/public/javascripts/tiny_mce/plugins/spellchecker/editor_plugin.js +1 -0
  154. data/public/javascripts/tiny_mce/plugins/spellchecker/editor_plugin_src.js +341 -0
  155. data/public/javascripts/tiny_mce/plugins/spellchecker/img/wline.gif +0 -0
  156. data/public/javascripts/tiny_mce/plugins/style/css/props.css +13 -0
  157. data/public/javascripts/tiny_mce/plugins/style/editor_plugin.js +1 -0
  158. data/public/javascripts/tiny_mce/plugins/style/editor_plugin_src.js +55 -0
  159. data/public/javascripts/tiny_mce/plugins/style/js/props.js +641 -0
  160. data/public/javascripts/tiny_mce/plugins/style/langs/en_dlg.js +63 -0
  161. data/public/javascripts/tiny_mce/plugins/style/props.htm +730 -0
  162. data/public/javascripts/tiny_mce/plugins/tabfocus/editor_plugin.js +1 -0
  163. data/public/javascripts/tiny_mce/plugins/tabfocus/editor_plugin_src.js +112 -0
  164. data/public/javascripts/tiny_mce/plugins/table/cell.htm +183 -0
  165. data/public/javascripts/tiny_mce/plugins/table/css/cell.css +17 -0
  166. data/public/javascripts/tiny_mce/plugins/table/css/row.css +25 -0
  167. data/public/javascripts/tiny_mce/plugins/table/css/table.css +13 -0
  168. data/public/javascripts/tiny_mce/plugins/table/editor_plugin.js +1 -0
  169. data/public/javascripts/tiny_mce/plugins/table/editor_plugin_src.js +1118 -0
  170. data/public/javascripts/tiny_mce/plugins/table/js/cell.js +269 -0
  171. data/public/javascripts/tiny_mce/plugins/table/js/merge_cells.js +27 -0
  172. data/public/javascripts/tiny_mce/plugins/table/js/row.js +212 -0
  173. data/public/javascripts/tiny_mce/plugins/table/js/table.js +449 -0
  174. data/public/javascripts/tiny_mce/plugins/table/langs/en_dlg.js +74 -0
  175. data/public/javascripts/tiny_mce/plugins/table/merge_cells.htm +37 -0
  176. data/public/javascripts/tiny_mce/plugins/table/row.htm +160 -0
  177. data/public/javascripts/tiny_mce/plugins/table/table.htm +192 -0
  178. data/public/javascripts/tiny_mce/plugins/template/blank.htm +12 -0
  179. data/public/javascripts/tiny_mce/plugins/template/css/template.css +23 -0
  180. data/public/javascripts/tiny_mce/plugins/template/editor_plugin.js +1 -0
  181. data/public/javascripts/tiny_mce/plugins/template/editor_plugin_src.js +159 -0
  182. data/public/javascripts/tiny_mce/plugins/template/js/template.js +106 -0
  183. data/public/javascripts/tiny_mce/plugins/template/langs/en_dlg.js +15 -0
  184. data/public/javascripts/tiny_mce/plugins/template/template.htm +38 -0
  185. data/public/javascripts/tiny_mce/plugins/visualchars/editor_plugin.js +1 -0
  186. data/public/javascripts/tiny_mce/plugins/visualchars/editor_plugin_src.js +76 -0
  187. data/public/javascripts/tiny_mce/plugins/wordcount/editor_plugin.js +1 -0
  188. data/public/javascripts/tiny_mce/plugins/wordcount/editor_plugin_src.js +98 -0
  189. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/abbr.htm +148 -0
  190. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/acronym.htm +148 -0
  191. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/attributes.htm +153 -0
  192. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/cite.htm +148 -0
  193. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/css/attributes.css +11 -0
  194. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/css/popup.css +9 -0
  195. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/del.htm +169 -0
  196. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/editor_plugin.js +1 -0
  197. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js +139 -0
  198. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/ins.htm +169 -0
  199. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/js/abbr.js +28 -0
  200. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/js/acronym.js +28 -0
  201. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/js/attributes.js +126 -0
  202. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/js/cite.js +28 -0
  203. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/js/del.js +63 -0
  204. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/js/element_common.js +234 -0
  205. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/js/ins.js +62 -0
  206. data/public/javascripts/tiny_mce/plugins/xhtmlxtras/langs/en_dlg.js +32 -0
  207. data/public/javascripts/tiny_mce/themes/advanced/about.htm +56 -0
  208. data/public/javascripts/tiny_mce/themes/advanced/anchor.htm +31 -0
  209. data/public/javascripts/tiny_mce/themes/advanced/charmap.htm +53 -0
  210. data/public/javascripts/tiny_mce/themes/advanced/color_picker.htm +75 -0
  211. data/public/javascripts/tiny_mce/themes/advanced/editor_template.js +1 -0
  212. data/public/javascripts/tiny_mce/themes/advanced/editor_template_src.js +1209 -0
  213. data/public/javascripts/tiny_mce/themes/advanced/image.htm +85 -0
  214. data/public/javascripts/tiny_mce/themes/advanced/img/colorpicker.jpg +0 -0
  215. data/public/javascripts/tiny_mce/themes/advanced/img/icons.gif +0 -0
  216. data/public/javascripts/tiny_mce/themes/advanced/js/about.js +72 -0
  217. data/public/javascripts/tiny_mce/themes/advanced/js/anchor.js +37 -0
  218. data/public/javascripts/tiny_mce/themes/advanced/js/charmap.js +335 -0
  219. data/public/javascripts/tiny_mce/themes/advanced/js/color_picker.js +253 -0
  220. data/public/javascripts/tiny_mce/themes/advanced/js/image.js +245 -0
  221. data/public/javascripts/tiny_mce/themes/advanced/js/link.js +156 -0
  222. data/public/javascripts/tiny_mce/themes/advanced/js/source_editor.js +62 -0
  223. data/public/javascripts/tiny_mce/themes/advanced/langs/en.js +62 -0
  224. data/public/javascripts/tiny_mce/themes/advanced/langs/en_dlg.js +51 -0
  225. data/public/javascripts/tiny_mce/themes/advanced/link.htm +63 -0
  226. data/public/javascripts/tiny_mce/themes/advanced/skins/default/content.css +36 -0
  227. data/public/javascripts/tiny_mce/themes/advanced/skins/default/dialog.css +116 -0
  228. data/public/javascripts/tiny_mce/themes/advanced/skins/default/img/buttons.png +0 -0
  229. data/public/javascripts/tiny_mce/themes/advanced/skins/default/img/items.gif +0 -0
  230. data/public/javascripts/tiny_mce/themes/advanced/skins/default/img/menu_arrow.gif +0 -0
  231. data/public/javascripts/tiny_mce/themes/advanced/skins/default/img/menu_check.gif +0 -0
  232. data/public/javascripts/tiny_mce/themes/advanced/skins/default/img/progress.gif +0 -0
  233. data/public/javascripts/tiny_mce/themes/advanced/skins/default/img/tabs.gif +0 -0
  234. data/public/javascripts/tiny_mce/themes/advanced/skins/default/ui.css +215 -0
  235. data/public/javascripts/tiny_mce/themes/advanced/skins/o2k7/content.css +35 -0
  236. data/public/javascripts/tiny_mce/themes/advanced/skins/o2k7/dialog.css +115 -0
  237. data/public/javascripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg.png +0 -0
  238. data/public/javascripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_black.png +0 -0
  239. data/public/javascripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_silver.png +0 -0
  240. data/public/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui.css +216 -0
  241. data/public/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui_black.css +8 -0
  242. data/public/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css +5 -0
  243. data/public/javascripts/tiny_mce/themes/advanced/source_editor.htm +31 -0
  244. data/public/javascripts/tiny_mce/themes/simple/editor_template.js +1 -0
  245. data/public/javascripts/tiny_mce/themes/simple/editor_template_src.js +85 -0
  246. data/public/javascripts/tiny_mce/themes/simple/img/icons.gif +0 -0
  247. data/public/javascripts/tiny_mce/themes/simple/langs/en.js +11 -0
  248. data/public/javascripts/tiny_mce/themes/simple/skins/default/content.css +25 -0
  249. data/public/javascripts/tiny_mce/themes/simple/skins/default/ui.css +32 -0
  250. data/public/javascripts/tiny_mce/themes/simple/skins/o2k7/content.css +17 -0
  251. data/public/javascripts/tiny_mce/themes/simple/skins/o2k7/img/button_bg.png +0 -0
  252. data/public/javascripts/tiny_mce/themes/simple/skins/o2k7/ui.css +35 -0
  253. data/public/javascripts/tiny_mce/tiny_mce.js +1 -0
  254. data/public/javascripts/tiny_mce/tiny_mce_popup.js +5 -0
  255. data/public/javascripts/tiny_mce/tiny_mce_src.js +13771 -0
  256. data/public/javascripts/tiny_mce/utils/editable_selects.js +70 -0
  257. data/public/javascripts/tiny_mce/utils/form_utils.js +200 -0
  258. data/public/javascripts/tiny_mce/utils/mctabs.js +77 -0
  259. data/public/javascripts/tiny_mce/utils/validate.js +220 -0
  260. metadata +322 -0
@@ -0,0 +1 @@
1
+ (function(){tinymce.create("tinymce.plugins.Nonbreaking",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceNonBreaking",function(){a.execCommand("mceInsertContent",false,(a.plugins.visualchars&&a.plugins.visualchars.state)?'<span class="mceItemHidden mceVisualNbsp">&middot;</span>':"&nbsp;")});a.addButton("nonbreaking",{title:"nonbreaking.nonbreaking_desc",cmd:"mceNonBreaking"});if(a.getParam("nonbreaking_force_tab")){a.onKeyDown.add(function(d,f){if(tinymce.isIE&&f.keyCode==9){d.execCommand("mceNonBreaking");d.execCommand("mceNonBreaking");d.execCommand("mceNonBreaking");tinymce.dom.Event.cancel(f)}})}},getInfo:function(){return{longname:"Nonbreaking space",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/nonbreaking",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("nonbreaking",tinymce.plugins.Nonbreaking)})();
@@ -0,0 +1,53 @@
1
+ /**
2
+ * editor_plugin_src.js
3
+ *
4
+ * Copyright 2009, Moxiecode Systems AB
5
+ * Released under LGPL License.
6
+ *
7
+ * License: http://tinymce.moxiecode.com/license
8
+ * Contributing: http://tinymce.moxiecode.com/contributing
9
+ */
10
+
11
+ (function() {
12
+ tinymce.create('tinymce.plugins.Nonbreaking', {
13
+ init : function(ed, url) {
14
+ var t = this;
15
+
16
+ t.editor = ed;
17
+
18
+ // Register commands
19
+ ed.addCommand('mceNonBreaking', function() {
20
+ ed.execCommand('mceInsertContent', false, (ed.plugins.visualchars && ed.plugins.visualchars.state) ? '<span class="mceItemHidden mceVisualNbsp">&middot;</span>' : '&nbsp;');
21
+ });
22
+
23
+ // Register buttons
24
+ ed.addButton('nonbreaking', {title : 'nonbreaking.nonbreaking_desc', cmd : 'mceNonBreaking'});
25
+
26
+ if (ed.getParam('nonbreaking_force_tab')) {
27
+ ed.onKeyDown.add(function(ed, e) {
28
+ if (tinymce.isIE && e.keyCode == 9) {
29
+ ed.execCommand('mceNonBreaking');
30
+ ed.execCommand('mceNonBreaking');
31
+ ed.execCommand('mceNonBreaking');
32
+ tinymce.dom.Event.cancel(e);
33
+ }
34
+ });
35
+ }
36
+ },
37
+
38
+ getInfo : function() {
39
+ return {
40
+ longname : 'Nonbreaking space',
41
+ author : 'Moxiecode Systems AB',
42
+ authorurl : 'http://tinymce.moxiecode.com',
43
+ infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/nonbreaking',
44
+ version : tinymce.majorVersion + "." + tinymce.minorVersion
45
+ };
46
+ }
47
+
48
+ // Private methods
49
+ });
50
+
51
+ // Register plugin
52
+ tinymce.PluginManager.add('nonbreaking', tinymce.plugins.Nonbreaking);
53
+ })();
@@ -0,0 +1 @@
1
+ (function(){var a=tinymce.dom.Event;tinymce.create("tinymce.plugins.NonEditablePlugin",{init:function(d,e){var f=this,c,b;f.editor=d;c=d.getParam("noneditable_editable_class","mceEditable");b=d.getParam("noneditable_noneditable_class","mceNonEditable");d.onNodeChange.addToTop(function(h,g,k){var j,i;j=h.dom.getParent(h.selection.getStart(),function(l){return h.dom.hasClass(l,b)});i=h.dom.getParent(h.selection.getEnd(),function(l){return h.dom.hasClass(l,b)});if(j||i){f._setDisabled(1);return false}else{f._setDisabled(0)}})},getInfo:function(){return{longname:"Non editable elements",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_block:function(c,d){var b=d.keyCode;if((b>32&&b<41)||(b>111&&b<124)){return}return a.cancel(d)},_setDisabled:function(d){var c=this,b=c.editor;tinymce.each(b.controlManager.controls,function(e){e.setDisabled(d)});if(d!==c.disabled){if(d){b.onKeyDown.addToTop(c._block);b.onKeyPress.addToTop(c._block);b.onKeyUp.addToTop(c._block);b.onPaste.addToTop(c._block)}else{b.onKeyDown.remove(c._block);b.onKeyPress.remove(c._block);b.onKeyUp.remove(c._block);b.onPaste.remove(c._block)}c.disabled=d}}});tinymce.PluginManager.add("noneditable",tinymce.plugins.NonEditablePlugin)})();
@@ -0,0 +1,90 @@
1
+ /**
2
+ * editor_plugin_src.js
3
+ *
4
+ * Copyright 2009, Moxiecode Systems AB
5
+ * Released under LGPL License.
6
+ *
7
+ * License: http://tinymce.moxiecode.com/license
8
+ * Contributing: http://tinymce.moxiecode.com/contributing
9
+ */
10
+
11
+ (function() {
12
+ var Event = tinymce.dom.Event;
13
+
14
+ tinymce.create('tinymce.plugins.NonEditablePlugin', {
15
+ init : function(ed, url) {
16
+ var t = this, editClass, nonEditClass;
17
+
18
+ t.editor = ed;
19
+ editClass = ed.getParam("noneditable_editable_class", "mceEditable");
20
+ nonEditClass = ed.getParam("noneditable_noneditable_class", "mceNonEditable");
21
+
22
+ ed.onNodeChange.addToTop(function(ed, cm, n) {
23
+ var sc, ec;
24
+
25
+ // Block if start or end is inside a non editable element
26
+ sc = ed.dom.getParent(ed.selection.getStart(), function(n) {
27
+ return ed.dom.hasClass(n, nonEditClass);
28
+ });
29
+
30
+ ec = ed.dom.getParent(ed.selection.getEnd(), function(n) {
31
+ return ed.dom.hasClass(n, nonEditClass);
32
+ });
33
+
34
+ // Block or unblock
35
+ if (sc || ec) {
36
+ t._setDisabled(1);
37
+ return false;
38
+ } else
39
+ t._setDisabled(0);
40
+ });
41
+ },
42
+
43
+ getInfo : function() {
44
+ return {
45
+ longname : 'Non editable elements',
46
+ author : 'Moxiecode Systems AB',
47
+ authorurl : 'http://tinymce.moxiecode.com',
48
+ infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable',
49
+ version : tinymce.majorVersion + "." + tinymce.minorVersion
50
+ };
51
+ },
52
+
53
+ _block : function(ed, e) {
54
+ var k = e.keyCode;
55
+
56
+ // Don't block arrow keys, pg up/down, and F1-F12
57
+ if ((k > 32 && k < 41) || (k > 111 && k < 124))
58
+ return;
59
+
60
+ return Event.cancel(e);
61
+ },
62
+
63
+ _setDisabled : function(s) {
64
+ var t = this, ed = t.editor;
65
+
66
+ tinymce.each(ed.controlManager.controls, function(c) {
67
+ c.setDisabled(s);
68
+ });
69
+
70
+ if (s !== t.disabled) {
71
+ if (s) {
72
+ ed.onKeyDown.addToTop(t._block);
73
+ ed.onKeyPress.addToTop(t._block);
74
+ ed.onKeyUp.addToTop(t._block);
75
+ ed.onPaste.addToTop(t._block);
76
+ } else {
77
+ ed.onKeyDown.remove(t._block);
78
+ ed.onKeyPress.remove(t._block);
79
+ ed.onKeyUp.remove(t._block);
80
+ ed.onPaste.remove(t._block);
81
+ }
82
+
83
+ t.disabled = s;
84
+ }
85
+ }
86
+ });
87
+
88
+ // Register plugin
89
+ tinymce.PluginManager.add('noneditable', tinymce.plugins.NonEditablePlugin);
90
+ })();
@@ -0,0 +1 @@
1
+ .mcePageBreak {display:block;border:0;width:100%;height:12px;border-top:1px dotted #ccc;margin-top:15px;background:#fff url(../img/pagebreak.gif) no-repeat center top;}
@@ -0,0 +1 @@
1
+ (function(){tinymce.create("tinymce.plugins.PageBreakPlugin",{init:function(b,d){var f='<img src="'+d+'/img/trans.gif" class="mcePageBreak mceItemNoResize" />',a="mcePageBreak",c=b.getParam("pagebreak_separator","<!-- pagebreak -->"),e;e=new RegExp(c.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(g){return"\\"+g}),"g");b.addCommand("mcePageBreak",function(){b.execCommand("mceInsertContent",0,f)});b.addButton("pagebreak",{title:"pagebreak.desc",cmd:a});b.onInit.add(function(){if(b.settings.content_css!==false){b.dom.loadCSS(d+"/css/content.css")}if(b.theme.onResolveName){b.theme.onResolveName.add(function(g,h){if(h.node.nodeName=="IMG"&&b.dom.hasClass(h.node,a)){h.name="pagebreak"}})}});b.onClick.add(function(g,h){h=h.target;if(h.nodeName==="IMG"&&g.dom.hasClass(h,a)){g.selection.select(h)}});b.onNodeChange.add(function(h,g,i){g.setActive("pagebreak",i.nodeName==="IMG"&&h.dom.hasClass(i,a))});b.onBeforeSetContent.add(function(g,h){h.content=h.content.replace(e,f)});b.onPostProcess.add(function(g,h){if(h.get){h.content=h.content.replace(/<img[^>]+>/g,function(i){if(i.indexOf('class="mcePageBreak')!==-1){i=c}return i})}})},getInfo:function(){return{longname:"PageBreak",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/pagebreak",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("pagebreak",tinymce.plugins.PageBreakPlugin)})();
@@ -0,0 +1,77 @@
1
+ /**
2
+ * editor_plugin_src.js
3
+ *
4
+ * Copyright 2009, Moxiecode Systems AB
5
+ * Released under LGPL License.
6
+ *
7
+ * License: http://tinymce.moxiecode.com/license
8
+ * Contributing: http://tinymce.moxiecode.com/contributing
9
+ */
10
+
11
+ (function() {
12
+ tinymce.create('tinymce.plugins.PageBreakPlugin', {
13
+ init : function(ed, url) {
14
+ var pb = '<img src="' + url + '/img/trans.gif" class="mcePageBreak mceItemNoResize" />', cls = 'mcePageBreak', sep = ed.getParam('pagebreak_separator', '<!-- pagebreak -->'), pbRE;
15
+
16
+ pbRE = new RegExp(sep.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g, function(a) {return '\\' + a;}), 'g');
17
+
18
+ // Register commands
19
+ ed.addCommand('mcePageBreak', function() {
20
+ ed.execCommand('mceInsertContent', 0, pb);
21
+ });
22
+
23
+ // Register buttons
24
+ ed.addButton('pagebreak', {title : 'pagebreak.desc', cmd : cls});
25
+
26
+ ed.onInit.add(function() {
27
+ if (ed.settings.content_css !== false)
28
+ ed.dom.loadCSS(url + "/css/content.css");
29
+
30
+ if (ed.theme.onResolveName) {
31
+ ed.theme.onResolveName.add(function(th, o) {
32
+ if (o.node.nodeName == 'IMG' && ed.dom.hasClass(o.node, cls))
33
+ o.name = 'pagebreak';
34
+ });
35
+ }
36
+ });
37
+
38
+ ed.onClick.add(function(ed, e) {
39
+ e = e.target;
40
+
41
+ if (e.nodeName === 'IMG' && ed.dom.hasClass(e, cls))
42
+ ed.selection.select(e);
43
+ });
44
+
45
+ ed.onNodeChange.add(function(ed, cm, n) {
46
+ cm.setActive('pagebreak', n.nodeName === 'IMG' && ed.dom.hasClass(n, cls));
47
+ });
48
+
49
+ ed.onBeforeSetContent.add(function(ed, o) {
50
+ o.content = o.content.replace(pbRE, pb);
51
+ });
52
+
53
+ ed.onPostProcess.add(function(ed, o) {
54
+ if (o.get)
55
+ o.content = o.content.replace(/<img[^>]+>/g, function(im) {
56
+ if (im.indexOf('class="mcePageBreak') !== -1)
57
+ im = sep;
58
+
59
+ return im;
60
+ });
61
+ });
62
+ },
63
+
64
+ getInfo : function() {
65
+ return {
66
+ longname : 'PageBreak',
67
+ author : 'Moxiecode Systems AB',
68
+ authorurl : 'http://tinymce.moxiecode.com',
69
+ infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/pagebreak',
70
+ version : tinymce.majorVersion + "." + tinymce.minorVersion
71
+ };
72
+ }
73
+ });
74
+
75
+ // Register plugin
76
+ tinymce.PluginManager.add('pagebreak', tinymce.plugins.PageBreakPlugin);
77
+ })();
@@ -0,0 +1 @@
1
+ (function(){var c=tinymce.each,d=null,a={paste_auto_cleanup_on_paste:true,paste_block_drop:false,paste_retain_style_properties:"none",paste_strip_class_attributes:"mso",paste_remove_spans:false,paste_remove_styles:false,paste_remove_styles_if_webkit:true,paste_convert_middot_lists:true,paste_convert_headers_to_strong:false,paste_dialog_width:"450",paste_dialog_height:"400",paste_text_use_dialog:false,paste_text_sticky:false,paste_text_notifyalways:false,paste_text_linebreaktype:"p",paste_text_replacements:[[/\u2026/g,"..."],[/[\x93\x94\u201c\u201d]/g,'"'],[/[\x60\x91\x92\u2018\u2019]/g,"'"]]};function b(e,f){return e.getParam(f,a[f])}tinymce.create("tinymce.plugins.PastePlugin",{init:function(e,f){var g=this;g.editor=e;g.url=f;g.onPreProcess=new tinymce.util.Dispatcher(g);g.onPostProcess=new tinymce.util.Dispatcher(g);g.onPreProcess.add(g._preProcess);g.onPostProcess.add(g._postProcess);g.onPreProcess.add(function(j,k){e.execCallback("paste_preprocess",j,k)});g.onPostProcess.add(function(j,k){e.execCallback("paste_postprocess",j,k)});e.pasteAsPlainText=false;function i(l,j){var k=e.dom;g.onPreProcess.dispatch(g,l);l.node=k.create("div",0,l.content);g.onPostProcess.dispatch(g,l);l.content=e.serializer.serialize(l.node,{getInner:1});if((!j)&&(e.pasteAsPlainText)){g._insertPlainText(e,k,l.content);if(!b(e,"paste_text_sticky")){e.pasteAsPlainText=false;e.controlManager.setActive("pastetext",false)}}else{if(/<(p|h[1-6]|ul|ol)/.test(l.content)){g._insertBlockContent(e,k,l.content)}else{g._insert(l.content)}}}e.addCommand("mceInsertClipboardContent",function(j,k){i(k,true)});if(!b(e,"paste_text_use_dialog")){e.addCommand("mcePasteText",function(k,j){var l=tinymce.util.Cookie;e.pasteAsPlainText=!e.pasteAsPlainText;e.controlManager.setActive("pastetext",e.pasteAsPlainText);if((e.pasteAsPlainText)&&(!l.get("tinymcePasteText"))){if(b(e,"paste_text_sticky")){e.windowManager.alert("Paste is now in plain text mode. Click again to toggle back to regular paste mode. After you paste something you will be returned to regular paste mode.")}else{e.windowManager.alert("Paste is now in plain text mode. Click again to toggle back to regular paste mode.")}if(!b(e,"paste_text_notifyalways")){l.set("tinymcePasteText","1",new Date(new Date().getFullYear()+1,12,31))}}})}e.addButton("pastetext",{title:"paste.paste_text_desc",cmd:"mcePasteText"});e.addButton("selectall",{title:"paste.selectall_desc",cmd:"selectall"});function h(s){var m,q,k,l=e.selection,p=e.dom,r=e.getBody(),j;if(p.get("_mcePaste")){return}m=p.add(r,"div",{id:"_mcePaste","class":"mcePaste"},"\uFEFF");if(r!=e.getDoc().body){j=p.getPos(e.selection.getStart(),r).y}else{j=r.scrollTop}p.setStyles(m,{position:"absolute",left:-10000,top:j,width:1,height:1,overflow:"hidden"});if(tinymce.isIE){k=p.doc.body.createTextRange();k.moveToElementText(m);k.execCommand("Paste");p.remove(m);if(m.innerHTML==="\uFEFF"){e.execCommand("mcePasteWord");s.preventDefault();return}i({content:m.innerHTML});return tinymce.dom.Event.cancel(s)}else{function o(n){n.preventDefault()}p.bind(e.getDoc(),"mousedown",o);p.bind(e.getDoc(),"keydown",o);q=e.selection.getRng();m=m.firstChild;k=e.getDoc().createRange();k.setStart(m,0);k.setEnd(m,1);l.setRng(k);window.setTimeout(function(){var t="",n=p.select("div.mcePaste");c(n,function(u){c(p.select("div.mcePaste",u),function(v){p.remove(v,1)});t+=(p.select("> span.Apple-style-span div",u)[0]||p.select("> span.Apple-style-span",u)[0]||u).innerHTML});c(n,function(u){p.remove(u)});if(q){l.setRng(q)}i({content:t});p.unbind(e.getDoc(),"mousedown",o);p.unbind(e.getDoc(),"keydown",o)},0)}}if(b(e,"paste_auto_cleanup_on_paste")){if(tinymce.isOpera||/Firefox\/2/.test(navigator.userAgent)){e.onKeyDown.add(function(j,k){if(((tinymce.isMac?k.metaKey:k.ctrlKey)&&k.keyCode==86)||(k.shiftKey&&k.keyCode==45)){h(k)}})}else{e.onPaste.addToTop(function(j,k){return h(k)})}}if(b(e,"paste_block_drop")){e.onInit.add(function(){e.dom.bind(e.getBody(),["dragend","dragover","draggesture","dragdrop","drop","drag"],function(j){j.preventDefault();j.stopPropagation();return false})})}g._legacySupport()},getInfo:function(){return{longname:"Paste text/word",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_preProcess:function(i,f){var l=this.editor,k=f.content,q=tinymce.grep,p=tinymce.explode,g=tinymce.trim,m,j;function e(h){c(h,function(o){if(o.constructor==RegExp){k=k.replace(o,"")}else{k=k.replace(o[0],o[1])}})}if(/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(k)||f.wordContent){f.wordContent=true;e([/^\s*(&nbsp;)+/gi,/(&nbsp;|<br[^>]*>)+\s*$/gi]);if(b(l,"paste_convert_headers_to_strong")){k=k.replace(/<p [^>]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi,"<p><strong>$1</strong></p>")}if(b(l,"paste_convert_middot_lists")){e([[/<!--\[if !supportLists\]-->/gi,"$&__MCE_ITEM__"],[/(<span[^>]+(?:mso-list:|:\s*symbol)[^>]+>)/gi,"$1__MCE_ITEM__"]])}e([/<!--[\s\S]+?-->/gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/&nbsp;/gi,"\u00a0"]]);do{m=k.length;k=k.replace(/(<[a-z][^>]*\s)(?:id|name|language|type|on\w+|\w+:\w+)=(?:"[^"]*"|\w+)\s?/gi,"$1")}while(m!=k.length);if(b(l,"paste_retain_style_properties").replace(/^none$/i,"").length==0){k=k.replace(/<\/?span[^>]*>/gi,"")}else{e([[/<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi,function(o,h){return(h.length>0)?h.replace(/./," ").slice(Math.floor(h.length/2)).split("").join("\u00a0"):""}],[/(<[a-z][^>]*)\sstyle="([^"]*)"/gi,function(u,h,t){var v=[],o=0,r=p(g(t).replace(/&quot;/gi,"'"),";");c(r,function(s){var w,y,z=p(s,":");function x(A){return A+((A!=="0")&&(/\d$/.test(A)))?"px":""}if(z.length==2){w=z[0].toLowerCase();y=z[1].toLowerCase();switch(w){case"mso-padding-alt":case"mso-padding-top-alt":case"mso-padding-right-alt":case"mso-padding-bottom-alt":case"mso-padding-left-alt":case"mso-margin-alt":case"mso-margin-top-alt":case"mso-margin-right-alt":case"mso-margin-bottom-alt":case"mso-margin-left-alt":case"mso-table-layout-alt":case"mso-height":case"mso-width":case"mso-vertical-align-alt":v[o++]=w.replace(/^mso-|-alt$/g,"")+":"+x(y);return;case"horiz-align":v[o++]="text-align:"+y;return;case"vert-align":v[o++]="vertical-align:"+y;return;case"font-color":case"mso-foreground":v[o++]="color:"+y;return;case"mso-background":case"mso-highlight":v[o++]="background:"+y;return;case"mso-default-height":v[o++]="min-height:"+x(y);return;case"mso-default-width":v[o++]="min-width:"+x(y);return;case"mso-padding-between-alt":v[o++]="border-collapse:separate;border-spacing:"+x(y);return;case"text-line-through":if((y=="single")||(y=="double")){v[o++]="text-decoration:line-through"}return;case"mso-zero-height":if(y=="yes"){v[o++]="display:none"}return}if(/^(mso|column|font-emph|lang|layout|line-break|list-image|nav|panose|punct|row|ruby|sep|size|src|tab-|table-border|text-(?!align|decor|indent|trans)|top-bar|version|vnd|word-break)/.test(w)){return}v[o++]=w+":"+z[1]}});if(o>0){return h+' style="'+v.join(";")+'"'}else{return h}}]])}}if(b(l,"paste_convert_headers_to_strong")){e([[/<h[1-6][^>]*>/gi,"<p><strong>"],[/<\/h[1-6][^>]*>/gi,"</strong></p>"]])}j=b(l,"paste_strip_class_attributes");if(j!=="none"){function n(r,o){if(j==="all"){return""}var h=q(p(o.replace(/^(["'])(.*)\1$/,"$2")," "),function(s){return(/^(?!mso)/i.test(s))});return h.length?' class="'+h.join(" ")+'"':""}k=k.replace(/ class="([^"]+)"/gi,n);k=k.replace(/ class=(\w+)/gi,n)}if(b(l,"paste_remove_spans")){k=k.replace(/<\/?span[^>]*>/gi,"")}f.content=k},_postProcess:function(h,j){var g=this,f=g.editor,i=f.dom,e;if(j.wordContent){c(i.select("a",j.node),function(k){if(!k.href||k.href.indexOf("#_Toc")!=-1){i.remove(k,1)}});if(b(f,"paste_convert_middot_lists")){g._convertLists(h,j)}e=b(f,"paste_retain_style_properties");if((tinymce.is(e,"string"))&&(e!=="all")&&(e!=="*")){e=tinymce.explode(e.replace(/^none$/i,""));c(i.select("*",j.node),function(n){var o={},l=0,m,p,k;if(e){for(m=0;m<e.length;m++){p=e[m];k=i.getStyle(n,p);if(k){o[p]=k;l++}}}i.setAttrib(n,"style","");if(e&&l>0){i.setStyles(n,o)}else{if(n.nodeName=="SPAN"&&!n.className){i.remove(n,true)}}})}}if(b(f,"paste_remove_styles")||(b(f,"paste_remove_styles_if_webkit")&&tinymce.isWebKit)){c(i.select("*[style]",j.node),function(k){k.removeAttribute("style");k.removeAttribute("_mce_style")})}else{if(tinymce.isWebKit){c(i.select("*",j.node),function(k){k.removeAttribute("_mce_style")})}}},_convertLists:function(h,f){var j=h.editor.dom,i,m,e=-1,g,n=[],l,k;c(j.select("p",f.node),function(u){var r,v="",t,s,o,q;for(r=u.firstChild;r&&r.nodeType==3;r=r.nextSibling){v+=r.nodeValue}v=u.innerHTML.replace(/<\/?\w+[^>]*>/gi,"").replace(/&nbsp;/g,"\u00a0");if(/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o]\s*\u00a0*/.test(v)){t="ul"}if(/^__MCE_ITEM__\s*\w+\.\s*\u00a0{2,}/.test(v)){t="ol"}if(t){g=parseFloat(u.style.marginLeft||0);if(g>e){n.push(g)}if(!i||t!=l){i=j.create(t);j.insertAfter(i,u)}else{if(g>e){i=m.appendChild(j.create(t))}else{if(g<e){o=tinymce.inArray(n,g);q=j.getParents(i.parentNode,t);i=q[q.length-1-o]||i}}}c(j.select("span",u),function(w){var p=w.innerHTML.replace(/<\/?\w+[^>]*>/gi,"");if(t=="ul"&&/^[\u2022\u00b7\u00a7\u00d8o]/.test(p)){j.remove(w)}else{if(/^[\s\S]*\w+\.(&nbsp;|\u00a0)*\s*/.test(p)){j.remove(w)}}});s=u.innerHTML;if(t=="ul"){s=u.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^[\u2022\u00b7\u00a7\u00d8o]\s*(&nbsp;|\u00a0)+\s*/,"")}else{s=u.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^\s*\w+\.(&nbsp;|\u00a0)+\s*/,"")}m=i.appendChild(j.create("li",0,s));j.remove(u);e=g;l=t}else{i=e=0}});k=f.node.innerHTML;if(k.indexOf("__MCE_ITEM__")!=-1){f.node.innerHTML=k.replace(/__MCE_ITEM__/g,"")}},_insertBlockContent:function(l,h,m){var f,j,g=l.selection,q,n,e,o,i,k="mce_marker";function p(t){var s;if(tinymce.isIE){s=l.getDoc().body.createTextRange();s.moveToElementText(t);s.collapse(false);s.select()}else{g.select(t,1);g.collapse(false)}}this._insert('<span id="'+k+'">&nbsp;</span>',1);j=h.get(k);f=h.getParent(j,"p,h1,h2,h3,h4,h5,h6,ul,ol,th,td");if(f&&!/TD|TH/.test(f.nodeName)){j=h.split(f,j);c(h.create("div",0,m).childNodes,function(r){q=j.parentNode.insertBefore(r.cloneNode(true),j)});p(q)}else{h.setOuterHTML(j,m);g.select(l.getBody(),1);g.collapse(0)}while(n=h.get(k)){h.remove(n)}n=g.getStart();e=h.getViewPort(l.getWin());o=l.dom.getPos(n).y;i=n.clientHeight;if(o<e.y||o+i>e.y+e.h){l.getDoc().body.scrollTop=o<e.y?o:o-e.h+25}},_insert:function(g,e){var f=this.editor;if(!f.selection.isCollapsed()){f.getDoc().execCommand("Delete",false,null)}f.execCommand(tinymce.isGecko?"insertHTML":"mceInsertContent",false,g,{skip_undo:e})},_insertPlainText:function(j,x,v){var t,u,l,k,r,e,p,f,n=j.getWin(),z=j.getDoc(),s=j.selection,m=tinymce.is,y=tinymce.inArray,g=b(j,"paste_text_linebreaktype"),o=b(j,"paste_text_replacements");function q(h){c(h,function(i){if(i.constructor==RegExp){v=v.replace(i,"")}else{v=v.replace(i[0],i[1])}})}if((typeof(v)==="string")&&(v.length>0)){if(!d){d=("34,quot,38,amp,39,apos,60,lt,62,gt,"+j.serializer.settings.entities).split(",")}if(/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(v)){q([/[\n\r]+/g])}else{q([/\r+/g])}q([[/<\/(?:p|h[1-6]|ul|ol|dl|table|div|blockquote|fieldset|pre|address|center)>/gi,"\n\n"],[/<br[^>]*>|<\/tr>/gi,"\n"],[/<\/t[dh]>\s*<t[dh][^>]*>/gi,"\t"],/<[a-z!\/?][^>]*>/gi,[/&nbsp;/gi," "],[/&(#\d+|[a-z0-9]{1,10});/gi,function(i,h){if(h.charAt(0)==="#"){return String.fromCharCode(h.slice(1))}else{return((i=y(d,h))>0)?String.fromCharCode(d[i-1]):" "}}],[/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi,"$1"],[/\n{3,}/g,"\n\n"],/^\s+|\s+$/g]);v=x.encode(v);if(!s.isCollapsed()){z.execCommand("Delete",false,null)}if(m(o,"array")||(m(o,"array"))){q(o)}else{if(m(o,"string")){q(new RegExp(o,"gi"))}}if(g=="none"){q([[/\n+/g," "]])}else{if(g=="br"){q([[/\n/g,"<br />"]])}else{q([/^\s+|\s+$/g,[/\n\n/g,"</p><p>"],[/\n/g,"<br />"]])}}if((l=v.indexOf("</p><p>"))!=-1){k=v.lastIndexOf("</p><p>");r=s.getNode();e=[];do{if(r.nodeType==1){if(r.nodeName=="TD"||r.nodeName=="BODY"){break}e[e.length]=r}}while(r=r.parentNode);if(e.length>0){p=v.substring(0,l);f="";for(t=0,u=e.length;t<u;t++){p+="</"+e[t].nodeName.toLowerCase()+">";f+="<"+e[e.length-t-1].nodeName.toLowerCase()+">"}if(l==k){v=p+f+v.substring(l+7)}else{v=p+v.substring(l+4,k+4)+f+v.substring(k+7)}}}j.execCommand("mceInsertRawHTML",false,v+'<span id="_plain_text_marker">&nbsp;</span>');window.setTimeout(function(){var h=x.get("_plain_text_marker"),B,i,A,w;s.select(h,false);z.execCommand("Delete",false,null);h=null;B=s.getStart();i=x.getViewPort(n);A=x.getPos(B).y;w=B.clientHeight;if((A<i.y)||(A+w>i.y+i.h)){z.body.scrollTop=A<i.y?A:A-i.h+25}},0)}},_legacySupport:function(){var f=this,e=f.editor;e.addCommand("mcePasteWord",function(){e.windowManager.open({file:f.url+"/pasteword.htm",width:parseInt(b(e,"paste_dialog_width")),height:parseInt(b(e,"paste_dialog_height")),inline:1})});if(b(e,"paste_text_use_dialog")){e.addCommand("mcePasteText",function(){e.windowManager.open({file:f.url+"/pastetext.htm",width:parseInt(b(e,"paste_dialog_width")),height:parseInt(b(e,"paste_dialog_height")),inline:1})})}e.addButton("pasteword",{title:"paste.paste_word_desc",cmd:"mcePasteWord"})}});tinymce.PluginManager.add("paste",tinymce.plugins.PastePlugin)})();
@@ -0,0 +1,929 @@
1
+ /**
2
+ * editor_plugin_src.js
3
+ *
4
+ * Copyright 2009, Moxiecode Systems AB
5
+ * Released under LGPL License.
6
+ *
7
+ * License: http://tinymce.moxiecode.com/license
8
+ * Contributing: http://tinymce.moxiecode.com/contributing
9
+ */
10
+
11
+ (function() {
12
+ var each = tinymce.each,
13
+ entities = null,
14
+ defs = {
15
+ paste_auto_cleanup_on_paste : true,
16
+ paste_block_drop : false,
17
+ paste_retain_style_properties : "none",
18
+ paste_strip_class_attributes : "mso",
19
+ paste_remove_spans : false,
20
+ paste_remove_styles : false,
21
+ paste_remove_styles_if_webkit : true,
22
+ paste_convert_middot_lists : true,
23
+ paste_convert_headers_to_strong : false,
24
+ paste_dialog_width : "450",
25
+ paste_dialog_height : "400",
26
+ paste_text_use_dialog : false,
27
+ paste_text_sticky : false,
28
+ paste_text_notifyalways : false,
29
+ paste_text_linebreaktype : "p",
30
+ paste_text_replacements : [
31
+ [/\u2026/g, "..."],
32
+ [/[\x93\x94\u201c\u201d]/g, '"'],
33
+ [/[\x60\x91\x92\u2018\u2019]/g, "'"]
34
+ ]
35
+ };
36
+
37
+ function getParam(ed, name) {
38
+ return ed.getParam(name, defs[name]);
39
+ }
40
+
41
+ tinymce.create('tinymce.plugins.PastePlugin', {
42
+ init : function(ed, url) {
43
+ var t = this;
44
+
45
+ t.editor = ed;
46
+ t.url = url;
47
+
48
+ // Setup plugin events
49
+ t.onPreProcess = new tinymce.util.Dispatcher(t);
50
+ t.onPostProcess = new tinymce.util.Dispatcher(t);
51
+
52
+ // Register default handlers
53
+ t.onPreProcess.add(t._preProcess);
54
+ t.onPostProcess.add(t._postProcess);
55
+
56
+ // Register optional preprocess handler
57
+ t.onPreProcess.add(function(pl, o) {
58
+ ed.execCallback('paste_preprocess', pl, o);
59
+ });
60
+
61
+ // Register optional postprocess
62
+ t.onPostProcess.add(function(pl, o) {
63
+ ed.execCallback('paste_postprocess', pl, o);
64
+ });
65
+
66
+ // Initialize plain text flag
67
+ ed.pasteAsPlainText = false;
68
+
69
+ // This function executes the process handlers and inserts the contents
70
+ // force_rich overrides plain text mode set by user, important for pasting with execCommand
71
+ function process(o, force_rich) {
72
+ var dom = ed.dom;
73
+
74
+ // Execute pre process handlers
75
+ t.onPreProcess.dispatch(t, o);
76
+
77
+ // Create DOM structure
78
+ o.node = dom.create('div', 0, o.content);
79
+
80
+ // Execute post process handlers
81
+ t.onPostProcess.dispatch(t, o);
82
+
83
+ // Serialize content
84
+ o.content = ed.serializer.serialize(o.node, {getInner : 1});
85
+
86
+ // Plain text option active?
87
+ if ((!force_rich) && (ed.pasteAsPlainText)) {
88
+ t._insertPlainText(ed, dom, o.content);
89
+
90
+ if (!getParam(ed, "paste_text_sticky")) {
91
+ ed.pasteAsPlainText = false;
92
+ ed.controlManager.setActive("pastetext", false);
93
+ }
94
+ } else if (/<(p|h[1-6]|ul|ol)/.test(o.content)) {
95
+ // Handle insertion of contents containing block elements separately
96
+ t._insertBlockContent(ed, dom, o.content);
97
+ } else {
98
+ t._insert(o.content);
99
+ }
100
+ }
101
+
102
+ // Add command for external usage
103
+ ed.addCommand('mceInsertClipboardContent', function(u, o) {
104
+ process(o, true);
105
+ });
106
+
107
+ if (!getParam(ed, "paste_text_use_dialog")) {
108
+ ed.addCommand('mcePasteText', function(u, v) {
109
+ var cookie = tinymce.util.Cookie;
110
+
111
+ ed.pasteAsPlainText = !ed.pasteAsPlainText;
112
+ ed.controlManager.setActive('pastetext', ed.pasteAsPlainText);
113
+
114
+ if ((ed.pasteAsPlainText) && (!cookie.get("tinymcePasteText"))) {
115
+ if (getParam(ed, "paste_text_sticky")) {
116
+ ed.windowManager.alert("Paste is now in plain text mode. Click again to toggle back to regular paste mode. After you paste something you will be returned to regular paste mode.");
117
+ } else {
118
+ ed.windowManager.alert("Paste is now in plain text mode. Click again to toggle back to regular paste mode.");
119
+ }
120
+
121
+ if (!getParam(ed, "paste_text_notifyalways")) {
122
+ cookie.set("tinymcePasteText", "1", new Date(new Date().getFullYear() + 1, 12, 31))
123
+ }
124
+ }
125
+ });
126
+ }
127
+
128
+ ed.addButton('pastetext', {title: 'paste.paste_text_desc', cmd: 'mcePasteText'});
129
+ ed.addButton('selectall', {title: 'paste.selectall_desc', cmd: 'selectall'});
130
+
131
+ // This function grabs the contents from the clipboard by adding a
132
+ // hidden div and placing the caret inside it and after the browser paste
133
+ // is done it grabs that contents and processes that
134
+ function grabContent(e) {
135
+ var n, or, rng, sel = ed.selection, dom = ed.dom, body = ed.getBody(), posY;
136
+
137
+ if (dom.get('_mcePaste'))
138
+ return;
139
+
140
+ // Create container to paste into
141
+ n = dom.add(body, 'div', {id : '_mcePaste', 'class' : 'mcePaste'}, '\uFEFF');
142
+
143
+ // If contentEditable mode we need to find out the position of the closest element
144
+ if (body != ed.getDoc().body)
145
+ posY = dom.getPos(ed.selection.getStart(), body).y;
146
+ else
147
+ posY = body.scrollTop;
148
+
149
+ // Styles needs to be applied after the element is added to the document since WebKit will otherwise remove all styles
150
+ dom.setStyles(n, {
151
+ position : 'absolute',
152
+ left : -10000,
153
+ top : posY,
154
+ width : 1,
155
+ height : 1,
156
+ overflow : 'hidden'
157
+ });
158
+
159
+ if (tinymce.isIE) {
160
+ // Select the container
161
+ rng = dom.doc.body.createTextRange();
162
+ rng.moveToElementText(n);
163
+ rng.execCommand('Paste');
164
+
165
+ // Remove container
166
+ dom.remove(n);
167
+
168
+ // Check if the contents was changed, if it wasn't then clipboard extraction failed probably due
169
+ // to IE security settings so we pass the junk though better than nothing right
170
+ if (n.innerHTML === '\uFEFF') {
171
+ ed.execCommand('mcePasteWord');
172
+ e.preventDefault();
173
+ return;
174
+ }
175
+
176
+ // Process contents
177
+ process({content : n.innerHTML});
178
+
179
+ // Block the real paste event
180
+ return tinymce.dom.Event.cancel(e);
181
+ } else {
182
+ function block(e) {
183
+ e.preventDefault();
184
+ };
185
+
186
+ // Block mousedown and click to prevent selection change
187
+ dom.bind(ed.getDoc(), 'mousedown', block);
188
+ dom.bind(ed.getDoc(), 'keydown', block);
189
+
190
+ or = ed.selection.getRng();
191
+
192
+ // Move caret into hidden div
193
+ n = n.firstChild;
194
+ rng = ed.getDoc().createRange();
195
+ rng.setStart(n, 0);
196
+ rng.setEnd(n, 1);
197
+ sel.setRng(rng);
198
+
199
+ // Wait a while and grab the pasted contents
200
+ window.setTimeout(function() {
201
+ var h = '', nl = dom.select('div.mcePaste');
202
+
203
+ // WebKit will split the div into multiple ones so this will loop through then all and join them to get the whole HTML string
204
+ each(nl, function(n) {
205
+ // WebKit duplicates the divs so we need to remove them
206
+ each(dom.select('div.mcePaste', n), function(n) {
207
+ dom.remove(n, 1);
208
+ });
209
+
210
+ // Contents in WebKit is sometimes wrapped in a apple style span so we need to grab it from that one
211
+ h += (dom.select('> span.Apple-style-span div', n)[0] || dom.select('> span.Apple-style-span', n)[0] || n).innerHTML;
212
+ });
213
+
214
+ // Remove the nodes
215
+ each(nl, function(n) {
216
+ dom.remove(n);
217
+ });
218
+
219
+ // Restore the old selection
220
+ if (or)
221
+ sel.setRng(or);
222
+
223
+ process({content : h});
224
+
225
+ // Unblock events ones we got the contents
226
+ dom.unbind(ed.getDoc(), 'mousedown', block);
227
+ dom.unbind(ed.getDoc(), 'keydown', block);
228
+ }, 0);
229
+ }
230
+ }
231
+
232
+ // Check if we should use the new auto process method
233
+ if (getParam(ed, "paste_auto_cleanup_on_paste")) {
234
+ // Is it's Opera or older FF use key handler
235
+ if (tinymce.isOpera || /Firefox\/2/.test(navigator.userAgent)) {
236
+ ed.onKeyDown.add(function(ed, e) {
237
+ if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45))
238
+ grabContent(e);
239
+ });
240
+ } else {
241
+ // Grab contents on paste event on Gecko and WebKit
242
+ ed.onPaste.addToTop(function(ed, e) {
243
+ return grabContent(e);
244
+ });
245
+ }
246
+ }
247
+
248
+ // Block all drag/drop events
249
+ if (getParam(ed, "paste_block_drop")) {
250
+ ed.onInit.add(function() {
251
+ ed.dom.bind(ed.getBody(), ['dragend', 'dragover', 'draggesture', 'dragdrop', 'drop', 'drag'], function(e) {
252
+ e.preventDefault();
253
+ e.stopPropagation();
254
+
255
+ return false;
256
+ });
257
+ });
258
+ }
259
+
260
+ // Add legacy support
261
+ t._legacySupport();
262
+ },
263
+
264
+ getInfo : function() {
265
+ return {
266
+ longname : 'Paste text/word',
267
+ author : 'Moxiecode Systems AB',
268
+ authorurl : 'http://tinymce.moxiecode.com',
269
+ infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste',
270
+ version : tinymce.majorVersion + "." + tinymce.minorVersion
271
+ };
272
+ },
273
+
274
+ _preProcess : function(pl, o) {
275
+ //console.log('Before preprocess:' + o.content);
276
+
277
+ var ed = this.editor,
278
+ h = o.content,
279
+ grep = tinymce.grep,
280
+ explode = tinymce.explode,
281
+ trim = tinymce.trim,
282
+ len, stripClass;
283
+
284
+ function process(items) {
285
+ each(items, function(v) {
286
+ // Remove or replace
287
+ if (v.constructor == RegExp)
288
+ h = h.replace(v, '');
289
+ else
290
+ h = h.replace(v[0], v[1]);
291
+ });
292
+ }
293
+
294
+ // Detect Word content and process it more aggressive
295
+ if (/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(h) || o.wordContent) {
296
+ o.wordContent = true; // Mark the pasted contents as word specific content
297
+ //console.log('Word contents detected.');
298
+
299
+ // Process away some basic content
300
+ process([
301
+ /^\s*(&nbsp;)+/gi, // &nbsp; entities at the start of contents
302
+ /(&nbsp;|<br[^>]*>)+\s*$/gi // &nbsp; entities at the end of contents
303
+ ]);
304
+
305
+ if (getParam(ed, "paste_convert_headers_to_strong")) {
306
+ h = h.replace(/<p [^>]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi, "<p><strong>$1</strong></p>");
307
+ }
308
+
309
+ if (getParam(ed, "paste_convert_middot_lists")) {
310
+ process([
311
+ [/<!--\[if !supportLists\]-->/gi, '$&__MCE_ITEM__'], // Convert supportLists to a list item marker
312
+ [/(<span[^>]+(?:mso-list:|:\s*symbol)[^>]+>)/gi, '$1__MCE_ITEM__'] // Convert mso-list and symbol spans to item markers
313
+ ]);
314
+ }
315
+
316
+ process([
317
+ // Word comments like conditional comments etc
318
+ /<!--[\s\S]+?-->/gi,
319
+
320
+ // Remove comments, scripts (e.g., msoShowComment), XML tag, VML content, MS Office namespaced tags, and a few other tags
321
+ /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,
322
+
323
+ // Convert <s> into <strike> for line-though
324
+ [/<(\/?)s>/gi, "<$1strike>"],
325
+
326
+ // Replace nsbp entites to char since it's easier to handle
327
+ [/&nbsp;/gi, "\u00a0"]
328
+ ]);
329
+
330
+ // Remove bad attributes, with or without quotes, ensuring that attribute text is really inside a tag.
331
+ // If JavaScript had a RegExp look-behind, we could have integrated this with the last process() array and got rid of the loop. But alas, it does not, so we cannot.
332
+ do {
333
+ len = h.length;
334
+ h = h.replace(/(<[a-z][^>]*\s)(?:id|name|language|type|on\w+|\w+:\w+)=(?:"[^"]*"|\w+)\s?/gi, "$1");
335
+ } while (len != h.length);
336
+
337
+ // Remove all spans if no styles is to be retained
338
+ if (getParam(ed, "paste_retain_style_properties").replace(/^none$/i, "").length == 0) {
339
+ h = h.replace(/<\/?span[^>]*>/gi, "");
340
+ } else {
341
+ // We're keeping styles, so at least clean them up.
342
+ // CSS Reference: http://msdn.microsoft.com/en-us/library/aa155477.aspx
343
+
344
+ process([
345
+ // Convert <span style="mso-spacerun:yes">___</span> to string of alternating breaking/non-breaking spaces of same length
346
+ [/<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi,
347
+ function(str, spaces) {
348
+ return (spaces.length > 0)? spaces.replace(/./, " ").slice(Math.floor(spaces.length/2)).split("").join("\u00a0") : "";
349
+ }
350
+ ],
351
+
352
+ // Examine all styles: delete junk, transform some, and keep the rest
353
+ [/(<[a-z][^>]*)\sstyle="([^"]*)"/gi,
354
+ function(str, tag, style) {
355
+ var n = [],
356
+ i = 0,
357
+ s = explode(trim(style).replace(/&quot;/gi, "'"), ";");
358
+
359
+ // Examine each style definition within the tag's style attribute
360
+ each(s, function(v) {
361
+ var name, value,
362
+ parts = explode(v, ":");
363
+
364
+ function ensureUnits(v) {
365
+ return v + ((v !== "0") && (/\d$/.test(v)))? "px" : "";
366
+ }
367
+
368
+ if (parts.length == 2) {
369
+ name = parts[0].toLowerCase();
370
+ value = parts[1].toLowerCase();
371
+
372
+ // Translate certain MS Office styles into their CSS equivalents
373
+ switch (name) {
374
+ case "mso-padding-alt":
375
+ case "mso-padding-top-alt":
376
+ case "mso-padding-right-alt":
377
+ case "mso-padding-bottom-alt":
378
+ case "mso-padding-left-alt":
379
+ case "mso-margin-alt":
380
+ case "mso-margin-top-alt":
381
+ case "mso-margin-right-alt":
382
+ case "mso-margin-bottom-alt":
383
+ case "mso-margin-left-alt":
384
+ case "mso-table-layout-alt":
385
+ case "mso-height":
386
+ case "mso-width":
387
+ case "mso-vertical-align-alt":
388
+ n[i++] = name.replace(/^mso-|-alt$/g, "") + ":" + ensureUnits(value);
389
+ return;
390
+
391
+ case "horiz-align":
392
+ n[i++] = "text-align:" + value;
393
+ return;
394
+
395
+ case "vert-align":
396
+ n[i++] = "vertical-align:" + value;
397
+ return;
398
+
399
+ case "font-color":
400
+ case "mso-foreground":
401
+ n[i++] = "color:" + value;
402
+ return;
403
+
404
+ case "mso-background":
405
+ case "mso-highlight":
406
+ n[i++] = "background:" + value;
407
+ return;
408
+
409
+ case "mso-default-height":
410
+ n[i++] = "min-height:" + ensureUnits(value);
411
+ return;
412
+
413
+ case "mso-default-width":
414
+ n[i++] = "min-width:" + ensureUnits(value);
415
+ return;
416
+
417
+ case "mso-padding-between-alt":
418
+ n[i++] = "border-collapse:separate;border-spacing:" + ensureUnits(value);
419
+ return;
420
+
421
+ case "text-line-through":
422
+ if ((value == "single") || (value == "double")) {
423
+ n[i++] = "text-decoration:line-through";
424
+ }
425
+ return;
426
+
427
+ case "mso-zero-height":
428
+ if (value == "yes") {
429
+ n[i++] = "display:none";
430
+ }
431
+ return;
432
+ }
433
+
434
+ // Eliminate all MS Office style definitions that have no CSS equivalent by examining the first characters in the name
435
+ if (/^(mso|column|font-emph|lang|layout|line-break|list-image|nav|panose|punct|row|ruby|sep|size|src|tab-|table-border|text-(?!align|decor|indent|trans)|top-bar|version|vnd|word-break)/.test(name)) {
436
+ return;
437
+ }
438
+
439
+ // If it reached this point, it must be a valid CSS style
440
+ n[i++] = name + ":" + parts[1]; // Lower-case name, but keep value case
441
+ }
442
+ });
443
+
444
+ // If style attribute contained any valid styles the re-write it; otherwise delete style attribute.
445
+ if (i > 0) {
446
+ return tag + ' style="' + n.join(';') + '"';
447
+ } else {
448
+ return tag;
449
+ }
450
+ }
451
+ ]
452
+ ]);
453
+ }
454
+ }
455
+
456
+ // Replace headers with <strong>
457
+ if (getParam(ed, "paste_convert_headers_to_strong")) {
458
+ process([
459
+ [/<h[1-6][^>]*>/gi, "<p><strong>"],
460
+ [/<\/h[1-6][^>]*>/gi, "</strong></p>"]
461
+ ]);
462
+ }
463
+
464
+ // Class attribute options are: leave all as-is ("none"), remove all ("all"), or remove only those starting with mso ("mso").
465
+ // Note:- paste_strip_class_attributes: "none", verify_css_classes: true is also a good variation.
466
+ stripClass = getParam(ed, "paste_strip_class_attributes");
467
+
468
+ if (stripClass !== "none") {
469
+ function removeClasses(match, g1) {
470
+ if (stripClass === "all")
471
+ return '';
472
+
473
+ var cls = grep(explode(g1.replace(/^(["'])(.*)\1$/, "$2"), " "),
474
+ function(v) {
475
+ return (/^(?!mso)/i.test(v));
476
+ }
477
+ );
478
+
479
+ return cls.length ? ' class="' + cls.join(" ") + '"' : '';
480
+ };
481
+
482
+ h = h.replace(/ class="([^"]+)"/gi, removeClasses);
483
+ h = h.replace(/ class=(\w+)/gi, removeClasses);
484
+ }
485
+
486
+ // Remove spans option
487
+ if (getParam(ed, "paste_remove_spans")) {
488
+ h = h.replace(/<\/?span[^>]*>/gi, "");
489
+ }
490
+
491
+ //console.log('After preprocess:' + h);
492
+
493
+ o.content = h;
494
+ },
495
+
496
+ /**
497
+ * Various post process items.
498
+ */
499
+ _postProcess : function(pl, o) {
500
+ var t = this, ed = t.editor, dom = ed.dom, styleProps;
501
+
502
+ if (o.wordContent) {
503
+ // Remove named anchors or TOC links
504
+ each(dom.select('a', o.node), function(a) {
505
+ if (!a.href || a.href.indexOf('#_Toc') != -1)
506
+ dom.remove(a, 1);
507
+ });
508
+
509
+ if (getParam(ed, "paste_convert_middot_lists")) {
510
+ t._convertLists(pl, o);
511
+ }
512
+
513
+ // Process styles
514
+ styleProps = getParam(ed, "paste_retain_style_properties"); // retained properties
515
+
516
+ // Process only if a string was specified and not equal to "all" or "*"
517
+ if ((tinymce.is(styleProps, "string")) && (styleProps !== "all") && (styleProps !== "*")) {
518
+ styleProps = tinymce.explode(styleProps.replace(/^none$/i, ""));
519
+
520
+ // Retains some style properties
521
+ each(dom.select('*', o.node), function(el) {
522
+ var newStyle = {}, npc = 0, i, sp, sv;
523
+
524
+ // Store a subset of the existing styles
525
+ if (styleProps) {
526
+ for (i = 0; i < styleProps.length; i++) {
527
+ sp = styleProps[i];
528
+ sv = dom.getStyle(el, sp);
529
+
530
+ if (sv) {
531
+ newStyle[sp] = sv;
532
+ npc++;
533
+ }
534
+ }
535
+ }
536
+
537
+ // Remove all of the existing styles
538
+ dom.setAttrib(el, 'style', '');
539
+
540
+ if (styleProps && npc > 0)
541
+ dom.setStyles(el, newStyle); // Add back the stored subset of styles
542
+ else // Remove empty span tags that do not have class attributes
543
+ if (el.nodeName == 'SPAN' && !el.className)
544
+ dom.remove(el, true);
545
+ });
546
+ }
547
+ }
548
+
549
+ // Remove all style information or only specifically on WebKit to avoid the style bug on that browser
550
+ if (getParam(ed, "paste_remove_styles") || (getParam(ed, "paste_remove_styles_if_webkit") && tinymce.isWebKit)) {
551
+ each(dom.select('*[style]', o.node), function(el) {
552
+ el.removeAttribute('style');
553
+ el.removeAttribute('_mce_style');
554
+ });
555
+ } else {
556
+ if (tinymce.isWebKit) {
557
+ // We need to compress the styles on WebKit since if you paste <img border="0" /> it will become <img border="0" style="... lots of junk ..." />
558
+ // Removing the mce_style that contains the real value will force the Serializer engine to compress the styles
559
+ each(dom.select('*', o.node), function(el) {
560
+ el.removeAttribute('_mce_style');
561
+ });
562
+ }
563
+ }
564
+ },
565
+
566
+ /**
567
+ * Converts the most common bullet and number formats in Office into a real semantic UL/LI list.
568
+ */
569
+ _convertLists : function(pl, o) {
570
+ var dom = pl.editor.dom, listElm, li, lastMargin = -1, margin, levels = [], lastType, html;
571
+
572
+ // Convert middot lists into real semantic lists
573
+ each(dom.select('p', o.node), function(p) {
574
+ var sib, val = '', type, html, idx, parents;
575
+
576
+ // Get text node value at beginning of paragraph
577
+ for (sib = p.firstChild; sib && sib.nodeType == 3; sib = sib.nextSibling)
578
+ val += sib.nodeValue;
579
+
580
+ val = p.innerHTML.replace(/<\/?\w+[^>]*>/gi, '').replace(/&nbsp;/g, '\u00a0');
581
+
582
+ // Detect unordered lists look for bullets
583
+ if (/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o]\s*\u00a0*/.test(val))
584
+ type = 'ul';
585
+
586
+ // Detect ordered lists 1., a. or ixv.
587
+ if (/^__MCE_ITEM__\s*\w+\.\s*\u00a0{2,}/.test(val))
588
+ type = 'ol';
589
+
590
+ // Check if node value matches the list pattern: o&nbsp;&nbsp;
591
+ if (type) {
592
+ margin = parseFloat(p.style.marginLeft || 0);
593
+
594
+ if (margin > lastMargin)
595
+ levels.push(margin);
596
+
597
+ if (!listElm || type != lastType) {
598
+ listElm = dom.create(type);
599
+ dom.insertAfter(listElm, p);
600
+ } else {
601
+ // Nested list element
602
+ if (margin > lastMargin) {
603
+ listElm = li.appendChild(dom.create(type));
604
+ } else if (margin < lastMargin) {
605
+ // Find parent level based on margin value
606
+ idx = tinymce.inArray(levels, margin);
607
+ parents = dom.getParents(listElm.parentNode, type);
608
+ listElm = parents[parents.length - 1 - idx] || listElm;
609
+ }
610
+ }
611
+
612
+ // Remove middot or number spans if they exists
613
+ each(dom.select('span', p), function(span) {
614
+ var html = span.innerHTML.replace(/<\/?\w+[^>]*>/gi, '');
615
+
616
+ // Remove span with the middot or the number
617
+ if (type == 'ul' && /^[\u2022\u00b7\u00a7\u00d8o]/.test(html))
618
+ dom.remove(span);
619
+ else if (/^[\s\S]*\w+\.(&nbsp;|\u00a0)*\s*/.test(html))
620
+ dom.remove(span);
621
+ });
622
+
623
+ html = p.innerHTML;
624
+
625
+ // Remove middot/list items
626
+ if (type == 'ul')
627
+ html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^[\u2022\u00b7\u00a7\u00d8o]\s*(&nbsp;|\u00a0)+\s*/, '');
628
+ else
629
+ html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^\s*\w+\.(&nbsp;|\u00a0)+\s*/, '');
630
+
631
+ // Create li and add paragraph data into the new li
632
+ li = listElm.appendChild(dom.create('li', 0, html));
633
+ dom.remove(p);
634
+
635
+ lastMargin = margin;
636
+ lastType = type;
637
+ } else
638
+ listElm = lastMargin = 0; // End list element
639
+ });
640
+
641
+ // Remove any left over makers
642
+ html = o.node.innerHTML;
643
+ if (html.indexOf('__MCE_ITEM__') != -1)
644
+ o.node.innerHTML = html.replace(/__MCE_ITEM__/g, '');
645
+ },
646
+
647
+ /**
648
+ * This method will split the current block parent and insert the contents inside the split position.
649
+ * This logic can be improved so text nodes at the start/end remain in the start/end block elements
650
+ */
651
+ _insertBlockContent : function(ed, dom, content) {
652
+ var parentBlock, marker, sel = ed.selection, last, elm, vp, y, elmHeight, markerId = 'mce_marker';
653
+
654
+ function select(n) {
655
+ var r;
656
+
657
+ if (tinymce.isIE) {
658
+ r = ed.getDoc().body.createTextRange();
659
+ r.moveToElementText(n);
660
+ r.collapse(false);
661
+ r.select();
662
+ } else {
663
+ sel.select(n, 1);
664
+ sel.collapse(false);
665
+ }
666
+ }
667
+
668
+ // Insert a marker for the caret position
669
+ this._insert('<span id="' + markerId + '">&nbsp;</span>', 1);
670
+ marker = dom.get(markerId);
671
+ parentBlock = dom.getParent(marker, 'p,h1,h2,h3,h4,h5,h6,ul,ol,th,td');
672
+
673
+ // If it's a parent block but not a table cell
674
+ if (parentBlock && !/TD|TH/.test(parentBlock.nodeName)) {
675
+ // Split parent block
676
+ marker = dom.split(parentBlock, marker);
677
+
678
+ // Insert nodes before the marker
679
+ each(dom.create('div', 0, content).childNodes, function(n) {
680
+ last = marker.parentNode.insertBefore(n.cloneNode(true), marker);
681
+ });
682
+
683
+ // Move caret after marker
684
+ select(last);
685
+ } else {
686
+ dom.setOuterHTML(marker, content);
687
+ sel.select(ed.getBody(), 1);
688
+ sel.collapse(0);
689
+ }
690
+
691
+ // Remove marker if it's left
692
+ while (elm = dom.get(markerId))
693
+ dom.remove(elm);
694
+
695
+ // Get element, position and height
696
+ elm = sel.getStart();
697
+ vp = dom.getViewPort(ed.getWin());
698
+ y = ed.dom.getPos(elm).y;
699
+ elmHeight = elm.clientHeight;
700
+
701
+ // Is element within viewport if not then scroll it into view
702
+ if (y < vp.y || y + elmHeight > vp.y + vp.h)
703
+ ed.getDoc().body.scrollTop = y < vp.y ? y : y - vp.h + 25;
704
+ },
705
+
706
+ /**
707
+ * Inserts the specified contents at the caret position.
708
+ */
709
+ _insert : function(h, skip_undo) {
710
+ var ed = this.editor;
711
+
712
+ // First delete the contents seems to work better on WebKit
713
+ if (!ed.selection.isCollapsed())
714
+ ed.getDoc().execCommand('Delete', false, null);
715
+
716
+ // It's better to use the insertHTML method on Gecko since it will combine paragraphs correctly before inserting the contents
717
+ ed.execCommand(tinymce.isGecko ? 'insertHTML' : 'mceInsertContent', false, h, {skip_undo : skip_undo});
718
+ },
719
+
720
+ /**
721
+ * Instead of the old plain text method which tried to re-create a paste operation, the
722
+ * new approach adds a plain text mode toggle switch that changes the behavior of paste.
723
+ * This function is passed the same input that the regular paste plugin produces.
724
+ * It performs additional scrubbing and produces (and inserts) the plain text.
725
+ * This approach leverages all of the great existing functionality in the paste
726
+ * plugin, and requires minimal changes to add the new functionality.
727
+ * Speednet - June 2009
728
+ */
729
+ _insertPlainText : function(ed, dom, h) {
730
+ var i, len, pos, rpos, node, breakElms, before, after,
731
+ w = ed.getWin(),
732
+ d = ed.getDoc(),
733
+ sel = ed.selection,
734
+ is = tinymce.is,
735
+ inArray = tinymce.inArray,
736
+ linebr = getParam(ed, "paste_text_linebreaktype"),
737
+ rl = getParam(ed, "paste_text_replacements");
738
+
739
+ function process(items) {
740
+ each(items, function(v) {
741
+ if (v.constructor == RegExp)
742
+ h = h.replace(v, "");
743
+ else
744
+ h = h.replace(v[0], v[1]);
745
+ });
746
+ };
747
+
748
+ if ((typeof(h) === "string") && (h.length > 0)) {
749
+ if (!entities)
750
+ entities = ("34,quot,38,amp,39,apos,60,lt,62,gt," + ed.serializer.settings.entities).split(",");
751
+
752
+ // If HTML content with line-breaking tags, then remove all cr/lf chars because only tags will break a line
753
+ if (/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(h)) {
754
+ process([
755
+ /[\n\r]+/g
756
+ ]);
757
+ } else {
758
+ // Otherwise just get rid of carriage returns (only need linefeeds)
759
+ process([
760
+ /\r+/g
761
+ ]);
762
+ }
763
+
764
+ process([
765
+ [/<\/(?:p|h[1-6]|ul|ol|dl|table|div|blockquote|fieldset|pre|address|center)>/gi, "\n\n"], // Block tags get a blank line after them
766
+ [/<br[^>]*>|<\/tr>/gi, "\n"], // Single linebreak for <br /> tags and table rows
767
+ [/<\/t[dh]>\s*<t[dh][^>]*>/gi, "\t"], // Table cells get tabs betweem them
768
+ /<[a-z!\/?][^>]*>/gi, // Delete all remaining tags
769
+ [/&nbsp;/gi, " "], // Convert non-break spaces to regular spaces (remember, *plain text*)
770
+ [
771
+ // HTML entity
772
+ /&(#\d+|[a-z0-9]{1,10});/gi,
773
+
774
+ // Replace with actual character
775
+ function(e, s) {
776
+ if (s.charAt(0) === "#") {
777
+ return String.fromCharCode(s.slice(1));
778
+ }
779
+ else {
780
+ return ((e = inArray(entities, s)) > 0)? String.fromCharCode(entities[e-1]) : " ";
781
+ }
782
+ }
783
+ ],
784
+ [/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi, "$1"], // Cool little RegExp deletes whitespace around linebreak chars.
785
+ [/\n{3,}/g, "\n\n"], // Max. 2 consecutive linebreaks
786
+ /^\s+|\s+$/g // Trim the front & back
787
+ ]);
788
+
789
+ h = dom.encode(h);
790
+
791
+ // Delete any highlighted text before pasting
792
+ if (!sel.isCollapsed()) {
793
+ d.execCommand("Delete", false, null);
794
+ }
795
+
796
+ // Perform default or custom replacements
797
+ if (is(rl, "array") || (is(rl, "array"))) {
798
+ process(rl);
799
+ }
800
+ else if (is(rl, "string")) {
801
+ process(new RegExp(rl, "gi"));
802
+ }
803
+
804
+ // Treat paragraphs as specified in the config
805
+ if (linebr == "none") {
806
+ process([
807
+ [/\n+/g, " "]
808
+ ]);
809
+ }
810
+ else if (linebr == "br") {
811
+ process([
812
+ [/\n/g, "<br />"]
813
+ ]);
814
+ }
815
+ else {
816
+ process([
817
+ /^\s+|\s+$/g,
818
+ [/\n\n/g, "</p><p>"],
819
+ [/\n/g, "<br />"]
820
+ ]);
821
+ }
822
+
823
+ // This next piece of code handles the situation where we're pasting more than one paragraph of plain
824
+ // text, and we are pasting the content into the middle of a block node in the editor. The block
825
+ // node gets split at the selection point into "Para A" and "Para B" (for the purposes of explaining).
826
+ // The first paragraph of the pasted text is appended to "Para A", and the last paragraph of the
827
+ // pasted text is prepended to "Para B". Any other paragraphs of pasted text are placed between
828
+ // "Para A" and "Para B". This code solves a host of problems with the original plain text plugin and
829
+ // now handles styles correctly. (Pasting plain text into a styled paragraph is supposed to make the
830
+ // plain text take the same style as the existing paragraph.)
831
+ if ((pos = h.indexOf("</p><p>")) != -1) {
832
+ rpos = h.lastIndexOf("</p><p>");
833
+ node = sel.getNode();
834
+ breakElms = []; // Get list of elements to break
835
+
836
+ do {
837
+ if (node.nodeType == 1) {
838
+ // Don't break tables and break at body
839
+ if (node.nodeName == "TD" || node.nodeName == "BODY") {
840
+ break;
841
+ }
842
+
843
+ breakElms[breakElms.length] = node;
844
+ }
845
+ } while (node = node.parentNode);
846
+
847
+ // Are we in the middle of a block node?
848
+ if (breakElms.length > 0) {
849
+ before = h.substring(0, pos);
850
+ after = "";
851
+
852
+ for (i=0, len=breakElms.length; i<len; i++) {
853
+ before += "</" + breakElms[i].nodeName.toLowerCase() + ">";
854
+ after += "<" + breakElms[breakElms.length-i-1].nodeName.toLowerCase() + ">";
855
+ }
856
+
857
+ if (pos == rpos) {
858
+ h = before + after + h.substring(pos+7);
859
+ }
860
+ else {
861
+ h = before + h.substring(pos+4, rpos+4) + after + h.substring(rpos+7);
862
+ }
863
+ }
864
+ }
865
+
866
+ // Insert content at the caret, plus add a marker for repositioning the caret
867
+ ed.execCommand("mceInsertRawHTML", false, h + '<span id="_plain_text_marker">&nbsp;</span>');
868
+
869
+ // Reposition the caret to the marker, which was placed immediately after the inserted content.
870
+ // Needs to be done asynchronously (in window.setTimeout) or else it doesn't work in all browsers.
871
+ // The second part of the code scrolls the content up if the caret is positioned off-screen.
872
+ // This is only necessary for WebKit browsers, but it doesn't hurt to use for all.
873
+ window.setTimeout(function() {
874
+ var marker = dom.get('_plain_text_marker'),
875
+ elm, vp, y, elmHeight;
876
+
877
+ sel.select(marker, false);
878
+ d.execCommand("Delete", false, null);
879
+ marker = null;
880
+
881
+ // Get element, position and height
882
+ elm = sel.getStart();
883
+ vp = dom.getViewPort(w);
884
+ y = dom.getPos(elm).y;
885
+ elmHeight = elm.clientHeight;
886
+
887
+ // Is element within viewport if not then scroll it into view
888
+ if ((y < vp.y) || (y + elmHeight > vp.y + vp.h)) {
889
+ d.body.scrollTop = y < vp.y ? y : y - vp.h + 25;
890
+ }
891
+ }, 0);
892
+ }
893
+ },
894
+
895
+ /**
896
+ * This method will open the old style paste dialogs. Some users might want the old behavior but still use the new cleanup engine.
897
+ */
898
+ _legacySupport : function() {
899
+ var t = this, ed = t.editor;
900
+
901
+ // Register command(s) for backwards compatibility
902
+ ed.addCommand("mcePasteWord", function() {
903
+ ed.windowManager.open({
904
+ file: t.url + "/pasteword.htm",
905
+ width: parseInt(getParam(ed, "paste_dialog_width")),
906
+ height: parseInt(getParam(ed, "paste_dialog_height")),
907
+ inline: 1
908
+ });
909
+ });
910
+
911
+ if (getParam(ed, "paste_text_use_dialog")) {
912
+ ed.addCommand("mcePasteText", function() {
913
+ ed.windowManager.open({
914
+ file : t.url + "/pastetext.htm",
915
+ width: parseInt(getParam(ed, "paste_dialog_width")),
916
+ height: parseInt(getParam(ed, "paste_dialog_height")),
917
+ inline : 1
918
+ });
919
+ });
920
+ }
921
+
922
+ // Register button for backwards compatibility
923
+ ed.addButton("pasteword", {title : "paste.paste_word_desc", cmd : "mcePasteWord"});
924
+ }
925
+ });
926
+
927
+ // Register plugin
928
+ tinymce.PluginManager.add("paste", tinymce.plugins.PastePlugin);
929
+ })();