xmt_froala 0.3.1

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 (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
+ }));