xmt_froala 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (203) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +2 -0
  5. data/app/assets/javascripts/xmt_froala.js +31 -0
  6. data/app/assets/stylesheets/xmt_froala.css +17 -0
  7. data/app/controllers/xmt_froala/application_controller.rb +5 -0
  8. data/app/controllers/xmt_froala/assets_controller.rb +94 -0
  9. data/app/models/xmt_froala/asset_uploader.rb +107 -0
  10. data/app/models/xmt_froala/file_uploader.rb +10 -0
  11. data/app/models/xmt_froala/flash_uploader.rb +10 -0
  12. data/app/models/xmt_froala/image_uploader.rb +10 -0
  13. data/app/models/xmt_froala/media_uploader.rb +10 -0
  14. data/config/routes.rb +6 -0
  15. data/lib/generators/xmt_froala/install/USAGE +10 -0
  16. data/lib/generators/xmt_froala/install/install_generator.rb +23 -0
  17. data/lib/generators/xmt_froala/install/templates/application.js +17 -0
  18. data/lib/generators/xmt_froala/install/templates/xmt_froala.rb +29 -0
  19. data/lib/generators/xmt_froala/migration/USAGE +14 -0
  20. data/lib/generators/xmt_froala/migration/migration_generator.rb +36 -0
  21. data/lib/generators/xmt_froala/migration/templates/migration/migration.rb +18 -0
  22. data/lib/generators/xmt_froala/migration/templates/models/active_record/xmt_froala/asset.rb +14 -0
  23. data/lib/generators/xmt_froala/migration/templates/models/active_record/xmt_froala/file.rb +3 -0
  24. data/lib/generators/xmt_froala/migration/templates/models/active_record/xmt_froala/flash.rb +3 -0
  25. data/lib/generators/xmt_froala/migration/templates/models/active_record/xmt_froala/image.rb +3 -0
  26. data/lib/generators/xmt_froala/migration/templates/models/active_record/xmt_froala/media.rb +3 -0
  27. data/lib/generators/xmt_froala/migration/templates/models/mongoid/xmt_froala/asset.rb +27 -0
  28. data/lib/generators/xmt_froala/migration/templates/models/mongoid/xmt_froala/file.rb +3 -0
  29. data/lib/generators/xmt_froala/migration/templates/models/mongoid/xmt_froala/flash.rb +3 -0
  30. data/lib/generators/xmt_froala/migration/templates/models/mongoid/xmt_froala/image.rb +3 -0
  31. data/lib/generators/xmt_froala/migration/templates/models/mongoid/xmt_froala/media.rb +3 -0
  32. data/lib/tasks/xmt_froala_tasks.rake +9 -0
  33. data/lib/xmt_froala.rb +65 -0
  34. data/lib/xmt_froala/active_record.rb +14 -0
  35. data/lib/xmt_froala/engine.rb +32 -0
  36. data/lib/xmt_froala/formtastic.rb +12 -0
  37. data/lib/xmt_froala/helper.rb +105 -0
  38. data/lib/xmt_froala/simple_form.rb +11 -0
  39. data/lib/xmt_froala/version.rb +3 -0
  40. data/vendor/assets/javascripts/xmt_froala/froala_editor.js +0 -0
  41. data/vendor/assets/javascripts/xmt_froala/languages/ar.js +318 -0
  42. data/vendor/assets/javascripts/xmt_froala/languages/bs.js +318 -0
  43. data/vendor/assets/javascripts/xmt_froala/languages/cs.js +318 -0
  44. data/vendor/assets/javascripts/xmt_froala/languages/da.js +318 -0
  45. data/vendor/assets/javascripts/xmt_froala/languages/de.js +318 -0
  46. data/vendor/assets/javascripts/xmt_froala/languages/en_ca.js +262 -0
  47. data/vendor/assets/javascripts/xmt_froala/languages/en_gb.js +262 -0
  48. data/vendor/assets/javascripts/xmt_froala/languages/es.js +318 -0
  49. data/vendor/assets/javascripts/xmt_froala/languages/et.js +318 -0
  50. data/vendor/assets/javascripts/xmt_froala/languages/fa.js +318 -0
  51. data/vendor/assets/javascripts/xmt_froala/languages/fi.js +318 -0
  52. data/vendor/assets/javascripts/xmt_froala/languages/fr.js +318 -0
  53. data/vendor/assets/javascripts/xmt_froala/languages/he.js +318 -0
  54. data/vendor/assets/javascripts/xmt_froala/languages/hr.js +318 -0
  55. data/vendor/assets/javascripts/xmt_froala/languages/hu.js +318 -0
  56. data/vendor/assets/javascripts/xmt_froala/languages/id.js +319 -0
  57. data/vendor/assets/javascripts/xmt_froala/languages/it.js +318 -0
  58. data/vendor/assets/javascripts/xmt_froala/languages/ja.js +318 -0
  59. data/vendor/assets/javascripts/xmt_froala/languages/ko.js +318 -0
  60. data/vendor/assets/javascripts/xmt_froala/languages/me.js +318 -0
  61. data/vendor/assets/javascripts/xmt_froala/languages/nb.js +318 -0
  62. data/vendor/assets/javascripts/xmt_froala/languages/nl.js +318 -0
  63. data/vendor/assets/javascripts/xmt_froala/languages/pl.js +318 -0
  64. data/vendor/assets/javascripts/xmt_froala/languages/pt_br.js +318 -0
  65. data/vendor/assets/javascripts/xmt_froala/languages/pt_pt.js +318 -0
  66. data/vendor/assets/javascripts/xmt_froala/languages/ro.js +319 -0
  67. data/vendor/assets/javascripts/xmt_froala/languages/ru.js +318 -0
  68. data/vendor/assets/javascripts/xmt_froala/languages/sk.js +318 -0
  69. data/vendor/assets/javascripts/xmt_froala/languages/sr.js +318 -0
  70. data/vendor/assets/javascripts/xmt_froala/languages/sv.js +318 -0
  71. data/vendor/assets/javascripts/xmt_froala/languages/th.js +318 -0
  72. data/vendor/assets/javascripts/xmt_froala/languages/tr.js +318 -0
  73. data/vendor/assets/javascripts/xmt_froala/languages/uk.js +318 -0
  74. data/vendor/assets/javascripts/xmt_froala/languages/vi.js +258 -0
  75. data/vendor/assets/javascripts/xmt_froala/languages/zh_cn.js +320 -0
  76. data/vendor/assets/javascripts/xmt_froala/languages/zh_tw.js +318 -0
  77. data/vendor/assets/javascripts/xmt_froala/plugins/align.js +139 -0
  78. data/vendor/assets/javascripts/xmt_froala/plugins/align.min.js +7 -0
  79. data/vendor/assets/javascripts/xmt_froala/plugins/char_counter.js +154 -0
  80. data/vendor/assets/javascripts/xmt_froala/plugins/char_counter.min.js +7 -0
  81. data/vendor/assets/javascripts/xmt_froala/plugins/code_beautifier.js +3270 -0
  82. data/vendor/assets/javascripts/xmt_froala/plugins/code_beautifier.min.js +7 -0
  83. data/vendor/assets/javascripts/xmt_froala/plugins/code_view.js +393 -0
  84. data/vendor/assets/javascripts/xmt_froala/plugins/code_view.min.js +7 -0
  85. data/vendor/assets/javascripts/xmt_froala/plugins/colors.js +492 -0
  86. data/vendor/assets/javascripts/xmt_froala/plugins/colors.min.js +7 -0
  87. data/vendor/assets/javascripts/xmt_froala/plugins/draggable.js +459 -0
  88. data/vendor/assets/javascripts/xmt_froala/plugins/draggable.min.js +7 -0
  89. data/vendor/assets/javascripts/xmt_froala/plugins/emoticons.js +509 -0
  90. data/vendor/assets/javascripts/xmt_froala/plugins/emoticons.min.js +7 -0
  91. data/vendor/assets/javascripts/xmt_froala/plugins/entities.js +121 -0
  92. data/vendor/assets/javascripts/xmt_froala/plugins/entities.min.js +7 -0
  93. data/vendor/assets/javascripts/xmt_froala/plugins/file.js +736 -0
  94. data/vendor/assets/javascripts/xmt_froala/plugins/file.min.js +239 -0
  95. data/vendor/assets/javascripts/xmt_froala/plugins/font_family.js +182 -0
  96. data/vendor/assets/javascripts/xmt_froala/plugins/font_family.min.js +7 -0
  97. data/vendor/assets/javascripts/xmt_froala/plugins/font_size.js +118 -0
  98. data/vendor/assets/javascripts/xmt_froala/plugins/font_size.min.js +7 -0
  99. data/vendor/assets/javascripts/xmt_froala/plugins/forms.js +430 -0
  100. data/vendor/assets/javascripts/xmt_froala/plugins/forms.min.js +7 -0
  101. data/vendor/assets/javascripts/xmt_froala/plugins/fullscreen.js +274 -0
  102. data/vendor/assets/javascripts/xmt_froala/plugins/fullscreen.min.js +7 -0
  103. data/vendor/assets/javascripts/xmt_froala/plugins/help.js +216 -0
  104. data/vendor/assets/javascripts/xmt_froala/plugins/help.min.js +7 -0
  105. data/vendor/assets/javascripts/xmt_froala/plugins/image.js +3323 -0
  106. data/vendor/assets/javascripts/xmt_froala/plugins/image.min.js +7 -0
  107. data/vendor/assets/javascripts/xmt_froala/plugins/image_manager.js +1056 -0
  108. data/vendor/assets/javascripts/xmt_froala/plugins/image_manager.min.js +7 -0
  109. data/vendor/assets/javascripts/xmt_froala/plugins/inline_style.js +94 -0
  110. data/vendor/assets/javascripts/xmt_froala/plugins/inline_style.min.js +7 -0
  111. data/vendor/assets/javascripts/xmt_froala/plugins/line_breaker.js +537 -0
  112. data/vendor/assets/javascripts/xmt_froala/plugins/line_breaker.min.js +7 -0
  113. data/vendor/assets/javascripts/xmt_froala/plugins/link.js +1157 -0
  114. data/vendor/assets/javascripts/xmt_froala/plugins/link.min.js +7 -0
  115. data/vendor/assets/javascripts/xmt_froala/plugins/lists.js +462 -0
  116. data/vendor/assets/javascripts/xmt_froala/plugins/lists.min.js +7 -0
  117. data/vendor/assets/javascripts/xmt_froala/plugins/paragraph_format.js +290 -0
  118. data/vendor/assets/javascripts/xmt_froala/plugins/paragraph_format.min.js +7 -0
  119. data/vendor/assets/javascripts/xmt_froala/plugins/paragraph_style.js +144 -0
  120. data/vendor/assets/javascripts/xmt_froala/plugins/paragraph_style.min.js +7 -0
  121. data/vendor/assets/javascripts/xmt_froala/plugins/plain_paste.js +96 -0
  122. data/vendor/assets/javascripts/xmt_froala/plugins/print.js +137 -0
  123. data/vendor/assets/javascripts/xmt_froala/plugins/print.min.js +7 -0
  124. data/vendor/assets/javascripts/xmt_froala/plugins/quick_format.js +89 -0
  125. data/vendor/assets/javascripts/xmt_froala/plugins/quick_insert.js +478 -0
  126. data/vendor/assets/javascripts/xmt_froala/plugins/quick_insert.min.js +7 -0
  127. data/vendor/assets/javascripts/xmt_froala/plugins/quote.js +141 -0
  128. data/vendor/assets/javascripts/xmt_froala/plugins/quote.min.js +7 -0
  129. data/vendor/assets/javascripts/xmt_froala/plugins/save.js +189 -0
  130. data/vendor/assets/javascripts/xmt_froala/plugins/save.min.js +7 -0
  131. data/vendor/assets/javascripts/xmt_froala/plugins/special_characters.js +781 -0
  132. data/vendor/assets/javascripts/xmt_froala/plugins/special_characters.min.js +7 -0
  133. data/vendor/assets/javascripts/xmt_froala/plugins/table.js +4194 -0
  134. data/vendor/assets/javascripts/xmt_froala/plugins/table.min.js +7 -0
  135. data/vendor/assets/javascripts/xmt_froala/plugins/url.js +194 -0
  136. data/vendor/assets/javascripts/xmt_froala/plugins/url.min.js +7 -0
  137. data/vendor/assets/javascripts/xmt_froala/plugins/video.js +2342 -0
  138. data/vendor/assets/javascripts/xmt_froala/plugins/video.min.js +7 -0
  139. data/vendor/assets/javascripts/xmt_froala/plugins/word_paste.js +1403 -0
  140. data/vendor/assets/javascripts/xmt_froala/plugins/word_paste.min.js +7 -0
  141. data/vendor/assets/javascripts/xmt_froala/third_party/embedly.js +543 -0
  142. data/vendor/assets/javascripts/xmt_froala/third_party/embedly.min.js +7 -0
  143. data/vendor/assets/javascripts/xmt_froala/third_party/image_aviary.js +163 -0
  144. data/vendor/assets/javascripts/xmt_froala/third_party/image_aviary.min.js +7 -0
  145. data/vendor/assets/javascripts/xmt_froala/third_party/spell_checker.js +222 -0
  146. data/vendor/assets/javascripts/xmt_froala/third_party/spell_checker.min.js +7 -0
  147. data/vendor/assets/javascripts/xmt_froala/xmt_froala.js +15172 -0
  148. data/vendor/assets/stylesheets/xmt_froala/css/font-awesome.css +2546 -0
  149. data/vendor/assets/stylesheets/xmt_froala/css/froala_editor.min.css +7 -0
  150. data/vendor/assets/stylesheets/xmt_froala/css/froala_editor.pkgd.css +2902 -0
  151. data/vendor/assets/stylesheets/xmt_froala/css/froala_editor.pkgd.min.css +7 -0
  152. data/vendor/assets/stylesheets/xmt_froala/css/froala_style.css +413 -0
  153. data/vendor/assets/stylesheets/xmt_froala/css/froala_style.min.css +7 -0
  154. data/vendor/assets/stylesheets/xmt_froala/css/plugins/char_counter.css +57 -0
  155. data/vendor/assets/stylesheets/xmt_froala/css/plugins/char_counter.min.css +7 -0
  156. data/vendor/assets/stylesheets/xmt_froala/css/plugins/code_view.css +112 -0
  157. data/vendor/assets/stylesheets/xmt_froala/css/plugins/code_view.min.css +7 -0
  158. data/vendor/assets/stylesheets/xmt_froala/css/plugins/colors.css +155 -0
  159. data/vendor/assets/stylesheets/xmt_froala/css/plugins/colors.min.css +7 -0
  160. data/vendor/assets/stylesheets/xmt_froala/css/plugins/draggable.css +43 -0
  161. data/vendor/assets/stylesheets/xmt_froala/css/plugins/draggable.min.css +7 -0
  162. data/vendor/assets/stylesheets/xmt_froala/css/plugins/emoticons.css +42 -0
  163. data/vendor/assets/stylesheets/xmt_froala/css/plugins/emoticons.min.css +7 -0
  164. data/vendor/assets/stylesheets/xmt_froala/css/plugins/file.css +146 -0
  165. data/vendor/assets/stylesheets/xmt_froala/css/plugins/file.min.css +7 -0
  166. data/vendor/assets/stylesheets/xmt_froala/css/plugins/fullscreen.css +28 -0
  167. data/vendor/assets/stylesheets/xmt_froala/css/plugins/fullscreen.min.css +7 -0
  168. data/vendor/assets/stylesheets/xmt_froala/css/plugins/help.css +52 -0
  169. data/vendor/assets/stylesheets/xmt_froala/css/plugins/help.min.css +7 -0
  170. data/vendor/assets/stylesheets/xmt_froala/css/plugins/image.css +244 -0
  171. data/vendor/assets/stylesheets/xmt_froala/css/plugins/image.min.css +7 -0
  172. data/vendor/assets/stylesheets/xmt_froala/css/plugins/image_manager.css +266 -0
  173. data/vendor/assets/stylesheets/xmt_froala/css/plugins/image_manager.min.css +7 -0
  174. data/vendor/assets/stylesheets/xmt_froala/css/plugins/line_breaker.css +37 -0
  175. data/vendor/assets/stylesheets/xmt_froala/css/plugins/line_breaker.min.css +7 -0
  176. data/vendor/assets/stylesheets/xmt_froala/css/plugins/quick_insert.css +70 -0
  177. data/vendor/assets/stylesheets/xmt_froala/css/plugins/quick_insert.min.css +7 -0
  178. data/vendor/assets/stylesheets/xmt_froala/css/plugins/special_characters.css +51 -0
  179. data/vendor/assets/stylesheets/xmt_froala/css/plugins/special_characters.min.css +7 -0
  180. data/vendor/assets/stylesheets/xmt_froala/css/plugins/table.css +181 -0
  181. data/vendor/assets/stylesheets/xmt_froala/css/plugins/table.min.css +7 -0
  182. data/vendor/assets/stylesheets/xmt_froala/css/plugins/video.css +231 -0
  183. data/vendor/assets/stylesheets/xmt_froala/css/plugins/video.min.css +7 -0
  184. data/vendor/assets/stylesheets/xmt_froala/css/themes/dark.css +1281 -0
  185. data/vendor/assets/stylesheets/xmt_froala/css/themes/dark.min.css +7 -0
  186. data/vendor/assets/stylesheets/xmt_froala/css/themes/gray.css +1281 -0
  187. data/vendor/assets/stylesheets/xmt_froala/css/themes/gray.min.css +7 -0
  188. data/vendor/assets/stylesheets/xmt_froala/css/themes/red.css +1281 -0
  189. data/vendor/assets/stylesheets/xmt_froala/css/themes/red.min.css +7 -0
  190. data/vendor/assets/stylesheets/xmt_froala/css/themes/royal.css +1281 -0
  191. data/vendor/assets/stylesheets/xmt_froala/css/themes/royal.min.css +7 -0
  192. data/vendor/assets/stylesheets/xmt_froala/css/third_party/embedly.css +64 -0
  193. data/vendor/assets/stylesheets/xmt_froala/css/third_party/embedly.min.css +7 -0
  194. data/vendor/assets/stylesheets/xmt_froala/css/third_party/spell_checker.css +72 -0
  195. data/vendor/assets/stylesheets/xmt_froala/css/third_party/spell_checker.min.css +7 -0
  196. data/vendor/assets/stylesheets/xmt_froala/css/xmt_froala.css +1423 -0
  197. data/vendor/assets/stylesheets/xmt_froala/fonts/FontAwesome.otf +0 -0
  198. data/vendor/assets/stylesheets/xmt_froala/fonts/fontawesome-webfont.eot +0 -0
  199. data/vendor/assets/stylesheets/xmt_froala/fonts/fontawesome-webfont.svg +2671 -0
  200. data/vendor/assets/stylesheets/xmt_froala/fonts/fontawesome-webfont.ttf +0 -0
  201. data/vendor/assets/stylesheets/xmt_froala/fonts/fontawesome-webfont.woff +0 -0
  202. data/vendor/assets/stylesheets/xmt_froala/fonts/fontawesome-webfont.woff2 +0 -0
  203. metadata +273 -0
@@ -0,0 +1,7 @@
1
+ /*!
2
+ * froala_editor v2.8.1 (https://www.froala.com/wysiwyg-editor)
3
+ * License https://froala.com/wysiwyg-editor/terms/
4
+ * Copyright 2014-2018 Froala Labs
5
+ */
6
+
7
+ !function(i){"function"==typeof define&&define.amd?define(["jquery"],i):"object"==typeof module&&module.exports?module.exports=function(e,t){return t===undefined&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),i(t)}:i(window.jQuery)}(function(G){G.extend(G.FE.POPUP_TEMPLATES,{"video.insert":"[_BUTTONS_][_BY_URL_LAYER_][_EMBED_LAYER_][_UPLOAD_LAYER_][_PROGRESS_BAR_]","video.edit":"[_BUTTONS_]","video.size":"[_BUTTONS_][_SIZE_LAYER_]"}),G.extend(G.FE.DEFAULTS,{videoAllowedTypes:["mp4","webm","ogg"],videoAllowedProviders:[".*"],videoDefaultAlign:"center",videoDefaultDisplay:"block",videoDefaultWidth:600,videoEditButtons:["videoReplace","videoRemove","|","videoDisplay","videoAlign","videoSize"],videoInsertButtons:["videoBack","|","videoByURL","videoEmbed","videoUpload"],videoMaxSize:52428800,videoMove:!0,videoResize:!0,videoSizeButtons:["videoBack","|"],videoSplitHTML:!1,videoTextNear:!0,videoUpload:!0,videoUploadMethod:"POST",videoUploadParam:"file",videoUploadParams:{},videoUploadToS3:!1,videoUploadURL:"https://i.froala.com/upload"}),G.FE.VIDEO_PROVIDERS=[{test_regex:/^.*((youtu.be)|(youtube.com))\/((v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))?\??v?=?([^#\&\?]*).*/,url_regex:/(?:https?:\/\/)?(?:www\.)?(?:m\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=|embed\/)?([0-9a-zA-Z_\-]+)(.+)?/g,url_text:"https://www.youtube.com/embed/$1",html:'<iframe width="640" height="360" src="{url}?wmode=opaque" frameborder="0" allowfullscreen></iframe>',provider:"youtube"},{test_regex:/^.*(?:vimeo.com)\/(?:channels(\/\w+\/)?|groups\/*\/videos\/\u200b\d+\/|video\/|)(\d+)(?:$|\/|\?)/,url_regex:/(?:https?:\/\/)?(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/(?:[^\/]*)\/videos\/|album\/(?:\d+)\/video\/|video\/|)(\d+)(?:[a-zA-Z0-9_\-]+)?/i,url_text:"https://player.vimeo.com/video/$1",html:'<iframe width="640" height="360" src="{url}" frameborder="0" allowfullscreen></iframe>',provider:"vimeo"},{test_regex:/^.+(dailymotion.com|dai.ly)\/(video|hub)?\/?([^_]+)[^#]*(#video=([^_&]+))?/,url_regex:/(?:https?:\/\/)?(?:www\.)?(?:dailymotion\.com|dai\.ly)\/(?:video|hub)?\/?(.+)/g,url_text:"https://www.dailymotion.com/embed/video/$1",html:'<iframe width="640" height="360" src="{url}" frameborder="0" allowfullscreen></iframe>',provider:"dailymotion"},{test_regex:/^.+(screen.yahoo.com)\/[^_&]+/,url_regex:"",url_text:"",html:'<iframe width="640" height="360" src="{url}?format=embed" frameborder="0" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true" allowtransparency="true"></iframe>',provider:"yahoo"},{test_regex:/^.+(rutube.ru)\/[^_&]+/,url_regex:/(?:https?:\/\/)?(?:www\.)?(?:rutube\.ru)\/(?:video)?\/?(.+)/g,url_text:"https://rutube.ru/play/embed/$1",html:'<iframe width="640" height="360" src="{url}" frameborder="0" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true" allowtransparency="true"></iframe>',provider:"rutube"},{test_regex:/^(?:.+)vidyard.com\/(?:watch)?\/?([^.&/]+)\/?(?:[^_.&]+)?/,url_regex:/^(?:.+)vidyard.com\/(?:watch)?\/?([^.&/]+)\/?(?:[^_.&]+)?/g,url_text:"https://play.vidyard.com/$1",html:'<iframe width="640" height="360" src="{url}" frameborder="0" allowfullscreen></iframe>',provider:"vidyard"}],G.FE.VIDEO_EMBED_REGEX=/^\W*((<iframe.*><\/iframe>)|(<embed.*>))\W*$/i,G.FE.PLUGINS.video=function(v){var a,f,p,u,o,i,d=2,l=3,c=4,h=5,g=6,r={};function m(){var e=v.popups.get("video.insert");e.find(".fr-video-by-url-layer input").val("").trigger("change");var t=e.find(".fr-video-embed-layer textarea");t.val("").trigger("change"),(t=e.find(".fr-video-upload-layer input")).val("").trigger("change")}function s(){var e=v.popups.get("video.edit");if(e||(e=function(){var e="";if(0<v.opts.videoEditButtons.length){e+='<div class="fr-buttons">',e+=v.button.buildList(v.opts.videoEditButtons);var t={buttons:e+="</div>"},i=v.popups.create("video.edit",t);return v.events.$on(v.$wp,"scroll.video-edit",function(){u&&v.popups.isVisible("video.edit")&&(v.events.disableBlur(),A(u))}),i}return!1}()),e){v.popups.setContainer("video.edit",v.$sc),v.popups.refresh("video.edit");var t=u.find("iframe, embed, video"),i=t.offset().left+t.outerWidth()/2,o=t.offset().top+t.outerHeight();v.popups.show("video.edit",i,o,t.outerHeight())}}function n(e){if(e)return v.popups.onRefresh("video.insert",m),v.popups.onHide("image.insert",K),!0;var t="";v.opts.videoUpload||v.opts.videoInsertButtons.splice(v.opts.videoInsertButtons.indexOf("videoUpload"),1),1<v.opts.videoInsertButtons.length&&(t='<div class="fr-buttons">'+v.button.buildList(v.opts.videoInsertButtons)+"</div>");var i,o="",r=v.opts.videoInsertButtons.indexOf("videoUpload"),s=v.opts.videoInsertButtons.indexOf("videoByURL"),n=v.opts.videoInsertButtons.indexOf("videoEmbed");0<=s&&(i=" fr-active",(r<s&&0<=r||n<s&&0<=n)&&(i=""),o='<div class="fr-video-by-url-layer fr-layer'+i+'" id="fr-video-by-url-layer-'+v.id+'"><div class="fr-input-line"><input id="fr-video-by-url-layer-text-'+v.id+'" type="text" placeholder="'+v.language.translate("Paste in a video URL")+'" tabIndex="1" aria-required="true"></div><div class="fr-action-buttons"><button type="button" class="fr-command fr-submit" data-cmd="videoInsertByURL" tabIndex="2" role="button">'+v.language.translate("Insert")+"</button></div></div>");var a="";0<=n&&(i=" fr-active",(r<n&&0<=r||s<n&&0<=s)&&(i=""),a='<div class="fr-video-embed-layer fr-layer'+i+'" id="fr-video-embed-layer-'+v.id+'"><div class="fr-input-line"><textarea id="fr-video-embed-layer-text'+v.id+'" type="text" placeholder="'+v.language.translate("Embedded Code")+'" tabIndex="1" aria-required="true" rows="5"></textarea></div><div class="fr-action-buttons"><button type="button" class="fr-command fr-submit" data-cmd="videoInsertEmbed" tabIndex="2" role="button">'+v.language.translate("Insert")+"</button></div></div>");var d="";0<=r&&(i=" fr-active",(n<r&&0<=n||s<r&&0<=s)&&(i=""),d='<div class="fr-video-upload-layer fr-layer'+i+'" id="fr-video-upload-layer-'+v.id+'"><strong>'+v.language.translate("Drop video")+"</strong><br>("+v.language.translate("or click")+')<div class="fr-form"><input type="file" accept="video/'+v.opts.videoAllowedTypes.join(", video/").toLowerCase()+'" tabIndex="-1" aria-labelledby="fr-video-upload-layer-'+v.id+'" role="button"></div></div>');var l={buttons:t,by_url_layer:o,embed_layer:a,upload_layer:d,progress_bar:'<div class="fr-video-progress-bar-layer fr-layer"><h3 tabIndex="-1" class="fr-message">Uploading</h3><div class="fr-loader"><span class="fr-progress"></span></div><div class="fr-action-buttons"><button type="button" class="fr-command fr-dismiss" data-cmd="videoDismissError" tabIndex="2" role="button">OK</button></div></div>'},f=v.popups.create("video.insert",l);return function(o){v.events.$on(o,"dragover dragenter",".fr-video-upload-layer",function(){return G(this).addClass("fr-drop"),!1},!0),v.events.$on(o,"dragleave dragend",".fr-video-upload-layer",function(){return G(this).removeClass("fr-drop"),!1},!0),v.events.$on(o,"drop",".fr-video-upload-layer",function(e){e.preventDefault(),e.stopPropagation(),G(this).removeClass("fr-drop");var t=e.originalEvent.dataTransfer;if(t&&t.files){var i=o.data("instance")||v;i.events.disableBlur(),i.video.upload(t.files),i.events.enableBlur()}},!0),v.helpers.isIOS()&&v.events.$on(o,"touchstart",'.fr-video-upload-layer input[type="file"]',function(){G(this).trigger("click")},!0);v.events.$on(o,"change",'.fr-video-upload-layer input[type="file"]',function(){if(this.files){var e=o.data("instance")||v;e.events.disableBlur(),o.find("input:focus").blur(),e.events.enableBlur(),e.video.upload(this.files)}G(this).val("")},!0)}(f),f}function b(e){v.events.focus(!0),v.selection.restore();var t=!1;u&&(X(),t=!0),v.html.insert('<span contenteditable="false" draggable="true" class="fr-jiv fr-video">'+e+"</span>",!1,v.opts.videoSplitHTML),v.popups.hide("video.insert");var i=v.$el.find(".fr-jiv");i.removeClass("fr-jiv"),W(i,v.opts.videoDefaultDisplay,v.opts.videoDefaultAlign),i.toggleClass("fr-draggable",v.opts.videoMove),v.events.trigger(t?"video.replaced":"video.inserted",[i])}function y(){var e=G(this);v.popups.hide("video.insert"),e.removeClass("fr-uploading"),e.parent().next().is("br")&&e.parent().next().remove(),A(e.parent()),v.events.trigger("video.loaded",[e.parent()])}function E(a,e,d,l,f){v.edit.off(),_("Loading video"),e&&(a=v.helpers.sanitizeURL(a));w("Loading video"),function(){var e,t;if(l){v.undo.canDo()||l.find("video").hasClass("fr-uploading")||v.undo.saveStep();var i=l.find("video").data("fr-old-src"),o=l.data("fr-replaced");l.data("fr-replaced",!1),v.$wp?((e=l.clone()).find("video").removeData("fr-old-src").removeClass("fr-uploading"),e.find("video").off("canplay"),i&&l.find("video").attr("src",i),l.replaceWith(e)):e=l;for(var r=e.find("video").get(0).attributes,s=0;s<r.length;s++){var n=r[s];0===n.nodeName.indexOf("data-")&&e.find("video").removeAttr(n.nodeName)}if(void 0!==d)for(t in d)d.hasOwnProperty(t)&&"link"!=t&&e.find("video").attr("data-"+t,d[t]);e.find("video").on("canplay",y),e.find("video").attr("src",a),v.edit.on(),k(),v.undo.saveStep(),v.$el.blur(),v.events.trigger(o?"video.replaced":"video.inserted",[e,f])}else e=function(e,t,i){var o,r="";if(t&&void 0!==t)for(o in t)t.hasOwnProperty(o)&&"link"!=o&&(r+=" data-"+o+'="'+t[o]+'"');var s=v.opts.videoDefaultWidth;s&&"auto"!=s&&(s+="px");var n=G('<span contenteditable="false" draggable="true" class="fr-video fr-dv'+v.opts.videoDefaultDisplay[0]+("center"!=v.opts.videoDefaultAlign?" fr-fv"+v.opts.videoDefaultAlign[0]:"")+'"><video src="'+e+'" '+r+(s?' style="width: '+s+';" ':"")+" controls>"+v.language.translate("Your browser does not support HTML5 video.")+"</video></span>");n.toggleClass("fr-draggable",v.opts.videoMove),v.edit.on(),v.events.focus(!0),v.selection.restore(),v.undo.saveStep(),v.opts.videoSplitHTML?v.markers.split():v.markers.insert(),v.html.wrap();var a=v.$el.find(".fr-marker");return v.node.isLastSibling(a)&&a.parent().hasClass("fr-deletable")&&a.insertAfter(a.parent()),a.replaceWith(n),v.selection.clear(),n.find("video").get(0).readyState>n.find("video").get(0).HAVE_FUTURE_DATA||v.helpers.isIOS()?i.call(n.find("video").get(0)):n.find("video").on("canplaythrough load",i),n}(a,d,y),k(),v.undo.saveStep(),v.events.trigger("video.inserted",[e,f])}()}function w(e){var t=v.popups.get("video.insert");if(t||(t=n()),t.find(".fr-layer.fr-active").removeClass("fr-active").addClass("fr-pactive"),t.find(".fr-video-progress-bar-layer").addClass("fr-active"),t.find(".fr-buttons").hide(),u){var i=u.find("video");v.popups.setContainer("video.insert",v.$sc);var o=i.offset().left+i.width()/2,r=i.offset().top+i.height();v.popups.show("video.insert",o,r,i.outerHeight())}void 0===e&&_(v.language.translate("Uploading"),0)}function C(e){var t=v.popups.get("video.insert");if(t&&(t.find(".fr-layer.fr-pactive").addClass("fr-active").removeClass("fr-pactive"),t.find(".fr-video-progress-bar-layer").removeClass("fr-active"),t.find(".fr-buttons").show(),e||v.$el.find("video.fr-error").length)){if(v.events.focus(),v.$el.find("video.fr-error").length&&(v.$el.find("video.fr-error").parent().remove(),v.undo.saveStep(),v.undo.run(),v.undo.dropRedo()),!v.$wp&&u){var i=u;z(!0),v.selection.setAfter(i.find("video").get(0)),v.selection.restore()}v.popups.hide("video.insert")}}function _(e,t){var i=v.popups.get("video.insert");if(i){var o=i.find(".fr-video-progress-bar-layer");o.find("h3").text(e+(t?" "+t+"%":"")),o.removeClass("fr-error"),t?(o.find("div").removeClass("fr-indeterminate"),o.find("div > span").css("width",t+"%")):o.find("div").addClass("fr-indeterminate")}}function A(e){O.call(e.get(0))}function x(e){_("Loading video");var t=this.status,i=this.response,o=this.responseXML,r=this.responseText;try{if(v.opts.videoUploadToS3)if(201==t){var s=function(e){try{var t=G(e).find("Location").text(),i=G(e).find("Key").text();return!1===v.events.trigger("video.uploadedToS3",[t,i,e],!0)?(v.edit.on(),!1):t}catch(o){return M(c,e),!1}}(o);s&&E(s,!1,[],e,i||o)}else M(c,i||o);else if(200<=t&&t<300){var n=function(e){try{if(!1===v.events.trigger("video.uploaded",[e],!0))return v.edit.on(),!1;var t=JSON.parse(e);return t.link?t:(M(d,e),!1)}catch(i){return M(c,e),!1}}(r);n&&E(n.link,!1,n,e,i||r)}else M(l,i||r)}catch(a){M(c,i||r)}}function S(){M(c,this.response||this.responseText||this.responseXML)}function R(e){if(e.lengthComputable){var t=e.loaded/e.total*100|0;_(v.language.translate("Uploading"),t)}}function D(){v.edit.on(),C(!0)}function U(e){if(!v.core.sameInstance(p))return!0;e.preventDefault(),e.stopPropagation();var t=e.pageX||(e.originalEvent.touches?e.originalEvent.touches[0].pageX:null),i=e.pageY||(e.originalEvent.touches?e.originalEvent.touches[0].pageY:null);if(!t||!i)return!1;if("mousedown"==e.type){var o=v.$oel.get(0).ownerDocument,r=o.defaultView||o.parentWindow,s=!1;try{s=r.location!=r.parent.location&&!(r.$&&r.$.FE)}catch(n){}s&&r.frameElement&&(t+=v.helpers.getPX(G(r.frameElement).offset().left)+r.frameElement.clientLeft,i=e.clientY+v.helpers.getPX(G(r.frameElement).offset().top)+r.frameElement.clientTop)}v.undo.canDo()||v.undo.saveStep(),(f=G(this)).data("start-x",t),f.data("start-y",i),a.show(),v.popups.hideAll(),L()}function I(e){if(!v.core.sameInstance(p))return!0;if(f){e.preventDefault();var t=e.pageX||(e.originalEvent.touches?e.originalEvent.touches[0].pageX:null),i=e.pageY||(e.originalEvent.touches?e.originalEvent.touches[0].pageY:null);if(!t||!i)return!1;var o=f.data("start-x"),r=f.data("start-y");f.data("start-x",t),f.data("start-y",i);var s=t-o,n=i-r,a=u.find("iframe, embed, video"),d=a.width(),l=a.height();(f.hasClass("fr-hnw")||f.hasClass("fr-hsw"))&&(s=0-s),(f.hasClass("fr-hnw")||f.hasClass("fr-hne"))&&(n=0-n),a.css("width",d+s),a.css("height",l+n),a.removeAttr("width"),a.removeAttr("height"),F()}}function $(e){if(!v.core.sameInstance(p))return!0;f&&u&&(e&&e.stopPropagation(),f=null,a.hide(),F(),s(),v.undo.saveStep())}function t(e){return'<div class="fr-handler fr-h'+e+'"></div>'}function B(e,t,i,o){return e.pageX=t,e.pageY=t,U.call(this,e),e.pageX=e.pageX+i*Math.floor(Math.pow(1.1,o)),e.pageY=e.pageY+i*Math.floor(Math.pow(1.1,o)),I.call(this,e),$.call(this,e),++o}function k(){var e,t=Array.prototype.slice.call(v.el.querySelectorAll("video, .fr-video > *")),i=[];for(e=0;e<t.length;e++)i.push(t[e].getAttribute("src")),G(t[e]).toggleClass("fr-draggable",v.opts.videoMove),""===t[e].getAttribute("class")&&t[e].removeAttribute("class"),""===t[e].getAttribute("style")&&t[e].removeAttribute("style");if(o)for(e=0;e<o.length;e++)i.indexOf(o[e].getAttribute("src"))<0&&v.events.trigger("video.removed",[G(o[e])]);o=t}function F(){p||function(){var e;if(v.shared.$video_resizer?(p=v.shared.$video_resizer,a=v.shared.$vid_overlay,v.events.on("destroy",function(){p.removeClass("fr-active").appendTo(G("body:first"))},!0)):(v.shared.$video_resizer=G('<div class="fr-video-resizer"></div>'),p=v.shared.$video_resizer,v.events.$on(p,"mousedown",function(e){e.stopPropagation()},!0),v.opts.videoResize&&(p.append(t("nw")+t("ne")+t("sw")+t("se")),v.shared.$vid_overlay=G('<div class="fr-video-overlay"></div>'),a=v.shared.$vid_overlay,e=p.get(0).ownerDocument,G(e).find("body:first").append(a))),v.events.on("shared.destroy",function(){p.html("").removeData().remove(),p=null,v.opts.videoResize&&(a.remove(),a=null)},!0),v.helpers.isMobile()||v.events.$on(G(v.o_win),"resize.video",function(){z(!0)}),v.opts.videoResize){e=p.get(0).ownerDocument,v.events.$on(p,v._mousedown,".fr-handler",U),v.events.$on(G(e),v._mousemove,I),v.events.$on(G(e.defaultView||e.parentWindow),v._mouseup,$),v.events.$on(a,"mouseleave",$);var o=1,r=null,s=0;v.events.on("keydown",function(e){if(u){var t=-1!=navigator.userAgent.indexOf("Mac OS X")?e.metaKey:e.ctrlKey,i=e.which;(i!==r||200<e.timeStamp-s)&&(o=1),(i==G.FE.KEYCODE.EQUALS||v.browser.mozilla&&i==G.FE.KEYCODE.FF_EQUALS)&&t&&!e.altKey?o=B.call(this,e,1,1,o):(i==G.FE.KEYCODE.HYPHEN||v.browser.mozilla&&i==G.FE.KEYCODE.FF_HYPHEN)&&t&&!e.altKey&&(o=B.call(this,e,2,-1,o)),r=i,s=e.timeStamp}}),v.events.on("keyup",function(){o=1})}}(),(v.$wp||v.$sc).append(p),p.data("instance",v);var e=u.find("iframe, embed, video");p.css("top",(v.opts.iframe?e.offset().top-1:e.offset().top-v.$wp.offset().top-1)+v.$wp.scrollTop()).css("left",(v.opts.iframe?e.offset().left-1:e.offset().left-v.$wp.offset().left-1)+v.$wp.scrollLeft()).css("width",e.get(0).getBoundingClientRect().width).css("height",e.get(0).getBoundingClientRect().height).addClass("fr-active")}function O(e){if(e&&"touchend"==e.type&&i)return!0;if(e&&v.edit.isDisabled())return e.stopPropagation(),e.preventDefault(),!1;if(v.edit.isDisabled())return!1;for(var t=0;t<G.FE.INSTANCES.length;t++)G.FE.INSTANCES[t]!=v&&G.FE.INSTANCES[t].events.trigger("video.hideResizer");v.toolbar.disable(),v.helpers.isMobile()&&(v.events.disableBlur(),v.$el.blur(),v.events.enableBlur()),v.$el.find(".fr-video.fr-active").removeClass("fr-active"),(u=G(this)).addClass("fr-active"),v.opts.iframe&&v.size.syncIframe(),q(),F(),s(),v.selection.clear(),v.button.bulkRefresh(),v.events.trigger("image.hideResizer")}function z(e){u&&(v.shared.vid_exit_flag||!0===e)&&(p.removeClass("fr-active"),v.toolbar.enable(),u.removeClass("fr-active"),u=null,L())}function e(){v.shared.vid_exit_flag=!0}function L(){v.shared.vid_exit_flag=!1}function P(e){var t=e.originalEvent.dataTransfer;if(t&&t.files&&t.files.length){var i=t.files[0];if(i&&i.type&&-1!==i.type.indexOf("video")){if(!v.opts.videoUpload)return e.preventDefault(),e.stopPropagation(),!1;v.markers.remove(),v.markers.insertAtPoint(e.originalEvent),v.$el.find(".fr-marker").replaceWith(G.FE.MARKERS),v.popups.hideAll();var o=v.popups.get("video.insert");return o||(o=n()),v.popups.setContainer("video.insert",v.$sc),v.popups.show("video.insert",e.originalEvent.pageX,e.originalEvent.pageY),w(),0<=v.opts.videoAllowedTypes.indexOf(i.type.replace(/video\//g,""))?T(t.files):M(g),e.preventDefault(),e.stopPropagation(),!1}}}function T(e){if(void 0!==e&&0<e.length){if(!1===v.events.trigger("video.beforeUpload",[e]))return!1;var t,i=e[0];if(i.size>v.opts.videoMaxSize)return M(h),!1;if(v.opts.videoAllowedTypes.indexOf(i.type.replace(/video\//g,""))<0)return M(g),!1;if(v.drag_support.formdata&&(t=v.drag_support.formdata?new FormData:null),t){var o;if(!1!==v.opts.videoUploadToS3)for(o in t.append("key",v.opts.videoUploadToS3.keyStart+(new Date).getTime()+"-"+(i.name||"untitled")),t.append("success_action_status","201"),t.append("X-Requested-With","xhr"),t.append("Content-Type",i.type),v.opts.videoUploadToS3.params)v.opts.videoUploadToS3.params.hasOwnProperty(o)&&t.append(o,v.opts.videoUploadToS3.params[o]);for(o in v.opts.videoUploadParams)v.opts.videoUploadParams.hasOwnProperty(o)&&t.append(o,v.opts.videoUploadParams[o]);t.append(v.opts.videoUploadParam,i);var r=v.opts.videoUploadURL;v.opts.videoUploadToS3&&(r=v.opts.videoUploadToS3.uploadURL?v.opts.videoUploadToS3.uploadURL:"https://"+v.opts.videoUploadToS3.region+".amazonaws.com/"+v.opts.videoUploadToS3.bucket);var s=v.core.getXHR(r,v.opts.videoUploadMethod);s.onload=function(){x.call(s,u)},s.onerror=S,s.upload.onprogress=R,s.onabort=D,w(),v.events.disableBlur(),v.edit.off(),v.events.enableBlur();var n=v.popups.get("video.insert");n&&n.off("abortUpload").on("abortUpload",function(){4!=s.readyState&&s.abort()}),s.send(t)}}}function M(e,t){v.edit.on(),u&&u.find("video").addClass("fr-error"),function(e){w();var t=v.popups.get("video.insert").find(".fr-video-progress-bar-layer");t.addClass("fr-error");var i=t.find("h3");i.text(e),v.events.disableBlur(),i.focus()}(v.language.translate("Something went wrong. Please try again.")),v.events.trigger("video.error",[{code:e,message:r[e]},t])}function N(){if(u){var e=v.popups.get("video.size"),t=u.find("iframe, embed, video");e.find('input[name="width"]').val(t.get(0).style.width||t.attr("width")).trigger("change"),e.find('input[name="height"]').val(t.get(0).style.height||t.attr("height")).trigger("change")}}function V(e){if(e)return v.popups.onRefresh("video.size",N),!0;var t={buttons:'<div class="fr-buttons">'+v.button.buildList(v.opts.videoSizeButtons)+"</div>",size_layer:'<div class="fr-video-size-layer fr-layer fr-active" id="fr-video-size-layer-'+v.id+'"><div class="fr-video-group"><div class="fr-input-line"><input id="fr-video-size-layer-width-'+v.id+'" type="text" name="width" placeholder="'+v.language.translate("Width")+'" tabIndex="1"></div><div class="fr-input-line"><input id="fr-video-size-layer-height-'+v.id+'" type="text" name="height" placeholder="'+v.language.translate("Height")+'" tabIndex="1"></div></div><div class="fr-action-buttons"><button type="button" class="fr-command fr-submit" data-cmd="videoSetSize" tabIndex="2" role="button">'+v.language.translate("Update")+"</button></div></div>"},i=v.popups.create("video.size",t);return v.events.$on(v.$wp,"scroll",function(){u&&v.popups.isVisible("video.size")&&(v.events.disableBlur(),A(u))}),i}function Y(e){if(void 0===e&&(e=u),e){if(e.hasClass("fr-fvl"))return"left";if(e.hasClass("fr-fvr"))return"right";if(e.hasClass("fr-dvb")||e.hasClass("fr-dvi"))return"center";if("block"==e.css("display")){if("left"==e.css("text-algin"))return"left";if("right"==e.css("text-align"))return"right"}else{if("left"==e.css("float"))return"left";if("right"==e.css("float"))return"right"}}return"center"}function H(e){void 0===e&&(e=u);var t=e.css("float");return e.css("float","none"),"block"==e.css("display")?(e.css("float",""),e.css("float")!=t&&e.css("float",t),"block"):(e.css("float",""),e.css("float")!=t&&e.css("float",t),"inline")}function X(){if(u&&!1!==v.events.trigger("video.beforeRemove",[u])){var e=u;v.popups.hideAll(),z(!0),v.selection.setBefore(e.get(0))||v.selection.setAfter(e.get(0)),e.remove(),v.selection.restore(),v.html.fillEmptyBlocks(),v.events.trigger("video.removed",[e])}}function K(){C()}function W(e,t,i){!v.opts.htmlUntouched&&v.opts.useClasses?(e.removeClass("fr-fvl fr-fvr fr-dvb fr-dvi"),e.addClass("fr-fv"+i[0]+" fr-dv"+t[0])):"inline"==t?(e.css({display:"inline-block"}),"center"==i?e.css({"float":"none"}):"left"==i?e.css({"float":"left"}):e.css({"float":"right"})):(e.css({display:"block",clear:"both"}),"left"==i?e.css({textAlign:"left"}):"right"==i?e.css({textAlign:"right"}):e.css({textAlign:"center"}))}function j(){v.$el.find("video").filter(function(){return 0===G(this).parents("span.fr-video").length}).wrap('<span class="fr-video" contenteditable="false"></span>'),v.$el.find("embed, iframe").filter(function(){if(v.browser.safari&&this.getAttribute("src")&&this.setAttribute("src",this.src),0<G(this).parents("span.fr-video").length)return!1;for(var e=G(this).attr("src"),t=0;t<G.FE.VIDEO_PROVIDERS.length;t++){var i=G.FE.VIDEO_PROVIDERS[t];if(i.test_regex.test(e)&&new RegExp(v.opts.videoAllowedProviders.join("|")).test(i.provider))return!0}return!1}).map(function(){return 0===G(this).parents("object").length?this:G(this).parents("object").get(0)}).wrap('<span class="fr-video" contenteditable="false"></span>');for(var e,t,i=v.$el.find("span.fr-video, video"),o=0;o<i.length;o++){var r=G(i[o]);!v.opts.htmlUntouched&&v.opts.useClasses?((t=r).hasClass("fr-dvi")||t.hasClass("fr-dvb")||(t.addClass("fr-fv"+Y(t)[0]),t.addClass("fr-dv"+H(t)[0])),v.opts.videoTextNear||r.removeClass("fr-dvi").addClass("fr-dvb")):v.opts.htmlUntouched||v.opts.useClasses||(W(e=r,e.hasClass("fr-dvb")?"block":e.hasClass("fr-dvi")?"inline":null,e.hasClass("fr-fvl")?"left":e.hasClass("fr-fvr")?"right":Y(e)),e.removeClass("fr-dvb fr-dvi fr-fvr fr-fvl"))}i.toggleClass("fr-draggable",v.opts.videoMove)}function q(){if(u){v.selection.clear();var e=v.doc.createRange();e.selectNode(u.get(0)),v.selection.get().addRange(e)}}return r[1]="Video cannot be loaded from the passed link.",r[d]="No link in upload response.",r[l]="Error during file upload.",r[c]="Parsing response failed.",r[h]="File is too large.",r[g]="Video file type is invalid.",r[7]="Files can be uploaded only to same domain in IE 8 and IE 9.",v.shared.vid_exit_flag=!1,{_init:function(){v.events.on("drop",P,!0),v.events.on("mousedown window.mousedown",e),v.events.on("window.touchmove",L),v.events.on("mouseup window.mouseup",z),v.events.on("commands.mousedown",function(e){0<e.parents(".fr-toolbar").length&&z()}),v.events.on("video.hideResizer commands.undo commands.redo element.dropped",function(){z(!0)}),v.helpers.isMobile()&&(v.events.$on(v.$el,"touchstart","span.fr-video",function(){i=!1}),v.events.$on(v.$el,"touchmove",function(){i=!0})),v.events.on("html.set",j),j(),v.events.$on(v.$el,"mousedown","span.fr-video",function(e){e.stopPropagation()}),v.events.$on(v.$el,"click touchend","span.fr-video",function(e){if("false"==G(this).parents("[contenteditable]:not(.fr-element):not(.fr-img-caption):not(body):first").attr("contenteditable"))return!0;O.call(this,e)}),v.events.on("keydown",function(e){var t=e.which;return!u||t!=G.FE.KEYCODE.BACKSPACE&&t!=G.FE.KEYCODE.DELETE?u&&t==G.FE.KEYCODE.ESC?(z(!0),e.preventDefault(),!1):u&&t!=G.FE.KEYCODE.F10&&!v.keys.isBrowserAction(e)?(e.preventDefault(),!1):void 0:(e.preventDefault(),X(),v.undo.saveStep(),!1)},!0),v.events.on("toolbar.esc",function(){if(u)return v.events.disableBlur(),v.events.focus(),!1},!0),v.events.on("toolbar.focusEditor",function(){if(u)return!1},!0),v.events.on("keydown",function(){v.$el.find("span.fr-video:empty").remove()}),v.$wp&&(k(),v.events.on("contentChanged",k)),n(!0),V(!0)},showInsertPopup:function(){var e=v.$tb.find('.fr-command[data-cmd="insertVideo"]'),t=v.popups.get("video.insert");if(t||(t=n()),C(),!t.hasClass("fr-active"))if(v.popups.refresh("video.insert"),v.popups.setContainer("video.insert",v.$tb),e.is(":visible")){var i=e.offset().left+e.outerWidth()/2,o=e.offset().top+(v.opts.toolbarBottom?10:e.outerHeight()-10);v.popups.show("video.insert",i,o,e.outerHeight())}else v.position.forSelection(t),v.popups.show("video.insert")},showLayer:function(e){var t,i,o=v.popups.get("video.insert");if(!u&&!v.opts.toolbarInline){var r=v.$tb.find('.fr-command[data-cmd="insertVideo"]');t=r.offset().left+r.outerWidth()/2,i=r.offset().top+(v.opts.toolbarBottom?10:r.outerHeight()-10)}v.opts.toolbarInline&&(i=o.offset().top-v.helpers.getPX(o.css("margin-top")),o.hasClass("fr-above")&&(i+=o.outerHeight())),o.find(".fr-layer").removeClass("fr-active"),o.find(".fr-"+e+"-layer").addClass("fr-active"),v.popups.show("video.insert",t,i,0),v.accessibility.focusPopup(o)},refreshByURLButton:function(e){v.popups.get("video.insert").find(".fr-video-by-url-layer").hasClass("fr-active")&&e.addClass("fr-active").attr("aria-pressed",!0)},refreshEmbedButton:function(e){v.popups.get("video.insert").find(".fr-video-embed-layer").hasClass("fr-active")&&e.addClass("fr-active").attr("aria-pressed",!0)},refreshUploadButton:function(e){v.popups.get("video.insert").find(".fr-video-upload-layer").hasClass("fr-active")&&e.addClass("fr-active").attr("aria-pressed",!0)},upload:T,insertByURL:function(e){void 0===e&&(e=(v.popups.get("video.insert").find('.fr-video-by-url-layer input[type="text"]').val()||"").trim());var t=null;if(/^http/.test(e)||(e="https://"+e),v.helpers.isURL(e))for(var i=0;i<G.FE.VIDEO_PROVIDERS.length;i++){var o=G.FE.VIDEO_PROVIDERS[i];if(o.test_regex.test(e)&&new RegExp(v.opts.videoAllowedProviders.join("|")).test(o.provider)){t=e.replace(o.url_regex,o.url_text),t=o.html.replace(/\{url\}/,t);break}}t?b(t):v.events.trigger("video.linkError",[e])},insertEmbed:function(e){void 0===e&&(e=v.popups.get("video.insert").find(".fr-video-embed-layer textarea").val()||""),0!==e.length&&G.FE.VIDEO_EMBED_REGEX.test(e)?b(e):v.events.trigger("video.codeError",[e])},insert:b,align:function(e){u.removeClass("fr-fvr fr-fvl"),!v.opts.htmlUntouched&&v.opts.useClasses?"left"==e?u.addClass("fr-fvl"):"right"==e&&u.addClass("fr-fvr"):W(u,H(),e),q(),F(),s(),v.selection.clear()},refreshAlign:function(e){if(!u)return!1;e.find("> *:first").replaceWith(v.icon.create("video-align-"+Y()))},refreshAlignOnShow:function(e,t){u&&t.find('.fr-command[data-param1="'+Y()+'"]').addClass("fr-active").attr("aria-selected",!0)},display:function(e){u.removeClass("fr-dvi fr-dvb"),!v.opts.htmlUntouched&&v.opts.useClasses?"inline"==e?u.addClass("fr-dvi"):"block"==e&&u.addClass("fr-dvb"):W(u,e,Y()),q(),F(),s(),v.selection.clear()},refreshDisplayOnShow:function(e,t){u&&t.find('.fr-command[data-param1="'+H()+'"]').addClass("fr-active").attr("aria-selected",!0)},remove:X,hideProgressBar:C,showSizePopup:function(){var e=v.popups.get("video.size");e||(e=V()),C(),v.popups.refresh("video.size"),v.popups.setContainer("video.size",v.$sc);var t=u.find("iframe, embed, video"),i=t.offset().left+t.width()/2,o=t.offset().top+t.height();v.popups.show("video.size",i,o,t.height())},replace:function(){var e=v.popups.get("video.insert");e||(e=n()),v.popups.isVisible("video.insert")||(C(),v.popups.refresh("video.insert"),v.popups.setContainer("video.insert",v.$sc));var t=u.offset().left+u.width()/2,i=u.offset().top+u.height();v.popups.show("video.insert",t,i,u.outerHeight())},back:function(){u?(v.events.disableBlur(),u.trigger("click")):(v.events.disableBlur(),v.selection.restore(),v.events.enableBlur(),v.popups.hide("video.insert"),v.toolbar.showInline())},setSize:function(e,t){if(u){var i=v.popups.get("video.size"),o=u.find("iframe, embed, video");o.css("width",e||i.find('input[name="width"]').val()),o.css("height",t||i.find('input[name="height"]').val()),o.get(0).style.width&&o.removeAttr("width"),o.get(0).style.height&&o.removeAttr("height"),i.find("input:focus").blur(),setTimeout(function(){u.trigger("click")},v.helpers.isAndroid()?50:0)}},get:function(){return u}}},G.FE.RegisterCommand("insertVideo",{title:"Insert Video",undo:!1,focus:!0,refreshAfterCallback:!1,popup:!0,callback:function(){this.popups.isVisible("video.insert")?(this.$el.find(".fr-marker").length&&(this.events.disableBlur(),this.selection.restore()),this.popups.hide("video.insert")):this.video.showInsertPopup()},plugin:"video"}),G.FE.DefineIcon("insertVideo",{NAME:"video-camera",FA5NAME:"camera"}),G.FE.DefineIcon("videoByURL",{NAME:"link"}),G.FE.RegisterCommand("videoByURL",{title:"By URL",undo:!1,focus:!1,toggle:!0,callback:function(){this.video.showLayer("video-by-url")},refresh:function(e){this.video.refreshByURLButton(e)}}),G.FE.DefineIcon("videoEmbed",{NAME:"code"}),G.FE.RegisterCommand("videoEmbed",{title:"Embedded Code",undo:!1,focus:!1,toggle:!0,callback:function(){this.video.showLayer("video-embed")},refresh:function(e){this.video.refreshEmbedButton(e)}}),G.FE.DefineIcon("videoUpload",{NAME:"upload"}),G.FE.RegisterCommand("videoUpload",{title:"Upload Video",undo:!1,focus:!1,toggle:!0,callback:function(){this.video.showLayer("video-upload")},refresh:function(e){this.video.refreshUploadButton(e)}}),G.FE.RegisterCommand("videoInsertByURL",{undo:!0,focus:!0,callback:function(){this.video.insertByURL()}}),G.FE.RegisterCommand("videoInsertEmbed",{undo:!0,focus:!0,callback:function(){this.video.insertEmbed()}}),G.FE.DefineIcon("videoDisplay",{NAME:"star"}),G.FE.RegisterCommand("videoDisplay",{title:"Display",type:"dropdown",options:{inline:"Inline",block:"Break Text"},callback:function(e,t){this.video.display(t)},refresh:function(e){this.opts.videoTextNear||e.addClass("fr-hidden")},refreshOnShow:function(e,t){this.video.refreshDisplayOnShow(e,t)}}),G.FE.DefineIcon("video-align",{NAME:"align-left"}),G.FE.DefineIcon("video-align-left",{NAME:"align-left"}),G.FE.DefineIcon("video-align-right",{NAME:"align-right"}),G.FE.DefineIcon("video-align-center",{NAME:"align-justify"}),G.FE.DefineIcon("videoAlign",{NAME:"align-center"}),G.FE.RegisterCommand("videoAlign",{type:"dropdown",title:"Align",options:{left:"Align Left",center:"None",right:"Align Right"},html:function(){var e='<ul class="fr-dropdown-list" role="presentation">',t=G.FE.COMMANDS.videoAlign.options;for(var i in t)t.hasOwnProperty(i)&&(e+='<li role="presentation"><a class="fr-command fr-title" tabIndex="-1" role="option" data-cmd="videoAlign" data-param1="'+i+'" title="'+this.language.translate(t[i])+'">'+this.icon.create("video-align-"+i)+'<span class="fr-sr-only">'+this.language.translate(t[i])+"</span></a></li>");return e+="</ul>"},callback:function(e,t){this.video.align(t)},refresh:function(e){this.video.refreshAlign(e)},refreshOnShow:function(e,t){this.video.refreshAlignOnShow(e,t)}}),G.FE.DefineIcon("videoReplace",{NAME:"exchange"}),G.FE.RegisterCommand("videoReplace",{title:"Replace",undo:!1,focus:!1,popup:!0,refreshAfterCallback:!1,callback:function(){this.video.replace()}}),G.FE.DefineIcon("videoRemove",{NAME:"trash"}),G.FE.RegisterCommand("videoRemove",{title:"Remove",callback:function(){this.video.remove()}}),G.FE.DefineIcon("videoSize",{NAME:"arrows-alt"}),G.FE.RegisterCommand("videoSize",{undo:!1,focus:!1,popup:!0,title:"Change Size",callback:function(){this.video.showSizePopup()}}),G.FE.DefineIcon("videoBack",{NAME:"arrow-left"}),G.FE.RegisterCommand("videoBack",{title:"Back",undo:!1,focus:!1,back:!0,callback:function(){this.video.back()},refresh:function(e){this.video.get()||this.opts.toolbarInline?(e.removeClass("fr-hidden"),e.next(".fr-separator").removeClass("fr-hidden")):(e.addClass("fr-hidden"),e.next(".fr-separator").addClass("fr-hidden"))}}),G.FE.RegisterCommand("videoDismissError",{title:"OK",undo:!1,callback:function(){this.video.hideProgressBar(!0)}}),G.FE.RegisterCommand("videoSetSize",{undo:!0,focus:!1,title:"Update",refreshAfterCallback:!1,callback:function(){this.video.setSize()}})});
@@ -0,0 +1,1403 @@
1
+ /*!
2
+ * froala_editor v2.8.1 (https://www.froala.com/wysiwyg-editor)
3
+ * License https://froala.com/wysiwyg-editor/terms/
4
+ * Copyright 2014-2018 Froala Labs
5
+ */
6
+
7
+ (function (factory) {
8
+ if (typeof define === 'function' && define.amd) {
9
+ // AMD. Register as an anonymous module.
10
+ define(['jquery'], factory);
11
+ } else if (typeof module === 'object' && module.exports) {
12
+ // Node/CommonJS
13
+ module.exports = function( root, jQuery ) {
14
+ if ( jQuery === undefined ) {
15
+ // require('jQuery') returns a factory that requires window to
16
+ // build a jQuery instance, we normalize how we use modules
17
+ // that require this pattern but the window provided is a noop
18
+ // if it's defined (how jquery works)
19
+ if ( typeof window !== 'undefined' ) {
20
+ jQuery = require('jquery');
21
+ }
22
+ else {
23
+ jQuery = require('jquery')(root);
24
+ }
25
+ }
26
+ return factory(jQuery);
27
+ };
28
+ } else {
29
+ // Browser globals
30
+ factory(window.jQuery);
31
+ }
32
+ }(function ($) {
33
+
34
+
35
+
36
+ $.extend($.FE.DEFAULTS, {
37
+ wordDeniedTags: [],
38
+ wordDeniedAttrs: [],
39
+ wordAllowedStyleProps: ['font-family', 'font-size', 'background', 'color', 'width', 'text-align', 'vertical-align', 'background-color', 'padding', 'margin', 'height', 'margin-top', 'margin-left', 'margin-right', 'margin-bottom', 'text-decoration', 'font-weight', 'font-style', 'text-indent'],
40
+ wordPasteModal: true
41
+ });
42
+
43
+ $.FE.PLUGINS.wordPaste = function (editor) {
44
+
45
+ var $modal;
46
+ var modal_id = 'word_paste';
47
+ var clipboard_html;
48
+
49
+ /*
50
+ * Init Word Paste.
51
+ */
52
+ function _init () {
53
+ editor.events.on('paste.wordPaste', function (html) {
54
+ clipboard_html = html;
55
+
56
+ if (editor.opts.wordPasteModal) {
57
+ _showModal();
58
+ }
59
+ else {
60
+ clean(true);
61
+ }
62
+
63
+ return false;
64
+ });
65
+ }
66
+
67
+ /*
68
+ * Build html body.
69
+ */
70
+ function _buildModalBody () {
71
+
72
+ // Begin body.
73
+ var body = '<div class="fr-word-paste-modal" style="padding: 20px 20px 10px 20px;">';
74
+ body += '<p style="text-align: left;">' + editor.language.translate('The pasted content is coming from a Microsoft Word document. Do you want to keep the format or clean it up?') + '</p>';
75
+ body += '<div style="text-align: right; margin-top: 50px;"><button class="fr-remove-word fr-command">' + editor.language.translate('Clean') + '</button> <button class="fr-keep-word fr-command">' + editor.language.translate('Keep') + '</button></div>';
76
+
77
+ // End body.
78
+ body += '</div>';
79
+
80
+ return body;
81
+ }
82
+
83
+ /*
84
+ * Show modal.
85
+ */
86
+ function _showModal () {
87
+ if (!$modal) {
88
+ var head = '<h4><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 74.95 73.23" style="height: 25px; vertical-align: text-bottom; margin-right: 5px; display: inline-block"><defs><style>.a{fill:#2a5699;}.b{fill:#fff;}</style></defs><path class="a" d="M615.15,827.22h5.09V834c9.11.05,18.21-.09,27.32.05a2.93,2.93,0,0,1,3.29,3.25c.14,16.77,0,33.56.09,50.33-.09,1.72.17,3.63-.83,5.15-1.24.89-2.85.78-4.3.84-8.52,0-17,0-25.56,0v6.81h-5.32c-13-2.37-26-4.54-38.94-6.81q0-29.8,0-59.59c13.05-2.28,26.11-4.5,39.17-6.83Z" transform="translate(-575.97 -827.22)"/><path class="b" d="M620.24,836.59h28.1v54.49h-28.1v-6.81h22.14v-3.41H620.24v-4.26h22.14V873.2H620.24v-4.26h22.14v-3.41H620.24v-4.26h22.14v-3.41H620.24v-4.26h22.14v-3.41H620.24V846h22.14v-3.41H620.24Zm-26.67,15c1.62-.09,3.24-.16,4.85-.25,1.13,5.75,2.29,11.49,3.52,17.21,1-5.91,2-11.8,3.06-17.7,1.7-.06,3.41-.15,5.1-.26-1.92,8.25-3.61,16.57-5.71,24.77-1.42.74-3.55,0-5.24.09-1.13-5.64-2.45-11.24-3.47-16.9-1,5.5-2.29,10.95-3.43,16.42q-2.45-.13-4.92-.3c-1.41-7.49-3.07-14.93-4.39-22.44l4.38-.18c.88,5.42,1.87,10.82,2.64,16.25,1.2-5.57,2.43-11.14,3.62-16.71Z" transform="translate(-575.97 -827.22)"/></svg> ' + editor.language.translate('Word Paste Detected') + '</h4>';
89
+ var body = _buildModalBody();
90
+
91
+ var modalHash = editor.modals.create(modal_id, head, body);
92
+
93
+ var $body = modalHash.$body;
94
+ $modal = modalHash.$modal;
95
+
96
+ modalHash.$modal.addClass('fr-middle');
97
+
98
+ editor.events.bindClick($body, 'button.fr-remove-word', function () {
99
+ var inst = $modal.data('instance') || editor;
100
+ inst.wordPaste.clean();
101
+ });
102
+
103
+ editor.events.bindClick($body, 'button.fr-keep-word', function () {
104
+ var inst = $modal.data('instance') || editor;
105
+
106
+ inst.wordPaste.clean(true);
107
+ });
108
+
109
+ // Resize help modal on window resize.
110
+ editor.events.$on($(editor.o_win), 'resize', function () {
111
+ editor.modals.resize(modal_id);
112
+ })
113
+ }
114
+
115
+ // Show modal.
116
+ editor.modals.show(modal_id);
117
+
118
+ // Modal may not fit window size.
119
+ editor.modals.resize(modal_id);
120
+ }
121
+
122
+ /*
123
+ * Hide modal.
124
+ */
125
+ function _hideModal () {
126
+ editor.modals.hide(modal_id);
127
+ }
128
+
129
+ /*
130
+ * Word paste cleanup.
131
+ */
132
+ function clean (keep_formatting) {
133
+ var wordAllowedStylePropsBackup = editor.opts.wordAllowedStyleProps;
134
+
135
+ if (!keep_formatting) {
136
+ editor.opts.wordAllowedStyleProps = [];
137
+ }
138
+
139
+ // Firefox paste.
140
+ if (clipboard_html.indexOf('<colgroup>') === 0) {
141
+ clipboard_html = '<table>' + clipboard_html + '</table>';
142
+ }
143
+
144
+
145
+ // Replace spaces.
146
+ clipboard_html = clipboard_html.replace(/<span[\n\r ]*style='mso-spacerun:yes'>([\r\n\u00a0 ]*)<\/span>/g, function (str, match) {
147
+ var spaces = '';
148
+ var i = 0;
149
+
150
+ while (i++ < match.length) {
151
+ spaces += '&nbsp;';
152
+ }
153
+
154
+ return spaces;
155
+ });
156
+
157
+ clipboard_html = _wordClean(clipboard_html, editor.paste.getRtfClipboard());
158
+
159
+ // Remove unwanted spaces.
160
+ var div = editor.doc.createElement('DIV');
161
+ div.innerHTML = clipboard_html;
162
+ editor.html.cleanBlankSpaces(div);
163
+ clipboard_html = div.innerHTML;
164
+
165
+ clipboard_html = editor.paste.cleanEmptyTagsAndDivs(clipboard_html);
166
+
167
+ // Remove invisible space.
168
+ clipboard_html = clipboard_html.replace(/\u200b/g, '');
169
+
170
+ _hideModal();
171
+
172
+ // Clean the processed clipboard_html.
173
+ editor.paste.clean(clipboard_html, true, true);
174
+
175
+ editor.opts.wordAllowedStyleProps = wordAllowedStylePropsBackup;
176
+ }
177
+
178
+ /**
179
+ * Remove a node. IE conpatible.
180
+ */
181
+ function _removeNode(node) {
182
+
183
+ var parent = node.parentNode;
184
+
185
+ if (!parent) {
186
+
187
+ return;
188
+ }
189
+
190
+ node.parentNode.removeChild(node);
191
+ }
192
+
193
+ /*
194
+ * Depth-first search traversing of the DOM.
195
+ */
196
+ function _traverse (node, callback) {
197
+
198
+ // Process node.
199
+ if (!callback(node)) {
200
+
201
+ return;
202
+ }
203
+
204
+ // Expand node. Take its first child.
205
+ var child = node.firstChild;
206
+
207
+ // While all childs are traversed.
208
+ while (child) {
209
+
210
+ // Store the current child.
211
+ var current_child = child;
212
+
213
+ // Store the previous child.
214
+ var previous_child = child.previousSibling;
215
+
216
+ // Take next child.
217
+ child = child.nextSibling;
218
+
219
+ // Expand the current child.
220
+ _traverse(current_child, callback);
221
+
222
+
223
+ // An unwrap was made. Need to calculate again the next child.
224
+ if ((!current_child.previousSibling && !current_child.nextSibling && !current_child.parentNode) && child && (previous_child != child.previousSibling) && child.parentNode) {
225
+ if (previous_child) {
226
+ child = previous_child.nextSibling;
227
+ }
228
+ else {
229
+ child = node.firstChild;
230
+ }
231
+ }
232
+
233
+ // A list was created. Need to calculate again the next child.
234
+ else if ((!current_child.previousSibling && !current_child.nextSibling && !current_child.parentNode) && child && (!child.previousSibling && !child.nextSibling && !child.parentNode)) {
235
+ if (previous_child) {
236
+ if (previous_child.nextSibling) {
237
+ child = previous_child.nextSibling.nextSibling;
238
+ }
239
+ else {
240
+ child = null;
241
+ }
242
+ }
243
+ else {
244
+ if (node.firstChild) {
245
+ child = node.firstChild.nextSibling;
246
+ }
247
+ }
248
+ }
249
+ }
250
+ }
251
+
252
+ /*
253
+ * Check if a node is a list. TODO: use Regex.
254
+ */
255
+ function _isList (node) {
256
+ // Check if it has mso-list:l in its style attribute.
257
+ if (!(node.getAttribute('style') && /mso-list:[\s]*l/gi.test(node.getAttribute('style').replace(/\n/gi, '')))) {
258
+
259
+ return false;
260
+ }
261
+
262
+ // Using try-catch to skip undefined checking.
263
+ try {
264
+ // Check mso-list.
265
+ if (!node.querySelector('[style="mso-list:Ignore"]')) {
266
+
267
+ return false;
268
+ }
269
+ }
270
+ catch (e) {
271
+
272
+ return false;
273
+ }
274
+
275
+ return true;
276
+ }
277
+
278
+ /*
279
+ * Get list level based on level attribute from node style.
280
+ */
281
+ function _getListLevel (node) {
282
+
283
+ return node.getAttribute('style').replace(/\n/gi, '').replace(/.*level([0-9]+?).*/gi, '$1')
284
+ }
285
+
286
+ /*
287
+ * Get list content.
288
+ */
289
+ function _getListContent (node, head_style_hash) {
290
+
291
+ var cloned_node = node.cloneNode(true);
292
+
293
+ // Some lists might be wrapped in a link. So we need to unwrap.
294
+ // if (cloned_node.firstElementChild && cloned_node.firstElementChild.tagName == 'A') {
295
+ // cloned_node = cloned_node.firstElementChild;
296
+ // }
297
+
298
+ // Heading list.
299
+ if (['H1', 'H2', 'H3', 'H4', 'H5', 'H6'].indexOf(node.tagName) != -1) {
300
+ var heading = document.createElement(node.tagName.toLowerCase());
301
+ heading.setAttribute('style', node.getAttribute('style'));
302
+ heading.innerHTML = cloned_node.innerHTML;
303
+ cloned_node.innerHTML = heading.outerHTML;
304
+ }
305
+
306
+ // Clean node recursively.
307
+ _traverse(cloned_node, function (node) {
308
+ if (node.nodeType == Node.ELEMENT_NODE) {
309
+
310
+ // Skip the first child which is an mso-list:Ignore node.
311
+ if (node.getAttribute('style') == 'mso-list:Ignore') {
312
+ node.parentNode.removeChild(node);
313
+ }
314
+
315
+ _cleanElement(node, head_style_hash);
316
+ }
317
+
318
+ return true;
319
+ });
320
+
321
+ // Take content.
322
+ var content = cloned_node.innerHTML;
323
+
324
+ // Replace comments.
325
+ content = content.replace(/<!--[\s\S]*?-->/gi, '');
326
+
327
+ return content;
328
+ }
329
+
330
+ /*
331
+ * Build ol/ul list.
332
+ */
333
+ function _buildList (node, head_style_hash) {
334
+
335
+ // Check ol/ul.
336
+ var order_regex = /[0-9a-zA-Z]./gi;
337
+ var is_ordered = false;
338
+
339
+ if (node.firstElementChild && node.firstElementChild.firstElementChild && node.firstElementChild.firstElementChild.firstChild) {
340
+ is_ordered = is_ordered || order_regex.test(node.firstElementChild.firstElementChild.firstChild.data || '');
341
+
342
+ if (!is_ordered && node.firstElementChild.firstElementChild.firstElementChild && node.firstElementChild.firstElementChild.firstElementChild.firstChild) {
343
+ is_ordered = is_ordered || order_regex.test(node.firstElementChild.firstElementChild.firstElementChild.firstChild.data || '');
344
+ }
345
+ }
346
+
347
+ var list_tag = is_ordered ? 'ol' : 'ul';
348
+
349
+ // Get list level.
350
+ var level = _getListLevel(node);
351
+
352
+ // Build list with first line.
353
+ var s = '<' + list_tag + '><li>' + _getListContent(node, head_style_hash);
354
+
355
+ // Get next sibling and remove the current node.
356
+ var next_element_sibling = node.nextElementSibling;
357
+ var parent_node = node.parentNode;
358
+ _removeNode(node);
359
+ node = null;
360
+
361
+ // Check if next siblings are lists too.
362
+ while (next_element_sibling) {
363
+
364
+ // Stop at first sibling that is not a list.
365
+ if (!_isList(next_element_sibling)) {
366
+ break;
367
+ }
368
+
369
+ // Store the previous element sibling.
370
+ var previous_element_sibling = next_element_sibling.previousElementSibling;
371
+
372
+ var next_level = _getListLevel(next_element_sibling);
373
+
374
+ // Compare the levels.
375
+ if (next_level > level) {
376
+
377
+ // Add nested list with a higher level.
378
+ s += _buildList(next_element_sibling, head_style_hash).outerHTML;
379
+ }
380
+ else if (next_level < level) {
381
+
382
+ // Lower level found. Current list is done.
383
+ break;
384
+ }
385
+ else {
386
+
387
+ // Add a new line with the content of the current sibling.
388
+ s += '</li><li>' + _getListContent(next_element_sibling, head_style_hash);
389
+ }
390
+
391
+ level = next_level;
392
+
393
+ // Sibling was not removed when nested list was added.
394
+ if (next_element_sibling.previousElementSibling || next_element_sibling.nextElementSibling || next_element_sibling.parentNode) {
395
+ var next_element_sibling_copy = next_element_sibling;
396
+ next_element_sibling = next_element_sibling.nextElementSibling;
397
+ _removeNode(next_element_sibling_copy);
398
+ next_element_sibling_copy = null;
399
+ }
400
+
401
+ // Sibling was removed. Take again the next sibling.
402
+ else if (previous_element_sibling) {
403
+ next_element_sibling = previous_element_sibling.nextElementSibling;
404
+ }
405
+ else {
406
+ next_element_sibling = parent_node.firstElementChild;
407
+ }
408
+ }
409
+
410
+ // Finish list.
411
+ s += '</li></' + list_tag + '>';
412
+
413
+ // Convert string to node element.
414
+ var div = document.createElement('div');
415
+ div.innerHTML = s;
416
+ var element = div.firstElementChild;
417
+
418
+ return element;
419
+ }
420
+
421
+ /*
422
+ * Change tag name of an element.
423
+ */
424
+ function _changeTagName (old_node, tag_name) {
425
+
426
+ var new_node = document.createElement(tag_name);
427
+
428
+ for (var i = 0; i < old_node.attributes.length; i++) {
429
+ var attribute = old_node.attributes[i].name;
430
+ new_node.setAttribute(attribute, old_node.getAttribute(attribute));
431
+ }
432
+
433
+ new_node.innerHTML = old_node.innerHTML;
434
+
435
+ old_node.parentNode.replaceChild(new_node, old_node)
436
+
437
+ return new_node;
438
+ }
439
+
440
+ /*
441
+ * Clean tr element.
442
+ */
443
+ function _cleanTr (tr, head_style_hash) {
444
+
445
+ // Clean tr attributes.
446
+ editor.node.clearAttributes(tr);
447
+
448
+ // Get first child.
449
+ var child = tr.firstElementChild;
450
+
451
+ // Total table width.
452
+ var total_width = 0;
453
+
454
+ // Tell if at least one child has a missing width.
455
+ var missing_width = false;
456
+
457
+ // Width attribute.
458
+ var width_attr = null;
459
+
460
+ // Clean td childs and calculate total table width.
461
+ while (child) {
462
+
463
+ // Cleanup w: tags.
464
+ if (child.firstElementChild && child.firstElementChild.tagName.indexOf('W:') != -1) {
465
+ child.innerHTML = child.firstElementChild.innerHTML;
466
+ }
467
+
468
+ // Add width to total.
469
+ width_attr = child.getAttribute('width');
470
+
471
+ if (!width_attr && !missing_width) {
472
+ missing_width = true;
473
+ }
474
+ total_width += parseInt(width_attr, 10);
475
+
476
+ // Replace to <br> childs that are empty or &nbsp.
477
+ if (!child.firstChild || (child.firstChild && child.firstChild.data == $.FE.UNICODE_NBSP)) {
478
+ if (child.firstChild) {
479
+ _removeNode(child.firstChild);
480
+ }
481
+ child.innerHTML = '<br>';
482
+ }
483
+
484
+ var td_child = child.firstElementChild;
485
+
486
+ // If child has more than one children, it means that every child has its own alignment.
487
+ var has_single_child = child.children.length == 1;
488
+
489
+ // Change p to span or div and clean alignment on every element child.
490
+ while (td_child) {
491
+
492
+ if (td_child.tagName == 'P' && !_isList(td_child)) {
493
+ // Set alignment to td parent.
494
+ if (has_single_child) {
495
+ _cleanAlignment(td_child);
496
+ }
497
+ }
498
+
499
+ // Move to next element sibling.
500
+ td_child = td_child.nextElementSibling;
501
+ }
502
+
503
+ // Add styles from head.
504
+ if (head_style_hash) {
505
+
506
+ // Style from .xl classes.
507
+ // Get class from child.
508
+ var class_attr = child.getAttribute('class');
509
+
510
+ if (class_attr) {
511
+ class_attr = _normalizeAttribute(class_attr);
512
+
513
+ // Match xl class.
514
+ var class_matches = class_attr.match(/xl[0-9]+/gi);
515
+
516
+ if (class_matches) {
517
+ var xl_class = class_matches[0];
518
+ var dot_xl_class = '.' + xl_class;
519
+
520
+ if (head_style_hash[dot_xl_class]) {
521
+ _appendStyle(child, head_style_hash[dot_xl_class]);
522
+ }
523
+ }
524
+ }
525
+
526
+ // Style from td.
527
+ if (head_style_hash.td) {
528
+ _appendStyle(child, head_style_hash.td);
529
+ }
530
+ }
531
+
532
+ var style = child.getAttribute('style');
533
+
534
+ if (style) {
535
+ style = _normalizeAttribute(style);
536
+
537
+ // Add semicolon, if it is missing, to the end of current style.
538
+ if (style && style.slice(-1) != ';') {
539
+ style += ';';
540
+ }
541
+ }
542
+
543
+ // Store valign attribute.
544
+ var valign = child.getAttribute('valign');
545
+
546
+ if (!valign && style) {
547
+ var valign_matches = style.match(/vertical-align:.+?[; "]{1,1}/gi);
548
+
549
+ if (valign_matches) {
550
+ valign = valign_matches[valign_matches.length - 1].replace(/vertical-align:(.+?)[; "]{1,1}/gi, '$1');
551
+ }
552
+ }
553
+
554
+ // Store text-align style attribute.
555
+ var halign = null;
556
+
557
+ if (style) {
558
+ var halign_matches = style.match(/text-align:.+?[; "]{1,1}/gi);
559
+
560
+ if (halign_matches) {
561
+ halign = halign_matches[halign_matches.length - 1].replace(/text-align:(.+?)[; "]{1,1}/gi, '$1');
562
+ }
563
+
564
+ if (halign == 'general') {
565
+ halign = null;
566
+ }
567
+ }
568
+
569
+ // Store background color style attribute.
570
+ var background_color = null;
571
+
572
+ if (style) {
573
+ var background_matches = style.match(/background:.+?[; "]{1,1}/gi);
574
+
575
+ if (background_matches) {
576
+ background_color = background_matches[background_matches.length - 1].replace(/background:(.+?)[; "]{1,1}/gi, '$1');
577
+ }
578
+ }
579
+
580
+ // Store colspan.
581
+ var colspan = child.getAttribute('colspan');
582
+
583
+ // Store rowspan.
584
+ var rowspan = child.getAttribute('rowspan');
585
+
586
+ // Restore colspan.
587
+ if (colspan) {
588
+ child.setAttribute('colspan', colspan);
589
+ }
590
+
591
+ // Restore rowspan.
592
+ if (rowspan) {
593
+ child.setAttribute('rowspan', rowspan);
594
+ }
595
+
596
+ // Add valign to style.
597
+ if (valign) {
598
+ child.style['vertical-align'] = valign;
599
+ }
600
+
601
+ // Add horizontal align to style.
602
+ if (halign) {
603
+ child.style['text-align'] = halign;
604
+ }
605
+
606
+ // Add background color to style.
607
+ if (background_color) {
608
+ child.style['background-color'] = background_color;
609
+ }
610
+
611
+ // Set the width again.
612
+ if (width_attr) {
613
+ child.setAttribute('width', width_attr);
614
+ }
615
+
616
+ // Move to next sibling.
617
+ child = child.nextElementSibling;
618
+
619
+ }
620
+
621
+ // Get first child again.
622
+ child = tr.firstElementChild;
623
+
624
+ // Set the width in percentage to every child.
625
+ while (child) {
626
+ width_attr = child.getAttribute('width');
627
+
628
+ if (missing_width) {
629
+
630
+ // Remove width.
631
+ child.removeAttribute('width');
632
+ }
633
+ else {
634
+
635
+ // Set the width considering that every child has equal widths.
636
+ child.setAttribute('width', (parseInt(width_attr, 10) * 100) / total_width + '%');
637
+ }
638
+
639
+ // Move to next sibling.
640
+ child = child.nextElementSibling;
641
+ }
642
+ }
643
+
644
+ /*
645
+ * Clean align attribute.
646
+ */
647
+ function _cleanAlignment (el) {
648
+
649
+ var parent = el.parentNode;
650
+ var align = el.getAttribute('align');
651
+
652
+ if (align) {
653
+ if (parent && parent.tagName == 'TD') {
654
+ parent.setAttribute('style', parent.getAttribute('style') + 'text-align:' + align + ';')
655
+ el.removeAttribute('align');
656
+ }
657
+ else {
658
+ el.style['text-align'] = align;
659
+ el.removeAttribute('align');
660
+ }
661
+ }
662
+ }
663
+
664
+ /*
665
+ * Clean up atribute.
666
+ */
667
+ function _normalizeAttribute (attribute) {
668
+
669
+ return attribute.replace(/\n|\r|\n\r|&quot;/g, '');
670
+ }
671
+
672
+ /*
673
+ * Append style to element.
674
+ */
675
+ function _appendStyle (el, style, last) {
676
+
677
+ if (!style) {
678
+ return;
679
+ }
680
+
681
+ // Get current element style.
682
+ var old_style = el.getAttribute('style');
683
+
684
+ // Add semicolon, if it is missing, to the end of current style.
685
+ if (old_style && old_style.slice(-1) != ';') {
686
+ old_style += ';';
687
+ }
688
+
689
+ // Add semicolon, if it is missing, to the end of current style.
690
+ if (style && style.slice(-1) != ';') {
691
+ style += ';';
692
+ }
693
+
694
+ // Remove newlines.
695
+ style = style.replace(/\n/gi, '');
696
+
697
+ // Append at the begining or at the end.
698
+ var new_style = null;
699
+
700
+ if (last) {
701
+ new_style = (old_style || '') + style;
702
+ }
703
+ else {
704
+ new_style = style + (old_style || '');
705
+ }
706
+ el.setAttribute('style', new_style);
707
+ }
708
+
709
+ /*
710
+ * Delete duplicate attributes found on style. Keep the last one.
711
+ */
712
+ function _cleanStyleDuplicates (el) {
713
+ var style = el.getAttribute('style');
714
+
715
+ if (!style) {
716
+
717
+ return;
718
+ }
719
+
720
+ style = _normalizeAttribute(style);
721
+
722
+ // Add semicolon, if it is missing, to the end of style.
723
+ if (style && style.slice(-1) != ';') {
724
+ style += ';';
725
+ }
726
+
727
+ // Get styles: attr:value;
728
+ var style_list = style.match(/(^|\S+?):.+?;{1,1}/gi);
729
+
730
+ if (!style_list) {
731
+ return;
732
+ }
733
+
734
+ // Key = attribute. Value = attribute's value. Duplicate keys will be overrided.
735
+ var style_hash = {};
736
+
737
+ for (var i = 0; i < style_list.length; i++) {
738
+ var style_list_item = style_list[i];
739
+
740
+ var splited_style = style_list_item.split(':');
741
+
742
+ if (splited_style.length != 2) {
743
+ continue;
744
+ }
745
+
746
+ // Add style to hash without text-align on span.
747
+ if (!(splited_style[0] == 'text-align' && el.tagName == 'SPAN')) {
748
+ style_hash[splited_style[0]] = splited_style[1];
749
+ }
750
+ }
751
+
752
+ // Create the new style without duplicates.
753
+ var new_style = '';
754
+
755
+ for (var attr in style_hash) {
756
+ if (style_hash.hasOwnProperty(attr)) {
757
+
758
+ // Change font-size form pt to px;
759
+ if (attr == 'font-size' && style_hash[attr].slice(-3) == 'pt;') {
760
+ var number = null;
761
+
762
+ try {
763
+ number = parseFloat(style_hash[attr].slice(0, -3), 10);
764
+ }
765
+ catch (e) {
766
+ }
767
+
768
+ if (number) {
769
+ number = Math.round(1.33 * number);
770
+ style_hash[attr] = number + 'px;';
771
+ }
772
+ }
773
+
774
+ new_style += attr + ':' + style_hash[attr];
775
+ }
776
+ }
777
+
778
+ if (new_style) {
779
+ el.setAttribute('style', new_style);
780
+ }
781
+ }
782
+
783
+ /*
784
+ * Convert a hex string to base64.
785
+ */
786
+ function _hexToBase64 (hex) {
787
+ var hexa_chars = hex.match(/[0-9a-f]{2}/gi);
788
+
789
+ var dec_chars = [];
790
+
791
+ for (var i = 0; i < hexa_chars.length; i++) {
792
+ dec_chars.push(String.fromCharCode(parseInt(hexa_chars[i], 16)));
793
+ }
794
+
795
+ var dec = dec_chars.join('');
796
+
797
+ return btoa(dec);
798
+ }
799
+
800
+ var _rtf_map = null;
801
+
802
+ function _getRtfData(rtf, letter, p_type) {
803
+ var imgs = rtf.split(p_type);
804
+
805
+ for (var i = 1; i < imgs.length; i++) {
806
+ var img_data = imgs[i];
807
+
808
+ img_data = img_data.split('shplid');
809
+
810
+ if (img_data.length > 1) {
811
+
812
+ img_data = img_data[1];
813
+
814
+ var id = '';
815
+ var t = 0;
816
+
817
+ while (t < img_data.length) {
818
+ if (img_data[t] == '\\' || img_data[t] == '{' || img_data[t] == ' ' || img_data[t] == '\r' || img_data[t] == '\n') {
819
+ break;
820
+ }
821
+
822
+ id += img_data[t];
823
+
824
+ t++;
825
+ }
826
+
827
+ var bliptab_split = img_data.split('bliptag');
828
+
829
+ if (bliptab_split && bliptab_split.length < 2) {
830
+
831
+ continue;
832
+ }
833
+
834
+ var image_type = null;
835
+
836
+ if (bliptab_split[0].indexOf('pngblip') != -1) {
837
+ image_type = 'image/png';
838
+ }
839
+ else if (bliptab_split[0].indexOf('jpegblip') != -1) {
840
+ image_type = 'image/jpeg';
841
+ }
842
+
843
+ if (!image_type) {
844
+
845
+ continue;
846
+ }
847
+
848
+ var bracket_split = bliptab_split[1].split('}');
849
+
850
+ if (bracket_split && bracket_split.length < 2) {
851
+
852
+ continue;
853
+ }
854
+
855
+ var space_split;
856
+
857
+ if (bracket_split.length > 2 && bracket_split[0].indexOf('blipuid') != -1) {
858
+ space_split = bracket_split[1].split(' ');
859
+ }
860
+ else {
861
+ space_split = bracket_split[0].split(' ');
862
+
863
+ if (space_split && space_split.length < 2) {
864
+
865
+ continue;
866
+ }
867
+
868
+ space_split.shift();
869
+ }
870
+
871
+ var image_hex = space_split.join('');
872
+
873
+ _rtf_map[letter + id] = {
874
+ image_hex: image_hex,
875
+ image_type: image_type
876
+ }
877
+ }
878
+ }
879
+ }
880
+
881
+ function _buildRtfMap (rtf) {
882
+ _rtf_map = {};
883
+
884
+ _getRtfData(rtf, 'i', '\\shppict');
885
+ _getRtfData(rtf, 's', '\\shp{');
886
+ }
887
+
888
+ /*
889
+ * Clean HTML Image.
890
+ */
891
+ function _cleanImage (el, rtf) {
892
+
893
+ if (!rtf) {
894
+
895
+ return;
896
+ }
897
+
898
+ // vshapes_tag will identify the image in rtf.
899
+ var vshapes_tag;
900
+
901
+ // Image case.
902
+ if (el.tagName == 'IMG') {
903
+ // Get src.
904
+ var src = el.getAttribute('src');
905
+
906
+ if (!src || src.indexOf('file://') == -1) {
907
+ return;
908
+ }
909
+
910
+ else if (src.indexOf('file://') === 0) {
911
+ if (editor.helpers.isURL(el.getAttribute('alt'))) {
912
+ el.setAttribute('src', el.getAttribute('alt'))
913
+
914
+ return;
915
+ }
916
+ }
917
+
918
+ // vshapes_tag will identify the image in rtf.
919
+ vshapes_tag = _v_shapes_map[el.getAttribute('v:shapes')];
920
+
921
+ if (!vshapes_tag) {
922
+ vshapes_tag = el.getAttribute('v:shapes');
923
+ }
924
+ }
925
+ else {
926
+ vshapes_tag = el.parentNode.getAttribute('o:spid');
927
+ }
928
+
929
+ el.removeAttribute('height');
930
+
931
+ if (!vshapes_tag) {
932
+
933
+ return;
934
+ }
935
+
936
+ _buildRtfMap(rtf);
937
+
938
+ var img_data = _rtf_map[vshapes_tag.substring(7)];
939
+
940
+ if (img_data) {
941
+
942
+ // Convert image hex to base64.
943
+ var image_base64 = _hexToBase64(img_data.image_hex);
944
+
945
+ // Build data uri.
946
+ var data_uri = 'data:' + img_data.image_type + ';base64,' + image_base64;
947
+
948
+ if (el.tagName === 'IMG') {
949
+ el.src = data_uri;
950
+ el.setAttribute('data-fr-image-pasted', true)
951
+ }
952
+ else {
953
+ $(el.parentNode).before('<img data-fr-image-pasted="true" src="' + data_uri + '" style="' + el.parentNode.getAttribute('style') + '">').remove();
954
+ }
955
+ }
956
+ }
957
+
958
+ /*
959
+ * Clean element.
960
+ */
961
+ function _cleanElement (el, head_style_hash) {
962
+
963
+ var tag_name = el.tagName;
964
+ var tag_name_lower_case = tag_name.toLowerCase();
965
+
966
+ // Check if we need to change a tag. Tags should be changed only from parent.
967
+ if (el.firstElementChild) {
968
+
969
+ // Change i to em.
970
+ if (el.firstElementChild.tagName == 'I') {
971
+ _changeTagName(el.firstElementChild, 'em');
972
+
973
+ // Change b to strong.
974
+ }
975
+ else if (el.firstElementChild.tagName == 'B') {
976
+ _changeTagName(el.firstElementChild, 'strong');
977
+ }
978
+ }
979
+
980
+ // Remove no needed tags.
981
+ var word_tags = ['SCRIPT', 'APPLET', 'EMBED', 'NOFRAMES', 'NOSCRIPT'];
982
+
983
+ if (word_tags.indexOf(tag_name) != -1) {
984
+ _removeNode(el);
985
+
986
+ return false;
987
+ }
988
+
989
+ // Check single spaces.
990
+ // if (tag_name == 'O:P' && el.innerHTML == '&nbsp;') {
991
+ // el.innerHTML = $.FE.INVISIBLE_SPACE;
992
+ // }
993
+
994
+ // Index used in for loops.
995
+ var i = -1;
996
+
997
+ // Remove tags but keep content.
998
+ var ignore_tags = ['META', 'LINK', 'XML', 'ST1:', 'O:', 'W:', 'FONT'];
999
+
1000
+ for (i = 0; i < ignore_tags.length; i++) {
1001
+ if (tag_name.indexOf(ignore_tags[i]) != -1) {
1002
+ if (el.innerHTML) {
1003
+ el.outerHTML = el.innerHTML;
1004
+ _removeNode(el);
1005
+
1006
+ return false;
1007
+ }
1008
+ else {
1009
+
1010
+ // Remove if does not have content.
1011
+ _removeNode(el);
1012
+
1013
+ return false;
1014
+ }
1015
+ break;
1016
+ }
1017
+ }
1018
+
1019
+ // Add class style from head.
1020
+ if (tag_name != 'TD') {
1021
+
1022
+ var class_attr = el.getAttribute('class');
1023
+
1024
+ if (head_style_hash && class_attr) {
1025
+ class_attr = _normalizeAttribute(class_attr);
1026
+ var class_contents = class_attr.split(' ');
1027
+
1028
+ // All classes.
1029
+ for (i = 0; i < class_contents.length; i++) {
1030
+ var class_content = class_contents[i];
1031
+
1032
+ // Create style attributes list.
1033
+ var style_attrs = [];
1034
+
1035
+ // Only classes.
1036
+ var style_attr = '.' + class_content;
1037
+ style_attrs.push(style_attr);
1038
+
1039
+ // Classes under tag.
1040
+ style_attr = tag_name_lower_case + style_attr;
1041
+ style_attrs.push(style_attr);
1042
+
1043
+ for (var j = 0; j < style_attrs.length; j++) {
1044
+ if (head_style_hash[style_attrs[j]]) {
1045
+ _appendStyle(el, head_style_hash[style_attrs[j]]);
1046
+ }
1047
+ }
1048
+ }
1049
+
1050
+ el.removeAttribute('class');
1051
+ }
1052
+
1053
+ // Add tag style from head.
1054
+ if (head_style_hash && head_style_hash[tag_name_lower_case]) {
1055
+ _appendStyle(el, head_style_hash[tag_name_lower_case]);
1056
+ }
1057
+ }
1058
+
1059
+ // Wrap paragraphs inner html in a span.
1060
+ var paragraph_tag_list = ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'PRE'];
1061
+
1062
+ if (paragraph_tag_list.indexOf(tag_name) != -1) {
1063
+
1064
+ // Set style from head.
1065
+ var el_class = el.getAttribute('class');
1066
+
1067
+ if (el_class) {
1068
+ if (head_style_hash && head_style_hash[tag_name.toLowerCase() + '.' + el_class]) {
1069
+ _appendStyle(el, head_style_hash[tag_name.toLowerCase() + '.' + el_class]);
1070
+ }
1071
+
1072
+ // Remove mso values from class.
1073
+ if (el_class.toLowerCase().indexOf('mso') != -1) {
1074
+ var cleaned_class = _normalizeAttribute(el_class);
1075
+ cleaned_class = cleaned_class.replace(/[0-9a-z-_]*mso[0-9a-z-_]*/gi, '');
1076
+
1077
+ if (cleaned_class) {
1078
+ el.setAttribute('class', cleaned_class);
1079
+ }
1080
+ else {
1081
+ el.removeAttribute('class');
1082
+ }
1083
+ }
1084
+ }
1085
+
1086
+ // keep only text-align in style.
1087
+ var paragraph_style = el.getAttribute('style');
1088
+ var paragraph_text_align = null;
1089
+
1090
+ if (paragraph_style) {
1091
+ var paragraph_style_matches = paragraph_style.match(/text-align:.+?[; "]{1,1}/gi);
1092
+
1093
+ if (paragraph_style_matches) {
1094
+ paragraph_text_align = paragraph_style_matches[paragraph_style_matches.length - 1].replace(/(text-align:.+?[; "]{1,1})/gi, '$1');
1095
+ }
1096
+ }
1097
+
1098
+ _cleanAlignment(el);
1099
+ }
1100
+
1101
+ // Clean tr.
1102
+ if (tag_name == 'TR') {
1103
+ _cleanTr(el, head_style_hash);
1104
+ }
1105
+
1106
+ // Clean empty links.
1107
+ if (tag_name == 'A' && !el.attributes.getNamedItem('href') && !el.attributes.getNamedItem('name') && el.innerHTML) {
1108
+ el.outerHTML = el.innerHTML;
1109
+ }
1110
+
1111
+ // Keep empty TH and TD.
1112
+ if ((tag_name == 'TD' || tag_name == 'TH') && !el.innerHTML) {
1113
+ el.innerHTML = '<br>';
1114
+ }
1115
+
1116
+ // Clean table.
1117
+ if (tag_name == 'TABLE') {
1118
+ el.style.width = '100%';
1119
+ }
1120
+
1121
+ // Remove lang attribute.
1122
+ if (el.getAttribute('lang')) {
1123
+ el.removeAttribute('lang');
1124
+ }
1125
+
1126
+ // Remove mso values from style.
1127
+ if (el.getAttribute('style') && el.getAttribute('style').toLowerCase().indexOf('mso') != -1) {
1128
+ var cleaned_style = _normalizeAttribute(el.getAttribute('style'));
1129
+ cleaned_style = cleaned_style.replace(/[0-9a-z-_]*mso[0-9a-z-_]*:.+?(;{1,1}|$)/gi, '');
1130
+
1131
+ if (cleaned_style) {
1132
+ el.setAttribute('style', cleaned_style);
1133
+ }
1134
+ else {
1135
+ el.removeAttribute('style');
1136
+ }
1137
+ }
1138
+
1139
+ return true;
1140
+ }
1141
+
1142
+ /*
1143
+ * Parse styles from head and return them into a hash.
1144
+ */
1145
+ function _parseHeadStyle (head) {
1146
+
1147
+ var head_style_hash = {};
1148
+
1149
+ var head_styles = head.getElementsByTagName('style');
1150
+
1151
+ if (head_styles.length) {
1152
+ var head_style = head_styles[0];
1153
+
1154
+ // Match styles.
1155
+ var style_list = head_style.innerHTML.match(/[\S ]+\s+{[\s\S]+?}/gi);
1156
+
1157
+ if (style_list) {
1158
+ for (var i = 0; i < style_list.length; i++) {
1159
+ var style = style_list[i];
1160
+
1161
+ // Get style attributes.
1162
+ var style_attrs = style.replace(/([\S ]+\s+){[\s\S]+?}/gi, '$1');
1163
+
1164
+ // Get style definitions.
1165
+ var style_definitions = style.replace(/[\S ]+\s+{([\s\S]+?)}/gi, '$1');
1166
+
1167
+ // Trim whitespaces.
1168
+ style_attrs = style_attrs.replace(/^[\s]|[\s]$/gm, '');
1169
+ style_definitions = style_definitions.replace(/^[\s]|[\s]$/gm, '');
1170
+
1171
+ // Trim new lines.
1172
+ style_attrs = style_attrs.replace(/\n|\r|\n\r/g, '');
1173
+ style_definitions = style_definitions.replace(/\n|\r|\n\r/g, '');
1174
+
1175
+ var style_attrs_array = style_attrs.split(', ');
1176
+
1177
+ // Add every attribute to hash.
1178
+ for (var j = 0; j < style_attrs_array.length; j++) {
1179
+ head_style_hash[style_attrs_array[j]] = style_definitions;
1180
+ }
1181
+ }
1182
+ }
1183
+ }
1184
+
1185
+ return head_style_hash;
1186
+ }
1187
+
1188
+ var _v_shapes_map = {};
1189
+
1190
+ /**
1191
+ * Create a map with the ID for images.
1192
+ */
1193
+ function _getVShapes (html) {
1194
+ var splits = html.split('v:shape');
1195
+
1196
+ for (var i = 1; i < splits.length; i++) {
1197
+ var split = splits[i];
1198
+ var id = split.split(' id="')[1];
1199
+
1200
+ if (id && id.length > 1) {
1201
+ id = id.split('"')[0];
1202
+
1203
+ var oid = split.split(' o:spid="')[1];
1204
+
1205
+ if (oid && oid.length > 1) {
1206
+ oid = oid.split('"')[0];
1207
+
1208
+ _v_shapes_map[id] = oid;
1209
+ }
1210
+ }
1211
+ }
1212
+ }
1213
+
1214
+ /*
1215
+ * Clean HTML that was pasted from Word.
1216
+ */
1217
+ function _wordClean (html, rtf) {
1218
+
1219
+ // Remove junk from outside html.
1220
+ html = html.replace(/[.\s\S\w\W<>]*(<html[^>]*>[.\s\S\w\W<>]*<\/html>)[.\s\S\w\W<>]*/i, '$1');
1221
+
1222
+ // Get the vshapes for images.
1223
+ _getVShapes(html);
1224
+
1225
+ // Convert string into document.
1226
+ var parser = new DOMParser();
1227
+ var word_doc = parser.parseFromString(html, 'text/html');
1228
+
1229
+ var head = word_doc.head;
1230
+ var body = word_doc.body;
1231
+
1232
+ // Create style attrs hash.
1233
+ var head_style_hash = _parseHeadStyle(head);
1234
+
1235
+ // Remove text nodes that do not contain non-whitespace characters and has new lines in them.
1236
+ _traverse(body, function (node) {
1237
+ if (node.nodeType == Node.TEXT_NODE && /\n|\u00a0|\r/.test(node.data)) {
1238
+
1239
+ if (!/\S| /.test(node.data)) {
1240
+ // Keep single &nbsp;
1241
+ if (node.data == $.FE.UNICODE_NBSP) {
1242
+ node.data = '\u200b';
1243
+
1244
+ return true;
1245
+ }
1246
+
1247
+ if (node.data.length == 1 && node.data.charCodeAt(0) == 10) {
1248
+ node.data = ' ';
1249
+
1250
+ return true;
1251
+ }
1252
+
1253
+ _removeNode(node);
1254
+
1255
+ return false;
1256
+ }
1257
+
1258
+ // Remove newlines.
1259
+ else {
1260
+ node.data = node.data.replace(/\n|\r/gi, ' ');
1261
+ }
1262
+ }
1263
+
1264
+ return true;
1265
+ });
1266
+
1267
+ // Process images.
1268
+ _traverse(body, function (node) {
1269
+
1270
+ // Element node.
1271
+ if (node.nodeType == Node.ELEMENT_NODE && (node.tagName == 'V:IMAGEDATA' || node.tagName == 'IMG')) {
1272
+ _cleanImage(node, rtf)
1273
+ }
1274
+
1275
+ return true;
1276
+ });
1277
+
1278
+ // Process lists.
1279
+ var lists = body.querySelectorAll('ul > ul, ul > ol, ol > ul, ol > ol');
1280
+
1281
+ for (var i = lists.length - 1; i >= 0; i--) {
1282
+ if (lists[i].previousElementSibling && lists[i].previousElementSibling.tagName === 'LI') {
1283
+ lists[i].previousElementSibling.appendChild(lists[i]);
1284
+ }
1285
+ }
1286
+
1287
+ // Clean the body.
1288
+ _traverse(body, function (node) {
1289
+
1290
+ // Text node.
1291
+ if (node.nodeType == Node.TEXT_NODE) {
1292
+
1293
+ // https://github.com/froala/wysiwyg-editor/issues/1364.
1294
+ node.data = node.data.replace(/<br>(\n|\r)/gi, '<br>');
1295
+
1296
+ return false;
1297
+ }
1298
+
1299
+ // Element node.
1300
+ else if (node.nodeType == Node.ELEMENT_NODE) {
1301
+ // List found.
1302
+ if (_isList(node)) {
1303
+ // Keep the parent node and previous sibling because the node could be deleted in the list building.
1304
+ var parent_node = node.parentNode;
1305
+ var previous_sibling = node.previousSibling;
1306
+
1307
+ // Get list element.
1308
+ var list_element = _buildList(node, head_style_hash);
1309
+
1310
+ // Find the element to insert the new list before it.
1311
+ var before_element = null;
1312
+
1313
+ // Current node was not the first.
1314
+ if (previous_sibling) {
1315
+ before_element = previous_sibling.nextSibling;
1316
+ }
1317
+ else {
1318
+ before_element = parent_node.firstChild;
1319
+ }
1320
+
1321
+ // Insert before.
1322
+ if (before_element) {
1323
+ parent_node.insertBefore(list_element, before_element);
1324
+ }
1325
+
1326
+ // Push to the end.
1327
+ else {
1328
+ parent_node.appendChild(list_element);
1329
+ }
1330
+
1331
+ return false;
1332
+ }
1333
+ else {
1334
+
1335
+ return _cleanElement(node, head_style_hash);
1336
+ }
1337
+ }
1338
+
1339
+ // Comment node.
1340
+ else if (node.nodeType == Node.COMMENT_NODE) {
1341
+ _removeNode(node);
1342
+
1343
+ return false;
1344
+ }
1345
+
1346
+ return true;
1347
+ });
1348
+
1349
+ // Remove empty tags and clean duplicate styles.
1350
+ _traverse(body, function (node) {
1351
+
1352
+ // Element node.
1353
+ if (node.nodeType == Node.ELEMENT_NODE) {
1354
+
1355
+ var tag_name = node.tagName;
1356
+
1357
+ // Empty. Skip br tag.
1358
+ if (!node.innerHTML && ['BR', 'IMG'].indexOf(tag_name) == -1) {
1359
+ var parent = node.parentNode;
1360
+
1361
+ // Remove recursively.
1362
+ while (parent) {
1363
+ _removeNode(node);
1364
+ node = parent;
1365
+
1366
+ // Stop when non-empty element is found.
1367
+ if (node.innerHTML) {
1368
+ break;
1369
+ }
1370
+ parent = node.parentNode;
1371
+ }
1372
+
1373
+ return false;
1374
+ }
1375
+ else {
1376
+ _cleanStyleDuplicates(node);
1377
+ }
1378
+ }
1379
+
1380
+ return true;
1381
+ });
1382
+
1383
+ // Converd document to string.
1384
+ var word_doc_string = body.outerHTML;
1385
+
1386
+ // Clean HTML.
1387
+ var htmlAllowedStylePropsCopy = editor.opts.htmlAllowedStyleProps;
1388
+ editor.opts.htmlAllowedStyleProps = editor.opts.wordAllowedStyleProps;
1389
+
1390
+ word_doc_string = editor.clean.html(word_doc_string, editor.opts.wordDeniedTags, editor.opts.wordDeniedAttrs, false);
1391
+
1392
+ editor.opts.htmlAllowedStyleProps = htmlAllowedStylePropsCopy;
1393
+
1394
+ return word_doc_string;
1395
+ }
1396
+
1397
+ return {
1398
+ _init: _init,
1399
+ clean: clean
1400
+ };
1401
+ };
1402
+
1403
+ }));